Bläddra i källkod

added method for parsing groyne entries in Field

application is now able to select and parse files to Field-Objects
feature-parse-setup-files
benjamin.m 5 år sedan
förälder
incheckning
adb4717ff3

+ 1
- 0
.gitignore Visa fil

@@ -1,2 +1,3 @@
.vs
obj
bin

+ 6
- 9
Buhnenrennen/Dog.cs Visa fil

@@ -12,19 +12,16 @@ namespace Buhnenrennen
public static readonly Dog MINNIE = new Dog( 'M', new char[] { 'm', 'x', 'M' }, 20 );
public static readonly Dog MAX = new Dog( 'X', new char[] { 'x', 'X' }, 30 );

private char[] fitsThrough;
public char[] FitsThrough => this.fitsThrough;
private double meterPerSecond;
public double MeterPerSecond => this.meterPerSecond;
private char start;
public char Start => this.start;
public char[] FitsThrough { get; private set; }
public double MeterPerSecond { get; private set; }
public char Start { get; private set; }

private Dog( char start, char[] fitsThrough, double kmh )
{
this.start = start;
this.fitsThrough = fitsThrough;
Start = start;
FitsThrough = fitsThrough;
// km/h : 3,6 = m/s ( Formula found through google )
this.meterPerSecond = kmh / 3.6;
MeterPerSecond = kmh / 3.6;
}
}
}

+ 37
- 21
Buhnenrennen/Field.cs Visa fil

@@ -1,37 +1,53 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Buhnenrennen
{
class Field
{
private Dictionary<double, List<Groyne>> groynes;
public Dictionary<double, List<Groyne>> Groynes => this.groynes;
public Dictionary<double, List<Groyne>> Groynes { get; private set; }

public Field( Groyne[] level0, Groyne[] level1, Groyne[] level2, Groyne[] level3 )
Regex groynSchema = new Regex( "(?<type>[A-Z]) (?<level>[0-9]+) (?<yCoord>[0-9\\.]+)", RegexOptions.IgnoreCase );

private Field( IEnumerable<string> groynes )
{
Groynes = new Dictionary<double, List<Groyne>>();
Match m;
foreach( string groyn in groynes )
{
if ( ( m = groynSchema.Match( groyn ) ).Success )
{
char type = m.Groups[ "type" ].Value.FirstOrDefault();
// Forcing a multiple of 70 by using '/ 70 * 70'
int level = int.Parse( m.Groups[ "level" ].Value ) / 70 * 70;
double yCoord = double.Parse( m.Groups[ "yCoord" ].Value );
if ( !this.Groynes.ContainsKey( level ) ) this.Groynes.Add( level, new List<Groyne>() );
this.Groynes[ level ].Add( new Groyne( yCoord, type ) );
}
}
}

public static Field fromFile( string filename )
{
groynes = new Dictionary<double, List<Groyne>>();
groynes.Add( 0, level0.ToList() );
groynes.Add( 70, level1.ToList() );
groynes.Add( 140, level2.ToList() );
groynes.Add( 210, level3.ToList() );
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 );
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 )
for( int level = 70; level <= Groynes.Keys.Max(); level += 70 )
{
List<Groyne> candidates = groynes[ level ].Where( groyne => groyne.canPass( dog ) ).ToList();
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 ) ];
@@ -43,17 +59,17 @@ namespace Buhnenrennen

public TimedGroyne findFastestPath( Dog dog )
{
Groyne start = groynes[ 0 ].Find( groyne => groyne.Type == dog.Start );
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 )
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 ] )
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() );
@@ -65,17 +81,17 @@ namespace Buhnenrennen

public Dictionary<double, List<TimedGroyne>> listFastestTimes( Dog dog )
{
Groyne start = groynes[ 0 ].Find( groyne => groyne.Type == dog.Start );
Groyne start = Groynes[ 0 ].Find( groyne => groyne.Type == dog.Start );
if ( start == null ) throw new Exception( "No start position found" );

Groyne lastLevel = start;
Dictionary<double, List<TimedGroyne>> times = new Dictionary<double, List<TimedGroyne>>();
times.Add( 0, new TimedGroyne[] { new TimedGroyne( null, start, 0 ) }.ToList() );
for ( int level = 70; level <= groynes.Keys.Max(); level += 70 )
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 ] )
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 ).FirstOrDefault() );
@@ -91,9 +107,9 @@ namespace Buhnenrennen
var huntedMap = listFastestTimes( hunted );

List<Groyne> safeGroynes = new List<Groyne>();
safeGroynes.Add( groynes[ 0 ].Find( groyne => groyne.Type == hunted.Start ) );
safeGroynes.Add( Groynes[ 0 ].Find( groyne => groyne.Type == hunted.Start ) );

