打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用c语言写一个简单的三子棋(井字棋)

emmmm…大致就是这个效果

将三子棋看作3x3的一个二维数组,由玩家和电脑分别填充这个数组。当行、列、叉能够达到三连时,就判断输赢。 

默认玩家先行且棋子为 ‘ X ’,电脑后手棋子为 ‘ 0 ’。 

下面是用到的一些函数。

//game.h

#ifndef __GAME_H__

#define __GAME_H__

#define ROW 3

#define CLO 3

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <memory.h>

void menu();                                           //打印菜单

void game(char arr[ROW][CLO], int row, int clo);       //执行菜单   

void play(char arr[ROW][CLO], int row, int clo);       //游戏主体

void InitBoard(char arr[ROW][CLO], int row, int clo);  //打印棋盘

void Pmove(char arr[ROW][CLO], int row, int clo);      //玩家下棋

void Cmove(char arr[ROW][CLO], int row, int clo);      //电脑下棋

int Isfull(char arr[ROW][CLO], int row, int clo);      //检测盘满

int Iswin(char arr[ROW][CLO], int row, int clo);       //判断输赢

#endif

下面是主函数

//test.c

#include'game.h'

int main()

{

    srand((unsigned int)time(NULL)); //产生随机数种子

    char arr[ROW][CLO];

    game(arr,ROW,CLO);

    system('pause');

    return 0;

}

打印菜单

void menu()

{

    printf('*******************\n');

    printf('*******1.play *****\n');

    printf('*******2.exit *****\n');

    printf('*******************\n');

}

这个函数打印菜单选项。

执行菜单

void game(char arr[ROW][CLO], int row, int clo)

{

    int input = 0;

    do

    {

        menu();

        scanf_s('%d',&input);

        memset(arr, ' ', ROW*CLO * sizeof(arr[0][0]));

        switch (input)

        {

        case 1:

            play(arr, row, clo); break;

        case 2:

            exit(0); break;

        default:printf('你按错键了?\n');

        }

    } while (input);

}

这个函数是菜单执行部分。其中 memset 用来初始化二位字符数组为全‘ 空格 ’。 

接着,用switch语句来判断玩家选项。

游戏主体

void play(char arr[ROW][CLO], int row, int clo)

{

    int flag = 0;

    InitBoard(arr, row, clo);

    while (1)

    {

        printf('人类走\n');

        Pmove(arr, row, clo);

        InitBoard(arr, row, clo);

        flag = Iswin(arr, row, clo);

        if (flag == 1)

        {

            printf('玩家赢\n');

            break;

        }

        flag = Isfull(arr, row, clo);

        if (flag == 4)

        {

            printf('棋盘满,游戏结束\n');

            break;

        }

        printf('电脑走\n');

        Cmove(arr, row, clo);

        InitBoard(arr, row, clo);

        flag = Iswin(arr, row, clo);

        if (flag == 1)

        {

            printf('电脑赢\n');

            break;

        }

    }

}

这个函数里面拥有一个 while 死循环,它的跳出条件是 玩家赢 、 电脑赢 、棋盘满。 

flag == 1 表示电脑或者玩家获胜,flag == 4 表示棋盘满了。 

这里将棋盘满的检测放在玩家行动后,因为只有先手才能使棋盘满。

棋盘打印

void InitBoard(char arr[ROW][CLO], int row, int clo)

{

    int i = 0;

    int j = 0;

    for (j = 0; j < row; j++)

    {

        for (i = 0; i < clo; i++)

        {

            printf(' %c ', arr[j][i]);

            if (i < (clo - 1))

            {

                printf('|');

            }

        }

        printf('\n');

        if (j < row - 1)

        {

            for (i = 0; i < clo; i++)

            {

                printf('---');

                if (i < (clo - 1))

                {

                    printf('|');

                }

            }

        }

        printf('\n');

    }

}

这个棋盘打印函数可以扩展。只要改变ROW 和 CLO 的值就可以改变棋盘大小。 

例如: 7x7的棋盘 

玩家下棋

void Pmove(char arr[ROW][CLO], int row, int clo)

{

    printf('请输入坐标(空格隔开)\n');

    int m = 0, n = 0;

    while (1)

    {

        scanf_s('%d %d', &m, &n);

        if (((m >= 1) && (m <= 3)) && ((n >= 1) && (n <= 3)))

        {

            if (arr[m - 1][n - 1] == ' ')

            {

                arr[m - 1][n - 1] = 'X';

                break;

            }

            else

            {

                printf('这里可能已经有棋子了\n');

            }

        }

        else

        {

            printf('可能你输错了\n');

        }

    }

}

这个是玩家输入函数。这里注意判断输入是否合法,输入范围1~3,并查看该点是否有棋子。考虑玩家因素,将获取的数字-1,使之成为数组变量。

