编程练习:斗地主 洗牌、发牌机制。涉及基础知识:1.继承 2.数组对象 (练习,可省略3.重写toString、hashCode、equals)
斗地主 洗牌、发牌机制
需求:
- 1.创建Card类,定义花色suit和点数rank的属性,添加相应的构造方法,在Card中覆盖toString,hashCode,equals方法
- 2.创建玩家类 Player类 ,定义名字name ,手牌 cards (Card[]),添加相应的构造方法,在Player中覆盖toString,hashCode,equals方法
- 3.创建一副扑克牌,54张
- 4.实现洗牌
- 5.实现轮流发牌
- 6.最终结果需要看到XXX手上的牌:[XXX,XXXX,XXXX…]
1.创建Card类,定义花色suit和点数rank的属性。
- 添加相应的构造方法,在Card中覆盖toString,hashCode,equals方法
public class PlayCard {
String[] suit = {"♠","♥","♣","♦"};
String[] rank = {"3","4","5","6","7","8","9","10","J","Q","K","A","2","小王","大王"};
public PlayCard() {
super();
}
public PlayCard(String[] suit, String[] rank) {
super();
this.suit = suit;
this.rank = rank;
}
//在Card中覆盖toString,hashCode,equals方法(练习,与题目无关,可忽略)
public String toString() {
String str = Arrays.toString(suit)+Arrays.toString(rank);
return str;
}
public int hashCode() {
System.out.println("扑克牌!");
return 0;
}
public boolean equals (Object obj) {
//判断obj是否为空
if (obj==null) {
return false;
}
//判断obj是否是this本身
if (obj==this) {
return true;
}
//判断obj是否和this本身类有关
if (obj instanceof PlayCard) {
return true;
}
//其他全为false
return false;
}
2.创建玩家类 Player类 ,定义名字name ,手牌 cards (Card[])
- 添加相应的构造方法,在Player中覆盖toString,hashCode,equals方法。
class Player extends PlayCard {
String name;
String[] cards;
public Player() {
super();
}
public Player(String name) {
super();
this.name = name;
}
public Player(String[] suit, String[] rank) {
super(suit, rank);
}
public Player(String name, String[] cards) {
super();
this.name = name;
this.cards = cards;
}
//在Player中覆盖toString,hashCode,equals方法(与题目无关)
public String toString() {
return name+cards;
}
public int hashCode() {
System.out.println("赌神!");
return 1;
}
public boolean equals(Object obj) {
//判断obj是否为空
if (obj==null) {
return false;
}
//判断obj是否是this本身
if (obj==this) {
return true;
}
//判断obj是否和this本身类有关
if (obj instanceof Player) {
return true;
}
//其他全为false
return false;
}
}
3.创建一副扑克牌,54张
public static void main(String[] args) {
PlayCard pc = new PlayCard();
//1.创建一副扑克牌,54张
String[] poke = new String[54];
//最后两张定义为大王小王
poke[52] = "小王"; poke[53] = "大王";
int n = 0;
//循环给poke牌赋值
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 13; j++) {
poke[n] = pc.suit[i]+pc.rank[j];
n++;
}
}
System.out.println("洗牌前:"+Arrays.toString(poke));
4.实现洗牌
- 注意随机数取出的元素和洗牌后的数组元素重复问题
//2.创建洗完牌后的poke2牌数组
String[] poke2 = new String[54];
Random rd = new Random();
A:for (int i = 0; i < poke2.length; i++) {
//取下标为 0-53的随机数,把牌数组下标元素赋值给洗完后的牌数组
int x = rd.nextInt(54);
poke2[i] = poke[x];
//去重,遍历新牌数组对比取出数组,重复了则i--返回A循环重新赋值,直到新牌数组赋值完成
for (int j = 0; j < i; j++) {
if (poke[x].equals(poke2[j])) {
i--;
continue A;
}
}
}
System.out.println("洗牌后:"+Arrays.toString(poke2));
5.实现轮流发牌
- 注意重复牌(元素)问题。
- 注意留三张底牌问题。
- 最终结果需要看到XXX手上的牌:[XXX,XXXX,XXXX…]
//创建三位玩家
Player pl1 = new Player("卢本伟");
Player pl2 = new Player("大司马");
Player pl3 = new Player("PDD");
//3.定义三个玩家手里牌数组,留三张底牌,每人17张牌
pl1.cards = new String[17];
pl2.cards = new String[17];
pl3.cards = new String[17];
for (int i = 0; i < poke2.length; i++) {
int x = rd.nextInt(54);
//定义发牌是随机的,所以前17张随机牌先给玩家1,后面以此类推
if (i<17) {
//随机牌为0则跳出循环重新随
if (poke2[x].equals("0")) {
i--;
continue ;
}else {
//牌堆数组里的随一张牌给玩家1,牌随出去后下标元素标记为0
pl1.cards[i] = poke2[x];
poke2[x] = "0";
}
}
//随的第17张到34张给玩家2
if (i >= 17 && i<34) {
int m = i-17;//让玩家2数组下标从0开始
if (poke2[x].equals("0")) {
i--;
continue ;
}else {
pl2.cards[m] = poke2[x];
poke2[x] = "0";
}
}
//同上
if (i >= 34 && i<51) {
int m = i-34;//让玩家3数组下标从0开始
if (poke2[x].equals("0")) {
i--;
continue ;
}else {
pl3.cards[m] = poke2[x];
poke2[x] = "0";
}
}
}
//创建三张底牌数组
String[] endCard = new String[3];
int p = 0;
//遍历发完牌的牌堆,不为0的赋值给底牌数组
for (int i = 0; i < poke2.length; i++) {
if (!poke2[i].equals("0")) {
endCard[p] = poke2[i];
p++;
}
}
System.out.println("发牌中.............");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发牌后:");
System.out.println(pl1.name+":"+Arrays.toString(pl1.cards)+"\n"
+pl2.name+":"+Arrays.toString(pl2.cards)+"\n"+pl3.name+":"+Arrays.toString(pl3.cards));
System.out.println("底牌是:"+Arrays.toString(endCard));
}
6.输出效果展示
