您的位置:首页 > 其它

Video Game Design

2011-04-24 16:18 253 查看
Professor Cloud has been consulting in the design of the most anticipated game of the
year: Takehome Fantasy XII. One of the levels in the game is a maze that players
must navigate through multiple rooms from an entrance to an exit. Each room can be
empty, contain a monster, or contain a life potion. As the player wanders through the
maze, points are added or subtracted from her life points L. Drinking a life potion
increases L, but battling a monster decreases L. If L drops to 0 or below, the player
dies.
As shown in Figure 1, the maze can be represented as a digraph G = (V, E), where
vertices correspond to rooms and edges correspond to (one-way) corridors running
from room to room. A vertex-weight
function f :V → Z represents the room
contents:
If f(v) = 0, the room is empty.
If f(v) > 0, the room contains a life
potion. Every time the player enters the
room, her life points L increase by f(v).
If f(v) < 0, the room contains a
monster. Every time the player enters the
room, her life points L drop by | f(v)|,
killing her if L becomes nonpositive. Figure 1 An example of a 1-admissible maze
The entrance to the maze is a designated room s ∈ V, and the exit is another room t ∈
V. Assume that a path exists from s to every vertex v ∈ V, and that a path exists from
every vertex v ∈ V to t. The player starts at the entrance s with L = L0 > 0 life points.
For simplicity, assume that the entrance is empty: f(s) = 0.
Professor Cloud has designed a program to put monsters and life potions randomly
into the maze, but some mazes may be impossible to safely navigate from entrance to
exit unless the player enters with a sufficient number L0 > 0 of life points. A path from
s to t is safe if the player stays alive along the way, i.e., her life points never become
nonpositive. Define a maze to be r-admissible if a safe path through the maze exists
when the player begins with L0 = r life points.
Help the professor by designing an efficient algorithm to determine the minimum
value r for which a given maze is r-admissible, or determine that no such r exists.
(a) Find a safe path in the maze in Figure 1.
(b) Formulate the problem as an equivalent problem where the weights are on the
edges,and prove equivalence.
(c) Assume for this problem part that there are no cycles whose traversal gives a net
increase in life points. Given r, how would you check whether the maze is
r-admissible?
(d) Now assume that there can be cycles in the graph whose traversal gives a net
increasein life points. Given r, how would you check whether the maze is
r-admissible?
(e) How can you find the minimum r for which the maze is r-admissible?
(f) Write a program to implement your algorithms

图的一个实现以及深度优先遍历,怕代码弄丢了,所以传上来。

#include "stdafx.h"
#include <iostream>
#include <malloc.h>
using namespace std;
#define MAX_VERTEX_NUM 20
int JUDGE=0;                 //标志位,判断是否为r—admissable
int firstmach=0;               //深度遍历第一次匹配标志
int Ver;                       //记录下深度遍历第一次匹配成功时的顶点

//用邻接表作为图的存储结构
typedef struct ArcNode{
int adjvex;               //该弧所指向的顶点的位置
struct ArcNode *nextarc;  //指向下一条弧的指针
int data;                 //该弧的权重
}*Arc;
typedef struct VNode{
int data;                 //顶点的信息
ArcNode *firstarc;        //指向第一条依附该顶点的弧的指针
}*Vertex;
typedef struct gra{           //图的存储结构
VNode g[MAX_VERTEX_NUM];
int vexnum,arcnum;
}*Graph;
int Find(int a[],int num,int v)
{
int i=0;
for(i=0;i<num;i++)
{
if(a[i]==v)
return 1;
}
return 0;
}
//创建一张地图
void CreatGraph(Graph &G)
{
int i;
int j;
int m,n;
Arc p;
int weight;
cout<<"请输入有向图的顶点数和边数:"<<endl;
cin>>G->vexnum>>G->arcnum;
for(i=0;i<G->vexnum;i++)
{
G->g[i].data=i;
G->g[i].firstarc=NULL;
}
for(j=0;j<G->arcnum;j++)
{
cout<<"请输入第"<<j+1<<"条边以及边的权重:"<<endl;
cin>>m>>n>>weight;
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=n;
p->data=weight;
p->nextarc=G->g[m].firstarc;
G->g[m].firstarc=p;
}
}
//**************************************************//
//当图中没有单增加血的循环路径的时候判断r血是否可通过此地图//
//**************************************************//
/*void dfs(Graph G,int v,int r)
{
if(r<=0)
return;
if(v==(G->vexnum)-1&&r>0)
{
JUDGE=1;
return;
}
ArcNode *p=(Arc)malloc(sizeof(ArcNode));
p=G->g[v].firstarc;
while(p!=NULL)
{
dfs(G,p->adjvex,r+p->data);
p=p->nextarc;
}
}*/
//**************************************************//
//当图中可能有单增加血的循环路径时判断r血是否可通过此地图//
//**************************************************//
void dfs2(Graph G,int v,int r,int IniR,int gnum[],int i)
{
if(!Find(gnum,i,v))
gnum[i]=v;             //v表示当前顶点,r表示当前血量
else
{
if(firstmach==0)     //添加第一次匹配成功的标志位,保证是回到循环路径的起始点时血量增加
{
firstmach=1;
Ver=v;
}
if(v!=0&&v==Ver&&r>IniR)             //如果经过此路径后血量增加说明存在单增的循环,
{                      //并且血量为正值,可以断定一定可以经过
JUDGE=1;
return;
}
}
if(r<=0)
return;
if(v==(G->vexnum)-1&&r>0)
{
JUDGE=1;
return;
}
ArcNode *p=(Arc)malloc(sizeof(ArcNode));
p=G->g[v].firstarc;
while(p!=NULL)
{
dfs2(G,p->adjvex,r+p->data,IniR,gnum,i+1);
p=p->nextarc;
}
}
//求可以通过的最小的血量
int MiniR(Graph G,int gnum[])
{
JUDGE=0;
int MiniR;
int INIR;
for(MiniR=1;MiniR<=100;MiniR++)
{
INIR=MiniR;
dfs2(G,0,MiniR,INIR,gnum,0);
if(JUDGE==1)
{
return MiniR;
}
else if(JUDGE==0)
{
for(int m=0;m<MAX_VERTEX_NUM;m++)
gnum[m]=-1;
continue;
}
}
return 0;
}
void main()
{
int gnum[MAX_VERTEX_NUM];
for(int k=0;k<MAX_VERTEX_NUM;k++)
gnum[k]=-1;                  //记录访问过的节点,可以输出路径
Graph G;
G=(Graph)malloc(sizeof(gra));
CreatGraph(G);
int MINIR=MiniR(G,gnum);
if(MINIR==0)
cout<<"满血(100)也不能通过此迷宫"<<endl;
else
cout<<"可以通过此迷宫的最小血量是:"<<MINIR<<endl;
int r;
cout<<"请输入测试血量r:"<<endl;
cin>>r;
JUDGE=0;
int IniR=r;//初始血量
dfs2(G,0,r,IniR,gnum,0);
if(JUDGE==0)
cout<<"不可以通过!!"<<endl;
else if(JUDGE==1)
cout<<"可以通过!";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: