携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第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中就是存放好的牌及牌对应的序号,输出打印出来的效果如下
- 将牌的顺序打乱
Collections.shuffle(pokerIndex);
- 将牌分发给三个模拟玩家,同时新建三个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);
- 由于出牌的时候要判断牌的大小,所以要识别出牌对应的数字,比如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中存放的就是牌号对应的数字,打印出来的效果如下
- 牌分发好了就要开始进入玩家环节,请玩家输入是否自动(如果选择是,则由人机自己跟自己打牌,不需要玩家手动操作)并让玩家选择是否当地主,并且输入玩家名称,如果玩家不输入,则赋予一个默认值
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 = "路人甲";
}
- 选择好了之后就要按照玩家的选择来分发底牌,新建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中存放的是所有玩家,及玩家对应的牌,打印出来的效果如下
后续明天再写,over