【Java小白】 简易扑克牌比大小游戏

背景

自学Java已有一周,决定开始做一个慕课里的小作业:简易扑克牌比大小
ps:我还真不会打牌…-_-||

游戏背景:两人每人随机发两张扑克牌(从同一副牌中),不考虑大、小王,每张牌包括花色(黑桃(Spade) > 红桃(Heart) > 梅花(Club) > 方片(Diamond))和大小(从小到大依次是:2-10,J,P,K,A),谁拥有最大的牌谁获胜,比较大小的规则是:点数相等比花色大小,否则比点数大小。

要求:需要做到输入两个选手的ID与姓名,给一副牌洗牌,分别发牌各两张,比较大小并输出。

涉及的知识点

  1. 面向对象程序设计、封装、继承、多态:将选手与扑克牌设计成类,实例化成对象;
  2. 输入输出;
  3. 数据结构 List 以及其自带的算法;
  4. 条件语句、循环结构;
  5. 异常处理:当输入的选手ID不是一个整数时,提示重新输入ID;
  6. 自定义比较大小规则:对接口类Comparable的compareTo()方法进行重写;
  7. 迭代器遍历容器:洗牌后逐个输出与初始状态对比;

源代码

第一个类 Card

package easypokergame;
import java.util.*;
public class Card implements Comparable<Card>{
    static String[] Points;
    static String[] FourSuits;
    static{
        Points=new String[]{"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
        FourSuits=new String[]{"方片","梅花","红桃","黑桃"};
    }
    public int PointsIndex;
    public int FourSuitsIndex;
    
    Card(int a,int b){
        PointsIndex=a;
        FourSuitsIndex=b;
    }
    public int getpoid(){
        return this.PointsIndex;
    }
    public int getfrstid(){
        return this.FourSuitsIndex;
    }
    static public void showcard(int a,int b){
        if(a<0||a>=13||b<0||b>=4)
        {
            System.out.println("Input Error!\nPlease input again!");
            Scanner inp=new Scanner(System.in);
            showcard(inp.nextInt(),inp.nextInt());
        }else{
            System.out.print(Card.FourSuits[b]+Card.Points[a]);
        }  
    }
    public void show(){
        System.out.println(Card.FourSuits[this.FourSuitsIndex]+Card.Points[this.PointsIndex]);
    }
    public void show2(){
        System.out.print(Card.FourSuits[this.FourSuitsIndex]+Card.Points[this.PointsIndex]);
    }
    //重写比较大小的方法
    @Override
    public int compareTo(Card o) {
       if(this.PointsIndex==o.getpoid()){
           if(o.getfrstid()>this.FourSuitsIndex)
               return 1;
           else
               return -1;
       }else{
           if(o.getpoid()>this.PointsIndex)
               return 1;
           else
               return -1;
       }
    }
            
}

第二个类 Player

package easypokergame;
import java.util.*;
public class Player {
   int id;
   String name;
   List<Card> Cards;
   public Player(int id,String name){
       this.id=id;
       this.name=name;
       Cards=new ArrayList();
   }
   public void AddCard(Card Acard){
       Cards.add(Acard);
   }
   public int getid(){
       return id;
   }
   public String getname(){
       return name;
   }
   public List<Card> getcards(){
       return this.Cards;
   }
   
}

第三个类,即主类 EasyPokerGame

package easypokergame;
import java.util.*;
public class EasyPokerGame {
    Player player1,player2;
    List<Card> Cards;
    //随机生成一副扑克牌
    public void CreatePokerCards(){
        System.out.println("-----------创建扑克牌-----------");
        Cards=new ArrayList();
        for(int i=0;i<13;i++)
            for(int j=0;j<4;j++)
                Cards.add(new Card(i,j));    
        System.out.println("-----------扑克牌创建成功!-----------");
        System.out.print("初始化为 :[");
         for(int i=0;i<4;i++)
             for(int j=0;j<13;j++)
             {
                 Card.showcard(j, i);
                 if(!(i==3&&j==12))
                      System.out.print(",");
                 else
                      System.out.println("]");
             }
        System.out.println("-----------开始洗牌-----------");
        Collections.shuffle(Cards); 
        Iterator it=Cards.iterator();
        System.out.print("洗牌后为 :[");
         while(it.hasNext()){
             Card cd=(Card)it.next();
             cd.show2();
             if(!it.hasNext())
                 System.out.println("]");
             else
                 System.out.print(",");
         }        
        System.out.println("-----------洗牌结束!-----------");
    }
    //输入玩家信息
    public void CreatePlayers(){
        System.out.println("-----------创建玩家...-----------");
        Scanner input=new Scanner(System.in);
        int id=0;
        String name="default";
        for(int i=0;i<2;i++){
            try{
                System.out.println("请输入第"+(i+1)+"位玩家的ID和姓名:");
                System.out.println("输入ID:");
                id=input.nextInt();
                System.out.println("输入姓名:");
                name=input.next();
                if(i==0)
                    player1=new Player(id,name);
                if(i==1)
                    player2=new Player(id,name); 
            }catch(InputMismatchException e){
                System.out.println("请输入整数类型的ID!");
                input.next();
                i--;
                continue;
             }    
        }
        System.out.println("------欢迎玩家:"+player1.getname());
        System.out.println("------欢迎玩家:"+player2.getname());
    }
    //发牌
    public void DistributeCards(){
        System.out.println("-----------开始发牌...-----------");
        for(int i=0;i<4;){
            player1.AddCard(Cards.get(i));
            System.out.println("------玩家:"+player1.getname()+"-拿牌");
            i++;
            player2.AddCard(Cards.get(i));
            System.out.println("------玩家:"+player2.getname()+"-拿牌");
            i++;
        }
        System.out.println("-----------发牌结束!-----------");
    }
    //两个玩家取出最大手牌相比较
    public void Compare(){
        System.out.println("-----------开始游戏...-----------");
        Collections.sort(player1.getcards());
        System.out.print("玩家:"+player1.getname()+"最大的手牌为:");
        player1.getcards().get(0).show();
        Collections.sort(player2.getcards());
        System.out.print("玩家:"+player2.getname()+"最大的手牌为:");
        player2.getcards().get(0).show();
        int pointindex1=player1.getcards().get(0).getpoid();
        int pointindex2=player2.getcards().get(0).getpoid();
        int suitindex1=player1.getcards().get(0).getfrstid();
        int suitindex2=player2.getcards().get(0).getfrstid();
        if((pointindex1==pointindex2&&suitindex1>suitindex2)||pointindex1>pointindex2)//点数相等比花色大小 否则比点数大小
            System.out.println("-----------玩家:"+player1.getname()+"获胜!-----------");
        else
            System.out.println("-----------玩家:"+player2.getname()+"获胜!-----------");
        System.out.println("玩家各自的手牌为:");
        System.out.print(player1.getname()+":[");
        player1.getcards().get(0).show2();
        System.out.print(",");
        player1.getcards().get(1).show2();
        System.out.println("]");
        System.out.print(player2.getname()+":[");
        player2.getcards().get(0).show2();
        System.out.print(",");
        player2.getcards().get(1).show2();
        System.out.println("]");
        System.out.println("-----------游戏结束!-----------");
    }
    public static void main(String[] args) {
        EasyPokerGame game=new EasyPokerGame();
        game.CreatePokerCards();
        game.CreatePlayers();  
        game.DistributeCards();
        game.Compare();
    }
    
}

代码执行结果

第一次:
输入第一位选手ID为:1,姓名为:Tom
输入第二位选手ID为:2,姓名为:Jack
结果如下:

run:
-----------创建扑克牌-----------
-----------扑克牌创建成功!-----------
初始化为 :[方片2,方片3,方片4,方片5,方片6,方片7,方片8,方片9,方片10,方片J,方片Q,方片K,方片A,梅花2,梅花3,梅花4,梅花5,梅花6,梅花7,梅花8,梅花9,梅花10,梅花J,梅花Q,梅花K,梅花A,红桃2,红桃3,红桃4,红桃5,红桃6,红桃7,红桃8,红桃9,红桃10,红桃J,红桃Q,红桃K,红桃A,黑桃2,黑桃3,黑桃4,黑桃5,黑桃6,黑桃7,黑桃8,黑桃9,黑桃10,黑桃J,黑桃Q,黑桃K,黑桃A]
-----------开始洗牌-----------
洗牌后为 :[方片A,梅花K,方片7,黑桃J,方片Q,梅花6,红桃2,黑桃2,黑桃10,红桃8,红桃7,方片9,黑桃K,梅花3,梅花J,梅花4,方片J,红桃10,黑桃A,黑桃8,梅花8,黑桃Q,红桃J,黑桃6,红桃4,黑桃7,方片10,红桃3,黑桃4,黑桃9,红桃Q,梅花9,红桃K,梅花Q,方片K,黑桃3,梅花10,红桃9,梅花7,梅花5,方片3,红桃5,黑桃5,梅花A,红桃A,梅花2,红桃6,方片5,方片4,方片6,方片2,方片8]
-----------洗牌结束!-----------
-----------创建玩家...-----------
请输入第1位玩家的ID和姓名:
输入ID:
1
输入姓名:
Tom
请输入第2位玩家的ID和姓名:
输入ID:
2
输入姓名:
Jack
------欢迎玩家:Tom
------欢迎玩家:Jack
-----------开始发牌...-----------
------玩家:Tom-拿牌
------玩家:Jack-拿牌
------玩家:Tom-拿牌
------玩家:Jack-拿牌
-----------发牌结束!-----------
-----------开始游戏...-----------
玩家:Tom最大的手牌为:方片A
玩家:Jack最大的手牌为:梅花K
-----------玩家:Tom获胜!-----------
玩家各自的手牌为:
Tom:[方片A,方片7]
Jack:[梅花K,黑桃J]
-----------游戏结束!-----------
成功构建 (总时间: 13)


第二次(测试一下异常处理):
尝试输入第一位选手ID为:pig
提示错误
然后输入第一位选手正确ID为:666,姓名为Anny
输入第二位选手的ID为:2333,姓名为Mark

run:
-----------创建扑克牌-----------
-----------扑克牌创建成功!-----------
初始化为 :[方片2,方片3,方片4,方片5,方片6,方片7,方片8,方片9,方片10,方片J,方片Q,方片K,方片A,梅花2,梅花3,梅花4,梅花5,梅花6,梅花7,梅花8,梅花9,梅花10,梅花J,梅花Q,梅花K,梅花A,红桃2,红桃3,红桃4,红桃5,红桃6,红桃7,红桃8,红桃9,红桃10,红桃J,红桃Q,红桃K,红桃A,黑桃2,黑桃3,黑桃4,黑桃5,黑桃6,黑桃7,黑桃8,黑桃9,黑桃10,黑桃J,黑桃Q,黑桃K,黑桃A]
-----------开始洗牌-----------
洗牌后为 :[黑桃4,方片4,方片8,黑桃3,梅花6,红桃K,梅花J,方片5,梅花7,梅花Q,红桃J,梅花K,红桃7,红桃A,方片J,方片6,黑桃7,红桃5,黑桃Q,红桃8,方片A,梅花10,红桃4,梅花2,红桃Q,梅花9,梅花8,方片3,黑桃5,黑桃A,方片2,方片K,梅花3,红桃10,方片Q,梅花4,黑桃8,黑桃6,黑桃10,红桃2,黑桃2,红桃6,红桃3,红桃9,方片9,方片7,方片10,黑桃K,梅花5,梅花A,黑桃J,黑桃9]
-----------洗牌结束!-----------
-----------创建玩家...-----------
请输入第1位玩家的ID和姓名:
输入ID:
pig
请输入整数类型的ID!
请输入第1位玩家的ID和姓名:
输入ID:
666
输入姓名:
Anny
请输入第2位玩家的ID和姓名:
输入ID:
2333
输入姓名:
Mark
------欢迎玩家:Anny
------欢迎玩家:Mark
-----------开始发牌...-----------
------玩家:Anny-拿牌
------玩家:Mark-拿牌
------玩家:Anny-拿牌
------玩家:Mark-拿牌
-----------发牌结束!-----------
-----------开始游戏...-----------
玩家:Anny最大的手牌为:方片8
玩家:Mark最大的手牌为:方片4
-----------玩家:Anny获胜!-----------
玩家各自的手牌为:
Anny:[方片8,黑桃4]
Mark:[方片4,黑桃3]
-----------游戏结束!-----------
成功构建 (总时间: 16)


注意事项

