井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。

想必大家小时候都玩过井字棋,今天分享大家一个用C语言做简单的井字棋游戏的教程,通过井字棋游戏,既能回忆起童年的美好,也能熟悉简单的C语言语法.

游戏演示:

动画

我们准备三个文件,分别为game.c,test.c,game.h

game.c文件用来写实现游戏功能的各个函数代码,test.c文件写游戏的总流程,game.h文件用来声明函数和初始值.

先来看test.c文件

文件内有三个函数,分别为菜单,游戏,主函数.

1
2
3
4
5
6
7
void menu()
{
printf("-----------------------\n");
printf("--------1.开始游戏-----\n");
printf("--------2.退出游戏-----\n");
printf("-----------------------\n");
}

菜单很简单,就是开始游戏和退出游戏.我们可以在主函数中switch-case语句实现,输入1开始游戏,输入2退出游戏,其他输入均提示重新输入.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
menu();
srand((unsigned int)time(NULL));
int input = 0;
do {
printf("请输入选项\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
break;
default:
break;
}

} while (input);
}

玩家输入1后进入游戏函数,游戏函数内对函数进行调用,函数的声明放在game.h头文件,定义放在game.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
25
26
27
28
29
30
31
32
33
34
35
void game()
{
char rst = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board,ROW,COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
while (1) {
//玩家下棋
player_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断输赢
rst = isWinner(board,ROW,COL);
if (rst != 'C') {
break;
}
//电脑下棋
computer_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
rst = isWinner(board, ROW, COL);
if (rst != 'C') {
break;
}

}
if (rst == '*') {
printf("恭喜你,赢得了胜利!\n");
}
else if (rst == '#') {
printf("很遗憾,你输了!\n");
}
else {
printf("平局了\n");
}

我们来简单说一下我们要实现的功能.首先,要初始化一个棋盘,我们可以用用三行三列的数组.玩家开始游戏,要将空棋盘显示给玩家,这时我们要打印棋盘.接着玩家下棋,输入坐标,将坐标处放上棋子,我们用*代表玩家的棋子,玩家下好后电脑下棋,用#代表电脑.当玩家或电脑先实现三个棋子连在一起,游戏结束.

下面是game.h头文件,文件内时头文件的引用,数据的初始化,游戏函数的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3

//初始化棋盘的
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(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);
//判断输赢
char isWinner(char board[ROW][COL], int row, int col);

下面是game.c文件的各个函数的定义

首先是初始化棋盘,便利3x3的数组,将数组内的元素置为空格字符

1
2
3
4
5
6
7
8
9
10
//初始化棋盘的
void InitBoard(char board[ROW][COL], int row, int col) {
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
board[i][j] = ' ';
}
}
}

接着是打印棋盘,打印棋盘很简单,但为了美观要将棋盘打印为井字,所以要花一些巧思

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
//打印棋盘
void DisplayBoard(char board[ROW][COL],int row,int col) {
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
printf(" %c ", board[i][j]);
if (j < col - 1) {
printf("|");
}

}
printf("\n");
if (i < row - 1) {
for (j = 0; j < col; j++)
{

printf("---");
if (j < col - 1) {
printf("|");
}
}
printf("\n");
}

}
}

接着是玩家下棋,当玩家输入的坐标小于1或大于3的,提示坐标非法,当坐标合法且该位置没有棋子将该坐标放上棋子*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//玩家下棋
void player_move(char board[ROW][COL], int row, int col) {
int x = 0;
int y = 0;

while (1) {
printf("玩家下棋>\n");
scanf("%d %d", &x, &y);
if (x<1 || x>row || y<1 || y>col) {
printf("坐标非法\n");
}
else {
if (board[x - 1][y - 1] == ' ') {
board[x - 1][y - 1] = '*';
break;
}
}

}

}

下面是电脑下棋,使用rand()和srand()生成随机值,rand()%row生成的值是0-2,+1后就是1-3,纵坐标同理,如果坐标处没有棋子放上棋子#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col) {
int x = 0;
int y = 0;
printf("电脑下棋\n");
while(1)
{
x = rand() % row;
y = rand() % col;
if(board[x][y] == ' ') {

board[x][y] = '#';
break;
}
}
}

最关键一步就是判断输赢,判断输赢无非就是行,列和对角线.除了输赢,还有平局,isPeace函数是用来判断平局,遍历棋盘,如果有至少一处为空,继续游戏,如果棋盘满了则为平局.返回* 玩家赢,返回# 电脑赢,返回Q 平局,返回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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int isPeace(char board[ROW][COL], int row, int col) {
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
if (board[i][j] == ' ') {
return 0;
}
}
return 1;
}
}
//判断输赢
char isWinner(char board[ROW][COL], int row, int col)
{

//判断行
int i = 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][1];
}
}
//判断列
int j = 0;
for (j = 0; j < col; j++) {
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ') {
return board[1][j];
}
}
//判断对角线
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ') {
return board[1][1];
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ') {
return board[1][1];
}
//判断平局
if (isPeace(board, row, col) == 1) {
return 'Q';
}
else {
return 'C';
}
}

以上就是一个用c语言制作简单的井字棋的介绍.代码和逻辑都很简单,只需要一些基础的c语言知识便可实现.技术有限,哪里有请指正,任何问题欢迎评论区留言交流.