Пример #1
0
        public static void LearnTheAgent(int timeInMs, double expFactor, string firstXml)
        {
            var masterMcts = new Mcts(timeInMs, expFactor);
            var weakerMcts = new Mcts(timeInMs, expFactor);

            masterMcts.LoadFromXml(firstXml);
            var tempFile   = string.Empty;
            var masterWins = 0;

            for (int i = 0; i < 100; i++)
            {
                tempFile = $"temp{i}.xml";
                masterMcts.SaveToXml(tempFile);

                if (SimulateGame(masterMcts, weakerMcts) == GameState.Player1Win)
                {
                    masterWins += 1;
                }

                masterMcts.BackToRoot();
                weakerMcts.LoadFromXml(tempFile);
            }

            File.WriteAllText("LearningResult.txt", $"Master won {masterWins} times");
        }
Пример #2
0
        public DevelopmentTest()
        {
            for (int i = 0; i < 32; i++)
            {
                uint stone = (uint)1 << i;
                Console.WriteLine(((Stones)stone).ToString() + ", " + GetPoint(stone));
            }

            Board board = new Board(Board.Tables.Outer, Board.Tables.Left, true);

            PrimaryUcb primaryUcb = new PrimaryUcb();
            Mcts       mcts       = new Mcts(primaryUcb);


            mcts.Init(board);

            while (!board.IsMyWin && !board.IsYoWin)
            {
                var t = mcts.SearchNextAsync();
                Console.WriteLine("Thinking ... ");
                t.Wait();
                Node node = t.Result;
                board.MoveNext(node.prevMove);
                mcts.SetMove(node.prevMove);
                board.PrintStones();


                Console.WriteLine("\n");
            }
        }
Пример #3
0
        public static byte OneRound(
            int blackTimeout         = 500,
            Algorithm blackAlgorithm = Algorithm.Mcts,
            int whiteTimeout         = 500,
            Algorithm whiteAlgorithm = Algorithm.Mcts,
            bool showLog             = true)
        {
            var state  = new State();
            var winner = Constant.Draw;

            while (!state.IsTerminal())
            {
                var isBlack   = state.Player == Constant.Black;
                var timeout   = isBlack ? blackTimeout : whiteTimeout;
                var algorithm = isBlack ? blackAlgorithm : whiteAlgorithm;
                var move      = Mcts.RunSearch(algorithm, state, timeout);

                state.NextState(move);
                winner = state.Winner();

                if (showLog)
                {
                    ShowLog(move, state);
                }
            }

            return(winner);
        }
Пример #4
0
 private void Mcts_ProgressUpdated(Mcts mcts, int visit, double rate)
 {
     Dispatcher.Invoke(() =>
     {
         ProgressBarVisitCount.Value = rate * 100;
         TextVisitCount.Text         = visit.ToString();
     });
 }
Пример #5
0
        public void FindBestPlay_NextTwoMoveBlock()
        {
            var gameBaord = new Board(0, 0);

            gameBaord.Board[0, 0] = new Cell {
                Row = 0, Col = 0, Value = Actor.Me
            };
            gameBaord.Board[1, 1] = new Cell {
                Row = 1, Col = 1, Value = Actor.Me
            };

            gameBaord.Board[0, 2] = new Cell {
                Row = 0, Col = 2, Value = Actor.Enemry
            };
            gameBaord.Board[2, 2] = new Cell {
                Row = 2, Col = 2, Value = Actor.Enemry
            };

            Console.WriteLine(gameBaord.ToString());

            var algo   = new Mcts();
            var player = new Player
            {
                Actor = Actor.Me
            };

            var play1 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play1.Row, play1.Col, player.Actor);

            Console.WriteLine(gameBaord.ToString());

            var expectedPlay1 = new Play(1, 2);

            Assert.AreEqual(expectedPlay1.Row, play1.Row);
            Assert.AreEqual(expectedPlay1.Col, play1.Col);
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play2 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play2.Row, play2.Col, player.Actor);

            Console.WriteLine(gameBaord.ToString());

            var expectedPlay2 = new Play(1, 0);

            Assert.AreEqual(expectedPlay2.Row, play2.Row);
            Assert.AreEqual(expectedPlay2.Col, play2.Col);
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);
        }
