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

大学期间,我在别人的基础上,写了一个简易的斗地主程序。

主要实现了面向对象设计,洗牌、发牌、判断牌型、比较牌的大小、游戏规则等算法。

通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算法的理解。

最近把这些设计和算法分享给大家,过些天会上传斗地主程序的源码。

项目截图

定义一张牌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

 

你可能感兴趣的:(算法)