想必大家都玩过三子棋游戏,就是说两个人在九宫格上面选一个空白部分,将其填上一个自己的符号,当你的符号连续三个连在一起就赢了(可以是: 横三行、竖三列、正对角线、反斜角线)就是如下红色部分相连的 。接下来让我分享下我的思路。(今天的代码分为三个部分,game.h头文件函数的声明存放部分,game.c是游戏的具体实现,test.c是我们的一个游戏的大概逻辑)
目录
1)打印菜单栏
菜单栏(menu)的打印方法是跟我写过的上一篇里猜数字游戏是一样的,这里我就再写一遍吧。首先我们都知道进游戏就会有个菜单让你选择玩和不玩游戏,不管三七二十一,kakaka先打印出来菜单,这里我们给两个选择1就是玩游戏,0就是退出游戏。代码如下:
//test.c源文件中的代码
void menu()
{
printf("**********************************\n");
printf("************ 1.play ************\n");
printf("************ 0.exit ************\n");
printf("**********************************\n");
}
这里之前要先写一个主函数,去调用这个菜单,(因为是不管怎样都要打印一遍,所以用do whiel 循环)代码如下:
//test.c源文件中的代码
int main()
{
do
{
menu(); //菜单栏打印
} while ();
return 0;
}
调用完菜单之后我们就要选择这两个,既然要选择 ,我们就要输入,我们定义一个变量为 input 代码如下:
//test.c源文件中的代码
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
} while ();
return 0;
}
选择完之后我们就要接收进来,根据选择的数字来做出相应的事情,这里就用到switch(),case语句实现,代码如下:
//test.c源文件中的代码
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1 :
game(); //选择1,就玩游戏,所以这里提供一个实现游戏代码的函数
break;
case 0 :
printf("退出游戏成功\n");
break;
default :
printf("选择错误,请重新选择>\n");
break;
}
} while (input); //根据输入0和1去判断循不循环
return 0;
}
接下来就是具体实现游戏的代码,首先下棋,我们知道要有一个九宫格棋盘(这里只说三子棋的棋盘),棋盘上不能有任何一个字符(棋盘初始化部分),有了棋盘就是我们在棋盘中填入我们的专属字符,所以要定义一个字符数组,然后就是玩家下棋,然后电脑下棋,然后判断部分,到底是谁赢或着是平局,或者还没下完,然后继续玩游戏。所以先来定义字符数组和初始化九宫格
2)定义字符数组和初始化九宫格
//test.c源文件中的代码
void game()
{
char board[ROW][COL] = { 0 }; //这里代码还是在test.c中
InitBoard(board,ROW,COL); //ROW,COL分别表示行和列(定义在头文件)
//这样可以让我们随心所欲的设置棋盘的行和列
}
//game.h头文件中的代码:
#define ROW 3
#define COL 3
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
初始化是将九宫格中全是空格部分即代码如下:
//game.c源文件中的代码
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] = ' '; //这里容易写成双引号,注意这里是单引号,字符形式
}
}
}
3)打印棋盘
首先要知棋盘的样子(一下图片是我们假设的棋盘样式),可看出一行的部分有九个减号,一列有三个竖杠,我们可以看到空格部分有三个,我们可以把我们要输入的字符放在中间,即就有一个空格一个字符一个空格一个竖杠,可以组成一个部分循环打印它,但注意这里只有两个竖杠,所以给条件要控制竖杠的打印,接下来就是打印横着的三个杠,只有两行所以也要个条件控制行部分的打印。
代码如下:
//test.c源文件中的代码:
void game()
{
char board[ROW][COL] = { 0 };
InitBoard(board,ROW,COL);
DisplayBoard(board, ROW, COL); //打印棋盘
}
//game.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);
//game.c源文件中的代码
void DisplayBoard(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("|");
}
printf("\n");
if (i < row - 1) //控制行的条件
{
for(j = 0; j < col; j++)
{
printf("---");
if(j < col - 1)
printf("|");
}
printf("\n");
}
}
}
3)玩家下棋
玩家下棋,玩家我们知道玩家不像我们的程序员,并不知道我们的行和列是由0开始的,所以定义下标时要注意,我们先定义两个变量,我们知道玩家不可能一把只能走一步,所以我们要写一个循环,这里注意,玩家在下坐标时只能有1-3的数字,所以你的坐标元素必须满足这个区间才行,不满足即是非法坐标,提示一下,满足了我们的区间,我们就又要判断那个坐标是否被下过了,没下过才能落子,下过了,就提示一句该坐标已被占用。
代码如下:
//test.c源文件中的代码
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board,ROW,COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL); //下完棋就要打印一次棋盘,这样才能看见棋子落在哪里
}
//game.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 PlayerBoard(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
void PlayerBoard(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家请下棋:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*'; //我们定义*为玩家的棋子
break;
}
else
{
printf("该坐标已被占用,请重新输入\n");
}
}
else
{
printf("非法坐标,请重新输入\n");
}
}
}
4)电脑下棋
电脑下棋的方式就比较简单,我们可以随机生成的坐标在区间范围内,随机生成数字的方式我已经在上一篇猜数字游戏中讲过了,这里就不讲了,电脑落子也要落在空格处,所以就找空格部分落
代码如下:
//test.c源文件中的代码
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board,ROW,COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ComputerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
}
}
//game.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 PlayerBoard(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
void ComputerBoard(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("电脑下棋:>\n");
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#'; //规定#为电脑下的棋子
break;
}
}
}
5)判断部分
有四种情况就是玩家赢,电脑赢,平局,继续游戏,我们可以有一个返回值,根据返回值来判读,比如,玩家赢我们就返回’*‘,电脑赢我们就返回’#‘,平局就返回’Q‘,还要继续游戏就根据'C'来判断
//test.c源文件中的代码
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board,ROW,COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C') //如果等于C了,说明还可以继续玩游戏,不等于了就退出循环
{
break;
}
ComputerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
//game.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 PlayerBoard(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
//判断输赢的情况
//玩家赢 就返回 '*'
//电脑赢 就返回 '#'
//平局 就返回 'Q'
//继续玩 就返回 'C'
char is_win(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
int is_full(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 is_win(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][0] != ' ')
{
return board[i][0];
}
}
// 判断竖三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][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 (1 == is_full(board, ROW, COL))
{
return 'Q'; //返回Q说明棋盘已经满了,并且没人输赢,即平局
}
else
{
return 'C'; //返回C说明棋盘没有满,游戏继续
}
}
6)game.h的全部代码
#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 PlayerBoard(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
//判断输赢的情况
//玩家赢 就返回 '*'
//电脑赢 就返回 '#'
//平局 就返回 'Q'
//继续玩 就返回 'C'
char is_win(char board[ROW][COL], int row, int col);
7)game.c的全部代码
#include "game.h"
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] = ' ';
}
}
}
void DisplayBoard(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("|");
}
printf("\n");
if (i < row - 1)
{
for(j = 0; j < col; j++)
{
printf("---");
if(j < col - 1)
printf("|");
}
printf("\n");
}
}
}
void PlayerBoard(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家请下棋:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("该坐标已被占用,请重新输入\n");
}
}
else
{
printf("非法坐标,请重新输入\n");
}
}
}
void ComputerBoard(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("电脑下棋:>\n");
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
// 返回 1 表示棋盘满了
// 返回 0 表示棋盘没满
int is_full(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 is_win(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][0] != ' ')
{
return board[i][0];
}
}
// 判断竖三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][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 (1 == is_full(board, ROW, COL))
{
return 'Q'; //返回Q说明棋盘已经满了,并且没人输赢,即平局
}
else
{
return 'C'; //返回C说明棋盘没有满,游戏继续
}
}
8)test.c的全部代码
#include "game.h"
void menu()
{
printf("**********************************\n");
printf("************ 1.play ************\n");
printf("************ 0.exit ************\n");
printf("**********************************\n");
}
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
InitBoard(board,ROW,COL);
DisplayBoard(board, ROW, COL);
while (1)
{
PlayerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1 :
game();
break;
case 0 :
printf("退出游戏成功\n");
break;
default :
printf("选择错误,请重新选择>\n");
break;
}
} while (input);
return 0;
}