三子棋(二)

学完如何打印九宫格之后,就要开始玩家与电脑下棋的游戏过程了;

我们知道玩三子棋其实就是玩家先下一步之后,就轮到电脑下,如此往复,直至游戏结束。

但在这一过程中,其实就相当于循环(下棋的次数),玩家和电脑分开执行。

while(1){

}

所以这里,我们先完成玩家下棋的操作,这里我们用PlayerMove()自定义函数来实现玩家下棋的操作。

test.c源文件

PlayerMove(board,ROW,COL);

玩家需要在九宫格棋盘中下,其实就是在二维数组中去存数据,所以这里就要传二维数组;传行和列就是给在棋盘内下。

然后,去game.h头文件中去声明

void PlayerMove(chaer board[ROW][COL],int row,int col);

之后,再去game.c源文件中去定义函数

分析:1、玩家在九宫格中玩三子棋,其实就是往二维数组中输入数据,所以这里需要scanf函数来接受玩家输入的数值,然后进行存储。

int x=0;

int y=0;

scanf("%d%d",&x,&y);

2、在这里我们考虑玩家在九宫格中输入数据的时候,会不会不小心在已经被占用的格子中输入数据,又或者在格子之外中输入数据,因此,这里我们需要判断玩家输入的数据是否在棋盘内。

先限制输入数据的范围:(是否在棋盘内)

if(x>=1&&x<=row&&y>=1&&y<=col){

}

else{

        printf("坐标非法,请重新输入!\n");

}

这里我们知道,二维数组的下标是从00开始的,但我们要考虑到在玩家的眼中,第一个格子表示可能是11;因此,我们不能当玩这游戏的玩家都是程序员,所以这里的下标我们从视角上的感官来写11。

就是在屏幕上输入九宫格的格子位置,用视角来看。

但实际下标还是00开始的(不变的)

然后,限制完输入范围之后,就需要判断是否在已被占用的格子中又输入数据:

if(board[x-1][y-1]==' '){

            board[x-1][y-1]='*';

             break;

 }

else{

       printf("坐标被占用,请重新输入:");

}

然后,在这里去判断二维数组的时候,就是要从下标开始查询,因此,这里就要回归到我们程序的本身,所以这里要减1。

如果没有的话,就输入玩家所操作的棋子(用“*”来表示)

void PlayerMove(char board[ROW][COL],int row,int col){

                              int x=0;

                              int y=0;

                               printf("请输入:");

                              while(1){

                                          if(x>=1&&x<=row&&y>=1&&y<col){

                                                                       if(board[x-1][y-1]==' '){

                                                                                                            board[x-1][y-1]='*';

                                                                                                             break;  

                                                                                                          }

                                                                              else{

                                                                                    printf("坐标被占用,请重新输入:");

                                                                                       }

                                                                                                 }

                                          else{

                                                    printf("坐标非法,请重新输入!\n");

                                                  }

                                          }

}

这里要用循环,是用来判断玩家输入的数值是否有误;对了,就跳出循环,错了,就重新输入。

然后返回到test.c源文件中,这里玩家下棋的过程就写完了,接下来,如果想要看在棋盘输入数字的效果,则在打印——

PlayerMove(board,ROW,COL);

DisplayBoard(board,ROW,COL);

玩家写完之后,就轮到电脑写了,那该如何写呢?

这里我们就用到ComputorMove()自定义函数——

ComputorMove(board,ROW,COL);

DisplayBoard(board,ROW,COL);

这里还是一样,要让电脑输入的数据在九宫格范围内。

game.h头文件中去进行函数声明——

void ComputorMove(char board[ROW][COL],int row,int col);

game.c源文件中进行函数定义——

void ComputorMove(char board[ROW][COL],int row,int col){

                 int x=0;

                 int y=0;

                 printf("电脑输入:");

                 while(1){

                           x=rand()%row;

                           y=rand()%col;

                if(board[x][y]==' '){

                                  board[x][y]='#';

                                   break;

                                             }                              

                           }

}

这里要提一点,电脑下棋,是随机在九宫格中的位置中下的;但这里并不是和玩家一样需要玩家自己输入。

而如何让电脑下呢?

电脑在九宫格中的随机位置下,其实就用到之前所学的生成随机数——rand函数

x=rand()%row;

y=rand()%col;

这里为什么要模上row和col呢?

这是因为rand函数生成的随机数范围是0~32767之间,范围比较大,但这里我们的九宫格是3*3的布局,所以缩小了生成随机坐标的范围。(0~2之间)

因为rand函数生成的随机数只有一次,所以在使用rand函数之前要先使用srand函数,而如何使用srand,之前有讲过

srand((unsigned int)time(NULL));

在这里,就要在game.h引头文件

#include<stdlib.h>

#include<time.h>

而生成的坐标就需要判断是否被占用

注:生成的坐标已经在我们合法范围内,所以不用减1.

if(board[x][y]==' '){

        board[x][y]='#';

         break;

}

这里如果被占用的话,就不要提示了,因为是电脑在下

接下就是将判断放入循环(放入死循环)

while(1){

}

玩家和电脑下棋的过程写完之后,就需要来判断输赢了

这里我们在game函数中使用写两个自定义函数IsWin(),用来判断输赢

假设

玩家赢——返回“*”

电脑赢——返回“#”

平局——返回“Q”

结束——返回“C”

所以我们需要一个变量来接受传回来的值,然后判断是否是结束游戏

int ret=IsWin();

if(ret !='C'){

              break;

}

int ret=IsWin();

if(ret !='C'){

              break;

}

跳出循环之后,就需要判断谁赢或平局

if(ret=='*'){

                 printf("玩家赢!\n");

}

else if(ret=='#'){

                printf("电脑赢!\n");

 }

else{

          printf("平局\n");

}

在九宫格中如何判断输赢呢?

无非就是横三竖三两个斜列的棋子是否一样,所以在判断输赢的时候,其实还是在判断棋盘内的内容

所以,这里

 InWin(board,ROW,COL);

在game.h头文件声明函数——

char InWin(char board[ROW][COL],int row,int col);

在game.c源文件中定义函数

char InWin(char board[ROW][COL],int row,int col){

             int =0;

              //横三行

             for(i=0;i<row;i++){

                           if(board[i][0]==board[i][1]&&board[i][1]==board[i][2]&&board[i][0]==' '){

                                                                          return board[i][1];

                                                                              }

                                        }

             //竖三行

             for(i=0;i<row;i++){

                           if(board[0][i]==board[1][i]&&board[1][i]==board[2][i]&&board[0][i]==' '){

                                                                          return board[1][i];

                                                                              }

                                        }

              //判断是否平局

             if(1==IsFull(board,ROW,COL)){

                                                return 'Q';

                                         }

                 return 'C';

}

这里为什么判断平局还要再写一个IsFull函数呢?

这里是因为我们需要去查看二维数组中每一行和列是否有数据,如果全都有则是被占用,就返回1,没有,则返回0.

因此,这里要传的参数还是二维数组的行和列

int IsFull(char board[ROW][COL],int row,int col){

               int i=0;

               int j=0

               for(i=0;i<=row;i++){

                               for(j=0;j<=col;j++){

                                                                 if(board[i][j]==' ')

                                                                       return 0;

                                                            }

                                              }

                  return 1;

}

以上就是关于三子棋游戏实现的程序逻辑和步骤。

【注:最终代码,请根据以上内容自行编译。】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值