手记

Java入门第三季-扑克牌游戏

扑克牌游戏
.
我没去看其他人写的这个代码,所以这里是由自己发挥写的
当然我是跟着老师视频里,做好后演示的效果,一步一步去写
注意玩家数X玩家手牌量要在1-52这个范围内,毕竟只有52张牌


.
一共两个class文件,基本上把所有内容压缩在一个class文件内了
代码在下面的下面,这里先来一张目录性质的截图……

然后是效果演示图

接下来是代码(包名为Poker):
先看这个class文件,取名Poker.class
里面有三个属性,分别为:color(花色)、num(点数)、score(分值)
整副扑克牌就是装52个Poker元素的array list集合

package Poker;

public class Poker{
    public String color;//花色
    public String num;//点数
    public int score;//分值
    public Poker(String color,String num,int score) {
        this.color = color;
        this.num = num;
        this.score = score;
    }
}

Run.class
几乎整个游戏的代码都在这里面了
可以一个方法一个方法慢慢看,一个方法一个方法调用
要记住在开头定义的那些变量,比较好看懂

package Poker;

import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Run {
    Scanner sc = new Scanner(System.in);
    Random rd =new Random();
    int players = 2;//玩家数
    int n =2;//发给每位玩家的牌量
    List<Poker> pokerList = new ArrayList<Poker>();//整副扑克牌的集合
    int[] id = new int[players];//储存玩家ID
    String[] name = new String[players];//储存玩家Name
    Poker[][] poker = new Poker[players][n];//二维数组储存玩家手牌

    public static void main(String[] args) {
        Run run = new Run();
        run.creatPoker();//创建一副牌
        run.washPoker();//洗牌
        run.creatPlayer();//创建玩家
        run.deal();//发牌
        run.gameStart();//比较大小
        run.end();//展示手牌
    }

//-----//////////创建一副牌//////////-----//
    private void creatPoker() {
        //利用双重循环给pokerList添加整副扑克牌
        System.out.println("----创建扑克牌----");
        String[] color = {"黑桃","红心","梅花","方块"};
        String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
        for(int i=0;i<4;i++) {
            for(int j=0;j<13;j++) {
                Poker newPoker = new Poker(color[i],num[j],(3-i)+j*4+1);
                pokerList.add(newPoker);
            }
        }
        //for each循环输出整副扑克牌
        //利用size()-1获取ArrayList集合最后一个元素,将括号括回来
        System.out.print("-----创建成功-----\n为[");
        for (Poker pl : pokerList) {
            if(pl != pokerList.get(pokerList.size()-1))
                System.out.print(pl.color + pl.num + ",");
            else
                System.out.println(pl.color + pl.num + "]");
        }
    }

//-----//////////洗牌//////////-----//
    private void washPoker() {
        //利用一个临时的list来洗牌
        //利用随机数,随机pokerList中的一个元素,赋值给list
        //直到list里面无重复地赋满52个值
        System.out.println("-----开始洗牌-----");
        List<Poker> list = new ArrayList<Poker>();
        for(int i=0;i<52;i++) {
            Poker newPoker;
            do {
                int r = rd.nextInt(52);
                newPoker = pokerList.get(r);
            }while(list.contains(newPoker));
            list.add(newPoker);
        }
        //(此时的list是打乱的52张牌了)
        //再把list一一赋值给pokerList
        for(int ii=0;ii<52;ii++) {
            pokerList.set(ii,list.get(ii));
        }
        System.out.println("-----洗牌结束-----");
    }

//-----//////////创建玩家//////////-----//
    private void creatPlayer() {
        System.out.println("-----创建玩家-----");
        //要判断输入的ID是否整型、是否在1-52的范围内、是否重复
        List<Integer> playerList = new ArrayList<Integer>();//临时的玩家IDlist,用于判断玩家ID是否重复
        for(int i=0;i<players;i++) {
            System.out.println("请输入第" + (i+1) + "位玩家的ID和姓名:");
            System.out.print("请输入ID:");
            /*----------------------------------
             *下面这一整坨while循环真的有点复杂
             *首先请在id[i]=sc.next.Int()看起
             *输入的不是数字,直接跑catch里面去,再整个while循环
             *输入的范围超出,直接整个while重新循环
             *输入的id相同,则在do while里面循环一次
             *输入的没有问题,就会被playerList收录进去*/
            while(!(id[i]>=1&&id[i]<=52)) {
                try {
                    do {
                        if(playerList.contains(id[i]) == true) {
                            System.out.print("该ID已被使用,请重新输入:");
                        }
                        id[i] = sc.nextInt();
                        if(id[i]<1||id[i]>52) {
                            System.out.print("请输入1-52的ID:");
                        }
                    }while(playerList.contains(id[i]));
                    if(id[i]>=1&&id[i]<=52) {
                        playerList.add(id[i]);
                    }
                }catch(InputMismatchException e) {
                    System.out.print("请输入1-52的ID:");
                    sc.next();
                    id[i]=0;
                }
            }
            System.out.print("请输入姓名:");
            name[i] = sc.next();
        }
        for(int ii=0;ii<players;ii++){
            System.out.println("-----欢迎玩家"+ name[ii] +"-----");
        }
    }

//-----//////////发牌//////////-----//
    private void deal() {
        //既然洗过牌了,拿就从牌堆表面一张一张发给玩家就行了
        System.out.println("-----开始发牌-----");
        int a = 0;
        for(int i=0;i<n;i++) {
            for(int j=0;j<players;j++) {
                poker[j][i] = pokerList.get(a);
                a++;
                System.out.println("---玩家" + name[j] + "-拿牌");
            }
        }
        System.out.println("-----发牌结束-----");
    }

//-----//////////比较大小//////////-----//
    private void gameStart() {
        System.out.println("-----开始游戏-----");
        int[] scores = new int[players];//用于记录每位玩家的最高分值
        int win = 0;//用于判断赢家
        for(int i=0;i<players;i++) {
            int a = 0;//用于记录目前这张牌的分值
            Poker b = pokerList.get(0);//用于记录目前这张牌的花色和点数
            for(int j=0;j<n;j++) {
                //下面这个if意思是:
                //如果这张牌的分值比a大,则用a和b记录这张牌
                //最后在这个for循环结束后,a和b记录的牌就是玩家手牌里最大的那张牌
                if(poker[i][j].score > a) {
                    a = poker[i][j].score;
                    b = poker[i][j];
                }
            }
            scores[i] = a;
            System.out.println("玩家:" + name[i] + "最大的手牌为:" + b.color + b.num);
            if(scores[i]>win) {
                win = scores[i];
            }
        }
        for(int ii=0;ii<players;ii++) {
            if(scores[ii] == win) {
                System.out.println("-----玩家:" + name[ii] + "获胜-----");
            }
        }
    }

//-----//////////展示手牌//////////-----//
    private void end() {
        System.out.println("玩家各自的手牌为:");
        for(int i=0;i<players;i++) {
            System.out.print(name[i] + ":[");
            for(int j=0;j<n;j++) {
                if(j!=n-1) {
                    System.out.print(poker[i][j].color + poker[i][j].num + ",");
                }
                else {
                    System.out.println(poker[i][j].color + poker[i][j].num + "]");
                }
            }
        }
    }
}

