0

0

Java中随机且不重复地放置战舰:20位置数组中部署5艘船只的策略

心靈之曲

心靈之曲

发布时间:2025-10-26 09:05:39

|

777人浏览过

|

来源于php中文网

原创

Java中随机且不重复地放置战舰:20位置数组中部署5艘船只的策略

本教程详细介绍了如何在java中实现战舰游戏的随机布船逻辑。针对在20个位置的数组中不重复地放置5艘编号为1到5的船只,并用0填充空位的问题,文章提出了一种高效的解决方案。该方案利用一个动态的可用位置列表来确保船只位置的唯一性,并通过随机选择并移除位置的方式,避免了重复和复杂的冲突检测。教程提供了完整的java代码示例,帮助开发者理解并实现这一核心游戏机制。

1. 问题背景与挑战

在开发如“战舰”这类棋盘游戏时,一个常见的需求是在一个固定大小的游戏板上随机且不重复地放置多艘船只。具体而言,我们面临的任务是在一个包含20个位置的数组中,随机放置5艘船只。每艘船只应有一个唯一的标识(例如,从1到5),而未放置船只的位置则用0表示。

直接使用简单的随机数生成器可能会导致以下问题:

  • 位置重复:同一位置可能被多次选中,导致多艘船只放置在同一格,或覆盖已放置的船只。
  • 船只标识重复:如果船只标识也随机生成,可能出现多个位置使用相同的船只标识。
  • 效率低下:为了避免重复,可能需要复杂的冲突检测和重试机制,尤其是在板子逐渐被填满时,效率会显著降低。

2. 核心策略:基于可用位置列表的随机选择

为了解决上述挑战,我们采用一种高效且简洁的策略:维护一个动态的“可用位置”列表。这个列表最初包含所有可能的棋盘位置索引。每次放置一艘船时,我们从这个列表中随机选择一个位置,然后将其从列表中移除。这样可以确保每个选定的位置都是唯一的,从而避免了重复放置的问题。

该策略的关键步骤如下:

立即学习Java免费学习笔记(深入)”;

  1. 初始化游戏板:创建一个大小为20的整型数组,所有元素默认初始化为0,表示空位。
  2. 创建可用位置列表:创建一个 List,并用0到19的整数填充它,代表所有可用的棋盘索引。
  3. 循环放置船只:对于要放置的每艘船(共5艘):
    • 生成随机索引:从0到 可用位置列表.size() - 1 之间生成一个随机整数作为索引。
    • 获取实际位置:使用这个随机索引从 可用位置列表 中获取一个实际的棋盘位置(例如,如果列表当前有10个元素,随机索引可能是3,获取到的值可能是原始棋盘的第7个位置)。
    • 放置船只:将当前船只的标识(例如,第1艘船为1,第2艘船为2,依此类推)放置到游戏板数组中对应的实际位置上。
    • 移除已用位置:从 可用位置列表 中移除刚才使用的随机索引处的元素。这样,该位置就不会被再次选中。

3. 实现步骤与代码示例

下面是使用Java语言实现上述策略的详细步骤和完整代码。

3.1 定义常量与主函数

首先,我们定义游戏板的大小和船只数量为常量,并在 main 方法中初始化游戏板并调用船只放置函数。

扣子编程
扣子编程

扣子推出的AI编程开发工具

下载
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class BattleshipPlacement {

    // 定义游戏板的大小
    private static final int BOARD_SIZE = 20;
    // 定义要放置的船只数量
    private static final int NUM_SHIPS = 5;

    public static void main(String[] args) {
        // 初始化游戏板数组,Java中int数组默认元素值为0
        int[] gameBoard = new int[BOARD_SIZE]; 

        // 调用函数随机放置船只
        placeShipsRandomly(gameBoard, NUM_SHIPS);

        // 打印最终的游戏板布局
        printBoard(gameBoard);
    }

    // ... (后续方法将在下面定义)
}

3.2 随机放置船只的逻辑

