翻牌模拟器 | Java

一、翻牌配对小游戏

1、玩家数量:2-4名。

2、需要道具:两两成对的牌若干。

3、游戏规则:游戏开始前,将牌洗乱,然后全部背面朝上放置在平面上。游戏开始后,每个人每次翻开两张牌,如果两张牌匹配,就可以把它们收走,否则要把两张牌翻回去。直至所有的牌都被拿走,此时统计每名玩家手中牌的数量,牌数多者为胜。

二、UNO

UNO是一种风靡全世界的常见桌游。玩家需在出剩最后1张牌时喊出”UNO“,故而得名。

博主写文于2023年1月24日,正是春节期间。

家里十分热闹,小孩很多,我常常带着他们一起玩各种游戏,包括但不限于藏与找东西、扑克牌、UNO、和平精英、穿越火线枪战王者、我的世界、飞行棋、卡坦拓荒、狼人杀等。是的,我刚刚提到了UNO。

23日晚上,我从UNO中去除了四张+4牌,两张改颜色牌,四张0牌,剩下98张牌。

我用这98张牌和他们玩翻牌配对的游戏。

这场大学生与初中生、小学生的比拼中,大学生取得了彻头彻尾的胜利,但大学生不满足于此。

当天晚上躺在床上,这个大学生的脑中,思考的是如何使用他的专业知识来设计一个翻牌游戏。

三、大学生的阴谋

其实这个大学生最初的目的不是完全设计出一个完整的翻牌游戏。

平日里他和善近人,是一个孩子王。谁知道,他是一个彻彻底底的阴谋家!

原来,他的目的是设计出翻牌游戏的版面。

他知道,只要提升了自己的记忆力,提升自己对游戏记忆的敏感程度,他就可以取得胜利!完完全全的胜利!!!

他太渴望胜利了(即使他玩这个游戏就没有输过),过去是,现在是,将来也是。

他的阴谋就是偷偷设计出模拟游戏情景的版面,然后用此来训练自己的记忆力,日后好一举击破他可怜的弟弟妹妹表弟表妹们脆弱不堪的心理防线!!!

理论存在,思路清晰,实践开始。

四、实现过程

1、生成牌组

按照上述提到的内容,首先要生成98张牌。代码如下:

public static String[] uno = new String[98];
public static char[] color = {'红','黄','蓝','绿'};
public static char[] number = {'1','2','3','4','5','6','7','8','9','转','禁','加'};

public static void GenerateCards(){
        int k=-1;
        for (int i=0; i<4; i++) {
            for (int j=0; j<12; j++) {
                k++;
                uno[k] = color[i] + String.valueOf(number[j]);
                k++;
                uno[k] = uno[k-1];
            }
        }
        uno[96] = "改"; uno[97] = "改";
    }

其中,“转”对应的是反转牌,“禁”对应的是禁止牌,“加”对应的是+2牌,“改”对应的是改颜色牌。

2、洗牌

最初我尝试生成1个随机数n(0≤n≤97),然后利用

for (int i=0; i<97; i++) {
    shuffle[i] = uno[i*n%97];
}
shuffle[97] = uno[97];

来实现洗牌。但是这种洗牌方式并不理想。

考虑加入布尔数组visit来确定牌是否已经被取走,在此基础上生成98个随机数来取牌,代码如下:

    //洗牌
    public static void ShuffleCards(){
        Random r = new Random();
        boolean[] visit = new boolean[98];
        //第一次洗牌
        String[] shuffle1 = new String[98];
        int k=0;
        Arrays.fill(visit, false);
        for (int i=0; i<98; i++) {
            int n = r.nextInt(97);
            while (visit[n]) {
                n = (n+1)%98;
            }
            shuffle1[k] = uno[n];
            visit[n] = true;
            k++;
        }
        //第二次洗牌
        String[] shuffle2 = new String[98];
        k=0;
        Arrays.fill(visit, false);
        for (int i=0; i<98; i++) {
            int n = r.nextInt(97);
            while (visit[n]) {
                n = (n+1)%98;
            }
            shuffle2[k] = shuffle1[n];
            visit[n] = true;
            k++;
        }
        //第三次洗牌
        String[] shuffle3 = new String[98];
        k=0;
        Arrays.fill(visit, false);
        for (int i=0; i<98; i++) {
            int n = r.nextInt(97);
            while (visit[n]) {
                n = (n+1)%98;
            }
            shuffle3[k] = shuffle2[n];
            visit[n] = true;
            k++;
        }
        //复制
        System.arraycopy(shuffle3, 0, uno, 0, 98);
    }

三次洗牌已经足够,如果需要,洗更多次当然也可以。

3、生成GUI与填牌

要阐释清楚还挺麻烦的,总之我希望的版面大概是这样:

翻牌模拟器 | Java_第1张图片

上面的牌有6行9列,共54张

(备注:不铺98张是因为场地有限,实际玩的时候不会一次性全部铺完;同时54和98满足54×2>98,有抽屉原理可知一定有解)

考虑设计54+3=57个按钮,每个按钮都有其对应的事件。

涉及到的代码有1099行,太多,就不打算放出来了。

五、成果

参考博主在b站发的视频,

【「Java」翻牌匹配模拟器的半成品=记忆力模拟器-哔哩哔哩】 https://b23.tv/4PFvvi0

六、总结反思

重复的工作太多,效率太低

6×9=54个按钮理应有统一实现,写一次代码足矣

但是我却写了54个addActionListener,浪费了巨多时间......

上次用C写了个数独游戏,这次用Java写了配对游戏

下次我会考虑用Python写的,刚好这学期我的大作业学的就是Pygame,专业对口了属于是

大概就这么多吧,博主去吃晚饭了

你可能感兴趣的:(奇思妙想,java)