手记

Java入门第三季第7章 综合实战- 简易扑克牌游戏

Reference:这位老哥的 AllenRp的手记
耗时:三天(痛苦😨…)

思路(Workload):

1.创建player对象,仅仅包含最基本的属性,不包含创建玩家的方法(基本属性:玩家id、玩家姓名和玩家所持有的poker集)
实际编写中,将其设置为private属性,对于调用还是不怎么习惯,尤其是考虑玩家手牌,getter()方法事实上只是返回player的手牌集合,而不需要setter()方法来设置手牌;另外,针对于player对象的equals()和toString()方法也进行了针对性的改写;

2.同样的Poker对象,仅仅针对poker的两个属性(花色 和数字)初始化了一些数组,比如对字符串"梅花,方片,红桃,黑桃"和"2,3,4,5,6,7,8,9,10,J,Q,K,A"了数组的拆分,字符串常用的方法见:String方法必知必会 改写了toString()方法;

3.创建游戏类,在游戏类中实现了很多针对于玩家和poker的设置

玩家:创建玩家列表list,针对用户输入游戏ID增加了一个Exception的报错,规定输入int型,若不是,报错提醒并回去继续接受键盘输入,同时展示玩家信息(用到player的toString改写方法)
Notice:针对报错部分,这里如果写不好,会出现一个死循环。可使用nextLine()吸收System.out.println()中的ln 换行

Poker:创建原始的扑克牌集合并且展示扑克牌(考虑到不会转化数组,就用笨办法,前n-1个输出为card+“,”,最后一个card+“]”不用加“,”), cardList就是原始的poker对象的list,这里就用到泛型<@Poker>
之后就是发牌,这时候就需要将card加入到player手中的集合(Set–无序不重复)
展示玩家发到的牌,开始游戏决出胜者,这时候set就头疼了,需要list才能排序,用到了Comparator临时比较接口。
将各玩家最大的card集合在一起,找出其中最最大,得到最最大card的索引位置,从而得到拥有最最大card的玩家的姓名

完结🌈~~~~~~

收获的知识点:

1.私有属性的get/set
2.类的构造方法的意义,初始化(无参不写,会报错nullpointer)
3.改写方法(equals和toString)
4.List和Set的基本操作
5.Exception知识点的回顾
6.针对list中contains方法,用来判断id/姓名的重复!!就用到改写的equals()方法
7.死循环的应用,continue和break的结合
8.nextLine和next的区别
9.在另外一个类中引入其他对象,从而完成对象属性的初始化
10.遍历list
11.学会在一个方法中调用另一个方法
12.排序,学会用自定义的方法排序,poker就要两种属性,比较是有原则,使用comparator接口,重写compare方法 sort(list,comparator)

困惑

1、定义了comparator比较规则,compare(o1,o2)所返回的值为什么能决定list的排列顺序?自己该如何根据多重属性进行对象的排序?
2、在game类中定义了public的Scanner类,同时在构造方法完成了初始化,应该在整个class应该都适用,为啥在main()中直接调用,程序就无法执行,无法一劳永逸?

代码

player类:

package com.imooc.game;

import java.util.*;

public class Player {
	//创建玩家基本属性 id name 手牌
	private int playerId;
	private String playerName;
	private Set<Poker>playerCard;
	
	//玩家id需要自己输入
	public Player(int playerId,String playerName) {
		playerCard = new HashSet<Poker>();//玩家手牌集合
	}
	
	public Player() {//无参构造器
		playerCard = new HashSet<Poker>();//玩家手牌集合
	}
	
	public int getPlayerId() {//获取玩家Id
		return playerId;
	}
	public void setPlayerId(int playerId) {//设置玩家Id
		this.playerId = playerId;
	}
	public String getPlayerName() {//获取玩家姓名
		return playerName;
	}
	public void setPlayerName(String playerName) {//设置玩家姓名
		this.playerName = playerName;
	}
	
	public Set<Poker> getPlayerCard() {//获取玩家手牌
		return playerCard;
	}
	
//	public void setPlayerCard(Set<Poker> playerCard) {
//		this.playerCard = playerCard;
//	}
	

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + playerId;
		result = prime * result + ((playerName == null) ? 0 : playerName.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof Player))
			return false;
		Player other = (Player) obj;
		if (this.getPlayerId() == other.getPlayerId())//只要id相同
			return true;
		if (this.getPlayerName() == null) {
			if (other.getPlayerName() != null)
				return false;
		} else if (!this.getPlayerName().equals(other.getPlayerName()))//只要姓名相同
			return false;
		return true;
	}
	
	@Override
	public String toString() {
		return ""+playerId+"."+playerName;
	}
}

Poker类:

package com.imooc.game;
import java.util.*;
/**
 * 定义实例变量 :扑克牌花色、点数
 *
 */
public class Poker {
	
