[C语言笔记]与Nios34一同开发扫雷:(2)开发过程中
前言
虽然已经不是第一次敲代码了,但是我对我的编程能力还是很没自信。我们总会解决问题的(实在不行还能求助)。
man-page is useful
在这之前Nios已经多次强调过man-page的作用,在这次开发中也多次向我展示了man-page的使用。
当然在man page-ArchWiki中有更为详细的讲解,在这里不多赘述。
在我们这次的编程过程中可以通过man ncurses来查看ncurses的手册,上面会详细的写出这个库的作用和其中函数的使用方法。在遇到问题时可以多使用man,man真的真的很有用。
代码
由于我的代码阅读能力和记性很差,所以先看看主函数回忆一下我们写了什么吧。
int main(int argv, const char **argc)
{
// Initialization the game's window.
// initscr函数来自<ncurses.h>,它在一个程序中只能调用一次。如果成功,它返回一个指向stdscr结构的指针;如果失败,它就输出一条诊断错误信息并使程序退出。在这里我们用它来初始化整个程序。
initscr();
// noecho的功能就是字面意思:关闭回显(按下一个字符之后,在屏幕不显示它)。
noecho();
// 这里的代码引用了主函数外的变量和函数row(),功能就如字面意思,初始化然后开始游戏。
start: { total_revealed = 0; }
for(int a=0; a<10; a+=2 ){
row(a);
}
// Create the chessboard-map
// 我们先要弄清楚坐标的概念,然后用xy轴的坐标表示我们的“棋盘”的每一个元素。
// 在这里我们使用了之前写的函数来创建并初始化整个游戏的棋盘,程序将在终端里用字符画出整个棋盘的样子。
Block map[MAP_MAX_Y][MAP_MAX_X];
map0(map);
// Vcursor in the window when the game start.
//我们在这个程序中定义了一个虚拟光标来代替本来的光标在棋盘中移动。
Position vcur = { .x = 0, .y = 0 };
vcur_to_cur(&vcur);
//接着是按键的分配了
while (1) {
switch (getch()) {
// 按下Q键退出程序。
case 'q':
// endwin()将清除ncurses中所有已分配的资源,并将tty模式恢复为调用initscr()之前的状态;
// 必须在ncurses库中的任何其他函数之前调用它,并且必须在程序退出之前调用endwin()。
endwin();
// 退出程序。
goto exit;
break;
// 按下R键重置游戏。
case 'r':
// erase意为抹去,此函数用于在顺序型容器中删除容器的一个元素.
erase();
// 跳转到start,重新开始游戏.
goto start;
break;
// 下面就是wsad控制上下左右;
// < w > for up.
case 'w':
// 在这里限制上移的边界;
if(vcur.y == 0) break;
// 我们让虚拟光标在按下W键时可以向上走一“格”。
vcur.y -= 1;
vcur_to_cur(&vcur);
break;
// 下移左移右移基本同理。
// down.
case 's':
if (vcur.y == 4) break;
vcur.y += 1;
vcur_to_cur(&vcur);
break;
// left.
case 'a':
if(vcur.x == 0) break;
vcur.x -= 1;
vcur_to_cur(&vcur);
break;
// right.
case 'd':
if(vcur.x == 9) break;
vcur.x += 1;
vcur_to_cur(&vcur);
break;
// 随后就是重头戏,关于扫雷怎么扫,我们在这里用L键
// sweeping.
case 'l':
if (map[vcur.y][vcur.x].flags & FLAG)
break;
//下面我们用星号*表示水雷,并在扫到雷时在棋盘里输出“You failed!"
// mine swept
if (map[vcur.y][vcur.x].flags & MINE) {
mvaddch(resolve_Y(vcur.y), resolve_X(vcur.x), '*');
mvaddstr(5, 3, "You failed!");
// getch这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取。
// 我们用它来实现游戏失败后按下任意键重置游戏。
getch();
erase();
goto start;
} else
reveal(map, vcur.y, vcur.x);
vcur_to_cur(&vcur);
break;
//下面是按下K键插旗子(标记)的代码,在有旗子的格子里按K则会变回空白格。
case 'k':
if (map[vcur.y][vcur.x].flags & REVEALED)
break;
if (map[vcur.y][vcur.x].flags & FLAG) {
mvaddch(resolve_Y(vcur.y), resolve_X(vcur.x), ' ');
// Remove the flag.
map[vcur.y][vcur.x].flags &= ~FLAG;
} else {
mvaddch(resolve_Y(vcur.y), resolve_X(vcur.x), '^');
// Add the flag.
map[vcur.y][vcur.x].flags |= FLAG;
}
vcur_to_cur(&vcur);
break;
}
//游戏胜利的判定,输出"You won!"。
if (total_revealed == (MAP_MAX_X * MAP_MAX_Y - MAP_MINE_COUNT)) {
mvaddstr(5, 3, "You won!");
getch();
erase();
goto start;
}
}
exit: {}
return 0;
}
小结
写代码真的好难,但是我也很想尝试学会它。程序的其他部分我打算放在后面几章写,暂时先这样吧!
Ask yourself whether you are happy and you cease to be so. -- John Stuart Mill

浙公网安备 33010602011771号