Пример #6
0
        private static ulong AiTurn(State state, int aiTimeout, Algorithm aiAlgorithm)
        {
            var move = Mcts.RunSearch(aiAlgorithm, state, aiTimeout);

            Console.Write("Ai move: " + move.ToNotation());
            Console.WriteLine(" - Runtime: {0}ms, Playout: {1}, wins: {2}%",
                              Mcts.LastRunTime,
                              Mcts.LastPlayout,
                              Mcts.LastWinPercentage);

            return(move);
        }
Пример #7
0
        private void button1_Click(object sender, EventArgs e)
        {
            tableLayoutPanelGamePanel.Controls.Clear();
            MCTSLogic = new Mcts(TimeToProcess, ExplorationFactor);
            string filePath = Path.Combine(Directory.GetCurrentDirectory(), "data.xml");

            MCTSLogic.LoadFromXml(filePath);
            RestartGameState();
            if (!IsPlayerStarting)
            {
                var move = MCTSLogic.GenerateMove();
                MCTSLogic.MakeMove(move);
                tableLayoutPanelGamePanel.Refresh();
            }
        }
Пример #8
0
 public void Load(Mcts mcts)
 {
     this.mcts = mcts;
     mcts.PauseSearching();
     mcts.WaitCycle();
     if (mcts.root.parent != null)
     {
         listUpTree(mcts.root.parent);
         show(mcts.root.parent);
     }
     else
     {
         listUpTree(mcts.root);
         show(mcts.root);
     }
     mcts.ResumeSearching();
 }
Пример #9
0
        public void FindBestPlay_NextMoveWin()
        {
            var gameBaord = new Board(0, 0);

            gameBaord.Board[0, 0] = new Cell {
                Row = 0, Col = 0, Value = Actor.Me
            };
            gameBaord.Board[0, 2] = new Cell {
                Row = 0, Col = 2, Value = Actor.Me
            };
            gameBaord.Board[1, 1] = new Cell {
                Row = 1, Col = 1, Value = Actor.Me
            };

            gameBaord.Board[0, 1] = new Cell {
                Row = 0, Col = 1, Value = Actor.Enemry
            };
            gameBaord.Board[1, 0] = new Cell {
                Row = 1, Col = 0, Value = Actor.Enemry
            };
            gameBaord.Board[2, 0] = new Cell {
                Row = 2, Col = 0, Value = Actor.Enemry
            };

            Console.WriteLine(gameBaord.ToString());

            var algo   = new Mcts();
            var player = new Player
            {
                Actor = Actor.Me
            };


            var play = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play.Row, play.Col, player.Actor);

            Console.WriteLine(gameBaord.ToString());

            var expectedPlay = new Play(2, 2);

            Assert.AreEqual(expectedPlay.Row, play.Row);
            Assert.AreEqual(expectedPlay.Col, play.Col);
            Assert.IsTrue(gameBaord.IsFull);
            Assert.AreEqual(Actor.Me, gameBaord.Pos.Value);
        }
Пример #10
0
        // zwraca informację czy wygrał lewy gracz
        private static GameState SimulateGame(int timeInMs, double firstParam, double secondParam)
        {
            var leftMcts  = new Mcts(timeInMs, firstParam);
            var rightMcts = new Mcts(timeInMs, secondParam);

            // wygenerowanie ruchu pierwszego gracza
            int leftPLayerMove = new Random(DateTime.Now.Millisecond).Next() % 7;
            int rightPlayerMove;

            while (true)
            {
                // wykonanie ruchu pierwszego gracza dla pierwszego parametru
                leftMcts.MakeMove(leftPLayerMove);
                if (leftMcts.IsEnd)
                {
                    return(leftMcts.GetBoard().State);
                }

                // wykonanie ruchu pierwszego gracza dla drugiego parametru
                rightMcts.MakeMove(leftPLayerMove);
                if (rightMcts.IsEnd)
                {
                    return(rightMcts.GetBoard().State);
                }

                // wygenerowanie ruchu drugiego gracza
                rightPlayerMove = rightMcts.GenerateMove();

                // wykonanie ruchu drugiego gracza dla pierwszego parametru
                leftMcts.MakeMove(rightPlayerMove);
                if (leftMcts.IsEnd)
                {
                    return(leftMcts.GetBoard().State);
                }

                // wykonanie ruchu drugiego gracza dla drugiego parametru
                rightMcts.MakeMove(rightPlayerMove);
                if (rightMcts.IsEnd)
                {
                    return(rightMcts.GetBoard().State);
                }

                leftPLayerMove = leftMcts.GenerateMove();
            }
        }
        public override void MakeMove(SimulationState state)
        {
            var root = Mcts.PerformMCTS(state, _useMinusOne, _progressiveBiasWeight);

            var bestChild = Mcts.FindBestChild(root);

            //DumpChildren(root);

            if (bestChild.PieceToPurchase.HasValue)
            {
                state.PerformPurchasePiece(bestChild.PieceToPurchase.Value);
            }
            else
            {
                state.PerformAdvanceMove();
            }

            MonteCarloTreeSearch <SearchNode> .NodePool.Value.ReturnAll();
        }
