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

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

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

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

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

项目截图

斗地主-项目截图

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

 

posted on 2013-10-09 18:41  you Richer  阅读(285)  评论(0编辑  收藏  举报