C语言实现五子棋

#include <stdio.h>
#include <conio.h>
#include <windows.h>

/***x是光标的横坐标,y是光标的纵坐标,flag用于切换黑白棋,over判断游戏是否结束。***/
int x = 9, y = 9, flag = 0, over = 0, peace = 361, reChessboard[19][20] = {0};

/***定义符号集***/
char *symbol[] = {"", "●", "○", "┬ ", "┴ ", "├ ", "┤ ", "┼ ", "┌ ", "┐ ", "└ ", "┘ ", "\n"};

/***定义19行22列的棋盘,每行前19列保存棋盘信息,后三行保存其他字符信息以及换行符***/
int Chessboard[19][20] = {{8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
                          {10,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11, 0}};

/***备份棋盘,用于重新开始后恢复棋盘的初始状态***/
void backup() {
    for (int i = 0; i < 19; i++) {
        for (int j = 0; j < 20; j++) {
            reChessboard[i][j] = Chessboard[i][j];
        }
    }
}

/***绘制棋盘函数***/
void drawBoard() {
    system("cls");//清屏函数,属于Dos命令。
    //通过循环绘制出棋盘。
    for (int i = 0; i < 19; i++) {
        for (int j = 0; j < 20; j++) {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
                                    (i == x && j == y) ? ((Chessboard[i][j] != 1 && Chessboard[i][j] != 2 && over != 1)
                                                          ? 175 : 207)
                                                       : 15);//绘制光标
            printf("%s", symbol[Chessboard[i][j]]);//取出符号集里的符号并拼凑成棋盘。
        }
    }
}

/***重新开始函数***/
void restart() {
    //通过循环将棋盘恢复至初始状态
    for (int i = 0; i < 19; i++) {
        for (int j = 0; j < 20; j++) {
            Chessboard[i][j] = reChessboard[i][j];
        }
    }
    //重置变量的值
    x = 9;
    y = 9;
    flag = 0;
    over = 0;
    peace = 361;
    drawBoard();//重新绘制棋盘
}

/***判断输赢函数***/
void judge() {
    drawBoard();
    if (peace <= 0) {
        MessageBox(NULL, "平局", "游戏结束", 0);
        over = 1;
    }
    int a, b, m = x, n = y, totalH = 1, totalS = 1, totalN = 1, totalP = 1;
    //判断垂直方向的连子数量,连子数量大于等于5个则游戏结束。
    for (a = m - 1; a >= 0; a--) {
        if (Chessboard[a][n] == Chessboard[m][n]) {
            totalS++;
        } else {
            break;
        }
    }
    for (a = m + 1; a <= 18; a++) {
        if (Chessboard[a][n] == Chessboard[m][n]) {
            totalS++;
        } else {
            break;
        }
    }
    if (totalS >= 5) {
        MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
        over = 1;
    }

    //判断水平方向的连子数量,连子数量大于等于5个则游戏结束。
    for (b = n - 1; b >= 0; b--) {
        if (Chessboard[m][b] == Chessboard[m][n]) {
            totalH++;
        } else {
            break;
        }
    }
    for (b = n + 1; b <= 18; b++) {
        if (Chessboard[m][b] == Chessboard[m][n]) {
            totalH++;
        } else {
            break;
        }
    }
    if (totalH >= 5) {
        MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
        over = 1;
    }

    //判断左上-右下方向的连子数量,连子数量大于等于5个则游戏结束。
    for (a = m - 1, b = n - 1; a >= 0 || b >= 0; a--, b--) {
        if (Chessboard[a][b] == Chessboard[m][n]) {
            totalN++;
        } else {
            break;
        }
    }
    for (a = m + 1, b = n + 1; a <= 18 || b <= 18; a++, b++) {
        if (Chessboard[a][b] == Chessboard[m][n]) {
            totalN++;
        } else {
            break;
        }
    }
    if (totalN >= 5) {
        MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
        over = 1;
    }

    //判断左下-右上方向的连子数量,连子数量大于等于5个则游戏结束。
    for (a = m - 1, b = n + 1; a >= 0 || b <= 18; a--, b++) {
        if (Chessboard[a][b] == Chessboard[m][n]) {
            totalP++;
        } else {
            break;
        }
    }
    for (a = m + 1, b = n - 1; a <= 18 || b >= 0; a++, b--) {
        if (Chessboard[a][b] == Chessboard[m][n]) {
            totalP++;
        } else {
            break;
        }
    }
    if (totalP >= 5) {
        MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
        over = 1;
    }
}

/***AI函数***/
void ai() {
    if (over != 1) {
        
    }
}

/***按键监听函数***/
void monitor() {
    int keyValue;
    while ((keyValue = getch()) != 0x1B) {//当按下ESC时程序退出
        if (keyValue == 119 || keyValue == 87 || keyValue == 72) { //W,w,↑向上
            x >= 1 ? x-- : (x = 0);//防止光标越界
        } else if (keyValue == 115 || keyValue == 83 || keyValue == 80) {//S,s,↓向下
            x <= 17 ? x++ : (x = 18);//防止光标越界
        } else if (keyValue == 97 || keyValue == 75 || keyValue == 65) {//A,a,←向左
            y >= 1 ? y-- : (y = 0);//防止光标越界
        } else if (keyValue == 100 || keyValue == 77 || keyValue == 68) {//D,d,→向右
            y <= 17 ? y++ : (y = 18);//防止光标越界
        } else if (keyValue == 114 || keyValue == 82) {//R键重新开始
            restart();//重新开始
        } else if (keyValue == 32 || keyValue == 13) {//空格或回车落子
            if (Chessboard[x][y] != 1 && Chessboard[x][y] != 2 && over == 0) {//切换黑白棋
                Chessboard[x][y] = flag % 2 == 0 ? 1 : 2;
                flag++;
                peace--;
                judge();//判断连子
            }
        }
        drawBoard();
    }
}

/***主函数***/
int main() {
    backup();
    system("mode con cols=38 lines=19");//设置DOS窗口大小
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &(CONSOLE_CURSOR_INFO) {25});//隐藏DOS自带光标
    drawBoard();//绘制棋盘
    monitor();//按键监听
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

球块

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

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

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

打赏作者

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

抵扣说明:

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

余额充值