斗地主算法的设计与实现(二)

您所在的位置:网站首页 七星斗地主牌型介绍图 斗地主算法的设计与实现(二)

斗地主算法的设计与实现(二)

2024-07-15 18:19| 来源: 网络整理| 查看: 265

本篇主要讲解斗地主中如何判断一手牌的牌型。

牌型  火箭:即双王(大王和小王),最大的牌。  炸弹:四张点数相同的牌,如:7777。  单牌:任意一张单牌。  对牌:任意两张点数相同的牌。  三张:任意三张点数相同的牌,如888。  三带一:点数相同的三张牌+一张单牌或一对牌。如:333+6 或 444+99。  单顺:任意五张或五张以上点数相连的牌,如:45678或78910JQK。不包括 2和双王。  双顺:三对或更多的连续对牌,如:334455、7788991010JJ。不包括 2 点和双王。  三顺:二个或更多的连续三张牌,如:333444 、555666777888。不包括 2 点和双王。  飞机带翅膀:三顺+同数量的单牌或同数量的对牌。如:444555+79 或333444555+7799JJ  四带二:四张牌+两手牌。(注意:四带二不是炸弹)。如:5555+3+8 或 4444+55+77 。

友情提示:本篇是接着上1篇讲述的,建议先看看上1篇一张牌Card的构造过程。

斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌

http://blog.csdn.net/fansunion/article/details/12516411

/** * 游戏规则 牌的类型共有10种: * * 1. 单 2.对子 3.3不带 4.3带1 5.炸弹 6.顺子 7.4带2 8.连队 9.飞机 10.对王 * * @author [email protected],http://FansUnion.cn, *         http://blog.csdn.net/FansUnion * */

1.单

 

