游戏规则
黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
算法设计
- 首先我们需要设计一个游戏开始菜单,整个逻辑我们可以使用do while嵌套switch语句完成。(test.c)
- 其次要进行游戏设计(我们创建函数的声明game.h和函数实现game.c两个文件):
- 首先设计对棋盘初始化的函数,因为该棋盘为二维,所以我们应该创建二维数组来进行存储。
- 其次应该设计棋盘的显示效果函数,将该二维数组按照一定格式输出。
- 然后就是分别控制玩家和电脑下棋的函数,按照一定的规则即可。
- 再然后就需要进行胜负的判定,有很多种不同的情况。
- 最后则是游戏逻辑函数的实现,调用以上功能函数实现游戏整体效果。
代码实现介绍
game.h
其中包含了各个函数的声明,以及各个指标的宏定义。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define DRAW 'd' //平局
#define CONTINUE 'c' //继续下棋
#define COMPUTER 'O' //电脑下棋
#define PLAYER 'X' //玩家下棋
#define BLANK ' ' //BLANK为空格字符用于初始化棋盘数组
#define ROW 3 //行
#define COL 3 //列
void tic_tac_toe(); //游戏逻辑函数
void init_board(char arr[ROW][COL]); //棋盘初始化函数
void show_board(char arr[ROW][COL]); //显示效果函数
char judge_game(char arr[ROW][COL]); //胜负判定函数
void player(char arr[ROW][COL]); //玩家下棋函数
void computer(char arr[ROW][COL]); //电脑下棋函数
game.c
其中包含了各个函数的具体实现。
棋盘初始化函数
函数逻辑:
- 将二维数组进行遍历,并将其都赋值为设定的初值。
代码实现:
void init_board(char arr[ROW][COL]) {
int i;
int j;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
arr[i][j] = BLANK;
}
}
}
显示效果函数
函数逻辑:
- 首先我们应该输出棋盘的坐标(行和列)
- 然后需要将棋盘展现出来,就要在输出数字的同时将棋盘边界输出。
代码实现:
void show_board(char arr[ROW][COL]) {
int i;
int j;
for (i = 0; i <= ROW; i++) {
printf(" %d ", i);
}
printf("\n -------------\n");
for (i = 0; i < ROW; i++) {
printf(" %d ", i + 1);
for (j = 0; j < COL; j++) {
if (j == 1) {
printf(" %c ", arr[i][j]);
}
else {
printf("| %c |", arr[i][j]);
}
}
printf("\n -------------\n");
}
}
玩家下棋函数
函数逻辑:
- 首先需要玩家进行下棋位置坐标输入,判断是否合法。
- 合法:继续判断该位置是否已有棋子。
- 无棋子:可以将该位置设置为玩家棋子。
- 有棋子:则输出提示信息,重新输入。
- 不合法:输出提示信息,然后重新输入。
代码实现:
void player(char arr[ROW][COL]) {
int i;
int j;
while (1) {
printf("请输入你要下棋位置的坐标:\n");
scanf("%d%d", &i, &j);
if (i < 1 || i > ROW || j < 1 || j > COL) {
printf("输入错误坐标\n");
continue;
}
if (arr[i - 1][j - 1] == BLANK) {
arr[i - 1][j - 1] = PLAYER;
break;
}
else {
printf("该位置已有棋子\n");
}
}
}
电脑下棋函数
函数逻辑:
- 电脑下棋我们使用最简化的设计,就是随机生成(rand函数)下棋位置(行和列),并除去已下棋位置即可。
代码实现:
void computer(char arr[ROW][COL]) {
printf("电脑下棋:\n");
while (1) {
int i = rand() % ROW;
int j = rand() % COL;
if (arr[i][j] == BLANK) {
arr[i][j] = COMPUTER;
break;
}
}
}
胜负判定函数
函数逻辑:
判断是否连成三个:
- 连成三个(结束):
- 竖着三个相连(1,1)(2,1)(3,1)…
- 横着三个相连(1,1)(1,2)(1,3)…
- 对角线三个相连(1,1)(2,2)(3,3)…
- 未连成三个:
- 判断有无空位:
- 有空位:继续
- 无空位:平局(结束)
代码实现:
char judge_game(char arr[ROW][COL]) {
int i;
int j;
//竖着三个
for (i = 0; i < ROW; i++) {
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != BLANK) {
return arr[i][0];
}
}
//横着三个
for (i = 0; i < COL; i++) {
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != BLANK) {
return arr[0][i];
}
}
//对角线三个
if ((arr[0][0] == arr[1][1] &&
arr[1][1] == arr[2][2]) ||
(arr[0][2] == arr[1][1] &&
arr[2][0] == arr[1][1]) &&
arr[1][1] != BLANK) {
return arr[1][1];
}
//未到三个,判断是否还能下棋
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (arr[i][j] == BLANK) {
return CONTINUE;
}
}
}
//平局
return DRAW;
}
游戏逻辑函数
函数逻辑:
- 首先创建二维数组,并将其初始化。
- 其次使用srand()配合随机数的动态生成。
- 然后将棋盘展示并进行下棋并判定是否继续,可以用while循环实现。
- 最后将结束结果用switch结构进行输出。
代码实现:
void tic_tac_toe() {
char arr[ROW][COL];
init_board(arr);
srand((unsigned)time(NULL));
char result = 0;
while (1) {
show_board(arr);
player(arr);
result = judge_game(arr);
if (result != CONTINUE) {
break;
}
show_board(arr);
system("pause");
system("cls");
computer(arr);
result = judge_game(arr);
if (result != CONTINUE) {
break;
}
}
show_board(arr);
switch (result)
{
case COMPUTER:
printf("电脑胜利!\n");
break;
case PLAYER:
printf("玩家胜利!\n");
break;
case DRAW:
printf("平局!\n");
break;
}
}
test.c
菜单展示函数
void menu() {
printf("***********************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("***********************\n");
}
主函数(程序逻辑)
函数逻辑:
- 首先用do while循环对菜单进行打印并将接收的输入,然后嵌套switch进行条件选择。
代码实现:
int main() {
int input = 0;
do
{
menu();
printf("请输入你的选择:\n");
scanf("%d", &input);
system("cls");
switch (input) {
case 1:
tic_tac_toe();
break;
case 0:
printf("退出游戏\n");
return 0;
break;
default:
printf("输入不合法\n");
break;
}
system("pause");
system("cls");
} while (input);
}
代码整体实现
game.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define DRAW 'd' //平局
#define CONTINUE 'c' //继续下棋
#define COMPUTER 'O' //电脑下棋
#define PLAYER 'X' //玩家下棋
#define BLANK ' ' //BLANK为空格字符用于初始化棋盘数组
#define ROW 3 //行
#define COL 3 //列
void tic_tac_toe(); //游戏逻辑函数
void init_board(char arr[ROW][COL]); //棋盘初始化函数
void show_board(char arr[ROW][COL]); //显示效果函数
char judge_game(char arr[ROW][COL]); //胜负判定函数
void player(char arr[ROW][COL]); //玩家下棋函数
void computer(char arr[ROW][COL]); //电脑下棋函数
game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//初始化棋盘
void init_board(char arr[ROW][COL]) {
int i;
int j;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
arr[i][j] = BLANK;
}
}
}
//显示棋盘
void show_board(char arr[ROW][COL]) {
int i;
int j;
for (i = 0; i <= ROW; i++) {
printf(" %d ", i);
}
printf("\n -------------\n");
for (i = 0; i < ROW; i++) {
printf(" %d ", i + 1);
for (j = 0; j < COL; j++) {
if (j == 1) {
printf(" %c ", arr[i][j]);
}
else {
printf("| %c |", arr[i][j]);
}
}
printf("\n -------------\n");
}
}
//玩家下棋
void player(char arr[ROW][COL]) {
int i;
int j;
while (1) {
printf("请输入你要下棋位置的坐标:\n");
scanf("%d%d", &i, &j);
if (i < 1 || i > ROW || j < 1 || j > COL) {
printf("输入错误坐标\n");
continue;
}
if (arr[i - 1][j - 1] == BLANK) {
arr[i - 1][j - 1] = PLAYER;
break;
}
else {
printf("该位置已有棋子\n");
}
}
}
//电脑下棋
void computer(char arr[ROW][COL]) {
printf("电脑下棋:\n");
while (1) {
int i = rand() % ROW;
int j = rand() % COL;
if (arr[i][j] == BLANK) {
arr[i][j] = COMPUTER;
break;
}
}
}
//判定胜负
char judge_game(char arr[ROW][COL]) {
int i;
int j;
//竖着三个
for (i = 0; i < ROW; i++) {
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != BLANK) {
return arr[i][0];
}
}
//横着三个
for (i = 0; i < COL; i++) {
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != BLANK) {
return arr[0][i];
}
}
//对角线三个
if ((arr[0][0] == arr[1][1] &&
arr[1][1] == arr[2][2]) ||
(arr[0][2] == arr[1][1] &&
arr[2][0] == arr[1][1]) &&
arr[1][1] != BLANK) {
return arr[1][1];
}
//未到三个,判断是否还能下棋
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (arr[i][j] == BLANK) {
return CONTINUE;
}
}
}
//平局
return DRAW;
}
void tic_tac_toe() {
char arr[ROW][COL];
init_board(arr);
srand((unsigned)time(NULL));
char result = 0;
while (1) {
show_board(arr);
player(arr);
result = judge_game(arr);
if (result != CONTINUE) {
break;
}
show_board(arr);
system("pause");
system("cls");
computer(arr);
result = judge_game(arr);
if (result != CONTINUE) {
break;
}
}
show_board(arr);
switch (result)
{
case COMPUTER:
printf("电脑胜利!\n");
break;
case PLAYER:
printf("玩家胜利!\n");
break;
case DRAW:
printf("平局!\n");
break;
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"game.h"
void menu() {
printf("***********************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("***********************\n");
}
int main() {
int input = 0;
do
{
menu();
printf("请输入你的选择:\n");
scanf("%d", &input);
system("cls");
switch (input) {
case 1:
tic_tac_toe();
break;
case 0:
printf("退出游戏\n");
return 0;
break;
default:
printf("输入不合法\n");
break;
}
system("pause");
system("cls");
} while (input);
}
IDE
- Visual Studio 2019