java摸鱼小游戏之斗地主(一)


简介:
*** 敲代码无聊了吗,来一把激动人心的斗地主吧 ***
本篇内容重在熟练正则判断,以及学习创作思路使用,摸鱼是开玩笑的。

一。准备工作

这里我们先创建项目,做一些基础工作,例如创建实体之类的

1.实体

(1)首先就是扑克牌实体

这段都比较好理解(废话)
name -> 牌的名字,可以是单张牌,也可以是组合牌,例如 3 ,3334
value -》牌的面值,用于比较大小
type -》 牌的种类,区分单排,对子,之类的,这个主要是个ai用的
j_value -》这个什么值来着的忘了,当时想扩展ai功能的,后来没做了给忘了
size -》牌的长度,实际就是name字段的长度
show -》是否展示,这里出了牌,并不是从集合中去掉,而是让他不展示,至于好处吗,忘了当时为啥选择这个

@Data
public class Poker {

    private String name;

    private Integer value;

    private Integer type;

    private String j_value;

    private Integer size;

    private Boolean show = true;

    @Override
    public String toString(){
        return name;
    }
}

(2)然后就是游戏结束返回类

@Data
public class GameOverBean {

    /**
     * 游戏结束是否继续
     */
    private Boolean isContinue;

    /**
     * 胜利次数
     */
    private Integer winNum;

    /**
     * 失败次数
     */
    private Integer failNum;

    /**
     * 得分
     */
    private Integer score;
}

(3)出牌类

场上最大牌,就是 A 出6,B 不要,6就是最大牌,A 就是最大牌玩家

@Data
@Builder
public class OutPokerVo {

    /**
     * 自己的手牌
     */
    private String s;

    /**
     * 场上最大牌面的类型
     */
    private Integer type;

    /**
     * 场上最大牌面
     */
    private String max;

    /**
     * 场上最大牌的玩家
     */
    private String maxPlayer;
}

(4)玩家类

优先级就是用来比较出牌顺序的

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Player {

    private String name;

    /**
     * 队伍编号
     * 0 地主
     * 1 地主队伍
     * 2 农民队伍
     */
    private Integer troopsType;

    /**
     * 优先级
     */
    private Integer priority;

    public Integer getPriority(){
        if (troopsType == 0){
            return -1;
        }
        return priority;
    }
    
}

(5)桌面信息类

这个主要是给ai用,可以让ai更强大

@Data
public class TableTopInformation {

    /**
     * 自己的牌
     */
    private String s;

    /**
     * 当前最大牌面
     */
    private String max;

    /**
     * 当前最大牌面 玩家
     */
    private String maxPlayer;

    /**
     * 地主名称
     */
    private String diZhu;

    /**
     * 出牌顺序
     */
    private String shunXu;

    /**
     * 历史出牌
     * key -> 出牌人
     * value -> 所出牌,以逗号隔开,"-" 代表不出
     */
    private Map<String, String> map;

    /**
     * 队伍map
     * key -> 游戏人名称
     * value -> 队伍序号 0 地主 1 地主队 2 农民队
     */
    private Map<String, Integer> troopsMap;

    /**
     * 玩家手牌集合
     * key 玩家名
     * value 玩家对应的手牌
     */
    private Map<String,List<Poker>> playerPokerMap;

    /**
     * 玩家集合
     * 集合的顺序为出牌顺序
     */
    private List<Player> playerList;

    private List<Poker> poker;

    private String wanJiaName;

    /**
     * key 玩家名
     * value 是否显示该玩家的手牌
     */
    private Map<String,Boolean> mapSB;

    /**
     * 地主牌
     */
    private List<Poker> poker0;

    /**
     * 游戏玩家名称
     */
    private LinkedHashSet<String> player;

    /**
     * key 玩家名
     * value 玩家对应的出牌记录
     */
    private Map<String,StringBuilder> mapCP;

    /**
     * key 玩家名
     * value 玩家对于的电脑ai
     */
    private Map<String,Ai> aiMap;

    /**
     * 游戏结束返回类
     */
    private GameOverBean gameOverBean;

    /**
     * 获取下一个出牌的人
     * @return
     */
    public Player nextPlayer(String name){
        int i = 0;
        for (Player player : playerList) {
            if (player.getName().equals(name)){
                i = playerList.indexOf(player);
                break;
            }
        }
        if (i == playerList.size() - 1){
            return playerList.get(0);
        }else {
            return playerList.get(i + 1);
        }
    }

}

(6) ai类

这里是一个抽象类,因为可以做迭代,一代ai一代强
主要就是两个动作,出牌,抢地主(这个动作没做,工作忙没空做了,也不影响摸鱼运行)

@Data
public abstract class Ai {

    private Integer type;

    private String name;

    private TableTopInformation tableTopInformation;

    public abstract String outPoker(OutPokerVo vo);

    public abstract Boolean robDiZhu(String s);

}

2.主体与工具

这方面就有点多了,先来点基础的,逻辑我们下回再说

(1)刷屏方法

这里我们的界面就是idea控制台,所以需要一个清屏的方法

public static void clear() throws AWTException{
        Robot ro = new Robot();
        ro.delay(100);//延时
        ro.mousePress(InputEvent.BUTTON3_MASK);//单机鼠标右键
        ro.mouseRelease(InputEvent.BUTTON3_MASK);//松开右键
        ro.keyPress(KeyEvent.VK_CONTROL);//按ctrl键
        ro.keyPress(KeyEvent.VK_R);//按R
        ro.keyRelease(KeyEvent.VK_R);//松开R
        ro.keyRelease(KeyEvent.VK_CONTROL);//松开ctrl
        ro.delay(100);//延时
    }

