要求
实现扑克牌的创建、洗牌、发牌、大小对比,输出赢家牌。
前提条件
首先需要创建三个集合,用于存储牌面值、牌号与比较规则,再创建一个类作为牌。
其次还需要了解到一个工具类,就是Collections类,该类的所有方法都是由 static 静态关键字修饰的,所以该类的所有方法都可直接使用 类名+. 的方式调用。
Collections类是针对集合的一个工具类,里面的所有方法就是针对集合来写的。
下面两个方法就是给类中给定的方法。
private static HashMap<Integer,poker> pokerBox; // 牌盒
/*
存储牌盒中的key键值,与牌盒中的牌一一对应,用于取出牌盒中的牌,对牌号的操作等同于对牌盒操作
但是对Integer类型操作比对String类型操作更简单。
同时牌号也能表示不同花色间的大小关系
*/
private static List<Integer> listPoker; // 牌号
private static HashMap<String,Integer> map; // 存储牌面值的大小规则
// poker类
// 代表扑克牌便于操作
class poker{
// 花色与牌面值分离了
// 汇总就是总值
String flowerColor; // 花色
String faceValue; // 牌面值
String value; // 总值
public poker(){}
// 有参构造
public poker(String flowerColor, String faceValue,String value) {
this.flowerColor = flowerColor;
this.faceValue = faceValue;
this.value=value;
}
}
扑克牌的创建
使用一个静态代码块来构建牌,初始化牌盒、牌号与大小规则等。
静态代码块是一种特殊的语法结构,它允许你在类加载到JVM时执行某些操作。这种结构常用于一次性的设置或初始化静态变量。
静态代码块在类被加载时执行一次,并且只执行一次。
// 准备牌
static {
map=new HashMap<>();
pokerBox=new HashMap<>();
listPoker=new ArrayList<>();
// 将牌号存入map集合,用于比较时的牌大小对比
map.put("2",2);
map.put("3",3);
map.put("4",4);
map.put("5",5);
map.put("6",6);
map.put("7",7);
map.put("8",8);
map.put("9",9);
map.put("10",10);
map.put("J",11);
map.put("Q",12);
map.put("K",13);
map.put("A",14);
map.put("234",15);
map.put("345",16);
map.put("456",17);
map.put("678",18);
map.put("789",19);
map.put("8910",20);
map.put("910J",21);
map.put("JQK",22);
map.put("QKA",23);
map.put("222",24);
map.put("333",25);
map.put("444",26);
map.put("555",27);
map.put("666",28);
map.put("777",29);
map.put("999",30);
map.put("101010",31);
map.put("JJJ",32);
map.put("QQQ",33);
map.put("KKK",34);
map.put("AAA",35);
// 235通吃(保留)
map.put("235",999999999);
// 花色
String[] FlowerColor=new String[]{"♦","♣","♥","♠"};
// 字母牌
String[] letter=new String[]{"J","Q","K","A"};
// 数字牌部分
int keyIndex=0;
for (int i = 2; i < 11; i++) {
for (int j = 0; j < FlowerColor.length; j++) {
listPoker.add(keyIndex); // 存放序号
pokerBox.put(keyIndex++,new 2poker(FlowerColor[j],i+"",FlowerColor[j]+i)); // 将序号与牌产生对应关系
}
}
// 字母牌部分
for (int i = 0; i < letter.length; i++) {
for (int j = 0; j < FlowerColor.length; j++) {
listPoker.add(keyIndex);
// 将牌号与牌存入牌盒中
pokerBox.put(keyIndex++,new poker(FlowerColor[j],letter[i],FlowerColor[j]+letter[i]));
}
}
}
洗牌
由于牌号内的序号是与牌盒中的牌一一对应的,那么将存储牌号的list集合打乱就可以达到洗牌的效果
// 洗牌
public void pokerShuffle(){
// shuffle方法作用是将指定List集合使用默认随机源进行置换,也就是打乱List集合内元素的位置,当然该方法只对List集合有效。
Collections.shuffle(listPoker); // 打乱牌的序号
}
发牌
List集合与List集合之间是可以嵌套的,使用List<List>作为该方法的返回值,外层的List集合中代码每一个玩家,内层的List中代表玩家的扑克牌数。
public List<List<Integer>> dealCards(int playerNumber){
// 对人数进行限制
if((playerNumber*3) > pokerBox.size() || playerNumber <= 0){
System.out.println("玩家超出限制,最多允许17位玩家、最少1一位玩家参加此游戏,请重新选择人数");
return null;
}
// 玩家列表
List<List<Integer>> playerList=new ArrayList<>();
int k=3; // 每位玩家牌的张数
for (int i = 0,curIntdex=0; i < playerNumber; i++) {
List<Integer> curPlayer=new ArrayList<>();
// 每位玩家发三张牌
for (int j = 0; j < k; j++) {
curPlayer.add(listPoker.get(curIntdex++));
}
playerList.add(curPlayer); // 将当前玩家添加到玩家列表中
}
return playerList;
}
看牌
// 看牌
public void lookPoker(List<List<Integer>> list){
// 所有玩家
for(int i=0,end=list.size(); i<end; ++i){
System.out.print("玩家"+(i+1)+":");
// 代表当前玩家
List<Integer> curPople=list.get(i);
// 玩家手中的牌
for(int j=0,n=curPople.size(); j<n; ++j){
// 从当前玩家curPople手中获取牌得序号,根据序号从牌盒PokerBox中取出牌来
System.out.print(pokerBox.get(curPople.get(j)).value + " ");
}
System.out.println();
}
System.out.println();
}
对每个玩家的手牌内部进行排序。
// 玩家手牌进行排序
public void playerPokerSort(List<List<Integer>> lists){
// 最大手牌在第一位,第二次之....
for (int i = 0; i < lists.size(); i++) {
// 排序,逆序
Collections.sort(lists.get(i),((o1, o2) -> (o2-o1)));
}
}
牌与牌之间的比较方法
返回值:
- 大于0:玩家a的手牌 大于 玩家b的手牌
- 小于0:玩家a的手牌 小于 玩家b的手牌
- 等于0:玩家a的手牌 等于 玩家b的手牌
牌与牌之间的比较方法
返回值:
- 大于0:玩家a的手牌 大于 玩家b的手牌
- 小于0:玩家a的手牌 小于 玩家b的手牌
- 等于0:玩家a的手牌 等于 玩家b的手牌
// 比较函数 public int cmp(List<Integer> a,List<Integer> b){ // O(a.size) StringBuilder sbA=new StringBuilder(); StringBuilder sbB=new StringBuilder(); // 逆序取 for(int i=a.size()-1; i>=0; --i){ sbA.append(pokerBox.get(a.get(i)).faceValue); sbB.append(pokerBox.get(b.get(i)).faceValue); } // 判断是否存在顺子牌等的情况 Integer numA=map.get(sbA.toString()); Integer numB=map.get(sbB.toString()); if((numA != null && null == numB) || (null == numA && numB != null)){ return (null == numA) ? -1 : 1; }else if(numA != null && numB != null){ return numA-numB; } // O(a.size) for(int i=0,end=a.size(); i < end; ++i) { // 从两个玩家手中获取牌根号,获取到牌号后再从牌盒中取出牌面值来 // 再从map中获取牌面值的大小,进行比较 numA=map.get(pokerBox.get(a.get(i)).faceValue); numB=map.get(pokerBox.get(b.get(i)).faceValue); if (numA == numB) { continue; } if (numA > numB) { return 1; } else { return -1; } } // 相等的情况 return 0; }
找牌最大的玩家
// 输出最大玩家的手牌 public void printWinPlayer(List<List<Integer>> list){ int maxIndex=0; List<Integer> maxPlayer=list.get(0); // 循环比较出最大玩家 for(int i=1,end=list.size(); i<end; ++i){ List<Integer> cur=list.get(i); // 根据比较方法来找出牌最大的玩家 if(cmp(maxPlayer,cur) < 0){ maxIndex=i; maxPlayer=cur; } } System.out.print("最大的手牌是玩家"+(maxIndex+1)+":"); List<Integer> ans=list.get(maxIndex); for(Integer i : ans){ System.out.print(pokerBox.get(i).value + " "); } System.out.println(); }
完整代码
运行结果
游戏代码
package newGame;
import java.util.*;
public class pokerGame {
// 由于牌盒不需要排序,那么使用hashMap即可
private static HashMap<Integer,poker> pokerBox; // 牌盒
/*
存储牌盒中的key键值,与牌盒中的牌一一对应,用于取出牌盒中的牌,对牌号的操作等同于对牌盒操作
但是对Integer类型操作比对String类型操作更简单。
同时牌号也能表示不同花色间的大小关系
*/
private static List<Integer> listPoker; // 牌号
private static HashMap<String,Integer> map; // 存储牌面值的大小规则
// 准备牌
static {
map=new HashMap<>();
pokerBox=new HashMap<>();
listPoker=new ArrayList<>();
// 将牌号存入map集合,用于比较时的牌大小对比
map.put("2",2);
map.put("3",3);
map.put("4",4);
map.put("5",5);
map.put("6",6);
map.put("7",7);
map.put("8",8);
map.put("9",9);
map.put("10",10);
map.put("J",11);
map.put("Q",12);
map.put("K",13);
map.put("A",14);
map.put("234",15);
map.put("345",16);
map.put("456",17);
map.put("678",18);
map.put("789",19);
map.put("8910",20);
map.put("910J",21);
map.put("JQK",22);
map.put("QKA",23);
map.put("222",24);
map.put("333",25);
map.put("444",26);
map.put("555",27);
map.put("666",28);
map.put("777",29);
map.put("999",30);
map.put("101010",31);
map.put("JJJ",32);
map.put("QQQ",33);
map.put("KKK",34);
map.put("AAA",35);
// 最大值(保留)
map.put("235",1000);
// 花色
String[] FlowerColor=new String[]{"♦","♣","♥","♠"};
// 字母牌
String[] letter=new String[]{"J","Q","K","A"};
// 数字牌部分
int keyIndex=0;
for (int i = 2; i < 11; i++) {
for (int j = 0; j < FlowerColor.length; j++) {
listPoker.add(keyIndex); // 存放序号
pokerBox.put(keyIndex++,new poker(FlowerColor[j],i+"",FlowerColor[j]+i)); // 将序号与牌产生对应关系
}
}
// 字母牌部分
for (int i = 0; i < letter.length; i++) {
for (int j = 0; j < FlowerColor.length; j++) {
listPoker.add(keyIndex);
pokerBox.put(keyIndex++,new poker(FlowerColor[j],letter[i],FlowerColor[j]+letter[i]));
}
}
}
// 洗牌
public void pokerShuffle(){
Collections.shuffle(listPoker); // 打乱牌的序号
}
// 发牌
public List<List<Integer>> dealCards(int playerNumber){
// 对人数进行限制
if((playerNumber*3) > pokerBox.size() || playerNumber <= 0){
System.out.println("玩家超出限制,最多允许17位玩家、最少1一位玩家参加此游戏,请重新选择人数");
return null;
}
// 玩家列表
List<List<Integer>> playerList=new ArrayList<>();
int k=3; // 每位玩家牌的张数
for (int i = 0,curIntdex=0; i < playerNumber; i++) {
List<Integer> curPlayer=new ArrayList<>();
// 每位玩家发三张牌
for (int j = 0; j < k; j++) {
curPlayer.add(listPoker.get(curIntdex++));
}
playerList.add(curPlayer); // 将当前玩家添加到玩家列表中
}
return playerList;
}
// 看牌
public void lookPoker(List<List<Integer>> list){
// 所有玩家
for(int i=0,end=list.size(); i<end; ++i){
System.out.print("玩家"+(i+1)+":");
// 代表当前玩家
List<Integer> curPople=list.get(i);
// 玩家手中的牌
for(int j=0,n=curPople.size(); j<n; ++j){
// 从当前玩家curPople手中获取牌得序号,根据序号从牌盒PokerBox中取出牌来
System.out.print(pokerBox.get(curPople.get(j)).value + " ");
}
System.out.println();
}
System.out.println();
}
// 玩家手牌进行排序
public void playerPokerSort(List<List<Integer>> lists){
// 最大手牌在第一位,第二次之....
for (int i = 0; i < lists.size(); i++) {
// 排序,逆序
Collections.sort(lists.get(i),((o1, o2) -> (o2-o1)));
}
}
// 比较函数
public int cmp(List<Integer> a,List<Integer> b){
// O(a.size)
StringBuilder sbA=new StringBuilder();
StringBuilder sbB=new StringBuilder();
// 逆序取
for(int i=a.size()-1; i>=0; --i){
sbA.append(pokerBox.get(a.get(i)).faceValue);
sbB.append(pokerBox.get(b.get(i)).faceValue);
}
Integer numA=map.get(sbA.toString());
Integer numB=map.get(sbB.toString());
if((numA != null && null == numB) || (null == numA && numB != null)){
return (null == numA) ? -1 : 1;
}else if(numA != null && numB != null){
return numA-numB;
}
// O(a.size)
for(int i=0,end=a.size(); i < end; ++i) {
// 从两个玩家手中获取牌根号,获取到牌号后再从牌盒中取出牌面值来
// 再从map中获取牌面值的大小,进行比较
numA=map.get(pokerBox.get(a.get(i)).faceValue);
numB=map.get(pokerBox.get(b.get(i)).faceValue);
if (numA == numB) { continue; }
// a玩家大于b玩家的情况
if (numA > numB) { return 1; }
// 小于的情况
else { return -1; }
}
// 相等的情况
return 0;
}
// 输出最大玩家的手牌
public void printWinPlayer(List<List<Integer>> list){
int maxIndex=0;
List<Integer> maxPlayer=list.get(0);
// 循环比较出最大玩家
for(int i=1,end=list.size(); i<end; ++i){
List<Integer> cur=list.get(i);
if(cmp(maxPlayer,cur) < 0){
maxIndex=i;
maxPlayer=cur;
}
}
System.out.print("最大的手牌是玩家"+(maxIndex+1)+":");
List<Integer> ans=list.get(maxIndex);
for(Integer i : ans){
System.out.print(pokerBox.get(i).value + " ");
}
System.out.println();
}
public pokerGame(){
// 同花顺的逻辑没有编写
pokerShuffle(); // 洗牌
int playyern=3; // 玩家人数
List<List<Integer>> lists = dealCards(playyern); // 发牌
if(null == lists){
System.out.println("玩家数不规范,程序退出");
System.exit(-1);
}
lookPoker(lists); // 看牌
playerPokerSort(lists); // 每个玩家的手牌内进行排序
// lookPoker(lists);
printWinPlayer(lists); // 输出手牌值最大的玩家
}
}
class poker{
// 花色与牌面值分离了
// 汇总就是总值
String flowerColor; // 花色
String faceValue; // 牌面值
String value; // 总值
public poker(){}
// 有参构造
public poker(String flowerColor, String faceValue,String value) {
this.flowerColor = flowerColor;
this.faceValue = faceValue;
this.value=value;
}
}