棋盘大小可改变的三子棋

头文件

game.h

#define _CRT_SECURE_NO_WARNINGS 1

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

#ifndef __GAME_H__
#define __GAME_H__

#define R 3//行
#define C 3//列
#define Ex 0//增加量

void is_Board(char arr[R+Ex][C+Ex], int r, int c);    //初始化棋盘
void display_Board(char arr[R + Ex][C + Ex], int r, int c);   //打印棋盘
void play_person(char arr[R + Ex][C + Ex], int r, int c);     //玩家走
void play_computer(char arr[R + Ex][C + Ex], int r, int c);   //电脑走
char Judge(char arr[R + Ex][C + Ex], int r, int c);           //判断输赢函数
int is_all_equal_without_blank(char arr[R + Ex]);             //判断成每一条直线上元素是否全都相等并且不为空
int full(char arr[R + Ex][C + Ex], int r, int c);       //判断棋盘是否满了

#endif //__GAME_H__

这里的Ex表示的是增加量,我们先定义的是三子棋,如果我们想玩五子棋的话,只需要把Ex后边的0改为2我们就可以玩五子棋了。

源文件

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void is_Board(char arr[R+Ex][C+Ex], int r, int c)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < R + Ex; i++)
    {
        for (j = 0; j < C + Ex; j++)
        {
            arr[i][j] = ' ';
        }
    }
}
void display_Board(char arr[R + Ex][C + Ex], int r, int c)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < R + Ex; i++)
    {
        for (j = 0; j < C + Ex; j++)
        {
            printf("_%c_|", arr[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void play_person(char arr[R + Ex][C + Ex], int r, int c)
{
    int i = 0;
    int j = 0;
    while (1)
    {
        printf("请选择要走哪:\n");
        scanf("%d %d", &i, &j);
        i--;   //因为数组下标是从0开始
        j--;
        if ((i >= 0 && i <= R + Ex - 1) && (j >= 0 && j <= C + Ex - 1))    //判断输入坐标是否合法
        {
            if (arr[i][j] == ' ')
            {
                arr[i][j] = 'X';
                break;
            }
            else
            {
                printf("输入错误,请重新输入!\n");
            }
        }
        else
        {
            printf("输入错误,请重新输入!\n");
        }
    }

}

void play_computer(char arr[R + Ex][C + Ex], int r, int c)
{
    srand((unsigned int)time(NULL));     //生成随机数
    while (1)
    {
        int x = rand() % (R + Ex);     //使生成的随机数在坐标范围内
        int y = rand() % (C + Ex);
        if (arr[x][y] == ' ')
        {
            arr[x][y] = 'O';
            break;
        }

    }
}

int full(char arr[R + Ex][C + Ex], int r, int c)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < R + Ex; i++)
    {
        for (j = 0; j < C + Ex; j++)
        {
            if (arr[i][j] == ' ')
            {
                return 0;
            }
        }
    }
    return 1;
}

int is_all_equal_without_blank(char arr[R + Ex])   
{
    char empty = arr[0];
    for (int i = 1; i < R + Ex; i++)
    {
        if (empty != arr[i] || empty == ' ')    //empty == ' '是为了防止全为空的情况
        {
            return 0;
        }
        else
        {
            empty = arr[i];
        }
    }
    return 1;
}

char Judge(char arr[R + Ex][C + Ex], int r, int c)
{
    int i;
    int j;
    char tmp[R + Ex];
    //判断行相等
    for (i = 0; i < R + Ex; i++)
    {
        for (j = 0; j < C + Ex; j++)
        {
            tmp[j] = arr[i][j];
        }
        if (is_all_equal_without_blank(tmp))
        {
            return tmp[0];
        }
    }
    //判断列相等
    for (j = 0; j < C + Ex; j++)
    {
        for (i = 0; i < R + Ex; i++)
        {
            tmp[i] = arr[i][j];
        }
        if (is_all_equal_without_blank(tmp))
        {
            return tmp[0];
        }
    }
    //判断正交
    for (i = 0; i < R + Ex; i++)
    {
        tmp[i] = arr[i][i];
    }
    if (is_all_equal_without_blank(tmp))
    {
        return tmp[0];
    }
    //判断反交
    for (i = 0; i < R + Ex; i++)
    {
        tmp[i] = arr[i][C + Ex - i - 1];
        if (is_all_equal_without_blank(tmp))
        {
            return tmp[0];
        }
    }
    //判断平局
    if (full(arr , R+Ex, C+Ex))
    {
        return 'q';
    }

    return ' ';
}

char Judge(char arr[R + Ex][C + Ex], int r, int c)函数中我们先定义一个tmp空数组,在判断行/列/正交线/反交线上的数组元素相等时,先把那一行/列/正交/反交的数组元素全部存进tmp数组中,然后把tmp数组作为实参传入int is_all_equal_without_blank(char arr[R + Ex])函数中,进行判断,看数组中的每个元素相等且不为空,如果那一行/列/正交/反交线上的数组元素相等且不为空,则反回tmp数组中的第一个元素就行。
int is_all_equal_without_blank(char arr[R + Ex])函数中,我们先把传进来的数组的第一个元素赋给empty,然后进行for循环,先用数组中的第一个元素和第二个元素相比较,如果它们两不等,或者都为空,则return 0,直接跳出,不用再进行后边的比较了,如果第一个元素和第二个元素相等,则把第二个元素的值赋给tmp,进入for循环,让第二个元素和第三个元素相比较,依次往后推,直到tmp数组中所以元素都相等,则return 1。
char Judge(char arr[R + Ex][C + Ex], int r, int c)函数中我们还需要判断是否会平局,平局是放在判断行/列/正交/反交线上所以元素相等的后边,如果没有连成一条线,我们再判断是否平局,在int full(char arr[R + Ex][C + Ex], int r, int c)函数中,我们只需要判断棋盘是否满了,若棋盘满了,并且前边的判断并没有返回任何值,则return ‘q’,表示平局。

测试函数

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void menu()
{
    printf("*************************\n");
    printf("********1. play**********\n");
    printf("********0. error**********\n");
    printf("*************************\n");
}

void game()
{
    char arr[R+Ex][C+Ex] = { 0 };
    char ret = 0;
    is_Board(arr, R+Ex, C+Ex);
    display_Board(arr, R + Ex, C + Ex);
    while (1)
    {
        play_person(arr, R + Ex, C + Ex);
        display_Board(arr, R + Ex, C + Ex);
        ret = Judge(arr, R + Ex, C + Ex);
        if (ret != ' ')
        {
            break;
        }
        play_computer(arr, R + Ex, C + Ex);
        display_Board(arr, R + Ex, C + Ex);
        ret = Judge(arr, R + Ex, C + Ex);
        if (ret != ' ')
        {
            break;
        }
    }
        if (ret == 'X')
        {
            printf("恭喜你,你赢了!\n");
        }
        else if(ret == 'O')
        {
            printf("真遗憾,你输了!\n");
        }
        else if (ret == 'q')
        {
            printf("平局!\n");
        }
        display_Board(arr, R + Ex, C + Ex);
}


int main()
{
    int num = 0;
    do
    {
        menu();
        printf("请选择:\n");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
            game();
            //printf("开始玩游戏!\n");
            break;
        case 0:
            printf("退出游戏!!!\n");
            break;
        default:
            printf("enter data error!\n");
        }

    }while (num);
    return 0;
}

在测试函数中呢,我们需要先把棋盘打印出来,然后用一个while循环,先让玩家走一步,打印出来,再进行判断,若返回的是空,则让电脑走,然后打印,再进行判断,一直循环,直到判断函数有一个返回值,根据返回值判断谁输谁赢或是平局。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值