示例#1
0
        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;
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
 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);
 }
示例#5
0
        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;
        }
示例#6
0
        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);
        }
示例#8
0
        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);
            }
        }
示例#9
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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;
        }
示例#12
0
        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;
        }
示例#13
0
        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);
        }
示例#14
0
        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);
            }
        }
示例#15
0
        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);
            }
        }
示例#16
0
        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);
        }
示例#17
0
        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;
        }
示例#18
0
        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;
            }
        }
示例#19
0
 public ComputerNode(LogarithmicGrid grid, SearchTree searchTree, int sum)
     : base(grid, searchTree, sum)
 {
 }
示例#20
0
 public void UpdateGrid(LogarithmicGrid grid)
 {
     this.History.Add(grid);
     this.searchTree.MoveRoot(grid);
 }
示例#21
0
        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);
        }
示例#22
0
        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));
        }
示例#23
0
        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;
        }
示例#24
0
        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;
        }
示例#25
0
 public ComputerNode(LogarithmicGrid grid, SearchTree searchTree, int sum)
     : base(grid, searchTree, sum)
 {
 }
示例#26
0
 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);
 }
示例#27
0
 protected Node(LogarithmicGrid grid, SearchTree searchTree, int sum)
 {
     this.Grid       = grid;
     this.SearchTree = searchTree;
     this.Sum        = sum;
 }
示例#28
0
 public SearchTree(IHeuristic heuristic, LogarithmicGrid startingGrid)
 {
     this.Heuristic = heuristic;
     this.rootNode = new PlayerNode(startingGrid, this, startingGrid.Sum());
 }
示例#29
0
 public SearchTree(IHeuristic heuristic, LogarithmicGrid startingGrid)
 {
     this.Heuristic = heuristic;
     this.rootNode  = new PlayerNode(startingGrid, this, startingGrid.Sum());
 }
示例#30
0
 protected Node(LogarithmicGrid grid, SearchTree searchTree, int sum)
 {
     this.Grid = grid;
     this.SearchTree = searchTree;
     this.Sum = sum;
 }
示例#31
0
        public TraverseBenchmark()
        {
            var rootGrid = LogarithmicGrid.Parse(StartgingNode);

            this.searchTree = new SearchTree(null, rootGrid);
        }