private static IEnumerable <byte> GetNeighbors(LogarithmicGrid grid, int cellX, int cellY) { for (var x = cellX + 1; x < 4; x++) { if (grid[x, cellY] == 0) { continue; } yield return(grid[x, cellY]); break; } for (var y = cellY + 1; y < 4; y++) { if (grid[cellX, y] == 0) { continue; } yield return(grid[cellX, y]); break; } }
private static int EvaluateEmptyCells(LogarithmicGrid grid) { var ajacentCount = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 3; x++) { if (grid[x, y] != 0 && grid[x, y] == grid[x + 1, y]) { ajacentCount++; x++; } } } for (var x = 0; x < 4; x++) { for (var y = 0; y < 3; y++) { if (grid[x, y] != 0 && grid[x, y] == grid[x, y + 1]) { ajacentCount++; y++; } } } var emptyCount = grid.Flatten().Count(b => b == 0); return(ajacentCount + emptyCount); }
public static int GetAdjacentCellCount(LogarithmicGrid grid) { var adjacentCount = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 3; x++) { if (grid[x, y] != 0 && grid[x, y] == grid[x + 1, y]) { adjacentCount++; x++; } } } for (var x = 0; x < 4; x++) { for (var y = 0; y < 3; y++) { if (grid[x, y] != 0 && grid[x, y] == grid[x, y + 1]) { adjacentCount++; y++; } } } return(adjacentCount); }
public PlayerNode(LogarithmicGrid grid, SearchTree searchTree, int sum) : base(grid, searchTree, sum) { this.heuristicLazy = new Lazy <double>(() => this.SearchTree.Heuristic.Evaluate(this), false); this.possibleStatesLazy = new Lazy <IEnumerable <KeyValuePair <Move, LogarithmicGrid> > >(this.GetPossibleStates, false); this.gameOverLazy = new Lazy <bool>(this.GetGameOver, false); }
public static int GetAdjacentCellCount(LogarithmicGrid grid) { var adjacentCount = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 3; x++) { if (grid[x, y] != 0 && grid[x, y] == grid[x + 1, y]) { adjacentCount++; x++; } } } for (var x = 0; x < 4; x++) { for (var y = 0; y < 3; y++) { if (grid[x, y] != 0 && grid[x, y] == grid[x, y + 1]) { adjacentCount++; y++; } } } return adjacentCount; }
public static void TestMoves() { // Arrange var grid = new LogarithmicGrid(new[, ] { { 2, 2, 4, 4 }, { 0, 2, 2, 0 }, { 0, 2, 2, 2 }, { 2, 0, 0, 2 } }); var expectedLeft = new LogarithmicGrid(new[, ] { { 4, 8, 0, 0 }, { 4, 0, 0, 0 }, { 4, 2, 0, 0 }, { 4, 0, 0, 0 } }); var expectedRight = new LogarithmicGrid(new[, ] { { 0, 0, 4, 8 }, { 0, 0, 0, 4 }, { 0, 0, 2, 4 }, { 0, 0, 0, 4 } }); var expectedUp = new LogarithmicGrid(new[, ] { { 4, 4, 4, 4 }, { 0, 2, 4, 4 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }); var expectedDown = new LogarithmicGrid(new[, ] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 2, 4, 4 }, { 4, 4, 4, 4 } }); // Act var left = grid.MakeMove(Move.Left); var right = grid.MakeMove(Move.Right); var up = grid.MakeMove(Move.Up); var down = grid.MakeMove(Move.Down); // Assert Assert.StrictEqual(left, expectedLeft); Assert.StrictEqual(right, expectedRight); Assert.StrictEqual(up, expectedUp); Assert.StrictEqual(down, expectedDown); }
public static void TestMoves() { // Arrange var grid = new LogarithmicGrid(new[,] { { 2, 2, 4, 4 }, { 0, 2, 2, 0 }, { 0, 2, 2, 2 }, { 2, 0, 0, 2 } }); var expectedLeft = new LogarithmicGrid(new[,] { { 4, 8, 0, 0 }, { 4, 0, 0, 0 }, { 4, 2, 0, 0 }, { 4, 0, 0, 0 } }); var expectedRight = new LogarithmicGrid(new[,] { { 0, 0, 4, 8 }, { 0, 0, 0, 4 }, { 0, 0, 2, 4 }, { 0, 0, 0, 4 } }); var expectedUp = new LogarithmicGrid(new[,] { { 4, 4, 4, 4 }, { 0, 2, 4, 4 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }); var expectedDown = new LogarithmicGrid(new[,] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 2, 4, 4 }, { 4, 4, 4, 4 } }); // Act var left = grid.MakeMove(Move.Left); var right = grid.MakeMove(Move.Right); var up = grid.MakeMove(Move.Up); var down = grid.MakeMove(Move.Down); // Assert Assert.StrictEqual(left, expectedLeft); Assert.StrictEqual(right, expectedRight); Assert.StrictEqual(up, expectedUp); Assert.StrictEqual(down, expectedDown); }
public Agent(LogarithmicGrid startingGrid, ISearcherFactory searcherFactory, IHeuristic heuristic) { this.searcherFactory = searcherFactory; this.searchTree = new SearchTree(heuristic, startingGrid); this.Timings.Add(1, Duration.Zero); if (startingGrid.Flatten().Any(i => i == 2)) { this.Timings.Add(2, Duration.Zero); } }
private static long EvaluateGrid(LogarithmicGrid grid, long[,] heatMap) { long result = 0; for (var x = 0; x < 4; x++) { for (var y = 0; y < 4; y++) { result += TwoToThePower(grid[x, y] * 2) * heatMap[x, y]; } } return(result); }
public static int GetEmptyCellCount(LogarithmicGrid grid) { var emptyCount = 0; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { emptyCount += grid[x, y] == 0 ? 1 : 0; } } return(emptyCount); }
public static int GetEmptyCellCount(LogarithmicGrid grid) { var emptyCount = 0; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { emptyCount += grid[x, y] == 0 ? 1 : 0; } } return emptyCount; }
public static int GetSmoothness(LogarithmicGrid grid) { var smoothness = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 4; x++) { foreach (var neighbor in GetNeighbors(grid, x, y)) { smoothness = smoothness - Math.Abs(grid[x, y] - neighbor); } } } return smoothness; }
public static int GetSmoothness(LogarithmicGrid grid) { var smoothness = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 4; x++) { foreach (var neighbor in GetNeighbors(grid, x, y)) { smoothness = smoothness - Math.Abs(grid[x, y] - neighbor); } } } return(smoothness); }
public void MoveRoot(LogarithmicGrid newGrid) { this.rootNode = (PlayerNode)this.rootNode.Children.Values .SelectMany(cn => cn.Children) .First(pn => pn.Grid.Equals(newGrid)); var sum = this.rootNode.Sum; foreach (var lesserSum in this.knownPlayerNodesBySum.Keys.Where(k => k <= sum).ToArray()) { this.knownPlayerNodesBySum.Remove(lesserSum); } foreach (var lesserSum in this.knownComputerNodesBySum.Keys.Where(k => k < sum).ToArray()) { this.knownComputerNodesBySum.Remove(lesserSum); } }
private static LogarithmicGrid RunGameInConsole() { var logGrid = new LogarithmicGrid(new byte[4, 4]).AddRandomTile().AddRandomTile(); var agent = new Agent(logGrid, new ProbabilityLimitedExpectiMaxerFactory(), new OvolveHeuristic()); try { int counter = 0; while (true) { counter++; var startTime = SystemClock.Instance.Now; Console.WriteLine("Start next move calculation..."); var result = agent.MakeDecision(); var elapsed = SystemClock.Instance.Now - startTime; Console.Clear(); Console.WriteLine("End move calcualtion, time taken: {0}", elapsed.ToString("ss.fff", CultureInfo.InvariantCulture)); Console.WriteLine(); Console.WriteLine(result); PrintTimings(agent); logGrid = logGrid.MakeMove(result.BestMove).AddRandomTile(); agent.UpdateGrid(logGrid); } } catch (GameOverException) { Console.WriteLine("GAME OVER!"); } return(logGrid); }
private static LogarithmicGrid RunGameInConsole() { var logGrid = new LogarithmicGrid(new byte[4, 4]).AddRandomTile().AddRandomTile(); var agent = new Agent(logGrid, new ProbabilityLimitedExpectiMaxerFactory(), new OvolveHeuristic()); try { int counter = 0; while (true) { counter++; var startTime = SystemClock.Instance.Now; Console.WriteLine("Start next move calculation..."); var result = agent.MakeDecision(); var elapsed = SystemClock.Instance.Now - startTime; Console.Clear(); Console.WriteLine("End move calcualtion, time taken: {0}", elapsed.ToString("ss.fff", CultureInfo.InvariantCulture)); Console.WriteLine(); Console.WriteLine(result); PrintTimings(agent); logGrid = logGrid.MakeMove(result.BestMove).AddRandomTile(); agent.UpdateGrid(logGrid); } } catch (GameOverException) { Console.WriteLine("GAME OVER!"); } return logGrid; }
private static IEnumerable<byte> GetNeighbors(LogarithmicGrid grid, int cellX, int cellY) { for (var x = cellX + 1; x < 4; x++) { if (grid[x, cellY] == 0) { continue; } yield return grid[x, cellY]; break; } for (var y = cellY + 1; y < 4; y++) { if (grid[cellX, y] == 0) { continue; } yield return grid[cellX, y]; break; } }
public ComputerNode(LogarithmicGrid grid, SearchTree searchTree, int sum) : base(grid, searchTree, sum) { }
public void UpdateGrid(LogarithmicGrid grid) { this.History.Add(grid); this.searchTree.MoveRoot(grid); }
public static int GetMonotonicity(LogarithmicGrid grid) { var down = 0; var up = 0; for (var x = 0; x < 4; x++) { var current = 0; var next = current + 1; while (next < 4) { while (next < 4 && grid[x, next] == 0) { next++; } if (next >= 4) { next--; } var currentValue = grid[x, current]; var nextValue = grid[x, next]; if (currentValue > nextValue) { down += nextValue - currentValue; } else if (nextValue > currentValue) { up += currentValue - nextValue; } current = next; next++; } } var right = 0; var left = 0; for (var y = 0; y < 4; y++) { var current = 0; var next = current + 1; while (next < 4) { while (next < 4 && grid[next, y] == 0) { next++; } if (next >= 4) { next--; } var currentValue = grid[current, y]; var nextValue = grid[next, y]; if (currentValue > nextValue) { right += nextValue - currentValue; } else if (nextValue > currentValue) { left += currentValue - nextValue; } current = next; next++; } } return Math.Max(up, down) + Math.Max(left, right); }
public static int GetMonotonicity(LogarithmicGrid grid) { var down = 0; var up = 0; for (var x = 0; x < 4; x++) { var current = 0; var next = current + 1; while (next < 4) { while (next < 4 && grid[x, next] == 0) { next++; } if (next >= 4) { next--; } var currentValue = grid[x, current]; var nextValue = grid[x, next]; if (currentValue > nextValue) { down += nextValue - currentValue; } else if (nextValue > currentValue) { up += currentValue - nextValue; } current = next; next++; } } var right = 0; var left = 0; for (var y = 0; y < 4; y++) { var current = 0; var next = current + 1; while (next < 4) { while (next < 4 && grid[next, y] == 0) { next++; } if (next >= 4) { next--; } var currentValue = grid[current, y]; var nextValue = grid[next, y]; if (currentValue > nextValue) { right += nextValue - currentValue; } else if (nextValue > currentValue) { left += currentValue - nextValue; } current = next; next++; } } return(Math.Max(up, down) + Math.Max(left, right)); }
private static int EvaluateEmptyCells(LogarithmicGrid grid) { var ajacentCount = 0; for (var y = 0; y < 4; y++) { for (var x = 0; x < 3; x++) { if (grid[x, y] != 0 && grid[x, y] == grid[x + 1, y]) { ajacentCount++; x++; } } } for (var x = 0; x < 4; x++) { for (var y = 0; y < 3; y++) { if (grid[x, y] != 0 && grid[x, y] == grid[x, y + 1]) { ajacentCount++; y++; } } } var emptyCount = grid.Flatten().Count(b => b == 0); return ajacentCount + emptyCount; }
private static long EvaluateGrid(LogarithmicGrid grid, long[,] heatMap) { long result = 0; for (var x = 0; x < 4; x++) { for (var y = 0; y < 4; y++) { result += TwoToThePower(grid[x, y] * 2) * heatMap[x, y]; } } return result; }
public PlayerNode(LogarithmicGrid grid, SearchTree searchTree, int sum) : base(grid, searchTree, sum) { this.heuristicLazy = new Lazy<double>(() => this.SearchTree.Heuristic.Evaluate(this), false); this.possibleStatesLazy = new Lazy<IEnumerable<KeyValuePair<Move, LogarithmicGrid>>>(this.GetPossibleStates, false); this.gameOverLazy = new Lazy<bool>(this.GetGameOver, false); }
protected Node(LogarithmicGrid grid, SearchTree searchTree, int sum) { this.Grid = grid; this.SearchTree = searchTree; this.Sum = sum; }
public SearchTree(IHeuristic heuristic, LogarithmicGrid startingGrid) { this.Heuristic = heuristic; this.rootNode = new PlayerNode(startingGrid, this, startingGrid.Sum()); }
public TraverseBenchmark() { var rootGrid = LogarithmicGrid.Parse(StartgingNode); this.searchTree = new SearchTree(null, rootGrid); }