用java写一个斗地主小游戏
时间: 2023-06-17 11:08:02 浏览: 192
好的,下面是一个简单的斗地主小游戏的实现,仅供参考:
```java
import java.util.*;
public class DouDiZhu {
private static final String[] CARD_TYPE = {"♠", "♥", "♣", "♦"};
private static final String[] CARD_NUMBER = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
private static final int CARD_NUM = 54; // 总牌数
private static final int LANDLORD_CARD_NUM = 3; // 地主牌数
private static final int PLAYER_NUM = 3; // 玩家数
private static final int PLAYER_TYPE_HUMAN = 1; // 玩家类型:人类玩家
private static final int PLAYER_TYPE_AI = 2; // 玩家类型:AI玩家
private static final int CARD_TYPE_JOKER = 0; // 牌类型:大小王
private static final int CARD_TYPE_NORMAL = 1; // 牌类型:普通牌
private static final int CARD_POINT_JOKER = 16; // 牌点数:小王、大王
private static final int CARD_POINT_START = 3; // 牌点数:普通牌的起点
private static final int GAME_OVER_POINT = 200; // 游戏结束点数
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
DouDiZhu game = new DouDiZhu();
game.startGame();
}
private Player[] players = new Player[PLAYER_NUM]; // 玩家数组
private List<Integer> cards = new ArrayList<>(); // 牌库
private int landlordIndex = 0; // 地主的索引
/**
* 开始游戏
*/
public void startGame() {
initPlayers(); // 初始化玩家
initCards(); // 初始化牌库
shuffleCards(); // 洗牌
allocateCards(); // 发牌
bidLandlord(); // 叫地主
playCards(); // 出牌
showResult(); // 展示结果
}
/**
* 初始化玩家
*/
private void initPlayers() {
for (int i = 0; i < PLAYER_NUM; i++) {
System.out.print("请输入玩家" + (i + 1) + "的名称:");
String name = scanner.nextLine();
int type;
do {
System.out.print("请选择玩家" + (i + 1) + "的类型(1:人类玩家,2:AI玩家):");
type = scanner.nextInt();
scanner.nextLine();
if (type != PLAYER_TYPE_HUMAN && type != PLAYER_TYPE_AI) {
System.out.println("无效的玩家类型,请重新输入。");
}
} while (type != PLAYER_TYPE_HUMAN && type != PLAYER_TYPE_AI);
players[i] = new Player(name, type);
}
}
/**
* 初始化牌库
*/
private void initCards() {
cards.clear();
for (int i = 0; i < CARD_NUM; i++) {
cards.add(i);
}
}
/**
* 洗牌
*/
private void shuffleCards() {
Collections.shuffle(cards);
}
/**
* 发牌
*/
private void allocateCards() {
int cardIndex = 0;
for (int i = 0; i < PLAYER_NUM; i++) {
List<Integer> playerCards = new ArrayList<>();
for (int j = 0; j < LANDLORD_CARD_NUM; j++) {
playerCards.add(cards.get(cardIndex++));
}
players[i].setCards(playerCards);
}
List<Integer> landlordCards = new ArrayList<>();
for (int i = cardIndex; i < cards.size(); i++) {
landlordCards.add(cards.get(i));
}
players[landlordIndex].addCards(landlordCards);
}
/**
* 叫地主
*/
private void bidLandlord() {
int bidIndex = 0;
int bidPoint = -1;
int bidCount = 0;
do {
Player player = players[bidIndex];
if (player.getType() == PLAYER_TYPE_HUMAN) {
System.out.print(player.getName() + ",请输入你的叫分(-1:不叫,0:不抢,1-3:叫分):");
bidPoint = scanner.nextInt();
scanner.nextLine();
} else {
bidPoint = player.bid();
System.out.println(player.getName() + "叫分:" + bidPoint);
}
if (bidPoint > 0) {
landlordIndex = bidIndex;
bidCount++;
}
bidIndex = (bidIndex + 1) % PLAYER_NUM;
} while (bidCount < 1 || bidIndex != landlordIndex);
players[landlordIndex].addCards(cards.subList(cards.size() - 3, cards.size()));
System.out.println(players[landlordIndex].getName() + "成为地主,地主牌为:" + getCardsString(players[landlordIndex].getLandlordCards()));
}
/**
* 出牌
*/
private void playCards() {
int currentPlayerIndex = landlordIndex;
int lastPlayerIndex = -1;
List<Integer> lastCards = new ArrayList<>();
int passCount = 0;
boolean gameOver = false;
while (!gameOver) {
Player currentPlayer = players[currentPlayerIndex];
List<Integer> currentCards;
if (currentPlayer.getType() == PLAYER_TYPE_HUMAN) {
System.out.print(currentPlayer.getName() + ",请输入你要出的牌(空格隔开,不出请输0):");
String input = scanner.nextLine();
if (input.equals("0")) {
currentCards = new ArrayList<>();
} else {
currentCards = parseCards(input);
}
} else {
currentCards = currentPlayer.play(lastCards);
System.out.println(currentPlayer.getName() + "出牌:" + getCardsString(currentCards));
}
if (currentCards.isEmpty()) {
passCount++;
} else {
passCount = 0;
}
if (passCount >= 2) {
lastPlayerIndex = -1;
lastCards.clear();
} else {
lastPlayerIndex = currentPlayerIndex;
lastCards = currentCards;
}
currentPlayer.removeCards(currentCards);
System.out.println(currentPlayer.getName() + "剩余的牌为:" + getCardsString(currentPlayer.getCards()));
if (currentPlayer.getCards().isEmpty()) {
gameOver = true;
}
currentPlayerIndex = (currentPlayerIndex + 1) % PLAYER_NUM;
}
int landlordScore;
if (lastPlayerIndex == landlordIndex) {
landlordScore = -getCardsScore(lastCards);
System.out.println(players[landlordIndex].getName() + "获胜,得分:" + landlordScore);
} else {
landlordScore = getCardsScore(lastCards);
System.out.println(players[lastPlayerIndex].getName() + "获胜,得分:" + landlordScore);
}
players[landlordIndex].addScore(landlordScore);
for (int i = 0; i < PLAYER_NUM; i++) {
if (i != landlordIndex) {
players[i].addScore(-landlordScore / 2);
}
}
}
/**
* 展示结果
*/
private void showResult() {
System.out.println("游戏结束,最终得分如下:");
for (Player player : players) {
System.out.println(player.getName() + ":" + player.getScore());
}
}
/**
* 解析牌
*/
private List<Integer> parseCards(String input) {
List<Integer> cardList = new ArrayList<>();
String[] cardStrings = input.split(" ");
for (String cardString : cardStrings) {
int cardIndex = Integer.parseInt(cardString) - 1;
cardList.add(cardIndex);
}
return cardList;
}
/**
* 获取牌的字符串表示
*/
private String getCardsString(List<Integer> cards) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cards.size(); i++) {
int cardIndex = cards.get(i);
sb.append(getCardString(cardIndex));
if (i < cards.size() - 1) {
sb.append(" ");
}
}
return sb.toString();
}
/**
* 获取牌的字符串表示
*/
private String getCardString(int cardIndex) {
int cardType = cardIndex / 13;
int cardNumber = cardIndex % 13;
if (cardType == CARD_TYPE_JOKER) {
return cardNumber == 0 ? "小王" : "大王";
} else {
return CARD_TYPE[cardType] + CARD_NUMBER[cardNumber];
}
}
/**
* 获取牌的点数
*/
private int getCardPoint(int cardIndex) {
int cardType = cardIndex / 13;
int cardNumber = cardIndex % 13;
if (cardType == CARD_TYPE_JOKER) {
return CARD_POINT_JOKER;
} else {
return cardNumber >= CARD_POINT_START ? cardNumber + 1 : CARD_POINT_START + cardNumber;
}
}
/**
* 获取牌的分数
*/
private int getCardsScore(List<Integer> cards) {
int score = 0;
for (Integer cardIndex : cards) {
score += getCardPoint(cardIndex);
}
return score;
}
/**
* 玩家类
*/
private class Player {
private String name; // 玩家名称
private int type; // 玩家类型
private List<Integer> cards = new ArrayList<>(); // 手牌
private List<Integer> landlordCards = new ArrayList<>(); // 地主牌
private int score; // 得分
public Player(String name, int type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public int getType() {
return type;
}
public List<Integer> getCards() {
return cards;
}
public void setCards(List<Integer> cards) {
this.cards = cards;
}
public void addCards(List<Integer> cards) {
this.cards.addAll(cards);
}
public void removeCards(List<Integer> cards) {
this.cards.removeAll(cards);
}
public List<Integer> getLandlordCards() {
return landlordCards;
}
public int getScore() {
return score;
}
public void addScore(int score) {
this.score += score;
}
/**
* AI玩家叫分
*/
public int bid() {
int maxPoint = -1;
for (int i = 0; i < cards.size(); i++) {
int cardIndex = cards.get(i);
int cardPoint = getCardPoint(cardIndex);
if (cardPoint > maxPoint) {
maxPoint = cardPoint;
}
}
int bidPoint = maxPoint >= 15 ? 3 : (maxPoint >= 12 ? 2 : 1);
if (bidPoint == 1) {
bidPoint = new Random().nextBoolean() ? 1 : 0;
}
return bidPoint;
}
/**
* AI玩家出牌
*/
public List<Integer> play(List<Integer> lastCards) {
List<Integer> currentCards;
if (lastCards.isEmpty()) { // 上一手牌为空,随便出牌
currentCards = findFirstValidCards();
} else if (lastCards.size() == 1) { // 上一手牌为单牌
currentCards = findValidSingleCards(lastCards.get(0));
} else if (lastCards.size() == 2 && lastCards.get(0).equals(lastCards.get(1))) { // 上一手牌为对子
currentCards = findValidPairCards(lastCards.get(0));
} else if (lastCards.size() == 3 && lastCards.stream().distinct().count() == 1) { // 上一手牌为三张
currentCards = findValidThreeCards(lastCards.get(0));
} else if (lastCards.size() == 4) { // 上一手牌为炸弹或四带二
currentCards = findValidFourCards(lastCards.get(0));
} else { // 上一手牌为顺子、连对或飞机
currentCards = findValidMultiCards(lastCards);
}
if (currentCards.isEmpty()) { // 没有符合要求的牌,只能随便出牌
currentCards = findFirstValidCards();
}
return currentCards;
}
/**
* 查找第一手合法牌
*/
private List<Integer> findFirstValidCards() {
List<Integer> validCards = new ArrayList<>();
validCards.addAll(findValidSingleCards(-1));
validCards.addAll(findValidPairCards(-1));
validCards.addAll(findValidThreeCards(-1));
validCards.addAll(findValidFourCards(-1));
validCards.addAll(findValidMultiCards(Collections.emptyList()));
return validCards;
}
/**
* 查找符合要求的单牌
*/
private List<Integer> findValidSingleCards(int lastCardPoint) {
List<Integer> validCards = new ArrayList<>();
for (int i = 0; i < cards.size(); i++) {
int cardIndex = cards.get(i);
int cardType = cardIndex / 13;
int cardNumber = cardIndex % 13;
int cardPoint = getCardPoint(cardIndex);
if (cardType != CARD_TYPE_JOKER && cardPoint > lastCardPoint) {
validCards.add(cardIndex);
}
}
return validCards;
}
/**
* 查找符合要求的对子
*/
private List<Integer> findValidPairCards(int lastCardPoint) {
List<Integer> validCards = new ArrayList<>();
for (int i = 0; i < cards.size() - 1; i++) {
int cardIndex1 = cards.get(i);
int cardIndex2 = cards.get(i + 1);
int cardType1 = cardIndex1 / 13;
int cardType2 = cardIndex2 / 13;
int cardNumber1 = cardIndex1 % 13;
int cardNumber2 = cardIndex2 % 13;
int cardPoint1 = getCardPoint(cardIndex1);
int cardPoint2 = getCardPoint(cardIndex2);
if (cardType1 != CARD_TYPE_JOKER && cardType1 == cardType2 && cardNumber1 == cardNumber2 && cardPoint1 > lastCardPoint) {
validCards.add(cardIndex1);
validCards.add(cardIndex2);
}
}
return validCards;
}
/**
* 查找符合要求的三张
*/
private List<Integer> findValidThreeCards(int lastCardPoint) {
List<Integer> validCards = new ArrayList<>();
for (int i = 0; i < cards.size() - 2; i++) {
int cardIndex1 = cards.get(i);
int cardIndex2 = cards.get(i + 1);
int cardIndex3 = cards.get(i + 2);
int cardType1 = cardIndex1 / 13;
int cardType2 = cardIndex2 / 13;
int cardType3 = cardIndex3 / 13;
int cardNumber1 = cardIndex1 % 13;
int cardNumber2 = cardIndex2 % 13;
int cardNumber3 = cardIndex3 % 13;
int cardPoint1 = getCardPoint(cardIndex1);
int cardPoint2 = getCardPoint(cardIndex2);
int cardPoint3 = getCardPoint(cardIndex3);
if (cardType1 != CARD_TYPE_JOKER && cardType1 == cardType2 && cardType2 == cardType3 && cardNumber1 == cardNumber2 && cardNumber2 == cardNumber3 && cardPoint1 > lastCardPoint) {
validCards.add(cardIndex1);
validCards.add(cardIndex2);
validCards.add(cardIndex3);
}
}
return validCards;
}
/**
* 查找符合要求的四张
*/
private List<Integer> findValidFourCards(int lastCardPoint) {
List<Integer> validCards = new ArrayList<>();
for (int i = 0; i < cards.size() - 3; i++) {
int cardIndex1 = cards.get(i);
int cardIndex2 = cards.get(i + 1);
int cardIndex3 = cards.get(i + 2);
int cardIndex4 = cards.get(i + 3);
int cardType1 = cardIndex1 / 13;
int cardType2 = cardIndex2 / 13;
int cardType3 = cardIndex3 / 13;
int cardType4 = cardIndex4 / 13;
int cardNumber1 = cardIndex1 % 13;
int cardNumber2 = cardIndex2 % 13;
int cardNumber3 = cardIndex3 % 13;
int cardNumber4 = cardIndex4 % 13;
int cardPoint1 = getCardPoint(cardIndex1);
int cardPoint2 = getCardPoint(cardIndex2);
int cardPoint3 = getCardPoint(cardIndex3);
int cardPoint4 = getCardPoint(cardIndex4);
if (cardType1 != CARD_TYPE_JOKER && cardType1 == cardType2 && cardType2 == cardType3 && cardType3 == cardType4 && cardNumber1
阅读全文