C++控制台数独开发:如何设置二维数组部分元素不可修改
问题背景
我正在开发一款控制台端数独游戏。根据数独游戏规则,用户在棋盘上移动光标时可修改自行填入的单元格数值。我目前采用二维数组存储棋盘所有数值,但遇到如下问题:数独棋盘存在部分预设初始值不可被用户修改,用户必须基于这些固定值推导完成解题,而我当前无法实现这部分单元格的常量锁定特性。
- 核心疑问:如何才能实现二维数组中指定元素的不可修改特性?
以下是现有完整项目代码:
#include <windows.h> #include <iostream> #include <conio.h> using namespace std; #define KEY_UP 72 #define KEY_DOWN 80 #define KEY_LEFT 75 #define KEY_RIGHT 77 class Sudoku { int wholeArray[9][9]; int number; public: void setArray(void); void displayArray(int& x, int& y); void readNumber(void); void setPositions(int& x, int& y); void changeEntry(int &x, int &y); }; void setConsoleColor(int textColor, int bgColor) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (textColor + (bgColor * 16))); } void Sudoku::setArray(void) { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { wholeArray[i][j] = 0; } } } void Sudoku::displayArray(int& x, int& y) { setConsoleColor(11, 0); cout << "\t\b\b\b1 2 3 4 5 6 7 8 9\n"; cout << " -------------------------\n"; for (int i = 0; i < 9; i++) { cout << i + 1 << " | "; for (int j = 0; j < 9; j++) { if (x == i && y == j) setConsoleColor(0, 11); cout << wholeArray[i][j]; setConsoleColor(11, 0); cout << " "; if ((j + 1) % 3 == 0) cout << "| "; } cout << endl; if ((i + 1) % 3 == 0) cout << " -------------------------\n"; } } void Sudoku::readNumber(void) { cout << "Enter number you want to enter (from 1-9): "; cin >> number; } void Sudoku::setPositions(int& x, int& y) { char key = _getch(); if (key == KEY_UP) x--; if (key == KEY_DOWN) x++; if (key == KEY_LEFT) y--; if (key == KEY_RIGHT) y++; if (x < 0) x = 8; else if (x > 8) x = 0; if (y < 0) y = 8; else if (y > 8) y = 0; if (key == 'x') exit(0); if (key == 'v') changeEntry(x, y); system("cls"); } void Sudoku:: changeEntry(int& x, int& y) { int entry; do { cout << "Enter value:\t"; cin >> entry; } while (entry < 1 || entry > 9); wholeArray[x][y] = entry; } int main() { int x = 0, y = 0, entry; Sudoku s1; s1.setArray(); s1.displayArray(x, y); while (1) { s1.setPositions(x, y); s1.displayArray(x, y); } return 0; }
实现方案
C++原生数组不支持给单个元素单独加const修饰实现锁效果,做数独场景下的格子锁定,用标记数组是最简单、可维护性最高的方案,全程不需要改动现有核心逻辑,只需要加3处小改动:
- 给Sudoku类新增一个和棋盘同尺寸的布尔二维数组
isFixed[9][9],专门记录对应坐标的格子是不是初始预设、禁止修改的固定值。 - 初始化阶段同步设置标记:初始化棋盘时先把
isFixed所有值设为false,后续加载数独题面、填入预设初始数字时,同步把对应坐标的isFixed设为true。 - 修改写入逻辑加拦截:在
changeEntry方法最开头加判断,如果当前光标所在格子的isFixed标记为true,直接终止修改流程,可按需给用户弹出提示,只有标记为false的格子允许用户写入数值。
核心改动代码参考
类成员新增标记数组:
class Sudoku { int wholeArray[9][9]; bool isFixed[9][9]; // 固定格子标记 int number; public: void setArray(void); void displayArray(int& x, int& y); void readNumber(void); void setPositions(int& x, int& y); void changeEntry(int &x, int &y); };
初始化方法补充标记初始化:
void Sudoku::setArray(void) { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { wholeArray[i][j] = 0; isFixed[i][j] = false; // 初始默认所有格子可修改 } } // 后续加载题面填预设值时,同步写 isFixed[i][j] = true 即可 }
修改方法加锁定拦截:
void Sudoku:: changeEntry(int& x, int& y) { // 拦截固定格子的修改请求 if (isFixed[x][y]) { cout << "错误:当前格子为初始预设值,无法修改" << endl; system("pause"); return; } int entry; do { cout << "Enter value:\t"; cin >> entry; } while (entry < 1 || entry > 9); wholeArray[x][y] = entry; }
可选体验优化
渲染棋盘时可以给isFixed为true的格子设置不同的文字颜色,比如用亮白色显示固定值,用青色显示用户填入的值,用户不需要试就能直接区分哪些格子可修改,交互体验会好很多。后续如果要加棋盘重置功能,也只需要遍历所有格子,把isFixed为false的格子值清0即可,不需要重复加载题面。
内容的提问来源于stack exchange,提问作者Abdul Muqeet
相关产品推荐
相关产品推荐

