|
|
|
@@ -11,7 +11,6 @@ namespace Buhnenrennen |
|
|
|
class Field |
|
|
|
{ |
|
|
|
public Dictionary<double, List<Groyne>> Groynes { get; private set; } |
|
|
|
|
|
|
|
Regex groynSchema = new Regex( "(?<type>[A-Z]) (?<level>[0-9]+) (?<yCoord>[0-9\\.]+)", RegexOptions.IgnoreCase ); |
|
|
|
|
|
|
|
private Field( IEnumerable<string> groynes ) |
|
|
|
@@ -32,52 +31,19 @@ namespace Buhnenrennen |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* <summary>returns a field object loaded from entries out of File at {filename}</summary> |
|
|
|
* <param name="filename">Location of the file to read</param> |
|
|
|
*/ |
|
|
|
public static Field fromFile( string filename ) |
|
|
|
{ |
|
|
|
return new Field( File.ReadAllLines( filename ) ); |
|
|
|
} |
|
|
|
|
|
|
|
public Groyne[] findShortestPath( Dog dog ) |
|
|
|
{ |
|
|
|
List<Groyne> poles = new List<Groyne>(); |
|
|
|
Groyne start = Groynes[ 0 ].Find( groyne => groyne.Type == dog.Start ); |
|
|
|
if ( start == null ) throw new Exception( "No start position found" ); |
|
|
|
poles.Add( start ); |
|
|
|
|
|
|
|
Groyne previous = start; |
|
|
|
for( int level = 70; level <= Groynes.Keys.Max(); level += 70 ) |
|
|
|
{ |
|
|
|
List<Groyne> candidates = Groynes[ level ].Where( groyne => groyne.canPass( dog ) ).ToList(); |
|
|
|
var distances = candidates.Select( groyne => groyne.distanceTo( previous ) ).ToList(); |
|
|
|
var minDistance = distances.Min(); |
|
|
|
previous = candidates[ distances.IndexOf( minDistance ) ]; |
|
|
|
poles.Add( previous ); |
|
|
|
} |
|
|
|
|
|
|
|
return poles.ToArray(); |
|
|
|
} |
|
|
|
|
|
|
|
public TimedGroyne findFastestPath( Dog dog ) |
|
|
|
{ |
|
|
|
Groyne start = Groynes[ 0 ].Find( groyne => groyne.Type == dog.Start ); |
|
|
|
if ( start == null ) throw new Exception( "No start position found" ); |
|
|
|
|
|
|
|
Groyne lastLevel = start; |
|
|
|
Dictionary<int, List<TimedGroyne>> times = new Dictionary<int, List<TimedGroyne>>(); |
|
|
|
times.Add( 0, new TimedGroyne[] { new TimedGroyne( null, start, 0 ) }.ToList() ); |
|
|
|
for ( int level = 70; level <= Groynes.Keys.Max(); level += 70 ) |
|
|
|
{ |
|
|
|
List<TimedGroyne> subTimes = new List<TimedGroyne>(); |
|
|
|
List<TimedGroyne> passables = times[ level - 70 ].Where( time => time.Groyne.canPass( dog ) ).ToList(); |
|
|
|
foreach ( Groyne groyne in Groynes[ level ] ) |
|
|
|
{ |
|
|
|
List<TimedGroyne> possibleTimes = passables.Select( passable => new TimedGroyne( passable, groyne, passable.TotalTime + groyne.requiredTimeTo( passable.Groyne, dog ) ) ).ToList(); |
|
|
|
subTimes.Add( possibleTimes.OrderBy( time => time.TotalTime ).First() ); |
|
|
|
} |
|
|
|
times.Add( level, subTimes ); |
|
|
|
} |
|
|
|
return times[ 3 ].OrderBy( time => time.TotalTime ).First(); |
|
|
|
} |
|
|
|
/** |
|
|
|
* <summary>returns a dictionary with groynes and the fastest times the give dog is able to reach them</summary> |
|
|
|
* <param name="dog">dog that is running to the groynes</param> |
|
|
|
*/ |
|
|
|
|
|
|
|
public Dictionary<double, List<TimedGroyne>> listFastestTimes( Dog dog ) |
|
|
|
{ |
|
|
|
@@ -90,10 +56,10 @@ namespace Buhnenrennen |
|
|
|
for ( int level = 70; level <= Groynes.Keys.Max(); level += 70 ) |
|
|
|
{ |
|
|
|
List<TimedGroyne> subTimes = new List<TimedGroyne>(); |
|
|
|
List<TimedGroyne> passables = times[ level - 70 ].Where( time => time.Groyne.canPass( dog ) ).ToList(); |
|
|
|
List<TimedGroyne> passables = times[ level - 70 ].Where( time => time.Groyne.CanPass( dog ) ).ToList(); |
|
|
|
foreach ( Groyne groyne in Groynes[ level ] ) |
|
|
|
{ |
|
|
|
List<TimedGroyne> possibleTimes = passables.Select( passable => new TimedGroyne( passable, groyne, passable.TotalTime + groyne.requiredTimeTo( passable.Groyne, dog ) ) ).ToList(); |
|
|
|
List<TimedGroyne> possibleTimes = passables.Select( passable => new TimedGroyne( passable, groyne, passable.TotalTime + groyne.RequiredTimeTo( passable.Groyne, dog ) ) ).ToList(); |
|
|
|
subTimes.Add( possibleTimes.OrderBy( time => time.TotalTime ).FirstOrDefault() ); |
|
|
|
} |
|
|
|
times.Add( level, subTimes ); |
|
|
|
@@ -101,6 +67,11 @@ namespace Buhnenrennen |
|
|
|
return times; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* <summary>returns the fastest route for {hunted} where {hunted} will always be faster than {hunter}</summary> |
|
|
|
* <param name="hunted">The dog, which will be hunted and is not to be catched ( Minnie )</param> |
|
|
|
* <param name="hunter">The dog, with the desire to hunt the {hunted} dog ( Max )</param> |
|
|
|
*/ |
|
|
|
public TimedGroyne getFastestSafeRoute( Dog hunter, Dog hunted ) |
|
|
|
{ |
|
|
|
var hunterMap = listFastestTimes( hunter ); |