private Map Update(Map old) { CopyFrom(old); // Map update loop for(int i = 0; i < this.M; i++) { for(int j = 0; j < this.N; j++) { var x = j; var y = i; // Console.Error.WriteLine("{0}x{1} Processing ({2};{3})", M, N, x, y); if((old[x, y] == Item.Rock) && ((y - 1) >= 0) && (old[x,y - 1] == Item.Empty)) { this[x,y] = Item.Empty; this[x,y - 1] = Item.Rock; } else if((old[x, y] == Item.Rock) && ((y-1) >= 0) && (x+1 < old.N) && (old[x, y-1] == Item.Rock) && (old[x+1,y] == Item.Empty) && (old[x+1,y-1] == Item.Empty)) { this[x,y] = Item.Empty; this[x+1, y-1] = Item.Rock; } else if((old[x, y] == Item.Rock) && ((y-1) >= 0) && (x-1 >= 0) && ((y+1) < old.M) && ((x+1) < old.N) && (old[x, y-1] == Item.Rock) && ((old[x+1,y] != Item.Empty) || (old[x+1,y-1] != Item.Empty)) && (old[x-1,y] == Item.Empty) && (old[x-1,y-1] == Item.Empty)) { this[x,y] = Item.Empty; this[x-1, y-1] = Item.Rock; } else if((old[x, y] == Item.Rock) && ((y-1) >= 0) && (old[x, y-1] == Item.Lambda) && ((x+1) < old.N) && (old[x+1,y] == Item.Empty) && (old[x+1,y-1] == Item.Empty)) { this[x,y] = Item.Empty; this[x+1, y-1] = Item.Rock; } else if((old[x,y] == Item.ClosedLift) && (old.LambdasLeft == 0)) { this[x,y] = Item.OpenLift; } else { this[x,y] = old[x,y]; } } } // Check 'Death' conditions if(((old.Y+1) < old.M) && (old[X, Y+1] != Item.Rock) && (this[X, Y+1] == Item.Rock)) { this.State = RobotState.Smashed; } if(old.TurnsUnderWater > old.Waterproof) { this.State = RobotState.Sank; // Она утонула. (с) ВВП } // Rise water! if((old.Flooding != 0) && (TurnNumber % Flooding == 0)) { Water++; } // Console.Error.WriteLine("Turn done. Score: {0}", this.Score); return this; }
public Map Clone() { var other = new Map(M, N); other.CopyFrom(this); Array.Copy(state, 0, other.state, 0, state.Length); return other; }
private Map CopyFrom(Map other) { X = other.X; Y = other.Y; Score = other.Score; LambdasLeft = other.LambdasLeft; LambdasCollected = other.LambdasCollected; Water = other.Water; Flooding = other.Flooding; Waterproof = other.Waterproof; State = other.State; TurnsUnderWater = other.TurnsUnderWater; TurnNumber = other.TurnNumber; foreach(var record in other.LinkedOutPoints) { LinkedOutPoints[record.Key] = record.Value; } return this; }
public static Map Read(TextReader src) { var lineMap = new List<string>(); var m = 0; var n = 0; while(src.Peek() >= 0) { var nextLine = src.ReadLine(); if(nextLine == "") { break; // End of map loading, only metadata left } n = Math.Max(n, nextLine.Length); lineMap.Add(nextLine); m++; } var retVal = new Map(m,n); for(var i = 0; i < m; i++) { for(var j = 0; j < n; j++) { retVal.state[i,j] = Item.Empty; } } var inOutMap = new Dictionary<Item, Point>(); for(var i = lineMap.Count - 1; i >= 0; i--) { var line = lineMap[i]; for(var j = 0; j < line.Length; j++) { var x = j; var y = lineMap.Count - 1 - i; var item = (Item)(line[j]); retVal[x,y] = item; if(item == Item.Robot) { retVal.X = x; retVal.Y = y; } else if(item == Item.Lambda) { retVal.LambdasLeft++; } else if(item.IsIn() || item.IsOut()) { inOutMap[item] = new Point(x, y); } } } // Now read the metadata while(src.Peek() >= 0) { var dataStr = src.ReadLine(); var data = dataStr.Split(' ', '\t'); if(data[0] == "Water ") { // Console.Error.WriteLine("Water tag found!"); retVal.Water = int.Parse(data[1]); continue; } else if(data[0] == "Flooding ") { // Console.Error.WriteLine("Flooding tag found!"); retVal.Flooding = int.Parse(data[1]); continue; } else if(data[0] == "Waterproof") { // Console.Error.WriteLine("Waterproof tag found!"); retVal.Waterproof = int.Parse(data[1]); continue; } else if(data[0] == "Trampoline") { var inp = (Item)data[1][0]; var inPoint = inOutMap[inp]; var outp = (Item)data[3][0]; var outPoint = inOutMap[outp]; retVal.LinkedOutPoints[inp] = new KeyValuePair<Point, List<Point>>(inOutMap[outp], new List<Point>( new [] { inOutMap[inp], } )); foreach(var regInp in retVal.LinkedOutPoints) { if(regInp.Key == inp) continue; // Skip self; if(regInp.Value.Key == outPoint) { regInp.Value.Value.Add(inPoint); retVal.LinkedOutPoints[inp].Value.Add(inOutMap[regInp.Key]); } } } } Map.first = retVal; Map.second = retVal.Clone(); System.GC.Collect(0); // SPIKE! return retVal; }