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"); } }
void runner() { userWaiter = new AutoResetEvent(false); Move move = new Move(); isRunning = true; while (isRunning) { if (mainBoard.IsMyTurn) { move = waitInput(myController); } else { move = waitInput(yoController); } if (!isRunning) { break; } //mcts의 상태를 변경해준다. board와는 따로 동작한다. //반드시 보드보다 먼저 실행해야 한다. 좀 복잡하네 ㅋㅋ mcts?.SetMove(move); //현재 게임의 상태를 변경. mainBoard.MoveNext(move); if (mainBoard.IsMyWin) { MessageBox.Show("내가 이겼다."); break; } else if (mainBoard.IsYoWin) { MessageBox.Show("상대가 이겼다."); break; } TreeViewerMain.Load(mcts); } }
/// <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 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); }
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); }
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); } } }