Java实现斗地主洗牌发牌功能(不打牌噢)
程序员文章站
2022-07-12 09:08:15
...
设计思路
- 初始化54张牌
- 洗牌
- 发牌
- 给玩家手牌排序
- 展示玩家手牌及3张底牌
实现思路
-
首先是54张牌要选择一种数据结构存放,这里选择List和Map集合都可以,我这里选择的是Map
- 要区分4种花色,则将四种花色存入String数组中,方便后续遍历生成牌池
- 因为每种花色的13张牌的顺序并不是严格的按照数字大小排序,所以每张牌的序号需要计算后存起来,与牌面对应,即典型的key-value形式,这是我选择使用Map的原因之一,主要原因还是刚学完Map,想熟练一下(若使用List存放牌池也完全OK,可以使用下标当作key使用)
- 考虑到方便后续对牌面进行排序,所以Map中的key存放54张牌排序后的序号,即:大小相同的牌,序号是连续的,比如:大王、小王、红桃2、黑桃2、方块2、梅花2,对应的序号应该是:54,53,52,51,50,49
-
其次是要有三个玩家,结合面向对象编程思想,需要创建一个玩家类,记录三个玩家的姓名和手牌list
- 轮流给3个玩家发牌时,根据对3取余是否为0,对3取余是否为1,对3取余是否为2来判断给哪个玩家发牌,即给哪个玩家的手牌list中添加元素
- 因为最后要对玩家手牌排序,所以玩家手牌的list中存放的应该是牌面对应的排序大小,而不是牌面值,即map的key值
- Collections工具类中已经提供了对List集合的升序排列,再结合该类的reverse方法,即可实现对手牌list的降序排列
代码实现
玩家类
import java.util.List;
/**
* @program:
* @description: 扑克牌玩家
* @author: Jack
* @create: 2020-11-09 21:41
**/
public class Player {
private String name;
private List<Integer> ownPokers;
public Player() {
}
public Player(String name, List<Integer> ownPokers) {
this.name = name;
this.ownPokers = ownPokers;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getOwnPokers() {
return ownPokers;
}
public void setOwnPokers(List<Integer> ownPokers) {
this.ownPokers = ownPokers;
}
@Override
public String toString() {
return "玩家[" + name + "]拥有手牌的keys:" + ownPokers;
}
}
功能实现主类
import java.util.*;
/**
* @program:
* @description:
* @author: Jack
* @create: 2020-11-10 14:41
**/
public class PlayCards {
public static Map<Integer,String> mapPoker = new HashMap<>();
private static Player p1 = new Player("廉颇", new ArrayList<>());
private static Player p2 = new Player("赵云", new ArrayList<>());
private static Player p3 = new Player("安琪拉", new ArrayList<>());
private static List<Integer> lastPoker = new ArrayList<>();
private static List<Integer> messyList = new ArrayList(); //为实现随机,先声明一个包含1-54,但是随机存放的的list
public static void main(String[] args) {
//1、初始化牌库
initPoker();
//2、洗牌
shufflePoker();
//3、发牌
givePoker();
//4、手牌排序
orderPoker(p1);
orderPoker(p2);
orderPoker(p3);
//5、手牌及底牌打印
printPlayerPoker(p1);
printPlayerPoker(p2);
printPlayerPoker(p3);
printLastPoker();
}
/**
* 初始化牌库
*/
public static void initPoker(){
String[] colors = {"♣","♠","♦","♥"}; //声明4种花色
String smallJoker = "☪"; //小王
String bigJoker = "●"; //大王
mapPoker.put(53, smallJoker);
mapPoker.put(54, bigJoker);
for (int i = 1; i < 14; i++) {
for (int j = 0; j < colors.length; j++) {
//处理顺序特殊的牌面
if(i == 2){
mapPoker.put(13*4 - j, colors[j] + i); //因为2是大小王之后的最大牌面,所以序号从小王的序号的下一个数值开始依次递减
} else if(i == 1) {
mapPoker.put(12*4 - j, colors[j] + i); //1是在2之后最大牌面,所以序号从2的最小序号的下一个数值开始依次递减
} else{
//将11-12-13转换为英文符号J-Q-K
String face = (i == 11) ? "J" : (i == 12) ? "Q" : (i == 13) ? "K" : String.valueOf(i);
mapPoker.put((i-2)*4 - j, colors[j] + face);
}
}
}
}
/**
* 洗牌
*/
public static void shufflePoker(){
p1.getOwnPokers().clear();
p2.getOwnPokers().clear();
p3.getOwnPokers().clear();
for (int i = 1; i <= 54 ; i++) {
messyList.add(i);
}
Collections.shuffle(messyList); //打乱元素值1-54的位置
}
/**
* 发牌
*/
public static void givePoker(){
for (int i = 0; i < 54; i++) { //发牌54次,并且轮流给三个玩家发牌
if(i > 50){ //最後三张底牌不发
lastPoker.add(messyList.get(i));
continue;
}
//给p3发牌
if(i%3 == 0){
p3.getOwnPokers().add(messyList.get(i));//将随机的牌库的下标保存到玩家手牌中
}
//给p2发牌
else if(i%3 == 1){
p2.getOwnPokers().add(messyList.get(i));//将随机的牌库的下标保存到玩家手牌中
}
//给p1发牌
else{
p1.getOwnPokers().add(messyList.get(i));//将随机的牌库的下标保存到玩家手牌中
}
}
}
/**
* 打印玩家手牌
*/
public static void printPlayerPoker(Player player){
System.out.print("\n玩家" + player.getName() + "手牌:");
for(Integer key : player.getOwnPokers()){
System.out.print(mapPoker.get(key) + " ");
}
}
/**
* 打印底牌
*/
public static void printLastPoker(){
System.out.print("\n剩余三张底牌:");
for(Integer key:lastPoker){
System.out.print(mapPoker.get(key) + " ");
}
}
/**
* 手牌排序
* @param
*/
public static void orderPoker(Player p){
Collections.sort(p.getOwnPokers());
Collections.reverse(p.getOwnPokers());
}
}
说明:使用List存放牌池相对比Map更简单一些,List的下标可以直接用来当作排序的key使用,按照同样的逻辑将54张牌添加到牌池list中,发牌时根据下标取牌即可
文章内容输出来源:拉勾教育_大数据开发高新训练营第3期第一阶段模块三作业5
上一篇: 干货|Java集合实现斗地主洗牌发牌
下一篇: <a/>中href和onclick的区别