三子棋优化实现双人对战

直接上代码

game.h文件

#define  _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<string.h>
#define ROW 3
#define COL 3

//初始化棋盘
void init_board(char arr[ROW][COL], int, int);

//打印棋盘
void print_board(char board[ROW][COL], int, int);

//玩家下棋
void person_move(char board[ROW][COL], int, int);
void person2_move(char board[ROW][COL], int, int);





//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);


//判断棋盘是否下满
int is_full(char board[ROW][COL], int row, int col);

//检查是否有一方获胜
char check_win(char board[ROW][COL], int row, int col);

test.c文件

 

#define  _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

#define ROW 3
#define COL 3

void menu() {
    printf("****************************\n");
    printf("*****   0 退出游戏    ******\n");
    printf("*****   1 进入游戏    ******\n");
    printf("****************************\n");
}


void model_menu() {
    printf("***************************\n");
    printf("** a 人机模式 b 双人模式 **\n");
    printf("***************************\n");

}

void difficulty_menu() {
    printf("***************************\n");
    printf("** e 简单模式 d 困难模式 **\n");
    printf("***************************\n");
}


//电脑简单下棋
void computer_move_easy(char board[ROW][COL], int row, int col) {
    int i = 0, j = 0;
    printf("电脑走:\n");
    while (1) {
        i = rand() % row;
        j = rand() % col;
        if (board[i][j] == ' ') {
            board[i][j] = '#';
            break;
        }
    }
}

//检查电脑是否一线两子 如果有直接赢
int computer_will_win(char board[ROW][COL], int row, int col) {
    int i = 0;
    int j = 0;
    int p_win = 0;//标志是否直接赢
    if (0 == p_win)
    {
        //判断电脑横行上是否会赢
        for (i = 0; i < row; i++)
        {
            if (board[i][0] == board[i][1] && board[i][1] == '#' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                p_win = 1;
                break;
            }
            if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                p_win = 1;
                break;
            }

            if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                p_win = 1;
                break;
            }
        }
        if (p_win != 0)
            return p_win;
        //判断电脑列上是否有机会赢
        for (j = 0; j < col; j++)
        {
            if (board[0][j] == board[1][j] && board[1][j] == '#' && board[2][j] == ' ')
            {
                board[2][j] = '#';
                p_win = 1;
                break;
            }

            if (board[0][j] == board[2][j] && board[2][j] == '#' && board[1][j] == ' ')
            {
                board[1][j] = '#';
                p_win = 1;
                break;
            }
            if (board[1][j] == board[2][j] && board[2][j] == '#' && board[0][j] == ' ')
            {
                board[0][j] = '#';
                p_win = 1;
                break;
            }
        }
        if (p_win != 0)
            return p_win;
    }
    //判断电脑在对角线上是否会赢
    if (0 == p_win)
    {
        if (board[0][0] == board[1][1] && board[1][1] == '#' && board[2][2] == ' ')
        {
            board[2][2] = '#';
            p_win = 1;
            return p_win;

        }

        if (board[0][0] == board[2][2] && board[2][2] == '#' && board[1][1] == ' ')
        {
            board[1][1] = '#';
            p_win = 1;
            return p_win;

        }

        if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
        {
            board[0][0] = '#';
            p_win = 1;
            return p_win;

        }

        if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
        {
            board[2][0] = '#';
            p_win = 1;
            return p_win;

        }

        if (board[0][2] == board[2][0] && board[2][0] == '#' && board[1][1] == ' ')
        {
            board[1][1] = '#';
            p_win = 1;
            return p_win;

        }
        if (board[1][1] == board[2][0] && board[2][0] == '#' && board[0][2] == ' ')
        {
            board[0][2] = '#';
            p_win = 1;
            return p_win;

        }

    }

    return p_win;//p_win==0 说明没有下棋 需再次下棋
}