  1. 当异常处理放在循环结构内部,有时候会出问题,陷入死循环。通过查资料得知,这是由于Scanner接受键盘输入信息的机制所造成的后果:
    Scanner在接受键盘输入时,在内存中会有一段专门用来接收键盘输入的信息。键盘信息输入内存以后与你定义的接收输入的类型匹配,如果不匹配会抛出异常,但是键盘输入的信息会停留在内存当中,当下次需要输入时直接读取该内存存在的值,继续抛出异常,导致无限循环。
    解决方案详见 这篇博客
    java 输入流异常处理并重新输入,无限循环抛异常问题处理_liudliu1992的博客
    link.

我采用的方法是在捕获异常后,增加一句Scanner的对象.next(),以清空上一次输入所占用的内存

}catch(InputMismatchException e){
                System.out.println("请输入整数类型的ID!");
                input.next();
                i--;
                continue;
 }
  1. 使用迭代器,取出容器内元素拷贝构造另一个同类元素时:
Iterator it=Cards.iterator();
System.out.print("洗牌后为 :[");
while(it.hasNext()){
             Card cd=(Card)it.next();
             cd.show2();
             if(!it.hasNext())
                 System.out.println("]");
             else
                 System.out.print(",");
         }

第一句代码必须使用强制类型转换,原因在于,不用泛型类声明Iterator的话,从List容器所取出的元素统一是Object类型的,所以需要使用强制类型转换
而若使用泛型类,则不需要强制类型转换:

Iterator<Card> it=Cards.iterator();
System.out.print("洗牌后为 :[");
while(it.hasNext()){
             Card cd=it.next();
             cd.show2();
             if(!it.hasNext())
                 System.out.println("]");
             else
                 System.out.print(",");
         }

结尾碎碎念

作为Java小白,我还有很多需要学习的(๑• . •๑)
第一次发blog,也不知道自己有没有错误和纰漏呀!!
希望代码没事/双手合十,希望人没事2333…
欢迎大佬们来交流或是批评指正 !!

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值