软件技术基础课程设计.docx
- 文档编号:6654672
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:28
- 大小:33.88KB
软件技术基础课程设计.docx
《软件技术基础课程设计.docx》由会员分享,可在线阅读,更多相关《软件技术基础课程设计.docx(28页珍藏版)》请在冰豆网上搜索。
软件技术基础课程设计
《软件技术基础》课程设计
项目名称:
用C语言编写的五子棋游戏软件
班级:
信息学院2001级电子信息工程
学号:
XXX(2001714XXX)
XXX(2001714XXX)
XXX(2001714XXX)
XXX(2001714XXX)
XXX(2001714XXX)
完成时间:
2004年2月24日
指导教师:
XXX
日期:
2004年2月24日
C语言编写的一个五子棋游戏程序(课程设计综合编程)
课程设计的目的:
运用所学的C语言基础编程知识,编写一个由简单向复杂过渡的软件,从中了解到开发一个实用软件的基本常识和一般步骤;使所学的理论性知识向应用型转变。
一句话,就是学有所用。
课程设计的要求:
不仅需要熟练掌握C语言的编程程序方法,而且要深知相应的计算机硬件知识,使用计算机寄存器进行数据操作,熟悉宏定义以及相应的编程技巧。
课程设计的步骤:
一确定软件的功能
二定义核心数据结构
三对整个软件功能模块进行划分
四编写程序实现各功能模块
五对源程序进行编译,调试,形成软件产品
程序的功能分析:
本程序是提供两人对战的五子棋,不需要人机对战功能,两个玩家交替在五子棋盘上交替下棋子,当其中一位玩家的棋子布局有形成五子相连时,程序编判断他赢棋.
定义核心数据结构:
五子棋需要一个19X19的棋盘,因此要定义一个19X19的二维数组gChessboard来记录棋盘的状态,数组中每个元素代表棋盘上的每个交点,比如gChessboard[0][0]代表棋盘的左上角,gChessboard[0][19]代表棋盘的右上角,gChessboard[19][0]代表棋盘的左下角,gChessboard[19][19]代表棋盘的右下角.在棋盘中每个交点有三种状态,即有黑棋占据,白棋占据和无棋占据.因此,数组中定义的每个元素要反映三种状态,在程序中定义"0"时是表示无棋占据,"O"表示玩家1的棋子(黑子)占据,"X"表示玩家2的棋子(白子)占据.在程序中用当前光标移动来确定玩家的落子,因此要定义一个数据结构来记录光标的位置,在程序中定义了一个结构类型struckpoint它的两个整型成员X和Y分别用于记录光标位于棋盘的行和列的坐标值.
程序结构:
Init()初始化
GetKey()获取用户按键ChessKey()分析按键类型CheckKey()判断按键类型
main()函数调用函数ChessGo来执行落子命令调用函数JudgeWin来判断当前玩家是否赢棋
在初始化图象部分调用了函数DrawMap调用DrawCross()来画棋盘上的交叉点
bioskey(),textmode(),clrscr(),putch(),cputs(),
程序用的库函数:
gotoxy(),textcolor(),delay(),sound(),nosound().
程序的功能模块划分:
程序要根据用户的按键来决定执行什么操作,因此要有一个专门的"接收按键模块"来接收和处理用户的输入,这个模块被循环调用,直到分出胜负或用户按下退出键.
如图所示:
玩游戏循环
光标移动键无效按键退出
落子键
程序编译环境:
TuborC编译器
运行环境:
Windows95/98/2000/NT/me/XP
程序开发的工作进程:
需求分析(黄昊升)(4天)
确定五子棋规则(石挺干)(2天)
可行性分析(吉训蓬)(5天)
详细功能模块划分(陶文静)(6天)
源程序代码编写(石挺干)(17天)
编译、调试和验证(王全)(5天)
设计起止时间:
2004年1月18日——2004年2月24日
成果交付时间:
2004年2月25日
成员名单:
石挺干(2001714054)
吉训蓬(2001714051)
陶文静(2001714094)
王全(2001714084)
黄昊升(2001714079)
五子棋源程序的编写:
核心数据结构及符号常量定义模块:
/**********************************************************/
/*棋盘交叉点坐标的数据结构*/
structpoint
{
intx,y;
};
/**********************************************************/
/*定义全局变量*/
intgPlayOrder;/*指示当前行棋方*/
structpointgCursor;/*光标在棋盘上的位置*/
chargChessBoard[19][19];/*用于记录棋盘上各点的状态*/
/**********************************************************/
/*定义符号常量*/
/*定义画棋盘所需的制表符*/
#defineCROSSRU0xbf/*右上角点*/
#defineCROSSLU0xda/*左上角点*/
#defineCROSSLD0xc0/*左下角点*/
#defineCROSSRD0xd9/*右下角点*/
#defineCROSSL0xc3/*左边*/
#defineCROSSR0xb4/*右边*/
#defineCROSSU0xc2/*上边*/
#defineCROSSD0xc1/*下边*/
#defineCROSS0xc5/*十字交叉点*/
/*定义棋盘左上角点在屏幕上的位置*/
#defineMAPXOFT5
#defineMAPYOFT2
/*定义1号玩家的操作键键码*/
#definePLAY1UP0x1157/*上移--'W'*/
#definePLAY1DOWN0x1f53/*下移--'S'*/
#definePLAY1LEFT0x1e41/*左移--'A'*/
#definePLAY1RIGHT0x2044/*右移--'D'*/
#definePLAY1DO0x3920/*落子--空格键*/
/*定义2号玩家的操作键键码*/
#definePLAY2UP0x4800/*上移--方向键up*/
#definePLAY2DOWN0x5000/*下移--方向键down*/
#definePLAY2LEFT0x4b00/*左移--方向键left*/
#definePLAY2RIGHT0x4d00/*右移--方向键right*/
#definePLAY2DO0x1c0d/*落子--回车键Enter*/
/*若想在游戏中途退出,可按Esc键*/
#defineESCAPE0x011b
/*定义棋盘上交叉点的状态,即该点有无棋子*/
/*若有棋子,还应能指出是哪个玩家的棋子*/
#defineCHESSNULL0/*没有棋子*/
#defineCHESS1'O'/*一号玩家的棋子*/
#defineCHESS2'X'/*二号玩家的棋子*/
/*定义按键类别*/
#defineKEYEXIT0/*退出键*/
#defineKEYFALLCHESS1/*落子键*/
#defineKEYMOVECURSOR2/*光标移动键*/
#defineKEYINVALID3/*无效键*/
/*定义符号常量:
真,假---真为1,假为0*/
#defineTRUE1
#defineFALSE0
初始化模块:
/**************************************************************/
/*程序的初始化模块是用函数Init来实现的。
*/
/*在初始化图象部分调用了函数DrawMap。
函数DrawMap的功能是*/
/*根据gChessBoard棋盘状态在屏幕上画一个19X19的棋盘。
*/
/*在函数DrawMap中又调用了函数DrawCross,用来画棋盘上的交叉点。
*/
/**************************************************************/
/*界面初始化,数据初始化*/
voidInit(void)
{
inti,j;
char*Msg[]=
{
"Player1key:
",
"UP----w",
"DOWN--s",
"LEFT--a",
"RIGHT-d",
"DO----space",
"",
"Player2key:
",
"UP----up",
"DOWN--down",
"LEFT--left",
"RIGHT-right",
"DO----ENTER",
"",
"exitgame:
",
"ESC",
NULL,
};
/*先手方为1号玩家*/
gPlayOrder=CHESS1;
/*棋盘数据清零,即棋盘上各点开始的时候都没有棋子*/
for(i=0;i<19;i++)
for(j=0;j<19;j++)
gChessBoard[i][j]=CHESSNULL;
/*光标初始位置*/
gCursor.x=gCursor.y=0;
/*画棋盘*/
textmode(C40);
DrawMap();
/*显示操作键说明*/
i=0;
textcolor(BROWN);
while(Msg[i]!
=NULL)
{
gotoxy(25,3+i);
cputs(Msg[i]);
i++;
}
/*显示当前行棋方*/
ShowOrderMsg(gPlayOrder);
/*光标移至棋盘的左上角点处*/
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*画棋盘*/
voidDrawMap(void)
{
inti,j;
clrscr();
for(i=0;i<19;i++)
for(j=0;j<19;j++)
DrawCross(i,j);
}
/*画棋盘上的交叉点*/
voidDrawCross(intx,inty)
{
gotoxy(x+MAPXOFT,y+MAPYOFT);
/*交叉点上是一号玩家的棋子*/
if(gChessBoard[x][y]==CHESS1)
{
textcolor(LIGHTBLUE);
putch(CHESS1);
return;
}
/*交叉点上是二号玩家的棋子*/
if(gChessBoard[x][y]==CHESS2)
{
textcolor(LIGHTBLUE);
putch(CHESS2);
return;
}
textcolor(GREEN);
/*左上角交叉点*/
if(x==0&&y==0)
{
putch(CROSSLU);
return;
}
/*左下角交叉点*/
if(x==0&&y==18)
{
putch(CROSSLD);
return;
}
/*右上角交叉点*/
if(x==18&&y==0)
{
putch(CROSSRU);
return;
}
/*右下角交叉点*/
if(x==18&&y==18)
{
putch(CROSSRD);
return;
}
/*左边界交叉点*/
if(x==0)
{
putch(CROSSL);
return;
}
/*右边界交叉点*/
if(x==18)
{
putch(CROSSR);
return;
}
/*上边界交叉点*/
if(y==0)
{
putch(CROSSU);
return;
}
/*下边界交叉点*/
if(y==18)
{
putch(CROSSD);
return;
}
/*棋盘中间的交叉点*/
putch(CROSS);
}
接收用户的输入模块:
/**************************************************************/
/*程序在主函数中进入循环后,调用函数GetKey来获取用户的按键。
*/
/*函数GetKey的作用就是等待用户按键,然后返回该按键值。
*/
/*按键如果是字母,GetKey函数将把按键值的低字节处理成大写字母。
*/
/*这样无论用户是按'A'还是'a',返回的按键值是一样的。
*/
/*获取到按键值后,主函数要调用函数ChessKey来分析按键类型,*/
/*根据按键类型采取不同的反应动作。
*/
/**************************************************************/
/********************************/
/*主函数*/
voidmain()
{
...
while
(1)
{
press=GetKey();/*获取用户按键*/
switch(CheckKey(press))/*判断按键类型*/
{
...
}
}
...
}
/*********************************/
/*获取按键值*/
intGetKey(void)
{
charlowbyte;
intpress;
while(bioskey
(1)==0);
/*如果用户没有按键,空循环*/
press=bioskey(0);
/*将低字节一律转换位大写*/
lowbyte=press&0xff;
press=press&0xff00+toupper(lowbyte);
return(press);
}
/*************************************************/
/*分析按键类型*/
intCheckKey(intpress)
{
if(press==ESCAPE)
returnKEYEXIT;/*是退出键*/
else
if
((press==PLAY1DO&&gPlayOrder==CHESS1)||
(press==PLAY2DO&&gPlayOrder==CHESS2)
)
returnKEYFALLCHESS;/*是落子键*/
else
if
(press==PLAY1UP||press==PLAY1DOWN||
press==PLAY1LEFT||press==PLAY1RIGHT||
press==PLAY2UP||press==PLAY2DOWN||
press==PLAY2LEFT||press==PLAY2RIGHT
)
returnKEYMOVECURSOR;/*是光标移动键*/
else
returnKEYINVALID;/*按键无效*/
}
光标移动模块:
/**************************************************************/
/*程序在主函数中进入循环后,调用函数GetKey来获取用户的按键。
*/
/*函数GetKey的作用就是等待用户按键,然后返回该按键值。
*/
/*按键如果是字母,GetKey函数将把按键值的低字节处理成大写字母。
*/
/*这样无论用户是按'A'还是'a',返回的按键值是一样的。
*/
/*获取到按键值后,主函数要调用函数ChessKey来分析按键类型,*/
/*根据按键类型采取不同的反应动作。
*/
/**************************************************************/
/********************************/
/*主函数*/
voidmain()
{
...
while
(1)
{
press=GetKey();/*获取用户按键*/
switch(CheckKey(press))/*判断按键类型*/
{
...
}
}
...
}
/*********************************/
/*获取按键值*/
intGetKey(void)
{
charlowbyte;
intpress;
while(bioskey
(1)==0);
/*如果用户没有按键,空循环*/
press=bioskey(0);
/*将低字节一律转换位大写*/
lowbyte=press&0xff;
press=press&0xff00+toupper(lowbyte);
return(press);
}
/*************************************************/
/*分析按键类型*/
intCheckKey(intpress)
{
if(press==ESCAPE)
returnKEYEXIT;/*是退出键*/
else
if
((press==PLAY1DO&&gPlayOrder==CHESS1)||
(press==PLAY2DO&&gPlayOrder==CHESS2)
)
returnKEYFALLCHESS;/*是落子键*/
else
if
(press==PLAY1UP||press==PLAY1DOWN||
press==PLAY1LEFT||press==PLAY1RIGHT||
press==PLAY2UP||press==PLAY2DOWN||
press==PLAY2LEFT||press==PLAY2RIGHT
)
returnKEYMOVECURSOR;/*是光标移动键*/
else
returnKEYINVALID;/*按键无效*/
}
落子与判断胜负模块:
/**************************************************************/
/*当玩家按下落子键,主函数先调用函数ChessGo来执行落子命令。
*/
/*若是当前玩家在棋盘上的空格点落子,则函数ChessGo返回TRUE,*/
/*且主函数继续调用函数JudgeWin来判断当前玩家是否赢棋。
*/
/**************************************************************/
/*****************************************/
/*主函数*/
voidmain()
{
...
...
/*是落子键*/
caseKEYFALLCHESS:
if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/
DoError();/*落子错误*/
else
{
DoOK();/*落子正确*/
/*如果当前行棋方赢棋*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile=TRUE;/*退出循环标志置为真*/
}
/*否则*/
else
/*交换走棋方*/
ChangeOrder();
}
break;
...
...
}
/*********************************************/
/*走棋*/
intChessGo(intOrder,structpointCursor)
{
/*判断交叉点上有无棋子*/
if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL)
{
/*若没有棋子,则可以落子*/
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
textcolor(LIGHTBLUE);
putch(Order);
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
gChessBoard[Cursor.x][Cursor.y]=Order;
returnTRUE;
}
else
returnFALSE;
}
/*判断当前行棋方落子后是否赢棋*/
intJudgeWin(intOrder,structpointCursor)
{
inti;
for(i=0;i<4;i++)
/*判断在指定方向上是否有连续5个行棋方的棋子*/
if(JudgeWinLine(Order,Cursor,i))
returnTRUE;
returnFALSE;
}
/*判断在指定方向上是否有连续5个行棋方的棋子*/
intJudgeWinLine(intOrder,structpointCursor,intdirection)
{
inti;
structpointpos,dpos;
constinttestnum=5;
intcount;
switch(direction)
{
case0:
/*在水平方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y;
dpos.x=1;
dpos.y=0;
break;
case1:
/*在垂直方向*/
pos.x=Cursor.x;
pos.y=Cursor.y-(testnum-1);
dpos.x=0;
dpos.y=1;
break;
case2:
/*在左下至右上的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y+(testnum-1);
dpos.x=1;
dpos.y=-1;
break;
case3:
/*在左上至右下的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y-(testnum-1);
dpos.x=1;
dpos.y=1;
break;
}
count=0;
for(i=0;i { if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) { if(gChessBoard[pos.x][pos.y]==Order) { count++
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件技术 基础 课程设计