	//花色和点数数组化
	private String baseKind = "梅花,方片,红桃,黑桃";
	private String baseNumber = "2,3,4,5,6,7,8,9,10,J,Q,K,A";
	private String[] cardKindList = baseKind.split(",");
	private String[] cardNumberList = baseNumber.split(",");
	
	private String cardKind;
	private String cardNumber;
	
	public Poker(String cardKind,String cardNumber) {
		//初始化poker对象具有的属性
		this.cardKind = cardKind;
		this.cardNumber = cardNumber;
		
	}
	public Poker() {
	
	}
	//访问属性
	public String getCardKind() {
		return cardKind;
	}
	public String getCardNumber() {
		return cardNumber;
	}

	//访问花色/数字 数组
	public String getBaseKind() {
		return baseKind;
	}
	
	public String getBaseNumber() {
		return baseNumber;
	}
	
	//访问poker集
	public String[] getCardKindList() {
		return cardKindList;
	}
	
	public String[] getCardNumberList() {
		return cardNumberList;
	}
	
	@Override
	public String toString() {
		return cardKind+cardNumber;
	}
}

主类(game)

package com.imooc.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.Set;


public class cardGame {
	
	private List<Player>playerList;
	private List<Poker>cardList;
//	public Scanner console;//创建Scanner属性
	
	
	public cardGame() {
		this.playerList = new ArrayList<Player>();
		this.cardList = new ArrayList<Poker>();
//		console = new Scanner(System.in);//初始化Scanner属性
	}
	
	
	
	/**
	 * 创建用户指定数量的玩家,输入int型的id,若不是则报错
	 * 同时注意id的不重复
	 */
	public void creatNewPlayer(int NumberOfPlayer) throws Exception {
		System.out.println("--------创建玩家------------");
		Scanner console = new Scanner(System.in);
		for(int i=0;i<NumberOfPlayer;i++) {
			while(true) {
				try {
					System.out.println("请输入用户ID:");
					int id = console.nextInt();	
					Player pl = new Player();
					pl.setPlayerId(id);
					if(!playerList.contains(pl)) {//id不重复,需要重写equals()
						while(true) {//检查姓名
							System.out.println("请输入对应的用户姓名:");
							String name = console.next();
							pl.setPlayerName(name);
							if(!playerList.contains(pl)) {//姓名不重复
								playerList.add(pl);
								break;
							}else {
								System.out.println("此用户名已存在!请重新输入!");
								continue;
							}
						}
					}else {
						System.out.println("此id已存在!请重新输入");
						continue;
					}	
				}catch(Exception e) {
					System.out.println("请输入正确的ID(数字)!");
					console.nextLine();//吸收enter
					continue;
				}
				break;
			}
		}
		//展示输入的玩家信息
		for (int i=0;i<playerList.size();i++) {
			System.out.println("欢迎玩家:"+playerList.get(i).toString());//toString改写
			//System.out.println("欢迎玩家:"+playerList.get(i).getPlayerId()+"."+playerList.get(i).getPlayerName());
		}
	}
	
	
	
	/**
	 * 创建poker并展示所创建的poker,同时将创建好的poker牌洗一下
	 */
	public void creatCardListAndShuffleCard() {
		System.out.println("--------创建扑克牌--------");
		//创建所有的扑克牌
		Poker pr = new Poker();//创建poker对象
		for (String kind : pr.getCardKindList()) {
			for (String num : pr.getCardNumberList()) {
				cardList.add(new Poker(kind,num));//加入到卡牌集合
			}
		}	
		System.out.println("--------创建完成----------");	
		
		//展示poker
		System.out.print("具体为:[");
		int i;
		for( i=0;i<cardList.size()-1;i++) {
			Poker poker = cardList.get(i);
			//System.out.print(poker.getCardKind()+poker.getCardNumber()+",");
			
			System.out.print(poker.toString()+",");//toString改写
		}
		Poker poker = cardList.get(i);
		//System.out.print(poker.getCardKind()+poker.getCardNumber());
		
		System.out.print(poker.toString());//toString改写
		System.out.println("]");
		
		shuffleCards(); //洗牌
	}
	 // 利用Collections类提供的shuffle方法完成随机洗牌
	public void shuffleCards() {
		System.out.println("------------开始洗牌-------------");
		Collections.shuffle(cardList);
		System.out.println("------------洗牌完成--------------");
		/*测试代码
		//展示poker
		System.out.print("具体为:[");
		int i;
		for( i=0;i<cardList.size()-1;i++) {
			Poker poker = cardList.get(i);
			System.out.print(poker.getCardKind()+poker.getCardNumber()+",");
		}
		Poker poker = cardList.get(i);
		System.out.print(poker.getCardKind()+poker.getCardNumber());
		System.out.println("]");
		*/
	}
	
	
	
	
	/**
	 *  各玩家依次取指定张数poker,加入到自己手牌set中
	 */
	public void giveCards(int NumberOfPlayer,int NumberOfCard) {
		System.out.println("-------开始发牌----------");
		for(int i=0;i<NumberOfCard;i++) {
			for(int j=0;j<NumberOfPlayer;j++) {//玩家依次拿牌
				System.out.println("玩家:"+playerList.get(j).getPlayerName()+"拿牌");
				playerList.get(j).getPlayerCard().add(cardList.get((j+i*NumberOfPlayer)));
				//利用setPlayerCard无法写出,但getter方法返回的也是玩家手牌set集
			}
		}
		System.out.println("-------发牌结束!--------------");
		
		//showCards(NumberOfPlayer);
	}
	
	
	/**
	 * 展示各玩家手中的手牌
	 * @param NumberOfPlayer
	 */
	public void showCards(int NumberOfPlayer) {
		System.out.println("玩家的各自手牌为:");
		for(int i=0;i<NumberOfPlayer;i++) {
			System.out.print(playerList.get(i).getPlayerName()+":");
			for (Poker poker : playerList.get(i).getPlayerCard()) {
				System.out.print(poker.toString());
			}
			System.out.println();//换行
		}
	}
	
	
	/**比赛
	 * 显示玩家最大手牌
	 * 比较手牌决出胜者
	 * @param 
	 */
	List<Poker>maxPoker = new ArrayList<Poker>();//用于存入每个玩家的最大手牌
	
