C++中移除游戏板矩阵元素并更新显示的最优方法
实现元素移除功能及代码优化建议
一、实现移除指定坐标元素的方法
要完成移除功能,核心是解析用户输入的坐标并修改对应位置的值,具体步骤如下:
- 解析坐标输入:从用户输入的字符串中提取行号(x)和列号(y),兼容
3,4或3 4这类常见格式 - 坐标转换:用户输入的是1-5的序号(1-based),而vector的索引是从0开始的,所以要将x和y各减1
- 合法性校验:确保转换后的索引在0-4范围内,超出则提示错误并要求重新输入
- 修改游戏板:将对应位置的值设为0(你的printBoard逻辑中,0会显示为空)
- 重新打印:修改后调用printBoard输出更新后的游戏板
修改后的核心代码片段
新增坐标解析函数,并更新main循环:
// 解析用户输入的坐标,返回是否成功,成功则通过引用返回x和y(0-based) bool parseCoordinates(const string& input, int& x, int& y) { size_t sepPos = input.find_first_of(", "); if (sepPos == string::npos) { return false; } try { x = stoi(input.substr(0, sepPos)) - 1; // 转0-based索引 y = stoi(input.substr(sepPos + 1)) - 1; } catch (...) { return false; } return x >= 0 && x < BOARD_SIDE && y >=0 && y < BOARD_SIDE; } int main() { Board board(BOARD_SIDE, vector<int>(BOARD_SIDE)); initBoard(board); printBoard(board); while (true) { cout << "Enter removable element (x, y): "; string removeInput; // 处理前一次输入留下的换行符,避免读取空字符串 if (cin.peek() == '\n') { cin.ignore(); } getline(cin, removeInput); int x, y; if (!parseCoordinates(removeInput, x, y)) { cout << "Invalid input! Please enter like '3,4' or '3 4' (1-5 for x and y)\n"; continue; } // 将指定位置置为空元素 board[x][y] = 0; printBoard(board); } }
二、代码优化建议
1. 避免using namespace std
全局引入std命名空间容易引发命名冲突,尤其是在大型项目中,建议显式使用std::前缀,比如std::vector、std::cin。
2. 替换老旧的rand()为C++11随机数库
你已经包含了<random>,没必要用C风格的srand()和rand(),现代随机数库生成的数值更均匀、类型安全:
// 替换initBoard中随机生成的代码 std::mt19937 rng(seed); std::uniform_int_distribution<int> dist(1, 5); for (auto& row : board) { for (auto& cell : row) { cell = dist(rng); } }
3. 简化随机生成逻辑
原来的代码先把随机数拼成字符串再读回vector,完全是绕弯路,直接生成数字存入vector即可,省去字符串转换的开销。
4. 移除冗余函数printNewBoard
这个函数只是简单调用printBoard,没有额外逻辑,直接删除,调用时用printBoard替代即可。
5. 统一空元素定义
当前用EMPTY = ' '字符,但判断的是0,语义不统一,建议定义:
const int EMPTY_CELL = 0; const unsigned char EMPTY_CHAR = ' ';
然后在printBoard中判断board.at(row).at(column) == EMPTY_CELL,输出EMPTY_CHAR,逻辑更清晰。
6. 增加输入合法性检查
- 在initBoard的输入模式中,检查用户输入的数字是否足够25个,不足则提示重新输入
- 处理用户输入非数字的情况,避免程序崩溃
7. 优化输入处理
原来的cin.ignore()可能会在某些情况下跳过正确输入,建议用cin.peek()判断是否有换行符再处理,或者在读取字符串前清空缓冲区。
完整优化后的代码
#include <iostream> #include <vector> #include <string> #include <sstream> #include <random> #include <stdexcept> #include <limits> using Board = std::vector<std::vector<int>>; const unsigned int BOARD_SIDE = 5; const int EMPTY_CELL = 0; const unsigned char EMPTY_CHAR = ' '; bool parseCoordinates(const std::string& input, int& x, int& y) { size_t sepPos = input.find_first_of(", "); if (sepPos == std::string::npos) { return false; } try { x = std::stoi(input.substr(0, sepPos)) - 1; y = std::stoi(input.substr(sepPos + 1)) - 1; } catch (const std::invalid_argument&) { return false; } catch (const std::out_of_range&) { return false; } return x >= 0 && x < BOARD_SIDE && y >= 0 && y < BOARD_SIDE; } void initBoard(Board& board) { while (true) { std::cout << "Select start (R for random, I for input): "; std::string start; std::cin >> start; if (start == "i" || start == "I") { std::cout << "Input 25 numbers separated by spaces: "; std::string input; std::cin.ignore(); std::getline(std::cin, input); std::istringstream is(input); int count = 0; bool valid = true; for (auto& row : board) { for (auto& cell : row) { if (!(is >> cell)) { std::cout << "Invalid input! Please enter exactly 25 numbers.\n"; valid = false; break; } count++; } if (!valid) break; } if (valid && count == BOARD_SIDE * BOARD_SIDE) { break; } } else if (start == "r" || start == "R") { std::cout << "Enter seed value: "; int seed; while (!(std::cin >> seed)) { std::cout << "Invalid seed! Enter an integer: "; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } std::mt19937 rng(seed); std::uniform_int_distribution<int> dist(1, 5); for (auto& row : board) { for (auto& cell : row) { cell = dist(rng); } } break; } else { std::cout << "Invalid choice! Enter R or I.\n"; } } } void printBoard(const Board& board) { std::cout << "=================" << std::endl; std::cout << "| | 1 2 3 4 5 |" << std::endl; std::cout << "-----------------" << std::endl; for (unsigned int row = 0; row < BOARD_SIDE; ++row) { std::cout << "| " << row + 1 << " | "; for (unsigned int column = 0; column < BOARD_SIDE; ++column) { if (board.at(row).at(column) == EMPTY_CELL) { std::cout << EMPTY_CHAR << " "; } else { std::cout << board.at(row).at(column) << " "; } } std::cout << "|" << std::endl; } std::cout << "=================" << std::endl; } int main() { Board board(BOARD_SIDE, std::vector<int>(BOARD_SIDE)); initBoard(board); printBoard(board); while (true) { std::cout << "Enter removable element (x, y): "; std::string removeInput; if (std::cin.peek() == '\n') { std::cin.ignore(); } std::getline(std::cin, removeInput); int x, y; if (!parseCoordinates(removeInput, x, y)) { std::cout << "Invalid input! Please enter like '3,4' or '3 4' (1-5 for x and y)\n"; continue; } board[x][y] = EMPTY_CELL; printBoard(board); } return 0; }
内容的提问来源于stack exchange,提问作者c_plusplus_beginner
相关产品推荐
相关产品推荐

