BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #95343同步于 2017/5/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

【问题】请大神看看这个2048小游戏的程序的bug怎么调?谢谢!

singingwheat
2017/5/20镜像同步6 回复
昨天也发这个帖子用markdown不知道为什么变成了502 bad gateway,帖子也删不掉了,我重新发一下,请大家不要在意。 程序全部代码如下: #include<iostream> #include <iomanip> #include<math.h> #include<stdlib.h> #include<time.h> #include <conio.h> //为了读取方向键 #include<windows.h> using namespace std; // 游戏矩形边长:4格 #define LINE_LENGTH 4 // 定义操作方向:上、下、左、右 typedef enum { E_DIR_UP, E_DIR_DOWN, E_DIR_LEFT, E_DIR_RIGHT, MAX_E_DIR } E_DIR; // 定义各游戏矩形中的各节点 typedef struct _S_NODE { int val; // 节点数值:0 无数据(空白);2^n 游戏数据 struct _S_NODE *neighbers[MAX_E_DIR]; // 上、下、左、右各方向的链表节点 } S_NODE; // 定义完整的游戏矩形 typedef struct _S_SQUARE{ int score; // 成绩,即当前最大的节点数值 S_NODE nodes[LINE_LENGTH][LINE_LENGTH]; // 各节点:边长 * 边长(4 * 4) S_NODE *walls[MAX_E_DIR][LINE_LENGTH]; // 各边节点指针:方向 * 边长(4 * 4) } S_SQUARE; // 初始化游戏矩形 void init_2048(S_SQUARE *square); // 在游戏矩形中空白位置随机产生一个数值(2或4) int generate_2048(S_SQUARE *square); // 按用户操作方向排列、合并矩形数据 int move_2048(S_SQUARE *square, E_DIR dir); // 显示游戏矩形的当前状态 void draw_2048(S_SQUARE *square); // 开始游戏,并进行游戏控制 void start_2048(void); // 初始化游戏矩形 // NOTICE:square的内存分配由调用者保证 void init_2048(S_SQUARE *square) { int i; int j; // 初始化各节点 for (i = 0; i < LINE_LENGTH; i++) { for (j = 0; j < LINE_LENGTH; j++) { square->nodes[i][j].val = 0; // 建立各节点间的链表关系 square->nodes[i][j].neighbers[E_DIR_UP] = ((i > 0) ? &square->nodes[i - 1][j] : NULL); square->nodes[i][j].neighbers[E_DIR_DOWN] = ((i < LINE_LENGTH - 1) ? &square->nodes[i + 1][j] : NULL); square->nodes[i][j].neighbers[E_DIR_LEFT] = ((j > 0) ? &square->nodes[i][j - 1] : NULL); square->nodes[i][j].neighbers[E_DIR_RIGHT] = ((j < LINE_LENGTH - 1) ? &square->nodes[i][j + 1] : NULL); } } // 初始化各方向的边节点 for (i = 0; i < LINE_LENGTH; i++) { square->walls[E_DIR_UP][i] = &square->nodes[0][i]; square->walls[E_DIR_DOWN][i] = &square->nodes[LINE_LENGTH - 1][i]; square->walls[E_DIR_LEFT][i] = &square->nodes[i][0]; square->walls[E_DIR_RIGHT][i] = &square->nodes[i][LINE_LENGTH - 1]; } } // 在游戏矩形中空白位置随机产生一个数值(2或4) // 返回值:0 游戏继续;-1 游戏结束 int generate_2048(S_SQUARE *square) { int ret = -1; // 获取所有的空白位置 S_NODE *freenodes[LINE_LENGTH * LINE_LENGTH]; int freenodes_num = 0; int i; for (i = 0; i < LINE_LENGTH; i++) { for (int j = 0; j < LINE_LENGTH; j++) { if (square->nodes[i][j].val == 0) { freenodes[freenodes_num] = &square->nodes[i][j]; freenodes_num++; } } } // 在空白位置中随机位置产生一个随机数 int gen_idx = rand() % freenodes_num; int gen_val = ((rand() % 2) ? 4 : 2); S_NODE* gennode = freenodes[gen_idx]; gennode->val = gen_val; // 还有空白节点,游戏继续 if (freenodes_num > 1) { return 0; } // 虽然没有空白节点了,但是还可以合并,所以游戏继续 for (i = 0; i < MAX_E_DIR; i++) { if (gennode->neighbers[i] && gennode->neighbers[i]->val == gennode->val) { ret = 0; break; } } return ret; } // 按用户操作方向排列、合并矩形数据 // 返回值:0 成功;-1 失败(无任何移动或合并) int move_2048(S_SQUARE *square, E_DIR dir) { int ret = -1; // 取得需合并节点所在的方向(用户操作的反向) E_DIR reverse; switch (dir) { case E_DIR_LEFT: reverse = E_DIR_RIGHT; break; case E_DIR_RIGHT: reverse = E_DIR_LEFT; break; case E_DIR_UP: reverse = E_DIR_DOWN; break; case E_DIR_DOWN: reverse = E_DIR_UP; break; } S_NODE *walls = square->walls[dir]; for (int i = 0; i < LINE_LENGTH; i++) { // 从边节点开始,逐个节点开始合并 S_NODE *last = walls[i]; S_NODE *node = last->neighbers[reverse]; for ( int j = 1; j < LINE_LENGTH; j++, node = node->neighbers[reverse]) { if (node->val == 0) { continue; } if (last->val == 0) { last->val = node->val; node->val = 0; ret = 0; continue; } if (last->val == node->val) { last->val += node->val; //设置得分 if (last->val > square->score) { square->score = node->val; } node->val = 0; last = last->neighbers[reverse]; ret = 0; continue; } last = last->neighbers[reverse]; if (last != node) { last->val = node->val; node->val = 0; ret = 0; } } } return ret; } // 显示游戏矩形的当前状态 void draw_2048(S_SQUARE *square) { system("cls"); system("color 6f"); cout<<setw(50)<<" |-----------------------|"<<endl; for ( int i = 0; i < LINE_LENGTH; i++) { cout<<setw(24)<<""; for ( int j = 0; j < LINE_LENGTH; j++) { if (square->nodes[i][j].val == 0) { cout<<setw(2)<<"|"<<setw(4)<<" "; } else { cout<<setw(2)<<"|"<<setw(4)<<square->nodes[i][j].val; } } cout<<setw(2)<<"|"<<endl; cout<<setw(50)<<" |-----------------------|"<<endl; } cout<< setw(46)<< "Score:"<< square->score<<endl; } // 开始游戏,并进行游戏控制 void start_2048(void) { S_SQUARE *square = NULL; memset(square, 0, sizeof(S_SQUARE)); init_2048(square); generate_2048(square); draw_2048(square); //等待用户输入,并进入游戏处理 while (1) { int key = _getch(); E_DIR dir; int ret; switch (key) { //Direction Key case 75: dir = E_DIR_LEFT; break; case 80: dir = E_DIR_DOWN; break; case 77: dir = E_DIR_RIGHT; break; case 72: dir = E_DIR_UP; break; default: continue; } //判断本次移动是否有效,无效时等待新的其他输入。 if (move_2048(square, dir) != 0) { break; } ret = generate_2048(square); draw_2048(square); } // 本次游戏结果输出 if(square->score >= 2048 ) { cout << "您赢了,您的得分:" << square->score << endl; } else { cout << "您输了,您的得分:" << square->score << endl; } free(square); square = NULL; } int main(int argc, const char *argv[]) { cout<< "你好,2048!" << endl; start_2048(); cout<< "游戏结束!" << endl; getchar(); return 0; } 这是2048游戏的全部代码,但是这段程序有5个bug,如下: 1) 程序存在一个编译问题。 2) 修改完编译问题后,游戏启动后就发生程序崩溃,无法运行。 3) 游戏开始后,在连续向同一个方向操作几次后,在存在空白区域的情况下,程序提前结束。 4) 游戏最高得分的显示不正确。 5) 游戏无空白区域且不能移动时,游戏不结束。 现在第一个bug我改出来了,是应给先new一个square变量,但是第二个错误调了两天也没调出来,不知道是不是因为我第一个bug改的就不对,还是就是我调不出来第二个错误,请大神帮我看看这第二个bug怎么调,谢谢!
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
FromSixToTen机器人#1 · 2017/5/20
好的,不介意。 @zc199102 @chaoshen
kitakami机器人#2 · 2017/5/20
无法运行是哪里来的错误345啊… 发自「贵邮」
bond1993机器人#3 · 2017/5/20
You'd better do homework by yourself
aq222po机器人#4 · 2017/5/23
怀疑大二
vi机器人#5 · 2017/5/24
设置断点,单步调试啊。程序的逻辑错误征兆都很明显,自己耐心一点都能解决
Vampire机器人#6 · 2017/5/28
樓主不要放棄學習機會……