1、玩家数量:2-4名。
2、需要道具:两两成对的牌若干。
3、游戏规则:游戏开始前,将牌洗乱,然后全部背面朝上放置在平面上。游戏开始后,每个人每次翻开两张牌,如果两张牌匹配,就可以把它们收走,否则要把两张牌翻回去。直至所有的牌都被拿走,此时统计每名玩家手中牌的数量,牌数多者为胜。
UNO是一种风靡全世界的常见桌游。玩家需在出剩最后1张牌时喊出”UNO“,故而得名。
博主写文于2023年1月24日,正是春节期间。
家里十分热闹,小孩很多,我常常带着他们一起玩各种游戏,包括但不限于藏与找东西、扑克牌、UNO、和平精英、穿越火线枪战王者、我的世界、飞行棋、卡坦拓荒、狼人杀等。是的,我刚刚提到了UNO。
23日晚上,我从UNO中去除了四张+4牌,两张改颜色牌,四张0牌,剩下98张牌。
我用这98张牌和他们玩翻牌配对的游戏。
这场大学生与初中生、小学生的比拼中,大学生取得了彻头彻尾的胜利,但大学生不满足于此。
当天晚上躺在床上,这个大学生的脑中,思考的是如何使用他的专业知识来设计一个翻牌游戏。
其实这个大学生最初的目的不是完全设计出一个完整的翻牌游戏。
平日里他和善近人,是一个孩子王。谁知道,他是一个彻彻底底的阴谋家!
原来,他的目的是设计出翻牌游戏的版面。
他知道,只要提升了自己的记忆力,提升自己对游戏记忆的敏感程度,他就可以取得胜利!完完全全的胜利!!!
他太渴望胜利了(即使他玩这个游戏就没有输过),过去是,现在是,将来也是。
他的阴谋就是偷偷设计出模拟游戏情景的版面,然后用此来训练自己的记忆力,日后好一举击破他可怜的弟弟妹妹表弟表妹们脆弱不堪的心理防线!!!
理论存在,思路清晰,实践开始。
按照上述提到的内容,首先要生成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牌,“改”对应的是改颜色牌。
最初我尝试生成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);
}
三次洗牌已经足够,如果需要,洗更多次当然也可以。
要阐释清楚还挺麻烦的,总之我希望的版面大概是这样:
上面的牌有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,专业对口了属于是
大概就这么多吧,博主去吃晚饭了