在学习编程的过程中,多少带点枯燥。我们学习编程就是为了能做点东西,
像游戏啥的,同时还能巩固知识。 一举两得,美哉美哉😃。
最近就做了一个小小的项目三子棋,下面是我自己实现这个游戏的一个大致过程。
文章目录
游戏演示
游戏的逻辑
- 用户选择玩游戏或者退出
- 当用户选择玩游戏
- 打印棋盘,用户输入坐标,然后放入棋子
- 电脑下棋
- 用户和电脑循环下棋,直达用户赢,电脑赢,或者平局
- 当用户选择退出
- 直接退出游戏界面,程序结束
文件的设计
- gameDriver.c这个文件负责游戏逻辑的实现,驱动游戏
代码:
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void game()
{
initBoard();
printBoard();
int ret = CONTINUE;
while (ret == CONTINUE)
{
playerGame();
printBoard();
ret = isWin();
if (ret == PLAYER_WIN)
{
printf("恭喜你赢了!!!\n");
return;
}
else if(ret == DRAW)
{
printf("平局\n");
return;
}
computerGame();
printBoard();
ret = isWin();
if (ret == COMPUTER_WIN)
{
printf("电脑赢了\n");
return;
}
else if(ret == DRAW)
{
printf("平局\n");
return;
}
}
}
void menu()
{
printf("======\t三子棋\t======\n");
printf("======\t1. play\t======\n");
printf("======\t0. exit\t======\n");
}
int main()
{
int input = 0;
//设置随机数生成器
srand((unsigned int)time(NULL));
do {
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("======\t退出三子棋游戏\t======\n");
break;
}
} while (input);
return 0;
}
- game.c这个文件负责各个功能的实现
代码:
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//初始化棋盘
void initBoard()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void printBoard()
{
int i = 0;
int j = 0;
int z = 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 (z = 0; z < col; z++)
{
if (i < row - 1)
{
printf("---");
}
if (z < col - 1 && i < row -1)
{
printf("|");
}
}
printf("\n");
}
}
//玩家玩游戏
void playerGame()
{
int x = 0;
int y = 0;
//1.判断坐标的合法性
//2.判断当前位置是否有棋子
printf("玩家玩\n");
do{
printf("请输入坐标(中间用空格隔开):\n");
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");
}
} while (1);
}
//电脑玩游戏
void computerGame()
{
printf("电脑玩\n");
do
{
//生成随机坐标
int x = rand() % row;
int y = rand() % col;
//放棋子
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
} while (1);
}
//判断输赢
int isWin()
{
//计数器
int count = 0;
//1.判断玩家是否赢了
//行判断
for (int i = 0; i < row; i++)
{
//每一行都把计数器重置
count = 0;
for (int j = 0; j < col; j++)
{
if (board[i][j] == '*')
{
count++;
}
}
if (count == row)
{
return PLAYER_WIN;
}
}
//列判断
for (int i = 0; i < col; i++)
{
//每一列都把计数器重置
count = 0;
for (int j = 0; j < row; j++)
{
if (board[j][i] == '*')
{
count++;
}
}
if (count == col)
{
return PLAYER_WIN;
}
}
//左对角线判断
//重置计数器
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == j && board[i][j] == '*')
{
count++;
}
}
}
if (count == row)
{
return PLAYER_WIN;
}
//右对角线
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i + j == row - 1 && board[i][j] == '*')
{
count++;
}
}
}
if (count == row)
{
return PLAYER_WIN;
}
//判断电脑是否赢了
for (int i = 0; i < row; i++)
{
//每一行都把计数器重置
count = 0;
for (int j = 0; j < col; j++)
{
if (board[i][j] == '#')
{
count++;
}
}
if (count == row)
{
return COMPUTER_WIN;
}
}
//列判断
for (int i = 0; i < col; i++)
{
//每一列都把计数器重置
count = 0;
for (int j = 0; j < row; j++)
{
if (board[j][i] == '#')
{
count++;
}
}
if (count == col)
{
return COMPUTER_WIN;
}
}
//左对角线判断
//重置计数器
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == j && board[i][j] == '#')
{
count++;
}
}
}
if (count == row)
{
return COMPUTER_WIN;
}
//右对角线判断
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i + j == row - 1 && board[i][j] == '#')
{
count++;
}
}
}
if (count == row)
{
return COMPUTER_WIN;
}
//判断是否平局
if (boardIsFull())
{
return DRAW;
}
//最后一种情况是继续游戏,直接返回即可
return CONTINUE;
}
//判断棋盘是否满了
static bool boardIsFull()
{
int count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] != ' ')
{
count++;
}
}
}
if (count == row * col)
{
return true;
}
else
{
return false;
}
}
- game.h这个头文件负责定义各种变量,函数,和引用库里的头文件
代码:
#define _CRT_SECURE_NO_WARNINGS
#define row 3
#define col 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>
char board[row][col];
void initBoard();
void printBoard();
void playerGame();
void computerGame();
int isWin();
static bool boardIsFull();
enum
{
PLAYER_WIN,
COMPUTER_WIN,
DRAW,
CONTINUE
};
主界面
主函数main()
- 我们根据主界面,先写出主函数
1.先打印菜单
2.让用户输入
3.根据用户输入选择进入game()函数,或者直接退出游戏
int main()
{
int input = 0;
do {
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("======\t退出三子棋游戏\t======\n");
break;
}
} while (input);
return 0;
}
- 运行截图
菜单函数menu()
- 根据界面即可写出菜单,下面是菜单函数的代码:
void menu()
{
printf("======\t三子棋\t======\n");
printf("======\t1. play\t======\n");
printf("======\t0. exit\t======\n");
}
游戏函数game()
- 代码:
void game()
{
initBoard();
printBoard();
int ret = CONTINUE;
while (ret == CONTINUE)
{
playerGame();
printBoard();
ret = isWin();
if (ret == PLAYER_WIN)
{
printf("恭喜你赢了!!!\n");
return;
}
else if(ret == DRAW)
{
printf("平局\n");
return;
}
computerGame();
printBoard();
ret = isWin();
if (ret == COMPUTER_WIN)
{
printf("电脑赢了\n");
return;
}
else if(ret == DRAW)
{
printf("平局\n");
return;
}
}
}
初始化棋盘函数initBoard()
ps:在这里我的函数都没有参数,因为我想简化一下程序
ps:数组的定义和其他变量的定义都放在game.h文件里了,因此我可以包含一下头文件直接进行操作
代码:
void initBoard()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
打印棋盘函数printBoard()
代码:
void printBoard()
{
int i = 0;
int j = 0;
int z = 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 (z = 0; z < col; z++)
{
if (i < row - 1)
{
printf("---");
}
if (z < col - 1 && i < row -1)
{
printf("|");
}
}
printf("\n");
}
}
用户玩游戏函数playerGame()
int x = 0;
int y = 0;
//1.判断坐标的合法性
//2.判断当前位置是否有棋子
printf("玩家玩\n");
do{
printf("请输入坐标(中间用空格隔开):\n");
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");
}
} while (1);
}
电脑玩游戏函数computerGame()
void computerGame()
{
printf("电脑玩\n");
do
{
//生成随机坐标
int x = rand() % row;
int y = rand() % col;
//放棋子
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
} while (1);
}
判断输赢函数isWin()
int isWin()
{
//计数器
int count = 0;
//1.判断玩家是否赢了
//行判断
for (int i = 0; i < row; i++)
{
//每一行都把计数器重置
count = 0;
for (int j = 0; j < col; j++)
{
if (board[i][j] == '*')
{
count++;
}
}
if (count == row)
{
return PLAYER_WIN;
}
}
//列判断
for (int i = 0; i < col; i++)
{
//每一列都把计数器重置
count = 0;
for (int j = 0; j < row; j++)
{
if (board[j][i] == '*')
{
count++;
}
}
if (count == col)
{
return PLAYER_WIN;
}
}
//左对角线判断
//重置计数器
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == j && board[i][j] == '*')
{
count++;
}
}
}
if (count == row)
{
return PLAYER_WIN;
}
//右对角线
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i + j == row - 1 && board[i][j] == '*')
{
count++;
}
}
}
if (count == row)
{
return PLAYER_WIN;
}
//判断电脑是否赢了
for (int i = 0; i < row; i++)
{
//每一行都把计数器重置
count = 0;
for (int j = 0; j < col; j++)
{
if (board[i][j] == '#')
{
count++;
}
}
if (count == row)
{
return COMPUTER_WIN;
}
}
//列判断
for (int i = 0; i < col; i++)
{
//每一列都把计数器重置
count = 0;
for (int j = 0; j < row; j++)
{
if (board[j][i] == '#')
{
count++;
}
}
if (count == col)
{
return COMPUTER_WIN;
}
}
//左对角线判断
//重置计数器
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i == j && board[i][j] == '#')
{
count++;
}
}
}
if (count == row)
{
return COMPUTER_WIN;
}
//右对角线判断
count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (i + j == row - 1 && board[i][j] == '#')
{
count++;
}
}
}
if (count == row)
{
return COMPUTER_WIN;
}
//判断是否平局
if (boardIsFull())
{
return DRAW;
}
//最后一种情况是继续游戏,直接返回即可
return CONTINUE;
}
判断棋盘是否满boardFull函数
static bool boardIsFull()
{
int count = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] != ' ')
{
count++;
}
}
}
if (count == row * col)
{
return true;
}
else
{
return false;
}
}