连连看C语言源代码Word文档格式.docx
- 文档编号:17551256
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:15
- 大小:18.81KB
连连看C语言源代码Word文档格式.docx
《连连看C语言源代码Word文档格式.docx》由会员分享,可在线阅读,更多相关《连连看C语言源代码Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
*/
unsignedcharBoard[10][10][2];
intCellSize=30;
intBoardX=20;
intBoardY=60;
intBoardWidth=10;
intBoardHeight=10;
intCellColor=WHITE;
intSelColor=BLUE;
/*selCell'
sborderrectcolor*/
intCurColor=RED;
/*curCell'
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->
while(min1-1>
=0&
&
Board[min1-1][c1->
y][0]==0)min1--;
while(min2-1>
Board[min2-1][c2->
y][0]==0)min2--;
left=max(min1,min2);
/*左边界*/
while(max1+1<
BoardWidth&
Board[max1+1][c1->
y][0]==0)max1++;
while(max2+1<
Board[max2+1][c2->
y][0]==0)max2++;
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);
y,BkGndColor);
/*插除线条!
returntrue;
}
if(right==(BoardWidth-1))
y,BoardWidth,c1->
y,BoardWidth,c2->
for(i=left;
i<
=right;
i++)
path=0;
/*统计垂直的公垂线长度!
for(j=min(c1->
y,c2->
y)+1;
j<
max(c1->
y);
j++)
path+=Board[i][j][0];
if(path>
0)break;
if(path==0)
y,i,c1->
y,i,c2->
/*---------------
(2)查找垂直方向公共区域!
y;
Board[c1->
x][min1-1][0]==0)min1--;
Board[c2->
x][min2-1][0]==0)min2--;
top=max(min1,min2);
BoardHeight&
x][max1+1][0]==0)max1++;
x][max2+1][0]==0)max2++;
bottom=min(max1,max2);
/*检查两条垂直线之间是否有公垂线连通!
if(top==0)
/*同在顶端消除*/
y,c1->
x,-1,c2->
if(bottom==(BoardHeight-1))
x,BoardHeight,c2->
for(j=top;
=bottom;
/*统计水平的公垂线长度!
for(i=min(c1->
x)+1;
i<
x);
i++)
/*水平公垂线*/
x,j,c2->
/*到达这里说明没有任何通路*/
}
/*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)
rectangle(BoardX+(c->
x)*CellSize+1,BoardY+(c->
y)*CellSize+1,BoardX+(c->
x+1)*CellSize-2,BoardY+(c->
y+1)*CellSize-2);
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)
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);
setfillstyle(SOLID_FILL,BkGndColor);
floodfill(BoardX+x*CellSize+3,BoardY+y*CellSize+3,EraColor);
setcolor(BkGndColor);
/*初始化进度条*/
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?
/*初始化程序*/
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;
PairsCount;
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*/
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.*/
StartTime=sysTime.ti_min*60+sysTime.ti_sec;
/*游戏进行*/
voidPlayGame()
intkey,percent;
longcurTime;
curCell.x=curCell.y=0;
/*当前所处位置!
selCell.x=selCell.y=-1;
/*为-1表示当前未选中*/
DrawBorderRect(&
curCell,CurColor);
/*用一个循环检测按键!
while(key!
=K_ESC)
/*waituntilakeypressed*/
while(!
(key=GetKeyCode()))
curTime=sysTime.ti_min*60+sysTime.ti_sec;
percent=(int)((1-(curTime-StartTime)*1.0/TotalTime)*100);
=1)
DrawGameOver("
YOUHAVELOSE!
return;
elseif(percent!
=PbValue)
UpdateProgressBar(percent);
PbValue=percent;
/*updatecachePbValue*/
delay(1000);
/*这时用户按下了某个键*/
/*需要恢复的是此前选中的cell!
if(curCell.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 连连 语言 源代码