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

C++扫雷游戏改造问题:已选坐标重复判定错误求解

扫雷游戏逻辑修正方案

背景与问题

我正在学习C++,参考了一个基于多维数组的战舰游戏示例(代码如下),尝试将其改造成扫雷游戏。目前代码可运行,但存在逻辑问题:选中安全坐标(值为true)后,代码会将其设为false,若再次选择该坐标,会被判定为踩雷导致游戏结束。

原战舰游戏示例代码

#include <iostream>
using namespace std;

int main() {
  // 用"1"表示有战舰
  bool ships[4][4] = {
    { 0, 1, 1, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 1, 0 },
    { 0, 0, 1, 0 }
  };

  // 记录击中次数和回合数
  int hits = 0;
  int numberOfTurns = 0;

  // 击中所有4艘战舰前持续游戏
  while (hits < 4) {
    int row, column;

    cout << "Selecting coordinates\n";

    // 输入行号
    cout << "Choose a row number between 0 and 3: ";
    cin >> row;

    // 输入列号
    cout << "Choose a column number between 0 and 3: ";
    cin >> column;

    // 检查坐标是否有战舰
    if (ships[row][column]) {
      // 击中后移除战舰(设为0)
      ships[row][column] = 0;

      // 增加击中计数
      hits++;

      // 提示击中信息和剩余战舰数
      cout << "Hit! " << (4-hits) << " left.\n\n";
    } else {
      // 提示未击中
      cout << "Miss\n\n";
    }

    // 统计回合数
    numberOfTurns++;
  }

  cout << "Victory!\n";
  cout << "You won in " << numberOfTurns << " turns";
  
  return 0;
}

我编写的扫雷游戏代码

#include <iostream>
using namespace std;

int main() {
// 这里用"1"表示安全区域,"0"表示炸弹
bool bombs[4][4] = {
  { 0, 1, 1, 1 },
  { 1, 1, 1, 1 },
  { 1, 1, 1, 1 },
  { 1, 1, 1, 1 }
};

// 记录相关统计值
int hits = 0;
int misses = 15;
int numberOfTurns = 0;

while (hits < 1 || misses > 0 ) {
  int row, column;

  cout << "Selecting coordinates\n";

  cout << "Choose a row number between 0 and 3: ";
  cin >> row;

  cout << "Choose a column number between 0 and 3: ";
  cin >> column;

  if (bombs[row][column]) {
    // 选中安全区域后设为0
    bombs[row][column] = 0;
    cout << "Good Job!" << (misses-1) << " left.\n\n" ;

    if (misses-1==0) {
        cout<< "Victory!";
        break;
    }

  }

   else {
    cout << "Ooops! You found a bomb! \n\n" ;
    break;

  }

  misses--;
  numberOfTurns++;
}


cout << "You survived " << numberOfTurns << " turns";

return 0;
}

问题分析与解决

问题核心在于用同一个数组同时存储炸弹位置和已访问状态,导致安全区域被点击后被标记为false,再次点击时会被误判为炸弹。

解决办法是新增一个独立的visited二维数组,专门记录哪些格子已经被点击过,不修改原炸弹数组的状态:

修正后的扫雷代码

#include <iostream>
using namespace std;

int main() {
    // 炸弹数组:0表示炸弹,1表示安全区域
    bool bombs[4][4] = {
        { 0, 1, 1, 1 },
        { 1, 1, 1, 1 },
        { 1, 1, 1, 1 },
        { 1, 1, 1, 1 }
    };
    // 新增已访问数组:初始全为false,标记格子是否被点击过
    bool visited[4][4] = {false};

    int safeCells = 15; // 总安全区域数量
    int numberOfTurns = 0;

    // 所有安全区域都被选中则胜利
    while (safeCells > 0) {
        int row, column;

        cout << "Selecting coordinates\n";
        cout << "Choose a row number between 0 and 3: ";
        cin >> row;
        cout << "Choose a column number between 0 and 3: ";
        cin >> column;

        // 先判断是否已访问过该格子
        if (visited[row][column]) {
            cout << "You already clicked this cell! Try another one.\n\n";
            continue; // 跳过本次循环,重新输入
        }

        // 标记为已访问
        visited[row][column] = true;
        numberOfTurns++;

        // 判断是否踩中炸弹
        if (!bombs[row][column]) {
            cout << "Ooops! You found a bomb! Game over.\n\n";
            break;
        }

        // 选中安全区域
        safeCells--;
        cout << "Good Job! " << safeCells << " safe cells left.\n\n";

        // 所有安全区域都已选中,胜利
        if (safeCells == 0) {
            cout << "Victory! You cleared all safe cells.\n";
        }
    }

    cout << "You survived " << numberOfTurns << " turns";
    return 0;
}

关键修改点

  • 新增visited[4][4]数组,独立记录已点击的格子,避免修改炸弹数组的原始状态
  • 每次输入坐标后先检查是否已访问,若已访问则提示并重新输入
  • 炸弹数组仅用于判断是否为炸弹,不再被修改,彻底区分了"炸弹位置"和"已访问状态"两个逻辑

内容的提问来源于stack exchange,提问作者G S Gekkosera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:28:32