C语言学习-五子棋盘

五子棋棋盘 five-in-a-row

用c语言写出可判断输赢的五子棋棋盘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 五子棋游戏,两个玩家,每个玩家输入要落子的行号和列号输入格式%d %d
*
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include <curses.h> mac使用

#define row 10 //棋盘行大小
#define col 10 //棋盘列大小

#define BLANK ' '//32 //空格
#define PL1 'O'//79 //显示O
#define PL2 'X'//88 //显示X

定义函数 define functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void init_board(int a[row][col]);
void output_board (int a[row][col]);
void setup_game(int* this_player,int* game_finished);

void this_player_makes_move (int a[row][col],int* this_player,int* game_finished);
int check_row_col_valid(int a[row][col],int validrow,int validcol);
void player_choose_row_col(int a[row][col],int* this_player,int* validrow,int* validcol);

int check_for_full_board(int a[row][col]);
int check_this_player_has_won(int a[row][col],int* this_player, int validrow,int validcol);
int check_row_has_won(int a[row][col],int* this_player,int validrow,int validcol);
int check_col_has_won(int a[row][col],int* this_player,int validrow,int validcol);
int check_main_diagonal_has_won(int a[row][col],int* this_player,int validrow,int validcol);
int check_Paradiagonal_has_won(int a[row][col],int* this_player,int validrow,int validcol);


void swap_this_player(int* this_player);

主程序 main code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(int argc, char const *argv[])
{
int board[row][col]; //棋盘数组
int this_player = 0; //当前落子的棋手,设定两个棋手0和1;
int game_finished = 0; //游戏结束标志,0表示没有结束,1表示游戏结束。

init_board(board); //初始化棋盘


setup_game(&this_player,&game_finished); //初始化游戏
output_board(board); //摆放棋盘
while(!game_finished) //如果游戏没有结束,继续进行
{
this_player_makes_move(board,&this_player,&game_finished); //游戏选手落子
swap_this_player(&this_player); //交换选手
}
}

set the chessboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 初始化棋盘
* @Author ZZP
* @DateTime 2019-08-01T23:45:18+0800
* 函数名: init_board
* @version 1.0
* @param a 棋盘数组
*/
void init_board(int a[row][col])
{
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
a[i][j]=BLANK;
}
}

start the game

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 建立游戏,将游戏参数初始化
* @Author ZZP
* @DateTime 2019-08-01T23:46:53+0800
* 函数名: setup_game
* @version 1.0
* @param this_player 传递当前游戏者编号
* @param game_finished 游戏结束标志
*/
void setup_game(int* this_player,int* game_finished)
{
*this_player=0;
*game_finished=0;
}

output the chessboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 输出棋盘
* @Author ZZP
* @DateTime 2019-08-01T23:48:27+0800
* 函数名: output_board
* @version 1.0
* @param a 棋盘数组
*/
void output_board (int a[row][col])
{
//printf("*1*2*3*4*5*6*7*\n");
//system("clear"); mac使用
system("cls");
for(int i=0;i<col;i++)printf("*%d",i);
printf("**\n");
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
printf("*");
printf("%c",a[i][j]);
}
printf("*%d\n",i);
//
}
//printf("***************\n");
for(int i=0;i<col;i++)printf("**");
printf("*\n");

}

change the player

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 交换游戏选手
* @Author ZZP
* @DateTime 2019-08-01T23:49:09+0800
* 函数名: swap_this_player
* @version 1.0
* @param this_player 当前游戏选手编号
*/
void swap_this_player(int* this_player)
{
*this_player=*this_player==0?1:0;
}

check whether the board is full

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 判断棋盘是否下满棋子
* @Author ZZP
* @DateTime 2019-08-01T23:52:10+0800
* 函数名: check_for_full_board
* @version 1.0
* @param a 棋盘数组
* @return 如果棋盘满返回1,否则返回0
*/
int check_for_full_board(int a[row][col])
{
int blankfound = 0;
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
if(a[i][j]==BLANK)
{
blankfound = 1;
break;
}
}
}
return blankfound;
}

make move

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 当前玩家进行落子
* @Author ZZP
* @DateTime 2019-08-01T23:49:48+0800
* 函数名: this_player_makes_move
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param game_finished 游戏结束标志
*/
void this_player_makes_move (int a[row][col],int* this_player,int* game_finished)
{
int validcol=0,validrow=0; //存放落子的行号和列号
if(check_for_full_board(a)){ //判断棋盘是否满了

player_choose_row_col(a,this_player,&validrow,&validcol); //选手下棋,获得落子的行号和列号

a[validrow][validcol] = *this_player==0?PL1:PL2; //棋盘数组落子

output_board(a); //更新棋盘

if(check_this_player_has_won(a,this_player,validrow,validcol))//判断玩家是否赢了
{
*game_finished=1;
printf("恭喜玩家%d赢了!!\n",*this_player+1);
}
}
else { //如果棋盘满了,那么游戏结束。
printf("没有可以地方可以落子,游戏结束!\n");
*game_finished = 1;
}
}

