#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <assert.h>
#include <time.h>

#define ROW 3
#define COL 3

char TABLE[ROW][COL];

int Menu();
void tableInit();
void print_table();
void PlayerMove();
void BotMove();
char CheckWinner();
void PlayNow();

#define DEBUG

#ifdef DEBUG
int Menu() {
    int choice = -1;

    printf("-----------------------------------\n");
    printf("           1. 开始游戏              \n");
    printf("           2. 退出程序              \n");
    printf("-----------------------------------\n");
    printf("请输入选项:");
    scanf("%d", &choice);

    return choice;
}

// 棋盘初始化为空格
void tableInit() {
    for (int row = 0; row < ROW; row++) {
        for (int col = 0; col < COL; col++) {
            TABLE[row][col] = ' ';
        }
    }
}

void print_table() {
    printf(" ------ ------ ------\n");
    printf("|      |      |      |\n");
    printf("|  %c   |  %c   |  %c   |\n", TABLE[0][0], TABLE[0][1], TABLE[0][2]);
    printf("|      |      |      |\n");
    printf(" ------ ------ ------\n");
    printf("|      |      |      |\n");
    printf("|  %c   |  %c   |  %c   |\n", TABLE[1][0], TABLE[1][1], TABLE[1][2]);
    printf("|      |      |      |\n");
    printf(" ------ ------ ------\n");
    printf("|      |      |      |\n");
    printf("|  %c   |  %c   |  %c   |\n", TABLE[2][0], TABLE[2][1], TABLE[2][2]);
    printf("|      |      |      |\n");
    printf(" ------ ------ ------\n");
}

void PlayerMove() {
    int row, col;

    printf("玩家落子!\n");

    while (1) {
        printf("请输入你要落子的位置(ROW COLUMN):");
        scanf("%d %d", &row, &col);
        row--; col--;

        // 检查用户输入是否合法
        if (row < 0 || row >= ROW) {
            printf("输入不合法,请重新输入!\n");
            continue;
        }
        if (col < 0 || col >= COL) {
            printf("输入不合法,请重新输入!\n");
            continue;
        }
        if (TABLE[row][col] != ' ') {
            printf("这个位置已被占用,请重新输入!\n");
            continue;
        }

        // 合法 落子
        TABLE[row][col] = 'O';
        system("cls");
        break;
    }

}

