三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
游戏主要分三个模块实现:game.h、game.c和test.c
game.h:用来写相关头文件,游戏中各部分函数的声明和预处理指令的实现
game.h的具体实现:
#pragma once
#include
#include
#include
#define ROW 3
#define COL 3
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void player_move(char board[ROW][COL], int row, int col,char x);
//电脑下棋
void computer_board(char board[ROW][COL], int row, int col, char x);
//判断输赢
char is_win(char board[ROW][COL], int row, int col,char ch);
test.c:主函数及游戏逻辑函数的实现
1.首先我们需要实现一个main函数,并将游戏菜单menu函数放入主函数中,使用一个循环来控制我们是否开始游戏,这里我们需要用到rand、srand和time函数来生成随机数,并将它运用于电脑下棋的坐标
2.接下来是游戏逻辑实现函数play_game函数:
test.c的具体实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//游戏逻辑实现函数
void play_game()
{
char result;
char board[ROW][COL] = { 0 };
init_board(board, ROW, COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)
{
player_move(board, ROW, COL, '*');//玩家下棋
result = is_win(board, ROW, COL, '*');//判断输赢
if (result == '*' || result == 'q')
break;
print_board(board, ROW, COL);//打印棋盘
computer_board(board, ROW, COL, '#');//电脑下棋
result = is_win(board, ROW, COL, '#');//判断输赢
if (result == '#' || result == 'q')
break;
print_board(board, ROW, COL);//打印棋盘
}
//判断输赢: 玩家: * 电脑: # 平局: q
if (result == '*')
printf("恭喜您获得了胜利\n");
else if (result == '#')
printf("很遗憾,电脑赢了\n");
else if (result == 'q')
printf("平局\n");
print_board(board, ROW, COL);//打印棋盘
}
//菜单函数
void menu()
{
printf("|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
printf("| 1.play |\n");
printf("| 0.exit |\n");
printf("|_______________________________________________________|\n");
}
//主函数
int main()
{
//随机数生成器
srand((unsigned int)time(NULL));
int input = 0;
do
{
//游戏菜单的实现
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
play_game();
break;
case 0:
printf("退出程序\n");
break;
default:
printf("选择错误,请重新选择:>");
break;
}
} while (input);
return 0;
}
game.c:游戏中各个接口函数的实现
由于这个模块是实现游戏过程中各个功能函数的实现,我们把它放到游戏实现这个模块来一一讲述
这里我们需要用到一个3*3的二维数组,并将其每个元素都置为空白字符,这里我们可以用字符 ‘空格’ 来实现。
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
为了使棋盘的打印更为美观
//打印棋盘
void print_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)//最后一列不需要打印
printf("|");
}
printf("\n");
if (i < row - 1)//最后一行不需要打印这两个字符
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
//玩家下棋
void player_move(char board[ROW][COL], int row, int col, char x)
{
int a, b;
printf("玩家下棋:\n");
while (1)
{
printf("请输入坐标:>");
scanf("%d%d", &a, &b);
//判断坐标是否合法
if ((a >= 1 && a <= row) && (b >= 1 && b <= col))
{
//判断坐标是否为空
if (board[a - 1][b - 1] != ' ')
{
printf("位置已被占用,请重新输入\n");
}
else
{
board[a - 1][b - 1] = x;
break;
}
}
else
{
printf("您的输入不合法,请重新输入\n");
}
}
if ((a >= 1 && a <= row)&& (b >= 1 && b <= col))
{
board[a - 1][b - 1] = x;
}
}
这个就相对简单了,不过需要注意的是
//电脑下棋
void computer_board(char board[ROW][COL], int row, int col, char x)
{
printf("电脑下棋\n");
while(1)
{
//生成随机数
int a = rand() % row;
int b = rand() % col;
//判断坐标是否已被占用
if (board[a][b] == ' ')
{
board[a][b] = x;
break;
}
}
}
//判断输赢
char is_win(char board[ROW][COL], int row, int col, char ch)
{
int count = 0;
int i;
//判断每一列
int j = 0;
for (int i = 0, j = 0; j < col; j++)
{
if (board[i][j] == ch)
{
count++;
for (int k = i + 1; k < row; k++)
{
if (board[k][j] == ch)
count++;
else
break;
}
}
if (count == row)
return ch;
else
count = 0;
}
count = 0;
//判断每一行
for (int j = 0,i = 0; i < row; i++)
{
if (board[i][j] == ch)
{
count++;
for (int k = j + 1; k < col; k++)
{
if (board[i][k] == ch)
count++;
else
break;
}
}
if (count == row)
return ch;
else
count = 0;
}
count = 0;
//判断主对角线
i = 0;
j = 0;
while (i < row)
{
if(board[i++][j++] == ch)
count++;
}
if (count == row)
return ch;
count = 0;
//判断副对角线
i = 0;
while (i < row)
{
for (j = 0; j < col; j++)
{
if (i + j == row - 1)
{
if (board[i][j] == ch)
count++;
}
}
i++;
}
if (count == row)
return ch;
int p = is_full(board, row, col);
if (p == 0)
{
return 'q';
}
}
判断棋盘是否已满
//判断棋盘是否已满
int is_full(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 1;
}
}
return 0;
}
注:这是test.c文件中的一段代码
while (1)
{
player_move(board, ROW, COL, '*');//玩家下棋
result = is_win(board, ROW, COL, '*');//判断输赢
if (result == '*' || result == 'q')
break;
print_board(board, ROW, COL);//打印棋盘
computer_board(board, ROW, COL, '#');//电脑下棋
result = is_win(board, ROW, COL, '#');//判断输赢
if (result == '#' || result == 'q')
break;
print_board(board, ROW, COL);//打印棋盘
}
//判断输赢: 玩家: * 电脑: # 平局: q
if (result == '*')
printf("恭喜您获得了胜利\n");
else if (result == '#')
printf("很遗憾,电脑赢了\n");
else if (result == 'q')
printf("平局\n");
print_board(board, ROW, COL);//打印棋盘
我们知道在前面的代码中,因为电脑是随机落子的,所以电脑获胜的可能性实在太小了,为了能让电脑下棋能够变得更加灵活,博主特地改编了电脑落子的方式
//电脑下棋(智能下棋)
void computer_board(char board[ROW][COL], int row, int col, char x)
{
printf("电脑下棋\n");
//若玩家将要赢,则去赌玩家
//主对角线
int i =0, j = 0;
if ((board[i][j] == '#' && board[i + 1][j + 1] == '#'&& board[i + 2][j + 2]==' ')
||(board[i][j] == '*' && board[i + 1][j + 1] == '*' && board[i + 2][j + 2] == ' '))
{
board[i + 2][j + 2] = x;
return;
}
else if ((board[i][j] == '#' && board[i + 2][j + 2] == '#'&& board[i + 1][j + 1]==' ')
|| (board[i][j] == '*' && board[i + 2][j + 2] == '*' && board[i + 1][j + 1] == ' '))
{
board[i + 1][j + 1] = x;
return;
}
else if ((board[i + 1][j + 1] == '#' && board[i + 2][j + 2] == '#'&& board[i][j]==' ')
|| (board[i + 1][j + 1] == '*' && board[i + 2][j + 2] == '*' && board[i][j] == ' '))
{
board[i][j] = x;
return;
}
//副对角线
i = 0, j = 2;
if ((board[i][j] == '#' && board[j][i] == '#'&& board[i + 1][j - 1]==' ')
|| (board[i][j] == '*' && board[j][i] == '*' && board[i + 1][j - 1] == ' '))
{
board[i + 1][j - 1] = x;
return;
}
else if ((board[i][j] == '#' && board[i + 1][j - 1] == '#'&& board[j][i]==' ')
|| (board[i][j] == '*' && board[i + 1][j - 1] == '*' && board[j][i] == ' '))
{
board[j][i] = x;
return;
}
else if ((board[j][i] == '#' && board[i + 1][j - 1] == '#'&& board[i][j]==' ')
|| (board[j][i] == '*' && board[i + 1][j - 1] == '*' && board[i][j] == ' '))
{
board[i][j] = x;
return;
}
//列
j = 0;
for (int i = 0, j = 0; j < col; j++)
{
if ((board[i][j] == '#' && board[i + 1][j] == '#' && board[i + 2][j] == ' ')
|| (board[i][j] == '*' && board[i + 1][j] == '*' && board[i + 2][j] == ' '))
{
board[i + 2][j] = x;
return;
}
else if ((board[i][j] == '#' && board[i + 2][j] == '#' && board[i + 1][j] == ' ')
|| (board[i][j] == '*' && board[i + 2][j] == '*' && board[i + 1][j] == ' '))
{
board[i + 1][j] = x;
return;
}
else if ((board[i + 1][j] == '#' && board[i + 2][j] == '#' && board[i][j] == ' ')
|| (board[i + 1][j] == '*' && board[i + 2][j] == '*' && board[i][j] == ' '))
{
board[i][j] = x;
return;
}
}
//行
for (int j = 0, i = 0; i < row; i++)
{
if ((board[i][j] == '#' && board[i][j + 1] == '#' && board[i][j + 2] == ' ')
|| (board[i][j] == '*' && board[i][j + 1] == '*' && board[i][j + 2] == ' '))
{
board[i][j + 2] = x;
return;
}
else if ((board[i][j] == '#' && board[i][j + 2] == '#' && board[i][j + 1] == ' ')
|| (board[i][j] == '*' && board[i][j + 2] == '*' && board[i][j + 1] == ' '))
{
board[i][j + 1] = x;
return;
}
else if ((board[i][j + 1] == '#' && board[i][j + 2] == '#' && board[i][j] == ' ')
|| (board[i][j + 1] == '*' && board[i][j + 2] == '*' && board[i][j] == ' '))
{
board[i][j] = x;
return;
}
}
//若下一步棋玩家赢不了,电脑也赢不了,则随机下棋
while (1)
{
//生成随机数
int a = rand() % row;
int b = rand() % col;
//判断坐标是否已被占用
if (board[a][b] == ' ')
{
board[a][b] = x;
break;
}
}
}
好了,到这里这个简单的C语言小游戏就实现了,其实代码量还是挺多的,如果大家觉得写的还不错的话还望给博主个三连哦!