疯狂Java讲义第六章下“梭哈游戏练习”

定义一个类,该类用于封装一桌梭哈游戏,这个类应该包含桌上剩下的牌的信息,并包含5个玩家的状态信息:他们各自的位置,游戏状态(正在游戏或已放弃)、手上已有的牌等信息。如果有可能,这个类还应该实现发牌方法,这个方法需要控制从谁开始发牌,不要发牌给放弃的人,并修改桌上剩下的牌。
一些思路:
1.发牌前先洗牌,可以调用Collections.shuffle(List)。默认扑克的一种有序的排列,然后进行编号,将这52个编号打乱,在找到对应的扑克。
2.发牌按照座位号的顺序,玩家随意入座。考虑到放弃游戏的玩家将不会发到牌,库顶的牌需要做“归位”处理。
3.五张牌的组合判断:同花和顺子的判断较为简单,对于两对,三对这类的组合只需要统计重复扑克的次数即可,方法同“判断数组中各元素出现的次数”,可参考

https://blog.csdn.net/haiyoung/article/details/49006361

代码如下:

import java.util.*;

public class Stud {
	private static final int ROYAL_FLUSH = 10;
	private static final int SRTAIGHT_FLUSH = 9;
	private static final int FOUR = 8;
	private static final int FULLHOUSE = 7;
	private static final int FLUSH = 6;
	private static final int STRAIGHT = 5;
	private static final int THREE = 4;
	private static final int TWO_PAIRS = 3;
	private static final int ONE_PAIRS = 2;
	private static final int ZILCH = 1;
	private static final int GIVE_UP = 0;
	private static final int PLAYER_ALL = 5;
	//0:♠ 1:♣ 2:♥ 3:♦
	public static String[] sPoker = new String[52];  //after shuffle
	private static int topcard = 0;
	private static int top = 0;
	private static int dealTimes = 0;
	private static int seatStart = 0;  // 0~4
	private static int rounds = 1;
	private static int space = 0;
	private static int[] winner = new int[5];
	
	private class Player {
		String pName;
		boolean state = true;
		String[] handPoker = new String[5];
		int[] handPokerNum = new int[5];
		char[] handPokerColor = new char[5];
	}
	static Player seat[] = new Player[PLAYER_ALL];

	//Initialization
	public void studInit() {
		String[][] Poker = new String[4][13];
		String[] color = {"♠", "♣", "♥", "♦"};
		String[] num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
		String[] name = {"player1", "player2", "player3", "player4", "player5"};
		
		for(int i =0 ; i < PLAYER_ALL; i++) {
			seat[i] = new Player();
		}
		
		for (int i = 0; i <4; i++) {
			for (int j = 0; j <13; j++) {
				Poker[i][j] = color[i]+num[j];
			}
		}
		//Shuffle
		List<Integer> cardList = new ArrayList<Integer>();
		for (int i = 0; i < 52; i++) {
			cardList.add(i+1);
		}
		Collections.shuffle(cardList);
		//exchange list to poker
		for (int n = 0; n < 52; n++) {
			sPoker[n] = Poker[(cardList.get(n)-1)/13][(cardList.get(n)-1)%13];
			System.out.print(sPoker[n]+" ");
			}
		System.out.print("\n");
		//take a seat
		List<Integer> pList = new ArrayList<Integer>();
		for (int i = 0; i < PLAYER_ALL; i++) {
			pList.add(i);
		}
		Collections.shuffle(pList);
		for (int n = 0; n < PLAYER_ALL; n++) {
			seat[n].pName = name[pList.get(n)];
		}
		}
	