Пример #12
0
        public void FindBestPlay_NextMovePreventFork()
        {
            var gameBaord = new Board(0, 0);

            gameBaord.Board[1, 1] = new Cell {
                Row = 1, Col = 1, Value = Actor.Me
            };
            gameBaord.Board[1, 2] = new Cell {
                Row = 1, Col = 2, Value = Actor.Me
            };

            gameBaord.Board[1, 0] = new Cell {
                Row = 1, Col = 0, Value = Actor.Enemry
            };
            gameBaord.Board[2, 2] = new Cell {
                Row = 2, Col = 2, Value = Actor.Enemry
            };

            Console.WriteLine(gameBaord.ToString());

            var algo   = new Mcts();
            var player = new Player {
                Actor = Actor.Me
            };

            var play1 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play1.Row, play1.Col, player.Actor);

            Console.WriteLine(gameBaord.ToString());

            var safePlays = new List <Play>
            {
                new Play(0, 0),
                new Play(0, 1),
                new Play(2, 0),
                new Play(2, 1),
            };

            Assert.IsTrue(safePlays.Contains(play1));
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);
        }
Пример #13
0
        private static GameState SimulateGame(Mcts lefMcts, Mcts righMcts)
        {
            // wygenerowanie ruchu pierwszego gracza
            int leftPLayerMove;
            int rightPlayerMove;

            while (true)
            {
                leftPLayerMove = lefMcts.GenerateMove();

                // wykonanie ruchu pierwszego gracza dla pierwszego parametru
                lefMcts.MakeMove(leftPLayerMove);
                if (lefMcts.IsEnd)
                {
                    return(lefMcts.GetBoard().State);
                }

                // wykonanie ruchu pierwszego gracza dla drugiego parametru
                righMcts.MakeMove(leftPLayerMove);
                if (righMcts.IsEnd)
                {
                    return(righMcts.GetBoard().State);
                }

                // wygenerowanie ruchu drugiego gracza
                rightPlayerMove = righMcts.GenerateMove();

                // wykonanie ruchu drugiego gracza dla pierwszego parametru
                lefMcts.MakeMove(rightPlayerMove);
                if (lefMcts.IsEnd)
                {
                    return(lefMcts.GetBoard().State);
                }

                // wykonanie ruchu drugiego gracza dla drugiego parametru
                righMcts.MakeMove(rightPlayerMove);
                if (righMcts.IsEnd)
                {
                    return(righMcts.GetBoard().State);
                }
            }
        }
Пример #14
0
        public (int row, int col) PerformAiMove(Algorithm algorithm)
        {
            var move = Mcts.RunSearch(algorithm, _state, _timeOut);

            _state.NextState(move); // TODO auto swapPlayer in state.NextState will effect this

            var notation = move.ToNotation();

            if (move != 0)
            {
                _recordText += notation;
            }
            Console.WriteLine("{0} - Me: {1} - Win {2}% - Playout {3}",
                              _recordText.Length / 2,
                              notation,
                              Mcts.LastWinPercentage,
                              Mcts.LastPlayout);

            return(move == 0 ? (-1, -1) : move.ToCoordinate());
        }
