连连看C语言源代码.docx

上传人:b****6 文档编号:4616343 上传时间:2022-12-07 格式:DOCX 页数:15 大小:18.81KB
下载 相关 举报
连连看C语言源代码.docx_第1页
第1页 / 共15页
连连看C语言源代码.docx_第2页
第2页 / 共15页
连连看C语言源代码.docx_第3页
第3页 / 共15页
连连看C语言源代码.docx_第4页
第4页 / 共15页
连连看C语言源代码.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

连连看C语言源代码.docx

《连连看C语言源代码.docx》由会员分享,可在线阅读,更多相关《连连看C语言源代码.docx(15页珍藏版)》请在冰豆网上搜索。

连连看C语言源代码.docx

连连看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+1y][0]==0)max1++;

while(max2+1y][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);

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;jy,c2->y);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+1x][max1+1][0]==0)max1++;

while(max2+1x][max2+1][0]==0)max2++;

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;ix,c2->x);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.

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

当前位置:首页 > 经管营销 > 企业管理

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

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