예제 #1
0
        /// <summary>
        /// find next move by direct score
        /// </summary>
        /// <param name="x">current board</param>
        /// <returns>next move</returns>
        static public int DirectScoreMove(Board x)
        {
            double maxScore = 0;
            int    maxi     = -1;

            for (int k = 0; k < 4; k++)
            {
                if (BoardControl.ExecuteMove(x, k) == x)
                {
                    continue;
                }
                if (PreScore.DirectScore(BoardControl.ExecuteMove(x, k)) > maxScore)
                {
                    maxScore = PreScore.DirectScore(BoardControl.ExecuteMove(x, k));
                    maxi     = k;
                }
            }
            if (maxi == -1)
            {
                return(new Random(DateTime.Now.Millisecond).Next() % 4);
            }
            else
            {
                return(maxi);
            }
        }
예제 #2
0
        /// <summary>
        /// play game for monte carlo method
        /// </summary>
        /// <param name="Str">play strategy</param>
        /// <param name="board">current board</param>
        /// <param name="nmove">monte carlo steps</param>
        /// <param name="move">pre-pointed next step</param>
        /// <returns>score by monte carlo</returns>
        public static double MontePlay(Strategy Str, Board board, int nmove, int move = -1)
        {
            bool first = true;

            while (true)
            {
                UInt64 newboard;
                if (first && (move != -1))
                {
                    if (BoardControl.ExecuteMove(board, move) == board)
                    {
                        return(0);
                    }
                    first = false;
                }
                else
                {
                    for (move = 0; move < 4; move++)
                    {
                        if (BoardControl.ExecuteMove(board, move) != board)
                        {
                            break;
                        }
                    }
                    if (move == 4)
                    {
                        break;
                    }
                    move = Str(board);
                    if (move < 0)
                    {
                        break;
                    }
                }

                newboard = BoardControl.ExecuteMove(board, move);
                if (newboard == board)
                {
                    continue;
                }
                UInt64 tile = BoardControl.RandomTile();
                board = BoardControl.InsertTileRand(newboard, tile);
                nmove--;
                if (nmove <= 0)
                {
                    return(PreScore.DirectScore(board));
                }
            }
            return(0);
        }
예제 #3
0
        /// <summary>
        /// play game by pointed strategy
        /// </summary>
        /// <param name="Str">play strategy</param>
        public static void Play(Strategy Str)
        {
            Board board        = BoardControl.InitBoard();
            int   moveno       = 0;
            int   scorepenalty = 0;

            while (true)
            {
                int   move;
                Board newboard;

                for (move = 0; move < 4; move++)
                {
                    if (BoardControl.ExecuteMove(board, move) != board)
                    {
                        break;
                    }
                }
                if (move == 4)
                {
                    break;
                }
                BoardControl.Print(board);
                System.Console.WriteLine("Move:" + (++moveno).ToString() + ", score:" + (BoardControl.Score(board) - scorepenalty).ToString() + '\n');
                move = Str(board);
                if (move < 0)
                {
                    break;
                }
                newboard = BoardControl.ExecuteMove(board, move);
                if (newboard == board)
                {
                    System.Console.WriteLine("Illegal move!\n");
                    moveno--;
                    continue;
                }
                Board tile = BoardControl.RandomTile();
                if (tile == 2)
                {
                    scorepenalty += 4;
                }
                board = BoardControl.InsertTileRand(newboard, tile);
            }

            BoardControl.Print(board);
            System.Console.WriteLine("\nGame over.\nScore:" + (BoardControl.Score(board) - scorepenalty).ToString() + ".\n");
        }
예제 #4
0
        /// <summary>
        /// score while next process is move
        /// </summary>
        /// <param name="x">current board</param>
        /// <param name="prob">current board probability</param>
        /// <param name="para">parameters of search</param>
        /// <returns>score</returns>
        static double ScoreNextMove(UInt64 x, float prob, Param para)
        {
            double best = 0.0f;
            UInt64 newboard;

            para.depth++;
            for (int d = 0; d < 4; ++d)
            {
                newboard = BoardControl.ExecuteMove(x, d);
                if (x != newboard)
                {
                    best = Math.Max(best, ScoreNextInsert(newboard, prob, para));
                }
            }
            para.depth--;
            return(best);
        }
