一个扑克牌的程序设计问题

baar 2011-12-13 09:10:04
最近在做一个类似于UNO的扑克牌程序,不知道有没有人玩过UNO,游戏规则很简单,就是一个玩家出一张牌,然后下一个玩家,出的牌,要么跟上个玩家出的牌数字相同,要么花色相同,如果都没有的话,就得在牌库里面摸一张牌,然后这些牌里面还有一些特殊功能的牌,譬如改变上一个玩家出的牌得花色或者数字,从而来适应自己的出牌,游戏最后把牌出光的就是胜利者,然后分数越少的排第2,其次少的拍第3.。。。。
我设计的时候一共分成三个类,第一个类是CARD,第二个类是PLAYER,第三个类是GAME,最后一个类是启动程序的MAIN,第一,二个类相信不用我介绍了,第三个GAME类是用来处理一些诸如初始化牌库,初始化玩家数,洗牌,派牌,计分等功能。
在设计的时候我有几个问题:
1,对于牌库,玩家的手牌,还有玩家群,分别用什么容器比较合适?特别对于牌库,有没有一个类似于单向链表的容器,因为我打算用一个随机数来把牌库里的牌分派给玩家,当第一个玩家得到牌之后,继续用这个随机数的话,如果不是单向链表那样,就会出现抽到空元素。
2,对于一些有特殊功能的牌,我是想用多态来实现,但是在实现那牌得功能之前,必须要先判断玩家的牌是否有特殊功能,这一判断的话,就失去了多态的优势,请问如果我想用多态来实现的话,应该怎样实现?
3.请问枚举类的元素可以是整数吗?我想用一个枚举类来装牌得数字,另外一个枚举类装牌得花色,但是装牌的数字的枚举类好像老是不通过编译。
...全文
478 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
baar 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 woxikuanwan 的回复:]
觉得UNO很复杂,楼主是大神啊!
[/Quote]
我做的只是简化版,不过,我想基本框架和思路就是那样了吧
woxikuanwan 2011-12-17
  • 打赏
  • 举报
回复
觉得UNO很复杂,楼主是大神啊!
蔡袅 2011-12-16
  • 打赏
  • 举报
回复
gomoku 2011-12-16
  • 打赏
  • 举报
回复
更正:)
public int Rank { get { return id / 4 + 1; } } //大小
gomoku 2011-12-16
  • 打赏
  • 举报
回复

public class Card
{
public enum CardSuit
{
Spade = 0, //黑桃
Heart = 1, //红心
Diamond = 2, //方块
Club = 3, //草花
Joker = 52, //小王
BigJoker = 53,//大王
}
private int id;
public int Rank { get { return id / 4; } } //大小
public CardSuit Suit //花色
{
get
{
if (id == 53) return CardSuit.BigJoker;
if (id == 52) return CardSuit.Joker;
return (CardSuit)(id & 3);
}
}
public override string ToString()
{
return Suit.ToString() + (Suit < CardSuit.Joker ? " " + Rank : "");
}
public static IEnumerable<Card> GetCards54() //随机发54张牌
{
return GetCards(54);
}
public static IEnumerable<Card> GetCards52() //随机发52张牌
{
return GetCards(52);
}
private static IEnumerable<Card> GetCards(int count)
{
int[] ids = new int[count];
for (int i = 0; i < ids.Length; i++) ids[i] = i;
for (int i = count; i > 0; i--)
{
int index = random.Next(i);
Card card = new Card() { id = ids[index] };
ids[index] = ids[i - 1];
yield return card;
}
}
[ThreadStatic]
private static Random random = new Random();
}

static void Main(string[] args) //测试发牌
{
foreach (Card c in Card.GetCards54())
{
Console.WriteLine(c);
}
}
阿非 2011-12-16
  • 打赏
  • 举报
回复
我的发牌思路有两个:
第一,从卡牌数组抽取一定的手牌到玩家1手里,譬如8张牌,然后第9张牌开始就给第2个玩家。。。。这个方法的问题是,怎样用循环表示第一个玩家抽到8张牌之后结束,然后第2个玩家从第9张牌抽?而且我设计的抽牌数个变量,根据人数不同,玩家手牌数也不同。
第二,要么我改变下存储卡牌的容器,但是又不知道有什么容器类比较好操作,我用STACK行吗?这个有点像摸牌那样,从盏堆顶抽取元素。
-------------
List 或者 Queue

