コード例 #1
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
 public void TestMixed()
 {
     var game = new Game();
     game.SetNumber(3, 1, 2);
     game.SetNumber(3, 2, 2);
     game.SetNumber(3, 3, 4);
     var res = game.Update(Direction.Up);
     Assert.AreEqual<uint>(2, game.GetNumber(0, 1));
     Assert.AreEqual<uint>(2, game.GetNumber(0, 2));
     Assert.AreEqual<uint>(4, game.GetNumber(0, 3));
     Assert.AreEqual(new Coordinate(0, 1), game.Transformations[3, 1].Destination);
     Assert.AreEqual(new Coordinate(0, 2), game.Transformations[3, 2].Destination);
     Assert.AreEqual(new Coordinate(0, 3), game.Transformations[3, 3].Destination);
     Assert.AreEqual(-1, game.Smoothness());
     Assert.AreEqual(1, game.Coherence());
     Assert.AreEqual<uint>(0, res.MergedCount);
     res = game.Update(Direction.Right);
     Assert.AreEqual<uint>(0, game.GetNumber(0, 1));
     Assert.AreEqual<uint>(4, game.GetNumber(0, 2));
     Assert.AreEqual<uint>(4, game.GetNumber(0, 3));
     Assert.AreEqual<uint>(1, res.MergedCount);
     Assert.AreEqual(new Coordinate(0, 2), game.Transformations[0, 1].Destination);
     Assert.AreEqual(true, game.Transformations[0, 2].WasNew);
     Assert.AreEqual(1, game.Coherence());
     res = game.Update(Direction.Left);
     Assert.AreEqual<uint>(8, game.GetNumber(0, 0));
     Assert.AreEqual<uint>(0, game.GetNumber(0, 2));
     Assert.AreEqual<uint>(0, game.GetNumber(0, 3));
     Assert.AreEqual(new Coordinate(0, 0), game.Transformations[0, 2].Destination);
     Assert.AreEqual(true, game.Transformations[0, 0].WasNew);
     Assert.AreEqual<uint>(1, res.MergedCount);
 }
コード例 #2
0
ファイル: Game.cs プロジェクト: LYP951018/FunnyThings
        public int Coherence()
        {
            var directions = new Direction[] { Direction.Up, Direction.Left, Direction.Right, Direction.Down };
            var game       = new Game(this);
            int ret        = int.MinValue;

            foreach (var direction in directions)
            {
                ret = Math.Max((int)game.Update(direction).MergedCount, ret);
                for (int i = 0; i < 4; ++i)
                {
                    for (int j = 0; j < 4; ++j)
                    {
                        game.AddCellTrivial(i, j, _numbers[i, j]);
                    }
                }
            }
            return(ret);
        }
コード例 #3
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
 public void TestMoveRightTrivial()
 {
     var game = new Game();
     game.SetNumber(1, 0, 2);
     game.Update(Direction.Right);
     Assert.AreEqual<uint>(2, game.GetNumber(1, 3));
     Assert.AreEqual<uint>(0, game.GetNumber(1, 1));
     Assert.AreEqual<uint>(0, game.GetNumber(1, 2));
 }
コード例 #4
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
 public void TestMoveRightRight()
 {
     var game = new Game();
     game.SetNumber(1, 3, 4);
     game.Update(Direction.Right);
     Assert.AreEqual<uint>(4, game.GetNumber(1, 3));
     Assert.AreEqual<uint>(0, game.GetNumber(1, 2));
     Assert.AreEqual<uint>(0, game.GetNumber(1, 1));
     foreach (var trans in game.Transformations)
         Assert.AreEqual(Coordinate.Nowhere, trans.Destination);
 }
コード例 #5
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
        public void TestMoveRightMulti()
        {
            var game = new Game();
            game.SetNumber(1, 0, 2);
            game.SetNumber(1, 1, 2);
            game.SetNumber(1, 2, 4);
            game.Update(Direction.Right);
            Assert.AreEqual<uint>(0, game.GetNumber(1, 0));
            Assert.AreEqual<uint>(0, game.GetNumber(1, 1));
            Assert.AreEqual<uint>(4, game.GetNumber(1, 2));
            Assert.AreEqual<uint>(4, game.GetNumber(1, 3));
            var info = game.Transformations[1, 0];
            Assert.AreEqual(new Coordinate(1, 2), info.Destination);
            Assert.AreEqual<uint>(2, info.PreviousNumber);
            info = game.Transformations[1, 2];
            Assert.AreEqual(true, info.WasNew);

            game.Update(Direction.Right);
            Assert.AreEqual<uint>(0, game.GetNumber(1, 0));
            Assert.AreEqual<uint>(0, game.GetNumber(1, 1));
            Assert.AreEqual<uint>(0, game.GetNumber(1, 2));
            Assert.AreEqual<uint>(8, game.GetNumber(1, 3));
        }
コード例 #6
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
        public void TestMoveDownMulti()
        {
            var game = new Game();
            game.SetNumber(1, 0, 4);
            game.SetNumber(2, 0, 2);
            game.SetNumber(3, 0, 2);
            game.Update(Direction.Down);
            Assert.AreEqual<uint>(0, game.GetNumber(1, 0));
            Assert.AreEqual<uint>(4, game.GetNumber(2, 0));
            Assert.AreEqual<uint>(4, game.GetNumber(3, 0));
            var info = game.Transformations[1, 0];
            Assert.AreEqual(new Coordinate(2, 0), info.Destination);
            Assert.AreEqual<uint>(4, info.PreviousNumber);
            info = game.Transformations[3, 0];
            Assert.AreEqual(true, info.WasNew);

            game.Update(Direction.Down);
            Assert.AreEqual<uint>(0, game.GetNumber(1, 0));
            Assert.AreEqual<uint>(0, game.GetNumber(2, 0));
            Assert.AreEqual<uint>(8, game.GetNumber(3, 0));
            info = game.Transformations[2, 0];
            Assert.AreEqual(new Coordinate(3, 0), info.Destination);
            Assert.AreEqual<uint>(4, info.PreviousNumber);
            info = game.Transformations[3, 0];
            Assert.AreEqual(true, info.WasNew);
        }
