目录
简介:
三子棋又叫九宫棋、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,当棋盘摆满棋子时,没有一方的棋子走成一条线就视为平局。
思路分析:
需要先设计一个游戏框架,该框架包含一下内容:
1.游戏菜单:根据玩家的需求判断是否开始游戏。当一次游戏结束后再次打印菜单。
开始游戏后:
2.打印棋盘:在游戏开始时,和每个玩家落子后,显示棋盘的实时情况。
3.双方下棋:双方在棋盘上落子。
4.判断输赢:在每方结束落子后,判断游戏是否结束。
5.打印结果:当游戏结束后,输出游戏结构。
游戏实现:
由于该函数的代码量 和 功能较多时,我们分模块来实现各个功能。
① game.h 文件:存放 头文件的包含、符号和函数的声明。
② game.c 文件:存放 函数的定义,来实现游戏的各个功能。
③ test.c 文件: 存放 游戏的基本框架和部分函数的定义。
该游戏为三子棋,我们在game.h文件中定义每行列的格子数:
#define ROW 3 //行
#define COL 3 //列
1.游戏框架:
首先打印游戏菜单,让玩家根据菜单提供的选项选择即可。当玩家结束一次游戏后或者没有根据菜单输入时,则需要再次输入。
test.c文件:
//游戏框架
void menu()//游戏菜单
{
printf("*************************\n");
printf("*********1.play**********\n");
printf("*************************\n");
printf("*********0.exit**********\n");
printf("*************************\n");
}
void game()//游戏内容
{
char ret;//接收输赢判断结果
char board[ROW][COL] = {0};//创建棋盘
init_board(board,ROW,COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)//双方下棋
{
player_move(board, ROW, COL);//玩家落子
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);//电脑落子
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断输赢
if (ret != 'C')
{
break;
}
}
over_print(ret);//打印结果
print_board(board, ROW, COL);//打印棋盘
}
void test()//游戏流程
{
srand((unsigned int)time(NULL));//设置随机数种子
int n;
do
{
menu();
printf("请输入:>\n");
scanf("%d", &n);
switch (n)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (n);
}
当玩家选择开始游戏后:
执行game()函数。
2.游戏内容实现:
game.c文件:
①在游戏刚开始时,将创建的棋盘初始化为空棋盘。
void init_board(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 print_board(char board[ROW][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 < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
③玩家落子:玩家根据打印出的棋盘,输入想要落子的坐标即可。玩家的棋子为 '#'。
void player_move(char board[ROW][COL],int row, int col)
{
int x, y;
while (1)
{
printf("玩家下:>\n");
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("该处错误,请重下\n");
}
}
}
④电脑落子:我们已实现三子棋游戏的功能为主,这里不追求电脑的智能化,所以电脑落子的坐标根据游戏流程中设置的随机数种子生成随机数即可。电脑的棋子为 '*'。
void computer_move(char board[ROW][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;
}
}
}
⑤输赢判断:判断输赢只需要判断在一条线上的棋子是否一致即可。一致则返回该条线的任意一个棋子样式,即可判断获胜方为谁。
//仅在当前文件中使用
static int is_full(char board[ROW][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 is_win(char board[ROW][COL], int row, int col)
{
//行
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col - 1; j++)
{
if (board[i][j] != board[i][j + 1])
{
break;
}
}
if (j >= col - 1 && board[i][j]!=' ')
{
return board[i][j];
}
}
//列
for (j = 0; j < col; j++)
{
for (i = 0; i < row - 1; i++)
{
if (board[i][j] != board[i+1][j])
{
break;
}
}
if (i >= row - 1 && board[i][j] != ' ')
{
return board[i][j];
}
}
//对角线
for (i = 0; i < row-1; i++)
{
if (board[i][i] != board[i + 1][i + 1])
{
break;
}
}
if (i >= row - 1&& board[0][0]!=' ')
{
return board[0][0];
}
for (i = 0; i < row-1 ; i++)
{
if (board[i][col-1-i] != board[i + 1][col-i])
{
break;
}
}
if (i >= row - 1 && board[0][col-1]!=' ')
{
return board[0][col - 1];
}
//平局
if (is_full(board,row,col))
{
return 'Q';
}
return 'C';//未结束,游戏继续
}
⑥如果输赢判断有结果,打印结果。
void over_print(char ret)
{
if (ret == '#')
{
printf("玩家赢\n");
}
if (ret == '*')
{
printf("电脑赢\n");
}
if(ret == 'Q')
{
printf("平局\n");
}
}
完整代码:
game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3 //行
#define COL 3 //列
void init_board(char arr[ROW][COL],int row,int col);
void print_board(char arr[ROW][COL], int row, int col);
void player_move(char arr[ROW][COL], int row, int col);
void computer_move(char arr[ROW][COL], int row, int col);
char is_win(char arr[ROW][COL], int row, int col);
void over_print(char ret);
game.c
#include"game.h"
void init_board(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 print_board(char board[ROW][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 < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
void player_move(char board[ROW][COL],int row, int col)
{
int x, y;
while (1)
{
printf("玩家下:>\n");
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("该处错误,请重下\n");
}
}
}
void computer_move(char board[ROW][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;
}
}
}
static int is_full(char board[ROW][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 is_win(char board[ROW][COL], int row, int col)
{
//行
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col - 1; j++)
{
if (board[i][j] != board[i][j + 1])
{
break;
}
}
if (j >= col - 1 && board[i][j]!=' ')
{
return board[i][j];
}
}
//列
for (j = 0; j < col; j++)
{
for (i = 0; i < row - 1; i++)
{
if (board[i][j] != board[i+1][j])
{
break;
}
}
if (i >= row - 1 && board[i][j] != ' ')
{
return board[i][j];
}
}
//对角线
for (i = 0; i < row-1; i++)
{
if (board[i][i] != board[i + 1][i + 1])
{
break;
}
}
if (i >= row - 1&& board[0][0]!=' ')
{
return board[0][0];
}
for (i = 0; i < row-1 ; i++)
{
if (board[i][col-1-i] != board[i + 1][col-i])
{
break;
}
}
if (i >= row - 1 && board[0][col-1]!=' ')
{
return board[0][col - 1];
}
//平局
if (is_full(board,row,col))
{
return 'Q';
}
return 'C';//未结束,游戏继续
}
void over_print(char ret)
{
if (ret == '#')
{
printf("玩家赢\n");
}
if (ret == '*')
{
printf("电脑赢\n");
}
if(ret == 'Q')
{
printf("平局\n");
}
}
test.c
#include"game.h"
void menu()//游戏菜单
{
printf("*************************\n");
printf("*********1.play**********\n");
printf("*************************\n");
printf("*********0.exit**********\n");
printf("*************************\n");
}
void game()
{
char ret;//接收输赢判断结果
char board[ROW][COL] = {0};//创建棋盘
init_board(board,ROW,COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)//双方下棋
{
player_move(board, ROW, COL);//玩家落子
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);//电脑落子
print_board(board, ROW, COL); //打印棋盘
ret = is_win(board, ROW, COL); //判断输赢
if (ret != 'C')
{
break;
}
}
over_print(ret);//打印结果
print_board(board, ROW, COL);//打印棋盘
}
void test()//游戏框架
{
srand((unsigned int)time(NULL));//设置随机数种子
int n;
do
{
menu();
printf("请输入:>\n");
scanf("%d", &n);
switch (n)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (n);
}
int main()
{
test();
return 0;
}
8110

被折叠的 条评论
为什么被折叠?



