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"); }
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"); } }
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); }
private void Mcts_ProgressUpdated(Mcts mcts, int visit, double rate) { Dispatcher.Invoke(() => { ProgressBarVisitCount.Value = rate * 100; TextVisitCount.Text = visit.ToString(); }); }
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); }
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); }
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(); } }
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(); }
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); }
// 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(); }
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); }
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); } } }
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()); }
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); } } }
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); }
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(); }
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(); }
/// <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); } } }
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); }
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); }