Пример #15
0
        void genMcts()
        {
            Console.WriteLine("genMcts ... ");
            //게임 한 판 시작 ---------------------------
            List <Tuple <Board, Move> > recP1 = new List <Tuple <Board, Move> >();
            List <Tuple <Board, Move> > recP2 = new List <Tuple <Board, Move> >();

            //랜덤으로 보드 생성
            //상대방 선수로 놓는다. 어차피 시작하자마자 GetOpposite로 돌릴 거다.

            RealYame   yame   = new RealYame(tcpCommClient);
            OnlyPolicy policy = new OnlyPolicy(tcpCommClient, policyNetName);

            Mcts mcts1 = new Mcts(yame);
            Mcts mcts2 = new Mcts(policy);

            mcts1.MaxVisitCount = 300;
            mcts2.MaxVisitCount = 1;

            //누가 먼저 시작하나.
            bool  isMyFirst = Global.Rand.NextDouble() > 0.5;
            Board board     = new Board((Board.Tables)Global.Rand.Next(4), (Board.Tables)Global.Rand.Next(4), isMyFirst);

            bool isMyWin = false;

            mcts1.Init(board);
            mcts2.Init(board);

            for (int turn = 0; turn < 100; turn++)
            {
                Move        move;
                Task <Node> task;
                if (board.IsMyTurn)
                {
                    task = mcts1.SearchNextAsync();
                }
                else
                {
                    task = mcts2.SearchNextAsync();
                }
                task.Wait();
                move = task.Result.prevMove;

                if (move.IsEmpty)
                {
                    var moves = board.GetAllPossibleMoves();
                    move = moves[Global.Rand.Next(moves.Count - 1)];
                }

                //움직임을 저장해주고
                if (isMyFirst)
                {
                    recP1.Add(new Tuple <Board, Move>(board, move));
                }
                else
                {
                    recP2.Add(new Tuple <Board, Move>(board, move));
                }

                mcts1.SetMove(move);
                mcts2.SetMove(move);

                board = board.GetNext(move);


                board.PrintStones();

                //겜이 끝났는지 확인
                if (board.IsFinished)
                {
                    isMyWin = board.IsMyWin;
                    break;
                }
            }

            //턴제한으로 끝났으면 점수로
            if (!board.IsFinished)
            {
                isMyWin = (board.Point > 0);
            }

            lock (dataPolicy)
            {
                if (isMyWin)
                {
                    Console.WriteLine("    Collect data : my win");
                    var flip = from rec in recP1 select(new Tuple <Board, Move>(rec.Item1.GetFlip(), rec.Item2.GetFlip()));

                    dataPolicy.AddRange(recP1);
                    dataPolicy.AddRange(flip);


                    var list1 = from rec in recP1 select(new Tuple <Board, float>(rec.Item1, 1.0f));

                    var list2 = from rec in recP2 select(new Tuple <Board, float>(rec.Item1.GetOpposite(), 0f));

                    var list1Flip = from rec in list1 select(new Tuple <Board, float>(rec.Item1.GetFlip(), rec.Item2));

                    var list2Flip = from rec in list2 select(new Tuple <Board, float>(rec.Item1.GetFlip(), rec.Item2));

                    dataValue.AddRange(list1);
                    dataValue.AddRange(list2);
                    dataValue.AddRange(list1Flip);
                    dataValue.AddRange(list2Flip);
                }
                else
                {
                    Console.WriteLine("    Collect data : YO win");
                    var flip = from rec in recP2 select(new Tuple <Board, Move>(rec.Item1.GetFlip(), rec.Item2.GetFlip()));

                    dataPolicy.AddRange(recP2);
                    dataPolicy.AddRange(flip);


                    var list1 = from rec in recP1 select(new Tuple <Board, float>(rec.Item1, 0f));

                    var list2 = from rec in recP2 select(new Tuple <Board, float>(rec.Item1.GetOpposite(), 1.0f));

                    var list1Flip = from rec in list1 select(new Tuple <Board, float>(rec.Item1.GetFlip(), rec.Item2));

                    var list2Flip = from rec in list2 select(new Tuple <Board, float>(rec.Item1.GetFlip(), rec.Item2));

                    dataValue.AddRange(list1);
                    dataValue.AddRange(list2);
                    dataValue.AddRange(list1Flip);
                    dataValue.AddRange(list2Flip);
                }
            }
        }
