思维导图
目录
2.1游戏第一步,写个主函数(在这个函数内部实现选择,打印菜单,玩游戏的功能)
4.1初始化函数(InitBoard(board,ROW,COL))
4.2显示棋盘函数(Display(board,ROW,COL))
4.3玩家下棋函数 (PlayMove(board,ROW,COL))
4.4电脑下棋(ComputerMove(board,ROW,COL)
1.准备阶段
创建三个文件:test.c game.c game .h,前两个是源文件,最后一个是头文件。
作用:
test.c:测试代码。在这里放主函数,以及安排顺序协调实现实现其它函数的功能,让游戏运行起来。
game.c:定义函数。
game.h:声明函数。
2test.c
2.1游戏第一步,写个主函数(在这个函数内部实现选择,打印菜单,玩游戏的功能)
代码如下:
int main() {
int input = 0;
srand((unsigned int)time(NULL));//函数rand()的种子
do {
menu();//打印菜单函数
printf(”请选择>:\n");
scanf("%d", &input);
switch (input) {//使用switch....case语句进行选择
case 1:game();//游戏函数
break;
case 0:printf("退出游戏\n");
break;
default:printf("选择错误,请重新选择>:\n");
break;
}
} while (input);
return 0;
}
2.2菜单函数的实现:
代码如下:
void menu() {
printf("***********************\n");
printf("******* 1. play ******\n");//1代表玩
printf("******* 0. exit ******\n");//0代表退出
printf("***********************\n");
}
2.3game函数的玩游戏逻辑
void game() {
char board[ROW][COL] = {0};//定义一个3*3的棋盘,ROW与COL是宏定义变量
InitBoard(board, ROW, COL);//初始化棋盘,作用是将棋盘board[][]初始化为空格
Display(board, ROW, COL);//显示棋盘;
char ret = 0;
while (1) {//人机大战不会一下子就结束,所以要有循环.
PlayerMove(board, ROW, COL);//玩家下棋;
ret=IsWin(board, ROW, COL);//判断输赢以及是否继续,如果不用继续就跳出循环
if (ret != 'C'){//假设代表继续的符号为'C'
break;
}
Display(board, ROW, COL);//显示棋盘
ComputerMove(board, ROW, COL);//电脑下棋;
ret=IsWin(board, ROW, COL);//判断输赢,如果不用继续就跳出循环
if(ret!='C') {// 假设代表继续的符号为'C'
break;
}
Display(board, ROW, COL);//显示棋盘;
}
if (ret == '*') {//假设玩家赢的返回符号为’*‘
printf("玩家赢\n");
}
else if (ret == '#') {//假设电脑赢的返回符号为’#‘
printf("电脑赢\n");
}
else {//假设平局的返回符号为’Q'.
printf("平局\n");
}
}
4.game()内函数的实现(game.c)
4.1初始化函数(InitBoard(board,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 (j = 0;j < col;j++) {
board[i][j] = ' ';//遍历初始化为空格。
}
}
}
4.2显示棋盘函数(Display(board,ROW,COL))
先看看我的棋盘:
这个棋盘其实可以分成六组来看:
void Display(char board[ROW][COL], int row, int col) {
int i = 0;
int j = 0;
for (i = 0;i < row;i++) {//第一个循环代表会打印row组
for (j = 0;j < col;j++) {//打印 | | 。
printf(" %c ", board[i][j]);
if (j < col - 1)//|只打印col-1行
printf("|");
}
printf("\n");
if (i < row - 1) {//打印---|---|---
for (j = 0;j < col;j++) {
printf("---");
if (j < col - 1)//|只打印col-1行
printf("|");
}
printf("\n");
}
}
}
看看效果:
4.3玩家下棋函数 (PlayMove(board,ROW,COL))
我想要实现的功能:
1.不是程序员的人也能轻松下棋(第一格坐标就是(1,1))。
2.下的格子用”*“代替。
3.如果下棋的地方被下了就不能下了。
4.不能下超过数组范围的地方。
实现代码:
void PlayerMove(char board[ROW][COL], int row, int col) {
int x = 0;
int y = 0;
while (1) {
printf("玩家下棋>:\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {//判断坐标是否合法
if (board[x - 1][y - 1] == ' ') {//判断下棋处是否被占用。x-1,y-1操作使得玩家下的(1,1)就是二维数组的(0,0)。
board[x - 1][y - 1] = '*';//将玩家下棋处改为’*‘。
break;//只有玩家下成功了才能跳出循环。
}
else
{
printf("该位置已被占用,请重新输入>:\n");//被占用提示
}
}
else
{
printf("坐标非法,请重新输入>:\n");//坐标非法提示
}
}
}
现在用Display()显示一下:
4.4电脑下棋(ComputerMove(board,ROW,COL)
电脑下棋的功能暂且实现到下随机合理的值。
代码:
void ComputerMove(char board[ROW][COL], int row, int col) {
printf("电脑下棋>:\n");
int x = 0;
int y = 0;
while (1) {
x = rand() % row;//调用库函数rand()随机生成0-row-1的值,所以x的值不会超过row
y = rand() % col;//调用库函数rand()随机生成0-col-1的值,所以x的值不会超过col
if (board[x][y] == ' ') {//电脑下的地方合法才能跳出循环
board[x][y] = '#';
break;
}
}
}
调用Display()看看效果:
4.5判断输赢(IsWin(board,ROW,COL))
功能:1.玩家赢返回’*‘。
2.电脑赢返回’#‘。
3. 平局返回’Q'.
4.游戏继续,返回‘C'。
实现代码:
char BoardFull( 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;
}
char IsWin(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];
else 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])//判断左对角线
return board[0][0];
else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//判断右对角线
return board[0][2];
else if (BoardFull(board, ROW, COL) ){//判断棋盘有没有满
return 'Q';
}
return 'C';//若无赢,无满就继续
}
看看效果:
5.全部代码
5.1game.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 Display(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
5.2test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu() {
printf("***********************\n");
printf("******* 1. play ******\n");
printf("******* 0. exit ******\n");
printf("***********************\n");
}
void game() {
char board[ROW][COL] = {0};//定义一个3*3的棋盘,ROW与COL是宏定义变量
InitBoard(board, ROW, COL);//初始化棋盘,作用是将棋盘board[][]初始化为空格
Display(board, ROW, COL);//显示棋盘;
char ret = 0;
while (1) {//人机大战不会一下子就结束,所以要有循环.
PlayerMove(board, ROW, COL);//玩家下棋;
Display(board, ROW, COL);//显示棋盘
ret=IsWin(board, ROW, COL);//判断输赢以及是否继续,如果不用继续就跳出循环
if (ret != 'C'){//假设代表继续的符号为'C'
break;
}
ComputerMove(board, ROW, COL);//电脑下棋;
Display(board, ROW, COL);//显示棋盘;
ret=IsWin(board, ROW, COL);//判断输赢,如果不用继续就跳出循环
if(ret!='C') {// 假设代表继续的符号为'C'
break;
}
}
if (ret == '*') {//假设玩家赢的返回符号为’*‘
printf("玩家赢\n");
}
else if (ret == '#') {//假设电脑赢的返回符号为’#‘
printf("电脑赢\n");
}
else {//假设平局的返回符号为’Q'.
printf("平局\n");
}
}
int main() {
srand((unsigned int)time(NULL));
int input = 0;
do {
menu();//打印菜单函数
printf("请选择>:\n");
scanf("%d", &input);
switch (input) {//使用switch....case语句进行选择
case 1:game();//游戏函数
break;
case 0:printf("退出游戏\n");
break;
default:printf("选择错误,请重新选择>:\n");
break;
}
} while (input);
return 0;
}
5.3game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void InitBoard(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 Display(char board[ROW][COL], int row, int col) {
int i = 0;
int j = 0;
for (i = 0;i < row;i++) {//第一个循环代表会打印row组
for (j = 0;j < col;j++) {//打印 | | 。
printf(" %c ", board[i][j]);
if (j < col - 1)//|只打印col-1行
printf("|");
}
printf("\n");
if (i < row - 1) {//打印---|---|---
for (j = 0;j < col;j++) {
printf("---");
if (j < col - 1)//|只打印col-1行
printf("|");
}
printf("\n");
}
}
}
void PlayerMove(char board[ROW][COL], int row, int col) {
int x = 0;
int y = 0;
while (1) {
printf("玩家下棋>:\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {//判断坐标是否合法
if (board[x - 1][y - 1] == ' ') {//判断下棋处是否被占用。x-1,y-1操作使得玩家下的(1,1)就是二维数组的(0,0)。
board[x - 1][y - 1] = '*';//将玩家下棋处改为’*‘。
break;//只有玩家下成功了才能跳出循环。
}
else
{
printf("该位置已被占用,请重新输入>:\n");//被占用提示
}
}
else
{
printf("坐标非法,请重新输入>:\n");//坐标非法提示
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col) {
printf("电脑下棋>:\n");
int x = 0;
int y = 0;
while (1) {
x = rand() % row;//调用库函数rand()随机生成0-row-1的值,所以x的值不会超过row
y = rand() % col;//调用库函数rand()随机生成0-col-1的值,所以x的值不会超过col
if (board[x][y] == ' ') {//电脑下的地方合法才能跳出循环
board[x][y] = '#';
break;
}
}
}
char BoardFull( 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;
}
char IsWin(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];
else 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])//判断左对角线
return board[0][0];
else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//判断右对角线
return board[0][2];
else if (BoardFull(board, ROW, COL) ){//判断棋盘有没有满
return 'Q';
}
return 'C';//若无赢,无满就继续
}
如果有不对的地方,请多多指教。