You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++二维数组优化及战舰游戏代码改进咨询

关于战舰游戏二维数组与类设计的解答

嘿,欢迎第一次来提问!咱们一步步来解决你的两个问题~

一、是否需要采用动态内存?

这个得看你的棋盘需求来定,不是必须的,分两种情况:

  • 固定大小棋盘(比如常见的10x10):完全没必要用动态内存。直接用静态二维数组(比如char grid[10][10];)或者std::vector<std::vector<char>> grid(10, std::vector<char>(10, '~'))就足够了。静态数组代码更简洁,不需要手动管理内存,出错概率更低。
  • 可变大小棋盘(支持玩家自定义尺寸):这时候动态内存就很有必要了。推荐用std::vector<std::vector<T>>来实现,它会自动帮你管理内存分配和释放,比手动用new/delete写二维数组安全得多——手动动态数组很容易因为忘记释放内存导致泄漏,或者越界访问出bug。

简单说:固定尺寸用静态/vector初始化固定大小;可变尺寸用vector(本质是动态内存,但不用你手动操心)。

二、类的使用改进建议

虽然你没贴具体代码,但结合战舰游戏的常见场景,我给你几个通用的类设计和正确性要点:

1. 核心类的封装思路

战舰游戏一般需要两个棋盘:自己的战舰布局棋盘,和敌方的视野棋盘(只记录命中/未命中)。别把数组暴露在类外面,应该封装成Board类,把数组设为私有成员,只通过成员函数来操作:

#include <vector>
#include <iostream>

class Board {
private:
    // 用vector封装棋盘,私有成员,外部不能直接修改
    std::vector<std::vector<char>> grid;
    int size;

public:
    // 构造函数初始化棋盘
    Board(int boardSize = 10) : size(boardSize), grid(boardSize, std::vector<char>(boardSize, '~')) {}

    // 放置战舰的成员函数
    bool placeShip(int x, int y, int length, bool isHorizontal) {
        // 这里写检查越界、是否重叠的逻辑
        // 比如:if (isHorizontal && x + length > size) return false;
        // 然后修改grid对应位置为'S'(代表战舰)
        return true;
    }

    // 处理攻击的成员函数
    char attack(int x, int y) {
        if (grid[x][y] == 'S') {
            grid[x][y] = 'X'; // 命中标记
            return 'X';
        } else if (grid[x][y] == '~') {
            grid[x][y] = 'O'; // 未命中标记
            return 'O';
        }
        return ' '; // 已攻击过的位置
    }

    // 显示棋盘的成员函数,支持是否显示战舰
    void display(bool showShips = false) {
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < size; ++j) {
                if (!showShips && grid[i][j] == 'S') {
                    std::cout << '~' << ' ';
                } else {
                    std::cout << grid[i][j] << ' ';
                }
            }
            std::cout << std::endl;
        }
    }
};

2. 常见的类使用误区修复

  • 不要把数组设为公有:如果外部代码能直接修改grid,很容易出现逻辑错误(比如不小心覆盖战舰位置),一定要用成员函数封装所有操作。
  • 避免重复代码:如果之前你是写了两个独立的二维数组,现在改成实例化两个Board对象就行——一个是玩家自己的棋盘(调用display(true)显示战舰),一个是敌方视野棋盘(调用display(false)隐藏战舰)。
  • 初始化要规范:在构造函数里完成棋盘的初始化,不要在成员函数里重复初始化,避免出现未定义的垃圾值。
  • 如果坚持用手动动态数组(不推荐):一定要在析构函数里释放内存,比如:
    class Board {
    private:
        char** grid;
        int size;
    public:
        Board(int s) : size(s) {
            grid = new char*[size];
            for (int i = 0; i < size; ++i) {
                grid[i] = new char[size];
                // 初始化每个元素为默认值
                for(int j=0;j<size;j++) grid[i][j] = '~';
            }
        }
        ~Board() {
            for (int i = 0; i < size; ++i) {
                delete[] grid[i];
            }
            delete[] grid;
        }
    };
    
    但还是那句话:用std::vector更省心,不用手动写析构函数,也不容易出错。

3. 扩展建议

可以再封装一个Ship类,用来记录战舰的长度、位置、受损状态等,然后Board类里可以包含一个std::vector<Ship>来管理所有战舰,这样逻辑会更清晰,也方便实现“判断战舰是否被击沉”这类功能。

内容的提问来源于stack exchange,提问作者Pepo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:04:18