//检测玩家是否能一线两子  如果有就拦截
int people_will_win(char board[ROW][COL], int row, int col) {
    int i = 0;
    int j = 0;
    int k = 0;
    while (0 == k)
    {
        //判断玩家在横行上是否会赢
        for (i = 0; i < row; i++)
        {
            if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                k = 1;
                break;
            }

            if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                k = 1;
                break;
            }

            if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                k = 1;
                break;
            }
        }
        if (k != 0)
            break;

        //判断玩家在竖列上是否会赢
        for (j = 0; j < col; j++)
        {
            if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
            {
                board[2][j] = '#';
                k = 1;
                break;
            }

            if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
            {
                board[1][j] = '#';
                k = 1;
                break;
            }

            if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
            {
                board[0][j] = '#';
                k = 1;
                break;
            }
        }
        break;
    }

    //判断玩家在对角线上是否会赢
    while (0 == k)
    {
        if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
        {
            board[2][2] = '#';
            k = 1;
            break;
        }

        if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
        {
            board[1][1] = '#';
            k = 1;
            break;
        }

        if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
        {
            board[0][0] = '#';
            k = 1;
            break;
        }

        if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
        {
            board[2][0] = '#';
            k = 1;
            break;
        }

        if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
        {
            board[1][1] = '#';
            k = 1;
            break;
        }

        if (board[1][1] == board[2][0] && board[2][0] == '*' && board[0][2] == ' ')
        {
            board[0][2] = '#';
            k = 1;
            break;
        }
        break;
    }
    return k;//返回值如果是1那么已经对玩家进行了阻拦,如果是0则无需阻拦。
}

//电脑下棋优化版
void computer_move_diff(char board[ROW][COL], int row, int col) {
    int i = 0, j = 0;
    int p;
    printf("电脑走:\n");

    //电脑先检测自己这一次落棋后自己是否能赢
    p = computer_will_win(board, row, col);
    if (p == 1) {//电脑已经下过棋
        return;
    }
    //检查玩家是否会赢 会赢直接堵截
    p = people_will_win(board, row, col);
    if (p == 1) {//电脑对玩家进行了堵截不需要再下
        return;
    }
    //运行到这说明也没有赢 也没有堵截 随机下棋
    while (1) {
        i = rand() % row;
        j = rand() % col;
        if (board[i][j] == ' ') {
            board[i][j] = '#';
            break;
        }
    }

}




//双人对战游戏
void play_game_pvp() {
    char key;//接收输赢结果
    //定义棋盘
    char  board[ROW][COL];
    //初始化棋盘
    init_board(board, ROW, COL);
    //打印棋盘
    print_board(board, ROW, COL);

    while (1)
    {
        printf("请p1下棋:(输入坐标)>");
        person_move(board, ROW, COL);//玩家1下棋
        print_board(board, ROW, COL);//打印棋盘    
        key = check_win(board, ROW, COL);//判输赢平局
        //打印输赢结果
        if (key == '*')
        {
            printf("恭喜p1赢啦\n");
            break;
        }
        if (key == '#')
        {
            printf("恭喜p2赢了\n");
            break;
        }
        if (key == '$')
        {
            printf("平局了!\n");
            break;
        }
        printf("请p2下棋:(输入坐标)>");
        person2_move(board, ROW, COL);//玩家2下棋
        print_board(board, ROW, COL);//打印棋盘
        key = check_win(board, ROW, COL);//判输赢平局
        //打印输赢结果
        if (key == '*')
        {
            printf("恭喜你获得胜利啦\n");
            break;
        }
        if (key == '#')
        {
            printf("p2赢了!\n");
            break;
        }
        if (key == '$')
        {
            printf("你们打平局了!\n");
            break;
        }

    }
}

