软件技术基础课程设计.docx

上传人:b****5 文档编号:6654672 上传时间:2023-01-08 格式:DOCX 页数:28 大小:33.88KB
下载 相关 举报
软件技术基础课程设计.docx_第1页
第1页 / 共28页
软件技术基础课程设计.docx_第2页
第2页 / 共28页
软件技术基础课程设计.docx_第3页
第3页 / 共28页
软件技术基础课程设计.docx_第4页
第4页 / 共28页
软件技术基础课程设计.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

软件技术基础课程设计.docx

《软件技术基础课程设计.docx》由会员分享,可在线阅读,更多相关《软件技术基础课程设计.docx(28页珍藏版)》请在冰豆网上搜索。

软件技术基础课程设计.docx

软件技术基础课程设计

《软件技术基础》课程设计

 

项目名称:

用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++

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1