4. 斗地主发牌
4.1 案例介绍
按照斗地主的规则,完成洗牌发牌的动作。 具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
4.2 案例分析
- 准备牌:
牌可以设计为一个ArrayList<String>,每个字符串为一张牌。 每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。 牌由Collections类的shuffle方法进行随机排序。 - 发牌
将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。 - 看牌
- 直接打印每个集合。
4.3 代码实现
public class App { public static void main(String[] args) { /* 完成控制台版的三步: 准备牌 洗牌 发牌 */ //从程序的主入口开启斗地主游戏 new PokerGame(); } } public class PokerGame { //牌盒 //♥3 ♣3 static ArrayList<String> list = new ArrayList<>(); //静态代码块 //特点:随着类的加载而在加载的,而且只执行一次。 static { //准备牌 // "♦", "♣", "♥", "♠" // "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" String[] color = {"♦", "♣", "♥", "♠" }; String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; for (String c : color) { //c依次表示每一种花色 for (String n : number) { //n 依次表示每一个数字 list.add(c + n); } } list.add("小王"); list.add("大王"); } public PokerGame(){ //洗牌 Collections.shuffle(list); //发牌 ArrayList<String> lord = new ArrayList<>(); ArrayList<String> player1 = new ArrayList<>(); ArrayList<String> player2 = new ArrayList<>(); ArrayList<String> player3 = new ArrayList<>(); //遍历牌盒得到每一张牌 for (int i = 0; i < list.size(); i++) { //i:索引 String poker = list.get(i); if(i <= 2){ lord.add(poker); continue; } //给三个玩家轮流发牌 if(i % 3 == 0){ player1.add(poker); }else if(i % 3 == 1){ player2.add(poker); }else{ player3.add(poker); } } //看牌 lookPoker("底牌",lord); lookPoker("钢脑壳",player1); lookPoker("大帅比",player2); lookPoker("蛋筒",player3); } /* * 参数一:玩家的名字 * 参数二:每位玩家的牌 * */ public void lookPoker(String name, ArrayList<String> list){ System.out.print(name + ": "); for (String poker : list) { System.out.print(poker + " "); } System.out.println(); } }
4.4 排序(第一种排序方式)
public class App { public static void main(String[] args) { /* 完成控制台版的四步: 准备牌 洗牌 发牌 排序 */ //从程序的主入口开启斗地主游戏 new PokerGame(); } } public class PokerGame { //牌盒 Map //此时我们只要把牌跟序号产生对应关系就可以了,不需要按照序号进行排序,所以只要HashMap就可以了 static HashMap<Integer, String> hm = new HashMap<>(); static ArrayList<Integer> list = new ArrayList<>(); static { String[] color = {"♦", "♣", "♥", "♠"}; String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; //序号 int serialNumber = 1; //细节 for (String n : number) { //依次表示每一个数字 for (String c : color) { //依次表示每一个花色 hm.put(serialNumber, c + n); list.add(serialNumber); serialNumber++; } } hm.put(serialNumber, "小王"); list.add(serialNumber); serialNumber++; hm.put(serialNumber, "大王"); list.add(serialNumber); } public PokerGame() { //洗牌 Collections.shuffle(list); //发牌 TreeSet<Integer> lord = new TreeSet<>(); TreeSet<Integer> player1 = new TreeSet<>(); TreeSet<Integer> player2 = new TreeSet<>(); TreeSet<Integer> player3 = new TreeSet<>(); for (int i = 0; i < list.size(); i++) { //i :依次表示集合中的每一个索引 //list.get(i)元素:牌的序号 int serialNumber = list.get(i); if(i <= 2){ lord.add(serialNumber); continue; } if(i % 3 == 0){ player1.add(serialNumber); }else if(i % 3 == 1){ player2.add(serialNumber); }else{ player3.add(serialNumber); } } //看牌 lookPoker("底牌",lord); lookPoker("钢脑壳",player1); lookPoker("大帅比",player2); lookPoker("蛋筒",player3); } /* * 参数一:玩家的名字 * 参数二:牌的序号 * */ public void lookPoker(String name, TreeSet<Integer> ts){ System.out.print(name + ": "); //遍历TreeSet集合得到每一个序号,再拿着序号到Map集合中去找真正的牌 for (int serialNumber : ts) { String poker = hm.get(serialNumber); System.out.print(poker + " "); } System.out.println(); } }
4.5 排序(第二种排序方式)
public class App { public static void main(String[] args) { new PokerGame(); } } public class PokerGame { //牌盒 static ArrayList<String> list = new ArrayList<>(); //创建一个集合,用来添加牌的价值 static HashMap<String, Integer> hm = new HashMap<>(); static { //准备牌 String[] color = {"♦", "♣", "♥", "♠"}; String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; for (String c : color) { for (String n : number) { list.add(c + n); } } list.add(" 小王"); list.add(" 大王"); //指定牌的价值 //牌上的数字到Map集合中判断是否存在 //存在,获取价值 //不存在,本身的数字就是价值 hm.put("J", 11); hm.put("Q", 12); hm.put("K", 13); hm.put("A", 14); hm.put("2", 15); hm.put("小王", 50); hm.put("大王", 100); } public PokerGame() { //洗牌 Collections.shuffle(list); //发牌 ArrayList<String> lord = new ArrayList<>(); ArrayList<String> player1 = new ArrayList<>(); ArrayList<String> player2 = new ArrayList<>(); ArrayList<String> player3 = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { String poker = list.get(i); //发底牌 if (i <= 2) { lord.add(poker); continue; } //给三个玩家轮流发牌 if (i % 3 == 0) { player1.add(poker); } else if (i % 3 == 1) { player2.add(poker); } else { player3.add(poker); } } //排序 order(lord); order(player1); order(player2); order(player3); //看牌 lookPoker("底牌",lord); lookPoker("钢脑壳",player1); lookPoker("大帅比",player2); lookPoker("蛋筒",player3); } /* * 参数一:玩家的名字 * 参数二:每位玩家的牌 * */ public void lookPoker(String name, ArrayList<String> list){ System.out.print(name + ": "); for (String poker : list) { System.out.print(poker + " "); } System.out.println(); } //利用牌的价值进行排序 //参数:集合 //♥5 ♥3 ♥6 ♥7 ♥9 public void order(ArrayList<String> list){ Collections.sort(list, new Comparator<String>() { //Array.sort (插入排序 + 二分查找) @Override public int compare(String o1, String o2) { //o1:表示当前要插入到有序序列中的牌 //o2:表示已经在有序序列中存在的牌 //负数:o1小 插入到前面 //正数:o1大 插入到后面 //0:o1的数字跟o2的数字是一样的,需要按照花色再次排序 //1.计算o1的花色和价值 大王 String color1 = o1.substring(0, 1); int value1 = getValue(o1); //2.计算o2的花色和价值 String color2 = o2.substring(0, 1); int value2 = getValue(o2); //3.比较o1和o2的价值 ♥3 ♠3 int i = value1 - value2; return i == 0 ? color1.compareTo(color2) : i; } }); } //计算牌的价值 //参数:牌 //返回值:价值 public int getValue(String poker){//♥3 //获取牌上的数字 String number = poker.substring(1);//把这里截取出来的结果,让这个结果再Map集合中存在 “ 大王” //拿着数字到map集合中判断是否存在 if(hm.containsKey(number)){ //存在,获取价值 return hm.get(number); }else{ //不存在,类型转换 return Integer.parseInt(number); } } }