目录
在解决方案资源管理器中找到源文件和头文件的文件夹,分别再头文件文件夹中创建game.h头文件以及在源文件文件夹中创建test.c、game.c两个源文件。
3-1.InitBoard() 自定义的棋盘初始化函数 对九个棋盘格进行初始化为空格
一、游戏逻辑
1.游戏菜单
我们都知道,每打开一个游戏,首先出现在你面前的就是一个菜单,所以我们需要先有一个菜单。
由于游戏只需要简单的开始或退出,所以游戏菜单由1和0来选择进入游戏和退出游戏。
2.3x3二维数组和棋盘的打印
接着我们需要有一个3x3的二维数组用来存放每个棋盘格的落子情况,然后再实现棋盘在运行时的打印,产生视觉效果。
3.实现人与电脑的回合制
有了棋盘之后,就是实现玩家和电脑的交替下棋。玩家或电脑每下一步棋,就对棋局进行判断是继续进行还是结束。
4.对结果进行判定
游戏结束后,对棋局落子情况进行判定,是玩家赢或是电脑赢或者是平局。
二、程序框架
我们将游戏的源文件和头文件分为三个部分,分别是:game.h 、test.c 、game.c
1. game.h
在game.h中为所有需要用到的库函数的头文件的声明,以及要在test.c源文件中使用需要在game.h中定义的自定义函数的声明。
2.test.c
test.c为游戏的整体逻辑部分,并引用头文件"game.h"。
3.game.c
game.c为游戏的实现部分,也要引用头文件"game.h"。
在解决方案资源管理器中找到源文件和头文件的文件夹,分别再头文件文件夹中创建game.h头文件以及在源文件文件夹中创建test.c、game.c两个源文件。
三、游戏实现
1.test.c中编辑游戏的整体逻辑
1-1.创建主函数
int main() //创建主函数
{
srand((unsigned)time(NULL)); //生成随机数随机数(后面用到)
test(); //在test();中实现游戏逻辑,让主函数更简洁
return 0;
}
1-2.定义test()函数
void test() //定义test();函数
{
int input = 0;
do
{
menu(); //打印菜单
//选择游戏进程
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //实现游戏逻辑
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误!!!(请重新输入1 or 0)\n");
break;
}
} while (input); //每次游戏结束后让玩家选择,当玩家输入1为真游戏继续并开始,输入0为假退出循
// 环,游戏结束。
}
1-3.定义menu()函数
void menu()
{
printf("***********************\n");
printf("**** 1. play ****\n");
printf("**** 0. exit ****\n");
printf("***********************\n");
}
1-4.定义game()函数
void game()
{
//创建棋盘
char board[ROW][COL] = { 0 };
//棋盘初始化
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1)
{
//玩家回合
Player_Move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断结束或继续
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
//电脑回合
Computer_Move(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");
}
以下为test.c源文件的整体逻辑
#include "game.h"
//打印菜单
void menu()
{
printf("***********************\n");
printf("**** 1. play ****\n");
printf("**** 0. exit ****\n");
printf("***********************\n");
}
//游戏实现
void game()
{
//创建棋盘
char board[ROW][COL] = { 0 };
//棋盘初始化
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1)
{
//玩家回合
Player_Move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断结束或继续
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
//电脑回合
Computer_Move(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");
}
void test()
{
int input = 0;
do
{
//打印菜单
menu();
//选择游戏进程
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误!!!(请重新输入1 or 0)\n");
break;
}
} while (input);
}
int main()
{
//随机数
srand((unsigned)time(NULL));
test();
return 0;
}
2.game.h头文件部分的内容
头文件中包含对库函数、自定义函数的声明。
#pragma once
//头文件声明
#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 Player_Move(char board[ROW][COL], int row, int col);
void Computer_Move(char board[ROW][COL], int row, int col);
//char返回类型
//若返回"*"则玩家获胜
//若返回"#"则玩家获胜
//若返回"D"(draw)则平局
//若返回"C"(continue)游戏继续
char Is_Win(char board[ROW][COL], int row, int col);
int Is_Full(char board[ROW][COL], int row, int col);
3.game.c 游戏逻辑的实现
game.c是对test.c中game()函数中所使用的函数的定义。
3-1.InitBoard() 自定义的棋盘初始化函数 对九个棋盘格进行初始化为空格
//棋盘初始化
//void 空型函数,char board[ROW][COL]二维数组接收指针,int row、int col接收ROW\COL的形参
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++) //用for循环语句对二维数组进行初始化
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
3-2.打印棋盘
//棋盘打印
//此方式打印出来的棋盘,可以通过对COW和COL宏常量的修改来改变棋盘大小
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");
for(j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
3-3.玩家回合下棋
//玩家回合
void Player_Move(char board[ROW][COL], int row, int col)
{
printf("玩家回合\n");
int x = 0;
int y = 0;
while (1)
{
printf("请输入:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("该位置已被占用!!!\n");
}
}
else
{
printf("输入错误!!!(请重新输入1 ~ 3)\n");
}
}
}
3-4.电脑回合下棋
void Computer_Move(char board[ROW][COL], int row, int col)
{
printf("电脑回合\n");
while (1)
{
int x = rand() % row; //rand()与之前的主函数中srand()共同调用生成随机数
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
3-5.判断游戏的输赢
//判断游戏是否结束
char Is_Win(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 1; j < col; j++)
{
if (board[i][j - 1] == board[i][j] && board[i][j] == board[i][j + 1] && board[i][j] != ' ')
return board[i][j];
}
}
for (j = 0; j < col; j++)
{
for(i = 1; i < row - 1; i++)
if (board[i - 1][j] == board[i][j] && board[i][j] == board[i + 1][j] && board[i][j] != ' ')
return board[i][j];
}
for (i = 1; i < row - 1; i++)
{
for (j = 1; j < col - 1; j++)
{
if (board[i - 1][j - 1] == board[i][j] && board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ')
return board[i][j];
if (board[i - 1][j + 1] == board[i][j] && board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ')
return board[i][j];
}
}
if (1 == Is_Full(board, row, col))
return 'D';
else
return 'C';
}
//判断棋盘是否下满
int Is_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;
}
}
return 1;
}
到这里我们就完成对井字棋的实现了,电脑的下棋是随机的,会类似于人工智障的效果。
你也可以通过学习AI技术来对电脑实现增强——类似于Alpha Dog,不过井字棋这种逻辑简单的游戏也可以通过简单的算法设计来对游戏难度进行升级