zemax 宏怎么编写数组_从零开始编写C语言五子棋程序1

从零开始编写C语言五子棋程序

C语言程序是国科大计算机系本科生必修课程,我选修的是武成岗老师的C语言课程。除了课上回答问题,实验课competitive programming的成绩之外,最终的大作业五子棋程序也占据了相当重的分值。除了写出基本的显示棋盘、人人对战、人机对战的功能之外,武老师对人机对战的策略提出了更高的要求。期末时每个人所写的AI会进行1对1的比赛,五子棋作业的分数与比赛排名直接挂钩(卷,就嗯卷)。开这个坑的原因有两点,一是记录自己写这个程序的过程(可能是我目前写过的代码最长的程序),理清思路同大家分享,另一方面想熟悉一下刚学的Markdown排版。(试图摆脱折磨人的公众号内部编辑)今天要解决的是第一部分,五子棋棋盘的实现。

五子棋棋盘的实现

解决这个问题可以有两种思路:

  • 利用双重循环首先构建出一个空棋盘,接着用户根据棋盘上显示的坐标实现下棋的操作,只需要把输入坐标所对应的字符替换成黑/白棋子即可。

  • 构建三个棋盘:第一个棋盘用于存放空棋盘的模板,第二个棋盘是用于在终端显示的棋盘(交互棋盘),第三个棋盘是所谓“内部棋盘”,用户输入的坐标改变的是内部棋盘上的数值,这一数值的改变反映到交互棋盘上就是黑/白棋子。

两种思路其实都可以实现棋盘的功能,在这里,我为了减轻后期调试工作的工作量,选择采取第二种方式来构建棋盘。

构建棋盘的过程中,最关键的就是二维数组的运用。二维数组和内部棋盘上的点建立起了一一映射的关系,通过改变二维数组中元素的值,即可改变棋盘上的落子情况。二维数组的相关知识,详见多维数组。

有了这个基本思想,下面我们就可以开始书写代码了。

  1. 宏定义与全局变量的声明

    #include #include #include #define SIZE 15#define CHARSIZE 2void initRecordBorard(void);void innerLayoutToDisplayArray(void);void displayBoard(void);//棋盘使用的是GBK编码,每一个中文字符占用2个字节。//空棋盘模板 char arrayForEmptyBoard[SIZE][SIZE*CHARSIZE+1] = {        "┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨",        "┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛"};//此数组存储用于显示的棋盘 char arrayForDisplayBoard[SIZE][SIZE*CHARSIZE+1];//此数组用于记录当前的棋盘的格局,即所谓“内部棋盘”int arrayForInnerBoardLayout[SIZE][SIZE];char play1Pic[]="●";//黑棋子;char play2Pic[]="◎";//白棋子;
  2. 主函数编写

    int main(){    initRecordBorard();    //初始化一个空棋盘    arrayForInnerBoardLayout[0][0]=1;    //在棋盘的左上角落一个黑色棋子    innerLayoutToDisplayArray();  //将心中的棋盘转成用于显示的棋盘    displayBoard();          //显示棋盘    getchar();       arrayForInnerBoardLayout[5][9]=2;    innerLayoutToDisplayArray();    displayBoard();    getchar();    arrayForInnerBoardLayout[3][4]=2;    innerLayoutToDisplayArray();    displayBoard();    getchar();    arrayForInnerBoardLayout[6][1]=1;    innerLayoutToDisplayArray();    displayBoard();    getchar();    arrayForInnerBoardLayout[9][4]=2;    innerLayoutToDisplayArray();    displayBoard();    getchar();    return 0;}//内部棋盘里的数组元素若为0,表示该位置为空,若为1,表示该位置落的是黑子,若为0,表示该位置落的是白子。//这是一个测试性的主函数(由于只是单纯想构建出棋盘来),整体操作分三步:落子——内部棋盘和交互棋盘的映射——显示出当前的交互棋盘棋盘的初始化
  3. 棋盘的初始化

    //初始化一个空棋盘格局 void initRecordBorard(void){    //通过双重循环,将arrayForInnerBoardLayout清0      int i,j;      for(i = 0;i<= SIZE-1 ;i++){          for(j = 0;j<= SIZE-1;j++)          arrayForInnerBoardLayout[i][j] = 0;      }}
  4. 内部棋盘和交互棋盘一一映射的构建

    //将arrayForInnerBoardLayout中记录的棋子位置,转化到arrayForDisplayBoard中void innerLayoutToDisplayArray(void){    //第一步:将arrayForEmptyBoard中记录的空棋盘,复制到arrayForDisplayBoard中        int i,j;        for(i = 0;i <= SIZE - 1;i++){           for(j = 0;j <=SIZE*CHARSIZE+1;j++)           arrayForDisplayBoard[i][j] = arrayForEmptyBoard[i][j];        }    //第二步:扫描arrayForInnerBoardLayout,当遇到非0的元素,将●或者◎复制到arrayForDisplayBoard的相应位置上    //注意:arrayForDisplayBoard所记录的字符是中文字符,每个字符占2个字节。●和◎也是中文字符,每个也占2个字节。        for( i = 0;i <= SIZE-1;i++){           for( j = 0; j <= SIZE-1;j++){            if(arrayForInnerBoardLayout[i][j]!=0){                if(arrayForInnerBoardLayout[i][j]==1){                arrayForDisplayBoard[i][2*j] = play1Pic[0];                arrayForDisplayBoard[i][2*j+1] = play1Pic[1];               }else if(arrayForInnerBoardLayout[i][j]==2){                arrayForDisplayBoard[i][2*j] = play2Pic[0];                arrayForDisplayBoard[i][2*j+1] = play2Pic[1];                }               }            }           }       }//这里涉及一个我之前没有接触过的知识点,将双字节字符赋值到字符数组里,要用连续的两个元素来进行赋值。
  5. 显示当前棋盘

    //显示棋盘格局 void displayBoard(void){    int i;    //第一步:清屏    system("clear");   //清屏      //第二步:将arrayForDisplayBoard输出到屏幕上        for(i=0;i<=SIZE-1;i++)        printf("%3d %s\n",SIZE-i,arrayForDisplayBoard[i]);    //第三步:输出最下面的一行字母A B ....         printf("   ");        for(i = 0;i<=SIZE-1;i++)        printf("%2c",'A'+i);        printf("\n");}

至此,我们已经完成了棋盘构建的全部工作,下面是程序的运行结果。

7491c68419bf48a5abe2e8d72d45e0f8.png


接下来的目标(周五前完成):

  • 胜负的判定

  • 先后手

  • 记录上一次棋子的位置

  • 输入quit退出游戏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值