//人机对战游戏
void playgame_pvc(char* diff) {

    char key;//接收输赢结果

    //定义棋盘
    char  board[ROW][COL];

    //初始化棋盘
    init_board(board, ROW, COL);

    //打印棋盘
    print_board(board, ROW, COL);

    while (1)
    {
        printf("请下棋:(输入坐标)>");
        person_move(board, ROW, COL);//玩家下棋
        print_board(board, ROW, COL);//打印棋盘    
        key = check_win(board, ROW, COL);//判输赢平局
        //打印输赢结果
        if (key == '*')
        {
            printf("恭喜你赢啦\n");
            break;
        }
        if (key == '#')
        {
            printf("电脑居然赢了\n");
            break;
        }
        if (key == '$')
        {
            printf("平局了!\n");
            break;
        }

        if (*diff == 'e') {
            computer_move_easy(board, ROW, COL);//简单版电脑下棋
        }
        else if (*diff == 'd') {
            computer_move_diff(board, ROW, COL);
        }

        print_board(board, ROW, COL);//打印棋盘
        key = check_win(board, ROW, COL);//判输赢平局
        //打印输赢结果
        if (key == '*')
        {
            printf("恭喜你获得胜利啦\n");
            break;
        }
        if (key == '#')
        {
            printf("很可惜,电脑赢了\n");
            break;
        }
        if (key == '$')
        {
            printf("你们打平局了!\n");
            break;
        }
    }

}

void playgame() {
    char model;//接收用户选择的模式
    char difficulty;//接收难度系数
    char ch;//接收数据 用于清空缓存区
    model_menu();
    printf("请你选择模式 >");
    while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区  
    scanf("%c", &model);

    if (model == 'a') {
        difficulty_menu();
        printf("请选择难度等级:");
        while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区 

        scanf("%c", &difficulty);
        if (difficulty == 'd') {
            printf("困难模式开始...\n");
            playgame_pvc(&difficulty);
        }
        else if (difficulty == 'e') {
            printf("简单模式开始...\n");
            playgame_pvc(&difficulty);
        }
    }
    else if (model == 'b') {
        printf("人人对战\n");
        play_game_pvp();
    }
}


int main() {
    srand((unsigned int)time(NULL));
    int input = 0;
    do
    {
        menu();
        printf("请输入 >");
        scanf("%d", &input);
        switch (input) {
        case 1:
            playgame();
            break;
        case 0:
            printf("游戏退出...\n");
            break;
        default:
            printf("请输入正确的格式\n");
        }

    } while (input);

    return 0;
}

game.c文件

#define  _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col) {
    int i = 0;
    for (i = 0; i < row; i++) {
        int j = 0;
        for (j = 0; j < col; j++) {
            board[i][j] = ' ';
        }
    }
}

//打印棋盘
void print_board(char board[ROW][COL], int row, int col) {
    int i = 0;
    for (i = 0; i < row; i++) {
        //打印数据
        for (int j = 0; j < col; j++) {
            if (j < col - 1)
                printf(" %c |", board[i][j]);
            else
                printf(" %c\n", board[i][j]);
        }
        //打印分隔符
        if (i < row - 1) {
            for (int j = 0; j < row; j++) {
                if (j < row - 1)
                    printf("---|");
                else
                    printf("---\n");
            }
        }
    }
}

//玩家下棋
void person_move(char board[ROW][COL], int row, int col) {
    int i = 0, j = 0;

    while (1) {
        scanf("%d %d", &i, &j);
        if (board[i - 1][j - 1] == ' ') {
            board[i - 1][j - 1] = '*';
            break;
        }
        else {
            printf("此位置已被下过,请重新落棋:");
        }
    }
}

//玩家2下棋
void person2_move(char board[ROW][COL], int row, int col) {
    int i = 0, j = 0;

    while (1) {
        scanf("%d %d", &i, &j);
        if (board[i - 1][j - 1] == ' ') {
            board[i - 1][j - 1] = '#';
            break;
        }
        else {
            printf("此位置已被下过,请重新落棋:");
        }
    }
}

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col) {
    int i = 0, j = 0;
    printf("电脑走:\n");
    while (1) {
        i = rand() % row;
        j = rand() % col;
        if (board[i][j] == ' ') {
            board[i][j] = '#';
            break;
        }
    }
}


//判断棋盘是否下满
int is_full(char board[ROW][COL], int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if (board[i][j] == ' ')
                //只要有位置为空就说明还没满
                return 0;
        }
    }
    //遍历全部都下满,则棋盘满了
    return 1;
}

//检查是否有一方获胜
char check_win(char board[ROW][COL], int row, int col)
{
    int i;
    //判断横向是否有一样的
    for (i = 0; i < row; 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 < col; 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, row, col))
        return '$';
    //以上情况都没有则分不出输赢
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术IT桐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值