/** * 判断牌是否为单 * * @param myCards * 牌的集合 * @return 如果为单,返回true;否则,返回false。 */ public static boolean isDan(List myCards) { // 默认不是单 boolean flag = false; if (myCards != null && myCards.size() == 1) { flag = true; } return flag; }

2.对子

    

/** * 判断牌是否为对子 * * @param myCards * 牌的集合 * @return 如果为对子,返回true;否则,返回false。 */ public static boolean isDuiZi(List myCards) { // 默认不是对子 boolean flag = false; if (myCards != null && myCards.size() == 2) { int grade1 = myCards.get(0).grade; int grade2 = myCards.get(1).grade; if (grade1 == grade2) { flag = true; } } return flag; }

3.3带1

    /**  

* 判断牌是否为3带1 * * @param myCards * 牌的集合 * @return 如果为3带1,被带牌的位置,0或3,否则返回-1。炸弹返回-1。 */ public static int isSanDaiYi(List myCards) { int flag = -1; // 默认不是3带1 if (myCards != null && myCards.size() == 4) { // 对牌进行排序 CardUtil.sortCards(myCards); int[] grades = new int[4]; grades[0] = myCards.get(0).grade; grades[1] = myCards.get(1).grade; grades[2] = myCards.get(2).grade; grades[3] = myCards.get(3).grade; // 暂时认为炸弹不为3带1 if ((grades[1] == grades[0]) && (grades[2] == grades[0]) && (grades[3] == grades[0])) { return -1; } // 3带1,被带的牌在牌头 else if ((grades[1] == grades[0] && grades[2] == grades[0])) { return 0; } // 3带1,被带的牌在牌尾 else if (grades[1] == grades[3] && grades[2] == grades[3]) { return 3; } } return flag; }

4.3不带

  

/** * 判断牌是否为3不带 * * @param myCards * 牌的集合 * @return 如果为3不带,返回true;否则,返回false。 */ public static boolean isSanBuDai(List myCards) { // 默认不是3不带 boolean flag = false; if (myCards != null && myCards.size() == 3) { int grade0 = myCards.get(0).grade; int grade1 = myCards.get(1).grade; int grade2 = myCards.get(2).grade; if (grade0 == grade1 && grade2 == grade0) { flag = true; } } return flag; }

5.顺子

  

/** * 判断牌是否为顺子 * * @param myCards * 牌的集合 * @return 如果为顺子,返回true;否则,返回false。 */ public static boolean isShunZi(List myCards) { // 默认是顺子 boolean flag = true; if (myCards != null) { int size = myCards.size(); // 顺子牌的个数在5到12之间 if (size < 5 || size > 12) { return false; } // 对牌进行排序 CardUtil.sortCards(myCards); for (int n = 0; n < size - 1; n++) { int prev = myCards.get(n).grade; int next = myCards.get(n + 1).grade; // 小王、大王、2不能加入顺子 if (prev == 17 || prev == 16 || prev == 15 || next == 17 || next == 16 || next == 15) { flag = false; break; } else { if (prev - next != -1) { flag = false; break; } } } } return flag; }

6.炸弹

    

/** * 判断牌是否为炸弹 * * @param myCards * 牌的集合 * @return 如果为炸弹,返回true;否则,返回false。 */ public static boolean isZhaDan(List myCards) { // 默认不是炸弹 boolean flag = false; if (myCards != null && myCards.size() == 4) { int[] grades = new int[4]; grades[0] = myCards.get(0).grade; grades[1] = myCards.get(1).grade; grades[2] = myCards.get(2).grade; grades[3] = myCards.get(3).grade; if ((grades[1] == grades[0]) && (grades[2] == grades[0]) && (grades[3] == grades[0])) { flag = true; } } return flag; }

7.王炸

  

/** * 判断牌是否为王炸 * * @param myCards * 牌的集合 * @return 如果为王炸,返回true;否则,返回false。 */ public static boolean isDuiWang(List myCards) { // 默认不是对王 boolean flag = false; if (myCards != null && myCards.size() == 2) { int gradeOne = myCards.get(0).grade; int gradeTwo = myCards.get(1).grade; // 只有小王和大王的等级之后才可能是33 if (gradeOne + gradeTwo == 33) { flag = true; } } return flag; }

8.连对

 

/** * 判断牌是否为连对 * * @param myCards * 牌的集合 * @return 如果为连对,返回true;否则,返回false。 */ public static boolean isLianDui(List myCards) { // 默认是连对 boolean flag = true; if (myCards == null) { flag = false; return flag; } int size = myCards.size(); if (size < 6 || size % 2 != 0) { flag = false; } else { // 对牌进行排序 CardUtil.sortCards(myCards); for (int i = 0; i < size; i = i + 2) { if (myCards.get(i).grade != myCards.get(i + 1).grade) { flag = false; break; } if (i < size - 2) { if (myCards.get(i).grade - myCards.get(i + 2).grade != -1) { flag = false; break; } } } } return flag; }

9.飞机

 

/** * 判断牌是否为飞机 * * @param myCards * 牌的集合 * @return 如果为飞机,返回true;否则,返回false。 */ public static boolean isFeiJi(List myCards) { boolean flag = false; // 默认不是单 if (myCards != null) { int size = myCards.size(); if (size >= 6) { // 对牌进行排序 CardUtil.sortCards(myCards); if (size % 3 == 0 && size % 4 != 0) { flag = isFeiJiBuDai(myCards); } else if (size % 3 != 0 && size % 4 == 0) { flag = isFeiJiDai(myCards); } else if (size == 12) { flag = isFeiJiBuDai(myCards) || isFeiJiDai(myCards); } } } return flag; }

10.飞机不带

 

/** * 判断牌是否为飞机不带 * * @param myCards * 牌的集合 * @return 如果为飞机不带,返回true;否则,返回false。 */ public static boolean isFeiJiBuDai(List myCards) { if (myCards == null) { return false; } int size = myCards.size(); int n = size / 3; int[] grades = new int[n]; if (size % 3 != 0) { return false; } else { for (int i = 0; i < n; i++) { if (!isSanBuDai(myCards.subList(i * 3, i * 3 + 3))) { return false; } else { // 如果连续的3张牌是一样的,记录其中一张牌的grade grades[i] = myCards.get(i * 3).grade; } } } for (int i = 0; i < n - 1; i++) { if (grades[i] == 15) {// 不允许出现2 return false; } if (grades[i + 1] - grades[i] != 1) { System.out.println("等级连续,如 333444" + (grades[i + 1] - grades[i])); return false;// grade必须连续,如 333444 } } return true; }

11.飞机带

  

/** * 判断牌是否为飞机带 * * @param myCards * 牌的集合 * @return 如果为飞机带,返回true;否则,返回false。 */ public static boolean isFeiJiDai(List myCards) { int size = myCards.size(); int n = size / 4;// 此处为“除”,而非取模 int i = 0; for (i = 0; i + 2 < size; i = i + 3) { int grade1 = myCards.get(i).grade; int grade2 = myCards.get(i + 1).grade; int grade3 = myCards.get(i + 2).grade; if (grade1 == grade2 && grade3 == grade1) { // return isFeiJiBuDai(myCards.subList(i, i + 3 * // n));8张牌时,下标越界,subList不能取到最后一个元素 ArrayList cards = new ArrayList(); for (int j = i; j < i + 3 * n; j++) {// 取字串 cards.add(myCards.get(j)); } return isFeiJiBuDai(cards); } } return false; }

12.4带2

  

/** * 判断牌是否为4带2 * * @param myCards * 牌的集合 * @return 如果为4带2,返回true;否则,返回false。 */ public static boolean isSiDaiEr(List myCards) { boolean flag = false; if (myCards != null && myCards.size() == 6) { // 对牌进行排序 CardUtil.sortCards(myCards); for (int i = 0; i < 3; i++) { int grade1 = myCards.get(i).grade; int grade2 = myCards.get(i + 1).grade; int grade3 = myCards.get(i + 2).grade; int grade4 = myCards.get(i + 3).grade; if (grade2 == grade1 && grade3 == grade1 && grade4 == grade1) { flag = true; } } } return flag; }

下一篇,将要介绍 如何比较2手牌的大小,敬请期待。

 

相关阅读

斗地主算法的设计与实现

面向对象实现斗地主程序的核心算法,包括洗牌、发牌、判断牌型、比较牌的大小、游戏规则等。

 

原文参见:http://FansUnion.cn/articles/2716



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3