C语言写连连看的疑问

chuishazuoshi 2012-04-10 05:00:22
#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <math.h>
#include <dos.h>
#include <bios.h>
#include <string.h>

#define true 1
#define false 0

typedef struct cell
{
char x;
char y;
} CELL;

int BkGndColor=BLACK;
int BorderColor=LIGHTGRAY;
int LineColor=LIGHTBLUE;/* 消除一对方块时时候的连线颜色 */
/* Pb - ProgressBar */
int PbColor=LIGHTGREEN;
int PbY=4;
int PbHeight=4;
int PbValue; /* 进度条百分比,初始值为100.*/
long StartTime; /* 开始时间的秒数,只统计分钟,秒 */
long TotalTime; /* 游戏总共的最大秒数!,*/

int m,n;
unsigned char Board[20][20][2];
int CellSize=30;
int BoardX=20;
int BoardY=60;
int CellNumX;/*列数*/
int CellNumY; /*行数*/
int m,n;
int CellColor=WHITE;
int SelColor=BLUE; /* selCell边界颜色 */
int CurColor=YELLOW; /* curCell边界颜色 */
int EraColor=CYAN; /* 用于擦除cell的颜色!*/
int PairsCount; /* 屏幕中有多少对 */

CELL selCell,curCell;/*缓存前一个被选中的位置以及当前所处位置!*/

enum KEYCODES
{
K_ESC =0x011b,
K_UP =0x4800,
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT =0x4d00,
K_SPACE =0x3920,
K_P =0x1970,
K_RETURN =0x1c0d,
};



/*函数列表*/
void attention();
void InitGame(char *bgiPath);
void PlayGame();
void QuitGame();
void InitProgressBar();
void UpdateProgressBar(int percent);
void DrawCell(int x,int y,int color);
void EraseCell(int x,int y);
void DrawBorderRect(CELL *c,int color);
void DrawGameOver(char* info);
int GetKeyCode();
int FindPath(CELL *c1,CELL *c2);
void DrawPath(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int color);

/* 函数实现 */

void attention()
{
int i,j;
window(1,1,100,50);
textbackground(LIGHTBLUE);
textcolor(YELLOW);
clrscr();
gotoxy(25,4);
printf("Game Start:(1)");
gotoxy(25,10);
printf("Game Over:(0)");
gotoxy(25,16);
printf("Please choose,press enter sure");
gotoxy(25,20);
scanf("%d",&i);
if(i==1)
{
clrscr();
window(1,1,100,50);
textbackground(LIGHTBLUE);
textcolor(YELLOW);
gotoxy(25,10);
printf("Game rules:");
gotoxy(25,14);
printf("press Left,Right,Up,Down key to move");
gotoxy(25,18);
printf("press ESC to quit");
gotoxy(20,22);
printf("Choose easy:(2) difficult:(3)");
gotoxy(25,26);
scanf("%d",&j);
if(j==2)
{
clrscr();
CellNumX=8;
CellNumY=5;
m=2;
n=12;

}
if(j==3)
{
clrscr();
CellNumX=16;
CellNumY=9;
m=2;
n=38;


}
InitGame("");
InitProgressBar();
PlayGame();
getch();
QuitGame();
}
else
{
if(i==0)
{
clrscr();
window(1,1,100,50);
textbackground(LIGHTBLUE);
textcolor(YELLOW);
gotoxy(25,10);
printf("Thank you");
getch();

}
}
}

/* 找到两个CELL之间的路径,成功返回true */
int FindPath(CELL *c1,CELL *c2)
{
int i,j,path,min1,max1,min2,max2,left,right,top,bottom;
/*---------------(0)判断是否点中相同块! ------------*/
if (Board[c1->x][c1->y][1] != Board[c2->x][c2->y][1])
return false;
/*---------------(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<CellNumX && Board[max1+1][c1->y][0]==0) max1++;
while (max2+1<CellNumX && 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);
DrawPath(c1->x,c1->y, -1,c1->y, -1,c2->y, c2->x,c2->y, BkGndColor);/*插除线条!*/
return true;
}
if (right==(CellNumX-1))
{
DrawPath(c1->x,c1->y, CellNumX,c1->y, CellNumX,c2->y, c2->x,c2->y, LineColor);
delay(6000);
DrawPath(c1->x,c1->y, CellNumX,c1->y, CellNumX,c2->y, c2->x,c2->y, BkGndColor);/*插除线条!*/
return true;
}

for (i=left;i<=right;i++)
{
path=0;/*统计垂直的公垂线长度!*/
for (j=min(c1->y,c2->y)+1;j<max(c1->y,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);/*插除线条!*/
return true;
}
}

/*---------------(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<CellNumY && Board[c1->x][max1+1][0]==0) max1++;
while (max2+1<CellNumY && Board[c2->x][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);/*插除线条!*/
return true;
}
if (bottom==(CellNumY-1))
{
DrawPath(c1->x,c1->y, c1->x,CellNumY, c2->x,CellNumY, c2->x,c2->y, LineColor);
delay(6000);
DrawPath(c1->x,c1->y, c1->x,CellNumY, c2->x,CellNumY, c2->x,c2->y, BkGndColor);/*插除线条!*/
return true;
}

