目录
三字棋介绍
说起三字棋,很多小伙伴在小时候课堂上或者课间一定和同学朋友玩过无数次了,但为了照顾没玩过的少数老铁,我们还是在这里回顾一下三字棋的规则:
在一个3*3的9宫格棋盘上下棋,双方依次在棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。
(三字棋)
话不多说,接下来让我介绍一下如何用C语言实现三字棋小游戏吧!
思路
大纲:
一、创建三个文件:
- game.c 存放实现本游戏的各个功能(棋盘、电脑玩家、游戏规则等...)的函数
- game.h 作为一种包含功能函数、数据接口声明
- test.c 存放主函数(main函数)控制游戏进程、引入game.h
作为本游戏存放主函数的.c文件,按我的设定,test.c的作用相当于搭建房屋时的框架,而game.c和game.h的作用是给这个房屋添砖加瓦,因此我们首先要把test.c文件搭建好再按需编写game.c文件,在通过game.h文件将他们组装成一个完整的“房屋”
二、功能及其实现
我们需要清楚实现一个三字棋小游戏需要解决的问题
- 棋盘的实现。
- 玩家下棋方式(输入坐标)。
- 电脑下棋方式(随机生成坐标)。
- 输赢判定方法。
怎么实现
第一步:创建test.c文件,构建框架
这里我们运用 do while循环和switch选择语句实现玩家根据meanu选择是否进行游戏,当输入为1时进行游戏,输入为0时结束游戏。
代码如下
void meanu()
{
printf("***********************************************\n");
printf("*********** 1.开始游戏 *************\n");
printf("*********** 0.结束游戏 *************\n");
printf("***********************************************\n");
}//打印菜单
void game()
{}//游戏函数
int main()
{
int input = 0;
do
{
meanu();
printf("请选择是否进行游戏:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}
第二步:实现游戏功能
创建game.c文件,分别实现打印棋盘、玩家下棋、电脑下棋、输赢判定。
打印棋盘
我们需要一个3*3的棋盘,可以用二维字符数组实现,一般情况下我们会选择用board[3][3]直接创建一个3行3列的字符数组,这没有错,但假如我们需要改变行列数时我们要把所有的board[3][3]改为我们所需要的board[x][y]。因此我们可以定义宏变量a b控制行列数,当我们需要改变行列数时,只需要把a和b的值改变就可以达到目的。这个思路适用于很多代码,这个习惯可以帮助你未来的代码更容易操作和改动。
打印以下3*3棋盘,我们首先在game.h文件里定义宏变量a 和 b,再在game.c文件里用intit_board初始化棋盘(每个棋子的位置放置' '空格符号),接着我们在display_board采用-和|符号打印棋盘,详见代码。
game.h下定义宏变量
#define a 3//定义行
#define b 3//定义列
intit_board初始化棋盘
void intit_board(char board[a][b])//初始化棋盘(二维字符数组内存放的全为' '(空格)字符)
{
int i = 0;
for (i = 0; i < a; i++)
{
int j = 0;
for (j = 0; j < b; j++)
{
board[i][j] =' ';
}
}
}
display_board打印棋盘
void display_board(char board[a][b], int x, int y)//打印棋盘
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < y; j++)
{
printf(" %c ", board[i][j]);
if (j < y - 1)
printf("|");
}//最后一列没有|
printf("\n");
if (i < x - 1)
{
for (j = 0; j < y; j++)
{
printf("---");
if (j < y - 1)
printf("|");
}//---|一个循环 但是每行的最后一个---|不打印|
}
printf("\n");
}
}
玩家下棋
逻辑很简单,玩家的棋子为 * 符号,只需要让玩家输入棋盘内某一坐标,如果该坐标没有棋子,就可以把棋子落在该位置。即输入字符数组下标,判定该字符是否为‘ ’,如果是落下棋子,如果不是则重新输入坐标。另外考虑到玩家可能不了解代码下标相关知识,我们需要在玩家输入坐标的基础上减1作为输入的下标。
代码如下
player_move
void player_move(char board[a][b], int x, int y)//玩家下棋
{
printf("玩家下棋:\n");
printf("请输入棋子位置:>");
int i = 0;
int j = 0;
do {
scanf("%d %d", &i, &j);
if (i - 1 < y && j - 1 < x)
{
if (board[j-1][i-1] == ' ')
{
board[j - 1][i - 1] = '*';
break;
}
else
printf("该位置已有其他棋子,请重新输入:\n");
}
else
printf("位置非法,请重新输入:\n");
} while (1);
}
电脑下棋
由于电脑玩家需要一定的随机性,所以我们引用rand函数和time控制电脑输入的下标。电脑的棋子为#符号。
computer_move(char board[a][b], int x, int y)
{
printf("电脑下棋:\n");
while (1)
{
int m = rand(time(NULL)) % a;
int n = rand(time(NULL)) % b;
if (board[m][n] == ' ')
{
board[m][n] = '#';
break;
}
}
}
输赢判定
回顾三字棋的规则:在一个3*3的9宫格棋盘上下棋,双方依次在棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。除了输赢还有把棋盘下满且无法判断输赢的情况,即为平局。我们在test.c文件下创建一个is_full函数判断棋盘是否下满,再创建一个is_win函数确定游戏规则并根据情况返回值,最后在test.c文件下的game()函数内根据返回值判断游戏胜负。
代码如下
is_full
用for循环按序检索二维数组内的值,遇到' '时返回1,代表棋盘没有满。
int is_full(char board[a][b], int x, int y)
{
int i = 0;
int j = 0;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
if (board[i][j] == ' ')
{
return 1;
}
}
}
return 0;
}
is_win
通过for循环语句和if判断行、列、斜方向的赢棋情况,并根据赢的棋子确定返回值,根据最后根据is_full的值返回‘Y’或者‘N’。
char is_win(char board[a][b], int x, int y)
{
int i = 0;
int j = 0;
for (i = 0; i < a; i++)
{
if (board[i][0] == board[i][1] &&board[i][1]== board[i][2]&&board[i][0]!=' ')//行
return board[i][0];
}
for (j = 0; j < b; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')//列
return board[0][j];
}
if (board[0][0] == board[1][1] && board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')//斜对角
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
{
return board[0][2];
}
if (is_full(board, a, b) == 0)
{
return 'N';
}
return 'Y';
}
game()
void game()
{
char board[a][b] = { 0 };//初始化二维字符数组
char x = 0;
intit_board(board);//初始化棋盘
display_board(board, a, b);//打印棋盘
while (1)
{
player_move(board, a, b);
display_board(board, a, b);
x = is_win(board, a, b);//接收is_win返回值
if (x != 'Y')
break;
computer_move(board, a, b);
display_board(board, a, b);
x = is_win(board, a, b);
if (x != 'Y')
break;
}
if (x == '*')
{
printf("恭喜你!赢得了本局游戏!!!\n");
}
else if (x == '#')
{
printf("很遗憾!你输掉了本局游戏!!!\n");
}
else if (x == 'N')
{
printf("平局!\n");
}
}
实现以上所有功能后,三字棋小游戏即可实现
-----------------------------------------------------------分割线-------------------------------------------------------------
总代码
所有代码如下所示
test.c
#include<stdio.h>
#include"game.h"
void meanu()
{
printf("***********************************************\n");
printf("*********** 1.开始游戏 *************\n");
printf("*********** 0.结束游戏 *************\n");
printf("***********************************************\n");
}
void game()
{
char board[a][b] = { 0 };
char x = 0;
intit_board(board);
display_board(board, a, b);
while (1)
{
player_move(board, a, b);
display_board(board, a, b);
x = is_win(board, a, b);
if (x != 'Y')
break;
computer_move(board, a, b);
display_board(board, a, b);
x = is_win(board, a, b);
if (x != 'Y')
break;
}
if (x == '*')
{
printf("恭喜你!赢得了本局游戏!!!\n");
}
else if (x == '#')
{
printf("很遗憾!你输掉了本局游戏!!!\n");
}
else if (x == 'N')
{
printf("平局!\n");
}
}
int main()
{
int input = 0;
do
{
meanu();
printf("请选择是否进行游戏:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}
game.h
#include<stdio.h>
#define a 3
#define b 3
#include<stdio.h>
void display_board(char board[a][b], int x, int y);
void intit_board(char board[a][b]);
void player_move(char board[a][b],int x,int y);
computer_move(char board [a][b], int x, int y);
char is_win(char board[a][b], int x, int y);
game.c
#include"game.h"
#include<stdlib.h>
#include<time.h>
void intit_board(char board[a][b])//初始化棋盘
{
int i = 0;
for (i = 0; i < a; i++)
{
int j = 0;
for (j = 0; j < b; j++)
{
board[i][j] = ' ';
}
}
}
void display_board(char board[a][b], int x, int y)//打印棋盘
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < y; j++)
{
printf(" %c ", board[i][j]);
if (j < y - 1)
printf("|");
}
printf("\n");
if (i < x - 1)
{
for (j = 0; j < y; j++)
{
printf("---");
if (j < y - 1)
printf("|");
}
}
printf("\n");
}
}
void player_move(char board[a][b], int x, int y)//玩家下棋
{
printf("玩家下棋:\n");
printf("请输入棋子位置:>");
int i = 0;
int j = 0;
do {
scanf("%d %d", &i, &j);
if (i - 1 < y && j - 1 < x)
{
if (board[j - 1][i - 1] == ' ')
{
board[j - 1][i - 1] = '*';
break;
}
else
printf("该位置已有其他棋子,请重新输入:\n");
}
else
printf("位置非法,请重新输入:\n");
} while (1);
}
computer_move(char board[a][b], int x, int y)
{
printf("电脑下棋:\n");
while (1)
{
int m = rand(time(NULL)) % a;
int n = rand(time(NULL)) % b;
if (board[m][n] == ' ')
{
board[m][n] = '#';
break;
}
}
}
//判断棋盘有没有满,如果满了返回0,没满返回1
int is_full(char board[a][b], int x, int y)
{
int i = 0;
int j = 0;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
if (board[i][j] == ' ')
{
return 1;
}
}
}
return 0;
}
char is_win(char board[a][b], int x, int y)
{
int i = 0;
int j = 0;
for (i = 0; i < a; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')//行
return board[i][0];
}
for (j = 0; j < b; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')//列
return board[0][j];
}
if (board[0][0] == board[1][1] && board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')//斜对角
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
{
return board[0][2];
}
if (is_full(board, a, b) == 0)
{
return 'N';
}
return 'Y';
}
代码运行截图:
本篇文章到此结束,欢迎提出建议~
如果对你有帮助,请点赞支持!
比心ღ(〃'▽'〃)