程序结构
程序结构图
程序入口模块
main
函数主要用来作为整个程序的入口,它的功能是打印菜单并接受用户的输入。如果用户输入0
则直接退出程序。如果用户输入1
则进入游戏控制模块。当用户输入其他的值的时候,告诉用户输入有误,请重新输入。
#define ROW 3
#define COL 3
void menu()
{
printf("***********************************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("***********************************\n");
}
int main()
{
//srand函数用来为整个程序设置一个随机数种子。
srand((unsigned)time(NULL));
int input = 0;
do{
menu();
printf("请做出选择: >");
scanf("%d",&input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束!~~~\n");
break;
default:
printf("输入有误,请重新选择!~\n");
break;
}
} while (input);
return 0;
}
游戏控制模块
- 游戏控制模块的主要功能是实现游戏的整个逻辑控制。它做的事情主要是将
棋盘初始化模块
、打印棋盘模块
、玩家落子模块
、电脑落子模块
以及输赢判断模块
合理的组织起来进而实现整个游戏的逻辑控制。
void game() {
char board[ROW][COL];//定义棋盘
char result = ' ';
init_board(board, ROW, COL);
show_board(board, ROW, COL);
while(1){
player_move(board,ROW, COL);
show_board(board, ROW, COL);
if ('C' != (result = is_win(board, ROW, COL)))
break;
computer_move(board, ROW, COL);
show_board(board, ROW, COL);
if ('C' != (result = is_win(board, ROW, COL)))
break;
}
switch (result)
{
case '*':
system("cls");
printf("恭喜玩家获胜!\n");
break;
case '#':
system("cls");
printf("很遗憾电脑获胜!\n");
break;
case 'Q':
system("cls");
printf("哈哈!~皆大欢喜!平局!~~\n");
break;
}
}
初始化棋盘模块
- 初始化棋盘模块的主要功能是将模拟棋盘的数组
char board[ROW][COL]
中的每个元素都初始化为字符' '
,使得棋盘在游戏开始的时候时空的。
void init_board(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
打印棋盘模块
- 打印棋盘模块的主要功能是在DOS界面下,根据数组
char board[ROW][COL]
中的内容模拟打印出一个棋盘。
void show_board(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col-1; j++) {
printf(" %c |",board[i][j]);
}
printf(" %c \n",board[i][j]);
for (j = 0; j < col - 1; j++) {
printf("___|");
}
printf("___\n");
}
}
玩家落子模块
- 玩家落子模块的主要功能是在用户的输入之后对用户的输入进行合法性的判断。如果输入非法,提示用户输入非法的原因并要求用户重新输入直到用户的输入合法为止。用户的输入合法之后,将棋盘中的对应位置修改为
'*'
。我们使用'*'
来代表用户的输入。
void player_move(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;
while(1){
printf("玩家:>");
scanf("%d %d",&x, &y);
if (x < 0 || y < 0 || x >ROW || y > ROW) {
printf("对不起你的输入有误请重新输入\n");
continue;
}
if (board[x-1][y-1] != ' '){
printf("您下的位置已被占用,请重新选择位置\n");
continue;
}
board[x-1][y-1] = '*';
break;
}
}
电脑落子模块
- 电脑落子模块的主要功能是利用生成随机数的函数
rand()
来生成随机坐标。在坐标生成之后,对坐标的和合法性进行判断。如果随机生成的坐标合法,我们就将棋盘中对应的位置修改为’#’。我们在这里使用'#'
来表示电脑的输入。如果随机生成的坐标不合法,我们就重新生成,直到随机生成的坐标合法为止。
void computer_move(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;
printf("本回合轮到电脑下:\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] != ' ')
continue;
break;
}
board[x][y] = '#';
}
输赢判断模块
- 输赢判断模块的主要功能是分别判断
3*3
棋盘的3
行3
列和2
个对角线上的元素是不是相等且不等于' '
,如果是的话则返回对应的字符。否则,通过调用棋盘判满模块来判断棋盘是不是满了,此时如果棋盘满了我们就返回字符'Q'
代表平局。如果棋盘未满,我们就返回字符'C'
代表继续游戏。P.s.is_win函数
的可能的返回值有:'*'
、'#'
、'Q'
和'C'
。其中,'*'
代表玩家赢。'#'
代表电脑赢。'Q'
代表平局。'C'
代表继续游戏。
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][2] != ' ')
return board[i][2];
}
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i]\
&& board[1][i] == board[2][i]\
&& board[2][i] != ' ')
return board[2][i];
}
if (board[0][0] == board[1][1]\
&& board[1][1] == board[2][2]\
&& board[2][2] != ' ')
return board[2][2];
if (board[0][2] == board[1][1]\
&& board[1][1] == board[2][0]\
&& board[2][0] != ' ')
return board[2][0];
if (is_full(board, ROW, COL))
return 'Q';
return 'C';
}
棋盘判满模块
- 棋盘判满模块通过遍历整个
char board[ROW][COL]
数组,来实现判满操作。如果在遍历过程中我们遇到了字符' '
代表当前棋盘未满,此时返回0
。如果在整个遍历过程中我们没有遇到过字符' '
代表棋盘已经落满子了,此时返回1
。
int is_full(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i ++)
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
return 1;
}
程序源码
-
点击下面的
程序源码
可以查看并下载我的程序代码