最近用面向对象描述现实生活中斗地主的过程
要求如下:
1.一副扑克牌,三个人斗地主,判断是否可以叫地主:有王 || 2个以上的2 || 有炸弹
2.结合底牌判断谁最适合拿底牌(看谁配出的炸弹最多,如果配出的个数相同,则看谁配出的炸弹最大)
代码如下:
import static java.lang.Math.*;// 静态引用,在本文件中可以直接使用Math类中的静态方法,而不用Math.;
class Test1011
{
public static void main(String args[])
{
// 初始化一副牌
Pai p = new Pai();
// 定义三个人数组
Person person[] = new Person[3];
// 初始化斗地主三个人
for (int i = 0; i < person.length; i++)
{
person[i] = new Person(17, "玩家" + (i + 1));
}
// 轮流给三个人发牌
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < person.length; j++)
{
person[j].getPai(p.getPai());
}
}
// 分别输出三个人的牌,并进行判断是否满足叫地主的条件
for (int i = 0; i < person.length; i++)
{
// 1.打印牌
PrintArr.print(person[i].getPais());
// 2.判断
int res = person[i].isCall();
switch (res)
{
case 1:
System.out.println(" " + person[i].getName() + ":有王叫地主");break;
case 2:
System.out.println(" " + person[i].getName() + ":有两个以上的2叫地主");break;
case 3:
System.out.println(" " + person[i].getName() + ":有炸弹叫地主");break;
default :
System.out.println(" " + person[i].getName() + ":没有资格叫地主");
}
System.out.println();
}
// 找出三张底牌
String diPais[] = new String[3];
System.out.print("三张底牌是:");
for (int i = 0; i < diPais.length; i++)
{
diPais[i] = p.getPai();
System.out.print(diPais[i] + " ");
}
System.out.println();
// 结合底牌检查
for (int i = 0; i < person.length; i++)
{
person[i].checkDiPais(diPais);
}
// 对人进行排序
PrintArr.sort(person);
if (person[0].getBomCount() > 0)
{
// 炸弹的数量
int bomCount = person[0].getBomCount();
// 炸弹的值
int bomNumber = person[0].getBomNumber();
String name = person[0].getName();// 玩家的名字
String s = null;
switch (bomNumber)
{
case 16:
s = "王";break;
case 15:
s = "2";break;
case 14:
s = "A";break;
case 13:
s = "k";break;
case 12:
s = "Q";break;
case 11:
s = "J";break;
default :
s = bomNumber + "";
}
System.out.println(name + "最适合拿底牌,可以配出:" + bomCount + "个炸弹,最大的炸弹是:" + s + "炸");
} else
{
System.out.println("都不适合拿底牌");
}
}
}
class PrintArr
{
/*
* 对人进行排序
* 规则:
* 1.炸弹个数多的排在前面
* 2.如果两个配出的炸弹个数一样,则比较谁配出的炸弹最大
*/
public static void sort(Person person[])
{
for (int i = 0; i < person.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < person.length; j++)
{
if (person[j].getBomCount() > person[index].getBomCount())
{
index = j;
} else if (person[j].getBomCount() == person[index].getBomCount() && person[j].getBomNumber() > person[index].getBomNumber())
{
index = j;
}
}
Person temp = person[i];
person[i] = person[index];
person[index] = temp;
}
}
// 对字符串数组进行排序
public static void sort(String arr[])
{
for (int i = 0; i < arr.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < arr.length; j++)
{
if (arr[j].charAt(1) < arr[index].charAt(1))
{
index = j;
}
}
String temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}
// 打印字符串数组
public static void print(String arr[])
{
sort(arr);// 排序
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
class Person
{
private String pais[];// 牌
private String name;// 名字
private int num = 0;// 每个人牌的数量,抽一张牌加1
private int bomCount = 0;// 炸弹的数量,统计与底牌结合的属性
private int bomNumber = 0;// 炸弹的值,只是记录最大的炸弹
public Person(int size, String name)
{
this.name = name;
pais = new String[size];
}
// 得到一张牌
public void getPai(String pai)
{
this.pais[num++] = pai;
}
// 得到每种牌的数量,用于统计每个人牌的情况
public int[] getEveryPaiNum()
{
int nums[] = new int[14];
char pm = '\u0000';
for (int i = 0; i < this.pais.length; i++)
{
pm = pais[i].charAt(1);
switch (pm)
{
case '王':
nums[0]++;break;
case 'A':
nums[1]++;break;
case 'J':
nums[11]++;break;
case 'Q':
nums[12]++;break;
case 'K':
nums[13]++;break;
case '1':
nums[10]++;break;
default :
nums[pm - '0']++;
}
}
return nums;
}
/*
* 判断是否满足叫地主的条件
*
* return 0(不满足叫地主的条件)1(有王叫地主) 2(有两个以上的2)3(有炸弹叫地主)
*/
public int isCall()
{
int nums[] = this.getEveryPaiNum();
int res = 0;
for (int i = 0; i < nums.length; i++)
{
switch (i)
{
case 0:
if (nums[i] > 0)
{
res = 1;
}break;
case 2:
if (nums[i] > 2)
{
res = 2;
}
default :
if (nums[i] == 4)
{
res = 3;
}
}
}
return res;
}
// 检查底牌与自己牌的结合情况
public void checkDiPais(String diPais[])
{
// 得到原来牌的情况
int nums[] = this.getEveryPaiNum();
// 如果原来的牌有炸弹则清零
for (int i = 0; i < nums.length; i++)
{
// 王炸清零
if (i == 0)
{
if (nums[i] == 2)
{
nums[i] = 0;
}
}
// 其他的炸弹
else
{
if (nums[i] == 4)
{
nums[i] = 0;
}
}
}
// 结合底牌的统计
char pm = '\u0000';
for (int i = 0; i < diPais.length; i++)
{
pm = diPais[i].charAt(1);
switch (pm)
{
case '王':
nums[0]++;break;
case 'A':
nums[1]++;break;
case 'J':
nums[11]++;break;
case 'Q':
nums[12]++;break;
case 'K':
nums[13]++;break;
case '1':
nums[10]++;break;
default :
nums[pm - '0']++;
}
}
// 1.先看3-10 , J Q K的情况
for (int i = 3; i < 14; i++)
{
if (nums[i] == 4)
{
this.bomCount++;
this.bomNumber = i;
}
}
// 2.倒序统计 A 2 王 的情况
if (nums[0] == 2)
{
this.bomCount++;
this.bomNumber = 16;// 王炸
} else if (nums[2] == 4)
{
this.bomCount++;
this.bomNumber = 15;// 2炸
} else if (nums[1] == 4)
{
this.bomCount++;
this.bomNumber = 14;// A炸
}
}
public String[] getPais()
{
return this.pais;
}
public int getNum()
{
return this.num;
}
public String getName()
{
return this.name;
}
public int getBomCount()
{
return this.bomCount;
}
public int getBomNumber()
{
return this.bomNumber;
}
}
class Pai
{
private String[] pais;
private int num;
public Pai()
{
this.num = 54;
this.pais = new String[num];
// 初始化牌
initPais();
}
/*
* 初始化一副牌的方法
*
* 一张牌是一个字符串:由花色和牌面组成(如:方A)
*/
public void initPais()
{
String huase[] = {"方", "草", "红", "黑"};
// 生成四种花色的牌,每种花色分别为13张
for (int i = 0; i < 52; i++)
{
int indexH = i/13;// 花色的下标
int pm = i%13;// 牌面的值
String pai = huase[indexH];
switch (pm)
{
case 0:
pai += "A";break;
case 10:
pai += "J";break;
case 11:
pai += "Q";break;
case 12:
pai += "K";break;
default :
pai += (pm + 1);break;
}
this.pais[i] = pai;
}
this.pais[52] = "小王";
this.pais[53] = "大王";
}
/*
* 随机抽取一张牌
*/
public String getPai()
{
// 随机产生一个牌的下标
int index = (int)floor(random() * this.num);
String pai = this.pais[index];
// 把index后面的牌一次向前移动
for (int i = index; i < this.num - 1; i++)
{
this.pais[i] = this.pais[i + 1];
}
// 将牌的数量减减
this.num--;
return pai;
}
public String[] getPais()
{
return this.pais;
}
public int getNum()
{
return this.num;
}
}