list 的话 取一个就移除一个
baar 2011-12-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xx_mm 的回复:]
我之前写的:
C++ QQ斗地主洗牌,发牌,选牌实现算法
[/Quote]现在又遇到了一个难题,我想把卡牌判断的函数CompSf(Karte obj)放到GAME这个类里面,但是现在遇到的问题是,我怎样把obj的枚举类跟特定的牌号做比较呢?譬如说,我7号牌的功能是让下一位玩家摸两张牌,我在Card这个类里面用有个emu CardName={7,8,9.....},
baar 2011-12-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sandy945 的回复:]
我的发牌思路有两个:
第一,从卡牌数组抽取一定的手牌到玩家1手里,譬如8张牌,然后第9张牌开始就给第2个玩家。。。。这个方法的问题是,怎样用循环表示第一个玩家抽到8张牌之后结束,然后第2个玩家从第9张牌抽?而且我设计的抽牌数个变量,根据人数不同,玩家手牌数也不同。
第二,要么我改变下存储卡牌的容器,但是又不知道有什么容器类比较好操作,我用STACK行吗?这个有点像摸牌那样,从盏堆顶抽取……
[/Quote]
现在又遇到了一个难题,我想把卡牌判断的函数CompSf(Karte obj)放到GAME这个类里面,但是现在遇到的问题是,我怎样把obj的枚举类跟特定的牌号做比较呢?譬如说,我7号牌的功能是让下一位玩家摸两张牌,我在Cart这个类里面用有个emu CartName={7,8,9.....}
baar 2011-12-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sandy945 的回复:]
我的发牌思路有两个:
第一,从卡牌数组抽取一定的手牌到玩家1手里,譬如8张牌,然后第9张牌开始就给第2个玩家。。。。这个方法的问题是,怎样用循环表示第一个玩家抽到8张牌之后结束,然后第2个玩家从第9张牌抽?而且我设计的抽牌数个变量,根据人数不同,玩家手牌数也不同。
第二,要么我改变下存储卡牌的容器,但是又不知道有什么容器类比较好操作,我用STACK行吗?这个有点像摸牌那样,从盏堆顶抽取……
[/Quote]
这是我发牌的程序,但是出现了一个问题,玩家得到的牌有些是相同的,请问怎样避免这样的情况?我也应经用了REMOVE的方法了

public void Kverteilt()
{
int j = 0;
Random rnd = new Random();
foreach (player s in PlayerTable)
{

for (int i = 0; i < 6; i++)
{
j = rnd.Next(0,32 - i);
s.KZiehen(shuffledKL.ElementAt(j));//取牌
shuffledKL.RemoveAt(j); //从牌库中删除取出的牌

}
}
}
baar 2011-12-16
  • 打赏
  • 举报
回复
现在又遇到了一个难题,我想把卡牌判断的函数CompSf(Karte obj)放到GAME这个类里面,但是现在遇到的问题是,我怎样把obj的枚举类跟特定的牌号做比较呢?譬如说,我7号牌的功能是让下一位玩家摸两张牌,我在karten这个类里面用有个emu KartenName={7,8,9.....},我用switch case

public void CompSf(Karte obj){
switch(obj)
{
case KartenName.7:....
case KartenName.8:....
case KartenName.9:....
}
}

但是在编译的时候却说不能用到KartenName,请问我怎样才能把这个功能放到GAME类里面去?
niaoked 2011-12-14
  • 打赏
  • 举报
回复
划分为:Table类,Player类,GameLogic类
Card不用单独做成一个类,直接一个数组就OK。
baar 2011-12-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sandy945 的回复:]
1 用List比较合适 比LinkList合适,尤其体现在随机分牌

2 继承自功能牌

3 枚举可以转换成整数

UNO 我倒是玩过,功能牌记不全了。你设计的类有点问题
[/Quote]
谢谢指导,请问我设计的类有什么问题?我现在就卡在发牌这个功能上面了,我PLAYER是用LIST实现,为了方便实现洗牌的功能,对于存储卡牌,我用了数组实现,但是现在问题是发牌的时候,如果写这两个循环发牌?我的发牌思路有两个:
第一,从卡牌数组抽取一定的手牌到玩家1手里,譬如8张牌,然后第9张牌开始就给第2个玩家。。。。这个方法的问题是,怎样用循环表示第一个玩家抽到8张牌之后结束,然后第2个玩家从第9张牌抽?而且我设计的抽牌数个变量,根据人数不同,玩家手牌数也不同。
第二,要么我改变下存储卡牌的容器,但是又不知道有什么容器类比较好操作,我用STACK行吗?这个有点像摸牌那样,从盏堆顶抽取元素。
阿非 2011-12-14
  • 打赏
  • 举报
回复
1 用List比较合适 比LinkList合适,尤其体现在随机分牌

2 继承自功能牌

3 枚举可以转换成整数

UNO 我倒是玩过,功能牌记不全了。你设计的类有点问题

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