关于Dev c++定义二维数组过大导致崩溃的问题

最近在用Dev c++联系c++编程,有一次在定义二维数组a[1001][1001]时Dev c++崩溃了 = =# ,
百度了一下发现是定义数组太大了,所以特意做了个实验,看看能定义最大的二维数组是多少:

#include<iostream>
using namespace std;
int main()
{
	int a[1001][1001] = {1};

	cout << a[0][0] << ' ' << a[1000][1000];
	return 0;
}

崩溃了。。
看到1001x1001时,程序崩溃了。。
经过梯度下降法(^ ^)终于找到定义上限,也就是719x719:

#include<iostream>
using namespace std;
int main()
{
//	int a[1001][1001] = {1};
	int a[719][719] = {1};

	cout << a[0][0] << ' ' << a[718][718];
	return 0;
}

success!
看来Dev c这个编译器还是有点矫情的^ ^。
那么是不是我们就没办法定义1001x1001的数组呢?当然不是啦,有个简单的方法,那就是在main函数外定义:

#include<iostream>
using namespace std;

int b[1001][1001] = {1};

int main()
{
//	int a[1001][1001] = {1};
	int a[719][719] = {1};

	cout << a[0][0] << ' ' << a[718][718];
	cout << endl;
	cout << b[0][0] << ' ' << b[1000][1000];
	return 0;
}

success x2 !
还有半个月就考ccf了,这个坑大家可得小心了~~(180块钱啊!好贵!T.T)

ccf Fan Che Le T.T

