此博客是这一篇博客的扩展只用C语言基础语法就能完成扫雷?-CSDN博客
此版相较于初篇的重要修改是棋盘的显示效果
这个显示效果优化我是从两个方面入手的
1,看起来更像个棋盘,而不仅仅只是一堆数字
2,优化了棋盘的打印逻辑,现在再打印行列数超过9的棋盘时不会再错行打印
首先是第一点
看起来更像个棋盘,而不仅仅只是一堆数字
这是上一版本棋盘打印的样子
这是优化后棋盘打印的样子
这个优化只用修改打印棋盘函数即可完成
下面这个是原来的打印函数定义
void printfboard(char board[ROWS][COLS], int row, int col)//棋盘打印函数
{
int i = 0;
int j = 0;
int k = 0;
printf("-------------------\n");
for (i = 0;i < row + 1;i++)
{
printf("%d ", i);//打印横坐标
}
printf("\n");
for (i = 1;i <= row; i++)
{
printf("%d ", i);//打印纵坐标
for (j = 1;j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("-------------------\n");
}
那么是怎么修改的呢?看我一步一步的来
我以这张图为例
首先我们要知道,终端中的打印是一行一行且从左到右打印的,也就是说,在我们分析如何优化时,想的应该是如何一行一行,从左到右打印出一个棋盘,并且棋盘中间还能正常显示数字
其次再是打印过程
看图中从上而下的第一个红色方框
那是我们在上一节就写出来的行列数打印,方便我们看出坐标,此处暂未进行修改,所以忽略
第二个方框中"1"的后面打印流程其实是(空格) *(空格) | (空格) * (空格) | (空格) * (空格) | (空格) * (空格) | .....
稍稍观察便会发现这一行的打印就只是"(空格) * (空格) | "的循环".而"*"元素就是我们打印的棋盘元素,换句话说,我们仅仅是添加了一个通道符"|"来美观棋盘
因此,我们便可以写出这么一串代码
void printfboard(char board[ROWS][COLS], int row, int col)//棋盘打印函数
{
int i = 0;
int j = 0;
printf("-------------------\n");
for (i = 0;i < row + 1;i++)
{
printf("%d ", i);//打印横坐标
}
printf("\n");
for (i = 1;i <= row; i++)
{
printf("%d ", i);//打印纵坐标
for (j = 1;j <= col; j++)
{
printf(" %c |", board[i][j]);
}
printf("\n");
}
printf("-------------------\n");
}
这串代码与上一串代码唯一的差别就是在打印棋盘元素时,并不是
printf("%c ", board[i][j]);
而是变成了
printf(" %c |", board[i][j]);
(仔细观察会发现只是在%c前加了一个空格,和%c(空格)后加了一个通道符 |
按照此代码,我们打印的结果如下
最显而易见的是,这个原本应该是正方形的棋盘,不正了.这是因为我们在打印一个%c元素时,额外打印了两个字符导致的,是正常现象.另外一个小细节,有没有发现每一行的最后都多打印了一个通道符?这样看起来并不太左右对称,想在每次打印时不打印最后一个通道符的话,,,好像有点难.毕竟我们上述代码是没打印一个%c元素就一定会在这个元素后添加一个通道符...想做到最后一个通道符不打印的话,可以将通道符的打印和%c元素的打印分开打,这样我们就可以在打印最后一个%c元素时,选择不打印最后一个元素的通道符
修改代码如下
for (j = 1;j <= col; j++)
{
printf(" %c ", board[i][j]);
if (j < col)
printf("|");
}
这样,当j = col时,管道符就不会再打印了,而%c元素仍然会打印
效果图
至此,我们完成了第二行打印的代码.如果理解了第二行代码的话,那么第三行代码就也很容易理解了
首先我们继续分析一下这个第二行代码
排除掉最前面的两个"--",再与上一行对比我们会发现这一行的打印逻辑和上一行如出一辙."---"对应着"(空格) * (空格)''.而加号"+"则对应着管道符" | ".既然知道了打印逻辑,那么代码便也好写了:
在第二行打印完后,接着打印第三行内容
for (j = 1;j <= col; j++)
{
printf(" %c ", board[i][j]);
if (j < col)//列符号
printf("|");
}
printf("\n");
if (i < row)
{
printf("--");
for (k = 0;k < col;k++)
{
printf("---");
if (k < col - 1)
printf("+");
}
printf("\n");
}
如果仔细对比的话,会发现if(i< row){}的打印逻辑和for (j = 1;j <= col; j++)几乎相同,唯一的差别是if中多了"--"的打印,而这个打印是与前面行列数的打印相对应的
修改为上述代码后运行结果如下
可以发现我们棋盘打印的很像个棋盘了
现在唯一扎眼的就是第一行的行列数了.理解了上面的内容,那么你大概也能猜到这个怎么修改了,只需要在打印行列数时,将原代码
for (i = 0;i < row + 1;i++)
{
printf("%d ", i);//打印横坐标
}
%d(空格)修改为(空格)(空格)(空格)%d,如下代码
for (i = 1;i < row + 1;i++)
{
printf(" %d", i);//打印横坐标
}
(注意修改后for循环从i = 1 开始,如果想问为什么的话,那你改回0就知道了)
打印结果如下
至此,我们便做到让棋盘更像个棋盘了
优化了棋盘的打印逻辑,再打印行列数超过9的棋盘时不会再错行打印
如果仔细辨别的话,我们会发现错行打印的原因其实是由于行列数错位打印才导致我们整个棋盘看起来是错位的
初版时的打印错位 ------------------------------优化棋盘后的打印错位
可以发现初版由于没有棋盘,行数打印错位使其看起来更加的乱.
另一方面,由于列数打印错位,会导致9列之后的纵坐标无法与列数对齐.
分析到这,我们便可以很容易的意识到,只需要给打印行列数的代码进行修改即可.
我先截取出初版中的行列数打印代码
for (i = 1;i < row + 1;i++)
{
printf(" %d", i);//打印横坐标
}
printf("\n");
for (i = 1;i <= row; i++)
{
printf("%d ", i);//打印纵坐标
可以发现当我们在打印9这种单数字时,printf函数打印的内容是"(空格)(空格)(空格) 9 ",一共占据了4个打印位.而如果是打印10这种双数字时,printf函数打印的内容是"(空格)(空格)(空格) 1 0 '',一共占据了5个打印位.这也正是我们打印行列数在9以上的棋盘时,棋盘会错位的根本原因了.
那么,知道了这些,是不是已经想到方法去解决了呢?其实很简单,只要选择打印10以下的行列数时打印内容为"(空格)(空格)(空格) 9 ",而当行列数在9以上时,打印内容为"(空格)(空格) 1 0 ".这样就能控制打印行列数时不错位了.
说白了就是将一个空格符替换为了数字
我自己写的优化代码如下
for (i = 1;i < row + 1;i++)
{
if (i > 9)
printf(" %d", i);
else
printf(" %d", i);//打印横坐标
}
printf("\n");
for (i = 1;i <= row; i++)
{
if (i > 9)
printf("%d", i);//打印纵坐标
else
printf("%d ", i);
最后,附上这次优化过的棋盘打印函数,与初版相比,这次优化只修改了棋盘打印函数,其它处的代码并未修改
void printfboard(char board[ROWS][COLS], int row, int col)//棋盘打印函数
{
int i = 0;
int j = 0;
int k = 0;
printf("-------------------\n");
for (i = 1;i < row + 1;i++)
{
if (i > 9)
printf(" %d", i);
else
printf(" %d", i);//打印横坐标
}
printf("\n");
for (i = 1;i <= row; i++)
{
if (i > 9)
printf("%d", i);//打印纵坐标
else
printf("%d ", i);
for (j = 1;j <= col; j++)
{
printf(" %c ", board[i][j]);
if(j<col)
printf("|");
}
printf("\n");
if (i < row)
{
printf("--");
for (k = 0;k < col;k++)
{
printf("---");
if (k < col - 1)
printf("+");
}
printf("\n");
}
}
printf("-------------------\n");
}
另外,我尝试更新一个难度选择的菜单,但是由于vs2022的编译器不支持变长数组,所以暂缓了.下次扫雷应该就是更新这个