	public void match(Player p, int k) {
		switch(p.handPoker[k].charAt(1)) {
		case 'A' :
			p.handPokerNum[k] = 1;
			break;
		case 'J' :
			p.handPokerNum[k] = 11;
			break;
		case 'Q' :
			p.handPokerNum[k] = 12;
			break;
		case 'K' :
			p.handPokerNum[k] = 13;
			break;
			default :
				p.handPokerNum[k] =(int)(p.handPoker[k].charAt(1)) - 48;
		}
	}
	//deal cards 存在放弃的玩家,需要space对topcard进行“归位”
	public void deal(int sStrat) {
		sStrat = seatStart;
		for(int i = 0; i < PLAYER_ALL; i++) {
			top = topcard - space;
			switch(topcard%5) {
			case 0:
				if(seat[sStrat%5].state) {
					seat[sStrat%5].handPoker[dealTimes] = sPoker[top];
					seat[sStrat%5].handPokerColor[dealTimes] = seat[sStrat%5].handPoker[dealTimes].charAt(0);
					match(seat[sStrat%5], dealTimes);
				}
				else space ++;
				break;
			case 1:
				if(seat[(sStrat+1)%5].state) {
					seat[(sStrat+1)%5].handPoker[dealTimes] = sPoker[top];
					seat[(sStrat+1)%5].handPokerColor[dealTimes] = seat[(sStrat+1)%5].handPoker[dealTimes].charAt(0);
					match(seat[(seatStart+1)%5], dealTimes);
				}
				else space ++;
				break;
			case 2:
				if(seat[(sStrat+2)%5].state) {
					seat[(sStrat+2)%5].handPoker[dealTimes] = sPoker[top];
					seat[(sStrat+2)%5].handPokerColor[dealTimes] = seat[(sStrat+2)%5].handPoker[dealTimes].charAt(0);
					match(seat[(sStrat+2)%5], dealTimes);
				}
				else space ++;
				break;
			case 3:
				if(seat[(sStrat+3)%5].state) {
					seat[(sStrat+3)%5].handPoker[dealTimes] = sPoker[top];
					seat[(sStrat+3)%5].handPokerColor[dealTimes] = seat[(sStrat+3)%5].handPoker[dealTimes].charAt(0);
					match(seat[(sStrat+3)%5], dealTimes);
				}
				else space ++;
				break;
			case 4:
				if(seat[(sStrat+4)%5].state) {
					seat[(sStrat+4)%5].handPoker[dealTimes] = sPoker[top];
					seat[(sStrat+4)%5].handPokerColor[dealTimes] = seat[(sStrat+4)%5].handPoker[dealTimes].charAt(0);
					match(seat[(sStrat+4)%5], dealTimes);
				}
				else space ++;
				break;
			}
			topcard ++;
		}
		dealTimes++;
	}
	//STRAIGHT
	public boolean jStraight(Player p) {
		//Sort
		boolean flag = false;
		Arrays.sort(p.handPokerNum);
		for (int i = 0; i < p.handPokerNum.length-1; i++) {
			if(p.handPokerNum[i]+1 == p.handPokerNum[i+1])
				flag = true;
			else {
				flag = false;
				break;
			}
		}
		return flag;
	}
	//FLUSH
	public boolean jFlush(Player p) {
		boolean flag = false;
		for (int i = 0; i < p.handPokerColor.length-1; i++) {
			if(p.handPokerColor[i] == p.handPokerColor[i+1])
				flag = true;
			else {
				flag = false;
				break;
			}
		}
		return flag;
	}
	// FOUR, FULLHOUSE, THREE, TWO_PAIRS, ONE_PAIRS
	public int repetition(Player p) {
		int reFour = 0;
		int reThree = 0;
		int reTwo= 0;
		HashMap<Integer, Integer> pokers = new HashMap<Integer, Integer>();
		for(int num : p.handPokerNum) {
			Integer key = pokers.get(num);
			pokers.put(num, key == null ? 1 : key+1);
		}
		Iterator<Integer> itr = pokers.keySet().iterator();
		while(itr.hasNext()) {
			Object key = itr.next();
			if(pokers.get(key) == 4) {
				reFour ++;
				break;
			}
			else if(pokers.get(key) == 3)
				reThree ++;
			else if(pokers.get(key) ==2)
				reTwo ++;
		}
		if(reFour == 1) return FOUR;
		if(reThree == 1 && reTwo == 1) return FULLHOUSE;
		if(reThree == 1 && reTwo == 0) return THREE;
		if(reTwo == 2) return TWO_PAIRS;
		if(reThree == 0 && reTwo ==1) return ONE_PAIRS;
		else return ZILCH;
	}
	
