三子棋分析与实现——C语言

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三子棋分析与实现——C语言相关的知识,希望对你有一定的参考价值。

三子棋作为一款经典的小游戏,对于初学C语言的我们如果 可以熟练了解并可以实现其游戏功能,则对于以后更系统的学习C语言有很好帮助。下来我分享一下我在编程时的感悟和代码

首先介绍一下三子棋规则:只要将自己的棋连成一条线(行,列,斜线),即为赢
如图:

技术图片

先根据图和玩法大致有个思路:

1.我们可以将棋盘看做是一个三行三列的二维数组,且每行每列用线隔开以便区分
2.分为电脑下棋和玩家下棋(电脑先下和玩家先下)
3.判断输赢(玩家赢,电脑赢和平局)

大致思路即为上面分析,下面开始写代码:

创建tset.c,game.c和head.h三个文件

1.在test.c中编写主函数并写出游戏菜单

在这里我分为电脑先下和玩家先下,代码如下;

void menu()

    printf("***************************************\n");
    printf("*      1.play             0.exit      *\n");
    printf("***************************************\n");

void first_move()

    printf("***************************************\n");
    printf("*  1.computer first   2.player first  *\n");
    printf("***************************************\n");

void game()

   return 0;

int main()

    int choice;
    srand((unsigned int)time(NULL));//产生随机数
    do
    
        menu();  
        printf("请选择:");
        scanf("%d", &choice);
        switch (choice)
        
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("输入错误请重新输入.\n");
            break;
        
     while (choice);
    return 0;

2.下来逐步在game.c中实现所需功能并且在game函数中调用

先打印出棋盘,并将棋盘初始化为空格。代码如下;

void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盘

    int i;
    for (int i = 0; i < rows; i++)
    
        printf("  %c | %c | %c  \n", board[i][0], board[i][1], board[i][2]);
        if (i != rows - 1)
            printf(" ---|---|--- \n");
    


void init_board(char board[ROWS][COLS], int rows, int cols)//将数组初始化为空格

    int i, j;
    for (i = 0; i < rows; i++)
    
        for (j = 0; j < cols; j++)
        
            board[i][j] = ‘ ‘;
        
    

效果如图
技术图片

3.编写玩家落子的代码

玩家数输入二维数组的坐标,这时需要判断玩家输入坐标是否合理以及在此坐标上是否有棋子,代码如下;

void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子

    int x, y;
    printf("玩家落子:\n");
    while (1)
    
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= rows && y >= 1 && y <= cols)
        
            if (board[x - 1][y - 1] == ‘ ‘)
            
                board[x - 1][y - 1] = ‘*‘;
                break;
            
            else printf("位置已被占用!请再试一次。\n");
        
        else printf("输入错误!请重新输入.\n");
    

4.玩成电脑落子

这里实现的是电脑在为空格的数组中随机落子。代码如下;

void computer_move(char board[ROWS][COLS], int rows, int cols)// 电脑落子


    int x, y;
    printf("电脑落子:\n");
    while (1)
    
        x = rand() % rows;
        y = rand() % cols;
        if (board[x][y] == ‘ ‘)
        
            board[x][y] = ‘#‘;
            break;
        
    

5.最后就只剩判断输赢

先讨论玩家或者电脑赢的情况;代码如下;

char check_win(char board[ROWS][COLS], int rows, int cols)//判断输赢

    int i;
    for (i = 0; i < rows; 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 < cols; 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];
    else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ‘ ‘)
        return board[1][1];
    else if (is_full(board, rows, cols))
        return ‘q‘;
    return 0;

这是考虑是平局的情况,平局则为棋盘下满都没有输赢,可以遍历整个数组(棋盘)若没有空格就为平局。代码如下;

static int is_full(char board[ROWS][COLS], int rows, int cols)//检测是否为平局

    int i, j;
    for (i = 0; i < rows; i++)
    
        for (j = 0; j < cols; j++)
        
            if (board[i][j] == ‘ ‘)
                return 0;
        
    
    return 1;

初步测试结果如下

技术图片

在图中我们可以看出电脑可以有赢的机会却在随机下子,这样的游戏是没有挑战的。因此应该修改下电脑下子的代码,使其智能化。我们可在电脑落子时判断如果有在同行,同列或者斜线上有相同棋子的,电脑则优先落子在其未成一条线的空格处,这样实现简单智能化