Пример #16
0
        void genRanPseudo()
        {
            Mcts mcts = new Mcts(new PseudoYame());

            mcts.MaxVisitCount = maxVisitedCount;

            Board board = new Board((Board.Tables)Global.Rand.Next(4), (Board.Tables)Global.Rand.Next(4), true, false);

            mcts.Init(board);

            List <Tuple <Board, Move> > moves1 = new List <Tuple <Board, Move> >();
            List <Tuple <Board, Move> > moves2 = new List <Tuple <Board, Move> >();

            bool isMyWin = false;


            for (int i = 0; i < 80; i++)
            {
                Move move;
                if (board.IsMyTurn)
                {
                    var task = mcts.SearchNextAsync();
                    task.Wait();
                    move = task.Result.prevMove;
                    moves1.Add(new Tuple <Board, Move>(board, move));
                }
                else
                {
                    mcts.root.PrepareMoves();
                    List <Move> moves = mcts.root.moves;
                    move = moves[Global.Rand.Next(moves.Count)];
                    moves2.Add(new Tuple <Board, Move>(board, move));
                }

                mcts.SetMove(move);

                board = board.GetNext(move);

                //겜이 끝났는지 확인
                if (board.IsFinished)
                {
                    isMyWin = board.IsMyWin;
                    break;
                }
            }

            //턴제한으로 끝났으면 점수로
            if (!board.IsFinished)
            {
                isMyWin = (board.Point > 0);
            }

            lock (dataPolicy)
            {
                if (isMyWin)
                {
                    dataPolicy.AddRange(moves1);
                }
                else
                {
                    dataPolicy.AddRange(moves2);
                }
            }

            lock (dataValue)
            {
                if (isMyWin)
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 1);
                    dataValue.AddRange(vals1);
                }
                else
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 0);
                    dataValue.AddRange(vals1);
                }
            }

            winGames2.Add(isMyWin ? 1 : 0);
            while (winGames2.Count > 100)
            {
                winGames2.RemoveAt(0);
            }

            winGames3.Add(isMyWin ? 1 : 0);
            while (winGames3.Count > 1000)
            {
                winGames3.RemoveAt(0);
            }

            float rate2 = winGames2.Average();
            float rate3 = winGames3.Average();

            Console.WriteLine("    winning rate : " + rate2 + ", " + rate3);
        }
Пример #17
0
        public override void MakeMove(SimulationState state)
        {
            var root = Mcts.PerformMCTS(state, true, 0);

            //DumpChildren(root);

            _lookahead.Clear();

            SearchNode bestRootChild  = null;
            int        preplaceAmount = 0;

            //Go through what we currently think are our best moves and record the pieces we'll get
            while (root.Children.Count > 0)
            {
                var bestChild = Mcts.FindBestChild(root);

                if (bestRootChild == null)
                {
                    bestRootChild = bestChild;
                }

                //If this move was made by us
                if (root.State.ActivePlayer == state.ActivePlayer)
                {
                    if (bestChild.PieceToPurchase.HasValue)
                    {
                        _lookahead.Add(PieceDefinition.AllPieceDefinitions[root.State.Pieces[bestChild.PieceToPurchase.Value % root.State.Pieces.Count]]);
                    }

                    //If we moved past a leather patch, we must have got it
                    if (bestChild.State.LeatherPatchesIndex > root.State.LeatherPatchesIndex)
                    {
                        _lookahead.Add(PieceDefinition.LeatherTile);
                    }
                }

                //Only need to preplace if we get a piece in our first move
                if (bestRootChild == bestChild && _lookahead.Count > 0)
                {
                    //If we have made one move and got 2 pieces, that means we purchased and got a leather tile, so we need to plan for that
                    preplaceAmount = _lookahead.Count;
                }

                root = bestChild;
            }


            //Tell the Preplacer what we are planning on getting
            if (preplaceAmount > 0)
            {
                _preplacer.PreparePlacePiece(state.PlayerBoardState[state.ActivePlayer], _lookahead, preplaceAmount);
            }


            if (bestRootChild.PieceToPurchase.HasValue)
            {
                state.PerformPurchasePiece(bestRootChild.PieceToPurchase.Value);
            }
            else
            {
                state.PerformAdvanceMove();
            }

            MonteCarloTreeSearch <SearchNode> .NodePool.Value.ReturnAll();
        }
