4. 斗地主发牌
4.1 案例介绍
按照斗地主的规则,完成洗牌发牌的动作。 具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
4.2 案例分析
-
准备牌:
牌可以设计为一个ArrayList<String>,每个字符串为一张牌。 每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。 牌由Collections类的shuffle方法进行随机排序。
-
发牌
将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
-
看牌
直接打印每个集合。
4.3 代码实现
java
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 排序(第一种排序方式)
java
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 排序(第二种排序方式)
java
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);
}
}
}