choose the place

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 当前玩家选择的落子点
* @Author ZZP
* @DateTime 2019-08-01T23:50:54+0800
* 函数名: player_choose_row_col
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子的行号
* @param validcol 落子的列号
*/
void player_choose_row_col(int a[row][col],int* this_player,int* validrow,int* validcol)
{
printf("请玩家%d输入要选择的行号(0-%d) 列号(0-%d)\n", *this_player+1,row-1,col-1);
scanf("%d %d",validrow,validcol);
while(!check_row_col_valid(a,*validrow,*validcol)){
printf("输入错误,请玩家%d输入要选择的行号(0-%d) 列号(0-%d)\n", *this_player+1,row-1,col-1);
scanf("%d %d",validrow,validcol);
}
}

check whether it is valid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 判断落子的位置是否符合要求
* @Author ZZP
* @DateTime 2019-08-01T23:54:14+0800
* 函数名: check_row_col_valid
* @version 1.0
* @param a 棋盘数组
* @param validrow 落子行号
* @param validcol 落子的列号
* @return 如果落子符合要求返回1,否则返回0
*/
int check_row_col_valid(int a[row][col],int validrow,int validcol)
{
int valid=0;
if (validrow<0||validrow>=row||validcol<0||validcol>=col)
{
valid=0;
}
else valid=a[validrow][validcol]==BLANK?1:0;
return valid;
}

check whether the player wins

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 判断该选手是否获胜
* @Author ZZP
* @DateTime 2019-08-01T23:55:46+0800
* 函数名: check_this_player_has_won
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子的行号
* @param validcol 落子的列号
* @return 如果获胜返回1,否则返回0
*/
int check_this_player_has_won(int a[row][col],int *this_player, int validrow,int validcol)
{
int win=0;
if (check_row_has_won(a,this_player,validrow,validcol)||
check_col_has_won(a,this_player,validrow,validcol)||
check_main_diagonal_has_won(a,this_player,validrow,validcol)||
check_Paradiagonal_has_won(a,this_player,validrow,validcol)
)
{
win=1;
}
return win;
}

check whether they are in a line

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* 判断水平方向上是否有五子连线
* @Author ZZP
* @DateTime 2019-08-02T00:00:17+0800
* 函数名: check_row_has_won
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子行号
* @param validcol 落子列号
* @return 如果有五子连线返回1,否则返回0
*/
int check_row_has_won(int a[row][col],int* this_player,int validrow,int validcol)
{
int win=0,count=1;
char c= *this_player==0?PL1:PL2;
for(int i=validcol-1;i>=0;i--){
if(a[validrow][i]!=c) break;
count++;
}
for(int i=validcol+1;i<=col;i++){
if(a[validrow][i]!=c) break;
count++;
}
if(count>=5){
win=1;
}
return win;
}

/**
* 判断竖直方向上是否有五子连线
* @Author ZZP
* @DateTime 2019-08-02T00:08:40+0800
* 函数名: check_col_has_won
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子行号
* @param validcol 落子列号
* @return 如果有五子连线返回1,否则返回0
*/
int check_col_has_won(int a[row][col],int* this_player,int validrow,int validcol)
{
int win=0,count=1;
char c= *this_player==0?PL1:PL2;
for(int i=validrow-1;i>=0;i--){
if(a[i][validcol]!=c) break;
count++;
}
for(int i=validrow+1;i<=col;i++){
if(a[i][validcol]!=c) break;
count++;
}
if(count>=5){
win=1;
}
return win;
}

/**
* 判断主对角线方向上是否有五子连线
* @Author ZZP
* @DateTime 2019-08-02T00:10:37+0800
* 函数名: check_main_diagonal_has_won
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子行号
* @param validcol 落子列号
* @return 如果有五子连线返回1,否则返回0
*/
int check_main_diagonal_has_won(int a[row][col],int* this_player,int validrow,int validcol)
{
int win=0,count=1,j;
char c= *this_player==0?PL1:PL2;
j=validcol+1;
for(int i=validrow-1;i>=0;i--){
if(a[i][--validcol]!=c) break;
count++;
}
for(int i=validrow+1;i<col;i++){
if(a[i][j++]!=c) break;
count++;
}
if(count>=5){
win=1;
}
return win;
}

/**
* 判断副对角线上是否有五子连线
* @Author ZZP
* @DateTime 2019-08-02T00:12:22+0800
* 函数名: check_Paradiagonal_has_won
* @version 1.0
* @param a 棋盘数组
* @param this_player 当前游戏选手编号
* @param validrow 落子行号
* @param validcol 落子列号
* @return 如果有五子连线返回1,否则返回0
*/
int check_Paradiagonal_has_won(int a[row][col],int* this_player,int validrow,int validcol)
{
int win=0,count=1,j;
char c= *this_player==0?PL1:PL2;
j=validcol-1;
for(int i=validrow-1;i>=0;i--){
if(a[i][++validcol]!=c) break;
count++;
}
for(int i=validrow+1;i<col;i++){
if(a[i][j--]!=c) break;
count++;
}
if(count>=5){
win=1;
}
return win;
}

dFVTJO.png