输入五子棋棋盘判断输赢或平局—程序设计(C语言)
?做这道题实在没有思路参考了这位作者的代码:
https://blog.csdn.net/jason_ranger/article/details/51250473
但在提交代码后系统只给了我8分,没有得到满分10分。
老师又要求画流程图写思路,于是就自己研究了一下。总体明白了,但有些地方还是想不通,就按照自己的想法做了一些更改。提交以后得了满分?。
自己写了一些注释,还画了一张流程图,大家可以参考一下,有错误欢迎指出。
以下是题目:
【问题描述】
已知两人分别执白棋和黑棋在一个围棋棋盘上下五子棋,若同一颜色的棋子在同一条横行、纵行或斜线上连成5个棋子,则执该颜色棋子的人获胜。编写程序读入某一时刻下棋的状态,并判断是否有人获胜。
输入的棋盘大小是19×19,用数字0表示空位置(即没有棋子),用数字 1表示该位置下了一白色棋子,用数字2表示该位置下了一黑色棋子。假设同一颜色的棋子在同一条横行、纵行或斜线上连成的棋子个数不会超过5个,并且最多有一人连成线的棋子个数为5。
【输入形式】
从控制台输入用来表示棋盘状态的数字0、1或2;每行输入19个数字,各数字之间以一个空格分隔,每行最后一个数字后没有空格;共输入19行表示棋盘状态的数字。
【输出形式】
若有人获胜,则先输出获胜人的棋子颜色(1表示白色棋子,2表示黑色棋子),然后输出英文冒号:,最后输出连成5个棋子连线的起始位置(棋盘横行自上往下、纵行自左往右从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 1 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表示)的人已经获胜,连成5个棋子的起始位置在第9行第8列,所以输出1:9,8。
在输入的样例2中,还没有同一颜色的棋子连成5个,所以无人获胜,直接输出No。
【评分标准】
该题要求判断五子棋的棋盘状态,提交程序文件名为chess.c或chess.cpp。
#include <stdio.h>
//宏定义
#define right 'r'
#define lower 'l'
#define lower_right 'i'
#define lower_left 'e'
#define none 'o'
//定义储存棋子的数组
int table[19][19];
//是否出界
int hit_space(int x, int y, char vec)
{
if (vec == right)
{
if (x - 1 >= 0 && table[x][y] == table[x + 4][y]&&x + 4 < 19 )
return 1;
}
if (vec == lower)
{
if (y - 1 >= 0 && table[x][y] == table[x][y + 4]&&y + 4 < 19)
return 1;
}
if (vec == lower_right)
{
if (x - 1 >= 0 && y - 1 >= 0 && table[x ][y ] ==table[x + 4][y + 4]&&x + 4 < 19 && y + 4 < 19 )
return 1;
}
if (vec == lower_left)
{
if (x - 1 >= 0 && y + 1 < 19 && table[x ][y ] == table[x + 4][y - 4]&&x + 4 < 19 && y - 4 >= 0)
return 1;
}
return 0;
}
//判断是否有相同的5个棋子
int tetra_colinear_on_vec(int x, int y, char vec)
{
if (vec == right)
{
//竖向的5个棋子一样返回1
if (x + 4 < 19//这里是判断最后一个棋子是否出棋盘
&& table[x][y] == table[x + 1][y]
&& table[x + 1][y] == table[x + 2][y]
&& table[x + 2][y] == table[x + 3][y]
&& table[x + 3][y] == table[x + 4][y])
return 1;
}
if (vec == lower)
{
//横向的5个棋子一样返回1
if (y + 4 < 19
&& table[x][y] == table[x][y + 1]
&& table[x][y + 1] == table[x][y + 2]
&& table[x][y + 2] == table[x][y + 3]
&& table[x][y + 3] == table[x][y + 4])
return 1;
}
if (vec == lower_right)
{
//斜向上↗5个棋子一样返回1
if (x + 4 < 19 && y + 4 < 19
&& table[x][y] == table[x + 1][y + 1]
&& table[x + 1][y + 1] == table[x + 2][y + 2]
&& table[x + 2][y + 2] == table[x + 3][y + 3]
&& table[x + 3][y + 3] == table[x + 4][y + 4])
return 1;
}
if (vec == lower_left)
{
//斜向下↘5个棋子一样返回1
if (x + 4 < 19 && y - 4 >= 0
&& table[x][y] == table[x + 1][y - 1]
&& table[x + 1][y - 1] == table[x + 2][y - 2]
&& table[x + 2][y - 2] == table[x + 3][y - 3]
&& table[x + 3][y - 3] == table[x + 4][y - 4])
return 1;
}
return 0;
}
/*
判断一个棋子哪一个方向有与它相同的5个棋子比如11111,
如果有的话返回该方向(竖向right,横向lower,斜向上LR,斜向下LL)
其他情况返回 none
*/
char tetra_colinear(int x, int y)
{
char vec;
vec = right;//right= "r"
if (tetra_colinear_on_vec(x, y, vec))
return vec;
vec = lower;
if (tetra_colinear_on_vec(x, y, vec))
return vec;
vec = lower_right;
if (tetra_colinear_on_vec(x, y, vec))
return vec;
vec = lower_left;
if (tetra_colinear_on_vec(x, y, vec))
return vec;
return none;
}
//判断哪位是赢家并输出
int checkmate()
{
int i, j;
for (i = 0; i < 19; i++)
for (j = 0; j < 19; j++)//遍历数组,找到连续的棋子1
{
if (table[i][j] == 1)
{
char vec = tetra_colinear(i, j);
if (vec == right || vec == lower || vec == lower_right||vec==lower_left)
{
if (hit_space(i, j, vec))
{
printf("1:%d,%d\n", i+1, j+1);
return 1;
}
}
}
}
for (i = 0; i < 19; i++)
for (j = 0; j < 19; j++)
{
if (table[i][j] == 2)
{
char vec = tetra_colinear(i, j);
if (vec == right || vec == lower || vec == lower_right || vec == lower_left)
{
if (hit_space(i, j, vec))
{
printf("2:%d,%d\n", i+1, j+1);
return 1;
}
}
}
}
return 0;
}
int main()
{
int i,j;
for (i = 0; i < 19; i++)
for (j = 0; j < 19; j++)//录入数组
scanf("%d",&table[i][j]);
if (!checkmate())
printf("No\n");
return 0;
}