for ( int level = 70; level <= groynes.Keys.Max(); level += 70 )
for ( int level = 70; level <= Groynes.Keys.Max(); level += 70 )
{
var huntedTimes = huntedMap[ level ];
var hunterTimes = hunterMap[ level ];
@@ -106,7 +122,7 @@ namespace Buhnenrennen
}
}

return huntedMap[ groynes.Keys.Max() ].Where( huntedRoute => safeGroynes.Contains( huntedRoute.Groyne ) ).OrderBy( huntedRoute => huntedRoute.TotalTime ).FirstOrDefault();
return huntedMap[ Groynes.Keys.Max() ].Where( huntedRoute => safeGroynes.Contains( huntedRoute.Groyne ) ).OrderBy( huntedRoute => huntedRoute.TotalTime ).FirstOrDefault();
}
}
}

+ 4
- 6
Buhnenrennen/Groyne.cs Visa fil

@@ -8,15 +8,13 @@ namespace Buhnenrennen
{
class Groyne
{
private double yCoord;
public double YCoord => this.yCoord;
private char type;
public char Type => this.type;
public double YCoord { get; private set; }
public char Type { get; private set; }

public Groyne( double yCoord, char type )
{
this.yCoord = yCoord;
this.type = type;
this.YCoord = yCoord;
this.Type = type;
}

public bool canPass( Dog dog ) => dog.FitsThrough.Contains( Type );

+ 40
- 22
Buhnenrennen/GroyneRun.cs Visa fil

@@ -1,37 +1,55 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Buhnenrennen
{
class GroyneRun
{
public void Start()
Regex setupFileRegex = new Regex( "^buhnenrennen(?<number>[0-9]+).txt$", RegexOptions.IgnoreCase );
Regex intFormatRegex = new Regex( "^[0-9]+$", RegexOptions.IgnoreCase );
private Field selectField()
{
Field field = new Field(
new Groyne[] {
new Groyne( 42.95, 'M' ),
new Groyne( 168.6, 'X' )
},
new Groyne[] {
new Groyne( 76.4, 'm' ),
new Groyne( 45.9, 'x' ),
new Groyne( 117.4, 'm' )
},
new Groyne[] {
new Groyne( 42.2, 'm' ),
new Groyne( 109.35, 'm' ),
new Groyne( 158.7, 'x' )
},
new Groyne[] {
new Groyne( 49.4, 'm' ),
new Groyne( 83.1, 'm' ),
new Groyne( 148.7, 'x' ),
new Groyne( 103.5 , 'x' )
var filenumbers_int = Directory.GetFiles( "setups", "buhnenrennen*.txt" )
.Select( Path.GetFileName )
.Where( file => setupFileRegex.IsMatch( file ) )
.Select( file => int.Parse( setupFileRegex.Match( file ).Groups[ "number" ].Value ) ).ToList();
filenumbers_int.Sort();
List<string> filenumbers = filenumbers_int.Select( filenumber => filenumber.ToString() ).ToList();
if ( filenumbers.Count <= 0 ) return null;
Console.WriteLine( "Es wurden Setup-Dateien mit den folgenden Nummern gefunden:" );
Console.WriteLine( "\t" + string.Join( ", ", filenumbers ) );
Console.Write( "Bitte geben sie die Nummer des gewünschten Setups an ( " + filenumbers.FirstOrDefault() + " ): " );
string number = null;
do
{
if ( number != null ) Console.Write( "Der angegebene Wert ist keine Zahl, bitte versuche es erneut ( " + filenumbers.FirstOrDefault() + " ): " );
number = Console.ReadLine();
if ( string.IsNullOrWhiteSpace( number ) )
{
number = filenumbers.FirstOrDefault();
}
);
} while ( !intFormatRegex.IsMatch( number ) );


return Field.fromFile( "setups/buhnenrennen" + number + ".txt" );
}

public void Start()
{
Field field = selectField();
if ( field == null )
{
Console.WriteLine( "Es ist leider keine Setupdatei vorhanden. Bitte leg welche an und versuche es erneut." );
Console.ReadKey();
return;
}

TimedGroyne safePath = field.getFastestSafeRoute( Dog.MAX, Dog.MINNIE );


Binär
Buhnenrennen/bin/Debug/Buhnenrennen.exe Visa fil


+ 0
- 6
Buhnenrennen/bin/Debug/Buhnenrennen.exe.config Visa fil

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

Binär
Buhnenrennen/bin/Debug/Buhnenrennen.pdb Visa fil


Laddar…
Avbryt
Spara