C语言编写程序判断五子棋游戏是否即将获胜

问题描述

已知两人分别执白棋和黑棋在一个围棋棋盘上下五子棋,若同一颜色的棋子在同一条横行、纵行或斜线上连成5个棋子,则执该颜色棋子的人获胜。编写程序读入某一时刻下棋的状态,并判断是否有人即将获胜,即:同一颜色的棋子在同一条横行、纵列或斜线上连成4个棋子,且该4个棋子的两端至少有一端为空位置。

输入的棋盘大小是19*19,用数字0表示空位置(即没有棋子),用数字1表示该位置下了一白色棋子,用数字2表示该位置下了一黑色棋子。假设同一颜色的棋子在同一条横行、纵列或斜线上连成的棋子个数不会超过4个,并且最多有一人连成线的棋子个数为4。

输入形式

从控制台输入用来表示棋盘状态的数字0、1或2;每行输入19个数字,各数字之间以一个空格分隔,每行最后一个数字后没有空格;共输入19行表示棋盘状态的数字。

输出形式

若有人即将获胜,则先输出即将获胜人的棋子颜色(1表示白色棋子,2表示黑色棋子),然后输出英文冒号:,最后输出连成4个棋子连线的起始位置(棋盘横行自上往下、纵列自左往右从1开始计数,横行最小的棋子在棋盘上的横行数和纵列数作为连线的起始位置,若在同一行上,则纵列数最小的棋子位置作为起始位置,两数字之间以一个英文逗号,作为分隔符)。

若没有人获胜,则输出英文字符串:No。

无论输出什么结果,最后都要有回车换行符。

输入样例1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 0 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 1 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 1 0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

输出样例1

1:9,8

输入样例2

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

输出样例2

No

样例说明

在输入的样例1中,执白棋(数字1表示)的人即将获胜,连成4个棋子且有一端为空的起始位置在第9行第8列,所以输出1:9,8。 在输入的样例2中,还没有同一颜色的棋子连成4个,所以无人即将获胜,直接输出No

解题思路

本题是对于五子棋的一个小变形,所以我们可以直接借鉴五子棋的求解方法,因为同一颜色的棋子在一条线上的数量不超过4个,所以我们只需要枚举每一个点,判断这个点的周围是否有同色棋子,有的话就扩展这个棋子的周围,判断是否有连续的4个棋子即可。

在判断是否有连续的4个棋子时,我们只需要判断两边是否为空即可。判断的方法和五子棋中一样,直接累加即可。

如果找到符合条件的棋子后,就可以直接输出结果了。

C语言代码

#include <stdio.h>

int main() {
    int chessboard[19][19];
    int i, j, k, count, color, row, col;
    // 输入棋盘状态
    for (i = 0; i < 19; i++) {
        for (j = 0; j < 19; j++) {
            scanf('%d', &chessboard[i][j]);
        }
    }
    // 判断是否有人即将获胜
    for (i = 0; i < 19; i++) {
        for (j = 0; j < 19; j++) {
            if (chessboard[i][j] != 0) {
                color = chessboard[i][j];
                // 判断横行
                count = 1;
                for (k = j + 1; k < 19 && chessboard[i][k] == color; k++) {
                    count++;
                }
                if (count == 4 && (j == 0 || chessboard[i][j - 1] == 0) && (k == 19 || chessboard[i][k] == 0)) {
                    row = i + 1;
                    col = j + 1;
                    printf('%d:%d,%d
', color, row, col);
                    return 0;
                }
                // 判断纵列
                count = 1;
                for (k = i + 1; k < 19 && chessboard[k][j] == color; k++) {
                    count++;
                }
                if (count == 4 && (i == 0 || chessboard[i - 1][j] == 0) && (k == 19 || chessboard[k][j] == 0)) {
                    row = i + 1;
                    col = j + 1;
                    printf('%d:%d,%d
', color, row, col);
                    return 0;
                }
                // 判断左斜线
                count = 1;
                for (k = 1; k < 19 && i + k < 19 && j + k < 19 && chessboard[i + k][j + k] == color; k++) {
                    count++;
                }
                if (count == 4 && (i == 0 || j == 0 || chessboard[i - 1][j - 1] == 0) && (i + k == 19 || j + k == 19 || chessboard[i + k][j + k] == 0)) {
                    row = i + 1;
                    col = j + 1;
                    printf('%d:%d,%d
', color, row, col);
                    return 0;
                }
                // 判断右斜线
                count = 1;
                for (k = 1; k < 19 && i + k < 19 && j - k >= 0 && chessboard[i + k][j - k] == color; k++) {
                    count++;
                }
                if (count == 4 && (i == 0 || j == 18 || chessboard[i - 1][j + 1] == 0) && (i + k == 19 || j - k == -1 || chessboard[i + k][j - k] == 0)) {
                    row = i + 1;
                    col = j + 1;
                    printf('%d:%d,%d
', color, row, col);
                    return 0;
                }
            }
        }
    }
    // 没有人即将获胜
    printf('No
');
    return 0;
}

代码说明

  1. 程序首先定义一个二维数组 chessboard 来存储棋盘状态。
  2. 程序使用嵌套循环来遍历棋盘上的每一个位置。
  3. 对于每个位置,程序判断该位置是否为空。如果该位置不为空,则判断该位置周围是否有同色的棋子。
  4. 如果周围有同色的棋子,则程序扩展该位置周围的同色棋子,并判断是否有连续的 4 个棋子。
  5. 如果找到了连续的 4 个棋子,且该 4 个棋子的两端至少有一端为空位置,则程序输出即将获胜的棋子颜色和连成 4 个棋子的起始位置。
  6. 如果遍历完整个棋盘,都没有找到符合条件的棋子,则程序输出 'No'。

程序改进

  1. 程序可以添加一些优化,例如在遍历棋盘时,可以根据当前位置的颜色来判断需要判断的方向。
  2. 程序可以添加一些错误处理,例如判断输入的棋盘状态是否合法。
C语言编写程序判断五子棋游戏是否即将获胜

原文地址: https://www.cveoy.top/t/topic/o0la 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录