65.9K
CodeProject 正在变化。 阅读更多。
Home

HiLow 纸牌游戏

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.67/5 (8投票s)

2004年11月9日

3分钟阅读

viewsIcon

95988

downloadIcon

2758

一篇关于使用 C# 创建一个简单的纸牌游戏的文章,使用了更新的 card.dll 包装类

HiLow Card Game

引言

这是一个简单的纸牌游戏 HiLow 版本,包含一个高分榜。

背景

2003年,当我开始用 C# 编程时,我对编写纸牌游戏很感兴趣。 一段时间后,我找到了足够的信息来编写一个包装类,以便使用 Windows 附带的 cards.dll。 这促使我写了一篇关于 DLL 的文章,可以在这里找到。 从那时起,我一直在逐步改进它,直到我认为它现在处于足够好的状态可以重新提交。 如果您想查看我如何到达现在这个类状态的历史,您可以在我的网站上查看。

高低游戏

这个游戏简单地基于猜测下一张随机牌比当前显示的牌更高或更低。 每局游戏花费 10 分,如果您猜对四张牌,您将赢得 20 分。 玩了一段时间后,猜对四张牌并不像看起来那么容易。

当您猜对了四张牌或者您输掉了游戏时,“再玩一次”按钮就会出现。

包装类

cards.dll 包装类的第一个更改是它现在实现了 IDisposable。 这是为了确保图形设备上下文被正确清理,因为该类现在有自己的图形表面可以绘制。

/// <summary>
/// .NET Graphics surface used for drawing.
/// </summary>
private Graphics graphicsSurface;

/// <summary>
/// Win32 HDC surface use for Win32 drawing.
/// </summary>
private IntPtr graphicsDC;

为了现在使用该类,我们在绘制任何牌之前调用 Begin,并在完成绘制牌后调用 End

protected override void OnPaint(PaintEventArgs e)
{
  // Allocate graphics device context
  cardDrawing.Begin( e.Graphics );

  // Do Card drawing
  . . .

  // Release graphics device context
  cardDrawing.End();

  // Draw anything else

  base.OnPaint(e);
}

此外,我们需要确保从窗体调用纸牌的 Dispose 方法。

if( cardDrawing != null )
{
  cardDrawing.Dispose();
}

新功能

该类的一个不错的新功能是能够以任何角度旋转绘制一张牌。 因此,为了从纸牌的左上角逆时针旋转 90 度绘制红桃K,我们将使用以下代码行

cardDrawing.DrawRotatedCard( new Point(120,120), 90, 
       Card.ToCardIndex( CardSuit.Hearts, CardRank.King ) );

其中 cardDrawingCard 类的一个实例。

一个简单的牌组类

此应用程序使用一个简单的类来表示一副牌。 我们只需要一个整数数组,而不是一个纸牌数组,因为 Card 类只绘制纸牌,没有其他功能。

public class Deck
{
  private int[] CardArray = new int[52];

  /// <summary>
  /// Initializes deck with the 52 integers.
  /// </summary>
  public Deck()
  {
    // Deck uses RankCollated cards 0 - 51
    for( int i = 0; i < 52; i++ )
    {
      CardArray[i] = i;
    }
  }
}

这使得实现一个洗牌程序变得容易,而且本质上非常随机。

/// <summary>
/// Randomly rearrange integers
/// </summary>
public void Shuffle()
{
  int[] newArray = new int[52];
  bool[] used = new bool[52];

  for( int j = 0; j < 52; j++ )
  {
    used[j] = false;
  }

  Random rnd = new Random();
  int iCount = 0;
  int iNum;

  while( iCount < 52 )
  {
    iNum = rnd.Next( 0, 52 ); // between 0 and 51

    if( used[iNum] == false )
    {
      newArray[iCount] = iNum;
      used[iNum] = true;
      iCount++;
    }
  }

  // Load original array with shuffled array
  CardArray = newArray;
}

最后,访问存储在我们数组中的当前整数以了解要绘制哪张牌。

/// <summary>
/// Obtains a card number from the deck.
/// </summary>
public int GetCard( int arrayNum )
{
  if (arrayNum >= 0 && arrayNum <= 51)
    return CardArray[arrayNum];
  else
    throw (new System.ArgumentOutOfRangeException("arrayNum", arrayNum,
      "Value must be between 0 and 51."));
}

代码重用

在制作这款游戏时,我决定需要一个高分榜。 为了避免重复发明轮子,我采用了之前提交的 Yahtzee 游戏中的 HighScore 类。

High Score Table

享受游戏!

历史

  • 2007年5月10日 - 更新了 .NET 2.0 的源代码
  • 2007年5月14日 - 更新后的文章发布到 Code Project

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.