- 最后登录
- 2024-2-24
- 在线时间
- 9662 小时
- 阅读权限
- 100
- 注册时间
- 2007-12-26
- 积分
- 37843
- 帖子
- 34374
- 精华
- 15
- UID
- 16477
- 性别
- 保密
- 积分
- 37843
- 帖子
- 34374
- 精华
- 15
- UID
- 16477
- 性别
- 保密
|
这些是Hash表相关类型。我们采用的是拉链法,这样可以利用指针申请到堆空间,结合保
护模式使用,效果更好。
var
HashTableHashTableType;
SokoMaze:MazeType;
IDA:IDAType;
procedure SetBit(var BS:BitString; p:integer);
begin
BS[p div 8]:=BS[p div 8] or BitMask[p mod 8];
end;
procedure ClearBit(var BS:BitString; p:integer);
begin
BS[p div 8]:=BS[p div 8] xor BitMask[p mod 8];
end;
function GetBit(var BS:BitString; p:integer):byte;
begin
if BS[p div 8] and BitMask[p mod 8]>0 then GetBit:=1 else GetBit:=0;
end;
这些是位操作,设置,清除和得到一个BitString的某一项。
procedure Init;
var
Lines:MapType;
procedure ReadInputFile;
var
f:text;
s:string;
begin
SokoMaze.X:=0;
SokoMaze.Y:=0;
SokoMaze.BoxCount:=0;
assign(f,infile);
reset(f);
while not eof(f) do
begin
readln(f,s);
if length(s)>SokoMaze.Y then
SokoMaze.Y:=length(s);
inc(SokoMaze.X);
Lines[SokoMaze.X]:=s;
end;
close(f);
end;
procedure AdjustData;
var
i,j:integer;
begin
for i:=1 to SokoMaze.X do
while length(Lines)<SokoMaze.Y do
Lines:=Lines+' ';
SokoMaze.Map:=Lines;
for i:=1 to SokoMaze.X do
for j:=1 to SokoMaze.Y do
if SokoMaze.Map[i,j] in [Char_BoxInTarget,Char_SokoInTarget,Char_Targe
t] then
SokoMaze.Map[i,j]:=Char_Target
else if SokoMaze.Map[i,j]<>Char_Wall then
SokoMaze.Map[i,j]:=Char_Empty;
调整Map数组,把箱子和搬运工去掉。
for i:=1 to SokoMaze.X do
for j:=1 to SokoMaze.Y do
if Lines[i,j] in [Char_Target,Char_BoxInTarget,Char_SokoInTarget] then
begin
inc(SokoMaze.BoxCount);
SokoMaze.GoalPosition[SokoMaze.BoxCount]:=(i-1)*SokoMaze.Y+j-1;
end;
统计Goal的个数和GoalPosition。
DeltaPos[Up]:=-SokoMaze.Y;
DeltaPos[Down]:=SokoMaze.Y;
MaxPosition:=SokoMaze.X*SokoMaze.Y;
根据地图尺寸调整DeltaPos和MaxPosition
end;
procedure ConstructMaze;
var
i,j:integer;
begin
fillchar(SokoMaze.Goals,sizeof(SokoMaze.Goals),0);
fillchar(SokoMaze.Walls,sizeof(SokoMaze.Walls),0);
for i:=1 to SokoMaze.X do
for j:=1 to SokoMaze.Y do
case Lines[i,j] of
Char_SokoInTarget, Char_BoxInTarget, Char_Target:
SetBit(SokoMaze.Goals,(i-1)*SokoMaze.Y+j-1);
Char_Wall:
SetBit(SokoMaze.Walls,(i-1)*SokoMaze.Y+j-1);
end;
end;
procedure InitIDA;
var
i,j:integer;
StartState:StateType;
begin
IDA.NodeCount:=0;
IDA.TopLevelNodeCount:=0;
fillchar(StartState,sizeof(StartState),0);
for i:=1 to SokoMaze.X do
for j:=1 to SokoMaze.Y do
case Lines[i,j] of
Char_Soko, Char_SokoInTarget:
StartState.ManPosition:=(i-1)*SokoMaze.Y+j-1;
Char_Box, Char_BoxInTarget:
SetBit(StartState.Boxes,(i-1)*SokoMaze.Y+j-1);
end;
StartState.g:=0;
IDA.StartState:=StartState;
new(HashTable);
for i:=1 to MaxHashEntry do
begin
HashTable^.FirstEntry:=nil;
HashTable^.Count:=0;
end;
end;
begin
ReadInputFile;
AdjustData;
ConstructMaze;
InitIDA;
end;
procedure PrintState(State:StateType);
var
i,x,y:integer;
Map:MapType;
begin
Map:=SokoMaze.Map;
x:=State.ManPosition div SokoMaze.Y+1;
y:=State.ManPosition mod SokoMaze.Y+1;
if Map[x,y]=Char_Target then
Map[x,y]:=Char_SokoInTarget
else
Map[x,y]:=Char_Soko;
for i:=1 to MaxPosition do
if GetBit(State.Boxes,i)>0 th |
|