C++战舰游戏:实现二维数组存储战舰坐标并重绘网格
问题分析与解决方案
你的核心问题是每次调用drawPlayerBoard()时,都会把整个playerBoard数组重置为.,这直接导致之前标记的战舰被覆盖。要实现「用户输入坐标标记战舰+重绘时保留标记」的功能,按以下步骤修改:
1. 移除绘制函数中的数组重置代码
把drawPlayerBoard()里这段清空数组的嵌套循环删掉:
for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { playerBoard[i][j] = 46;// ascii } }
数组初始化只需要在程序启动时做一次,而不是每次绘制都清空。
2. 实现用户输入坐标标记战舰的函数
添加专门处理输入的函数,把用户输入的坐标转成数组索引,再标记+:
void placePlayerShip() { char xInput; int yInput; cout << "请输入战舰坐标(例:A 5):"; cin >> xInput >> yInput; // 把A-J转成数组列索引0-9,统一处理大小写 int xIndex = toupper(xInput) - 'A'; // 把1-10转成数组行索引0-9 int yIndex = yInput - 1; // 检查坐标是否在合法范围内 if (xIndex >= 0 && xIndex < columns && yIndex >=0 && yIndex < rows) { playerBoard[yIndex][xIndex] = '+'; cout << "战舰已放置!\n"; } else { cout << "坐标不合法,请重新输入!\n"; } }
3. 调整主逻辑流程
在main()里按「初始化棋盘→循环放置战舰→重绘棋盘」的顺序执行:
const int rows = 10; const int columns = 10; char playerBoard[rows][columns]; int main() { // 初始化棋盘为全点(只执行一次) for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { playerBoard[i][j] = '.'; } } char choice; do { drawPlayerBoard(); placePlayerShip(); cout << "继续放置战舰?(Y/N):"; cin >> choice; } while (toupper(choice) == 'Y'); return 0; }
4. 优化绘制函数的可读性
把ASCII码换成字符字面量,让代码更直观:
void drawPlayerBoard() { int yLabel = 0; char xLabel = 'A'; cout << " "; for (xLabel = 'A'; xLabel <= 'J'; xLabel++) { cout << xLabel << " "; } cout << "\n"; for (int i = 0; i < rows; i++) { yLabel++; // 处理数字对齐:10占两位,1-9补空格 cout << (yLabel >= 10 ? to_string(yLabel) + " " : to_string(yLabel) + " "); for (int j = 0; j < columns; j++) { cout << playerBoard[i][j] << " "; } cout << "\n"; } }
修改后,用户放置的战舰+会被永久保存在playerBoard数组中,每次重绘网格都会正确显示,不会被清空。
内容的提问来源于stack exchange,提问作者Connor McDonald
相关产品推荐
相关产品推荐

