欢迎来到Java版21点游戏,一个将经典赌场游戏与编程技术完美结合。每一张牌都隐藏着无限可能,每一次决策都关乎胜负。让热爱编程的开发者,都能在这个简单却极具深度的游戏中找到属于自己的乐趣,探索21点背后的策略与魅力。
游戏规则:游戏开始时,玩家和庄家各获得两张牌,玩家可以看到自己手中的两张牌以及庄家的一张明牌。玩家需要根据手中的牌面总和,选择“要牌”(Hit)以获取更多牌,或“停牌”(Stand)停止要牌。如果玩家的牌面总和超过21点,即为爆牌,玩家立即输掉游戏。若玩家选择停牌,庄家则开始行动,其策略是当牌面总和小于17点时必须继续要牌。若庄家牌面总和超过21点,则庄家爆牌,玩家获胜。若双方均未爆牌,最终比较牌面总和,更接近21点的一方获胜;若牌面总和相同,则游戏以平局结束。
该文章的目录:
1. 开发目标
2. 游戏流程规划
3. 关键技术点
4. 完整代码
5. 测试和运行
原创-谷宇博客,拥有更多案例:https://biguyu.top/home
--------------------
一. 开发目标
通过编写和运行代码,深入理解Java编程的核心概念和技巧。玩家将学习如何设计和实现一个完整的交互式游戏。玩家能够培养逻辑思维能力和问题解决能力。最终,通过运行和测试游戏,从而在实践中巩固和深化对Java编程的理解!
二. 游戏流程设计
(1) 初始化牌堆:创建一个包含52张牌的牌堆,每张牌由花色(♠, ♥, ♣, ♦)和牌面(2-10, J, Q, K, A)组成。
(2) 洗牌:通过随机算法打乱牌堆的顺序,确保每次游戏的牌序都是随机的。
(3) 发牌:游戏开始时,玩家和庄家各获得两张牌。玩家可以看到自己的两张牌和庄家的一张明牌。
(4) 玩家行动:玩家根据当前手牌的总和,选择“要牌”(Hit)或“停牌”(Stand)。
(5) 庄家行动:庄家的行动由固定规则决定。如果庄家的牌面总和小于17点,必须继续要牌。
(6) 胜负判定:比较牌面,如果玩家和庄家都没有爆牌,比较双方的牌面总和。更接近21点的一方获胜。如果双方的牌面总和相同,则游戏以平局结束。
(7) 游戏结束:系统会显示玩家和庄家的最终手牌和总和,并宣布胜负结果。
三. 关键技术点
(1) 数组的应用:使用一维数组存储52张牌,每张牌由花色和牌面组成。同时对数组数据进行管理和操作。
(2) 随机数生成:通过Random类生成随机数,打乱牌堆的顺序,从打乱后的牌堆中依次抽取牌,模拟发牌过程。
(3) 用户输入处理:使用Scanner类的scanner.nextInt()从控制台接收玩家的输入。实现玩家的“要牌”和“停牌”操作。
(4) 控制流语句while循环:游戏整体回合的管理和操作。
(5) 函数封装:模块化设计:将游戏的各个功能模块化,封装为独立的函数单元。这些封装后的函数能够在游戏的不同环节中多次调用,有效提升了代码的复用性,减少了重复代码的编写,使程序更加简洁高效。
四. 完整代码
package com.simple;
import java.util.Random;
import java.util.Scanner;
/**
* 21点
* 游戏开始时,玩家和庄家各发两张牌。
* 玩家可以看到自己的牌和庄家的一张明牌。
* 玩家可以选择“要牌”(Hit)或“停牌”(Stand)。
* 如果玩家的牌面总和超过21点,玩家爆牌,游戏结束,玩家输。
* 如果玩家选择停牌,庄家开始行动,庄家的策略是牌面总和小于17点时必须要牌。
* 庄家的牌面总和超过21点,庄家爆牌,玩家赢。
* 如果庄家和玩家都没有爆牌,比较牌面总和,谁的牌面总和更接近21点谁赢。
* 如果牌面总和相同,游戏平局。
* **/
public class TwentyOne {
public static void main(String[] args) {
//游戏开始
System.out.println("赌桌上的魅力,21点游戏开始");
System.out.println("你需要连续解密五次才能成功拆弹。");
System.out.println("------------------------------");
//声明Scanner类,用于接收用户的输入
Scanner scanner = new Scanner(System.in);
//声明Random类,用户获得随机数
Random random = new Random();
// 初始化牌堆,共52张牌
String[] symbels = {"♠", "♥", "♣", "♦"};
String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
String[] deck = new String[symbels.length * ranks.length];
int index = 0;
for (int i = 0; i < symbels.length; i++) {
for (int j = 0; j < ranks.length; j++) {
deck[index] = symbels[i] + ranks[j];
index++;
}
}
//洗牌,打乱数组中的数据的顺序
for (int i = 0; i < deck.length; i++) {
int randomIndex = random.nextInt(deck.length);
String temp = deck[i];
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
//声明玩家和庄家的手牌
int playerIndex = 0; //玩家手牌的数组索引
String[] playerHand = new String[10];
int dealerIndex = 0; //庄家手牌的数组索引
String[] dealerHand = new String[10];
int deckIndex = 0; //牌堆的数组索引
//玩家初始获取两张牌
playerHand[playerIndex++] = deck[deckIndex++];
playerHand[playerIndex++] = deck[deckIndex++];
//庄家同样获取两张牌
dealerHand[dealerIndex++] = deck[deckIndex++];
dealerHand[dealerIndex++] = deck[deckIndex++];
// 显示玩家的所有牌和庄家的明牌
System.out.println("玩家的牌:" + playerHand[0] + ", " + playerHand[1]);
System.out.println("庄家的明牌:" + dealerHand[0]);
// 21点游戏主体
while (true) {
//玩家回合
System.out.print("请选择你的行动(1.要牌 2.停牌):");
int choice = scanner.nextInt();
if(choice != 1 && choice != 2) {
System.out.println("无效输入,请重新选择!");
continue;
} else if(choice == 2) {
//如果选择停牌,则跳出循环,分别计算玩家和庄家的手牌,再对比双方牌面
break;
}
//在牌堆中发放一张牌给玩家
playerHand[playerIndex++] = deck[deckIndex++];
//打印玩家手牌
String playerHandDeck = getDecks(playerHand);
System.out.println("玩家的手牌是:" + playerHandDeck);
//计算手牌的总和
int playerTotal = sumHands(playerHand);
if(playerTotal > 21) {
System.out.println("玩家爆牌,庄家胜,游戏结束。");
//打印庄家说牌
String dealerHandDeck = getDecks(dealerHand);
System.out.println("庄家的手牌是:" + dealerHandDeck);
return;
}
//庄家回合
//计算手牌的总和
int dealerTotal = sumHands(dealerHand);
//如果庄家牌小于17点,则要牌
if(dealerTotal < 17) {
dealerHand[dealerIndex++] = deck[deckIndex++];
//再次计算庄家手牌总和
dealerTotal = sumHands(dealerHand);
if(dealerTotal > 21) {
System.out.println("庄家爆牌,玩家胜,游戏结束。");
return;
}
}
}
//对比结果
System.out.println("-------------------");
int playerTotal = sumHands(playerHand);
int dealerTotal = sumHands(dealerHand);
//打印手牌
String playerHandDeck = getDecks(playerHand);
System.out.println("玩家的手牌是:" + playerHandDeck);
String dealerHandDeck = getDecks(dealerHand);
System.out.println("庄家的手牌是:" + dealerHandDeck);
if(playerTotal > dealerTotal){
System.out.println("恭喜你,玩家胜。游戏结束!");
} else if(dealerTotal > playerTotal) {
System.out.println("胜败兵家常事,庄家胜。游戏结束!");
} else {
System.out.println("没有胜利者,平局!");
}
}
/**
* 获取所拥有的手牌
* 参数hand:玩家或者庄家的手牌
* 返回值:所拥有手牌的字符串
* **/
public static String getDecks(String[] hands) {
if(hands != null && hands.length > 0) {
String handDeck = "";
for(String h : hands) {
if(h == null){
break;
}
handDeck += h + ",";
}
return handDeck;
}
return "";
}
/**
* 计算手牌的总和
* **/
public static int sumHands(String[] hands) {
int value = 0;
for (int i = 0; i < hands.length; i++) {
if(hands[i] == null){
break;
}
String rank = hands[i].substring(1);
if (rank.equals("J") || rank.equals("Q") || rank.equals("K")) {
value += 10;
} else if (rank.equals("A")) {
value += 1;
} else {
value += Integer.parseInt(rank);
}
}
return value;
}
}
五. 测试和运行
在测试和运行Java21点游戏时,启动程序后,控制台会显示欢迎信息和游戏规则,随后初始化并显示玩家和庄家的初始手牌。玩家可以通过输入“1”或“2”选择“要牌”或“停牌”,程序会实时反馈玩家的手牌总和和当前状态。如果玩家爆牌,程序会立即提示玩家输掉游戏,并显示庄家的手牌。如果玩家停牌,庄家会根据规则自动行动,程序会判断庄家是否爆牌或比较双方手牌总和,最终输出胜负结果。整个游戏过程流畅,操作提示清晰,玩家能够轻松地进行游戏并体验其中的乐趣!