目录
首先一副扑克牌是54张,这里我们去掉大小王,也就是52张扑克牌
有♣,♠,♥,◆,四种花色,每种花色对应1到13张
一.扑克牌的定义
1.牌的定义
我们定义一个Card类,来表示一张扑克牌,上面有花色suit和牌的值rank。
这里我重写了toString方法,方便我们打印每一张牌
这里我还重写了equals方法,如果判断两张牌是否相同,会用到
注意:如果没有重写equals方法,那么比较的就是两个Card是不是同一个对象,而不是花色和数值是否相同了,达不到我们想要的效果
/**
* Created with IntelliJ IDEA.
* User: 13498
* Date: 2021/12/10
* Time: 20:07
* Description: No Description
*/
public class Card {
String suit; //花色
int rank; //大小
public Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
@Override
public boolean equals(Object obj) {
if (obj == null){
return false;
}
if (!(obj instanceof Card)){
return false;
}
Card card = (Card)obj;
return this.suit.equals(card.suit) && this.rank == card.rank;
}
@Override
public String toString() {
return String.format("[%s %d]",suit,rank); //注意一下这种输出方式
}
}
2.玩家的定义
除了牌本身,我们还要对玩家进行定义,所以我们这里定义了一个Player类来表示玩家,每一个玩家都有手牌,我们用一个Card类型的顺序表来保存,注意这里的顺序表后面new了,也就是初始化了,这个不能少,不然后面还要专门为每个玩家的手牌初始化,会比较麻烦;同时,玩家还有一个姓名。
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: 13498
* Date: 2021/12/10
* Time: 20:24
* Description: No Description
*/
public class Player {
String name;
List<Card> cards = new ArrayList<>();
public Player(String name) {
this.name = name;
}
}
二.扑克牌的操作(初始化,洗牌,发牌等)
注:这里对每个功能及其实现方法进行讲解,后面有全部代码
1.初始化
初始化完成后,打印牌库中的牌是这样
initialiseCards(cards); //初始化52张手牌
对应方法的代码
public static void initialiseCards(List<Card> cards){
for (String s : new String[]{"♣","♠","♥","◆"}){
for (int i = 1; i <= 13 ; i++) {
cards.add(new Card(s,i));
}
}
}
这里使用了一个for each循环,大家也可以用两个for循环,效果是一样的
2.洗牌
我们可以对牌库里面的牌洗牌
和前面的不一样,牌库中牌的顺序被完全打乱
washCards(cards);//洗牌
对应方法的代码
public static void washCards(List<Card> cards) {
Random random = new Random();
for (int i = 0; i < cards.size(); i++) {
int toExchange = random.nextInt(cards.size());
Card tempCard = cards.get(i);
cards.set(i,cards.get(toExchange));
cards.set(toExchange,tempCard);
}
}
使用了random类,遍历整个cards顺序表,对于每个元素,不大于元素个数下标的随机数,让这个随机下标对应的元素与当前元素进行交换,从而实现洗牌的效果
3.发牌
比如我们有四个玩家,我们让他们依次抓牌,抓完后,可以查看他们的手牌
sendCardsToPlayers(players,cards); //将手牌分别发给不同的玩家,每人13张 printPlayersCards(players); //依次打印所有玩家手中的手牌
对应方法的代码
public static void sendCardsToPlayers(List<Player> players, List<Card> cards) {
for (Player player : players) {
for (int i = 0; i < 13; i++) {
Card card = cards.remove(0);
player.cards.add(card);
}
}
}
public static void printPlayersCards(List<Player> players) {
for (Player player : players) {
System.out.printf("玩家[%s]的手牌是:",player.name);
System.out.println(player.cards);
}
}
三.初始化,洗牌,发牌代码(全)
初始化,洗牌,发牌的全部代码,本人亲测能正常运行,注意这个类的类名是Main类,同时前面的Card类和Player类也要建好
简单说,一个包下面要有这三个类才行,Card类和Player类的代码在最前面文章开头给了
剩下的就是下面的Main类
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Card> cards = new ArrayList<>();
List<Player> players = new ArrayList<>();
players.add(new Player("Zebra"));
players.add(new Player("Pig"));
players.add(new Player("Dog"));
players.add(new Player("You"));
initialiseCards(cards); //初始化52张手牌
printCards(cards); //每行13张打印牌库中的牌
washCards(cards);//洗牌
printCards(cards); //每行13张打印牌库中的牌
sendCardsToPlayers(players,cards); //将手牌分别发给不同的玩家,每人13张
printPlayersCards(players); //依次打印所有玩家手中的手牌
}
public static void initialiseCards(List<Card> cards){
for (String s : new String[]{"♣","♠","♥","◆"}){
for (int i = 1; i <= 13 ; i++) {
cards.add(new Card(s,i));
}
}
}
private static void printCards(List<Card> cards) {
for (int i = 0; i < cards.size(); i++) {
System.out.print(cards.get(i)+",");
if ((i+1)%13 == 0){
System.out.println("");
}
}
}
public static void washCards(List<Card> cards) {
Random random = new Random();
for (int i = 0; i < cards.size(); i++) {
int toExchange = random.nextInt(cards.size());
Card tempCard = cards.get(i);
cards.set(i,cards.get(toExchange));
cards.set(toExchange,tempCard);
}
}
public static void sendCardsToPlayers(List<Player> players, List<Card> cards) {
for (Player player : players) {
for (int i = 0; i < 13; i++) {
Card card = cards.remove(0);
player.cards.add(card);
}
}
}
public static void printPlayersCards(List<Player> players) {
for (Player player : players) {
System.out.printf("玩家[%s]的手牌是:",player.name);
System.out.println(player.cards);
}
}
}
四.捉鬼游戏
下面我们来实现一个捉鬼游戏吧,游戏规则:
* Description: 捉鬼: * A-5 20张牌,去掉一张A * 五个人依次抓牌,直到把所有的牌都抓光。抓牌期间,一旦出现两张牌点数相同(凑成一对子了)就可以扔掉 * 正式游戏: * 一个回合一个回合进行: * 每个人(甲)抽取下家(乙)的一张随机手牌: * 1.如果乙的手牌被抽完了。则乙退出游戏 * 2.甲检查手中有没有凑成一-对,抽成了,还是把- -对扔掉,如果扔掉- -对后 手牌没有了,甲也退出 * 只到只剩一个人。抓到鬼了
新建一个GameCatchGhost类,记得要在刚刚那个有Card和Player的包下面建哦
游戏效果:
代码:亲测能正常运行
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: 13498
* Date: 2021/12/12
* Time: 16:34
* Description: 捉鬼:
* A-5 20张牌,去掉一张A
* 五个人依次抓牌,直到把所有的牌都抓光。抓牌期间,一旦出现两张牌点数相同(凑成一对子了)就可以扔掉
* 正式游戏:
* 一个回合一个回合进行:
* 每个人(甲)抽取下家(乙)的一张随机手牌:
* 1.如果乙的手牌被抽完了。则乙退出游戏
* 2.甲检查手中有没有凑成一-对,抽成了,还是把- -对扔掉,如果扔掉- -对后 手牌没有了,甲也退出
* 只到只剩一个人。抓到鬼了
*/
public class GameCatchGhost {
public static void main(String[] args) {
List<Card> cards = new ArrayList<>();
List<Player> players = new ArrayList<>();
players.add(new Player("Zebra"));
players.add(new Player("Pig"));
players.add(new Player("Dog"));
players.add(new Player("Cat"));
players.add(new Player("You"));
initialiseCards2(cards); //初始化19张牌,去掉一张A
washCards(cards);//洗牌
System.out.println("摸完牌以后,玩家中的手牌情况:");
sendCardsToPlayers(players,cards); //发牌,如果有两张一样的手牌就丢弃
printPlayersCards(players); //依次打印所有玩家手中的手牌
play(players); //玩捉鬼游戏
}
private static void sendCardsToPlayers(List<Player> players, List<Card> cards) {
while(cards.size() > 0){
for (int i = 0; i < players.size(); i++) {
if (cards.size() <= 0){ //如果牌发完了,要马上退出才行
break;
}
Player player = players.get(i);
Card nextCardToBePutIn = cards.remove(0);
putCardInOnePlayer(player,nextCardToBePutIn);
}
}
}
private static void play(List<Player> players) {
int t = 1;
while(players.size() > 1){
for (int i = 0; i < players.size(); i++) {
Player player = players.get(i);
if (player.cards.size() == 0){
System.out.println("****************************************玩家"+player.name+"手牌为空,退出");
players.remove(i);
}
Random random = new Random();
Player nextPlayer = players.get(i == players.size()-1 ? 0 : i+1);
if (nextPlayer.cards.size() == 0){ //如果下一个玩家的手牌为0,不用进行随机数生成,下面的不执行
System.out.println("****************************************玩家"+nextPlayer.name+"手牌为空,退出");
players.remove(nextPlayer);
continue;
}
int toDrawNextCardPos = random.nextInt(nextPlayer.cards.size());
Card nextCardtoBePutIn = nextPlayer.cards.get(toDrawNextCardPos);
System.out.println("第"+t+"轮,"+player.name+"抽了"+nextPlayer.name+"一张手牌"+nextCardtoBePutIn.toString());
putCardInOnePlayer(player,nextCardtoBePutIn);
printPlayersCards(players); //依次打印所有玩家手中的手牌
t++;
}
}
System.out.println("抓到鬼了!"+players.get(0).name+"是鬼,现在他的手牌是"+players.get(0).cards);
}
private static void putCardInOnePlayer(Player player,Card nextCardToBePutIn){
//传入一个玩家,和将要插入这个玩家的手牌,如果有重复,删除重复牌,没重复则插入
boolean flag = true;
for (int j = 0; j < player.cards.size(); j++) {
if (player.cards.get(j).rank == nextCardToBePutIn.rank){
//如果有重复的卡,那就把那张重复的也删除
player.cards.remove(j);
flag = false; //同时标记,现在这张卡不需要add
break;
}
}
if (flag){ //flag=true表示没有重复的卡,那就add进去
player.cards.add(nextCardToBePutIn);
}
}
private static void initialiseCards2(List<Card> cards){
for (String s : new String[]{"♠","♣","♥","◆"}){
for (int i = 1; i <= 5 ; i++) {
cards.add(new Card(s,i));
}
}
cards.remove(0);
}
public static void printPlayersCards(List<Player> players) {
for (Player player : players) {
System.out.printf("玩家[%s]的手牌是:",player.name);
System.out.println(player.cards);
}
}
public static void washCards(List<Card> cards) {
Random random = new Random();
for (int i = 0; i < cards.size(); i++) {
int toExchange = random.nextInt(cards.size());
Card tempCard = cards.get(i);
cards.set(i,cards.get(toExchange));
cards.set(toExchange,tempCard);
}
}
}
OK,就这些了,代码能运行无bug,如果有什么地方出错了或者有什么不懂都可以评论问我。