【Java实例-智慧牌局】Java实现赌桌上的21点

简介: 游戏规则:游戏开始时,玩家和庄家各获得两张牌,玩家可以看到自己手中的两张牌以及庄家的一张明牌。玩家需要根据手中的牌面总和,选择“要牌”(Hit)以获取更多牌,或“停牌”(Stand)停止要牌。如果玩家的牌面总和超过21点,即为爆牌,玩家立即输掉游戏。若玩家选择停牌,庄家则开始行动,其策略是当牌面总和小于17点时必须继续要牌。若庄家牌面总和超过21点,则庄家爆牌,玩家获胜。若双方均未爆牌,最终比较牌面总和,更接近21点的一方获胜;若牌面总和相同,则游戏以平局结束。

top.jpg

欢迎来到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”选择“要牌”或“停牌”,程序会实时反馈玩家的手牌总和和当前状态。如果玩家爆牌,程序会立即提示玩家输掉游戏,并显示庄家的手牌。如果玩家停牌,庄家会根据规则自动行动,程序会判断庄家是否爆牌或比较双方手牌总和,最终输出胜负结果。整个游戏过程流畅,操作提示清晰,玩家能够轻松地进行游戏并体验其中的乐趣!


finish.png

目录
相关文章
|
2月前
|
安全 Java 测试技术
Java 大学期末实操项目在线图书管理系统开发实例及关键技术解析实操项目
本项目基于Spring Boot 3.0与Java 17,实现在线图书管理系统,涵盖CRUD操作、RESTful API、安全认证及单元测试,助力学生掌握现代Java开发核心技能。
102 1
|
3月前
|
人工智能 Java 开发者
【Java实例-简易计算机】使用Java实现简单的计算机案例
一个简单的Java案例——“简易计算器”,帮助编程新手快速上手。通过实现用户输入、基本逻辑运算和结果输出,学习者可以掌握变量声明、Scanner对象使用、控制流语句等关键知识点。文章分为设计思路、关键知识点、完整代码和测试运行四个部分。
123 9
【Java实例-简易计算机】使用Java实现简单的计算机案例
|
4月前
|
Java 测试技术 项目管理
【JavaEE】从 0 到 1 掌握 Maven 构建 Java 项目核心技巧 解锁 Java 项目高效管理实用实例
本文从Maven基础概念讲起,涵盖安装配置、核心概念(如POM与依赖管理)及优化技巧。结合Java Web项目实例,演示如何用Maven构建和管理项目,解决常见问题,助你高效掌握这一强大工具,提升Java开发与项目管理能力。适合初学者及进阶开发者学习。资源链接:[点此获取](https://pan.quark.cn/s/14fcf913bae6)。
154 6
|
3月前
|
Java 开发者
【Java实例-神秘年龄】用Java挑战你的直觉
我们一起走进这款款简单却充满趣味的Java小游戏——“神秘年龄”。这款游戏不仅适合编程初学者作为练习项目,也能为有一定基础的开发者提供一个轻松的编程小憩。
39 0
【Java实例-神秘年龄】用Java挑战你的直觉
|
3月前
|
Java 开发者
【Java实例-神秘硬币】用Java投掷你的幸运硬币,你是猜正还是反?
本文分享了一个简单有趣的编程案例——猜硬币正反面游戏。通过模拟抛硬币(0为正面,1为反面),用户输入猜测值,程序判断结果并输出。
103 0
【Java实例-神秘硬币】用Java投掷你的幸运硬币,你是猜正还是反?
|
3月前
|
Java 开发者
【Java实例-英雄对战】Java战斗之旅,既分胜负也决生死
游戏规则:在“英雄对战”中,玩家和敌人轮流选择行动,目标是在对方生命值归零前将其击败。游戏开始时,玩家和敌人都有100生命值。每回合,玩家可以选择“攻击”,“追击”,“闪避反击”这三种行动之一。
46 0
|
11月前
|
Java
Java关键字 —— super 详细解释!一看就懂 有代码实例运行!
文章详细解释了Java关键字`super`的用途,包括访问父类的成员变量、调用父类的构造方法和方法,并提供了相应的代码实例。
781 5
Java关键字 —— super 详细解释!一看就懂 有代码实例运行!
|
3月前
|
Java
【Java实例-小兵拆炸弹】Java打造数学挑战-拆炸弹
今天,我将向大家分享一款用Java开发的控制台小案例——“小兵拆炸弹”。游戏规则:玩家需要在有限的尝试次数内解开一系列数学题,以成功拆解炸弹。游戏的目标是连续答对五道数学题,每道题都由系统随机生成。如果玩家在五次机会内成功解密,游戏胜利;否则,炸弹爆炸,游戏结束。
60 0
|
5月前
|
前端开发 JavaScript Java
【Java进阶】JavaScript电灯开关实例:从理论到实践
这个例子展示了JavaScript的基本功能,包括操作HTML元素,监听事件,以及改变元素的样式。通过学习和理解这个例子,你可以了解到JavaScript在网页中的应用,以及如何使用JavaScript来创建交互式的网页。
97 13
|
8月前
|
存储 Java 计算机视觉
Java二维数组的使用技巧与实例解析
本文详细介绍了Java中二维数组的使用方法
225 15