home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Killer
/
Game_Killer.bin
/
092.ROBPATH.INC
< prev
next >
Wrap
Text File
|
1992-07-23
|
9KB
|
235 lines
function AddSectorToVector( var sv : sectorVector; s : sector ) : boolean;
{ try to add new sector. If duplicated, return false; otherwise add. }
var
i : 0..MaxMPS;
ok : boolean;
begin
ok := true;
for i := 0 to sv.size do
if sv.data[i] = s then
ok := false;
AddSectorToVector := ok;
if ok then
begin
sv.size := sv.size + 1;
sv.data[ sv.size ] := s;
end;
end;
procedure FindRobPath( var path : sectorvector;{ initialized with start }
ports : portindex; { number of ports we want }
var turns : integer; { max turns allowed }
base : sectorindex; { starting point for path }
closed : boolean); { if "turns" includes back}
{ greedy algorithm }
{
path is the sequence of ports we are trying to find. Its preloaded with
"base", our start point. "ports" is the maximum number of ports we are
looking for. "Turns" is the maximum number of turns we are allowed to use
in path. Return turns set to any turns remaining. "closed" is true if we
have to add the turns back from the last point to base, and pclass is
true/false depending on if we are looking for ports buying
equipment/selling equipment or organics.
}
var
DistToPorts: distanceArray;
PortOK : array [ sector ] of boolean;
PortsAvail : boolean;
top,
NumPorts : sectorindex;
current : sector;
n : integer;
outgoing : integer;
begin
PortsAvail := true;
current := base;
for n := 1 to 1000 do
PortOK[n] := false;
TwoWayDistances( base, distances, true, false );
for n := 1 to maxSector do distances[ n ].s := n;
DistToPorts := distances; { distances will store the return path }
write('sifting... ');
EliminateUnwanted( distToPorts, RobHolds, NumPorts, 0 );
for n := 1 to NumPorts do
PortOK[ distToPorts[ n ].s ] := true;
writeln('Ports to avoid (in addition to busted ports):');
n := GetSector;
while n <> 0 do
begin
PortOK[ n ] := false;
n := GetSector;
end;
while PortsAvail and (turns > 0) and (ports > 0) do
begin
TwoWayDistances( current, distToPorts, false, true );
for n := 1 to maxSector do distToPorts[ n ].s := n;
writeln('sorting... ');
SortDistances( distToPorts, maxSector );
PortsAvail := false;
n := 1;
while (n <= MaxSector) and (distToPorts[n].d <= turns) do
if portOK[ disttoports[n].s ] then
begin
outgoing := distToPorts[n].d;
if not closed
or (turns >= outgoing + Distances[ DistToPorts[n].s ].d) then
begin
top := path.size; { okay, see length }
if AddSectorToVector( path, distToPorts[n].s ) then { successful? }
begin
PortsAvail := true; { yes. Keep going }
current := distToPorts[n].s; { here is our next }
turns := turns - outgoing; { update turns, ports }
ports := ports - 1;
n := MaxSector; { but exit this while }
end;
end;
n := n + 1;
end {while}
else
n := n + 1;
end; {while more ports}
if closed then
turns := turns - distances[current].d;
end;
procedure TradingSpree( var path : sectorvector; { initialized with start }
ports : portindex; { number of ports we want }
var turns : integer; { max turns allowed }
base : sectorindex; { starting point for path }
closed : boolean ); { if "turns" includes back}
{ greedy algorithm }
{
path is the sequence of ports we are trying to find. Its preloaded with
"base", our start point. "ports" is the maximum number of ports we are
looking for. "Turns" is the maximum number of turns we are allowed to use
in path. Return turns set to any turns remaining. "closed" is true if we
have to add the turns back from the last point to base, and pclass is
true/false depending on if we are looking for ports buying
equipment/selling equipment or organics.
}
var
DistToPorts: distanceArray;
PortsAvail : boolean;
top,
NumPorts : sectorindex;
current : sector;
n : sector;
outgoing : integer;
buyequip : boolean;
begin
PortsAvail := true;
current := base;
buyEquip := true;
TwoWayDistances( base, distances, true, false );
for n := 1 to maxSector do distances[ n ].s := n;
DistToPorts := distances;
while PortsAvail and (turns > 0) and (ports > 0) do
begin
TwoWayDistances( current, distToPorts, false, true );
for n := 1 to maxSector do distToPorts[ n ].s := n;
write('sifting... ');
if buyEquip then
EliminateUnwanted( distToPorts, BuyEquipSellOrganic, NumPorts, 0 )
else
EliminateUnwanted( distToPorts, BuyOrganicSellEquip, NumPorts, 0 );
buyEquip := not buyEquip;
writeln('sorting... ');
SortDistances( distToPorts, NumPorts );
PortsAvail := false;
n := 1;
while (n <= NumPorts) and (distToPorts[n].d <= turns) do
begin
outgoing := distToPorts[n].d;
if not closed
or (turns >= outgoing + FixPath( DistToPorts[n].s, base, turns - outgoing)) then
begin
top := path.size; { okay, see length }
if AddSectorToVector( path, distToPorts[n].s ) then { successful? }
begin
PortsAvail := true; { yes. Keep going }
current := distToPorts[n].s; { here is our next }
turns := turns - outgoing; { update turns, ports }
ports := ports - 1;
n := NumPorts; { but exit this while }
end;
end;
n := n + 1;
end; {while}
end; {while}
if closed then
turns := turns - FixPath( current, base, turns );
end;
procedure RobPath;
{
A person provides the base point, a max number of ports, and a max number
of turns. The computer computes a sequence of ports at which the player
has not been busted, such that the number of turns or ports is not
exceeded.
The algorithm will just use the greedy algorithm. Its not optimal, but
it should suffice.
}
var
targets : sectorvector; { our sequence }
maxtargets : portindex; { maximum places sought }
turnsleft, { turns left over returned from proc }
maxturns : integer; { maximum turns allowed }
s1, s2 : sectorindex; { variables for short path displays }
i, { generic loop index }
currsector : sectorindex; { used for input }
closed, { should we use a closed path? }
equiponly : boolean; { buying equipment, or stealing holds? }
begin
repeat
write('Maximum number of targets? [max ', MaxMPS, '] ');
maxtargets := ReadNumberFromTerminal;
until (maxtargets >= 0) and (maxTargets <= MaxMPS);
if maxTargets = 0 then
exit;
write('Maximum number of turns? ');
maxturns := readNumberFromTerminal;
if maxTargets = 0 then
exit;
write('Starting ');
currsector := GetSector;
if currsector = 0 then
exit;
closed := prompt('Closed path? ');
equiponly := prompt('Trading spree path? (alternate trading equip/organic) ');
if not equiponly then
writeln('Okay, will choose ports to "rob holds".');
targets.size := 0;
targets.data[0] := currsector;
turnsleft := maxturns;
if equiponly then
TradingSpree( targets, maxtargets, turnsleft, currsector, closed )
else
FindRobPath( targets, maxtargets, turnsleft, currsector, closed );
for i := 0 to targets.size - 1 do
write( targets.data[i] : 4, ' > ');
write( targets.data[ targets.size ] );
if closed then
write( ' > ', currsector );
writeln(' of length ', maxturns - turnsleft );
writeln('Here are the intermediate paths:');
for i := 1 to Targets.size do
begin
s1 := targets.data[ i-1 ];
s2 := targets.data[ i ];
writeln( s1, ' to ', s2, ' of length ', fixpath( s1, s2, maxturns) );
printpath( s1, s2 );
readln;
end; {for}
if closed then
begin
s1 := targets.data[ targets.size ];
s2 := targets.data[ 0 ];
writeln( s1, ' to ', s2, ' of length ', fixpath( s1, s2, maxturns) );
printpath( s1, s2 );
readln;
end;
end; {rob path}