人机斗地主小游戏(一)

325 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

工作间隙做个人机斗地主小游戏,娱乐一下

玩家可以选择是自己出牌还是人机出牌,如果是人机出牌则所有玩家都是人机,人机跟人机打,如果是玩家自己出牌,则是玩家打人机,当前玩家能看到自己的牌,选择要出哪些,打出对应数字及字符即可;目前只是实现了线下人机斗地主,并且人机比较智障,之后可以慢慢扩展,让人机变得更灵活一点,并且实现线上真人斗地主

实现效果如下

image.png
  1. 首先列出所有的牌号及牌的花色,通过遍历将所有的牌组装好放进map中,并且准备一个List集合存放牌的索引
//准备一个map集合,存储牌的索引和组装好的牌
HashMap<Integer, String> poker = new HashMap<>();
//准备一个List结合,存储牌的索引
ArrayList<Integer> pokerIndex = new ArrayList<>();
//准备集合用来存放花色
ArrayList<String> colors = new ArrayList<>();
colors.add("♥");
colors.add("♠");
colors.add("♣");
colors.add("♦");

ArrayList<String> allPok = new ArrayList<>();
ArrayList<String> nums = new ArrayList<>();
nums.add("2");
nums.add("3");
nums.add("4");
nums.add("5");
nums.add("6");
nums.add("7");
nums.add("8");
nums.add("9");
nums.add("10");
nums.add("J");
nums.add("Q");
nums.add("K");
nums.add("A");
//把大王和小王存储到集合中去
int index = 0;
poker.put(index, "大王");
pokerIndex.add(index);
index++;
poker.put(index, "小王");
pokerIndex.add(index);
index++;
//循环嵌套遍历两个集合,组装54张牌。存放到集合中
for (String num : nums) {
    for (String color : colors) {
        poker.put(index, color + num);
        allPok.add(color + num);
        pokerIndex.add(index);
        index++;
    }
}

poker中就是存放好的牌及牌对应的序号,输出打印出来的效果如下

image.png
  1. 将牌的顺序打乱
Collections.shuffle(pokerIndex);
  1. 将牌分发给三个模拟玩家,同时新建三个List存放发下来的牌,再新建一个List存放底牌,这几个list存放的是牌对应的序号,如果要模拟更多的玩家需要修改对应的代码
ArrayList<Integer> player01 = new ArrayList<>();
ArrayList<Integer> player02 = new ArrayList<>();
ArrayList<Integer> player03 = new ArrayList<>();
ArrayList<Integer> card = new ArrayList<>();

for (int i = 0; i < pokerIndex.size(); i++) {
    Integer in = pokerIndex.get(i);
    if (i > 50) {
        card.add(in);
    } else if (i % 3 == 0) {
        player01.add(in);
    } else if (i % 3 == 1) {
        player02.add(in);
    } else if (i % 3 == 2) {
        player03.add(in);
    }
}
//将牌整理一下
Collections.sort(player01);
Collections.sort(player02);
Collections.sort(player03);
Collections.sort(card);
  1. 由于出牌的时候要判断牌的大小,所以要识别出牌对应的数字,比如10对应的数字即为10,J对应数字为11,Q为12,以此类推,小王大王按照大小顺序赋数字,并且有花色的牌也要赋上对应数字如♥J、♣J、♦J、♠J等
Map<String, Integer> setMap = new HashMap();
Map<String, Integer> valueMap = new HashMap();
for (int i = 3; i <= 10; i++) {
    setMap.put(String.valueOf(i), i);
}
setMap.put("J", 11);
setMap.put("Q", 12);
setMap.put("K", 13);
setMap.put("A", 14);
setMap.put("2", 15);
setMap.put("小王", 16);
setMap.put("大王", 17);

//有花色的牌号也要赋对应的数字
colors.stream().forEach(color -> {
    setMap.keySet().stream().forEach(value -> {
        if (!value.equals("大王") && !value.equals("小王")) {
            valueMap.put(color + value, setMap.get(value));
        } else {
            valueMap.put(value, setMap.get(value));
        }
    });
});
valueMap.putAll(setMap);

