初学Java,也是第一次码这么多代码。花了三天时间,比较慢,不求最快,本着尽量使用课上讲过的方法,同时也要求代码有一定的重用性。玩家数量可以自定义,只需更改一个参数即可。
下面从类结构阐述整个编程的思路:
1、PokersSuitAndFaces类,用来存放扑克牌的花色和牌面,通过SUIT和FACES两个静态数组来实现,并使用final修饰
public class PokersSuitAndFaces {
final static String[] SUIT = new String[]{"黑桃","红桃","梅花","方片"};
final static String[] FACES = new String[]{"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
}
2、Poker类,主要给poker对象定义了三个属性,suit(花色)、faces(牌面)、和pokerValue(牌值),其中牌值是一个2元素的数组,数组的元素是通过获取牌的花色和牌面在SUIT和FACES中对应的下标来得到的,方便对牌进行比较,同时Poker类还实现了Comparable接口,重写了compareTo()方法,可以对扑克牌进行自然排序。
public class Poker implements Comparable<Poker>{
private String suit; //花色
private String faces; //点数
//定义一个数组用来存放花色在SUIT中的下标和点数在FACES中的下标,用于比较牌的大小
private int[] pokerValue;
public Poker(String suit,String faces){
this.suit = suit;
this.faces = faces;
this.setPokerValue();
}
public Poker(){
}
public String getSuit() {
return suit;
}
public void setSuit(String suit) {
this.suit = suit;
}
public String getFaces() {
return faces;
}
public void setFaces(String faces) {
this.faces = faces;
}
public int[] getPokerValue() {
return pokerValue;
}
public void setPokerValue() {
int[] pv =new int[2];
for (int i = 0; i < PokersSuitAndFaces.SUIT.length; i++) {
if(this.getSuit().equals(PokersSuitAndFaces.SUIT[i])){
pv[0] = i; //存入花色在SUIT中的下标
break;
}
}
for (int i = 0; i < PokersSuitAndFaces.FACES.length; i++) {
if(this.getFaces().equals(PokersSuitAndFaces.FACES[i])){
pv[1] = i; //存入点数在SUIT中的下标
break;
}
}
this.pokerValue = pv;
}
@Override
public String toString(){
return this.getSuit() + this.getFaces();
}
/**
* 定义默认的排序规则
* @param o
* @return
*/
@Override
public int compareTo(Poker o) {
if(this.pokerValue[1] < o.pokerValue[1]){ //先比点数
return this.pokerValue[1] - o.pokerValue[1];
}
if(this.pokerValue[1] > o.pokerValue[1]){ //先比点数
return this.pokerValue[1] - o.pokerValue[1];
}
if(this.pokerValue[1] == o.pokerValue[1]){ //如果点数相等,再比花色
if(this.pokerValue[0] < o.pokerValue[0]){
return this.pokerValue[0] - o.pokerValue[0];
}
if(this.pokerValue[0] > o.pokerValue[0]){
return this.pokerValue[0] - o.pokerValue[0];
}
}else{
return 0;
}
return 0;
}
}
3、Gamer类,定义了玩家的ID、姓名、手牌和最大的牌四个属性,其中手牌属性通过ArrayList实现;定义了创建玩家的方法和输出玩家的一系列方法。
public class Gamer {
private int id; //玩家ID
private String name; //玩家姓名
private List<Poker> holdPokers; //玩家手牌
private Poker maxPoker; //玩家最大的
public Gamer(int id,String name){
this.id = id;
this.name = name;
holdPokers = new ArrayList<Poker>();
}
public Gamer(){
}
public int getId() {
return id;
}
public void setHoldPokers(List<Poker> holdPokers) {
this.holdPokers.addAll(holdPokers);//将传入的手牌追加到holdPokers的队尾
}
public String getName() {
return name;
}
public Poker getMaxPoker() {
return maxPoker;
}
public void setMaxPoker() {
this.maxPoker = Collections.max(this.holdPokers); //取得玩家手牌中最大的一张牌
}
/**
*创建一个玩家
*@return gamer 返回一个玩家对象
*/
private static Gamer createGamer(){
Scanner input = new Scanner(System.in);
System.out.println("请输入玩家ID:");
int id;
try {
id = input.nextInt();
} catch (InputMismatchException e) {
input.next();
System.out.println("玩家ID必须为正整数,请重新输入!");
return null;
}
System.out.println("请输入玩家姓名:");
String name = input.next();
Gamer gamer = new Gamer(id, name);
System.out.println("成功创建玩家:" + gamer.getName() + "\n");
return gamer;
}
/**
*创建玩家集
*@param gamersAmount 传入玩家数量
*@return gamers 玩家集
*/
public static Set<Gamer> createGamersSet(int gamersAmount){
Set<Gamer> gamers = new HashSet<Gamer>(); //创建玩家集
System.out.println("-------------需要创建"+gamersAmount+"名玩家-----------\n" );
for (int i = 0; i < gamersAmount; ) {
System.out.print("现在开始创建第"+(i+1)+"名玩家," );
Gamer gamer = new Gamer();
gamer = Gamer.createGamer();
if(gamer != null){
gamers.add(gamer);
i++;
}
}
return gamers;
}
/**
*打印玩家集
*@param gamers 玩家集
*
*/
public static void outGamers(Set<Gamer> gamers){
System.out.println("--------------欢迎" + gamers.size() + "位玩家--------------" );
for (Gamer gamer : gamers) {
System.out.println("玩家ID:" + gamer.getId() + " 玩家姓名:" + gamer.getName());
}
}
/**
*打印玩家手牌
*@param gamer 传入一个玩家
*
*/
public static void outGamerHoldPoker(Gamer gamer){
for (Poker poker : gamer.holdPokers) {
System.out.println("玩家" + gamer.getName() + "的第"
+ (gamer.holdPokers.indexOf(poker) + 1) + "张牌是:" + poker.toString());
}
System.out.println();
}
/**
*打印玩家集的手牌
*@param gamers 传入一个玩家集
*
*/
public static void outGamersHoldPoker(Set<Gamer> gamers){
for (Gamer gamer : gamers) {
Gamer.outGamerHoldPoker(gamer);
}
}
/**
*打印玩家最大的手牌
*@param gamer 传入一个玩家
*
*/
public static void outGamerMaxPoker(Gamer gamer){
System.out.println("玩家" + gamer.getName() + "最大的牌是:" + gamer.getMaxPoker());
}
/**
*打印玩家集最大的手牌
*@param gamers 传入一个玩家集
*
*/
public static void outGamersMaxPoker(Set<Gamer> gamers){
for (Gamer gamer : gamers) {
Gamer.outGamerMaxPoker(gamer);
}
}
}
4、 PokerGame类,为主类,主要定义了生成扑克牌、洗牌、发牌及开始游戏的方法,方法大多数为静态方法,通过类名可以直接调用。
public class PokerGame {
/**
*创建一副扑克牌(不含大小王)
*@param pokers 传入存放扑克牌的List
*/
public static void createPockers(List<Poker> pokers){
System.out.println("---------------创建扑克牌---------------");
for (int i = 0; i < PokersSuitAndFaces.SUIT.length; i++) {
for (int j = 0; j < PokersSuitAndFaces.FACES.length; j++) {
String suit = PokersSuitAndFaces.SUIT[i];//抽取花色
String faces = PokersSuitAndFaces.FACES[j];//抽取点数
Poker poker = new Poker(suit, faces);//新建一张牌
pokers.add(poker);
}
}
System.out.println("------------扑克牌创建成功!-----------" );
}
/**
*输出牌
*@param pokers 传入需要输出的扑克牌的List
*/
public static void outPokers(List<Poker> pokers){
//System.out.println("共有" + pokers.size() + "张牌。" );
int n = 0;
for (Poker poker : pokers) {
System.out.print(poker.toString() + "\t");
n++;
if(n == 13){
System.out.println();
n = 0;
}
}
System.out.println();
}
/**
*洗牌
*@param pokers 传入需要洗的扑克牌List
*@return sp 返回洗好牌的List
*/
public static List<Poker> shufflePokers(List<Poker> pokers){
System.out.println("---------------开始洗牌...-------------" );
Random random = new Random();
List<Poker> sp = new ArrayList<Poker>();
for (int i = 0; i < pokers.size(); i++) {
int k;
do{
k = random.nextInt(pokers.size());
}while(sp.contains(pokers.get(k))); //避免随机到重复的牌
sp.add(pokers.get(k));
}
System.out.println("---------------洗牌完成!--------------" );
return sp;
}
/**
*发牌
*@param pokers 传入待发的扑克牌List
*@param gamer 传入被发牌的玩家
*/
public static void dealPokers(List<Poker> pokers, Gamer gamer) {
System.out.println("玩家" + gamer.getName() + "拿牌...");
List<Poker> lp = new ArrayList<Poker>();
lp.add(pokers.get(0)); //抽取pokers的第一张牌给lp
pokers.remove(0); //抽取牌后从pokers中删掉抽取的牌
gamer.setHoldPokers(lp); //将lp追加到gamer的holdPoker中
gamer.setMaxPoker(); //每拿一次牌就找一次最大的牌
}
/**
*给一个玩家集发牌一次
*@param pokers 传入待发的扑克牌List
*@param gamers 传入被发牌的玩家集
*/
public static void dealPokerToGamers(List<Poker> pokers,Set<Gamer> gamers){
for (Gamer gamer : gamers) {
PokerGame.dealPokers(pokers, gamer);
}
}
/**
*开始游戏,定义游戏规则
*@param pokers 传入玩家集
*@return gamer 返回当前局的赢家
*/
public static Gamer gameStart(Set<Gamer> gamers){
System.out.println("---------------开始游戏!--------------");
//定义一个数组序列用来存放每名玩家的最大手牌
List<Poker> maxPokers = new ArrayList<Poker>();
for (Gamer gamer : gamers) {
maxPokers.add(gamer.getMaxPoker());
}
//打印玩家集最大的手牌
Gamer.outGamersMaxPoker(gamers);
//找出所有玩家中的最大一张牌
Poker maxPokerForGamePoker = Collections.max(maxPokers);
for (Gamer gamer : gamers) {
//从maxPokers中找出持有最大的牌的玩家,就是赢家
if(maxPokerForGamePoker.equals(gamer.getMaxPoker())){
return gamer;
}
}
return null;
}
/**
* @param args
* @author Yangyang
* @version 1.0
*
*/
public static void main(String[] args) {
List<Poker> pokers = new ArrayList<Poker>(); //创建一个ArrayList,用来存放扑克牌
PokerGame.createPockers(pokers); //创建一副扑克牌
PokerGame.outPokers(pokers); //打印整副牌
List<Poker> sp = PokerGame.shufflePokers(pokers); //洗牌
// PokerGame.outPokers(sp); //打印洗好的牌
Set<Gamer> gamers = new HashSet<Gamer>(); //创建一个HashSet,用来存放玩家
gamers = Gamer.createGamersSet(2); //创建2名玩家
Gamer.outGamers(gamers); //打印玩家
System.out.println("---------------开始发牌!--------------");
PokerGame.dealPokerToGamers(sp, gamers); //第1轮发牌
PokerGame.dealPokerToGamers(sp, gamers); //第2轮发牌
System.out.println("---------------发牌完成!--------------");
Gamer winner = PokerGame.gameStart(gamers); //获取赢家
System.out.println("---------------玩家" + winner.getName() +"获胜!---------------");
System.out.println("玩家各自的手牌为:");
Gamer.outGamersHoldPoker(gamers); //打印玩家手牌
}
}
运行效果展示