Java基础之如何解决斗地主问题
难的是逻辑的分析,把逻辑转化成代码是一种能力,这种能力需要多练习总结。
多多指教,共同进步。
问题:
要求实现斗地主游戏发牌过程,打印三个玩家的牌和底牌。在不看底牌的情况下,统计出三个玩家的炸弹数;
S(small)代表小王,B(big)代表大王
-----------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------
思路分析:
全部用数字代表牌的大小和花色,这样可以方便的进行存储分发,只有在最终的打印牌的时候再进行实际的花色和大小的转化;
如何随机发牌,如何统计炸弹数量?
1,牌库包括54张牌,用二维数组进行存储4行14列(行代表花色,列代表牌的大小)
1)难点在于如何存储大小王
因为接下来是进行随机发放给三个人的,所以随便用两行的第14列来存储大小王,(也用数字代表大小王),剩下的两行的第14列置为空即可;
2)定义布尔类型的二维数组,也是4行14列,把牌库中有牌的下标置成true;
2,随机生成牌
随机生成数字0—3来控制行数,即牌的花色;
随机生成数字0—14来控制列数,即牌的大小;
3,随机分发牌
1)随机生成数字1—3,对3求余,0代表第一个人,1代表第二个人,2代表第三个人;
2)判断是否已经发出去了(用布尔数组进行判断,true代表没有发出去)
用一位数组存储发出去的花色,发出去后用布尔数组把下标置成false;同时计算发出去牌的数量;
3)同理为第二,第三个人随机发牌;
4)条件判断,当已经发出去51张牌时,跳出循环;
4,打印生成的牌和底牌
1)遍历布尔型数组和此时的牌库,找出下标和牌的大小,即可得到底牌;
2)用存储花色的一位数组和存储牌大小的一位数组进行遍历求生成的牌的花色和大小;
5,遍历统计每个人的炸弹数量
1)先统计大小王的个数,再进行双重循环遍历其他牌是否存在用炸弹;
2)同理,统计第二个人,第三个的;
代码实现:
import java.util.Random;
public class TestThree {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] zhangsan = new int[17];
int[] lisi = new int[17];
int[] wangwu = new int[17];
int[][] pai = new int[4][14];// 牌库
boolean[][] follow = new boolean[4][14];// 跟踪标记牌是否被发出去了
for (int i = 0; i < pai.length; i++)
for (int j = 0; j < pai[0].length - 1; j++) {
pai[i][j] = j + 1;
follow[i][j] = true;
}
pai[0][13] = 99;// 99代表小王
pai[1][13] = 100;// 100代表大王
follow[0][13] = true;// 默认是false,所有要设置成true
follow[1][13] = true;
int x = 0;
int y = 0;
int z = 0;
int count = 0;// 用来计算发出去的牌的数量
int[] zs = new int[17];// 张三
int[] ls = new int[17];// 李四
int[] ww = new int[17];// 王五
Random random = new Random();
while (true) {
int i = random.nextInt(4);// 产生0——3,代表牌的四种花色
int j = random.nextInt(14);// 产生0——13代表牌的大小
int a = (int) (random.nextInt(3) + 1);// 随机产生1,2,3三个整数,用来识别发牌的对象
if (a % 3 == 0) {// 代表张三
if (follow[i][j])// 表示这张牌没有被发出去
for (; x < zhangsan.length;) {
zhangsan[x] = pai[i][j];
follow[i][j] = false;// 表示这张牌已经发出去
zs[x] = i;// 记下牌的花色
count++;
x++;
break;// 退出for循环,进入while循环
}
} else if (a % 3 == 1) {// 代表李四
if (follow[i][j])
for (; y < lisi.length;) {
lisi[y] = pai[i][j];
follow[i][j] = false;
ls[y] = i;
count++;
y++;
break;
}
} else if (a % 3 == 2) {// 代表王五
if (follow[i][j])
for (; z < wangwu.length;) {
wangwu[z] = pai[i][j];
follow[i][j] = false;
ww[z] = i;
count++;
z++;
break;
}
}
if (count == 51)// 当发出51张牌的时候结束发牌
break;
}
System.out.println("张三的牌是:");
for (int i = 0; i < zhangsan.length; i++) {
print(zs[i], zhangsan[i]);// 打印张三的牌
}
System.out.println();
System.out.println("李四的牌是:");
for (int i = 0; i < lisi.length; i++) {
print(ls[i], lisi[i]);// 打印李四的牌(花色,牌的大小)
}
System.out.println();
System.out.println("王五的牌是:");
for (int i = 0; i < wangwu.length; i++) {
print(ww[i], wangwu[i]);// 打印王五的牌
}
System.out.println();
System.out.println("底牌是:");
for (int i = 0; i < pai.length; i++)
for (int j = 0; j < pai[0].length; j++) {
if (follow[i][j]) {
print(i, pai[i][j]);// 打印底牌
}
}
// 求每个人炸弹的个数
System.out.println();
int all1 = 0;// 计算张三的炸的个数
int all2 = 0;
int all3 = 0;
int king1 = 0;// 标记张三的王数量
int king2 = 0;
int king3 = 0;
for (int i = 0; i < zhangsan.length; i++) {
int count1 = 0;
int count2 = 0;
int count3 = 0;
// 判断张三的王炸
if (zhangsan[i] == 99 || zhangsan[i] == 100) {
king1++;
}
if (lisi[i] == 99 || lisi[i] == 100) {
king2++;
}
if (wangwu[i] == 99 || wangwu[i] == 100) {
king3++;
}
for (int j = i; j < zhangsan.length; j++) {
if (zhangsan[i] == zhangsan[j]) {
count1++;
if (count1 == 4) {
all1++;// 张三的炸+1
}
}
if (lisi[i] == lisi[j]) {
count2++;
if (count2 == 4) {
all2++;
}
}
if (wangwu[i] == wangwu[j]) {
count3++;
if (count3 == 4) {
all3++;
}
}
}
}
if (king1 == 2) {
all1++;// 判断张三是否有两个王
}
if (king2 == 2) {
all2++;
}
if (king3 == 2) {
all3++;
}
System.out.println("张三有" + all1 + "个炸");
System.out.println("李四有" + all2 + "个炸");
System.out.println("王五有" + all3 + "个炸");
}
public static void print(int num1, int num2) {
String s1 = "♥";
String s2 = "♠";
String s3 = "♦";
String s4 = "♣";
String s5 = "A";
String s6 = "J";
String s7 = "Q";
String s8 = "K";
String s9 = "S";// small表示小王
String s10 = "B";// big表示大王
// 判断花色
switch (num1) {
case 0:
System.out.printf("%-2s", s1);
break;
case 1:
System.out.printf("%-2s", s2);
break;
case 2:
System.out.printf("%-2s", s3);
break;
case 3:
System.out.printf("%-2s", s4);
break;
default:
break;
}
// 判断牌的大小
if (num2 == 1) {
System.out.printf("%-4s", s5 + " ");
} else if (num2 == 11) {
System.out.printf("%-4s", s6 + " ");
} else if (num2 == 12) {
System.out.printf("%-4s", s7 + " ");
} else if (num2 == 13) {
System.out.printf("%-4s", s8 + " ");
} else if (num2 == 99) {
System.out.printf("%-4s", s9 + " ");
} else if (num2 == 100) {
System.out.printf("%-4s", s10 + " ");
} else {
System.out.printf("%-4s", num2 + " ");
}
}
}
Java基础之如何解决斗地主问题的更多相关文章
- java基础(1)IntelliJ IDEA入门和数组操作 解决idea启动速度慢--配置JVM
一. IntelliJ IDEA入门 1 快捷键和技巧 智能补全代码,比如只写首字母按回车: psvm+Enter :public stactic void main(String[] args) s ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- 【JAVA面试题系列一】面试题总汇--JAVA基础部分
JAVA基础 基础部分的顺序: 基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法 线程的语法,集合的语法,io 的语法,虚拟机方面的语法 每天几道,持续更新!! 1.一个". ...
- 最适合作为Java基础面试题之Singleton模式
看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...
- Java基础知识【上】(转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- java基础知识小总结【转】
java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...
- 微冷的雨Java基础学习手记(一)
使用Java理解程序逻辑 之凌波微步 船舶停靠在港湾是很安全的,但这不是造船的目的 北大青鸟五道口原玉明老师出品 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识点时,要 ...
- 万能的林萧说:一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础”。
来历 本文来自于一次和群里猿友的交流,具体的情况且听LZ慢慢道来. 一日,LZ在群里发话,"招人啦." 然某群友曰,"群主,俺想去." LZ回之,"你 ...
随机推荐
- KMP详解
原文: http://blog.csdn.net/v_july_v/article/details/7041827 从头到尾彻底理解KMP 1. 引言 本KMP原文最初写于2年多前的2011年12月, ...
- yii打印sql
想打印Sql的话,可以用把你要执行的命令例如queryAll(),queryOne(),execute()换成getRawSql(); 例如 : 要看$result = Yii::$app->d ...
- How to copy remote computer files quickly to local computer
if we want copy file from VM(Remote VM) to local computer. Always can not easy copy file so easy. no ...
- Object 转化为String时的一个问题 null->"null"
近日在工作出了一个较大的问题,导致被客户投诉. 事情大致是,某个功能里新增对用户手机的修改,在平台数据同步过程中,出现了将用户以前的要同步的数据,那时还没有手机号码所以是null,新功能上线后,将手机 ...
- Oracle中rownum和rowid的理解(转)
本文转自地址http://www.linuxidc.com/Linux/2012-04/58300.htm rownum,rowid都叫伪列. 但是,rownum是逻辑上的编号,且其值总是从1开始,每 ...
- X86上搭建交叉工具链,来给龙芯笔记本编译本地工具链(未完待续)
故事的背景是,我买了一台龙芯2F的笔记本来装B. 为什么说是装B呢?因为不但操作系统是Linux,而且CPU还是龙芯的. 一般人有这么酷的装备吗?简直是装B大圣啊. 这里一定要申明一点,本人不是IT技 ...
- (转)Linux下root密码丢失和运行级别错误的解决办法
我们知道,root用户在Linux中是相当重要的,其地位如同Windows中的Adminstrator 有了root权限我们还能修改其他用户的密码,可是,如果root用户的密码丢失该怎么办? 不用担心 ...
- Windows 8.1 应用开发文章汇总
Windows 8.1 应用再出发 - C# + XAML 1. Windows 8.1 应用再出发 - 创建我的第一个应用 2. Windows 8.1 应用再出发 - 几种常用控件 3. Win ...
- Jquery Mobile 学习笔记(一)
1.模拟器,IOS:XCODE GENYMOTION ANDROID:ECLIPSE GENYMOTION 2.jquery mobile data-role=page 代表一个页面 data-po ...
- [转]Java学习日记之 volatile
用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...