三子棋

三子棋
在这个程序里面总共包含了5个子函数,和一个main函数。接下来逐个分析一下每个函数的构建思路。
1.初始化函数。
该部分函数主要对棋盘内的9个空格进行赋值,一般情况下我们把它们设为空格,这里我把它设为‘0’,不是空格也无大碍。这是很简单的一部分,只需要些两个for循环就可以把初始化完成。
对于传参这部分,需要把数组board传进去,因为我们要用数组对棋盘进行初始化,还需要row和col两个参数,来控制棋盘的大小。

void InitBoard(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++)
        {
            board[i][j]='0';
        }
    }

}`

2.显示棋盘
这里也是比较简单的一部分,只需要一个for循环就可以完成。对于格子里的横线竖线,我们可以自己调整到自己喜欢的样子,我这里没有画出外面的一圈线,因为我发现不太好画,画出来不美观。
传参同样需要数组board和row、col,和初始化函数一致。

void PrintBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
        if(i != row-1)
        printf("---|---|---\n");
    }
}

3.电脑走
这里是玩家先走还是电脑先走,是我们自己定的,我这里定的电脑先走,毕竟电脑下这个三子棋不会思考,所以让它先走吧,不要欺负它嘛!
先说传参的部分,与上面的部分一致,需要一个数组,还需要知道行和列。
要想电脑走到任意一个位置,这里我们就用到了一个生成随机数的关键字rand,但是事先我们要在测试文件中定义srand((unsigned int)time(NULL)),这样子才可以使用rand()。然后我们用rand模上行和列,就得到了电脑要下的位置,行和列是3,所以我们模3的结果就是0-2,就是棋盘数组的下标,这就是我们为什么要模3的原因。
还需要注意的一点就是,电脑在下的时候,需要判断该位置是否已经被占了,如果被占了,肯定是不能下这个地方的,所以这个地方用一个if,判断一下,就OK了,因为我的初始化是设为0,所以如果该位置不为0,那就可以下。

void ComMove(char board[ROW][COL],int row,int col)
{
    int x = 0;
    int y = 0;
    printf("电脑走!\n");
    while(1)
    {
        x = rand()%row;//因为下标是0-2,所以这里模3
        y = rand()%col;
        if(board[x][y] =='0')
        {
            board[x][y] ='2';
            break;
        }
    }
}

4.玩家走
玩家走的时候,也需要考虑和电脑走的时候同样的问题,一个是该位置是否被占,一个是玩家输入座标是否合法。
## 判断是否被占 ##
假如玩家输入x和y,x和y就要在1-3之间,这样子才能匹配棋盘位置,然后数组里面的部分就要写成x-1和y-1,因为数组下标从0开始,下标与顺序差1。
其实也可以规定输入x和y要在0-2之间,这样子数组里面就不用改了,只是玩家要清楚位置与下标之间的关系。
## 判断输入是否合法 ##
这里与电脑输入一样,判断要下的位置是否为0,不是0才可以下到该位置。否则输出“座标非法!重新输入”,我们可以看见把printf(“玩家走!\n”)放在while(1)外面,就是为了不重复显示“玩家走”,重复显示“请输入座标”就可以了!

void PlayerMove(char board[ROW][COL],int row,int col)
{
int x = 0;
int y = 0;
printf("玩家走!\n");
while(1)
{
printf("请输入座标(x,y):");
scanf("%d%d",&x,&y);
if(((x>=1) && (x<=row)) &&((y>=1) &&( y<=col)))
{
if(board[x-1][y-1] == '0')
{
board[x-1][y-1] ='1';
break;
}
else
{
printf("该位置被占用!");
}
}
else
{
printf("座标错误!");
}
}
}

5.判断输赢
这里我们知道有8种赢的局面,横着3个相同的相连有3种,竖着也有3种,还有斜着的有2种。
所以只要我们判断出是否有上述8种情况出现,就可以判断出输赢。不过我们还不知道谁输谁赢,所以我们要判断出现“赢”的情况时,那一步是谁下的。所以我们的思路是,电脑或者玩家走,判断输赢,打印棋盘,打印谁输谁赢。

`char CheckWin(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for(i=0; i<row; i++)   
  {      
      if((board[i][0]==board[i][1] )&& 
         (board[i][1]==board[i][2])&&  
         (board[i][1]!=' '))       
          return board[i][1];    
  } 
  for(i=0; i<col; i++)    
  {     
      if((board[0][i]==board[1][i])&& 
         (board[1][i]==board[2][i])&& 
         (board[1][i]!=' '))      
         return board[1][i];   
  }  
    if((board[0][0]==board[1][1])&&
        (board[1][1]==board[2][2])&&
        (board[1][1]!=' '))      
        return board[1][1];  
    if((board[0][2]==board[1][1])  
        &&(board[1][1]==board[2][0])  
        &&(board[1][1]!=' '))      
        return board[1][1];  

    if(is_full(board,row,col))
    {
        return 'q';
    }
    return ' ';
}`
static int is_full(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;
        }
    }
}

5个函数就写好了,我们把它们放在game.c里面

接下来,还需要一个测试文件test.c,把我们写的game.c运行起来。

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
//测试的代码都放到test文件里面,游戏的代码都放到game文件里面
void menu()
{
    printf("*****1.play 0.exit*****\n");
}
//1.打印棋盘 玩家走;请输入座标;判断输赢;电脑走;判断输赢
void game()
{
    char arr[ROW][COL]={0};
    InitBoard(arr,ROW,COL);
    PrintBoard(arr,ROW,COL);
    while(1)
    {
        ComMove(arr,ROW,COL);
        PrintBoard(arr,ROW,COL);

        CheckWin();
        PlayerMove(arr,ROW,COL);
        PrintBoard(arr,ROW,COL);


        CheckWin();


    }
}



void test()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("请选择:");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("选择错误\n");
            break;
        }
    }while(input);
}


int main()
{
    test();
    system("pause");
    return 0;
}

最后我们还需要一个头文件,来声明这些函数,我们设置头文件可以防止里面的函数被重复调用。

#ifndef __GAME_H__
#define __GAME_H__

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define COL 3
#define ROW 3

void InitBoard(char board[ROW][COL],int row,int col);
void PrintBoard(char board[ROW][COL],int row,int col);
void ComMove(char board[ROW][COL],int row,int col);
void PlayerMove(char board[ROW][COL],int row,int col);
char CheckWin(char board[ROW][COL], int row, int col);

#endif   //__GAME_H__

!运行实例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章