valueMap中存放的就是牌号对应的数字,打印出来的效果如下

image.png

  1. 牌分发好了就要开始进入玩家环节,请玩家输入是否自动(如果选择是,则由人机自己跟自己打牌,不需要玩家手动操作)并让玩家选择是否当地主,并且输入玩家名称,如果玩家不输入,则赋予一个默认值
String local = "";
System.out.println("请输入是否自动(Y|N 可不输,默认非自动)");
int randomLand = 0;
boolean self = true;
boolean lan = false;
//输入是手动还是自动
String self1 = scanner.nextLine();
if (StringUtils.isEmpty(self1)) {
    self1 = "N";
}
if (self1.equals("非自动") || self1.equals("N") || self1.equals("n")) {
    self = false;
    System.out.println("是否抢地主(Y|N),默认随机地主");
    String land = scanner.nextLine();
    if (StringUtils.isEmpty(land)) {
        land = "N";
    }
    if (land.equals("是") || land.equals("Y") || land.equals("y")) {
        lan = true;
    } else {
        randomLand = RandomUtils.nextInt(1, 4);
    }
} else {
    //随机地主
    randomLand = RandomUtils.nextInt(1, 4);
}
System.out.println("请输入当前玩家的名称(不输则为默认玩家)");
local = scanner.nextLine();
if (StringUtils.isEmpty(local)) {
    local = "路人甲";
}
  1. 选择好了之后就要按照玩家的选择来分发底牌,新建Map存放对应的人员序号及人员对应的牌
ArrayList list = null;
Map<String, List> pokMap = new HashMap<>();
Map<Integer, String> peoperMap = new HashMap<>();
for (int i = 1; i < 4; i++) {
    switch (i) {
        case 1:
            list = player01;
            break;
        case 2:
            list = player02;
            break;
        case 3:
            list = player03;
            break;
    }
    String name = "";
    if (i == 1 && self) {
        //如果是自动,则默认第一个是当前玩家
        name = local;
    } else {
       //模拟玩家的名称,可以自己定义
        String[] s = {"路人甲", "路人乙", "路人丙"};
        String[] s2 = {local, "玩家二", "玩家三"};
        while (StringUtils.isEmpty(name)) {
            if (Arrays.asList(s).contains(local)) {
                for (String str : s) {
                    if (peoperMap.containsValue(str)) {
                        continue;
                    }
                    name = str;
                }
            }  else {
                for (String str : s2) {
                    if (peoperMap.containsValue(str)) {
                        continue;
                    }
                    name = str;
                }
            }
        }
    }
    peoperMap.put(i, name);
    if (StringUtils.isNotEmpty(local)) {
       //如果玩家名称输入了,并且跟地主名称一致,将底牌放入当前玩家卡牌池
        if (name.equals(local)) {
            list.addAll(card);
        }
    } else {
        //没有输入玩家名,就按照地主序号来放入底牌
        if (i == randomLand) {
            local = name;
            list.addAll(card);
        }
    }
    //调用方法,根据玩家牌号获取对应的牌
    List pokList = lookPoker(poker, list);
    //list排序
    listSort(pokList, valueMap);
    //将玩家的名称及牌存入Map中
    pokMap.put(name, pokList);
}


根据牌的序号匹配对应的花色,并返回

/*
 * 参数:
 * HashMap<Integer,String> poker:存储牌号的map结合
 * ArrayList<Integer> list :存储玩家和底牌的list集合
 */
public static List lookPoker(Map<Integer, String> poker, ArrayList<Integer> list) {
    ArrayList pokList = new ArrayList();
    for (Integer key : list) {
        String value = poker.get(key);
        pokList.add(value);
    }

    return pokList;
}

根据牌对应的序号将花色的牌按照正常顺序存放,避免顺序太乱看不清牌

//list排序
public static List<String> listSort(List<String> list, Map<String, Integer> valueMap) {
    if (list.size() == 0) {
        return list;
    }
    Collections.sort(list, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return valueMap.get(o1) - valueMap.get(o2);
        }
    });
    return list;
}

pokMap中存放的是所有玩家,及玩家对应的牌,打印出来的效果如下

image.png

后续明天再写,over