june的小游戏程序求助!
自己看了下小游戏的程序,有几处问题需要求助!
函数catPace()里的求最短路和初始化没有看懂!尤其那个TEMP变量!注释说是记录最短路径,个变量怎么记得了啊~
这个函数里的变量和DJ斯科拉算法有很大的关系,我居然把DJ斯科拉算法给搞忘了,拜托谁知道给我大体说说,应该有个提示就能想起来~多谢!
下面是june贴出的小游戏程序:
源码和exe在下面的包里.有兴趣的同学可以下载下来玩一玩.很简单的小游戏.
/**********************************************************************/
/**
/** 游戏说明:
/** 此游戏为单人游戏.共有两个角色.分别由玩家和电脑控制.玩家控
/** 角色,相当于"老鼠",吃掉地图中的"面包",电脑则扮演"猫"来抓"鼠".
/** 如果规定时间内玩家把所有的"面包"吃掉则胜利.进入下一关.
/** 如果没有吃光或者被"猫"抓到则游戏失败.玩家可以选择重新闯关.
/** 该游戏共有9关,如果你感兴趣的话可以自己修改代码或者添加新地 图.
/** 本游戏是C语言版的Tom and Jerry游戏.功能比较简单.能够改进的
/** 地方很多.VC++.net版本的Tom and Jerry功能要比这个全.重新用C语言
/** 写这个游戏主要是想和大家交流交流.
/** 前3关没有难度.4.5.6关难度也不高.7.8.9就有点难度了.看看大家
/** 能不能闯过所有关口.试试看吧
/**
/**********************************************************************/
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#include <time.h>
#define LEFT 0x4b00 /* 定义键盘数值 */
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define TOTAL 9 /* 共9关 */
void init(void); /* 初始化图形界面 */
void close(void); /* 关闭图形界面,游戏结束时调用*/
void startFace(void); /* 欢迎界面 */
void drawFace(void); /* 画游戏界面,调用下面显示信息 */
void showRemain(void); /* 显示剩余面包和剩余时间 */
void showOperate(void); /* 显示操作说明 */
void showMapNum(void); /* 显示第几关 */
void play(void); /* 游戏函数,游戏结果调用 输 和 赢 函数 */
void gameOver(void); /* 输 */
void gameWin(void); /* 赢 */
void mousePace(void); /* 玩家控制走步 */
void catPace(void); /* 电脑控制走步.用到下面dijkstra最短路函数 */
void dijkstra(int C[100][100], int n, int D[100],int path[100],int v0);
void nextPace(int way,int role); /* 走步.way代表方向,role 0为玩家1为电脑 */
int i,j; /* 用来循环 */
char str[10]; /* 用来在界面上显示文字 */
clock_t St,Et,Ct; /* 用来计时,(Et,St)用来倒计时,(Et,Ct)电脑走步的速度 */
int key; /* 用来接受按键 */
int location[2]; /* 记录玩家和电脑两个角色的位置,0为玩家,1为电脑 */
int breadmount; /* 记录面包个数 */
int playtime; /* 记录游戏时间 */
int mapnum=0; /* 记录当前关数 */
int map[9][100] ={ /* 游戏地图,共9张(关),0代表空,1代表墙,2代表面包*/
{ /* 第一关 */
0,0,0,0,1,1,1,0,0,0,
0,1,1,0,1,1,1,0,0,0,
0,1,1,0,0,0,1,1,1,0,
0,0,0,1,1,0,1,1,1,0,
1,1,0,1,1,0,1,1,0,0,
1,1,0,1,1,0,0,0,0,1,
0,0,0,1,1,0,1,1,0,1,
0,1,0,0,0,0,1,1,0,1,
0,1,1,1,1,1,1,1,0,1,
0,0,0,0,0,0,0,0,0,1},
{ /* 第二关 */
1,1,0,0,0,0,0,0,1,1,
1,0,0,1,1,0,1,0,0,1,
0,0,1,1,0,0,0,1,0,0,
0,1,0,0,0,1,0,1,1,0,
0,0,0,1,1,1,0,0,1,0,
0,1,0,0,1,1,1,0,0,0,
0,1,1,0,1,0,0,0,1,0,
0,0,1,0,0,0,1,1,0,0,
1,0,0,1,0,1,1,0,0,1,
1,1,0,0,0,0,0,0,1,1},
{ /* 第三关 */
1,1,0,0,0,0,0,0,1,1,
0,0,0,1,1,1,1,0,0,0,
0,1,1,0,0,0,0,1,1,0,
0,0,0,0,1,1,0,0,0,0,
0,1,1,0,0,0,0,1,1,0,
0,1,1,0,1,1,0,1,1,0,
0,0,1,0,1,1,0,1,0,0,
1,0,1,0,0,0,0,1,0,1,
0,0,0,0,1,1,0,0,0,0,
0,1,1,1,1,1,1,1,1,0},
{ /* 第四关 */
0,0,0,0,0,0,0,0,0,1,
0,1,1,1,0,1,1,1,0,1,
0,0,1,0,0,1,0,1,0,1,
1,0,1,1,1,1,0,1,0,0,
1,0,0,0,0,0,0,1,1,0,
1,0,1,1,0,1,0,0,1,0,
1,0,0,1,0,1,0,1,1,0,
1,1,0,0,0,0,0,0,0,0,
0,1,0,1,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0},
{ /* 第五关 */
1,1,0,1,1,0,0,0,1,0,
0,0,0,0,0,0,1,0,0,0,
0,1,0,1,0,1,1,0,1,0,
0,0,0,0,0,1,0,0,1,0,
1,0,1,1,0,1,0,1,1,0,
0,0,0,1,0,0,0,1,0,0,
0,1,1,1,1,1,0,1,1,0,
0,1,0,0,0,0,0,0,1,0,
0,1,1,0,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0},
{ /* 第六关 */
1,0,0,0,0,0,0,0,0,0,
0,0,1,1,1,1,1,1,1,0,
0,0,1,0,0,0,1,0,1,0,
0,0,0,0,0,0,0,0,1,0,
1,0,1,1,0,1,0,1,1,0,
0,0,1,0,1,0,0,0,0,0,
0,0,0,0,1,0,1,0,1,1,
0,1,0,1,1,0,1,0,0,1,
0,1,0,0,1,1,0,1,0,1,
0,0,0,0,0,0,0,0,0,1},
{ /* 第七关 */
0,0,0,0,0,0,0,0,0,0,
0,1,0,1,0,1,0,1,1,0,
0,0,1,0,0,0,0,0,1,0,
0,1,0,1,0,1,0,1,1,0,
0,0,0,0,1,1,1,0,1,0,
0,1,0,1,1,1,0,0,0,0,
0,1,1,0,1,0,1,0,1,0,
0,1,0,0,0,0,0,1,0,0,
0,1,1,0,1,0,1,0,1,0,
0,0,0,0,0,0,0,0,0,0},
{ /* 第八关 */
0,1,1,1,0,1,0,1,0,1,
0,0,0,0,0,0,0,0,0,0,
1,0,1,1,1,0,1,0,1,0,
0,0,0,0,0,0,0,0,0,0,
0,1,0,1,0,1,1,1,0,1,
0,0,0,0,0,0,0,0,0,0,
1,0,1,0,1,0,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,
0,1,0,1,1,1,0,1,0,1,
0,0,0,0,0,0,0,0,0,0},
{ /* 第九关 */
1,0,0,0,0,1,0,0,1,1,
0,0,0,0,1,0,0,0,0,0,
0,1,1,0,1,0,1,1,0,0,
0,1,1,0,0,0,1,0,0,1,
0,0,0,0,1,0,0,1,0,0,
0,0,0,0,0,1,0,0,0,0,
0,0,1,0,1,0,0,1,0,1,
1,0,0,0,0,0,1,0,0,0,
1,1,0,1,0,0,1,1,0,0,
1,0,0,0,0,0,0,0,0,1}
};
int main(void)
{
init(); /* 初始化 */
startFace(); /* 欢迎界面 */
drawFace(); /* 画游戏界面 */
play(); /* 游戏 */
return 0;
}
void init(void) /* 初始化程序 */
{
int gd=DETECT,gm;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"e:\\tc");
}
void startFace(void) /* 欢迎界面 */
{
cleardevice(); /* 清屏 */
while(!kbhit()) /* 如果没有按键.循环执行 */
{
setcolor(rand()%13+1); /* 色彩随机 */
settextstyle(0,0,4);
outtextxy(120,100,"Tom And Herry");
settextstyle(0,0,2);
outtextxy(40,160,"+++++++++++++++++++++++++++++++++++");
outtextxy(380,200,"Made By Z.D.L.");
settextstyle(0,0,2);
outtextxy(85,280," | ");
outtextxy(85,305," ] [ ");
outtextxy(85,330," _____[:::]______ ");
outtextxy(85,360,"[:::]=[:::::TTTTT:::::]=[:::]");
settextstyle(0,0,1);
outtextxy(400,435,"press any key to start...");
delay(5000); /* 延迟一段时间再循环 */
}
key=bioskey(0); /* 接受按键 */
if(key==ESC)
{
close();exit(0); /* 如果按键为Esc 则退出程序 */
}
}
void drawFace(void) /* 画界面 */
{
cleardevice(); /* 清屏 */
breadmount=0; /* 面包 */
if(mapnum<5)playtime=25; /* 1.2.3.4.5关由于简单故把时间设为25秒 */
else if(mapnum==5)playtime=30; /* 第6关时间为30秒 */
else playtime=40; /* 7.8.9比较难.时间设置为45秒 */
setfillstyle(SOLID_FILL,11); /* 画边界 */
bar(30, 30, 449, 39); /*上*/
bar(30, 440, 449, 449); /*下*/
bar(30, 30, 39, 449); /*左*/
bar(440, 30, 449, 449); /*右*/
for(i=0;i<100;i++) /* 画游戏地图 */
{
if(map[mapnum]==1) /* 如果是墙,画墙 */
{
setfillstyle(HATCH_FILL,11);
bar((i%10+1)*40, (i/10+1)*40, (i%10+1)*40+39,(i/10+1)*40+39);
}
else /* 如果不是墙,画面包 */
{
setfillstyle(SOLID_FILL,5);
bar((i%10+1)*40+10, (i/10+1)*40+10, (i%10+1)*40+29,(i/10+1)*40+29);
breadmount++; /* 面包个数加一 */
map[mapnum]=2; /* 将为面包的位置记录为2 */
}
}
for(i=0;i<100;i++)if(map[mapnum]!=1)break; /* 找玩家的位置 */
location[0]=i; /* 记录玩家位置 */
map[mapnum]=0; /* 将玩家位置的面包去除掉 */
breadmount--; /* 面包个数减1 */
setfillstyle(EMPTY_FILL,0); /* 清除将此位置图象 */
bar((i%10+1)*40, (i/10+1)*40, (i%10+1)*40+39,(i/10+1)*40+39);
setfillstyle(SOLID_FILL,2); /* 画玩家角色,颜色为绿 */
pieslice((i%10+1)*40+20,(i/10+1)*40+20,0,360,10);
for(i=99;i>0;i--)if(map[mapnum]!=1)break; /* 找电脑控制角色的位置 */
location[1]=i; /* 记录其位置 */
setfillstyle(EMPTY_FILL,0); /* 清除将此位置图象 */
bar((i%10+1)*40, (i/10+1)*40, (i%10+1)*40+39,(i/10+1)*40+39);
setfillstyle(SOLID_FILL,1); /* 画电脑角色,颜色为蓝 */
pieslice((i%10+1)*40+20,(i/10+1)*40+20,0,360,10);
setfillstyle(SOLID_FILL,YELLOW); /* 显示游戏信息 */
setcolor(6);
settextstyle(0,0,2);
bar(465,45,600,70);
outtextxy(470,50,"remain"); /* 剩余标签 */
bar(465,175,600,200);
outtextxy(470,180,"operate"); /* 操作标签 */
bar(465,345,600,440);
outtextxy(470,350,"round"); /* 关数标签 */
showRemain(); /* 显示剩余信息 */
showOperate(); /* 显示操作信息 */
showMapNum(); /* 显示关数信息 */
}
void showRemain(void)
{
setcolor(6);
settextstyle(0,0,2);
setfillstyle(EMPTY_FILL,0); /* 清除原先信息 */
bar(465, 85, 600,110);
sprintf(str,"bread:%2d",breadmount); /* 显示面包信息 */
outtextxy(470,90,str);
setfillstyle(EMPTY_FILL,0); /* 清除原先信息 */
bar(465, 125, 600,150);
sprintf(str,"time :%2d",playtime); /* 显示剩余时间 */
outtextxy(470,130,str);
}
void showOperate(void)
{
setcolor(6);
settextstyle(0,0,2);
outtextxy(470,220,"start: 1"); /* 显示操作说明 */
outtextxy(470,260,"stop : 2");
outtextxy(470,300,"exit : 3");
}
void showMapNum(void)
{
setcolor(6);
settextstyle(0,0,6);
sprintf(str,"%d",mapnum+1); /* 显示当前第几关 */
outtextxy(510,380,str);
}
void close(void)
{
closegraph(); /* 游戏结束时关闭图象 */
}
void play(void) /* 游戏函数 */
{
while(1)
{
key=bioskey(0); /* 接受按键 */
if((char)key=='1')break; /* 如果按键为1,跳出死循环开始游戏. */
if(key==ESC||(char)key=='3') /* 如果按键为3或者Esc,退出游戏 */
{close();exit(0);}
}
St=clock(); /* 记录每一秒的开始时间 */
Ct=clock(); /* 记录每次电脑走步的时间 */
while(1)
{
Et=clock(); /* 每次循环开始记录当前时间 */
if((Et-Ct)/CLK_TCK>=0.2) /* 每隔0.2秒电脑走一步 */
{
catPace(); /* 电脑走步 */
Ct=clock(); /* 走完一步重新记录起始时间 */
if(location[1]==location[0]) /* 如果电脑抓住玩家 */
{
gameOver(); /* 游戏失败. */
}
}
if((Et-St)/CLK_TCK>=1) /* 每隔1秒倒计时减1 */
{
St=clock(); /* 重新记录每一秒的起始时间 */
playtime--; /* 剩余时间减1 */
showRemain(); /* 重新显示剩余信息 */
if(playtime==0) /* 如果剩余时间为0,游戏结束 */
{
gameOver(); /* 游戏失败 */
}
}
if(kbhit()) /* 如果有按键发生 */
{
key=bioskey(0); /* 接受按键 */
if(key==ESC||(char)key=='3') /* 若按键为3或者Esc则推出游戏 */
{close();exit(0);}
if((char)key=='2') /* 如果按键为2.停止游戏 */
{
while(1) /* 游戏进入死循环. */
{
key=bioskey(0); /* 如果按键为1则跳出循环.开始游戏 */
if((char)key=='1')break;
}
};
mousePace(); /* 根据按键情况让玩家走步 */
if(breadmount==0) /* 如果剩余面包为0,游戏结束 */
{
gameWin(); /* 游戏胜利 */
}
}
}
}
void gameOver(void) /* 游戏失败 */
{
setfillstyle(EMPTY_FILL,0); /* 显示失败界面 */
bar(90, 190, 549,289);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);
setcolor(15);
rectangle(100, 200, 539,279);
settextstyle(0,0,2);
if(location[1]==location[0]) /* 如果被抓 */
outtextxy(125,220,"Game Over!You are caught!");
else /* 否则显示时间用尽 */
outtextxy(125,220,"Game Over!Time is outuse!");
outtextxy(125,250," Y retry / N exit "); /* 再来否 */
while(1)
{
key=bioskey(0); /* 接受按键 */
if((char)key=='y') /* 如果再来 */
{
drawFace(); /* 重新显示游戏界面 */
play(); /* 开始游戏 */
}
else if((char)key=='n') /* 否则退出游戏 */
{close();exit(0);}
}
}
void gameWin(void)
{
setfillstyle(EMPTY_FILL,0); /* 显示胜利界面 */
bar(90, 190, 549,289);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);
setcolor(13);
rectangle(100, 200, 539,279);
if(mapnum==TOTAL-1) /* 如果过全关. */
{
settextstyle(0,0,2);
outtextxy(125,220,"WELL DONE! GAMES ALL WIN!");
settextstyle(0,0,1);
outtextxy(155,245,"Thanks for playing ! Press any key to exit! ");
outtextxy(380,260,"Made By Z.D.L ^_^ ");
getch();
close(); /* 退出程序 */
exit(0);
}
else /* 否则选择是否进入下一关 */
{
settextstyle(0,0,2);
outtextxy(125,220,"Congratulations! You win!");
outtextxy(125,250," Y go on / N exit ");
while(1)
{
key=bioskey(0); /* 接受按键 */
if((char)key=='y') /* 如果选择继续玩 */
{
mapnum++; /* 地图加1,代表关数 */
drawFace(); /* 重新画游戏界面 */
play(); /* 开始游戏 */
}
else if((char)key=='n') /* 否则退出游戏 */
{close();exit(0);}
}
}
}
void nextPace(int way,int role) /* 走步.role:0代表玩家,1代表电脑. */
{ /* way:1.左走 -1.右 2.上 -2.下 */
setfillstyle(SOLID_FILL,0); /* 清空角色当前位置 */
bar((location[role]%10+1)*40,(location[role]/10+1)*40,
(location[role]%10+1)*40+39,(location[role]/10+1)*40+39);
/* 如果role是电脑并且当前位置值为2(代表是面包) */
if(role==1&&map[mapnum][location[role]]==2)
{
setfillstyle(SOLID_FILL,5); /* 将当前位置显示为面包 */
bar((location[role]%10+1)*40+10,(location[role]/10+1)*40+10,
(location[role]%10+1)*40+29,(location[role]/10+1)*40+29);
}
switch(way) /* 走步,记录走步后的角色位置 */
{
case 2: location[role] -= 10;break;
case -2: location[role] += 10;break;
case -1: location[role] -= 1;break;
case 1: location[role] += 1;break;
}
if(role==0) /* 如果role为玩家 */
{
/* 如果当前位置值为2,代表玩家吃到一个面包 */
if(map[mapnum][location[role]]==2)
{
map[mapnum][location[role]]=0; /* 将当前位置值变为0,代表吃到 */
breadmount--; /* 剩余面包总数减1 */
showRemain(); /* 重新显示剩余面包信息 */
}
setfillstyle(EMPTY_FILL,0); /* 将当前位置清空 */
bar((location[role]%10+1)*40,(location[role]/10+1)*40,
(location[role]%10+1)*40+39,(location[role]/10+1)*40+39);
setfillstyle(SOLID_FILL,2); /* 显示玩家..(绿圆) */
pieslice((location[role]%10+1)*40+20,(location[role]/10+1)*40+20,0,360,10);
}
else /* 如果role为电脑 */
{
setfillstyle(EMPTY_FILL,0); /* 清空当前位置 */
bar((location[role]%10+1)*40,(location[role]/10+1)*40,
(location[role]%10+1)*40+39,(location[role]/10+1)*40+39);
setfillstyle(SOLID_FILL,1); /* 显示电脑角色..(蓝圆) */
pieslice((location[role]%10+1)*40+20,(location[role]/10+1)*40+20,0,360,10);
}
}
void mousePace(void) /* 玩家控制走步 */
{
switch(key) /* 检测key的值 */
{
case UP: /* 如果按下的方向键为上,并且没有墙的话 */
if(location[0]>=10 && map[mapnum][location[0]-10]!=1)
nextPace(2,0); /* 玩家向上走(0代表玩家,2代表向上) */
break;
case DOWN: /* 如果按下的方向键为下,并且没有墙的话 */
if(location[0]<90 && map[mapnum][location[0]+10]!=1)
nextPace(-2,0); /* 玩家向下走(0代表玩家,-2代表向下) */
break;
case LEFT: /* 如果按下的方向键为左,并且没有墙的话 */
if(location[0]%10!=0 && map[mapnum][location[0]-1]!=1)
nextPace(-1,0); /* 玩家向左走(0代表玩家,-1代表向左) */
break;
case RIGHT: /* 如果按下的方向键为右,并且没有墙的话 */
if(location[0]%10!=9 && map[mapnum][location[0]+1]!=1)
nextPace(1,0); /* 玩家向右走(0代表玩家,1代表向右) */
break;
}
}
void catPace(void) /* 电脑控制角色走步 */
{
/**********************************************************************/
/**************** 求最短路 *********************/
int path[100],D[100];
int C[100][100];
int left=0,right=0,up=0,down=0,center=0;
int temp=0;
int count = 0;
/*************** 初始化 *************************/
for(i=0; i<100; i++)for(j=0; j<100; j++)C[j] = 9999;
for(i=0; i<100; i++)
{
path=9999;
D=9999;
if(map[mapnum]!=1)
{
count++;
left = i-1;right = i+1;up = i-10;down = i+10;
if(i%10>0 && map[mapnum][left] != 1)C[left] = 1;
if(i%10<9 && map[mapnum][right] != 1)C[right] = 1;
if(up >= 0 && map[mapnum][up] != 1)C[up] = 1;
if(down < 100 && map[mapnum][down] != 1)C[down] = 1;
}
}
/*************** 初始化结束 *********************/
temp = 9999; /* 记录最短路径 */
center = location[1];
left = center-1;right = center+1;up = center-10;down = center+10;
dijkstra(C,100,D,path,location[0]);
temp = D[center]<temp ? D[center] : temp;
temp = (center%10>0 && D[left]<temp) ? D[left] : temp;
temp = (center%10<9 && D[right]<temp) ? D[right] : temp;
temp = (up>=0 && D[up]<temp) ? D[up] : temp;
temp = (down<100 && D[down]<temp) ? D[down] : temp;
/***********************************************************************/
/**********************************************************************/
if(center%10>0 && temp == D[left]) /* 如果向左走为最短路 */
nextPace(-1,1);/* 向左走,1代表电脑控制, */
else if(center%10<9 && temp == D[right]) /* 如果向右走为最短路 */
nextPace(1,1);/* 向右走,1代表电脑控制, */
else if(up>=0 && temp == D[up]) /* 如果向上走为最短路 */
nextPace(2,1);/* 向上走,1代表电脑控制, */
else if(down<100 && temp == D[down]) /* 如果向下走为最短路 */
nextPace(-2,1);/* 向下走,1代表电脑控制, */
}
/********** 用到数据结构中的dijkstra算法,求单源最短路径问题 **********/
void dijkstra(int C[100][100], int n, int D[100],int path[100],int v0)
{
int mindis=0;
int u=0;
int s[100];for( i=0; i<100; i++)s=0; /*标记已求出最短路的结点*/
for( i=0 ; i<n ; i++ ) /*初始化*/
{
D = C[v0];
s = 0;
if(D!=9999)path = v0;
else path=9999;
}
s[v0]=1;
for(i=0;i<n;i++) /* dijkstra算法*/
{
mindis = 9999;
for(j=0;j<n;j++)
if(s[j]==0&&D[j]<mindis)
{
u=j;
mindis = D[j];
}
s=1;
for(j=0;j<n;j++)
if(s[j]==0&&D[j]>(D+C[j]))
{
D[j]=D+C[j];
path[j] = u;
}
}
D[v0]=0;
}
搜索更多相关主题的帖子:
june 小游戏 程序