三子棋
三子棋的规则是:在3x3的棋盘里,双方轮流下子(以X和O表示),先将3个子连成一条线(横竖斜都可以)的一方获胜
下面是三子棋C语言实现的几个问题:
1.要想实现三子棋,我们需要一个棋盘,然后就是棋盘的内容。
2.下棋的时候需要判断是否该位置合法。
3.玩家和电脑的下棋逻辑不同,玩家需要手动输入,电脑是自己下棋
4.每下一步棋都需要判断游戏是否结束(哪方胜利、平局还是继续下棋)。
设计方式:
需要创建三个文件:一个头文件,两个源文件,头文件里面放的是函数的声明以及一系列预处理命令,命名为game.h
两个源文件,一个里面放的是主函数(游戏大体的运行顺序),命名为work.c,一个里面放的是游戏内容的实现逻辑(放大部分执行函数),命名为game.c
work.c的设置
首先是进入游戏,为了确保游戏可以重复玩,我们可以以循环的方式实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//work.c里面的内容
#include"gmae.h"//这样的话,在game.h里面包含的文件,在work.c里面也能使用
int main()
{
int option = 0; //在主函数里面设计循环,可以保证每次游戏结束后可以选择继续游戏或者退出游戏
do
{
Menu();
scanf ( "%d" , &option);
switch (option)
{
case 1:
game(); //如果选择开始游戏,就会进入到game()函数,
/*我们需要定义game函数来存放游戏的实现顺序*/
break ;
case 0:
printf ( "已退出" );
break ;
default :
printf ( "错误选择,请重新输入" );
}
} while (option);
return 0;
}
|
1
2
3
4
5
6
7
8
9
|
//work.c里面的内容
void Menu() //定义菜单函数,配合主函数里面的循环,可以实现每次游戏结束会跳到这个界面
{
printf ( "*****************\n" );
printf ( "*** 1.play ****\n" );
printf ( "*** 0.exit ****\n" );
printf ( "*****************\n" );
printf ( "请选择" );
}
|
然后就是游戏进行的顺序需要在game函数里面实现
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
|
//work.c里面的内容
void game()
{
srand ((unsigned int ) time (NULL)); //使用随机数,便于后面电脑下棋时是随机出棋
char board[ROW][COL] = { 0 }; //创建一个二维数组,用来实现棋盘的内容
printf ( "游戏开始:\n" );
init_board(board,ROW,COL); //初始化棋盘
print_board(board, ROW, COL); //打印棋盘
while (1)
{
char ret = '0' ;
player_move(board, ROW, COL); //玩家下棋
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断是否结束
if (ret == '*' )
{
printf ( "玩家胜利\n" );
break ;
}
computer_move(board, ROW, COL); //电脑下棋
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断是否结束
if (ret == '#' ) //
{
printf ( "电脑胜利\n" );
break ;
} //判断电脑胜利
if (ret == 'Q' ) //判断平局
{
printf ( "平局\n" );
break ;
} //判断平局
}
}
//work.c里面的内容
void game()
{
srand ((unsigned int ) time (NULL)); //使用随机数,便于后面电脑下棋时是随机出棋
char board[ROW][COL] = { 0 }; //创建一个二维数组,用来实现棋盘的内容
printf ( "游戏开始:\n" );
init_board(board,ROW,COL); //初始化棋盘
print_board(board, ROW, COL); //打印棋盘
while (1)
{
char ret = '0' ;
player_move(board, ROW, COL); //玩家下棋
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断是否结束
if (ret == '*' )
{
printf ( "玩家胜利\n" );
break ;
}
computer_move(board, ROW, COL); //电脑下棋
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断是否结束
if (ret == '#' ) //
{
printf ( "电脑胜利\n" );
break ;
} //判断电脑胜利
if (ret == 'Q' ) //判断平局
{
printf ( "平局\n" );
break ;
} //判断平局
}
}
|
下面是对这几点问题的解决方法:
game.h的内容设置
1
2
3
4
5
6
7
8
9
10
11
|
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3//设置了行与列的值,可以更改
#include<stdio.h>
#include<time.h>//用来实现时间戳
//下面是游戏实现逻辑所需的函数声明。
void init_board( char board[ROW][COL], int row, int col);
void player_move( char board[ROW][COL], int row, int col);
void computer_move( char board[ROW][COL], int row, int col);
void print_board( char board[ROW][COL], int row, int col);
char is_win( char board[ROW][COL], int row, int col);
|
game.c的设置
1.棋盘的内容
我们通过创建一个二维数组来作为棋子,通过输入坐标的方式来进行下棋的步骤
创建数组:
1
2
|
char board[ROW][COL] ;这里括号里面的值我们用提前处理过的ROW与COL来表示,
通过预处理命令,我们后期可以很方便的更改ROW与COL的值来改变棋盘的大小
|
2.棋盘以及棋盘的初始化
棋盘是3x3形式,所以我们可以通过循环的方式打印一个棋盘,下面是棋盘的格式
1
2
3
4
5
6
7
8
9
10
|
0 | 0 | 0
---|---|---
0 | 0 | 0
---|---|---
0 | 0 | 0 //而这个表里面的0就是我们的下的棋子占有的位置
/*而这个棋盘的设计是有明显的规律的:
第一行: 空格%c空格
第二行:---|循环3遍,但是最后遍不打印“|”
然后这样的两行在循环中多次打印,就出现了这样的三子棋表格
注意:最后一行不用再打印“---”
|
这里我们定义init_board()函数来初始化棋盘(即让数组的所有元素的值都为空格)
1
2
3
4
5
6
7
8
9
10
11
12
|
void init_board( char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ' ; //把所有元素赋值为' '
}
}
}
|
3.打印棋盘
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
|
void print_board( char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf ( " %c " , board[i][j]);
if (j != col - 1)
{
printf ( "|" ); //最后一列不打印'|'
}
}
//每次进行上一个循环时,i的值在变化,打印的是不同的值
printf ( "\n" );
if (i != row - 1) //最后一行不打印字符
{
for (j = 0; j < col; j++)
{
printf ( "---" );
if (j != col - 1)
printf ( "|" );
}
}
printf ( "\n" );
}
printf ( "\n" );
}
|
4.下棋步骤 玩家下棋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
void player_move( char board[ROW][COL], int row, int col)
{
printf ( "玩家下棋:\n" );
int x = 0;
int y = 0;
int i = 0;
int j = 0;
while (1)
{
scanf ( "%d %d" , &x, &y);
if (x >= 1 && x <= row && y <= col & y >= 1)
{
if (board[x-1][y-1] == ' ' )
{
board[x-1][y-1] = '*' ;
break ;
}
else
{
printf ( "该坐标被占用,请重新输入\n" );
}
}
}
}
|
电脑下棋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void computer_move( char board[ROW][COL], int row, int col)
{
char x = 0;
char y = 0;
while (1)
{
x = rand () % row;
y = rand () % col;
if (board[x][y] == ' ' )
{
board[x][y] = '#' ;
break ;
}
}
}
|
5.判断是否胜利
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
|
char is_full( char board[ROW][COL], int row, int col)
//判断是否格子占满了,格子占满了还没有出现胜利的话就会判断平局
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] = ' ' )
return 0; //用是否还有空格判断平局
}
}
}
char is_win( char board[ROW][COL], int row, int col) //这里是判断横竖斜三种方式是否出现胜利
{
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
if ((board[i][0] == board[i][1])&&(board[i][1]==board[i][2])&&board[i][1]!= ' ' );
{
return board[i][0];
}
}
for (i = 0; i < row; i++)
{
if ((board[0][i] == board[1][i])&&(board[2][i]==board[1][i]) && board[1][i] != ' ' )
{
return board[0][i];
}
}
if ((board[0][0] == board[1][1]) &&( board[1][1] == board[2][2]) && board[1][1] != ' ' )
{
return board[1][1];
}
if ((board[0][2] == board[1][1] )&& (board[1][1] == board[2][0]) && board[1][1] != ' ' )
{
return board[1][1];
}
//一旦出现胜利,就返回胜利一方的棋子字符
if (is_full(board,ROW,COL))
{
return 'Q' ; //平局返回'Q'
}
else
return 'C' ; //什么情况都没有就继续游戏
}
|
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/cainiaochufa2021/article/details/121256392