初学者的三子棋游戏
摘要:相信每个人都有一个设计游戏的梦想,都曾玩过王者农药,cf等许多游戏,对之充满好奇,好奇他是怎样做出来的呢。
目录
摘要:相信每个人都有一个设计游戏的梦想,都曾玩过王者农药,cf等许多游戏,对之充满好奇,好奇他是怎样做出来的呢。
一、设计游戏
1.游戏的基本流程
首先一个代码的执行要现有main()函数
2.打印游戏菜单
可以通过函数的方法来使主函数变得简洁一些,写一个test()函数用来打印菜单,可以采用do—while循环来写,这样写可以先打印菜单,再判断玩家是否进行游戏。
创建一个整型变量,利用switch语句来判断是否进行下一步。
void test()
{
int input = 0;
do
{
//打印菜单
printf("************n");
printf("***1.开始***n");
printf("***0.退出***n");
printf("************n");
//判断玩家的选择
scanf("%d", &input);
switch (input)
{
//选择1则执行游戏程序
case 1:
game();
break;
//选择0退出游戏
case 0:
break;
//输入其他的数
default:
printf("请重新选择n");
}
} while (input);
}
3.规划
将每个部分分开
创建一个game.c文件将函数体部分放进game.c里。
创建一个game.h文件用来声明函数。
创建一个test.c文件写游戏的的主体部分
这样做可以合理规划,方便调试。
二、游戏划分
1.设计棋盘
要下棋得先有一个棋盘才能开始啊
首先棋盘3*3的大小
便采用#define来定义常量,也可以方便日后的棋盘大小的更改。
棋盘的样子也想好了,那便定义一个二维数组用来当作棋盘。
接下就是初始化棋盘,并将其盘打印出来。
2.打印棋盘
要打印棋盘可以先将二维数组初始化为空格,编写一个函数 initialize_board(board, ROW, COL);
在game.c文件里编写函数体,进行二维数组的初始化。
//初始化棋盘
void initialize_board(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++)
{
board[i][j] = ' ';
}
}
}
当然要在game.h文件里声明该函数。
初始化后便可以将棋盘整体打印出来。
//打印棋盘
void printf_board(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)//这里来限制分割行的次数,重用打印2行---
{
for (j = 0; j < col; j++)//用来打印每列的---
{
printf("---");
if (j < col - 1)//与上面一样,限制打印 | 的次数
printf("|");
}
printf("n");
}
}
}
效果如下
我们来分析这一段代码,首先可以将棋盘分为三行三列,用 | 来隔离每个字符,分割行则利用 --- 来处理;
有2点需要注意:
第2列后不用打 | ,这时便需要限制他的打印次数,可以利用if语句的效果做到限制,编写出 if (j < col - 1) 用来限制打印 | 的次数。
第2行后不用打印 --- ,同样利用上面的if语句 if (i < row - 1) 来限制分割行的次数,只用打印2行分割行 --- 。
3.玩家下棋
棋盘已将打印出来,接下来便是游戏的开始了,这时就要往棋盘里下棋。
//玩家下棋
void play_game(char board[ROW][COL], int row, int col)
{
//定义2个整型常量,来存放玩家输入的坐标位置
int x = 0;
int y = 0;
printf("玩家下棋n");
printf("请输入坐标n");
while (1)
{
scanf("%d %d", &x, &y);
//判断玩家输入的坐标是否在范围内
if (x > 0 && x <= row && y > 0 && y <= col)
{
//判断坐标是否被占用
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标已被占用,请重新输入坐标。n");
}
}
else
printf("坐标非法n");
}
}
4.电脑下棋
玩家下完棋,就该电脑下了,那电脑该怎么下棋呢?
这是要利用到库函数 rand()函数;来生成一个随机数。
//电脑下棋
void computer_game(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;//生成0~2的数字
y = rand() % col;//生成0~2的数字
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
这里的x = rand() % row; 很重要,%row可以将生成的数字保持在0~2之间,y也是一样。
其中使用rand()是需先引用srand((unsigned int)time(NULL)); //随机产生一个数
5.判断输赢
双方都下过棋了,就需要判断谁赢谁输,还是平局。
可以采用函数的返回类型来进行判断,C——继续,Q——平局,*——玩家赢,#——电脑赢。
//判断输赢
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][1] != ' ')
{
return board[i][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[0][i];
}
}
//判断正对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[0][0];
}
//判断副对角线
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[0][2];
}
//判断平局
//以上4种情况都不满足时
if (1 == board_full(board, row, col))
{
return 'Q';
}
//继续
return 'C';
}
在判断出没有人赢时,在利用 board_full(board, row, col) 函数进行检测棋盘是否下满,下满则返回1,否之返回0;
//判断
int board_full(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++)
{
if (board[i][j] == ' ')//判断游戏是否继续进行
return 0;
}
}
//棋盘以下满,返回1;
return 1;
}
所以game.c里的函数体也就结束了,剩下的便是在test.c文件中来接受返回的字符。
//判断
if ('C' != is_win(board, ROW, COL))
{
if ('*' == is_win(board, ROW, COL))
{
printf("玩家赢n");
break;
}
if ('#' == is_win(board, ROW, COL))
{
printf("电脑赢n");
break;
}
if ('Q' == is_win(board, ROW, COL))
{
printf("平局n");
break;
}
}
记得在判断谁赢了后加上break;来终止循环。
在test.c文件中的game()函数中调用的函数有以下这些,这样写的好处是代码简单明了。方便检查错误。有很大的便利。
void game()
{
//定义一个二维数组
char board[ROW][COL] = { 0 };
//初始化棋盘
initialize_board(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
while (1)
{
//玩家下棋
play_game(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
//判断
if ('C' != is_win(board, ROW, COL))
{
if ('*' == is_win(board, ROW, COL))
{
printf("玩家赢n");
break;
}
if ('#' == is_win(board, ROW, COL))
{
printf("电脑赢n");
break;
}
if ('Q' == is_win(board, ROW, COL))
{
printf("平局n");
break;
}
}
//电脑下棋
computer_game(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
//判断
if ('C' != is_win(board, ROW, COL))
{
if ('*' != is_win(board, ROW, COL))
printf("玩家赢n");
if ('#' != is_win(board, ROW, COL))
printf("电脑赢n");
if ('Q' != is_win(board, ROW, COL))
printf("平局n");
}
}
}
至此,整个游戏也便可以运行了。
快去试试写出自己的三子棋游戏。
三、整个游戏代码
test.c
#include"game.h"
void game()
{
//定义一个二维数组
char board[ROW][COL] = { 0 };
//初始化棋盘
initialize_board(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
while (1)
{
//玩家下棋
play_game(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
//判断
if ('C' != is_win(board, ROW, COL))
{
if ('*' == is_win(board, ROW, COL))
{
printf("玩家赢n");
break;
}
if ('#' == is_win(board, ROW, COL))
{
printf("电脑赢n");
break;
}
if ('Q' == is_win(board, ROW, COL))
{
printf("平局n");
break;
}
}
//电脑下棋
computer_game(board, ROW, COL);
//打印棋盘
printf_board(board, ROW, COL);
//判断
if ('C' != is_win(board, ROW, COL))
{
if ('*' != is_win(board, ROW, COL))
printf("玩家赢n");
if ('#' != is_win(board, ROW, COL))
printf("电脑赢n");
if ('Q' != is_win(board, ROW, COL))
printf("平局n");
}
}
}
void meau()
{
//打印菜单
printf("************n");
printf("***1.开始***n");
printf("***0.退出***n");
printf("************n");
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));//随机产生一个数
do
{
meau();
printf("请选择n");
//判断玩家的选择
scanf("%d", &input);
switch (input)
{
//选择1则执行游戏程序
case 1:
game();
break;
//选择0退出游戏
case 0:
break;
//输入其他的数
default:
printf("请重新选择n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
game.c
#include"game.h"
//初始化棋盘
void initialize_board(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void printf_board(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)//这里来限制分割行的次数,只用打印2行---
{
for (j = 0; j < col; j++)//用来打印每列的---
{
printf("---");
if (j < col - 1)//与上面一样,限制打印 | 的次数
printf("|");
}
printf("n");
}
}
}
//玩家下棋
void play_game(char board[ROW][COL], int row, int col)
{
//定义2个整型常量,来存放玩家输入的坐标位置
int x = 0;
int y = 0;
printf("玩家下棋n");
printf("请输入坐标n");
while (1)
{
scanf("%d %d", &x, &y);
//判断玩家输入的坐标是否在范围内
if (x > 0 && x <= row && y > 0 && y <= col)
{
//判断坐标是否被占用
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标已被占用,请重新输入坐标。n");
}
}
else
printf("坐标非法n");
}
}
//电脑下棋
void computer_game(char board[ROW][COL], int row, int col)
{
printf("电脑下棋n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;//生成0~2的数字
y = rand() % col;//生成0~2的数字
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判断
int board_full(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++)
{
if (board[i][j] == ' ')//判断游戏是否继续进行
return 0;
}
}
//棋盘以下满,返回1;
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][1] != ' ')
{
return board[i][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[0][i];
}
}
//判断正对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[0][0];
}
//判断副对角线
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[0][2];
}
//判断平局
//以上4种情况都不满足时
if (1 == board_full(board, row, col))
{
return 'Q';
}
//继续
return 'C';
}
game.h
#include<stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 3 //行
#define COL 3 //列
//初始化棋盘
void initialize_board(char board[ROW][COL], int row, int col);
//打印棋盘
void printf_board(char board[ROW][COL], int row, int col);
//玩家下棋
void play_game(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_game(char board[ROW][COL], int row, int col);
//判断
char is_win(char board[ROW][COL], int row, int col);