连连看C语言源代码.docx
- 文档编号:4616343
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:15
- 大小:18.81KB
连连看C语言源代码.docx
《连连看C语言源代码.docx》由会员分享,可在线阅读,更多相关《连连看C语言源代码.docx(15页珍藏版)》请在冰豆网上搜索。
连连看C语言源代码
/*
*连连看游戏C语言源代码
*/
#include
#include
#include
#include
#include
#definetrue1
#definefalse0
/*---------------------全局变量------------------------------------*/
intBkGndColor=BLACK;
intBorderColor=LIGHTGRAY;
intLineColor=LIGHTBLUE;/*消除一对方块时时候的连线颜色*/
/*Pb-ProgressBar*/
intPbColor=LIGHTGREEN;
intPbY=4;
intPbHeight=4;
intPbValue;/*进度条百分比,初始值为100.*/
longStartTime;/*开始时间的秒数,只统计分钟,秒*/
longTotalTime;/*游戏总共的最大秒数!
,*/
/*BoardDatas:
asmall-sizeboard*/
/*Board[x][y][0]-0:
empty,1:
filled*/
/*Board[x][y][1]-cell'skey;*/
unsignedcharBoard[10][10][2];
intCellSize=30;
intBoardX=20;
intBoardY=60;
intBoardWidth=10;
intBoardHeight=10;
intCellColor=WHITE;
intSelColor=BLUE;/*selCell'sborderrectcolor*/
intCurColor=RED;/*curCell'sborderrectcolor*/
intEraColor=CYAN;/*用于擦除cell的颜色!
*/
intPairsCount;/*howmuchpairswehaveputonboard*/
/*用于存储逻辑坐标(索引)*/
typedefstruct_tagCELL
{
charx;
chary;
}CELL;
CELLselCell,curCell;/*缓存前一个被选中的位置以及当前所处位置!
*/
/*ScanCodesDefine*/
enumKEYCODES
{
K_ESC=0x011b,
K_UP=0x4800,/*upwardarrow*/
K_LEFT=0x4b00,
K_DOWN=0x5000,
K_RIGHT=0x4d00,
K_SPACE=0x3920,
K_P=0x1970,
K_RETURN=0x1c0d,/*Enter*/
};
/*---------------------函数列表------------------------------------*/
voidInitGame(char*bgiPath);
voidPlayGame();
voidQuitGame();
voidInitProgressBar();
voidUpdateProgressBar(intpercent);
voidDrawCell(intkey,intx,inty,intcolor);
voidEraseCell(intx,inty);
voidDrawBorderRect(CELL*c,intcolor);
voidDrawGameOver(char*info);
intGetKeyCode();
intFindPath(CELL*c1,CELL*c2);
/*绘制消除方块时候的连接路径!
,用指定颜色!
*/
voidDrawPath(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4,intcolor);
/*----------------------函数实现-----------------------------------*/
/*----------------------[核心算法]---------------------------------
*先进行水平方向判断,找出两点所在的水平直线活动范围,
*算出这两条线段在垂直方向的共同区域,
*遍历该区域判断能否在两线段间架起公垂线,能则两点连接上;
*接着进行垂直方向判断,类同。
无论两点在不在一条直线上,
*都能使用该算法,因为两点同线只是两点作为矩形对角点的特例而已。
*/
/*找到两个CELL之间的路径,成功返回true*/
intFindPath(CELL*c1,CELL*c2)
{
inti,j,path,min1,max1,min2,max2,left,right,top,bottom;
/*---------------(0)判断是否点中相同块!
------------*/
if(Board[c1->x][c1->y][1]!
=Board[c2->x][c2->y][1])
returnfalse;
/*---------------
(1)查找水平方向公共区域!
-----------*/
min1=max1=c1->x;
min2=max2=c2->x;
while(min1-1>=0&&Board[min1-1][c1->y][0]==0)min1--;
while(min2-1>=0&&Board[min2-1][c2->y][0]==0)min2--;
left=max(min1,min2);/*左边界*/
while(max1+1
while(max2+1
right=min(max1,max2);/*右边界*/
/*检查两条水平线之间是否有公垂线连通!
*/
/*可以在边缘连通*/
if(left==0)
{
/*左边缘连通*/
DrawPath(c1->x,c1->y,-1,c1->y,-1,c2->y,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,-1,c1->y,-1,c2->y,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
if(right==(BoardWidth-1))
{
DrawPath(c1->x,c1->y,BoardWidth,c1->y,BoardWidth,c2->y,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,BoardWidth,c1->y,BoardWidth,c2->y,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
for(i=left;i<=right;i++)
{
path=0;/*统计垂直的公垂线长度!
*/
for(j=min(c1->y,c2->y)+1;j
{
path+=Board[i][j][0];
if(path>0)break;
}
if(path==0)
{
DrawPath(c1->x,c1->y,i,c1->y,i,c2->y,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,i,c1->y,i,c2->y,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
}
/*---------------
(2)查找垂直方向公共区域!
-----------*/
min1=max1=c1->y;
min2=max2=c2->y;
while(min1-1>=0&&Board[c1->x][min1-1][0]==0)min1--;
while(min2-1>=0&&Board[c2->x][min2-1][0]==0)min2--;
top=max(min1,min2);
while(max1+1
while(max2+1
bottom=min(max1,max2);
/*检查两条垂直线之间是否有公垂线连通!
*/
/*可以在边缘连通*/
if(top==0)
{
/*同在顶端消除*/
DrawPath(c1->x,c1->y,c1->x,-1,c2->x,-1,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,c1->x,-1,c2->x,-1,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
if(bottom==(BoardHeight-1))
{
DrawPath(c1->x,c1->y,c1->x,BoardHeight,c2->x,BoardHeight,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,c1->x,BoardHeight,c2->x,BoardHeight,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
for(j=top;j<=bottom;j++)
{
path=0;/*统计水平的公垂线长度!
*/
for(i=min(c1->x,c2->x)+1;i
{
path+=Board[i][j][0];
if(path>0)break;
}
if(path==0)
{
/*水平公垂线*/
DrawPath(c1->x,c1->y,c1->x,j,c2->x,j,c2->x,c2->y,LineColor);
delay(6000);
DrawPath(c1->x,c1->y,c1->x,j,c2->x,j,c2->x,c2->y,BkGndColor);/*插除线条!
*/
returntrue;
}
}
/*到达这里说明没有任何通路*/
returnfalse;
}
/*GetKeyCode*/
intGetKeyCode()
{
intkey=0;
if(bioskey
(1))
{
key=bioskey(0);
}
returnkey;
}
/*绘制消除方块时候的连接路径!
,用指定颜色!
,坐标是CELL逻辑坐标!
*/
voidDrawPath(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4,intcolor)
{
setcolor(color);
moveto(BoardX+CellSize/2+CellSize*x1,BoardY+CellSize/2+CellSize*y1);
lineto(BoardX+CellSize/2+CellSize*x2,BoardY+CellSize/2+CellSize*y2);
lineto(BoardX+CellSize/2+CellSize*x3,BoardY+CellSize/2+CellSize*y3);
lineto(BoardX+CellSize/2+CellSize*x4,BoardY+CellSize/2+CellSize*y4);
}
/*congratulationsinfo,theuserhassuccessfinishthegame!
*/
voidDrawGameOver(char*info)
{
/*计算棋盘的中心点*/
intcx=BoardX+CellSize*BoardWidth/2;
intcy=BoardY+CellSize*BoardHeight/2;
structtextsettingstypetextInfos;
/*获取此前的文字信息*/
gettextsettings(&textInfos);
setcolor(DARKGRAY);
setfillstyle(SOLID_FILL,BLUE);
/*文字居中*/
rectangle(cx-102,cy-22,cx+102,cy+22);
floodfill(cx,cy,DARKGRAY);
rectangle(cx-100,cy-20,cx+100,cy+20);
settextjustify(CENTER_TEXT,CENTER_TEXT);
setcolor(LIGHTBLUE);
outtextxy(cx,cy,info);
/*restoreorignaltextsettings*/
settextjustify(textInfos.horiz,textInfos.vert);
}
/*drawafocusrectonthecellwiththecolor*/
/*用制定颜色绘制一个选中的外边框*/
voidDrawBorderRect(CELL*c,intcolor)
{
setcolor(color);
rectangle(BoardX+(c->x)*CellSize+1,BoardY+(c->y)*CellSize+1,BoardX+(c->x+1)*CellSize-2,BoardY+(c->y+1)*CellSize-2);
rectangle(BoardX+(c->x)*CellSize,BoardY+(c->y)*CellSize,BoardX+(c->x+1)*CellSize-1,BoardY+(c->y+1)*CellSize-1);
}
/*在x,y处用指定颜色绘制键为key的CELL,key在2,3,4,5,6,7,8,9,10,11之间随机*/
voidDrawCell(intkey,intx,inty,intcolor)
{
setcolor(color);
rectangle(BoardX+x*CellSize+2,BoardY+y*CellSize+2,BoardX+(x+1)*CellSize-3,BoardY+(y+1)*CellSize-3);
setfillstyle(key,color);
floodfill(BoardX+x*CellSize+3,BoardY+y*CellSize+3,color);
}
/*擦除CELL*/
voidEraseCell(intx,inty)
{
setcolor(EraColor);
rectangle(BoardX+x*CellSize+2,BoardY+y*CellSize+2,BoardX+(x+1)*CellSize-3,BoardY+(y+1)*CellSize-3);
setfillstyle(SOLID_FILL,BkGndColor);
floodfill(BoardX+x*CellSize+3,BoardY+y*CellSize+3,EraColor);
setcolor(BkGndColor);
rectangle(BoardX+x*CellSize+2,BoardY+y*CellSize+2,BoardX+(x+1)*CellSize-3,BoardY+(y+1)*CellSize-3);
}
/*初始化进度条*/
voidInitProgressBar()
{
intwidth=CellSize*BoardWidth;
/*progressbarborderrect*/
setcolor(BorderColor);
rectangle(BoardX-2,PbY-2,BoardX+width+2,PbY+PbHeight+2);
/*drawavalue=100%progressbar*/
setcolor(PbColor);
rectangle(BoardX,PbY,BoardX+width,PbY+PbHeight);
setfillstyle(SOLID_FILL,PbColor);
floodfill(BoardX+1,PbY+1,PbColor);
}
/*更新进度条,设置为某个百分比*/
voidUpdateProgressBar(intpercent)
{
intp=percent;
intwidth;
if(percent<0)p=0;
elseif(percent>100)p=100;
width=BoardWidth*percent/100*CellSize;
setfillstyle(SOLID_FILL,BkGndColor);
floodfill(BoardX+1,PbY+1,BorderColor);
if(width<2)return;/*toosmallvalue?
*/
setcolor(PbColor);
rectangle(BoardX,PbY,BoardX+width,PbY+PbHeight);
setfillstyle(SOLID_FILL,PbColor);
floodfill(BoardX+1,PbY+1,PbColor);
}
/*初始化程序*/
voidInitGame(char*bgiPath)
{
intgdriver=DETECT,gmode,i,x,y,key;
structtimesysTime;
/*清空棋盘数据!
*/
memset(Board,0,sizeof(Board[0][0][0]*BoardWidth*BoardHeight*2));
/*setnewseed!
*/
gettime(&sysTime);
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);
/*entergraphicsmode*/
initgraph(&gdriver,&gmode,bgiPath);
PairsCount=BoardWidth*BoardHeight/4;
for(i=0;i { key=random(10)+2; /*fillfirstcellofpair*/ do { x=random(BoardWidth); y=random(BoardHeight); } while(Board[x][y][0]! =0); DrawCell(key,x,y,CellColor); Board[x][y][0]=1; Board[x][y][1]=key; /*fillsecondcellofpair*/ do { x=random(BoardWidth); y=random(BoardHeight); } while(Board[x][y][0]! =0); DrawCell(key,x,y,CellColor); Board[x][y][0]=1; Board[x][y][1]=key; } setcolor(YELLOW); outtextxy(BoardX,BoardY+BoardHeight*CellSize+30,"PressESCtoExit! "); outtextxy(BoardX,BoardY+BoardHeight*CellSize+42,"ArrowKeystomove,EntertoConfirm."); outtextxy(BoardX,BoardY+BoardHeight*CellSize+54,"--byHoodlum1980"); PbValue=100; TotalTime=3*60;/*Totalminutes.*/ gettime(&sysTime); StartTime=sysTime.ti_min*60+sysTime.ti_sec; } /*游戏进行*/ voidPlayGame() { intkey,percent; longcurTime; structtimesysTime; curCell.x=curCell.y=0;/*当前所处位置! */ selCell.x=selCell.y=-1;/*为-1表示当前未选中*/ DrawBorderRect(&curCell,CurColor); /*用一个循环检测按键! */ while(key! =K_ESC) { /*waituntilakeypressed*/ while(! (key=GetKeyCode())) { gettime(&sysTime); curTime=sysTime.ti_min*60+sysTime.ti_sec; percent=(int)((1-(curTime-StartTime)*1.0/TotalTime)*100); if(percent<=1) { DrawGameOver("YOUHAVELOSE! "); return; } elseif(percent! =PbValue) { UpdateProgressBar(percent); PbValue=percent;/*updatecachePbValue*/ } delay(1000); } /*这时用户按下了某个键*/ /*需要恢复的是此前选中的cell! */ if(curCell.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 连连 语言 源代码