void BotMove() {
    int row, col;

    //判断第一行'O'
    if ((TABLE[0][2] == ' ') && (TABLE[0][0] == 'O'&&TABLE[0][1] == 'O'))
    {
        row = 0;
        col = 2;
    }
    else if ((TABLE[0][1] == ' ') && (TABLE[0][0] == 'O'&&TABLE[0][2] == 'O'))
    {
        row = 0;
        col = 1;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[0][1] == 'O'&&TABLE[0][2] == 'O'))
    {
        row = 0;
        col = 0;
    }
    //判断第二行'O'
    else if ((TABLE[1][2] == ' ') && (TABLE[1][0] == 'O'&&TABLE[1][1] == 'O'))
    {
        row = 1;
        col = 2;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[1][0] == 'O'&&TABLE[1][2] == 'O'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[1][0] == ' ') && (TABLE[1][1] == 'O'&&TABLE[1][2] == 'O'))
    {
        row = 1;
        col = 0;
    }
    //判断第三行'O'
    else if ((TABLE[2][2] == ' ') && (TABLE[2][0] == 'O'&&TABLE[2][1] == 'O'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[2][1] == ' ') && (TABLE[2][0] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 2;
        col = 1;
    }
    else if ((TABLE[2][0] == ' ') && (TABLE[2][1] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 2;
        col = 0;
    }
    //判断第一列'O'
    else if ((TABLE[2][0] == ' ') && (TABLE[0][0] == 'O'&&TABLE[1][0] == 'O'))
    {
        row = 2;
        col = 0;
    }
    else if ((TABLE[1][0] == ' ') && (TABLE[0][0] == 'O'&&TABLE[2][0] == 'O'))
    {
        row = 1;
        col = 0;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[1][0] == 'O'&&TABLE[2][0] == 'O'))
    {
        row = 0;
        col = 0;
    }
    //判断第二列'O'
    else if ((TABLE[2][1] == ' ') && (TABLE[0][1] == 'O'&&TABLE[1][1] == 'O'))
    {
        row = 2;
        col = 1;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][1] == 'O'&&TABLE[2][1] == 'O'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][1] == ' ') && (TABLE[1][1] == 'O'&&TABLE[2][1] == 'O'))
    {
        row = 0;
        col = 1;
    }
    //判断第三列'O'
    else if ((TABLE[2][2] == ' ') && (TABLE[0][2] == 'O'&&TABLE[1][2] == 'O'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[1][2] == ' ') && (TABLE[0][2] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 1;
        col = 2;
    }
    else if ((TABLE[0][2] == ' ') && (TABLE[1][2] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 0;
        col = 2;
    }
    //判断右斜对角↖'O'
    else if ((TABLE[2][2] == ' ') && (TABLE[0][0] == 'O'&&TABLE[1][1] == 'O'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][0] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[1][1] == 'O'&&TABLE[2][2] == 'O'))
    {
        row = 0;
        col = 0;
    }
    //判断左斜对角↗'O'
    else if ((TABLE[2][0] == ' ') && (TABLE[0][2] == 'O'&&TABLE[1][1] == 'O'))
    {
        row = 2;
        col = 0;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][2] == 'O'&&TABLE[2][0] == 'O'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][2] == ' ') && (TABLE[1][1] == 'O'&&TABLE[2][0] == 'O'))
    {
        row = 0;
        col = 2;
    }
    //判断第一行'X'
    else if ((TABLE[0][2] == ' ') && (TABLE[0][0] == 'X'&&TABLE[0][1] == 'X'))
    {
        row = 0;
        col = 2;
    }
    else if ((TABLE[0][1] == ' ') && (TABLE[0][0] == 'X'&&TABLE[0][2] == 'X'))
    {
        row = 0;
        col = 1;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[0][1] == 'X'&&TABLE[0][2] == 'X'))
    {
        row = 0;
        col = 0;
    }
    //判断第二行'X'
    else if ((TABLE[1][2] == ' ') && (TABLE[1][0] == 'X'&&TABLE[1][1] == 'X'))
    {
        row = 1;
        col = 2;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[1][0] == 'X'&&TABLE[1][2] == 'X'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[1][0] == ' ') && (TABLE[1][1] == 'X'&&TABLE[1][2] == 'X'))
    {
        row = 1;
        col = 0;
    }
    //判断第三行'X'
    else if ((TABLE[2][2] == ' ') && (TABLE[2][0] == 'X'&&TABLE[2][1] == 'X'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[2][1] == ' ') && (TABLE[2][0] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 2;
        col = 1;
    }
    else if ((TABLE[2][0] == ' ') && (TABLE[2][1] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 2;
        col = 0;
    }
    //判断第一列'X'
    else if ((TABLE[2][0] == ' ') && (TABLE[0][0] == 'X'&&TABLE[1][0] == 'X'))
    {
        row = 2;
        col = 0;
    }
    else if ((TABLE[1][0] == ' ') && (TABLE[0][0] == 'X'&&TABLE[2][0] == 'X'))
    {
        row = 1;
        col = 0;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[1][0] == 'X'&&TABLE[2][0] == 'X'))
    {
        row = 0;
        col = 0;
    }
    //判断第二列'X'
    else if ((TABLE[2][1] == ' ') && (TABLE[0][1] == 'X'&&TABLE[1][1] == 'X'))
    {
        row = 2;
        col = 1;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][1] == 'X'&&TABLE[2][1] == 'X'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][1] == ' ') && (TABLE[1][1] == 'X'&&TABLE[2][1] == 'X'))
    {
        row = 0;
        col = 1;
    }
    //判断第三列'X'
    else if ((TABLE[2][2] == ' ') && (TABLE[0][2] == 'X'&&TABLE[1][2] == 'X'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[1][2] == ' ') && (TABLE[0][2] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 1;
        col = 2;
    }
    else if ((TABLE[0][2] == ' ') && (TABLE[1][2] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 0;
        col = 2;
    }
    //判断右斜对角↖'X'
    else if ((TABLE[2][2] == ' ') && (TABLE[0][0] == 'X'&&TABLE[1][1] == 'X'))
    {
        row = 2;
        col = 2;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][0] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][0] == ' ') && (TABLE[1][1] == 'X'&&TABLE[2][2] == 'X'))
    {
        row = 0;
        col = 0;
    }
    //判断左斜对角↗'X'
    else if ((TABLE[2][0] == ' ') && (TABLE[0][2] == 'X'&&TABLE[1][1] == 'X'))
    {
        row = 2;
        col = 0;
    }
    else if ((TABLE[1][1] == ' ') && (TABLE[0][2] == 'X'&&TABLE[2][0] == 'X'))
    {
        row = 1;
        col = 1;
    }
    else if ((TABLE[0][2] == ' ') && (TABLE[1][1] == 'X'&&TABLE[2][0] == 'X'))
    {
        row = 0;
        col = 2;
    }
    else {
        while (1) {
            row = rand() % 3;
            col = rand() % 3;

            if (TABLE[row][col] != ' ')
                continue;
            else
                break;
        }
    }

    // 落子
    TABLE[row][col] = 'X';
    system("cls");
}

