小游戏——三子棋(智能)

三子棋就是人们俗称的井字棋,只要三个棋子连成一条直线,就赢了。但如果两个人都掌握了技巧,一般来说都是平局。所以就需要把电脑写的智能一些,这样才好玩。


先来屡一下思路:
1.打印棋盘
先来看图,我们预期想要打印出来的棋盘是以下的样式,但要如何才能打印出呢?
假设打印3*3的棋盘,我们来观察一下规律:(□表示空格)
第一行是:□%c□|□%c□|□%c□
第二行是:---|---|---
第三行是:□%c□|□%c□|□%c□
第四行是:---|---|---
第五行是:□%c□|□%c□|□%c□
在打印棋盘的时候可以将上面的分解为□%c□|---|,通过行、列(row、col)来控制打印。(若需要扩展棋盘,只需修改row、col的值即可)

这里写图片描述

2.电脑走
无论玩家先走还是电脑先走,要是最中间空着,电脑的一步一定是走最中间,接着走四角中的一个,然后电脑就可以判断那条线上若有两个相同的棋子,就走这条线上第三个位子,当有自己的棋子和对手的棋子都为两个的时候,先走自己的位子。(我是通过列出所有可能出现的情况来实现智能的)

3.玩家走
玩家走是玩家输入,没什么好说的,但要有一点要注意,玩家数的坐标值比数组的坐标值大1,可以在玩家输入后通过自减的方式,完美的解决这个问题。

4.判断输赢
有三个棋子连成一条线就胜利,或者棋盘满了都没有胜者,这样就为平局。


这里同扫雷一样,这里也是在工程里创建三个文件:测试文件、游戏文件和头文件,来分装代码(如下图)


这里写图片描述


三子棋相对扫雷来说比较简单,这里就直接给出我的三子棋的源代码:
game.h

#ifndef _GAME_H__
#define _GAME_H__

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

#define ROW 3
#define COL 3


void Init(char board[ROW][COL],int row, int col);//初始化棋盘
void Print(char board[ROW][COL],int row, int col);//打印棋盘
void Computer_go(char board[ROW][COL],int row,int col);//电脑走
void Player_go(char board[ROW][COL],int row,int col);//玩家走
char Iswin(char board[ROW][COL],int row,int col);//判断是否有玩家胜出

#endif //_GAME_H__

test.c

#include "game.h"

void menu()
{
    printf("***********************************\n");
    printf("*     welcome~ o(* ̄︶ ̄*)o~      *\n");
    printf("*             1.play              *\n");
    printf("*             0.exit              *\n");
    printf("***********************************\n");
}

void game()
{
    int input = 0;
    int ret = 0;
    char chess_board[ROW][COL] = {0};
    Init(chess_board,ROW,COL);//初始化棋盘
    Print(chess_board,ROW,COL);//打印棋盘
    do
    {
        printf("请选择下棋顺序:1.电脑先走  2.玩家先走\n");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            break;
        case 2:
            Player_go(chess_board,ROW,COL);//玩家走
            break;
        default:
            printf("请重新输入:");
            break;
        }
    }while((input!=1)&&(input!=2));
    while(1)
    {
        Computer_go(chess_board,ROW,COL);
        Print(chess_board,ROW,COL);
        ret = Iswin(chess_board,ROW,COL);////判断是否有玩家胜出
        if(ret != ' ')
        {
            break;
        }
        Player_go(chess_board,ROW,COL);
        Print(chess_board,ROW,COL);
        ret = Iswin(chess_board,ROW,COL);//判断是否有玩家胜出
        if(ret != ' ')
        {
            break;
        }
    }
    //电脑赢        x
    //玩家赢        o
    //平局          =
    //游戏继续     空格
    if(ret == 'x')
    {
        printf("电脑赢\n");
    }
    if(ret == 'o')
    {
        printf("玩家赢\n");
    }
    if(ret == '=')
    {
        printf("平局\n");
    }
    Print(chess_board,ROW,COL);

}
void test()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();//打印菜单
        printf("请选择:");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("请重新输入:\n");
            break;
        }
    }while(input);
}
int main()
{
    test();
    return 0;
}

game.c

#include "game.h"
void Init(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++)
    //  {
    //      chess_board[i][j]=' ';
    //  }
    //}
    memset(board,' ',sizeof(board[0][0])*row*col );
}