placeShipsRandomly 方法是核心,它实现了我们前面讨论的策略。

    /**
     * 随机放置指定数量的船只到游戏板上。
     * 船只编号从1到NUM_SHIPS,空位为0。
     *
     * @param board 游戏板数组,用于存储船只位置
     * @param numShips 要放置的船只数量
     */
    public static void placeShipsRandomly(int[] board, int numShips) {
        // 检查船只数量是否超过板子大小,防止越界或逻辑错误
        if (numShips > board.length) {
            System.err.println("错误:船只数量不能超过板子大小。");
            return;
        }

        // 1. 初始化所有可用位置的列表
        // 这个列表最初包含所有棋盘位置的索引 (0 到 BOARD_SIZE-1)
        List availablePositions = new ArrayList<>();
        for (int i = 0; i < board.length; i++) {
            availablePositions.add(i);
        }

        // 创建一个随机数生成器实例
        Random random = new Random();

        // 2. 循环放置每艘船只
        // shipId 从1开始,代表第一艘船到第五艘船
        for (int shipId = 1; shipId <= numShips; shipId++) {
            // 生成一个随机索引,范围是 0 到 availablePositions.size() - 1
            // 随着位置的移除,availablePositions.size() 会逐渐减小
            int randomIndex = random.nextInt(availablePositions.size());

            // 从可用位置列表中获取选定的实际棋盘位置
            int actualPosition = availablePositions.get(randomIndex);

            // 将当前船只的标识(shipId)放置到游戏板的对应位置上
            board[actualPosition] = shipId; 

            // 从可用位置列表中移除该位置,确保该位置不会被再次选中
            availablePositions.remove(randomIndex);
        }
    }

3.3 打印游戏板的方法

为了验证结果,我们需要一个辅助方法来打印游戏板的当前布局。

    /**
     * 打印游戏板内容。
     *
     * @param board 游戏板数组
     */
    public static void printBoard(int[] board) {
        System.out.println("最终游戏板布局:");
        for (int i = 0; i < board.length; i++) {
            System.out.print(board[i] + "\t"); // 使用制表符分隔,使输出更整齐
        }
        System.out.println(); // 换行
    }

4. 运行结果示例

运行上述 BattleshipPlacement 类,你将得到类似以下输出的结果(具体位置因随机性而异):

最终游戏板布局:
0       0       0       0       3       0       0       0       0       0       1       0       0       5       0       0       0       4       2       0

在这个示例中,船只1、2、3、4、5分别被放置在了索引为10、18、4、17、13的位置,其余位置均为0。

5. 注意事项与总结

  • 随机数生成器:java.util.Random 是线程安全的,但在高并发场景下可能存在性能瓶颈。对于大多数单线程游戏应用,它是足够的。如果需要更高质量的随机性或并发需求,可以考虑 java.security.SecureRandom 或为每个线程使用独立的 Random 实例。
  • 灵活性:通过修改 BOARD_SIZE 和 NUM_SHIPS 常量,你可以轻松地调整游戏板的大小和船只的数量,而无需修改核心逻辑。
  • 船只标识:本教程中,船只标识从1到 NUM_SHIPS 顺序分配。如果需要船只标识本身也是随机的(但仍需保证唯一性),可以创建一个包含1到 NUM_SHIPS 的列表,然后像处理位置一样,每次取一个随机船只标识并移除。
  • 效率:对于相对较小的板子和船只数量,这种基于 ArrayList 的方法效率很高。remove(index) 操作在 ArrayList 中是O(n)时间复杂度,因为需要移动后续元素。然而,由于 NUM_SHIPS 通常远小于 BOARD_SIZE,且 BOARD_SIZE 本身不大(例如20),这种开销可以忽略不计。如果 BOARD_SIZE 非常大,或者 NUM_SHIPS 接近 BOARD_SIZE,可以考虑使用 Collections.shuffle() 方法先打乱整个 availablePositions 列表,然后直接取前 NUM_SHIPS 个元素,这样每次移除的开销就变为O(1)。

通过本教程介绍的方法,开发者可以轻松地在Java中实现战舰游戏的随机布船逻辑,确保船只位置的唯一性和随机性,为游戏的核心机制奠定坚实基础。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1501

2023.10.24

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

503

2023.08.10

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

1

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

1

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

23

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

120

2026.01.26

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

51

2026.01.26

苹果官方查询网站 苹果手机正品激活查询入口
苹果官方查询网站 苹果手机正品激活查询入口

苹果官方查询网站主要通过 checkcoverage.apple.com/cn/zh/ 进行,可用于查询序列号(SN)对应的保修状态、激活日期及技术支持服务。此外,查找丢失设备请使用 iCloud.com/find,购买信息与物流可访问 Apple (中国大陆) 订单状态页面。

192

2026.01.26

npd人格什么意思 npd人格有什么特征
npd人格什么意思 npd人格有什么特征

NPD(Narcissistic Personality Disorder)即自恋型人格障碍,是一种心理健康问题,特点是极度夸大自我重要性、需要过度赞美与关注,同时极度缺乏共情能力,背后常掩藏着低自尊和不安全感,影响人际关系、工作和生活,通常在青少年时期开始显现,需由专业人士诊断。

7

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号