其实,如果实在看着晕,照着把代码打一遍就懂了
**难点有两个:
1.创建玩家的ID:
要求ID只能在一些数字范围,
输入还要用异常接收保证其输入的有效性,
还要考虑玩家之间ID的是否重复
2.比较大小
怎么比较,我想到的就是利用分值,
方块A分值为1,梅花A分值为2,红心A分值为3,黑桃A分值为4
方块2分值为5,梅花2分值为6,红心2分值为7……………
然后挑选出玩家手里分值最高的
再进行玩家间比较大小

写完这东西后,写一些心得(是吐槽吧)
一开始有些迷茫,不知道要用hash map还是array list
于是我第一次用hash map写了出来,写是写出来
但是感觉代码很糟糕,于是改用array list 全部重写了
为什么我一开始用hash map来定扑克牌集合
是因为hash map的Key值可以很好的比较大小
反正后来改用array list,在集合类里多定个int变量就可以解决了
总之,写这个游戏,三分之一的时间在想这该死的比较大小
期间还考虑用comparator来自定义排序,
可是根本不知道怎么搞这个东西来给扑克牌集合排序
后来还想到用二位数组来存储玩家手牌
其实可以用array list来存储玩家手牌,
不过这个游戏的功能比较简单,只是比较所有手牌中谁的更大,
所以用二位数组来弄可以让代码简洁不少
真正认识到里程序的BUG真的是防不胜防
何况我还只是写这么一个简单的东西
在输入ID这个难点上真的是,总以为写好了,
乱输来乱输去,还是出了BUG...(当然最后我杀掉了这bug)

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

热门评论

真厉害啊,我才学20天,  要是能自己打的像你这么好就好了啊

操作了一遍,很有收获。

加入分值score不符合慕课网的要求吧,看完后,我想最初还是希望先用Compareable做为默认比较规则来比较数字,然后数字相同再启用Comparator做为临时规则比较花色吧

查看全部评论