Пример #18
0
        private void ButtonNewGame_Click(object sender, RoutedEventArgs e)
        {
            Board.Tables myTable;
            Board.Tables yoTable;

            bool isMyFirst;


            if (RadioButtonMyInner.IsChecked.Value)
            {
                myTable = Board.Tables.Inner;
            }
            else if (RadioButtonMyOuter.IsChecked.Value)
            {
                myTable = Board.Tables.Outer;
            }
            else if (RadioButtonMyLeft.IsChecked.Value)
            {
                myTable = Board.Tables.Left;
            }
            else
            {
                myTable = Board.Tables.Right;
            }

            if (RadioButtonYoInner.IsChecked.Value)
            {
                yoTable = Board.Tables.Inner;
            }
            else if (RadioButtonYoOuter.IsChecked.Value)
            {
                yoTable = Board.Tables.Outer;
            }
            else if (RadioButtonYoLeft.IsChecked.Value)
            {
                yoTable = Board.Tables.Left;
            }
            else
            {
                yoTable = Board.Tables.Right;
            }

            if (RadioButtonMyFirst.IsChecked.Value)
            {
                isMyFirst = true;
            }
            else
            {
                isMyFirst = false;
            }

            mainBoard = new Board(myTable, yoTable, isMyFirst, false);

            StageMain.Board    = mainBoard;
            mainBoard.Changed += MainBoard_Changed;

            if (RadioButtonMyControllerAI.IsChecked.Value)
            {
                myController = Controllers.AI;
            }
            else if (RadioButtonMyControllerHuman.IsChecked.Value)
            {
                myController = Controllers.Human;
            }

            if (RadioButtonYoControllerAI.IsChecked.Value)
            {
                yoController = Controllers.AI;
            }
            else if (RadioButtonYoControllerHuman.IsChecked.Value)
            {
                yoController = Controllers.Human;
            }


            //종료 절차
            if (mcts != null)
            {
                isRunning = false;
                userWaiter.Set();
                mcts.ProgressUpdated -= Mcts_ProgressUpdated;
                ResumeSearching();
                mcts.ForceStopSearch();
                thread?.Join();
            }

            if (realYame == null)
            {
                realYame = new RealYame(client);
            }

            if (onlyPolicy == null)
            {
                onlyPolicy = new OnlyPolicy(client);
            }

            mcts = new Mcts(realYame)
            {
                MaxVisitCount = 500
            };

            TextBoxMaxVisitCount.Text = mcts.MaxVisitCount.ToString();
            mcts.Init(mainBoard);
            mcts.ProgressUpdated += Mcts_ProgressUpdated;
            ResumeSearching();

            thread = new Thread(runner);
            thread.Start();
        }
Пример #19
0
        /// <summary>
        /// 두 네트워크가 서로 싸움을 해서 그 기보를 학습 데이터로 내보낸다.
        /// </summary>
        void genReinforce()
        {
            //Mcts mcts1 = new Mcts(new OnlyPolicy(tcpCommClient));
            Mcts mcts1 = new Mcts(new RealYame(tcpCommClient));
            Mcts mcts2 = new Mcts(new RealYame(tcpCommClient));

            mcts1.MaxVisitCount = 500;
            mcts2.MaxVisitCount = 500;

            //bool isMyFirst = Global.Rand.Next() % 2 == 0;
            Board board = new Board((Board.Tables)Global.Rand.Next(4), (Board.Tables)Global.Rand.Next(4), true, false);


            mcts1.Init(new Board(board));
            mcts2.Init(new Board(board));

            List <Tuple <Board, Move> > moves1 = new List <Tuple <Board, Move> >();
            List <Tuple <Board, Move> > moves2 = new List <Tuple <Board, Move> >();

            bool isMyWin = false;


            for (int i = 0; i < 80; i++)
            {
                Move move;
                if (board.IsMyTurn)
                {
                    var task = mcts1.SearchNextAsync();
                    task.Wait();
                    move = task.Result.prevMove;
                    moves1.Add(new Tuple <Board, Move>(board, move));
                }
                else
                {
                    var task = mcts2.SearchNextAsync();
                    task.Wait();
                    move = task.Result.prevMove;
                    moves2.Add(new Tuple <Board, Move>(board, move));
                }

                mcts1.SetMove(move);
                mcts2.SetMove(move);

                board = board.GetNext(move);

                //겜이 끝났는지 확인
                if (board.IsFinished)
                {
                    isMyWin = board.IsMyWin;
                    break;
                }

                //mcts2.MaxVisitCount += 200;
            }

            //턴제한으로 끝났으면 점수로
            if (!board.IsFinished)
            {
                isMyWin = (board.Point > 0);
            }

            lock (dataPolicy)
            {
                if (isMyWin)
                {
                    dataPolicy.AddRange(moves1);
                }
                else
                {
                    dataPolicy.AddRange(moves2);
                }
            }

            lock (dataValue)
            {
                if (isMyWin)
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 1);
                    var vals2 = from e in moves2 select new Tuple <Board, float>(e.Item1.GetOpposite(), 0);
                    dataValue.AddRange(vals1);
                    dataValue.AddRange(vals2);
                }
                else
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 0);
                    var vals2 = from e in moves2 select new Tuple <Board, float>(e.Item1.GetOpposite(), 1);
                    dataValue.AddRange(vals1);
                    dataValue.AddRange(vals2);
                }
            }
        }
