[置顶] 斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌
大学期间,我在别人的基础上,写了一个简易的斗地主程序。
主要实现了面向对象设计,洗牌、发牌、判断牌型、比较牌的大小、游戏规则等算法。
通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算法的理解。
最近把这些设计和算法分享给大家,过些天会上传斗地主程序的源码。
项目截图
定义一张牌Card
a.一张牌的类型
// 一张牌的大类型 public enum CardBigType { HEI_TAO, HONG_TAO, MEI_HUA, FANG_KUAI, XIAO_WANG, DA_WANG }
// 一张牌的小类型 public enum CardSmallType { A, ER, SAN, SI, WU, LIU, QI, BA, JIU, SHI, J, Q, K, XIAO_WANG, DA_WANG }
b.一张牌Card的属性
// 牌的数字ID,1到54 public int id; // 牌的大类型,方块,梅花,红桃,黑桃,小王,大王 public final CardBigType bigType; // 牌的小类型,2_10,A,J,Q,K public final CardSmallType smallType; // 牌的等级,对牌进行排序时会用到 public int grade; // 牌的图像名字,图形界面显示牌用到 public String imageName;
c.构造一张牌
// 通过牌的整型id构造一张牌 public Card(int id) { this.id = id; bigType = CardUtil.getBigType(id); smallType = CardUtil.getSmallType(id); grade = CardUtil.getGrade(id); imageName = CardUtil.getImageName(id); Icon icon = DdzUtil.getImageIcon(imageName); setIcon(icon); }
d.根据牌的id获得一张牌的大类型:方块,梅花,红桃,黑桃,小王,大王
/** * 根据牌的id获得一张牌的大类型:方块,梅花,红桃,黑桃,小王,大王 * * @param id * 牌的id * * @return 牌的大类型:方块,梅花,红桃,黑桃,小王,大王 */ public static CardBigType getBigType(int id) { CardBigType bigType = null; if (id >= 1 && id <= 13) { bigType = CardBigType.FANG_KUAI; } else if (id >= 14 && id <= 26) { bigType = CardBigType.MEI_HUA; } else if (id >= 27 && id <= 39) { bigType = CardBigType.HONG_TAO; } else if (id >= 40 && id <= 52) { bigType = CardBigType.HEI_TAO; } else if (id == 53) { bigType = CardBigType.XIAO_WANG; } else if (id == 54) { bigType = CardBigType.DA_WANG; } return bigType; }
e.根据牌的id,获取牌的小类型:2_10,A,J,Q,K
/** * 根据牌的id,获取牌的小类型:2_10,A,J,Q,K * * @param id * 牌的id * * @return 牌的小类型:2_10,A,J,Q,K */ public static CardSmallType getSmallType(int id) { if (id < 1 || id > 54) { throw new RuntimeException("牌的数字不合法"); } CardSmallType smallType = null; if (id >= 1 && id <= 52) { smallType = numToType(id % 13); } else if (id == 53) { smallType = CardSmallType.XIAO_WANG; } else if (id == 54) { smallType = CardSmallType.DA_WANG; } else { smallType = null; } return smallType; } /** * 将阿拉伯数字0到12转换成对应的小牌型,被getSmallType方法调用 * * @param num * 数字(0到12) * @return 牌的小类型 */ private static CardSmallType numToType(int num) { CardSmallType type = null; switch (num) { case 0: type = CardSmallType.K; break; case 1: type = CardSmallType.A; break; case 2: type = CardSmallType.ER; break; case 3: type = CardSmallType.SAN; break; case 4: type = CardSmallType.SI; break; case 5: type = CardSmallType.WU; break; case 6: type = CardSmallType.LIU; break; case 7: type = CardSmallType.QI; break; case 8: type = CardSmallType.BA; break; case 9: type = CardSmallType.JIU; break; case 10: type = CardSmallType.SHI; break; case 11: type = CardSmallType.J; break; case 12: type = CardSmallType.Q; break; } return type; }
f.根据牌的id,获得一张牌的等级
/** * 根据牌的id,获得一张牌的等级 * * @param id * 牌的id * @return 与牌数字对应的等级 */ public static int getGrade(int id) { if (id < 1 || id > 54) { throw new RuntimeException("牌的数字不合法"); } int grade = 0; // 2个王必须放在前边判断 if (id == 53) { grade = 16; } else if (id == 54) { grade = 17; } else { int modResult = id % 13; if (modResult == 1) { grade = 14; } else if (modResult == 2) { grade = 15; } else if (modResult == 3) { grade = 3; } else if (modResult == 4) { grade = 4; } else if (modResult == 5) { grade = 5; } else if (modResult == 6) { grade = 6; } else if (modResult == 7) { grade = 7; } else if (modResult == 8) { grade = 8; } else if (modResult == 9) { grade = 9; } else if (modResult == 10) { grade = 10; } else if (modResult == 11) { grade = 11; } else if (modResult == 12) { grade = 12; } else if (modResult == 0) { grade = 13; } } return grade; }
g.根据牌的id获得牌图片的名字
/** * 根据牌的id获得牌图片的名字 * * @param id * 牌的id * @return 图片的名字 */ public static String getImageName(int id) { // 得到图片的前一个字符,表示是第几个牌 String imageName = ""; if (id == 53) { imageName += "smallJoker"; } else if (id == 54) { imageName += "bigJoker"; } else { int mod = id % 13; String firstLetter = ""; switch (mod) { case 0: firstLetter = "K"; break; case 1: firstLetter = "A"; break; case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: firstLetter = "" + mod; break; case 11: firstLetter = "J"; break; case 12: firstLetter = "Q"; break; default: break; } String secondLetter = ""; // 得到图片的后一个字符,表示什么颜色的牌 if (id >= 1 && id <= 13) { secondLetter = "0"; } else if (id >= 14 && id <= 26) { secondLetter = "1"; } else if (id >= 27 && id <= 39) { secondLetter = "2"; } else if (id >= 40 && id <= 52) { secondLetter = "3"; } imageName = firstLetter + secondLetter; } String extension = ".gif"; return imageName + extension; }
下一篇将介绍 斗地主出牌规则算法的设计和实现
不出意外,本周末10月13号将上传源码到CSDN下载资源。
刚刚看了下日历,10月12号 星期六,仍然要上班,果然是史上最复杂的国庆放假啊。
原文参见:http://FansUnion.cn/articles/2712