C语言实现小游戏——三子棋(Three Peices Chess)


前言


相信不少小伙伴都玩过五子棋,其实三子棋和它的游戏规则一样,谁在行/列/对角线上连成直线,谁就获得胜利。

接下来用C语言实现它


Code and Explain


首先为了方便代码编写,实现系统试编程。在工程里定义3个文件:

1

其中,tpc.h是用来存放宏定义和函数声明的头文件

tpc.c是头文件中声明函数的具体实现

test.c则是用来测试代码的源文件。

下面给出各个模块的代码并解释:

首先,tcp.h

#ifndef __TPC_H__
#define __TPC_H__

//棋盘的行和列,为了方便修改所以定义成宏。因为是三子棋所以定义为3
#define COLS 3
#define ROWS 3

//下面是各种函数声明
void init_board(char board[ROWS][COLS], int rows, int cols);//初始化棋盘
void    display_board(char board[ROWS][COLS], int rows, int cols);//打印棋盘
void player_move(char board[ROWS][COLS], int rows, int cols);//玩家操作
void computer_move(char board[ROWS][COLS], int rows, int cols);//电脑操作
char check_win(char board[ROWS][COLS], int rows, int cols);//判断输赢

#endif

其次,tpc.c:

#define _CRT_SECURE_NO_WARNINGS
#include "tpc.h"
#include<string.h>
#include<stdio.h>

void init_board(char board[ROWS][COLS], int rows, int cols)//初始化棋盘(数组)
{
    memset(board, ' ', sizeof(char)*cols*rows);//用库函数代替for循环初始化数组,提高效率
}
void    display_board(char board[ROWS][COLS], int rows, int cols)//打印棋盘
{
    int i = 0;
    for (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 player_move(char board[ROWS][COLS], int rows, int cols)//玩家操作
{
    int x = 0;
    int y = 0;

    while (1)
    {
        printf("请输入坐标:>");
        scanf("%d%d", &x, &y);

        x--;//此举是为了方便玩家操作,玩家输入的第一行第一列实际上是是数组下标的0 0,所以要--
        y--;

        if ((x >= 0) && (x <= rows - 1) && (y >= 0) && (y <= cols - 1))//判断输入合法性
        {
            if (board[x][y] = ' ')
            {
                board[x][y] = 'P';
                break;
            }
            else
            {
                printf("tips:该位置已经放有数据了哦,请重新输入坐标。\n");
            }
        }
    }
}

void computer_move(char board[ROWS][COLS], int rows, int cols)//电脑操作
{
    while (1)//电脑操作不需要判断合法性,因为它不可能非法
    {
        int x = rand() % 3;
        int y = rand() % 3;
        if (board[x][y] = ' ')//没放数据的位置才可以放
        {
            board[x][y] = 'C';
            break;
        }
    }
}

static int Is_full(char board[ROWS][COLS], int rows, int cols)//判断棋盘是否为空,用于checkwin函数调用
//使用static使其不带外部链接属性
{
    int i = 0;
    int j = 0;
    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 = 0;

    //判断3行3列,直接用for循环
    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];
        }

        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, rows, cols))
    {
        return 'Q';//如棋盘已满,则为平局
    }

    return ' ';//输出空格表示棋盘未满,且无人赢。此时游戏继续
}

最后就是test.c:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
#include"tpc.h"
#include<time.h>
#include<stdlib.h>

void menu()//菜单,可以自己设置
{
    printf("|************Tic-Tac-Toe  Game***********|\n");
    printf("|----------------------------------------|\n");
    printf("|*********        1.play        *********|\n");
    printf("|*********        0.exit        *********|\n");
    printf("|________________________________________|\n");
    printf("\n");
}


enum OPTION//用枚举来定义操作,便于代码编写,提高程序可读性
{
    EXIT,
    PLAY
};

void game()
{
    char board[ROWS][COLS] = { 0 };//定义并初始化棋盘数组

    char ret = 0;//checkwin的返回值

    init_board(board, ROWS, COLS);
    display_board(board, ROWS, COLS);

    while (1)//玩家和电脑一直进行操作直到条件不满足退出
    {
        //玩家操作
        player_move(board, ROWS, COLS);
        display_board(board, ROWS, COLS);
        ret = check_win(board, ROWS, COLS);

        //判断游戏是否结束
        if (ret != ' ')//游戏并没有结束
            break;

        //电脑操作
        computer_move(board, ROWS, COLS);
        printf("Compter Move:\n");
        printf("\n");
        display_board(board, ROWS, COLS);
        ret = check_win(board, ROWS, COLS);

        //判断游戏是否结束
        if (ret != ' ')
            break;
    }

    //判断输赢
    if (ret == 'P')
    {
        printf("The Winner is YOU~\n");
    }
    else if (ret == 'C')
    {
        printf("The Winner is Computer~\n");
    }
    else
    {
        printf("Both of you are Winner~\n");
    }
}

int main()
{
    int input = 0;
    srand((unsigned)time(NULL));
    do//使用do while循环
    {
        menu();//默认打印menu
        printf("请选择>:");
        scanf("%d", &input);
        switch (input)
        {
        case PLAY:
            printf("开始游戏~\n");
            printf("\n");

            game();
            break;
        case EXIT:
            break;
        default:
            printf("您的输入有误,请重新选择!!!\n");
            break;
        }
    } while (input);

    system("pause");
    return 0;
}

测试


玩家赢

玩家赢真的很容易,不信你试试。。

2
3

电脑赢双赢就不测试了,太难了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值