判断输赢

int Iswin(char arr[ROW][CLO], int row, int clo)

{

    //行

    int i = 0;

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

    {

        if (((arr[i][0] == arr[i][1]) && (arr[i][1] == arr[i][2])) && ((arr[i][0] != ' ')))

        {

            return 1;

        }

    }

    //列

    for (i = 0; i < clo; i++)

    {

        if ((arr[0][i] == arr[1][i]) && (arr[1][i] == arr[2][i]) && ((arr[0][i] != ' ') ))

        {

            return 1;

        }

    }

    //叉

    if ((arr[0][0] == arr[1][1]) && (arr[1][1] == arr[2][2]) && ((arr[0][0] != ' ') ))

    {

        return 1;

    }

    if ((arr[0][2] == arr[1][1]) && (arr[1][1] == arr[2][0]) && ((arr[0][2] != ' ')))

    {

        return 1;

    }

    return 0;

}

这个函数判断输赢。由于3行3列,所以用for循环扫描3次。当连续三字相同且不为‘ 空格 ’,那么取得胜利。

电脑下棋(核心)

void Cmove(char arr[ROW][CLO], int row, int clo)

{

    int flag = 0;

    int m = 0, n = 0;

    for (m = 0; m < row; m++)

    {

        for (n = 0; n < row; n++)

        {

            if (arr[m][n] == ' ')

            {

                arr[m][n] = '0';

                flag = Iswin(arr, row, clo);

                if (flag == 0)

                {

                    arr[m][n] = ' ';

                }

                if (flag == 1)

                {

                    break;

                }

            }

        }

        if (flag == 1)

        {

            break;

        }

    }

    if (flag == 0)

    {

        for (m = 0; m < row; m++)

        {

            for (n = 0; n < row; n++)

            {

                if (arr[m][n] == ' ')

                {

                    arr[m][n] = 'X';

                    flag = Iswin(arr, row, clo);

                    if (flag == 0)

                    {

                        arr[m][n] = ' ';

                    }

                    if (flag == 1)

                    {

                        arr[m][n] = '0';

                        break;

                    }

                }

            }

            if (flag == 1)

            {

                break;

            }

        }



        if ((m == 3) && (n == 3))

        {

            while (1)

            {

                m = rand() % 3;

                n = rand() % 3;

                if (arr[m][n] == ' ')

                {

                    arr[m][n] = '0';

                    break;

                }

            }

        }

    }

}

这是个电脑下棋函数。这里动了点歪脑筋。 

第一个双层for循环的作用是:依次检测空位。如果是空位,那么先让该空位被’ 0 ‘填充,然后判断能不能获胜。能获胜就跳出 且 flag == 1,不能获胜就把改位再次置成空位。

接上述不能获胜。如果扫描完后发现并不能获胜,那么采取防守策略。

第二个双层for循环也是检测空位。如果是空位,那么让该位被 ’ X ‘填充,(相当电脑伪装成玩家先走一步)。填充后判断输赢,如果能够获胜,那么电脑再将这个位置改为‘ 0 ’,达到阻止玩家取胜的目的。

最后如果既不能取得胜利,也不用阻止玩家获胜。那么,就让电脑随机找位置下棋。

判断盘满

int Isfull(char arr[ROW][CLO], int row, int clo)

{

    int i = 0, j = 0;

    int count = 0;

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

    {

        for (j = 0; j < clo; j++)

        {

            if (arr[i][j] != ' ')

            {

                count ++;

            }

        }

    }

    if (count == 9)

    {

        return 4;

    }

    return 3;

}

这个函数是判断棋盘是否满。使用count变量计数,扫描棋盘,如果不为‘ 空格 ’的位置有九个,那么就表示棋盘满了。

3.效果演示

会堵人的电脑 

 

会优先自己胜利的电脑 

 

棋盘满效果 

PS:先手优势很大,不出意外的话是先手赢,或是平局。 

依此类推,五子棋在15x15及其以上的棋盘,先手必胜。 

但是电脑获胜算法非常复杂,反正我是写不出来。

--------------------- 

作者:H_Strong 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C语言实现的统计php代码行数功能源码(支持文件夹、多目录)
C程序上机考试设计题(附源代码)-ッ志远ヴ自留屋
编程中国 - 结构体数组的定义和引用
三子棋游戏
C语言开发一篇文章带你还原童年扫雷游戏完整源码分析(用二维数组生成两个棋盘一个用于存放雷一个用于玩家的游玩用头文件加源文件的形式撰写代码这样写代码可以直接通过更改.h文件中的数组更改我们的格子大小)
【新年第一个程序】三子棋小游戏(C语言数组实现)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服