	public int type(Player p) {
		int TYPE = 0;
		if(p.state) {
			if(jStraight(p)) {
				if(jFlush(p)) {
					if(p.handPokerNum[0] == 1)
						TYPE = ROYAL_FLUSH;
					else
						TYPE = SRTAIGHT_FLUSH;
				}
				else TYPE = STRAIGHT;
			}
			else if(jFlush(p)) TYPE = FLUSH;
			else TYPE = repetition(p);
			return TYPE;
		}
		else return GIVE_UP;
	}
	
	//其他辅助函数
	public char[] change(String str) {
		String s;
		s = str.replace(" ", "");   //删除字符串中的空格
		char[] stringArr = s.toCharArray();  //字符串转换为数组
		return stringArr;
	}
	public int max(int data[]) {
		int m = 0;
		for (int i = 0; i < data.length; i++)
		{
			if(m < data[i]) m= data[i];
		}
		return m;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Stud s = new Stud();
		s.studInit();
		Scanner in = new Scanner(System.in);
		System.out.println("=======5人梭哈游戏=======");
		System.out.print("随机分配座位... 回车开始游戏");
		while(in.nextLine() == null);
		for (int i = 0; i < PLAYER_ALL; i++) {
			System.out.print(" || "+(i+1)+"号座位: "+seat[i].pName+" || ");
		}
		System.out.println();
		//以下不考虑输入错误
		System.out.print("确认从几号座位开始发牌(输入1~5):");
		int sSt = 0;
		sSt = in.nextInt();
		seatStart = sSt - 1;
		System.out.println(sSt);
		s.deal(seatStart);
		for (int i = 0; i < 5; i++) {
			System.out.println("各位玩家状态及剩余扑克牌信息:");
			for (int j = 0; j < PLAYER_ALL; j++) {
				if(seat[j].state) System.out.print((j+1)+"号位置:"+seat[j].pName+"玩家    "+"状态:正在游戏   ");
				else System.out.print((j+1)+"号位置:"+seat[j].pName+"玩家    "+"状态:放弃游戏   ");
				System.out.print("手牌:");
				for(int r = 0; r < rounds; r++) {
					System.out.print(seat[j].handPoker[r]+ "  ");
				}
				System.out.println();
			}
			System.out.println("剩余扑克牌为:");
			for(int p = rounds*5 - space; p < 52; p++) {
				System.out.print(sPoker[p]+" ");
			}
			System.out.println();
			if(i == 4) break;
			System.out.println("剩余玩家是否继续游戏(继续:Y,放弃:N)?允许出现空格,不能有其他字符");
			char[] yOrN = s.change(in.next());
			for (int k = 0; k < PLAYER_ALL; k++) {
				if (yOrN[k] == 'N') {
					seat[k].state = false;
				}
			}
			rounds ++;
			s.deal(seatStart);
		}
		in.close();
		for (int v = 0; v < PLAYER_ALL; v++) {
			winner[v] = s.type(seat[v]);
		}
		int maximum = s.max(winner);
		for (int v = 0; v< PLAYER_ALL; v++) {
			if(maximum == winner[v]) System.out.print("获胜者为"+(v+1)+"号位置"+seat[v].pName+"玩家");
		}
	}
}

运行结果大致符合题目要求,但存在如下问题:
1.当玩家选择放弃游戏后,在系统询问是否继续游戏时仍需输入Y/N(随意输入,系统不再发牌至该座位玩家)。
2.五轮发牌结束前过早地出现全部玩家放弃的情况,系统无法正常运行。
3.一轮游戏结束后需要重新运行程序才可以开始下一轮游戏。
4.为了简化程序,未考虑异常输入对程序运行带来的影响。
5.······

猜你喜欢

转载自blog.csdn.net/MaaaMalik/article/details/82963686
今日推荐