代码如下;

void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化电脑落子

    int x, y, i;
    printf("电脑落子:\n");
    while (1)
    
        x = rand() % rows;
        y = rand() % cols;
        for (i = 0; i < rows; i++)
        
            if (board[i][0] == board[i][1] && board[i][0] == ‘#‘ && board[i][2] == ‘ ‘)
            
                board[i][2] = ‘#‘;
                goto flag1;
            
            else if (board[i][1] == board[i][2] && board[i][1] == ‘#‘ && board[i][0] == ‘ ‘)
            
                board[i][0] = ‘#‘;
                goto flag1;
            
            else if (board[i][0] == board[i][2] && board[i][2] == ‘#‘ && board[i][1] == ‘ ‘)
            
                board[i][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[1][i] && board[0][i] == ‘#‘ && board[2][i] == ‘ ‘)
            
                board[2][i] = ‘#‘;
                goto flag1;
            
            else if (board[1][i] == board[2][i] && board[1][i] == ‘#‘ && board[0][i] == ‘ ‘)
            
                board[0][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[2][i] && board[2][i] == ‘#‘ && board[1][i] == ‘ ‘)
            
                board[1][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[1][1] && board[0][0] == ‘#‘ && board[2][2] == ‘ ‘)
            
                board[2][2] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][2] && board[1][1] == ‘#‘ && board[0][0] == ‘ ‘)
            
                board[0][0] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[2][2] && board[0][0] == ‘#‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][2] == board[1][1] && board[1][1] == ‘#‘ && board[2][0] == ‘ ‘)
            
                board[2][0] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][0] && board[1][1] == ‘#‘ && board[0][2] == ‘ ‘)
            
                board[0][2] = ‘#‘;
                goto flag1;
            
            else if (board[2][0] == board[0][2] && board[2][0] == ‘#‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
        
        for (i = 0; i < rows; i++)
        
            if (board[i][0] == board[i][1] && board[i][0] == ‘*‘ && board[i][2] == ‘ ‘)
            
                board[i][2] = ‘#‘;
                goto flag1;
            
            else if (board[i][1] == board[i][2] && board[i][1] == ‘*‘ && board[i][0] == ‘ ‘)
            
                board[i][0] = ‘#‘;
                goto flag1;
            
            else if (board[i][0] == board[i][2] && board[i][2] == ‘*‘ && board[i][1] == ‘ ‘)
            
                board[i][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[1][i] && board[0][i] == ‘*‘ && board[2][i] == ‘ ‘)
            
                board[2][i] = ‘#‘;
                goto flag1;
            
            else if (board[1][i] == board[2][i] && board[1][i] == ‘*‘ && board[0][i] == ‘ ‘)
            
                board[0][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[2][i] && board[2][i] == ‘*‘ && board[1][i] == ‘ ‘)
            
                board[1][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[1][1] && board[0][0] == ‘*‘ && board[2][2] == ‘ ‘)
            
                board[2][2] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][2] && board[1][1] == ‘*‘ && board[0][0] == ‘ ‘)
            
                board[0][0] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[2][2] && board[0][0] == ‘*‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][2] == board[1][1] && board[1][1] == ‘*‘ && board[2][0] == ‘ ‘)
            
                board[2][0] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][0] && board[1][1] == ‘*‘ && board[0][2] == ‘ ‘)
            
                board[0][2] = ‘#‘;
                goto flag1;
            
            else if (board[2][0] == board[0][2] && board[2][0] == ‘*‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
        
        if (board[x][y] == ‘ ‘)
        
            board[x][y] = ‘#‘;
            goto flag1;
        
    
flag1:;

效果如图;
技术图片

检测所有结果

电脑赢
技术图片
玩家赢
技术图片
平局
技术图片

全部代码

tese.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"
void menu()

    printf("***************************************\n");
    printf("*      1.play             0.exit      *\n");
    printf("***************************************\n");

void first_move()

    printf("***************************************\n");
    printf("*  1.computer first   2.player first  *\n");
    printf("***************************************\n");

void game()

    int choice, win;
    char board[ROWS][COLS];
    init_board(board, ROWS, COLS);
    first_move();
flag:
    printf("请选择");
    scanf("%d", &choice);
    switch (choice)
    
    case 1: //电脑先落子
        do
        
            computer_move(board, ROWS, COLS);   //电脑落子
            show_board(board, ROWS, COLS);      //打印棋盘
            win = check_win(board, ROWS, COLS); 
            if (win != 0)  //没赢
                break;
            player_move(board, ROWS, COLS);     //玩家落子
            show_board(board, ROWS, COLS);      // 打印棋盘
            win = check_win(board, ROWS, COLS);
         while (win == 0);
        if (win == ‘#‘)
            printf("很遗憾,你输了!\n");
        if (win == ‘*‘)
            printf("恭喜,你赢了!\n");
        if (win == ‘q‘)
            printf("平局\n");
        break;
    case 2: //玩家先落子
        show_board(board, ROWS, COLS);
        do
        
            player_move(board, ROWS, COLS);
            show_board(board, ROWS, COLS);
            win = check_win(board, ROWS, COLS);
            if (win != 0)
                break;
            computer_move(board, ROWS, COLS);
            show_board(board, ROWS, COLS);
            win = check_win(board, ROWS, COLS);
         while (win == 0);
        if (win == ‘#‘)
            printf("很遗憾,你输了!\n");
        if (win == ‘*‘)
            printf("恭喜,你赢了!\n");
        if (win == ‘q‘)
            printf("平局\n");
        break;
    default:
        printf("输入错误,请重新输入\n");
        goto flag;
    

int main()

    int choice;
    srand((unsigned int)time(NULL));//产生随机数
    do
    
        menu();  
        printf("请选择:");
        scanf("%d", &choice);
        switch (choice)
        
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("输入错误请重新输入.\n");
            break;
        
     while (choice);
    return 0;

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"

void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盘

    int i;
    for (int i = 0; i < rows; i++)
    
        printf("  %c | %c | %c  \n", board[i][0], board[i][1], board[i][2]);
        if (i != rows - 1)
            printf(" ---|---|--- \n");
    


void init_board(char board[ROWS][COLS], int rows, int cols)//将数组初始化为空格

    int i, j;
    for (i = 0; i < rows; i++)
    
        for (j = 0; j < cols; j++)
        
            board[i][j] = ‘ ‘;
        
    


//void computer_move(char board[ROWS][COLS], int rows, int cols)// 电脑落子
//
//
//  int x, y;
//  printf("电脑落子:\n");
//  while (1)
//  
//      x = rand() % rows;
//      y = rand() % cols;
//      if (board[x][y] == ‘ ‘)
//      
//          board[x][y] = ‘#‘;
//          break;
//      
//  
//
void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化电脑落子

    int x, y, i;
    printf("电脑落子:\n");
    while (1)
    
        x = rand() % rows;
        y = rand() % cols;
        for (i = 0; i < rows; i++)
        
            if (board[i][0] == board[i][1] && board[i][0] == ‘#‘ && board[i][2] == ‘ ‘)
            
                board[i][2] = ‘#‘;
                goto flag1;
            
            else if (board[i][1] == board[i][2] && board[i][1] == ‘#‘ && board[i][0] == ‘ ‘)
            
                board[i][0] = ‘#‘;
                goto flag1;
            
            else if (board[i][0] == board[i][2] && board[i][2] == ‘#‘ && board[i][1] == ‘ ‘)
            
                board[i][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[1][i] && board[0][i] == ‘#‘ && board[2][i] == ‘ ‘)
            
                board[2][i] = ‘#‘;
                goto flag1;
            
            else if (board[1][i] == board[2][i] && board[1][i] == ‘#‘ && board[0][i] == ‘ ‘)
            
                board[0][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[2][i] && board[2][i] == ‘#‘ && board[1][i] == ‘ ‘)
            
                board[1][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[1][1] && board[0][0] == ‘#‘ && board[2][2] == ‘ ‘)
            
                board[2][2] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][2] && board[1][1] == ‘#‘ && board[0][0] == ‘ ‘)
            
                board[0][0] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[2][2] && board[0][0] == ‘#‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][2] == board[1][1] && board[1][1] == ‘#‘ && board[2][0] == ‘ ‘)
            
                board[2][0] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][0] && board[1][1] == ‘#‘ && board[0][2] == ‘ ‘)
            
                board[0][2] = ‘#‘;
                goto flag1;
            
            else if (board[2][0] == board[0][2] && board[2][0] == ‘#‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
        
        for (i = 0; i < rows; i++)
        
            if (board[i][0] == board[i][1] && board[i][0] == ‘*‘ && board[i][2] == ‘ ‘)
            
                board[i][2] = ‘#‘;
                goto flag1;
            
            else if (board[i][1] == board[i][2] && board[i][1] == ‘*‘ && board[i][0] == ‘ ‘)
            
                board[i][0] = ‘#‘;
                goto flag1;
            
            else if (board[i][0] == board[i][2] && board[i][2] == ‘*‘ && board[i][1] == ‘ ‘)
            
                board[i][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[1][i] && board[0][i] == ‘*‘ && board[2][i] == ‘ ‘)
            
                board[2][i] = ‘#‘;
                goto flag1;
            
            else if (board[1][i] == board[2][i] && board[1][i] == ‘*‘ && board[0][i] == ‘ ‘)
            
                board[0][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][i] == board[2][i] && board[2][i] == ‘*‘ && board[1][i] == ‘ ‘)
            
                board[1][i] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[1][1] && board[0][0] == ‘*‘ && board[2][2] == ‘ ‘)
            
                board[2][2] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][2] && board[1][1] == ‘*‘ && board[0][0] == ‘ ‘)
            
                board[0][0] = ‘#‘;
                goto flag1;
            
            else if (board[0][0] == board[2][2] && board[0][0] == ‘*‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
            else if (board[0][2] == board[1][1] && board[1][1] == ‘*‘ && board[2][0] == ‘ ‘)
            
                board[2][0] = ‘#‘;
                goto flag1;
            
            else if (board[1][1] == board[2][0] && board[1][1] == ‘*‘ && board[0][2] == ‘ ‘)
            
                board[0][2] = ‘#‘;
                goto flag1;
            
            else if (board[2][0] == board[0][2] && board[2][0] == ‘*‘ && board[1][1] == ‘ ‘)
            
                board[1][1] = ‘#‘;
                goto flag1;
            
        
        if (board[x][y] == ‘ ‘)
        
            board[x][y] = ‘#‘;
            goto flag1;
        
    
flag1:;


void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子

    int x, y;
    printf("玩家落子:\n");
    while (1)
    
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= rows && y >= 1 && y <= cols)
        
            if (board[x - 1][y - 1] == ‘ ‘)
            
                board[x - 1][y - 1] = ‘*‘;
                break;
            
            else printf("位置已被占用!请再试一次。\n");
        
        else printf("输入错误!请重新输入.\n");
    


static int is_full(char board[ROWS][COLS], int rows, int cols)//检测是否为平局

    int i, j;
    for (i = 0; i < rows; i++)
    
        for (j = 0; j < cols; j++)
        
            if (board[i][j] == ‘ ‘)
                return 0;
        
    
    return 1;


char check_win(char board[ROWS][COLS], int rows, int cols)//判断输赢

    int i;
    for (i = 0; i < rows; 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 < cols; 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];
    else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ‘ ‘)
        return board[1][1];
    else if (is_full(board, rows, cols))
        return ‘q‘;
    return 0;

head.h

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

#define ROWS 3
#define COLS 3

void show_board(char board[ROWS][COLS], int rows, int cols);//打印棋盘
void init_board(char board[ROWS][COLS], int rows, int cols);//初始化棋盘为空格
void computer_move(char board[ROWS][COLS], int rows, int cols);//电脑落子
void player_move(char board[ROWS][COLS], int rows, int cols);//玩家落子
char check_win(char board[ROWS][COLS], int rows, int cols);//判断输赢

以上是关于三子棋分析与实现——C语言的主要内容,如果未能解决你的问题,请参考以下文章

C语言经典项目实战——三子棋

C语言经典项目实战——三子棋

小时候玩过的三子棋(井字棋),你还记得吗?C语言实现简单的三子棋小游戏

C语言三子棋游戏与多子棋 (保姆级的实现过程)

C语言游戏跟电脑battle三子棋

C语言实现三子棋(井字棋)