for (j=top;j<=bottom;j++)
{
path=0;/*统计水平的公垂线长度!*/
for (i=min(c1->x,c2->x)+1; i<max(c1->x,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);/*插除线条!*/
return true;
}
}

/* 到达这里说明没有任何通路 */
return false;
}
/*Get Key Code */
int GetKeyCode()
{
int key=0;
if (bioskey(1))
{
key=bioskey(0);
}
return key;
}

/*绘制消除方块时候的连接路径!,用指定颜色!,坐标是CELL逻辑坐标!*/
void DrawPath(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int color)
{
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);
}


/* congratulations info,the user has success finish the game ! */
void DrawGameOver(char* info)
{
/*计算棋盘的中心点*/
int cx=BoardX+CellSize*CellNumX/2;
int cy=BoardY+CellSize*CellNumY/2;
struct textsettingstype textInfos;
/*获取此前的文字信息*/
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);
/*restore orignal text settings */
settextjustify(textInfos.horiz, textInfos.vert);
}


...全文
143 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
chuishazuoshi 2012-04-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hen_hao_ji 的回复:]

可能你的编译器没有加载这个图像库;

可以的,楼主学习 一下 window 编程
[/Quote]

我现在知道怎么办了,加个registerbgidriver(EGAVGA_driver);就好了
天台的故事 2012-04-10
  • 打赏
  • 举报
回复
以上面的程序为模板,用鼠标怎么实现呢?
我之前的想法是对棋盘上的没一格用数字来标记,这样的话,当循环中,遇到相同的数字时,就记下其 X Y 值,这样的话,可以根据记录鼠标点的地方,对应 X Y值,但字符型的怎么判断呢?
还有,我要插入图片是不是会很麻烦了?

chuishazuoshi 2012-04-10
  • 打赏
  • 举报
回复
以上面的程序为模板,用鼠标怎么实现呢?
我之前的想法是对棋盘上的没一格用数字来标记,这样的话,当循环中,遇到相同的数字时,就记下其 X Y 值,这样的话,可以根据记录鼠标点的地方,对应 X Y值,但字符型的怎么判断呢?
还有,我要插入图片是不是会很麻烦了?
hen_hao_ji 2012-04-10
  • 打赏
  • 举报
回复
可能你的编译器没有加载这个图像库;

可以的,楼主学习 一下 window 编程
chuishazuoshi 2012-04-10
  • 打赏
  • 举报
回复
/* 用制定颜色绘制一个选中的外边框 */
void DrawBorderRect(CELL *c,int color)
{
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);
}


void DrawCell(int x,int y,int color)
{
setcolor(color);
rectangle(BoardX+x*CellSize+2, BoardY+y*CellSize+2, BoardX+(x+1)*CellSize-3, BoardY+(y+1)*CellSize-3);
setfillstyle(SOLID_FILL, RED);
floodfill(BoardX+x*CellSize+3, BoardY+y*CellSize+3, color);
}

/* 擦除CELL */
void EraseCell(int x,int y)
{
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);
}


/* 初始化进度条 */
void InitProgressBar()
{
int width=CellSize*CellNumX;
/* progress bar border rect */
setcolor(BorderColor);
rectangle(BoardX-2,PbY-2,BoardX+width+2,PbY+PbHeight+2);

/* draw a value = 100% progress bar */
setcolor(PbColor);
rectangle(BoardX,PbY,BoardX+width,PbY+PbHeight);
setfillstyle(SOLID_FILL,PbColor);
floodfill(BoardX+1,PbY+1,PbColor);
}

/* 更新进度条,设置为某个百分比 */
void UpdateProgressBar(int percent)
{

int width;

width=CellNumX*percent/100*CellSize;

setfillstyle(SOLID_FILL,BkGndColor);
floodfill(BoardX+1,PbY+1,BorderColor);

if (width<2) return;/* too small value? */
setcolor(PbColor);
rectangle(BoardX,PbY,BoardX+width,PbY+PbHeight);
setfillstyle(SOLID_FILL,PbColor);
floodfill(BoardX+1,PbY+1,PbColor);
}


/* 初始化程序 */
void InitGame(char *bgiPath)
{
int gdriver=DETECT,gmode,i,x,y;
struct time sysTime;
/* set new seed! */
gettime(&sysTime);
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);

