连子游戏设计报告书
2009年12月
目录页
目录
1 需求分析... 3
1.1功能与数据需求... 3
1.1.1题目要求的功能... 3
1.1.2 扩展功能... 3
1.2界面需求... 4
1.3 开发环境与运行需求... 6
2 概要设计... 6
2.1主要数据结构... 6
2.2程序总体结构... 6
2.3 各模块函数说明... 7
3 详细设计... 9
3.1主函数部分... 9
3.2 游戏绘图部分... 9
3.3 游戏部分... 10
3.4 判断输赢部分... 11
3.5 游戏存档读取 排名部分... 11
3.6 游戏AI部分... 12
4 测试... 13
5 用户手册... 13
5.1应用程序功能的详细说明... 13
5.2应用程序运行环境要求... 13
5.5输入数据类型、格式和内容限制... 13
6总结提高... 13
6.1课程设计总结... 13
6.2开发中遇到的问题和解决方法... 14
6.3 对自己完成课设完成情况的评价... 15
6.4对于《高级语言程序设计Ⅲ》与《高级语言程序设计课程设计》两门课程的意见与建议 15
附录:程序源代码... 16
需求分析
功能与数据需求
.1.1题目要求的功能
1. 游戏画面分为ABC三部分,分别代表菜单,棋盘和记分牌。
2. 进入游戏后玩家建立/读取存档,选择难度,开始游戏。
3. 在B区画棋盘,玩家与计算机交替部子(棋子颜色不同)。
4. 玩家通过上下左右移动键盘光标回车键下棋(鼠标亦可)。
5. 棋盘竖直放立,因此棋子会在该列由上往下落。
6. 游戏的任意一方横向,纵向或者斜向棋子连成4子即为胜利,于是本局游戏结束并积1分。若棋盘布满未分胜负,本局结束,双方各记一分。
7. 在存档中存储玩家胜负信息及游戏棋盘。
8. 游戏中途按Esc退出游戏。
9. 游戏设有排行榜,玩家可以看到自己的胜负,排名,胜率。
10. 玩家保存后将棋局录入存档。
11. A区是菜单栏,设:Level,New,Load/Save,Rank,Help。
12. B区是玩家栏,显示当前玩家与电脑的比分。玩家每次输赢均录入存档。
扩展功能
1. 设计游戏封面。
2. 调整坐标设计游戏友好UI。
3. 插入游戏声音。
4. 设计下棋动画,使画面更为流畅酷炫。
5. 在退出时候再次请求用户确认以防误操作。
6. 完善AI。
界面需求
开发环境与运行需求
硬件:Duo CORE2 T6500 ,4G Ram ,320G HDD ,nVidia 105M Video Clip.
软件:Windows Vista 的安全模式 在EVGA(640*480)的显示模式下运行 Turbo C++ IDE 3.0.
概要设计
主要数据结构
1.结构体:
Typedef struct{
Player P1;
Player P2;
board[2][8][9];
}Info;
typedef struct {
char name[8];
int score;
}Player;
其中 Info用来储存每个玩家的游戏数据,其中,巧妙地使用一个三维数组来实现两个棋盘的读取。
2. 整形数据
int imax,jmax,level,i;
其中,imax jmax用来定义棋盘边界,level定义本局游戏级数(有1,2)来选择棋盘。i是下子的位置(即棋盘的横坐标)。
程序总体结构
各模块函数说明
/*===========================函数声明=========================*/
//---------------------------绘画函数--------------------------
void startGraphics(); 绘制显卡
void coverage(); 绘制封面
void drawTittle(); 绘制封面文字
void drawCoverPicture1();绘制封面图片1
void drawCoverPicture2();绘制封面图片2
int all_key(); 键盘接受函数,返回键盘编码
void drawGameUI(); 绘制游戏界面
void drawStepXY(int i,int j,int level,int player);
绘制棋子,接收棋子所在棋盘坐标 I,J 棋盘登记 Level 棋子颜色Player等变量
void drawChessBoard(int level); 绘制棋盘,接收等级level 变量
void drawPlayerInfo(char name[]); 绘制玩家信息 接受玩家姓名字符串 name[]
void drawMenu(); 绘制控制菜单
void drawScoreP1(int score); 绘制玩家1分数
void drawScoreP2(int score); 绘制玩家2分数
void repaintBoard(); 刷新棋盘
void repaint(); 刷新游戏界面
void clearStepXY(int i,int j,int level);清除棋子,接收坐标(I,j)登记level
void moveChess(); 移动棋子函数
void PlayerTurn(int player); 玩家1或2轮控制函数,接收玩家player变量
void dropChess(int i,int player); 下子函数,接收下子列I,玩家Player变量
void drawArrow(int i); 绘制选择箭头,接收箭头所指列i
void clearArrow(int i); 清除选择箭头,接收箭头所指列i
//---------------------------游戏函数------------------------------
void newGame(); 新的游戏函数
void playingGame(int player); 玩家局,接收玩家player变量
void SureToQuit(); 再次确认退出游戏界面
void endDraw(char *buf); 一盘结束代码 输出字符串buf (输赢或平)
void save(); 储存游戏函数
void load(); 读取游戏函数
void rank(); 排名界面
void cpyInfo(Info *p1,Info *p2); 复制游戏信息结构体函数p1 to p2
void help(); 帮助界面
int judge(); 判断输赢 返回0继续 1玩家赢 2输 3平
void AITurn(int player); 电脑下棋函数 接受下子颜色player
int ThinkNextStep(int player); 电脑计算下棋函数
//---------------------------设置函数----------------------------
void setimaxjmax(); 设置棋盘边界 改变全局变量imax jmax
void setlevel(); 设计等级 (直接改变全局变量level)
void setPlayerName(Info *p); 设置玩家姓名,形参指针指向贮存游戏信息的结构体
详细设计
主函数部分
本程序主函数短小精悍,意思简洁明了!
void main(){
coverage();//绘制封面图片
setlevel();//设置游戏等级
newGame(); //开始新的游戏
}
游戏绘图部分
游戏程序中,设计了多个绘图移动图块的函数,比如绘制棋子的drawStepXY() ,clearStepXY(),drawArrow(),clearArrow()。
所有绘制函数参使用整形变量 i,j,player。分别代表所在棋盘的横纵坐标,哪个玩家。这样在多次使用绘图函数中,直观方便,简洁明了,增强了函数的易读性和维护性。
为了在游戏中跳出后返回,设置了一个repaint()函数,此函数可以重新绘制棋盘,十分方便! 代码:
void repaint(){
clearviewport();
drawGameUI();
drawChessBoard(level);
drawPlayerInfo(InfoNow.P1.name);
drawScoreP1(InfoNow.P1.score);
drawScoreP2(InfoNow.P2.score);
if(level==1){
drawStepXY(8,1,level,1);
drawStepXY(8,4,level,2);
}
if(level==2){
drawStepXY(11,1,level,1);
drawStepXY(11,5,level,2);
}
drawArrow(i);
repaintBoard();
}
游戏部分
newGame()函数为新开始游戏,次函数可以供游戏中菜单NewGame呼出后递 归套用,实现新开始游戏功能。
nextGame()可以由”下一局”功能调用模块,不会重置分数。
playingGame()函数为游戏进行函数,是一个循环函数。
当PlayerTurn()时,接受键盘输入,此时玩家可以按F1~F6开启菜单功能,按Esc退出游戏,左右回车控制下子。其中使用repaint()函数来重绘界面,返回游戏。代码:
void PlayerTurn(int player){
//set the Movement Limit
//move
while(1){
keycode=all_key();
if (keycode==RIGHT_ARROW && i>0 && i
clearArrow(i);
i++;
drawArrow(i);
}
if (keycode==LEFT_ARROW && i>1 && i<=imax ){
clearArrow(i);
i--;
drawArrow(i);
}
if(keycode==ENTER){
if(InfoNow.board[level-1][0][i-1]==0){
dropChess(i,player);
break;
}
}
if(keycode==ESC){
SureToQuit();
}
if(keycode==F1){newGame();
}
if(keycode==F2){nextGame();
}
if(keycode==F3){load()repain();;
}
if(keycode==F4){save();repaint();
}
if(keycode==F5){rank();repaint();
}
if(keycode==F6){setlevel();repaint();
}
if(keycode==F7){ help();repaint();
}
}
}
判断输赢部分
判断输赢或者平局函数judge,使用多重循环对棋盘进行扫描,遍历所有可能情况。
代码较长,取一小段示意:
int judge(){ //0:continue; 1:P1 win; 2:P2 win; 3:draw.
/*-------set who?-------*/
int who,code=1;
int im,jm,k;
/*------------"-"check------------*///横向检查
for (jm=1;jm<=jmax;jm++)
for (im=1;im<=imax-3;im++)
if((who=InfoNow.board[level-1][jm-1][im-1])!=0){
for(k=1;k<=3;k++)
if(InfoNow.board[level-1][jm-1][im-1+k]==who) code++;
if (code==4) return(who);
else code=1;
}
……
……
……
游戏存档读取 排名部分
结构体Info用来存储玩家名字,排名,局势,棋盘, 玩家密码。
读写过程中需要用户名和密码的输入。
游戏存读取通过链表组织,通过dos的文件读写完成存档的读写。读档流程图:
存档流程图:
排名是在文件读取出链表,然后根据链表内容进行冒泡排序,输出实现的。关键代码:
_node=_temp=head;
for(;_temp->next;_temp=_temp->next)
for(_node=p;_node->next;_node=_node->next){
if(_node->P1.score < _node->next->P1.score){
cpyInfo(&InfoTemp,_node);
cpyInfo(_node,_node->next);
cpyInfo(_node->next,&InfoTemp);
}
}
游戏AI部分
游戏AI是本课设的难点,也是最后花费最多时间完成的内容。思路如下
测试
用户手册
应用程序功能的详细说明
本游戏为北京工业大学09级计算机学院刘某编写的高级语言程序课程设计作业。
游戏简单易上手,游戏过程中,按F6可以查询帮助。
规则:连子游戏,游戏两方交替部子,棋盘垂直,棋子受重力吸引。任意一方棋子横纵斜连成4子即可获胜。
操作:按左右方向键移动光标,按回车(Enter)进行部子。F1重新开始;F2读取上局游戏;F3 存取当前游戏; F4查看排行榜; F5设置等级; F6查询帮助; 游戏途中按Esc键随时退出!(退出前会询问是否确认退出以防误操作。是Enter 取消Esc。)
应用程序运行环境要求
本游戏代码在TurboC 3.0 于 Dos 6.22 编译成功运行。
所得二进制程序需在Dos或兼容Dos的操作系统内运行,如WinXP及以下。建议以全屏模式运行。
输入数据类型、格式和内容限制
要求输入玩家名时,需输入ASCII码的可显示字符。限八字符内。
总结提高
课程设计总结
这次课设作业,是我所做过的印象最深,收获最大的作业之一!二到十二周学习的理论知识,一直停留在仅仅能完成简单的课后作业的水平而已。自从学习高级语言程序设计以来,就特别有独立完成一个使用程序的强烈愿望。而这次课程设计作业给了我一个很好实践理论知识的机会。也许是应为需要完成一个富有趣味性但是开发起来有一定难度游戏的缘故吧,在开发过程中,体会到了很多课上学不到的东西。
首先,面对一个待构建的庞大程序,应该先组织好一个清晰的思路,用科学统筹的方法去做好规划。而我在开始的时候没有这样的觉悟,毫无进展地度过了一个星期。
其次,我学会了用以致学。计算机科学是一门博大精深的学科,里面有相当多的知识,工具。但是,为了更好的提高我们的工作效率,我们不可能全面了解某些领域的知识。这个时候,就需要我们选择性的学习,以提高我们的效率。
第三,学会利用图书馆。没进入大学之前,我的知识主要从互联网得来。以前认为,凡事都可以在互联网上搜索得到,现在已经不需要图书馆了。然而,开始做课设时发现,应为TurboC是很久以前的东西,互联网上关于它的资料不多,于是我开始检索图书馆。在图书馆里,我发现了许多有用的书籍,比如当我对指针模棱两可的时候,阅读几本书,我就基本明白了指针的原理和应用。当我对链表不太熟悉的时候,几本书的实例又让我长了知识。我恍然大悟,图书馆真的是一个知识的宝库,我们应该好好利用它!
第四,让我学会直面困难。初学者设计程序,错误,Bug在所难免。在一次次让人沮丧的Compiling Error里头,我不断地鼓励自己,不断探索,思考,分析,修改,调试,直至一个个模块被我顺利调试通过,那难以言表的喜悦之情,重新点燃了我的斗志!
第五,我学会了如何更加有效率地Debug。无数次报错,让我我学会了巧妙设置断点,巧妙地注释掉代码来排除Bug,提高了我的开发效率。
最后,也是最重要的一点,在完成课设的过程中,培养了我专注,坚持不懈的品质。
好几个周末,我都沉醉的蓝色的海洋,从早上直到深夜,几乎一直专注地在思索,考虑,调试……
开发中遇到的问题和解决方法
开发中遇到的问题可以说是无以计数的吧,下面就印象最深的谈谈。
在开始的一个星期里头,只最没有头绪的时候。首先要解决的,也是最能看出问题的就是绘制图形界面。其中设计是比较耗费时间的,为了日后调用方便,我定义了许多绘图函数,同时做了大量的计算工作。
完成绘画函数后,接下来就在调用键盘疑惑了,后来查看了两三个课设的源代码,知道了可以用一个无条件循环来运行程序, 在按下按键后跳出,长了见识。
在后期的开发中,输赢的判断和电脑下棋是一大难点。因为这两种错误都不是显而易见的。为了应对这种情况,我在Debug的过程中学会了合理地设置断点,逐步或跳步运行,监视变量等技巧,大大的提高了开发效率。
最后,存读档是另一重点。课设让我了解到先前我对链表,文件的应用掌握的不是很充分。于是,我查找了许多书籍,阅读了许多案例,最终把链表,文件读取的应用模块编出来了。因为链表部分容易出隐藏错误,所以在老师的提示下,我将存读取档单独编译通过之后,在加入主函数。
随着Debug次数的增加,我也认识了解了各种各样的错误和处理方法。而遇到
然的问题但是总是报错的时候,我也可以渐渐冷静下来,仔细思考,逐步分析,排除错误。
对自己完成课设完成情况的评价
在刚看到课设题目的时候,完全没有头绪。当时对C开发程序还是,一窍不通,更不会将诸多函数灵活贯通了。但是随着自己编写的函数一点一点的积累,逐渐的学会利用帮助文档学习利用新的函数,学会利用参考书籍加深对不太明白的知识点的理解。眼看期末考检查临近,开发接近尾声,突然想到对游戏功能再加强巩固,可是时间不允许了。设计的程序离自己理想的目标还差很远,我也会利用寒假时间进一步完善和改进。
至此,我对电脑的运算速度再次惊叹,了解了编程的精萃是算法。如何利用更加高效的算法运行在速度有限的设备上,为人类解决更加多的问题,是程序员们永无止境的课题。
同时,我对人工智能算法产生了浓厚的兴趣。同时也查阅了许多资料,涉及到剪枝,Alpha-beta算法等尚未涉猎的知识。相对于象棋算法和五子棋算法,连子游戏可能情况还是较少的,这进一步激发了我对更大规模,更高效的棋牌算法的兴趣。
对于《高级语言程序设计Ⅲ》与《高级语言程序设计课程设计》两门课程的意见与建议
在这两门课程即将结束之际,我受益匪浅。我深深得知在计算机领域,学习的道路是永无止境的。计算机科学是一门注重实用的学科,掌握的所有理论,是为实际应用。应此,学习本门课程需要进行大量实践。而高级语言程序设计和课程设计,为学生提供了一个绝佳的小试牛刀的机会。在开发的过程中,为了达成目标,而更加牢固地掌握所需知识,达到了很好的促进学习作用。同时巧妙的课设题目安排,也大大激发了学生的兴趣,而老师的辛勤工作,上机辅导对我们的启发良多!
我觉得使用TurboC进行图形界面开发有些困难,而我曾见一些同学把主要精力放在了开发华丽界面上,而不是程序算法的优化完善,实在有些本末倒置了。而且TurboC图形模式的运行环境要求比较苛刻,不是在所有的Windows虚拟Dos环境下都可以完美兼容,为此我曾用了许多时间调试DOS的模拟环境。因此我建议,课设作业不妨布置一些用TurboC在文本模式下进行一些注重算法的程序开发,而类Windows UI程序的开发,不妨准许同学们使用图形界面下的IDE,这样也许会事半功倍!
最后,在这两门课程的学习过程中,培养了对计算机科学与技术这门专业强烈的兴趣,在气氛融洽的学习环境中,受益匪浅,感谢老师在这一学期里的耐心指导!
in order you wanna cheat,You got to form up this code together all by yourself.
BTW,I use project in TC3.0.
main.c:
#include "headfile.h" //=========================Data Settings========================== typedef struct{ char name[8]; int score; }PlayerInfo; //Player Infomation typedef struct info{ int board[2][8][9];//set two chess board. board[0] for level 1;board[1] for level 2; PlayerInfo P1;//You PlayerInfo P2;//PC char psw[16]; int player;//whose turn struct info * next; }Info; Info InfoNow; board[2][8][9];// Creat two board for different level. 0 for nothing; 1 for player; 2 for PC. void *buf; //for sprintf use int level=1; int i=1,j=1; //Position of Chess int imax,jmax;//Set Limit Position unsigned int keycode;//receive key reaction code in all_key(); //data for game /*=========================Declare Statis=======================*/ //--------------------------Draw COVER------------------------- void startGraphics(); void coverage(); void drawTittle(); void drawCoverPicture1(); void drawCoverPicture2(); int all_key(); //Draw GameUI void drawGameUI(); void drawStepXY(int i,int j,int level,int player); void drawChessBoard(int level); void drawPlayerInfo(char name[]); void drawBar(); void drawScoreP1(int score); void drawScoreP2(int score); void repaintBoard(); void clearStepXY(int i,int j,int level); void moveChess(); void PlayerTurn(int player);//1 is you 2is pc void dropChess(int i,int player);// player=1 is You ; player=2 is PC void drawArrow(int i);// draw select arrow void clearArrow(int i);//clr select arrow //---------------------------Gaming------------------------------ void newGame(); void nextGame(); void playingGame(int player); void SureToQuit(); void endDraw(char *buf); void setPlayerName(char p[8]); void setPassWord(char p[16]); void save(); void load(); void rank(); void cpyInfo(Info *p1,Info *p2); void help(); void setlevel(); int judge();// 0 is gaming; 1 is YOU win; 2 is PC win; 3 is Draw. void AITurn(int player); int ThinkNextStep(int player); //---------------------------Settings---------------------------- void setimaxjmax(); void beginSet(); void repaint(); //----------------------------------------------------------------- /*================================================================*/ /*==========================Main Function=========================*/ /*================================================================*/ void main(){ //Draw Beginning Picture,Press Any Key to Continue.Press Esc to exit. coverage(); setlevel(); newGame(); } /*---------------------------------------------------------------*/ /*==========================Functions=============================*/ void newGame(){ /*---------------Draw Game UI----------------*/ //set struct InfoNow.P1.score=0; InfoNow.P2.score=0; strcpy(InfoNow.P1.name,"YOU"); InfoNow.player=1;//Set Player Turns nextGame(); } void nextGame(){ //Clear Chess Board while(1){ //-------------Clear Board------------- for(int i=0;i<2;i++) for(int j=0;j<8;j++) for(int k=0;k<9;k++) InfoNow.board[i][j][k]=0 ; i=1; //--------Playing Part----------- playingGame(InfoNow.player); } } void playingGame(int player){ repaint(); while(1){ if(judge()==1){InfoNow.P1.score+=2;endDraw("Win");while(!bioskey(0)) break;break;} if(judge()==2){InfoNow.P2.score+=2;endDraw("Lose");while(!bioskey(0))break;break;} if(judge()==3){InfoNow.P1.score+=1;InfoNow.P2.score+=1;endDraw("Draw");while(!bioskey(0))break;break;} if(player==1) PlayerTurn(player);//Player=2 Change to AITurn() later! if(player==2) AITurn(player); player=(player)%2+1;//take turn to play } } void PlayerTurn(int player){ //set the Movement Limit //move while(1){ keycode=all_key(); if (keycode==RIGHT_ARROW && i>0 && i1 && i<=imax ){ clearArrow(i); i--; drawArrow(i); } if(keycode==ENTER){ if(InfoNow.board[level-1][0][i-1]==0){ dropChess(i,player); break; } } if(keycode==ESC){ SureToQuit(); } if(keycode==F1){newGame(); } if(keycode==F2){nextGame(); } if(keycode==F3){load(); } if(keycode==F4){save(); } if(keycode==F5){rank(); } if(keycode==F6){setlevel(); } if(keycode==F7){ help();//returnGame(player); } } } void AITurn(int player){ int t=ThinkNextStep(player); while(t<1&&t>imax){//Adjust position; if(t>imax) t--; if(t<1) t++; } dropChess(t,player); } int ThinkNextStep(int player){//return iTemp to step to win; if no way to win,return -1. int boardTemp[2][8][9]; for(int a=0;a<2;a++)//save boar for(int b=0;b<8;b++) for(int c=0;c<9;c++) boardTemp[a][b][c]=InfoNow.board[a][b][c]; int p2=player%2+1; //Try to drop use judge() to judge /*-------------Find my(AI) way to Win--------------*/ //Calculate how many times to drop & drop Dataly for( int iTemp=1;iTemp<=imax;iTemp++){ if(InfoNow.board[level-1][0][iTemp-1]==0){ j=jmax; while (InfoNow.board[level-1][j-1][iTemp-1]!=0 ) j--; InfoNow.board[level-1][j-1][iTemp-1]=player; //Judge if(judge()==player){ for(int a=0;a<2;a++)//restore board for(int b=0;b<8;b++) for(int c=0;c<9;c++) InfoNow.board[a][b][c]=boardTemp[a][b][c]; return iTemp; } else{ for( a=0;a<2;a++)//restore board for( b=0;b<8;b++) for( c=0;c<9;c++) InfoNow.board[a][b][c]=boardTemp[a][b][c]; } } } /*-------------------------------------------------*/ /*------------Prevent oppponent to Win--------------*/ /*------Situation 1 (...oo.....)----*/ for(int jA=1;jA<=jmax;jA++){ for (int iA=2;iA<=imax-1;iA++){ if(InfoNow.board[level-1][0][iA-1]==0){ if (jA==1 && InfoNow.board[level-1][jmax-jA][iA-1-1]==0 && InfoNow.board[level-1][jmax-jA][iA-1+0]==p2&& InfoNow.board[level-1][jmax-jA][iA-1+1]==p2&& InfoNow.board[level-1][jmax-jA][iA-1+2]==0) return (iA+2); if (jA>1 && InfoNow.board[level-1][jmax-jA][iA-1-1]==0 && InfoNow.board[level-1][jmax-jA][iA-1+0]==p2&& InfoNow.board[level-1][jmax-jA][iA-1+1]==p2&& InfoNow.board[level-1][jmax-jA][iA-1+2]==0 && InfoNow.board[level-1][jmax-jA+1][iA-1-1]!=0 && InfoNow.board[level-1][jmax-jA+1][iA-1+2]!=0 ) return (iA-1); } } } /*------Situation 2 (...ooo....)---*/ for( iTemp=1;iTemp<=imax;iTemp++){ if(InfoNow.board[level-1][0][iTemp-1]==0){ j=jmax; while (InfoNow.board[level-1][j-1][iTemp-1]!=0 ) j--; InfoNow.board[level-1][j-1][iTemp-1]=p2; //Judge if(judge()==p2){ for(int a=0;a<2;a++)//restore board for(int b=0;b<8;b++) for(int c=0;c<9;c++) InfoNow.board[a][b][c]=boardTemp[a][b][c]; return iTemp; } else{ for(int a=0;a<2;a++)//restore board for(int b=0;b<8;b++) for(int c=0;c<9;c++) InfoNow.board[a][b][c]=boardTemp[a][b][c]; } } } /*---------Situation 3- ..o.o..-----*/ for(jA=1;jA<=jmax;jA++){ for (int iA=2;iA<=imax-3;iA++){ if(InfoNow.board[level-1][0][iA-1]==0){ if (jA==1&&// InfoNow.board[level-1][jmax-jA-1][iA-1-1]==0 && InfoNow.board[level-1][jmax-jA][iA-1+0]==1&& InfoNow.board[level-1][jmax-jA][iA-1+1]==0 && InfoNow.board[level-1][jmax-jA][iA-1+2]==1 // InfoNow.board[level-1][jA-1][iA-1+3]==0 ) return (iA+1); if( jA!=1&& InfoNow.board[level-1][jmax-jA][iA-1+0]!=1 && InfoNow.board[level-1][jmax-jA][iA-1+1]==0 && InfoNow.board[level-1][jmax-jA-1][iA-1+1]==0&& InfoNow.board[level-1][jmax-jA+1][iA-1+1]!=0&& InfoNow.board[level-1][jmax-jA][iA-1+2]!=1 ) return(iA+1); } } } /*-----------------------------------------------*/ /*----Find the way YOU won't win in next draw----*/ //Random int iRandom; while(1){ iRandom=random(imax)+1; if(InfoNow.board[level-1][0][iRandom-1]==0) return iRandom; } } void save(){ closegraph(); printf("/nNow Saving your Game "); for(int t=0;t<10;t++){ printf("."); delay(100); } printf("/n"); //----text---- FILE *fp; Info *head,*p1,*p2; fp=fopen("d://tc30//BINGO//Savings.txt","r"); if(fp==NULL){//No saving ,create setPlayerName(InfoNow.P1.name); setPassWord(InfoNow.psw); fclose(fp); fp=fopen("d://tc30//BINGO//Savings.txt","w"); InfoNow.next=NULL; fwrite(&InfoNow,sizeof(Info),1,fp); } else{//Have saving, Read & Add Now & Write //Read fclose(fp); fp=fopen("d://tc30//BINGO//Savings.txt","r"); head=(Info *)malloc(sizeof(Info)); p1=head; p2=head; fread(head,sizeof(Info),1,fp); while(p1->next!=NULL){ p2=(Info *)malloc(sizeof(Info)); fread(p2,sizeof(Info),1,fp); p1->next=p2; p1=p2; } p2->next=NULL; //Write if(strcmp(InfoNow.P1.name,p2->P1.name)==0){//Same Name REFRESH cpyInfo(p2,&InfoNow); p2->next=NULL; //Write fclose(fp); fp=fopen("d://tc30//BINGO//Savings.txt","w"); p1=head; while(p1!=NULL){ fwrite(p1,sizeof(Info),1,fp); p1=p1->next; } printf("/n Saving Updated to new!"); } else{//Not the Same Name Refresh if(!strcmp(InfoNow.P1.name,"YOU")){ setPlayerName(InfoNow.P1.name); setPassWord(InfoNow.psw); } //Add InfoNow to the END p2->next=&InfoNow; InfoNow.next=NULL; //Write p1=head; fclose(fp); fp=fopen("d://tc30//BINGO//Savings.txt","w"); while(p1!=NULL){ fwrite(p1,sizeof(Info),1,fp); p1=p1->next; } printf("/n Saving Succeed!"); } while(!bioskey(0)) break; } fclose(fp); startGraphics(); repaint(); } void load(){ closegraph(); printf("/nEnter your name.If you have no savings,continue current game!/nName:"); char tempname[8]; char temppsw[16]; scanf("%s",tempname); printf("/nNow Loading"); for(int t=0;t<10;t++){ printf("."); delay(100); } //----text---- FILE *fp; Info *head,*p1,*p2; fp=fopen("d://tc30//BINGO//Savings.txt","r"); if (fp==NULL){ printf("/n No Saved files to load/n"); fclose(fp); } else{ rewind(fp); head=(Info*)malloc(sizeof(Info)); p1=head; p2=head; fread(head,sizeof(Info),1,fp); while(p1->next!=NULL){ p2=(Info*)malloc(sizeof(Info)); fread(p2,sizeof(Info),1,fp); p1->next=p2; p1=p2; } p2->next=NULL; //Check If there's a save Named XX p2=head; while(strcmp(tempname,p2->P1.name)){ if(p2==NULL)break; p2=p2->next; } //output if(!strcmp(tempname,p2->P1.name)){//Name Right! printf(" %s's saving exist!/n",tempname); printf("/nPassword : "); scanf("%s",temppsw); if(!strcmp(temppsw,p2->psw)){//PassWord RIGHT! printf("/nHallo! %s !",tempname); cpyInfo(&InfoNow,p2); InfoNow.next=NULL; fclose(fp); } else{//name right psw wrong printf("/nPassword Wrong!/n"); int count=0; while(1){ if(count>1) {printf("/nPassword Wrong!");break;} printf("/nTry Again:"); scanf("%s",temppsw); delay(1000); if(!strcmp(temppsw,p2->psw)){//PassWord RIGHT! printf("/nHallo! %s !",tempname); cpyInfo(&InfoNow,p2); InfoNow.next=NULL; break; } else count ++;//PassWord Wrong } fclose(fp); } } /*else{//Name Wrong , cpy Lastgame to InfoNow while(p2!=NULL){ p2=p2->next; } cpyInfo(&InfoNow,p2); printf("/n%s's Saving not found. Load Last Game!",tempname); } fclose(fp); */ } //End Loading while(!bioskey(0)) break; startGraphics(); repaint(); } void rank (){ //Read From LinkList and Rank FILE *fp; Info *head,*p1,*p2,*p,*_temp,*_node; Info InfoTemp; int scoreTemp[11]; char nameTemp[11][8]; p=(Info *)malloc(sizeof(Info)); fp=fopen("d://tc30//BINGO//Savings.txt","r"); if(fp==NULL){ fclose(fp); } else{ //Load LinkList rewind(fp); head=(Info*)malloc(sizeof(Info)); p1=head; p2=head; fread(head,sizeof(Info),1,fp); while(p1->next!=NULL){ p2=(Info*)malloc(sizeof(Info)); fread(p2,sizeof(Info),1,fp); p1->next=p2; p1=p2; } fclose(fp); p2->next=NULL; p1=head; _node=p1; _temp=p1; p=head; //Buble sort for(;_temp->next;_temp=_temp->next) for(_node=p;_node->next;_node=_node->next){ if(_node->P1.score < _node->next->P1.score){ cpyInfo(&InfoTemp,_node); cpyInfo(_node,_node->next); cpyInfo(_node->next,&InfoTemp); } } } //out put i 0~9 Top 1~10 clearviewport(); settextstyle(GOTHIC_FONT,0,8); outtextxy(215,0,"Rank"); settextstyle(SANS_SERIF_FONT,0,4); outtextxy(40,80,"No. Name Score"); outtextxy(40,105,"-------------------------"); settextstyle(3,0,4); char buf[100]; p1=head; for(int m=0;m<10;m++){ if(p1!=NULL){ //if(p1->score>0) little color egg for me! sprintf(buf,"%2d %7s",(m+1),p1->P1.name); outtextxy(40,125+m*33,buf); sprintf(buf,"%-d",p1->P1.score); outtextxy(500,125+m*33,buf); p1=p1->next; } } //Press Anykey To Return while(1){ if ((keycode=all_key())!=ESC) {repaint();break;} if (keycode==ESC) SureToQuit(); } } void help(){ clearviewport(); settextstyle(GOTHIC_FONT,0,1); outtextxy(220,5,"Help"); settextstyle(6,0,3); outtextxy(40,100," This is a Game Create by LEWIS in 09070328.When one "); outtextxy(10,150,"side chess stick in a line ,it wins!"); outtextxy(40,200," Press Left or Right to control your position . "); outtextxy(40,250," Press ENTER to drop ."); outtextxy(40,300," Press Esc anytime if you want to quit .This game "); outtextxy(10,350,"will record your score and name."); outtextxy(40,400," Press anykey to continue your game "); while(1){ if ((keycode=all_key())!=ESC){repaint();break;} if (keycode==ESC) SureToQuit(); } } void SureToQuit(){ closegraph(); cprintf(" Quit Game ? Yes(Enter) / No(Esc) "); while(1){ if((keycode=all_key())==ESC){ break; } if(keycode==ENTER){ printf("/n ----YES----/n"); printf("/n Save Current Game ? Yes(Enter) / No(Esc) "); while(1){ if((keycode=all_key())==ESC){ exit(0); } if(keycode==ENTER){ printf("/n ----YES----"); save(); exit(0); } } } } startGraphics(); repaint(); } int judge(){ //0:continue; 1:P1 win; 2:P2 win; 3:draw. /*-------set who?-------*/ int who,code=1; int im,jm,k; /*------------"-"check------------*/ for (jm=1;jm<=jmax;jm++) for (im=1;im<=imax-3;im++) if((who=InfoNow.board[level-1][jm-1][im-1])!=0){ for(k=1;k<=3;k++) if(InfoNow.board[level-1][jm-1][im-1+k]==who) code++; if (code==4) return(who); else code=1; } /*-----------"|"checf-------------*/ for (im=1;im<=imax;im++) for (jm=1;jm<=jmax-3;jm++) if((who=InfoNow.board[level-1][jm-1][im-1])!=0){ for(k=1;k<=3;k++) if(InfoNow.board[level-1][jm-1+k][im-1]==who) code++; if (code==4) return(who); else code=1; } /*------------"/"check------------*/ for (im=1;im<=imax-3;im++) for(jm=1;jm<=jmax-3;jm++) if((who=InfoNow.board[level-1][jm-1][im-1])!=0){ for(k=1;k<=3;k++) if(InfoNow.board[level-1][jm-1+k][im-1+k]==who) code++; if (code==4) return(who); else code=1; } /*------------"/"check------------*/ for( im=4;im<=imax;im++) for (jm=1;jm<=jmax-3;jm++) if((who=InfoNow.board[level-1][jm-1][im-1])!=0){ for(k=1;k<=3;k++) if(InfoNow.board[level-1][jm-1+k][im-1-k]==who) code++; if (code==4) return(who); else code=1; } /*------------Draw Check----------*/ for(int jj=0;jjboard[i][j][k]=p2->board[i][j][k]; strcpy(p1->P1.name,p2->P1.name); strcpy(p1->P2.name,p2->P2.name); strcpy(p1->psw,p2->psw); p1->P1.score=p2->P1.score; p1->P2.score=p2->P2.score; p1->player=p2->player; } void repaint(){ clearviewport(); drawGameUI(); drawChessBoard(level); drawPlayerInfo(InfoNow.P1.name); drawScoreP1(InfoNow.P1.score); drawScoreP2(InfoNow.P2.score); if(level==1){ drawStepXY(8,1,level,1); drawStepXY(8,4,level,2); } if(level==2){ drawStepXY(11,1,level,1); drawStepXY(11,5,level,2); } drawArrow(i); } void drawGameUI(){ settextstyle(6,0,1); outtextxy(8,2,"New(F1) Next(F2) Load(F3) Save(F4) rank(F5) Level(F6) help(F7) Quit(ESC)"); drawBar(); } void drawBar(void){ for(int i=0;i<8;i++) rectangle(2+80*i,4,2+80*(i+1)-10,28); } void drawChessBoard(int level){ if (level==1){ for(int i=0;i<=6;i++) //-- line (0,47+i*72,504,47+i*72); for(int j=0;j<=7;j++) //|| line (j*72,48,j*72,480); for( i=0;i<7;i++){ for(int j=0;j<7;j++){ circle(72*i+36,48+72*j+36,36); } } } if (level==2){ for(int i=0;i<=8;i++)//-- line(0,31+i*56,504,31+i*56); for(int j=0;j<=9;j++)//|| line(j*56,32,j*56,480); for( i=0;i<9;i++){ for(int j=0;j<8;j++){ circle(56*i+28,31+56*j+28,28); } } } //draw chess for(int i=1;i<=imax;i++) for(int j=1;j<=jmax;j++){ if (InfoNow.board[level-1][j-1][i-1]==1) drawStepXY(i,j,level,1); if (InfoNow.board[level-1][j-1][i-1]==2) drawStepXY(i,j,level,2); } } void drawPlayerInfo(char name[]){ setlinestyle(SOLID_LINE,1,1); //line(504,0,504,480); //| line(504,240,640,240);//--- settextstyle(SANS_SERIF_FONT,0,4); outtextxy(520,160,name); outtextxy(520,400,"PC"); settextstyle(SMALL_FONT,0,1); outtextxy(563,470 ,"Made By Lewis From 09070328"); // draw01(572,60,level); // draw02(572,300,level); } void drawArrow(int i){ int x, y,r; setfillstyle(SOLID_FILL,GREEN); if (level==1) y=48,r=36; if (level==2) y=32,r=28; floodfill(2*r*i-r*3/2,y,getmaxcolor()); floodfill(2*r*i-r/2,y,getmaxcolor()); } void clearArrow(int i){ int x,y,r; setfillstyle(SOLID_FILL,BLACK); if (level==1) y=48,r=36; if (level==2) y=32,r=28; floodfill(2*r*i-r*3/2,y,getmaxcolor()); floodfill(2*r*i-r/2,y,getmaxcolor()); } void drawStepXY(int i,int j,int level,int player){ if (player==1) setfillstyle(LTBKSLASH_FILL,LIGHTGREEN); if (player==2) setfillstyle(BKSLASH_FILL,LIGHTRED); if (level==1){ i=72*i-36; j=48+72*j-36; circle(i,j,36); floodfill(i,j,getmaxcolor()); } if (level==2){ i=56*i-28; j=31+56*j-28; circle(i,j,28); floodfill(i,j,getmaxcolor()); } } void clearStepXY(int i,int j,int level){ setfillstyle(SOLID_FILL,BLACK); if (level==1){ i=72*i-36; j=48+72*j-36; circle(i,j,36); floodfill(i,j,WHITE); } if (level==2){ i=56*i-28; j=31+56*j-28; circle(i,j,28); floodfill(i,j,getmaxcolor()); } } void dropChess(int i,int player){ //Calculate how many times to drop j=jmax; while (InfoNow.board[level-1][j-1][i-1]!=0 ) j--; InfoNow.board[level-1][j-1][i-1]=player; //draw Step if (j==1 ) drawStepXY(i,j,level,player); else{ for(int m=1;m
keboard.c:
#include "headfile.h" int all_key(void); int all_key(){ int keycode; keycode=bioskey(0); if(bioskey(2)&0x04){ return keycode; } return keycode & 0xff? keycode & 0xff :keycode; }
headfile.h:
#include "stdio.h" #include "dos.h" #include "graphics.h" #include "stdlib.h" #include "conio.h" #include "bios.h" #include "alloc.h" #include "string.h" #include "ctype.h" #include "time.h" #define NULL 0 #define ESC 27 #define ENTER 0x0d #define F1 0x3b00 #define F2 0x3c00 #define F3 0x3d00 #define F4 0x3e00 #define F5 0x3f00 #define F6 0x4000 #define F7 0x4100 #define LEFT_ARROW 0x4b00 #define RIGHT_ARROW 0x4d00 #define UP_ARROW 0x4800 #define DOWN_ARROW 0x5000
cover.c:
#include "headfile.h"" void startGraphics(); void drawTittle(); void drawCoverPicture1(); void drawCoverPicture2(); void coverage(); int all_key(); void coverage(){ while(!bioskey(1)){ setviewport(1,1,639,479,1); startGraphics (); drawTittle(); drawCoverPicture1(); drawCoverPicture2(); if((all_key())!=ESC) break; else exit(0); } clearviewport(); } void startGraphics(){//Begin Graphics Mode /* request auto detection */ int gdriver = DETECT, gmode, errorcode; /* initialize graphics mode */ initgraph(&gdriver, &gmode, "d://tc30 //bgi"); } void drawCoverPicture1(){ //Define the size of the two beginning pictur int x=410,y=200,r=100; //Draw rectangle(x-r,y-r,x+r,y+r); circle(x,y,r); setfillstyle(SLASH_FILL,LIGHTRED); floodfill(x-r+1,y,WHITE); } void drawCoverPicture2(){ //Define the size of the two beginning pictur int x=410,y=200,r=100;x+=r,y+=r; //Draw setfillstyle(XHATCH_FILL,LIGHTGREEN); rectangle(x-r,y-r,x+r,y+r); circle(x,y,r); floodfill(x-r/2,y-r/2,getmaxcolor()); setfillstyle(LTBKSLASH_FILL,LIGHTBLUE); floodfill(x-1,y-1,getmaxcolor()); floodfill(x+1,y+1,getmaxcolor()); } void drawTittle(){ clearviewport(); settextstyle(GOTHIC_FONT,0,10); outtext("Bingo!"); settextstyle(SANS_SERIF_FONT,0,4); outtextxy(130,430,"Press anykey to continue!"); }