// 返回'O'表示玩家获胜
// 返回'X'表示bot获胜
// 返回'q'表示和棋
// 返回' '表示暂无胜者
char CheckWinner() {
    int row, col;

    // 检查竖线
    for (col = 0; col < COL; col++) {
        if (TABLE[0][col] == TABLE[1][col]
            && TABLE[0][col] == TABLE[2][col]) {
            return TABLE[0][col];
        }
    }

    // 检查横线
    for (row = 0; row < ROW; row++) {
        if (TABLE[row][0] == TABLE[row][1]
            && TABLE[row][0] == TABLE[row][2]) {
            return TABLE[row][0];
        }
    }

    // 检查对角线
    if (TABLE[0][0] == TABLE[1][1] && TABLE[0][0] == TABLE[2][2])
        return TABLE[0][0];
    if (TABLE[0][2] == TABLE[1][1] && TABLE[0][2] == TABLE[2][0])
        return TABLE[0][2];

    // 检查是否和棋
    for (row = 0; row < ROW; row++) {
        for (col = 0; col < COL; col++) {
            if (TABLE[row][col] == ' ')
                return ' ';
        }
    }

    // 和棋
    return 'q';
}

void game() {
    char winner;

    // 1. 初始化棋盘
    tableInit();
    print_table();

    while (1) {
        // 2. 用户落子
        PlayerMove();
        print_table();

        // 3. 判断胜负
        winner = CheckWinner();
        if (winner != ' ')  // 胜负已分
            break;

        // 4. bot落子
        BotMove();
        print_table();

        // 5. 判断胜负
        CheckWinner();
        winner = CheckWinner();
        if (winner != ' ')  // 胜负已分
            break;
    }

    if (winner == 'O') {
        printf("您获胜了!\n");
        return;
    }
    else if (winner == 'X') {
        printf("Bot获胜了!\n");
        return;
    }
    else if (winner == 'q') {
        printf("您和Bot55开!\n");
        return;
    }
    else {
        assert(0);
    }
}

void PlayNow() {
    int choice;

    srand((unsigned int)time(0));  // 设置种子

    while (1) {
        choice = Menu();
        if (choice == 1) {
            Sleep(200);
            system("cls");
            game();
            system("pause");
        }
        else if (choice == 2) {
            exit(0);
        }
        else {
            printf("输入错误,请重新输入");
            Sleep(500);
            printf("!");
            Sleep(500);
            printf("!");
            Sleep(500);
            printf("!");
            Sleep(500);
            system("cls");
            continue;
        }

        system("cls");
    }
}
#endif

int main() {
    PlayNow();

    system("pause");
    return 0;
}
Last modification:November 10th, 2019 at 10:09 am