예제 #5
0
        /// <summary>
        /// score while next process is insert
        /// </summary>
        /// <param name="x">current board</param>
        /// <param name="prob">current board probability</param>
        /// <param name="para">parameters of search</param>
        /// <returns>score</returns>
        static double ScoreNextInsert(UInt64 x, float prob, Param para)
        {
            if (para.depth < DictionaryLimit)
            {
                if (para.scoreTable.ContainsKey(x))
                {
                    return(para.scoreTable[x]);
                }
            }

            if (prob < ProbTresh || para.depth >= para.depthLimit)
            {
                return(HeurScore(x));
            }

            int num = BoardControl.CountEmpty(x);

            prob /= num;

            double res  = 0.0f;
            UInt64 tmp  = x;
            UInt64 tile = 1;

            while (tile != 0)
            {
                if ((tmp & 0xf) == 0)
                {
                    res += ScoreNextMove(x | tile, prob * 0.9f, para) * 0.9f;
                    res += ScoreNextMove(x | (tile << 1), prob * 0.1f, para) * 0.1f;
                }
                tmp  >>= 4;
                tile <<= 4;
            }
            res = res / num;

            if (para.depth < DictionaryLimit)
            {
                para.scoreTable[x] = res;
            }

            return(res);
        }
예제 #6
0
        /// <summary>
        /// score board while pointed the next move
        /// </summary>
        /// <param name="x">current board</param>
        /// <param name="d">pre-pointed next move</param>
        /// <returns>score</returns>
        public static double ScoreFirstMove(Board x, int d)
        {
            double res;

            Param para = new Param();

            para.scoreTable = new Dictionary <ulong, double>();
            para.depthLimit = Math.Max(3, BoardControl.CountDistinctTiles(x) - 2);
            UInt64 newboard = BoardControl.ExecuteMove(x, d);

            if (x == newboard)
            {
                res = 0;
            }
            else
            {
                res = ScoreNextInsert(newboard, 1.0f, para) + 1e-6;
            }
            return(res);
        }
예제 #7
0
        /// <summary>
        /// find next move by monte carlo method
        /// </summary>
        /// <param name="x">current board</param>
        /// <returns>next move</returns>
        static public int MonteCarloMove(Board x)
        {
            int iterN = 2000;

            double[] score = new double[4] {
                0, 0, 0, 0
            };
            double maxScore = 0;
            int    maxi     = 0;

            Parallel.For(0, 4, (i, loopState) =>
            {
                if (BoardControl.ExecuteMove(x, i) != x)
                {
                    for (int j = 0; j < iterN; j++)
                    {
                        score[i] = score[i] + PlayGame.MontePlay(DirectScoreMove, x, 10, i);
                    }
                }
            });
            for (int k = 0; k < 4; k++)
            {
                if (score[k] > maxScore)
                {
                    maxScore = score[k];
                    maxi     = k;
                }
            }
            if (BoardControl.ExecuteMove(x, maxi) == x)
            {
                return(new Random(DateTime.Now.Millisecond).Next() % 4);
            }

            Console.WriteLine("Predict average score:" + (maxScore / iterN).ToString());
            Console.WriteLine();
            return(maxi);
        }
예제 #8
0
 static void Main(string[] args)
 {
     BoardControl.Initialize();
     PreScore.Initialize();
     PlayGame.Play(AI.SearchMove);
 }
예제 #9
0
 /// <summary>
 /// calculate direct score by rules
 /// </summary>
 /// <param name="x">current board</param>
 /// <returns>direct score</returns>
 public static double DirectScore(Board x)
 {
     return(BoardControl.ScoreHelper(x, scoreTable) +
            BoardControl.ScoreHelper(BoardControl.Transpose(x), scoreTable));
 }