(2)静态字段(包括一些正则表达式)

首先是两个基础静态字段,玩家 和 扑克牌

private static final List<String> game_player = new ArrayList<String>(){
        {
            add("吊炸天");
            add("拖拉机");
            add("煤炭");
            add("输不起");
            add("再来");
            add("你大爷");
            add("二愣子");
            add("最美富二代");
        }
    };

    public static final Map<String, Integer> valueMap = new HashMap<String, Integer>(){
        {
            put("3",3);
            put("4",4);
            put("5",5);
            put("6",6);
            put("7",7);
            put("8",8);
            put("9",9);
            put("X",10);
            put("J",11);
            put("Q",12);
            put("K",13);
            put("A",14);
            put("2",15);
            put("w",16);
            put("W",17);
        }
    };

其次是我们需要用到的正则表达是静态字符串
这个我写了两份,一个是在主体里面,二个是在判断工具里面,第二个是后来才提出来的,所以有些冗余,下面这个是主体里面的

/**
     * 测试
     */
    private static final String CANONICAL_test = "(\\d)\\1{2}";

    /**
     * 正则单牌
     */
    private static final String CANONICAL_NP = "[^2-9XJQKAWw\\-\\*]";

    /**
     * 正则单牌
     */
    private static final String CANONICAL_X = "[2-9XJQKAWw\\*]";

    /**
     * 正则对子
     */
    private static final String CANONICAL_XX = "([2-9XJQKAWw\\*])\\1{1}";

    /**
     * 正则三个
     */
    private static final String CANONICAL_XXX = "([2-9XJQKAWw\\*])\\1{2}";

    /**
     * 正则炸弹
     */
    private static final String CANONICAL_XXXX = "([2-9XJQKAWw\\*])\\1{3}";

    /**
     * 正则至少重复4次
     */
    private static final String CANONICAL_XXXX_Min = "([2-9XJQKAWw\\*])\\1{4,}";

    /**
     * 正则三带一
     */
    private static final String CANONICAL_XXXY = "([2-9XJQKAWw\\*])\\1{2}[2-9XJQKAWw\\*]";

    /**
     * 顺子
     */
    private static final String CANONICAL_ABCDE = "(3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=X)|X(?=J)|J(?=Q)|Q(?=K)|K(?=A)){4,}";
    /**
     * 顺子
     */
    private static final String CANONICAL_EDCBA = "((?<=3)4|(?<=4)5|(?<=5)6|(?<=6)7|(?<=7)8|(?<=8)9|(?<=9)X|(?<=X)J|(?<=J)Q|(?<=Q)K|(?<=K)A){4,}";

    /**
     * 连续 至少两次
     */
    private static final String CANONICAL_ABCDE_N = "(3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=X)|X(?=J)|J(?=Q)|Q(?=K)|K(?=A)){N,}";
    /**
     * 连续 至少两次
     */
    private static final String CANONICAL_EDCBA_N = "((?<=3)4|(?<=4)5|(?<=5)6|(?<=6)7|(?<=7)8|(?<=8)9|(?<=9)X|(?<=X)J|(?<=J)Q|(?<=Q)K|(?<=K)A){N,}";

下面这个是判断工具里面的

/**
     * 正则单牌
     */
    private static final String CANONICAL_NP = "[^2-9XJQKAWw\\-\\*]";

    /**
     * 正则单牌
     */
    private static final String CANONICAL_X = "[2-9XJQKAWw\\*]";

    /**
     * 正则对子
     */
    private static final String CANONICAL_XX = "([2-9XJQKAWw\\*])\\1{1}";

    /**
     * 正则至少N次重复
     */
    private static final String CANONICAL_XX_N = "([2-9XJQKAWw\\*])\\1{N,}";

    /**
     * 正则三个
     */
    private static final String CANONICAL_XXX = "([2-9XJQKAWw\\*])\\1{2}";

    /**
     * 正则炸弹
     */
    private static final String CANONICAL_XXXX = "([2-9XJQKAWw\\*])\\1{3}";

    /**
     * 正则至少重复4次
     */
    private static final String CANONICAL_XXXX_Min = "([2-9XJQKAWw\\*])\\1{4,}";

    /**
     * 正则三带一
     */
    private static final String CANONICAL_XXXY = "([2-9XJQKAWw\\*])\\1{2}[2-9XJQKAWw\\*]";

    /**
     * 顺子
     */
    private static final String CANONICAL_ABCDE = "(3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=X)|X(?=J)|J(?=Q)|Q(?=K)|K(?=A)){4,}";
    /**
     * 顺子
     */
    private static final String CANONICAL_EDCBA = "((?<=3)4|(?<=4)5|(?<=5)6|(?<=6)7|(?<=7)8|(?<=8)9|(?<=9)X|(?<=X)J|(?<=J)Q|(?<=Q)K|(?<=K)A){4,}";

    /**
     * 连续 至少两次
     */
    private static final String CANONICAL_ABCDE_N = "(3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=X)|X(?=J)|J(?=Q)|Q(?=K)|K(?=A)){N,}[3-9XJQKA]";
    /**
     * 连续 至少两次
     */
    private static final String CANONICAL_EDCBA_N = "((?<=3)4|(?<=4)5|(?<=5)6|(?<=6)7|(?<=7)8|(?<=8)9|(?<=9)X|(?<=X)J|(?<=J)Q|(?<=Q)K|(?<=K)A){N,}";

3.本片文章只是开始,太长了难得翻,下一篇将讲主体,游戏的运行逻辑,长话短说,下回见;下一篇

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值