void Print(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(i<row)
            {
                printf(" %c ",board[i][j]);
            }
            if(j<col-1)
            {
                printf("|");
            }
        }
        printf("\n");
        if(i<row-1)
        {
        for(j=0; j<col; j++)
        {
            printf("---");
            if(j<col-1)
            {
                printf("|");
            }
        }
        }
        printf("\n");
    }
}
static void concern(char board[ROW][COL])//四个角选一个下棋
{
    int c = rand()%4+1;//1-4
    switch(c)
    {
    case 1:
        board[0][0] = 'x';
        break;
    case 2:
        board[0][2] = 'x';
        break;
    case 3:
        board[2][0] = 'x';
        break;
    case 4:
        board[2][2] = 'x';
        break;

    }
}
void Computer_go(char board[ROW][COL],int row,int col)//电脑走
{
    int i = 0;
    int j = 0;
    int flag = 0;

    if(board[1][1]==' ')
    {
        board[1][1] = 'x';
        flag = 1;//电脑走中间
        return ;
    }
    if(flag==1)//中间有棋
    {
        concern(board);//走四个角的一个
        flag = 0;
        return ;
    }
    for(i=0; i<3; i++)//
    {
        if(board[i][1]==board[i][0] && board[i][2]==' ' && board[i][1]=='x')
        {
            board[i][2] = 'x';
            return ;
        }
        else if(board[i][1]==board[i][0] && board[i][2]==' ' && board[i][1]=='o')
        {
            board[i][2] = 'x';
            return ;
        }

        else if(board[i][1]==board[i][2] && board[i][0]==' ' && board[i][1]=='x')
        {
            board[i][0] = 'x';
            return ;
        }
        else if(board[i][1]==board[i][2] && board[i][0]==' ' && board[i][1]=='o')
        {
            board[i][0] = 'x';
            return ;
        }

        else if(board[i][0]==board[i][2] && board[i][1]==' ' && board[i][0]=='x')
        {
            board[i][1] = 'x';
            return ;
        }
        else if(board[i][0]==board[i][2] && board[i][1]==' ' && board[i][0]=='o')
        {
            board[i][1] = 'x';
            return ;
        }
    }
    for(j=0; j<col; j++)
    {
        if(board[1][j]==board[0][j] && board[2][j]==' ' && board[1][j]=='x')
        {
            board[2][j] = 'x';
            return ;
        }
        else if(board[1][j]==board[0][j] && board[2][j]==' ' && board[1][j]=='o')
        {
            board[2][j] = 'x';
            return ;
        }

        else if(board[1][j]==board[2][j] && board[0][j]==' ' && board[1][j]!='x')
        {
            board[0][j] = 'x';
            return ;
        }
        else if(board[1][j]==board[2][j] && board[0][j]==' ' && board[1][j]!='o')
        {
            board[0][j] = 'x';
            return ;
        }

        else if(board[0][j]==board[2][j] && board[1][j]==' ' && board[0][j]=='x')
        {
            board[1][j] = 'x';
            return ;
        }
        else if(board[0][j]==board[2][j] && board[1][j]==' ' && board[0][j]=='o')
        {
            board[1][j] = 'x';
            return ;
        }
    }
    if(board[1][1]==board[0][2] && board[2][0]==' ' && board[1][1]=='x')
    {
        board[2][0] = 'x';
        return ;
    }
    else if(board[1][1]==board[0][2] && board[2][0]==' ' && board[1][1]=='o')
    {
        board[2][0] = 'x';
        return ;
    }

    else if(board[1][1]==board[2][0] && board[0][2]==' ' && board[1][1]=='x')
    {
        board[0][2] = 'x';
        return ;
    }
    else if(board[1][1]==board[2][0] && board[0][2]==' ' && board[1][1]=='o')
    {
        board[0][2] = 'x';
        return ;
    }

    else if(board[1][1]==board[0][0] && board[2][2]==' ' && board[1][1]=='x')
    {
        board[2][2] = 'x';
        return ;
    }
    else if(board[1][1]==board[0][0] && board[2][2]==' ' && board[1][1]=='o')
    {
        board[2][2] = 'x';
        return ;
    }

    else if(board[1][1]==board[2][2] && board[0][0]==' ' && board[1][1]=='x')
    {
        board[0][0] = 'x';
        return ;
    }
    else if(board[1][1]==board[2][2] && board[0][0]==' ' && board[1][1]=='o')
    {
        board[0][0] = 'x';
        return ;
    }

    while(1)
    {
        i = rand()%row;
        j = rand()%col;
        if(board[i][j]==' ')
        {
            board[i][j]='x';
            break;
        }
    }
}
void Player_go(char board[ROW][COL],int row,int col)//玩家走
{
    int x = 0;
    int y = 0;
    while(1)
    {
        printf("玩家走,请输入坐标:");
        scanf("%d%d",&x,&y);
        x--;//玩家输入的坐标比数组的坐标大1
        y--;
        if(((x>=0)&&(x<row))&&((y>=0)&&(y<col)))//坐标合法
        {
            if(board[x][y]==' ')
            {
                board[x][y]='o';
                break;
            }
            else
            {
                printf("该坐标已被占用,请重新输入:\n");
            }
        }
        else
        {
            printf("该坐标超出棋盘范围,请重新输入:\n");
        }
    }
}

static int Full_board(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;
}

char Iswin(char board[ROW][COL],int row,int col)//判断是否有玩家胜出
{
    int i = 0;
    int j = 0;
    int count = 0;
    for(i=0; i<row; i++)//行
    {
        for(j=1; j<col-1; j++)
        {
            if((board[i][j-1]==board[i][j])&&(board[i][j]== board[i][j+1])&&(board[i][j]!=' '))
            {
                return board[i][j];
            }
        }

    }

    for(i=1; i<row-1; i++)//列
    {
        for(j=0; j<col; j++)
        {
            if((board[i-1][j]==board[i][j])&&(board[i][j]==board[i+1][j])&&(board[i][j]!=' '))
            {
                return board[i][j];
            }
        }

    }

    for(i=1; i<row-1; i++)//斜
    {
        for(j=1; j<col-1; j++)
        {
            if((board[i-1][j-1]==board[i][j])&&(board[i][j]==board[i+1][j+1])&&(board[i][j]!=' '))
            {
                return board[i][j];
            }
        }

    }
    for(i=0; i<row; i++)//斜
    {
        for(j=1; j<col-1; j++)
        {
            if((board[i-1][j+1]==board[i][j])&&(board[i][j]==board[i+1][j-1])&&(board[i][j]!=' '))
            {
                return board[i][j];
            }
        }

    }
    if(Full_board(board,ROW,COL))//棋盘满,平局
    {
        return '=';
    }
    return ' ';
}

运行结果如下:


这里写图片描述


这里写图片描述


这里写图片描述


END

发布了38 篇原创文章 · 获赞 37 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Lsxlsxls/article/details/80465552