	public void maxCardAndWin(int NumberOfPlayer) {
		System.out.println("---------开始游戏------------");
		for (int i=0; i<NumberOfPlayer; i++) {
			//set无法用sort排序,麻烦放弃
//			Set<Poker> sortSet = new TreeSet<Poker>(new PokerComparator());
//			sortSet.addAll(pr.getPlayerCard());
			
			//转成list再排序
			List<Poker>pokerList =new ArrayList<Poker>(playerList.get(i).getPlayerCard());
			Collections.sort(pokerList, new PokerComparator());
			/*测试代码
			for (Poker poker : pokerList) {
				System.out.println(poker.toString());
			}
			*/
			System.out.println("玩家"+playerList.get(i).getPlayerName()+"最大手牌为:"+pokerList.get(pokerList.size()-1));
			maxPoker.add(i,pokerList.get(pokerList.size()-1));//i号玩家最大手牌插入maxPoker的i位置
		}
		//利用collections的max返回最大元素,再利用ArrayList的indexOf方法返回索引值
		
		/**测试代码
		System.out.println("-----------");
		for (Poker poker : maxPoker) {
			System.out.println(poker.toString());
		}
		*/
		Poker max = Collections.max(maxPoker, new PokerComparator());//比较器类
		int i = maxPoker.indexOf(max);
		System.out.println("-------Champion:"+playerList.get(i).getPlayerName()+"--------");
		
	}
	
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		cardGame cg = new cardGame();
		cg.creatCardListAndShuffleCard();//创建并洗牌
		System.out.println("输入玩家数量:");
		Scanner console = new Scanner(System.in);
		int NumberOfPlayer = console.nextInt();	
		System.out.println("输入各玩家持有的卡牌数量:");
		int NumberOfCard = console.nextInt();	
		cg.creatNewPlayer(NumberOfPlayer);
		cg.giveCards(NumberOfPlayer,NumberOfCard);  
		cg.maxCardAndWin(NumberOfPlayer);
		cg.showCards(NumberOfPlayer);  
		
		console.close();
		
	}

}

pokerComparator类:

package com.imooc.game;

import java.util.Comparator;

public class PokerComparator implements Comparator<Poker> {

	@Override
	public int compare(Poker o1, Poker o2) {//按照花色和点色排序
		//等于0 相等;    大于0,o1比o2大;   小于0,o1比o2小
		// TODO Auto-generated method stub
		String o1_num = o1.getCardNumber();
		String o1_kind =o1.getCardKind();
		String o2_num = o2.getCardNumber();  //j q k 这种无法转化为数字
		String o2_kind =o2.getCardKind();
		Poker poker = new Poker();//利用子串在数组的位置进行排序
		if(poker.getBaseNumber().indexOf(o1_num)!=poker.getBaseNumber().indexOf(o2_num)) {//点数不等,直接比较
			return poker.getBaseNumber().indexOf(o1_num)-poker.getBaseNumber().indexOf(o2_num);
		}else {//点数相等,再比较花色(按照花色靠前大)
			return poker.getBaseKind().indexOf(o1_kind)-poker.getBaseKind().indexOf(o2_kind);
		}
	}

}
1人推荐
随时随地看视频
慕课网APP

热门评论

针对Scanner类困惑已经解决

main方法是静态方法,无法调用非静态变量

[静态方法](https://www.imooc.com/code/1843)

查看全部评论