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

桥牌游戏和牌面展示

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (3投票s)

2012年2月11日

CPOL

2分钟阅读

viewsIcon

62612

downloadIcon

1863

玩随机抽四人桥牌游戏

328668/2.png

328668/3.png

要玩上述游戏,请下载 BridgeCardGameV3.zip

引言

我相信学习数学或编程的人迟早都会研究纸牌游戏。过去我曾多次涉及这个主题,无论是学习面向对象编程还是概率统计。最近,我阅读了 Gary Stafford 的 C# 纸牌战争游戏模拟,我非常喜欢它,因为它与其他的纸牌程序不同,并且具有一些独特的特点,而且他的代码在整个过程中都有很好的文档记录,易于理解。

最大的优点是它的简单性,并且不需要链接到任何 DLL,例如 Cards.dll

通常,链接到正确的 DLL 并找到和下载 DLL 并不是一件简单的事情。花时间下载和链接,却发现是 DLL 的错误版本。有了 Gary 的代码,你可以立即启动并运行,专注于研究纸牌游戏算法,而不是处理编程接口问题。

为了练习编程,我采用了他的代码和其他我在 Google 上找到的示例纸牌类,并将其制作成一个桥牌游戏演示。如果你在机场感到无聊,可以随机显示桥牌的四手牌进行查看。这篇文章也可以作为未来扩展的基础。

本文将演示以下内容

  • 基于现有的 CodeProject 文章进行变体
  • 面向对象编程的应用
  • 使用 XML 和 XML 样式表制作漂亮的演示文稿
  • 讨论未来的编程想法

Using the Code

我从 introcs.cs.princeton.edu 的 Deck 类代码(Java) 找到一个非常基本的 Deck 类。令我惊讶的是,Java 和 C# 非常相似。这个类非常短,就是一个包含 52 张随机洗牌的牌堆。我添加了一个模块,两个 dictionary 对象,以及一个漂亮的套装,显示字符集。该项目是在 Microsoft Visual C# 2010 Express 下编译的。

static string[] suit = { "♦", "♣", "♥", "♠" };
static string[] rank = { "2", "3", "4", "5", "6", 
       "7", "8", "9", "10", "J", "Q", "K", "A" };

// Dictionary contains the index value to card suit and rank
// for example, A♠ = 52, 2♦ = 0
// so it can display nicely as player groups his cards on hand

Dictionary<string, int> cardOrder = new Dictionary<string, int>();
Dictionary<int, string> orderedDeck = new Dictionary<int, string>();

/// <summary>
/// format drawing cards to xml tagged string for nice display
/// refer to t.xml and t.css
/// </summary>
// 
public string drawCardXml(int numCard, int sideIdx)
{
    string handxml = "";
    orderedDeck.Clear();

    if (CardIndex + numCard <= N) //enough cards left to draw
    {
        for (int i = CardIndex; i < CardIndex + numCard; i++)
        {
            Console.Out.WriteLine(deck[i]);
            orderedDeck.Add(cardOrder[deck[i]], deck[i]);
        }
        CardIndex += numCard;
        // order cards on hand by suit
        var sortedDict = (from entry in orderedDeck orderby entry.Key descending 
               select entry).ToDictionary(pair => pair.Key, pair => pair.Value);

        string[] suitOnHand = { "", "", "", "" };
        char[] suitchar = { '♦', '♣', '♥', '♠' };
        char[] side = { 'N', 'E', 'W', 'S' };

        string[] suitName = { "DIAMONDS-", "CLUBS-", "HEARTS-", "SPADES-" };

        foreach (KeyValuePair<int, string> pair in sortedDict)
        {
            int idx = pair.Key / RANKS;
            // extract only the value of the card
            suitOnHand[idx] += pair.Value.TrimEnd(suitchar[idx]) + ",  ";
        }
        for (int i = SUITS-1; i >= 0; i--) // reverse order, spade on top
        {
            handxml += "<" + suitName[i] + side[sideIdx] + ">" + suit[i] + ": " 
                            + suitOnHand[i].TrimEnd(new Char[] { ' ', ',' }) 
                            + @"</" + suitName[i] + side[sideIdx] + ">";
        }
    }
    return handxml;
}

drawCardXml 返回一个 string,它将被保存到 t.xml 中进行显示;t.xml 显示如下

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="t.css"?>
<GAME><BRIDGE>

<SPADES-N>♠: 5</SPADES-N>
<HEARTS-N>♥: Q ,  9 ,  8 ,  2</HEARTS-N>
<CLUBS-N>♣: 10 ,  5</CLUBS-N>
<DIAMONDS-N>♦: 10 ,  9 ,  7 ,  6 ,  5 ,  4</DIAMONDS-N>

<SPADES-E>♠: 9 ,  4 ,  2</SPADES-E>
<HEARTS-E>♥: K ,  7 ,  4</HEARTS-E>
<CLUBS-E>♣: K ,  Q ,  7 ,  3</CLUBS-E>
<DIAMONDS-E>♦: K ,  8 ,  2</DIAMONDS-E>

<SPADES-W>♠: A ,  Q ,  J ,  10 ,  3</SPADES-W>
<HEARTS-W>♥: J ,  10 ,  6</HEARTS-W>
<CLUBS-W>♣: 9 ,  8 ,  6 ,  4</CLUBS-W>
<DIAMONDS-W>♦: J</DIAMONDS-W>

<SPADES-S>♠: K ,  8 ,  7 ,  6</SPADES-S>
<HEARTS-S>♥: A ,  5 ,  3</HEARTS-S>
<CLUBS-S>♣: A ,  J ,  2</CLUBS-S>
<DIAMONDS-S>♦: A ,  Q ,  3</DIAMONDS-S>

</BRIDGE></GAME>

最后,我们需要一个样式表 t.css 来在屏幕上用不同的颜色排列四手桥牌。

GAME
{
background-color: #ffffff;
width: 100%;
}
BRIDGE
{
display: block;
margin-bottom: 30pt;
margin-left: 0;
}

SPADES-N
{
display: block;
color: #000000;
font-size: 20pt;
margin-left: 200pt;
}
CLUBS-N
{
display: block;
color: #000000;
font-size: 20pt;
margin-left: 200pt;
}
HEARTS-N
{
display: block;
color: #FF0000;
font-size: 20pt;
margin-left: 200pt;
}
DIAMONDS-N
{
display: block;
color: #FF0000;
font-size: 20pt;
margin-left: 200pt;
}

未来项目构想

一个数据库包含几份报纸上发表的桥牌游戏,包含叫牌合同和游戏步骤,缓慢显示纸牌游戏的过程。

参考文献

历史

  • 2012 年 2 月 11 日 - 第一个版本(显示牌)
  • 2012 年 2 月 17 日 - V3(玩牌);修复了错误并添加了 AI 来生成默认合同
© . All rights reserved.