/* enter graphics mode */
initgraph(&gdriver,&gmode,bgiPath);
PairsCount=CellNumX*CellNumY/2;
for (i=m; i<n; i++)
{
char buf[150];

/* fill first cell of pair */
do
{
x=random(CellNumX);
y=random(CellNumY);
}
while (Board[x][y][0]!=0);
DrawCell(x,y,CellColor);
sprintf(buf,"%d",i);
settextstyle(1,0,1);
outtextxy(BoardX+x*CellSize+8, BoardY+y*CellSize+8,buf);
Board[x][y][0]=1;
Board[x][y][1]=i;

/* fill second cell of pair */
do
{
x=random(CellNumX);
y=random(CellNumY);
}
while (Board[x][y][0]!=0);
DrawCell(x,y,CellColor);
sprintf(buf,"%d",i);
settextstyle(1,0,1);
outtextxy(BoardX+x*CellSize+8, BoardY+y*CellSize+8,buf);
Board[x][y][0]=1;
Board[x][y][1]=i;
do
{
x=random(CellNumX);
y=random(CellNumY);
}
while (Board[x][y][0]!=0);
DrawCell(x,y,CellColor);
sprintf(buf,"%d",i);
settextstyle(1,0,1);
outtextxy(BoardX+x*CellSize+8, BoardY+y*CellSize+8,buf);
Board[x][y][0]=1;
Board[x][y][1]=i;
do
{
x=random(CellNumX);
y=random(CellNumY);
}
while (Board[x][y][0]!=0);
DrawCell(x,y,CellColor);
sprintf(buf,"%d",i);
settextstyle(1,0,1);
outtextxy(BoardX+x*CellSize+8, BoardY+y*CellSize+8,buf);
Board[x][y][0]=1;
Board[x][y][1]=i;
}
setcolor(YELLOW);
outtextxy(BoardX,BoardY+CellNumY*CellSize+30,"Press ESC to Exit!");
PbValue=100;
TotalTime=3*60; /* Total minutes. */
gettime(&sysTime);
StartTime=sysTime.ti_min*60+sysTime.ti_sec;
}

/* 游戏进行 */
void PlayGame()
{
int key,percent;
long curTime;
struct time sysTime;
curCell.x = curCell.y = 0;/*当前所处位置!*/
selCell.x = selCell.y = -1;/*为-1表示当前未选中*/
DrawBorderRect(&curCell, CurColor);

/*用一个循环检测按键!*/
while (key!=K_ESC)
{
/* wait until a key pressed */
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("YOU HAVE LOSE!");
return;
}
else if (percent!=PbValue)
{
UpdateProgressBar(percent);
PbValue=percent;/* update cache PbValue */
}
delay(1000);
}
/* 这时用户按下了某个键 */

/*需要恢复的是此前选中的cell!*/
if (curCell.x==selCell.x && curCell.y==selCell.y)
DrawBorderRect(&curCell, SelColor); /*恢复选中cell的focus痕迹 */
else
DrawBorderRect(&curCell, BkGndColor); /*擦除此前的focus痕迹 */
switch (key)
{
case K_LEFT:
curCell.x--;
if (curCell.x < 0) curCell.x += CellNumX;
break;
case K_RIGHT:
curCell.x++;
if (curCell.x >= CellNumX) curCell.x -= CellNumX;
break;
case K_UP:
curCell.y--;
if (curCell.y < 0) curCell.y += CellNumY;
break;
case K_DOWN:
curCell.y++;
if (curCell.y >= CellNumY) curCell.y -= CellNumY;
break;

/* 对回车键 */
case K_RETURN:
/* 如果此处没有任何cell,不处理! */
if (Board[curCell.x][curCell.y][0]==0)
break;
/* 与此前选中的位置重合,则不处理 */
if (curCell.x==selCell.x && curCell.y==selCell.y)
break;
/*如果此前没有任何选中,则设置改点为选中位置*/
if (selCell.x<0 || selCell.y<0)
{
selCell.x=curCell.x;
selCell.y=curCell.y;
DrawBorderRect(&selCell,SelColor);
continue;
}
/*如果此前已有选中,则判断是否可以消除!*/
if (FindPath(&selCell,&curCell))
{
/* 消除这两个cell!*/
EraseCell(selCell.x,selCell.y);
EraseCell(curCell.x,curCell.y);
/* 清除棋盘数据 */
Board[selCell.x][selCell.y][0]=0;
Board[selCell.x][selCell.y][1]=0;
Board[curCell.x][curCell.y][0]=0;
Board[curCell.x][curCell.y][1]=0;
/* 清除selCell */
DrawBorderRect(&selCell,BkGndColor);
selCell.x=selCell.y=-1;
/* decrease the pairs count */
PairsCount--;
if (PairsCount==0)
{
DrawGameOver("CONGRATULATIONS!");
return;
}
}
else
{
/* 不能消除这两个cell!*/
/* erase the selCell's focus rect!*/
DrawBorderRect(&selCell,BkGndColor);
selCell.x=selCell.y=-1;
}
break;
case K_ESC:
DrawGameOver("GAME OVER!");
break;
default:
break;
}
/*绘制当前focus位置*/
DrawBorderRect(&curCell, CurColor);
}
}

void QuitGame()
{
closegraph();
}

int main()
{
attention();
return 0;
}

这是我找的一个代码,想了解一下其运行状况,但运行不起来,用TC运行后,还是有问题,出现了BGI Error:Graphics not initialized (use 'initgraph')
求大神赐教!!!

附带问一句:如果我要把这个程序用鼠标实现,并且每幅图要用插入的图,可行性打吗?
具体的方法是怎么样的呢?

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