目录
前言
本篇文章利用软件工程的方法开发一个叫做三子棋的游戏,旨在加深对二维数组的认识和使用。
一、项目背景
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,如果棋盘已经下满棋还未出现胜者,则判本局胜负为平局。
本项目提出的目的是通过使用c语言的二维数组实现三子棋,使学者可以加深对c语言的二维数组的使用。
二、需求分析
2.1 可行性分析
本项目通过从技术、经济、操作、‘社会这四个方面进行可行性分析,从而确定本项目是否可以进行开发。
2.1.1 技术可行性分析
本项目用到了c语言的基础知识,开发者具备了相关知识,可以进行。
2.1.2 经济可行性分析
本项目作为学习过程的一个综合案例,旨在检验学习的效果,不涉及商业,不涉及任何经济支出。
2.1.3 操作可行性分析
本项目运行在电脑端,作为一个单间机游戏,参与者只需根据提示输入即可,不涉及任何复杂操作,只需了解键盘的使用即可。
2.1.4 社会可行性分析
本项目只是一个学习的一个案例,不涉及社会危害性。
2.2 功能需求分析
本项目开发一个叫三子棋的单价游戏,参与者有两个,分别是人和电脑。用例图如图2.2所示:
三、总体设计
通过层次结构图,展示了本项目的主要模块。如图3.1所示
四、详细设计
4.1 界面设计
界面使用控制台输出各种符合和文字信息,用户输入相应的数字选择相应的功能。
4.1.1 主菜单界面设计
主菜单第一行输出游戏名称
******** 三子棋 ***********
第二行输出分割线
*******************************************
第三和第四行输出功能选择
******** 1 play ***********
******** 0 exit ***********
最后两行输出
*******************************************
*******************************************
4.1.2 棋盘界面设计
棋盘界面是一个3x3的9宫格
组成元素:空格、下划线、短竖线
每个格子由三个空格组成,中间空格可以被其他符号替代。
相邻一行棋格使用四个下划线分割
相邻一列棋格使用一根短竖线分割
| |
------------
| |
------------
| |
棋盘的格子为空表示棋盘位置空闲
|
----
棋盘的格子被*占据,则表示玩家的走法
* |
----
棋盘的格子被#占据,则表示电脑的走法
# |
----
4.2 核心功能设计
4.2.1 数据存储结构
本项目使用二维数组表示一个3x3的棋盘,数组下标表示棋盘的位置。
4.2.2 胜负判断功能设计
首先,确定游戏的输出规则
* -> 玩家赢
# -> 电脑赢
'Q' -> 平局
'C' -> 继续下
- 利用一个循环检查每一行
- 利用一个循环检查每一列
- 检查对角线
- 判断棋盘是否空闲,空闲则继续,否则平局
- 继续下棋
下面利用N-S图描述胜负判断的逻辑过程,如图4.2.2所示
五、编码
程序设计语言:c语言
5.1 棋盘界面实现
//定义初始化棋盘的界面的函数
void boardView(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int k = 0;
for(i = 0; i < row; i++)
{
for (j = 0; j < row; j++)
{
printf(" %c ",board[i][j]);
if (j < row-1)
printf("|");
}
printf("\n");
//绘制下划线
if (i < row - 1)
{
for (k = 0; k < row; k++)
{
printf("----");
}
}
printf("\n");
}
}
5.2 玩家下棋
//定义玩家下棋的函数,玩家输入横坐标和纵坐标
//横坐标范围x:1~3
//纵坐标范围y:1~3
void playerMove(char board[ROW][COL], int row, int col)
{
int x = 0; //横坐标
int y = 0; //纵坐标
while (1)
{
printf("玩家回合\n");
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("输入的坐标超出范围!\n");
}
}
}
5.3 电脑下棋
//定义电脑下棋的函数,电脑的坐标由随机数生成
void computerMove(char board[ROW][COL], int row, int col)
{
printf("电脑回合\n");
while (1)
{
int x = rand() % ROW; //横坐标0~(ROW-1)
int y = rand() % COL; //纵坐标0~(COL-1)
//判断随机数的坐标对应的棋盘坐标是否空闲
if (' ' == board[x][y])
{
board[x][y] = '#';
break;
}
}
}
5.4 胜负判断
//定义判断游戏结果的函数
//
// *->player win
// #->computer win
// 'Q' -> 平局
// 'C' -> 继续下
char gameResult(char board[ROW][COL], int row, int col)
{
int i = 0; //行下标
int j = 0; //列下标
//检查行
for (i = 0; i < row; i++)
{
if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2])
return board[i][0];
}
//检查列
for (j = 1; j < row; j++)
{
if (board[0][j] != ' ' && board[0][j] == board[1][j] && board[1][j] == board[2][j])
return board[0][j];
}
//检查对角线
if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2])
return board[0][0];
if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0])
return board[1][1];
//平局检查
if (!isBoardAvailable(board, row, col))
return 'Q';
return 'C';
}