<think>好的,我现在需要帮助用户找到一个使用Dev-C++编写的五子棋小游戏源代码,要求具备双人对战和悔棋功能。首先,我得回忆一下五子棋的基本逻辑,以及如何在C++中实现这些功能。 首先,双人对战的话,需要两个玩家轮流下棋,通常用不同的符号表示,比如黑子和白子。棋盘可以用二维数组来表示,每个位置的状态(空、黑、白)存储在其中。然后,每次玩家输入坐标,检查是否合法,再更新棋盘,并判断是否有五子连珠的情况。 悔棋功能需要记录每一步的走法,可以用一个栈或者列表来保存每一步的位置和玩家。当用户选择悔棋时,弹出最近的一步或两步(因为双人轮流,悔一步可能只是回到上一个玩家,但通常悔棋是双方各退一步),然后恢复棋盘状态。 接着,界面部分,Dev-C++通常使用控制台程序,所以需要用控制台输出棋盘。可能需要用到Windows.h中的一些函数来设置光标位置,避免频繁清屏闪烁。比如用SetConsoleCursorPosition来移动光标,局部刷新棋盘。 然后,判断胜负的逻辑是关键。每次下子后,检查该位置的四个方向(水平、垂直、两个对角线)是否有连续五个相同棋子。这可以通过遍历每个方向,计数连续的棋子数来实现。 现在需要考虑代码结构。可能分为几个部分:初始化棋盘,绘制棋盘,处理输入,判断胜负,悔棋逻辑。可能需要使用结构体或类来保存棋局状态,比如每个棋步的位置和玩家。 关于悔棋的实现,可以用一个栈保存每一步的坐标。当用户输入悔棋命令时(比如输入'U'),弹出栈顶的元素,并恢复棋盘对应的位置为空。同时需要切换当前玩家,可能需要弹出两次,因为一次悔棋通常是撤销一步,但如果是双人轮流,可能需要双方各退一步?或者用户希望一次悔棋只撤销一步,由对方继续下。这里需要明确需求,通常悔棋是撤销一步,轮到对方下。但用户可能希望每次悔棋撤销一步,所以需要处理这种情况。 可能的代码结构: 1. 定义棋盘小,比如15x15。 2. 二维数组存储棋盘状态。 3. 当前玩家变量,交替切换。 4. 栈保存历史步骤。 5. 主循环:显示棋盘,获取输入,处理命令(下棋或悔棋),判断胜负。 输入处理方面,可能需要让用户输入坐标,如行和列,或者合并输入如“A15”这样的形式,但控制台处理可能麻烦,所以直接输入数字更简单,比如输入行和列的数字,或者用字母和数字组合,需要转换。 悔棋命令的触发,比如输入'U'表示悔棋,这时候从栈中弹出最近的一步,将对应位置置空,并切换玩家。但需要考虑栈是否为空的情况。 绘制棋盘时,需要显示行列号,方便用户输入。可以用循环打印每个格子,用字符表示棋子,比如'O'和'X',或者使用更复杂的符号。 示例代码的致流程: 初始化棋盘,历史栈,当前玩家。 循环: 清屏或刷新棋盘。 显示当前玩家。 获取输入。 如果输入是悔棋命令: 如果栈不为空,弹出最后一步,恢复棋盘,切换玩家。 否则: 解析坐标,检查是否合法(是否在棋盘内,是否为空)。 如果合法,落子,记录到历史栈,切换玩家。 检查是否胜利,如果胜利则结束游戏。 判断胜利的函数:检查当前落子点的四个方向是否有连续五个。 现在,代码中需要注意的细节: 1. 输入处理:如何读取用户输入,可能需要处理不同输入方式,比如先输入行再列,或者用逗号分隔。 2. 棋盘显示:每次更新后如何刷新,避免闪烁,可能需要使用光标定位函数。 3. 悔棋栈的实现:每次落子时将坐标和玩家存入栈,但可能只需要存储坐标,因为玩家交替,所以可以根据栈的长度判断当前玩家。 4. 胜负判断的效率:每次落子后只需要检查当前落子点周围是否形成五连,而不需要全盘扫描。 可能的错误点: - 忘记切换玩家。 - 栈在悔棋时弹出后未正确恢复棋盘。 - 坐标转换错误,比如用户输入1-based,而数组是0-based。 - 胜负判断逻辑遗漏某些方向或边界条件。 现在,编写示例代码: 使用控制台,棋盘小为15x15,用二维数组,字符显示,'O'和'X'代表棋子,历史步骤用栈存储,每次悔棋弹出一步。 代码的纲: #include <iostream> #include <stack> #include <conio.h> #include <windows.h> using namespace std; const int SIZE = 15; char board[SIZE][SIZE]; stack<pair<int, int>> history; enum Player { BLACK, WHITE }; Player current = BLACK; void initBoard() { for (int i=0; i<SIZE; ++i) for (int j=0; j<SIZE; ++j) board[i][j] = '.'; } void drawBoard() { system("cls"); // 显示列号 cout << " "; for (int j=0; j<SIZE; ++j) cout << j%10 << ' '; cout << endl; for (int i=0; i<SIZE; ++i) { cout << i%10 << ' '; for (int j=0; j<SIZE; ++j) { cout << board[i][j] << ' '; } cout << endl; } cout << "Current player: " << (current == BLACK ? "Black(O)" : "White(X)") << endl; cout << "Input row col (like 3 5), or U to undo: "; } bool checkWin(int row, int col) { char target = current == BLACK ? 'O' : 'X'; int directions[4][2] = {{1,0}, {0,1}, {1,1}, {1,-1}}; for (auto d : directions) { int dx = d[0], dy = d[1]; int count = 1; // 向正方向检查 int x = row + dx, y = col + dy; while (x >=0 && x < SIZE && y >=0 && y < SIZE && board[x][y] == target) { count++; x += dx; y += dy; } // 向反方向检查 x = row - dx; y = col - dy; while (x >=0 && x < SIZE && y >=0 && y < SIZE && board[x][y] == target) { count++; x -= dx; y -= dy; } if (count >=5) return true; } return false; } int main() { initBoard(); bool gameover = false; while (!gameover) { drawBoard(); string input; cin >> input; if (input == "U" || input == "u") { if (!history.empty()) { auto last = history.top(); history.pop(); board[last.first][last.second] = '.'; current = current == BLACK ? WHITE : BLACK; // 切换回上一个玩家 } continue; } int row = stoi(input); int col; cin >> col; // 检查输入是否合法 if (row <0 || row >= SIZE || col <0 || col >= SIZE) { cout << "Invalid position!" << endl; continue; } if (board[row][col] != '.') { cout << "Position occupied!" << endl; continue; } // 落子 board[row][col] = current == BLACK ? 'O' : 'X'; history.push({row, col}); // 检查胜利 if (checkWin(row, col)) { drawBoard(); cout << (current == BLACK ? "Black" : "White") << " wins!" << endl; gameover = true; break; } // 切换玩家 current = current == BLACK ? WHITE : BLACK; } return 0; } 可能的改进点: 1. 使用更精确的光标控制来避免清屏闪烁,比如使用Windows API的SetConsoleCursorPosition函数。 2. 输入错误处理,比如非数字输入。 3. 悔棋可能允许次,只要栈不为空。 4. 显示更友好的界面,比如颜色区分棋子。 现在需要检查代码是否满足用户需求:双人对战、悔棋。是的,双人轮流下,输入U悔棋,历史记录存储在栈中,每次悔棋一步,切换回上一个玩家。 可能的问题: - 在输入时,如果用户输入非U或数字,程序会崩溃,比如输入字母。需要处理异常,比如用try-catch块处理stoi转换错误。 - 棋盘显示可能因为system("cls")而闪烁,可以改用更局部的刷新方式。 - 行列的显示是否正确,比如用户输入0-based还是1-based?代码中是0-based,但用户可能需要输入1-based,导致坐标错误。需要明确说明输入方式。 改进后的输入处理: 在代码中,用户输入的行列是0-based吗?例如,输入0 0对应左上角。但用户可能习惯输入1-based,比如1到15。所以可能需要调整输入的坐标减1。 修改代码中的输入部分: 将输入的row和col减1: int row = stoi(input) - 1; cin >> col; col -= 1; 同时,在提示中说明输入是1-based还是0-based。或者在绘制棋盘时显示行列号,让用户知道如何输入。 另外,关于输入错误,比如输入字母,会导致stoi抛出异常,程序崩溃。因此需要用try-catch块: 例如: try { int row = stoi(input) - 1; cin >> col; col -= 1; } catch (...) { cout << "Invalid input!" << endl; continue; } 综上,代码需要进一步优化错误处理,并可能调整输入为1-based。</think><< 以下是具备双人对战和悔棋功能的五子棋C++代码示例: ```cpp #include <iostream> #include <stack> #include <conio.h> #include <windows.h> using namespace std; const int SIZE = 15; char board[SIZE][SIZE]; stack<pair<int, int>> history; enum Player { BLACK, WHITE }; Player current = BLACK; void initBoard() { for (int i = 0; i < SIZE; ++i) for (int j = 0; j < SIZE; ++j) board[i][j] = '.'; } void gotoXY(int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void drawBoard() { system("cls"); cout << " "; for (int j = 0; j < SIZE; ++j) printf("%2d", j+1); cout << "\n"; for (int i = 0; i < SIZE; ++i) { printf("%2d ", i+1); for (int j = 0; j < SIZE; ++j) { cout << board[i][j] << ' '; } cout << endl; } cout << "\n当前玩家: " << (current == BLACK ? "黑棋(O)" : "白棋(X)") << endl; cout << "输入坐标(例:3 5)或 U 悔棋: "; } bool checkWin(int row, int col) { char target = current == BLACK ? 'O' : 'X'; int dirs[4][2] = {{1,0}, {0,1}, {1,1}, {1,-1}}; for (auto &dir : dirs) { int count = 1; int dx = dir[0], dy = dir[1]; for (int i = 1; ; ++i) { int x = row + dx*i; int y = col + dy*i; if (x < 0 || x >= SIZE || y < 0 || y >= SIZE) break; if (board[x][y] != target) break; count++; } for (int i = 1; ; ++i) { int x = row - dx*i; int y = col - dy*i; if (x < 0 || x >= SIZE || y < 0 || y >= SIZE) break; if (board[x][y] != target) break; count++; } if (count >= 5) return true; } return false; } int main() { initBoard(); bool gameover = false; while (!gameover) { drawBoard(); string input; cin >> input; if (input == "U" || input == "u") { if (!history.empty()) { // 悔棋需要回退两步(双方各退一步) for (int i = 0; i < 2 && !history.empty(); ++i) { auto last = history.top(); history.pop(); board[last.first][last.second] = '.'; } current = BLACK; } continue; } try { int row = stoi(input) - 1; int col; cin >> col; col -= 1; if (row < 0 || row >= SIZE || col < 0 || col >= SIZE) { cout << "坐标超出范围!"; getch(); continue; } if (board[row][col] != '.') { cout << "该位置已有棋子!"; getch(); continue; } board[row][col] = (current == BLACK) ? 'O' : 'X'; history.push({row, col}); if (checkWin(row, col)) { drawBoard(); cout << "\n恭喜" << (current == BLACK ? "黑棋" : "白棋") << "获胜!"; gameover = true; break; } current = (current == BLACK) ? WHITE : BLACK; } catch (...) { cout << "输入格式错误!"; getch(); } } return 0; } ``` 实现原理: 1. 双人对战:通过交替切换current变量实现玩家轮流下棋 2. 悔棋功能:使用stack数据结构存储历史记录,回退时弹出最近记录 3. 胜负判断:每次落子后检查四个方向是否形成五连 4. 界面显示:使用Windows API实现光标定位,优化显示效果 注意事项: 1. 输入坐标时使用1-based索引(如1-15) 2. 输入U执行悔棋操作(回退双方各一步) 3. 棋盘使用字符'O'和'X'表示棋子 4. 使用conio.h实现按键暂停功能 >>
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值