目录
1.1 在此文件中,我们对其它需要在此游戏中实现的功能所对应的函数库进行了包含
前言
用写小游戏的方式,可以更快,更高效且有趣地学习C语言!!!
一、游戏的设计思路
1.游戏模式
2.设计模块
二、分层说明
1.game.h文件
1.1 在此文件中,我们对其它需要在此游戏中实现的功能所对应的函数库进行了包含
//头文件包含
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
这样做的好处在于,当我们需要同时使用stdio.h、stdlib.h和time.h时,不用再到每个文件中进行文件包含,我们只需写一句#include"game.h"就行,如在test.c文件中进行文件包含。
1.2 进行符号定义
为什么需要符号定义呢?这是因为我们这里的符号ROW,COL对应了二维字符数组的大小,如果当我们想改变该字符数组的大小时,只需在改动game.h文件中的ROW和COL的值,就可以改变在此游戏中,所对应的字符数组大小,不用再一个一个数字去修改。
//符号定义
#define ROW 3
#define COL 3
1.3 函数声明
在game.h文件中进行函数声明后,在其他.c文件中想用调用在game.h声明过的函数,只需要将game.h进行一个文件包含就行了。如:#include"game.h"
//函数声明
//初始化二维字符数组
void InitBoard(char[][COL], int, int);
//展示棋盘
void DisplayBoard(char[][COL], int, int);
//玩家下棋
void PlayerMove(char[][COL], int, int);
//电脑下棋
void ComputerMove(char[][COL], int, int);
//判断输赢
char IsWin(char[][COL], int, int);
2.game.c文件
在此文件中,主要是编辑了一些关于棋局实现,玩家下棋,电脑下棋,棋局展示代码等等。
2.1 对二维字符数组进行初始化
void InitBoard(char board[ROW][COL], int row, int col) {
int i, j;
for (i = 0;i < row;i++) {
for (j = 0;j < col;j++) {
board[i][j] = ' ';
}
}
}
2.2 展示棋盘
void DisplayBoard(char board[][COL], int row, int col) {
int i, j;
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");
}
}
}
2.3 玩家下棋
void PlayerMove(char board[][COL], int row, int col) {
//定义一个坐标x,y
int x = 0, y = 0;
printf("玩家走>:\n");
while (1) {
printf("请输入下棋的坐标>:");
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");
}
}
}
2.4 电脑下棋
void ComputerMove(char board[][COL], int row, int col) {
printf("电脑走>:\n");
while (1) {
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
这其中的rand()%row,rand()%col,体现了电脑下棋的随机性,在这里我没有设计“让电脑看起来聪明点”的算法,我们初学者先能让电脑走起来就行了。
2.5 判断棋局是否为满
int IsFull(char board[][COL], int row, int col) {
int i, j;
for (i = 0;i < row;i++) {
for (j = 0;j < col;j++) {
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
2.6 判断是否赢了
char IsWin(char board[][COL], int row, int col) {
int i;
//横向三个连一起为赢
for (i = 0; i < row; i++) {
// board[i][1] != ' ' :如果三格都是空的,那也是不行的
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[2][i] == board[1][i] && board[1][i] != ' ') {
return board[1][i];
}
}
//对角线连在一起为赢
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
return board[1][1];
}
else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') {
return board[1][1];
}
//判断平局
//判断棋局是否为满(1为满,0为非满)
if (IsFull(board, row, col) == 1) {
return 'Q';
}
return 'C';
}
3.test.c文件
3.1 main函数
游戏的主要流程步骤,在main函数中体现出来,在main函数中,不断的调用其他函数从而来实现游戏功能。在test.c文件中,还主要编辑了菜单函数menu和游戏函数game
3.2 menu函数
void menu() {
printf("*************************\n");
printf("*****开始游戏输入:1*****\n");
printf("*****结束游戏输入:0*****\n");
printf("*************************\n");
}
3.3 game函数
void game() {
//对棋局进行初始化——用二维数组
char board[ROW][COL];
//对棋局进行初始化
InitBoard(board, ROW, COL);
//展示棋局,本质是打印二维数组的内容
DisplayBoard(board, ROW, COL);
//ret判断谁赢的变量
char ret = 0;
//玩家和电脑下棋
while (1) {
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
/*
ret的值为Q:平局 —— 游戏结束
ret的值为*:玩家赢 —— 游戏结束
ret的值为#:电脑赢 —— 游戏结束
ret的值为C:还没有人赢 —— 游戏继续
*/
ret = IsWin(board, ROW, COL);
if (ret != 'C') {
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C') {
break;
}
}
if (ret == '*') {
printf("玩家胜利!\n");
}
else if(ret == '#') {
printf("电脑胜利!\n");
}
else {
printf("平局!\n");
}
}
我们在game函数中,还调用了game.c文件中的函数,从而丰富了我们的游戏功能。这种分模块设计思想,也是以后在工作中设计一个项目的一个中心思想。
三、完整代码展示
1.test.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu() {
printf("*************************\n");
printf("*****开始游戏输入:1*****\n");
printf("*****结束游戏输入:0*****\n");
printf("*************************\n");
}
void game() {
//对棋局进行初始化——用二维数组
char board[ROW][COL];
//对棋局进行初始化
InitBoard(board, ROW, COL);
//展示棋局,本质是打印二维数组的内容
DisplayBoard(board, ROW, COL);
//ret判断谁赢的变量
char ret = 0;
//玩家和电脑下棋
while (1) {
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
/*
ret的值为Q:平局 —— 游戏结束
ret的值为*:玩家赢 —— 游戏结束
ret的值为#:电脑赢 —— 游戏结束
ret的值为C:还没有人赢 —— 游戏继续
*/
ret = IsWin(board, ROW, COL);
if (ret != 'C') {
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C') {
break;
}
}
if (ret == '*') {
printf("玩家胜利!\n");
}
else if(ret == '#') {
printf("电脑胜利!\n");
}
else {
printf("平局!\n");
}
}
int main() {
//input 用来接受用户的开始游戏的指令
int input;
srand((unsigned int)time(NULL));
do{
menu();
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入的数据有误,请重新输入!\n");
}
//input为0是跳出循环,游戏结束;input为1或者非零数时,游戏继续
} while (input);
return 0;
}
2.game.h文件
#define _CRT_SECURE_NO_WARNINGS 1
//头文件包含
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//符号定义
#define ROW 3
#define COL 3
//函数声明
//初始化二维字符数组
void InitBoard(char[][COL], int, int);
//展示棋盘
void DisplayBoard(char[][COL], int, int);
//玩家下棋
void PlayerMove(char[][COL], int, int);
//电脑下棋
void ComputerMove(char[][COL], int, int);
//判断输赢
char IsWin(char[][COL], int, int);
3.game.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//对二维字符数组进行初始化
void InitBoard(char board[ROW][COL], int row, int col) {
int i, j;
for (i = 0;i < row;i++) {
for (j = 0;j < col;j++) {
board[i][j] = ' ';
}
}
}
//展示棋盘
void DisplayBoard(char board[][COL], int row, int col) {
int i, j;
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 PlayerMove(char board[][COL], int row, int col) {
//定义一个坐标x,y
int x = 0, y = 0;
printf("玩家走>:\n");
while (1) {
printf("请输入下棋的坐标>:");
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 ComputerMove(char board[][COL], int row, int col) {
printf("电脑走>:\n");
while (1) {
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
//判断棋局是否为满
int IsFull(char board[][COL], int row, int col) {
int i, j;
for (i = 0;i < row;i++) {
for (j = 0;j < col;j++) {
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
//判断是否赢了
char IsWin(char board[][COL], int row, int col) {
int i;
//横向三个连一起为赢
for (i = 0; i < row; i++) {
// board[i][1] != ' ' :如果三格都是空的,那也是不行的
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[2][i] == board[1][i] && board[1][i] != ' ') {
return board[1][i];
}
}
//对角线连在一起为赢
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
return board[1][1];
}
else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') {
return board[1][1];
}
//判断平局
//判断棋局是否为满(1为满,0为非满)
if (IsFull(board, row, col) == 1) {
return 'Q';
}
return 'C';
}
四、游戏效果图
哈哈哈,看到这里不容易哇!第一次写这种游戏代码思路,不足之处,请多多指教。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。