public void HandleChanges(bool Dynamic, int StepNumber) { StaticState.Changes = new LinkedList <GenericGridWorldDynamicState>( ); Unit u = StaticState.InitialDynamicState.FindUnit(0); Step Changes = StaticState.Next(StepNumber); if (Changes != null && Changes.Changes != null) { foreach (Coord c in Changes.Changes) { if (StaticState.Tiles[c.Y][c.X] is PassableTile <GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if (!(u.X == c.X && u.Y == c.Y) || StaticState.Map.ChangeList.BlockOnAgent) { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } } else if (StaticState.Tiles[c.Y][c.X] is BlockedTile <GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if (StaticState.Tiles[c.Y][c.X].LastChoke) { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new ChokeTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } else { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new PassableTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } } else if (StaticState.Tiles[c.Y][c.X] is ChokeTile <GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if (!(u.X == c.X && u.Y == c.Y) || StaticState.Map.ChangeList.BlockOnAgent) { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; newTile.LastChoke = true; StaticState.Tiles[c.Y][c.X] = newTile; } } } } foreach (var row in StaticState.Tiles) { foreach (var t in row) { var tile = t; if (!tile.BeenExplored && tile.Visible(StaticState)) { tile.BeenExplored = true; } if (Dynamic) { bool isGoal = tile.X == u.DstX && tile.Y == u.DstY || tile.X == u.X && tile.Y == u.Y; ; if (!isGoal && tile is PassableTile <GenericGridWorldStaticState, GenericGridWorldDynamicState> && gen.Next( ) % ChangeChance == 0) { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( tile.X, tile.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = tile.LastPassable; newTile.BeenExplored = tile.BeenExplored; newTile.Hits = tile.Hits; tile = newTile; StaticState.Tiles[tile.Y][tile.X] = tile; } else if (!isGoal && tile is BlockedTile <GenericGridWorldStaticState, GenericGridWorldDynamicState> && gen.Next( ) % ChangeChance == 0) { Tile <GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new PassableTile <GenericGridWorldStaticState, GenericGridWorldDynamicState>( tile.X, tile.Y, StaticState.Height, StaticState.Width); newTile.LastPassable = tile.LastPassable; newTile.BeenExplored = tile.BeenExplored; newTile.Hits = tile.Hits; tile = newTile; StaticState.Tiles[tile.Y][tile.X] = tile; } } bool nowPassable = tile.IsPassable(StaticState, false); if (tile.LastPassable != nowPassable) { tile.LastPassable = nowPassable; var ds = new GenericGridWorldDynamicState( ); var ut = u.Clone( ) as Unit; ds.hash ^= ut.GetHashCode( ); ut.X = tile.X; ut.Y = tile.Y; ds.hash ^= ut.GetHashCode( ); ds.AddWorldObject(ut); StaticState.Changes.AddFirst(ds); } } } }
public void Make( int Seed, String Filename ) { System.Console.WriteLine( "Generating Map [{0}]", Filename ); Random Gen = new Random( Seed ); xml.Version = 1; xml.Date = DateTime.Now; xml.Generator = Generator.MAIDynamicRooms; xml.Seed = Seed; xml.LOS = LOS; xml.LOSSpecified = true; xml.Start = new Coord( ); xml.Goal = new Coord( ); if ( UseCorners ) { xml.Start.X = 0; xml.Start.Y = 0; xml.Goal.X = xml.Width - 1; xml.Goal.Y = xml.Height - 1; } else { double Dis; do { xml.Start.X = Gen.Next( xml.Width ); xml.Start.Y = Gen.Next( xml.Height ); xml.Goal.X = Gen.Next( xml.Width ); xml.Goal.Y = Gen.Next( xml.Height ); Dis = Distance.OctileDistance( xml.Start.X, xml.Goal.X, xml.Start.Y, xml.Goal.Y ); } while ( Dis < MinHDistance || Dis > MaxHDistance ); } GenericGridWorldDynamicState DS = new GenericGridWorldDynamicState( ); GenericGridWorldStaticState SS = new GenericGridWorldStaticState( xml.Height, xml.Width, DS ); DS.AddWorldObject( new Unit( xml.Start.X, xml.Start.Y, xml.Height, xml.Width, xml.Goal.X, xml.Goal.Y, LOS, 0 ) ); int RoomWidth = xml.Width / this.NumHorzRooms; int RoomHeight = xml.Height / this.NumVertRooms; bool[,] TilesBlocked = new bool[xml.Width, xml.Height]; for ( int Y = 0 ; Y < xml.Height ; Y++ ) { for ( int X = 0 ; X < xml.Width ; X++ ) { SS.Tiles[Y][X] = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); TilesBlocked[X, Y] = false; } } // Vert Walls for ( int Y = RoomHeight ; Y < xml.Height ; Y+=RoomHeight ) { for ( int X = 0 ; X < xml.Width ; X++ ) { if ( !( X == xml.Start.X && Y == xml.Start.Y ) && !( Y == xml.Goal.Y && X == xml.Goal.X ) ) { SS.Tiles[Y][X] = new BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); TilesBlocked[X, Y] = true; } } } // Horz Walls for ( int X = RoomWidth ; X < xml.Width ; X+=RoomWidth ) { for ( int Y = 0 ; Y < xml.Height ; Y++ ) { if ( !( X == xml.Start.X && Y == xml.Start.Y ) && !( Y == xml.Goal.Y && X == xml.Goal.X ) ) { SS.Tiles[Y][X] = new BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); TilesBlocked[X, Y] = true; } } } List<Door> Doors = new List<Door>( ); // Vert Doors for ( int Y = RoomHeight ; Y < xml.Height ; Y+=RoomHeight ) { for ( int X = RoomWidth/2 ; X < xml.Width ; X+=RoomWidth ) { if ( !( X == xml.Start.X && Y == xml.Start.Y ) && !( Y == xml.Goal.Y && X == xml.Goal.X ) ) { SS.Tiles[Y][X] = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); if ( ( X/RoomWidth ) % VertRoomModifier == 0 ) { Doors.Add( new Door( ) { Open = true, X = X, Y = Y } ); TilesBlocked[X, Y] = false; } } } } // Horz Doors for ( int X = RoomWidth ; X < xml.Width ; X+=RoomWidth ) { for ( int Y = RoomHeight/2 ; Y < xml.Height ; Y+=RoomHeight ) { if ( !( X == xml.Start.X && Y == xml.Start.Y ) && !( Y == xml.Goal.Y && X == xml.Goal.X ) ) { SS.Tiles[Y][X] = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); if ( ( Y/RoomHeight ) % HorzRoomModifier == 0 ) { Doors.Add( new Door( ) { Open = true, X = X, Y = Y } ); TilesBlocked[X, Y] = false; } } } } xml.Tiles = GridWorldFormat.ToTileString( SS, DS ); try { var sol = new AStar< GenericGridWorldStaticState, GenericGridWorldDynamicState>( new SingleUnitOctileDistanceHeuristic( ), true, null ) .Compute( SS, SS.InitialDynamicState, new DestinationsReachedGoal( ), GridWorldOperator.Ops ).First( ); xml.OptimalSolutionCost = sol.Cost.ToDouble( ); xml.OptimalSolutionCostSpecified = true; if ( !UseCorners && ( xml.OptimalSolutionCost < MinAStarDistance || xml.OptimalSolutionCost > MaxAStarDistance ) ) { throw new ChokepointGridWorldMaker.MapCreationFailed( ); } System.Console.WriteLine( "\tMap Generated Solution Cost [{0}]", sol.Cost ); } catch ( PathNotFoundException ) { System.Console.WriteLine( "\tMap Generation Failed [{0}]", Filename ); throw new ChokepointGridWorldMaker.MapCreationFailed( ); } List<Step> ChangeList = new List<Step>( ); Step step = new Step( ); int sN; List<Coord> Changes; List<Door> DoorChanges; // Add one for skipped. step.StepNum = 0; step.Changes = new Coord[] { }; ChangeList.Add( step ); for ( sN = 1 ; sN < NumSteps + 1; sN++ ) { step = new Step( ); step.StepNum = sN; do { Changes = new List<Coord>( ); DoorChanges = new List<Door>( ); foreach ( Door D in Doors ) { if ( D.Open ) { if ( Gen.NextDouble( ) < ChanceClose ) { D.Open = false; Changes.Add( new Coord( ) { X = D.X, Y = D.Y } ); DoorChanges.Add( D ); TilesBlocked[D.X, D.Y] = true; } } else { if ( Gen.NextDouble( ) < ChanceOpen ) { D.Open = true; Changes.Add( new Coord( ) { X = D.X, Y = D.Y } ); DoorChanges.Add( D ); TilesBlocked[D.X, D.Y] = false; } } } } while ( !ResolveReachability( DoorChanges, Changes, TilesBlocked, new Point( xml.Goal.X, xml.Goal.Y ), xml.Width, xml.Height ) ); step.Changes = Changes.ToArray( ); ChangeList.Insert( ChangeList.Count, step ); } // Add one more step to guarentee repeatablity. step = new Step( ); step.StepNum = sN; Changes = new List<Coord>( ); foreach ( Door D in Doors ) { if ( !D.Open ) { Changes.Add( new Coord( ) { X = D.X, Y = D.Y } ); } } step.Changes = Changes.ToArray( ); ChangeList.Insert( ChangeList.Count, step ); xml.ChangeList = new ChangeList( ); xml.ChangeList.Repeatable = true; xml.ChangeList.BlockOnAgent = false; xml.ChangeList.Steps = ChangeList.ToArray( ); System.Console.WriteLine( "\tMap Generated [{0}]", Filename ); XmlSerializer s = new XmlSerializer( typeof( Map ) ); TextWriter w = new StreamWriter( Filename ); s.Serialize( w, xml ); w.Close( ); }
public void HandleChanges( bool Dynamic, int StepNumber ) { StaticState.Changes = new LinkedList<GenericGridWorldDynamicState>( ); Unit u = StaticState.InitialDynamicState.FindUnit( 0 ); Step Changes = StaticState.Next( StepNumber ); if ( Changes != null && Changes.Changes != null ) { foreach ( Coord c in Changes.Changes ) { if ( StaticState.Tiles[c.Y][c.X] is PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if ( !( u.X == c.X && u.Y == c.Y ) || StaticState.Map.ChangeList.BlockOnAgent ) { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } } else if ( StaticState.Tiles[c.Y][c.X] is BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if ( StaticState.Tiles[c.Y][c.X].LastChoke ) { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new ChokeTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } else { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; StaticState.Tiles[c.Y][c.X] = newTile; } } else if ( StaticState.Tiles[c.Y][c.X] is ChokeTile<GenericGridWorldStaticState, GenericGridWorldDynamicState> ) { if ( !( u.X == c.X && u.Y == c.Y ) || StaticState.Map.ChangeList.BlockOnAgent ) { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( c.X, c.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = StaticState.Tiles[c.Y][c.X].LastPassable; newTile.BeenExplored = StaticState.Tiles[c.Y][c.X].BeenExplored; newTile.Hits = StaticState.Tiles[c.Y][c.X].Hits; newTile.LastChoke = true; StaticState.Tiles[c.Y][c.X] = newTile; } } } } foreach ( var row in StaticState.Tiles ) { foreach ( var t in row ) { var tile = t; if ( !tile.BeenExplored && tile.Visible( StaticState ) ) { tile.BeenExplored = true; } if ( Dynamic ) { bool isGoal = tile.X == u.DstX && tile.Y == u.DstY || tile.X == u.X && tile.Y == u.Y; ; if ( !isGoal && tile is PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState> && gen.Next( )%ChangeChance == 0 ) { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( tile.X, tile.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = tile.LastPassable; newTile.BeenExplored = tile.BeenExplored; newTile.Hits = tile.Hits; tile = newTile; StaticState.Tiles[tile.Y][tile.X] = tile; } else if ( !isGoal && tile is BlockedTile<GenericGridWorldStaticState, GenericGridWorldDynamicState> && gen.Next( )%ChangeChance == 0 ) { Tile<GenericGridWorldStaticState, GenericGridWorldDynamicState> newTile = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( tile.X, tile.Y, StaticState.Height, StaticState.Width ); newTile.LastPassable = tile.LastPassable; newTile.BeenExplored = tile.BeenExplored; newTile.Hits = tile.Hits; tile = newTile; StaticState.Tiles[tile.Y][tile.X] = tile; } } bool nowPassable = tile.IsPassable( StaticState, false ); if ( tile.LastPassable != nowPassable ) { tile.LastPassable = nowPassable; var ds = new GenericGridWorldDynamicState( ); var ut = u.Clone( ) as Unit; ds.hash ^= ut.GetHashCode( ); ut.X = tile.X; ut.Y = tile.Y; ds.hash ^= ut.GetHashCode( ); ds.AddWorldObject( ut ); StaticState.Changes.AddFirst( ds ); } } } }
public void Make( int Seed, String Filename ) { System.Console.WriteLine( "Generating Map [{0}]", Filename ); Random Gen = new Random( Seed ); xml.Version = 1; xml.Date = DateTime.Now; xml.Generator = Generator.MAIDynamicChokepoint; xml.Seed = Seed; xml.LOS = LOS; xml.Start = new Coord( ); xml.Start.X = Gen.Next( xml.Width ); xml.Start.Y = Gen.Next( xml.Height ); xml.Goal = new Coord( ); xml.Goal.X = Gen.Next( xml.Width ); xml.Goal.Y = Gen.Next( xml.Height ); GenericGridWorldDynamicState DS = new GenericGridWorldDynamicState( ); GenericGridWorldStaticState SS = new GenericGridWorldStaticState( xml.Height, xml.Width, DS ); DS.AddWorldObject( new Unit( xml.Start.X, xml.Start.Y, xml.Height, xml.Width, xml.Goal.X, xml.Goal.Y, LOS, 0 ) ); bool[][] tiles = new bool[xml.Height][]; for ( int i = 0 ; i < xml.Height ; i++ ) { tiles[i] = new bool[xml.Width]; } LinkedList<Point> ChokePoints = new LinkedList<Point>( ); for ( int i = 0 ; i < NumChokepoints ; i++ ) { ChokePoints.AddFirst( new Point( Gen.Next( xml.Width ), Gen.Next( xml.Height ) ) ); } for ( int Y = 0 ; Y < xml.Height ; Y++ ) { for ( int X = 0 ; X < xml.Width ; X++ ) { if ( ChokePoints.Any( cp => Distance.OctileDistance( cp.X, X, cp.Y, Y ) <= ChokepointRadius ) ) { SS.Tiles[Y][X] = new ChokeTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); tiles[Y][X] = false; } else { SS.Tiles[Y][X] = new PassableTile<GenericGridWorldStaticState, GenericGridWorldDynamicState>( X, Y, xml.Height, xml.Width ); tiles[Y][X] = false; } } } Point U = new Point( xml.Start.X, xml.Start.Y ); foreach ( var From in ChokePoints ) { foreach ( var To in ChokePoints ) { DrawLine( From, To, xml, SS, U, tiles ); } } xml.Tiles = GridWorldFormat.ToTileString( SS, DS ); try { var sol = new AStar< GenericGridWorldStaticState, GenericGridWorldDynamicState>( new SingleUnitOctileDistanceHeuristic( ), true, null ) .Compute( SS, SS.InitialDynamicState, new DestinationsReachedGoal( ), GridWorldOperator.Ops ).First( ); System.Console.WriteLine( "\tMap Generated Solution Cost [{0}]", sol.Cost ); } catch ( PathNotFoundException ) { System.Console.WriteLine( "\tMap Generation Failed [{0}]", Filename ); throw new MapCreationFailed( ); } LinkedList<Point> AgentsLocs = new LinkedList<Point>( ChokePoints.Take( NumAgents ) ); LinkedList<Agent> Agents = new LinkedList<Agent>( ); foreach ( Point Loc in AgentsLocs ) { Agents.AddFirst( new Agent( ) { Location = Loc, Dst = Loc, Start = Loc } ); } LinkedList<Step> ChangeList = new LinkedList<Step>( ); for ( int sN = 0 ; sN < NumSteps || !AllAtStart( Agents ) ; sN++ ) { Step step = new Step( ); step.StepNum = sN; List<Coord> Changes = new List<Coord>( ); if ( sN == 0 ) { foreach ( Agent Agent in Agents ) { ToogleCircle( tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height, Agent.Location, Agents, AgentRadius, false ); } } foreach ( Agent Agent in Agents ) { if ( sN < NumSteps && sN != 0 && Agent.Location.Equals( Agent.Dst ) && ( Gen.NextDouble( ) < MoveRate ) ) { var NotReserved = ChokePoints.Where( x => !Agents.Any( a => a.Dst.Equals( x ) ) ); if ( NotReserved.Count( ) > 0 ) { Agent.Dst = NotReserved.Skip( Gen.Next( NotReserved.Count( ) ) ).First( ); } } else if ( !( sN < NumSteps ) ) { Agent.Dst = Agent.Start; } if ( !Agent.Location.Equals( Agent.Dst ) ) { ToogleCircle( tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height, Agent.Location, Agents, AgentRadius, false ); Agent.Location = NextAll( Agent.Location, xml.Width, xml.Height, Agent.Dst ); ToogleCircle( tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height, Agent.Location, Agents, AgentRadius, false ); } } step.Changes = Optimize( Changes ).ToArray( ); ChangeList.AddLast( step ); } xml.ChangeList = new ChangeList( ); xml.ChangeList.Repeatable = true; xml.ChangeList.BlockOnAgent = true; xml.ChangeList.Steps = ChangeList.ToArray( ); System.Console.WriteLine( "\tMap Generated [{0}]", Filename ); XmlSerializer s = new XmlSerializer( typeof( Map ) ); TextWriter w = new StreamWriter( Filename ); s.Serialize( w, xml ); w.Close( ); }
/// <summary> /// Converts the GridWorld into a simple string representation. This /// is for debugging purposes. /// </summary> /// <param name="GridWorldStaticState">The static state to stringilize /// </param> /// <param name="GridWorldDynamicState">The dynamic state to stringilize /// and yes if you are wondering I just made that word up but I think /// it sounds really cool.</param> /// <returns>A string.</returns> public static string ToString( GenericGridWorldStaticState GridWorldStaticState, GenericGridWorldDynamicState GridWorldDynamicState) { System.Text.StringBuilder sb = new System.Text.StringBuilder( ); sb.Append( " " ); for ( int j = 0 ; j < GridWorldStaticState.Width ; j++ ) { sb.Append( j % 10 ); } sb.Append( "\r\n" ); for ( int i = 0 ; i < GridWorldStaticState.Tiles.Length ; i++ ) { sb.Append( i % 10 + " " ); foreach ( var x in GridWorldStaticState.Tiles[i] ) { sb.Append( GetAscii( x, GridWorldDynamicState. GetWorldObjects( ) ) ); } sb.Append( "\r\n" ); } return sb.ToString( ); }