深入探索 Java 实现的 21 点游戏
简介
21 点游戏(Blackjack)是一种广泛流行的纸牌游戏,在赌场和家庭聚会中都很常见。使用 Java 来实现 21 点游戏不仅能加深我们对 Java 编程的理解,还能锻炼我们的面向对象编程思维。本文将全面介绍 Java 实现 21 点游戏的相关内容,包括基础概念、使用方法、常见实践和最佳实践。
目录
- 基础概念
- 使用方法
- 常见实践
- 最佳实践
- 小结
- 参考资料
基础概念
21 点游戏规则
- 游戏目标是使手中牌的点数之和接近但不超过 21 点,超过 21 点则“爆点”输牌。
- 牌面点数:数字牌按牌面数字计算点数,J、Q、K 计为 10 点,A 可以计为 1 点或 11 点(取对玩家最有利的值)。
- 游戏流程:玩家和庄家各发两张牌,玩家可以选择“要牌”(Hit)或“停牌”(Stand),最后比较玩家和庄家的牌点数决定胜负。
Java 实现的关键类
- Card 类:表示一张扑克牌,包含牌面和花色信息。
- Deck 类:表示一副扑克牌,负责洗牌和发牌操作。
- Player 类:表示玩家或庄家,包含手中的牌和计算牌点数的方法。
- BlackjackGame 类:表示整个 21 点游戏,负责游戏流程的控制。
使用方法
环境准备
确保你已经安装了 Java 开发环境(JDK),可以使用任何 Java 开发工具,如 IntelliJ IDEA 或 Eclipse。
代码示例
// Card 类
class Card {
private String suit;
private String rank;
public Card(String suit, String rank) {
this.suit = suit;
this.rank = rank;
}
public String getSuit() {
return suit;
}
public String getRank() {
return rank;
}
@Override
public String toString() {
return rank + " of " + suit;
}
}
// Deck 类
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Deck {
private List<Card> cards;
public Deck() {
cards = new ArrayList<>();
String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
for (String suit : suits) {
for (String rank : ranks) {
cards.add(new Card(suit, rank));
}
}
shuffle();
}
public void shuffle() {
Collections.shuffle(cards);
}
public Card dealCard() {
return cards.remove(0);
}
}
// Player 类
import java.util.ArrayList;
import java.util.List;
class Player {
private List<Card> hand;
public Player() {
hand = new ArrayList<>();
}
public void receiveCard(Card card) {
hand.add(card);
}
public int getHandValue() {
int value = 0;
int aces = 0;
for (Card card : hand) {
String rank = card.getRank();
if (rank.equals("Ace")) {
aces++;
value += 11;
} else if (rank.equals("Jack") || rank.equals("Queen") || rank.equals("King")) {
value += 10;
} else {
value += Integer.parseInt(rank);
}
}
while (value > 21 && aces > 0) {
value -= 10;
aces--;
}
return value;
}
public List<Card> getHand() {
return hand;
}
}
// BlackjackGame 类
import java.util.Scanner;
public class BlackjackGame {
public static void main(String[] args) {
Deck deck = new Deck();
Player player = new Player();
Player dealer = new Player();
// 发初始牌
player.receiveCard(deck.dealCard());
dealer.receiveCard(deck.dealCard());
player.receiveCard(deck.dealCard());
dealer.receiveCard(deck.dealCard());
// 玩家回合
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Your hand: " + player.getHand());
System.out.println("Your hand value: " + player.getHandValue());
System.out.println("Dealer's visible card: " + dealer.getHand().get(0));
System.out.println("Do you want to hit (h) or stand (s)?");
String choice = scanner.nextLine().toLowerCase();
if (choice.equals("h")) {
player.receiveCard(deck.dealCard());
if (player.getHandValue() > 21) {
System.out.println("You bust! Dealer wins.");
return;
}
} else if (choice.equals("s")) {
break;
}
}
// 庄家回合
while (dealer.getHandValue() < 17) {
dealer.receiveCard(deck.dealCard());
if (dealer.getHandValue() > 21) {
System.out.println("Dealer busts! You win.");
return;
}
}
// 比较结果
System.out.println("Your hand value: " + player.getHandValue());
System.out.println("Dealer's hand value: " + dealer.getHandValue());
if (player.getHandValue() > dealer.getHandValue()) {
System.out.println("You win!");
} else if (player.getHandValue() < dealer.getHandValue()) {
System.out.println("Dealer wins.");
} else {
System.out.println("It's a tie.");
}
}
}
使用步骤
- 将上述代码保存为
.java
文件,例如BlackjackGame.java
。 - 打开命令行,进入代码所在目录。
- 编译代码:
javac BlackjackGame.java
。 - 运行程序:
java BlackjackGame
。 - 根据提示输入
h
或s
进行要牌或停牌操作。
常见实践
异常处理
在实际开发中,可能会遇到牌堆为空的情况,需要在 Deck
类的 dealCard
方法中添加异常处理:
public Card dealCard() {
if (cards.isEmpty()) {
throw new IllegalStateException("The deck is empty.");
}
return cards.remove(0);
}
增加游戏交互性
可以添加更多的提示信息和错误处理,提高用户体验。例如,当用户输入无效的选择时,提示用户重新输入。
最佳实践
面向对象设计
遵循面向对象的设计原则,将不同的功能封装到不同的类中,提高代码的可维护性和可扩展性。
代码复用
可以将一些通用的方法提取出来,如计算牌点数的方法,避免代码重复。
测试驱动开发
使用 JUnit 等测试框架对各个类的方法进行单元测试,确保代码的正确性。
小结
本文介绍了 Java 实现 21 点游戏的基础概念、使用方法、常见实践和最佳实践。通过实现 21 点游戏,我们可以更好地理解 Java 的面向对象编程和异常处理等知识。同时,在开发过程中遵循最佳实践可以提高代码的质量和可维护性。
参考资料
- 《Effective Java》
- Java 官方文档
- JUnit 官方文档