コード例 #7
0
ファイル: UnitTest1.cs プロジェクト: LYP951018/FunnyThings
 public void TestMoveDownBottom()
 {
     var game = new Game();
     game.SetNumber(3, 0, 4);
     game.Update(Direction.Down);
     Assert.AreEqual<uint>(4, game.GetNumber(3, 0));
     Assert.AreEqual<uint>(0, game.GetNumber(1, 0));
     Assert.AreEqual<uint>(0, game.GetNumber(2, 0));
     foreach (var trans in game.Transformations)
         Assert.AreEqual(Coordinate.Nowhere, trans.Destination);
 }
コード例 #8
0
ファイル: Game.cs プロジェクト: LYP951018/FunnyThings
 public int Coherence()
 {
     var directions = new Direction[] { Direction.Up, Direction.Left, Direction.Right, Direction.Down };
     var game = new Game(this);
     int ret = int.MinValue;
     foreach (var direction in directions)
     {
         ret = Math.Max((int)game.Update(direction).MergedCount, ret);
         for (int i = 0; i < 4; ++i)
             for (int j = 0; j < 4; ++j)
                 game.AddCellTrivial(i, j, _numbers[i, j]);
     }
     return ret;
 }
コード例 #9
0
ファイル: GameAI.cs プロジェクト: LYP951018/FunnyThings
        //static Dictionary<Game, SearchResultInfo> _games = new Dictionary<Game, SearchResultInfo>();
        public static unsafe SearchResultInfo Search(uint depth, bool isMax, Game theGame, int alpha, int beta)
        {
            Game.Logger($"-----------------Start searching depth = {depth} alpha = {alpha}------------------");
            theGame.LogGrid();
            if (isMax)
            {
                if (depth == 0)
                {
                    Game.Logger($"Depth = 0, score : {Evaluate(theGame, depth)}");
                    return new SearchResultInfo
                    {
                        Score = Evaluate(theGame, depth)
                    };
                }
                var newGame = new Game(theGame);
                Direction? bestMove = null;
                foreach (var direction in Directions)
                {
                    Game.Logger($"Searching {direction}");
                    //var game = new Game(theGame);
                    var res = newGame.Update(direction);
                    if (res.HasMoved)
                    {
                        if (res.HasWon)
                            return new SearchResultInfo
                            {
                                Score = int.MaxValue,
                                MoveDirection = direction
                            };
                        else
                        {
                            Game.Logger("Searching down by max.");
                            var result = Search(depth - 1, false, newGame, alpha, beta);
                            if (result.Score > alpha)
                            {
                                bestMove = direction;
                                alpha = result.Score;
                                if (alpha >= beta)
                                    break;
                            }
                        }
                    }
                    newGame.Reset(theGame);
                }
                Game.Logger($"result = {alpha} {bestMove}");
                return new SearchResultInfo
                {
                    Score = alpha,
                    MoveDirection = bestMove
                };
            }
            else
            {
                var bitmap = theGame.GetBitmap();
                var ptr = stackalloc int[48];
                var cellScores = new StaticList(ptr);
                var emptyCells = new StaticList(ptr + 16);
                int lowestScore = int.MaxValue;
                for (int i = 0; i < 16; ++i)
                {
                    ushort mask = (ushort)(1 << i);
                    if((bitmap & mask) == 0)
                    {
                        var x = i / 4;
                        var y = i % 4;
                        theGame.AddCellTrivial(x, y, 1);
                        var score = theGame.Smoothness() - theGame.Dispersion();
                        Game.Logger($"Add cell at {x}, {y} gets score {score}, Smooth = {theGame.Smoothness()}, Monotonic = {theGame.Monotonicity()} Dispersion = {theGame.Dispersion()}");
                        theGame.LogGrid();
                        cellScores.Add(score);
                        lowestScore = Math.Min(score, lowestScore);
                        theGame.RemoveCellTrivial(x, y);
                        emptyCells.Add(i);
                    }
                }

                var lowestCells = new StaticList(ptr + 32);
                for (int i = 0; i < emptyCells.Count; ++i)
                {
                    if (cellScores[i] == lowestScore)
                        lowestCells.Add(emptyCells[i]);
                }
                for(int i = 0; i < lowestCells.Count; ++i)
                {
                    var cell = lowestCells[i];
                    Game.Logger($"Add cell at {cell}, score is {lowestScore}");
                    var x = cell / 4;
                    var y = cell % 4;
                    theGame.AddCellTrivial(x, y, 1);
                    Game.Logger("Searching down by min.");
                    var result = Search(depth, true, theGame, alpha, beta);
                    theGame.RemoveCellTrivial(x, y);
                    if (result.Score < beta)
                    {
                        beta = result.Score;
                        Game.Logger($"Beta updated {beta}");
                        if (alpha >= beta)
                        {
                            Game.Logger("Cutoff");
                            break;
                        }
                    }
                }
                return new SearchResultInfo
                {
                    Score = beta,
                    MoveDirection = null
                };
            }
        }