Пример #20
0
        void genRealPseudo()
        {
            //Mcts mcts1 = new Mcts(new OnlyPolicy(tcpCommClient));
            Mcts mcts1 = new Mcts(new PseudoYame());
            Mcts mcts2 = new Mcts(new PseudoYame());

            mcts1.MaxVisitCount = 500;
            mcts2.MaxVisitCount = 500;

            bool  isMyFirst = Global.Rand.Next() % 2 == 0;
            Board board     = new Board((Board.Tables)Global.Rand.Next(4), (Board.Tables)Global.Rand.Next(4), isMyFirst);


            mcts1.Init(new Board(board));
            mcts2.Init(new Board(board));

            List <Tuple <Board, Move> > moves1 = new List <Tuple <Board, Move> >();
            List <Tuple <Board, Move> > moves2 = new List <Tuple <Board, Move> >();

            bool isMyWin = false;


            for (int i = 0; i < 80; i++)
            {
                Move move;
                if (board.IsMyTurn)
                {
                    var task = mcts1.SearchNextAsync();
                    task.Wait();
                    move = task.Result.prevMove;
                    moves1.Add(new Tuple <Board, Move>(board, move));
                }
                else
                {
                    var task = mcts2.SearchNextAsync();
                    task.Wait();
                    move = task.Result.prevMove;
                    moves2.Add(new Tuple <Board, Move>(board, move));
                }

                mcts1.SetMove(move);
                mcts2.SetMove(move);

                board = board.GetNext(move);

                //겜이 끝났는지 확인
                if (board.IsFinished)
                {
                    isMyWin = board.IsMyWin;
                    break;
                }

                //mcts2.MaxVisitCount += 200;
            }

            //턴제한으로 끝났으면 점수로
            if (!board.IsFinished)
            {
                isMyWin = (board.Point > 0);
            }

            lock (dataPolicy)
            {
                if (isMyWin)
                {
                    dataPolicy.AddRange(moves1);
                }
                else
                {
                    dataPolicy.AddRange(moves2);
                }
            }

            lock (dataValue)
            {
                if (isMyWin)
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 1);
                    var vals2 = from e in moves2 select new Tuple <Board, float>(e.Item1.GetOpposite(), 0);
                    dataValue.AddRange(vals1);
                    dataValue.AddRange(vals2);
                }
                else
                {
                    var vals1 = from e in moves1 select new Tuple <Board, float>(e.Item1, 0);
                    var vals2 = from e in moves2 select new Tuple <Board, float>(e.Item1.GetOpposite(), 1);
                    dataValue.AddRange(vals1);
                    dataValue.AddRange(vals2);
                }
            }

            winGames2.Add(isMyWin ? 1 : 0);
            while (winGames2.Count > 100)
            {
                winGames2.RemoveAt(0);
            }

            winGames3.Add(isMyFirst ? 1 : 0);
            while (winGames3.Count > 100)
            {
                winGames3.RemoveAt(0);
            }

            float rate2 = winGames2.Average();
            float rate3 = winGames3.Average();

            Console.WriteLine("    winning rate : " + rate2 + ", " + rate3);
        }
Пример #21
0
        public void FindBestPlay_FullGameTie()
        {
            var gameBaord = new Board(0, 0);

            Console.WriteLine(gameBaord.ToString());

            var algo   = new Mcts();
            var player = new Player {
                Actor = Actor.Me
            };

            var play1 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play1.Row, play1.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play2 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play2.Row, play2.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play3 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play3.Row, play3.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play4 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play4.Row, play4.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play5 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play5.Row, play5.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play6 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play6.Row, play6.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play7 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play7.Row, play7.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play8 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play8.Row, play8.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsFalse(gameBaord.IsFull);
            Assert.AreEqual(Actor.None, gameBaord.Pos.Value);

            player = player.NextPlayer();
            var play9 = algo.FindBestPlay(gameBaord, player);

            gameBaord.UpdateCell(play9.Row, play9.Col, player.Actor);
            Console.WriteLine(gameBaord.ToString());
            Assert.IsTrue(gameBaord.IsFull);
            Assert.AreEqual(Actor.Tie, gameBaord.Pos.Value);
        }