public static void TestEndGameEngine() { var board = new BitBoard(23502599851429632UL, 560695349311UL); Console.WriteLine(board.Draw("black")); var engine = new ZebraEngine(); var r = engine.Search(board, board.EmptyPiecesCount()); Console.WriteLine(r); }
public override SearchResult Search(BitBoard board, int depth) { var pattern = board.Draw(ownSymbol: "O", oppSymbol: "X", emptySymbol: "-"); depth = board.EmptyPiecesCount(); var gameMode = depth <= EndGameDepth ? "endgame-search" : "midgame-search"; var r = CallEdax(gameMode, pattern); return(r); }
public override SearchResult Search(BitBoard board, int depth) { var empties = board.EmptyPiecesCount(); //if (empties.InRange(55, 60)) //{ // var engine = openingBookEngine; // return engine.Search(board, 0); //} var pattern = board.Draw(ownSymbol: "O", oppSymbol: "X", emptySymbol: "-"); var r = (empties <= WinLoseDepth && empties > EndGameDepth ? CallEdax("endgame-search", pattern, -1, 1, empties) : (empties <= EndGameDepth ? CallEdax("endgame-search", pattern, -64, 64, empties) : (CallEdax("midgame-search", pattern, -64, 64, depth))) ); return(r); }
private FightResult DoFight(IEngine engineA, IEngine engineB, BitBoard board) { var clock = new Clock(); clock.Start(); var engines = new IEngine[] { engineA, engineB }; var timespans = new TimeSpan[] { TimeSpan.Zero, TimeSpan.Zero }; var colors = new[] { "Black", "White" }; int turn = 0; Console.WriteLine(board.Draw(colors[turn])); while (!board.IsFull) { var empties = board.EmptyPiecesCount(); if (empties <= TrainDepth + 1) { var moves = Rule.FindMoves(board); if (moves.Length > 0) { var bestScore = -64; var bestMove = -1; foreach (var move in moves) { var oppboard = Rule.MoveSwitch(board, move); var own = false; if (!Rule.CanMove(oppboard)) { oppboard = oppboard.Switch(); own = true; } var sr = AnalyzeEndGame(oppboard, turn); var eval = own ? sr.Score : -sr.Score;//opp's score if (eval > bestScore) { bestScore = eval; bestMove = move; } Console.WriteLine($"color:{turn} move:{move}, score:{eval}"); } var winIndex = bestScore >= 0 ? turn : 1 - turn; return(new FightResult { WinnerName = engines[winIndex].Name, LoserName = engines[1 - winIndex].Name, WinnerStoneType = colors[winIndex], Score = Math.Abs(bestScore), TimeSpan = clock.Elapsed }); } } var depth = 0; var sw = Stopwatch.StartNew(); var searchResult = engines[turn].Search(board.Copy(), depth); sw.Stop(); timespans[turn] += sw.Elapsed; Console.WriteLine($"[{engines[turn].Name}][{board.EmptyPiecesCount()}] {searchResult}"); if (engines[turn].Name == "EdaxEngine" && board.EmptyPiecesCount() <= EdaxEngine.EndGameDepth) { SaveResult(board, searchResult); } if (searchResult.Move < 0 || searchResult.Move >= Constants.StonesCount || !Rule.FindMoves(board).Contains(searchResult.Move)) { clock.Stop(); //error Console.WriteLine("----------------Error Move----------------------"); Console.WriteLine(board.Draw(colors[turn])); return(new FightResult() { WinnerName = engines[1 - turn].Name, LoserName = engines[turn].Name, WinnerStoneType = colors[turn], Score = 1, TimeSpan = clock.Elapsed }); } else { board = Rule.MoveSwitch(board, searchResult.Move); Console.WriteLine(board.Draw(colors[turn])); } turn = 1 ^ turn; var canFlip = Rule.CanMove(board); if (!canFlip) { //pass Console.WriteLine($"{engines[turn].Name} pass"); turn = 1 ^ turn; board = board.Switch(); canFlip = Rule.CanMove(board); if (!canFlip) { Console.WriteLine($"{engines[turn].Name} pass, game over!"); AnalyzeEndGame(board, turn); //both pass break; } } } clock.Stop(); Console.WriteLine("################### Game Over #######################"); for (var i = 0; i < 2; i++) { Console.WriteLine($"Total spent time({engines[i].Name}): {timespans[i]}"); } return(new FightResult(board, engines, turn) { TimeSpan = clock.Elapsed }); }
private FightResult Fight(IEngine engineA, IEngine engineB, BitBoard board) { var clock = new Clock(); clock.Start(); var engines = new IEngine[] { engineA, engineB }; var timespans = new TimeSpan[] { TimeSpan.Zero, TimeSpan.Zero }; var colors = new[] { "Black", "White" }; int turn = 0; Console.WriteLine(board.Draw(colors[turn])); while (!board.IsFull) { var depth = 8; var sw = Stopwatch.StartNew(); var searchResult = engines[turn].Search(board.Copy(), depth); sw.Stop(); timespans[turn] += sw.Elapsed; Console.Title = $"[{board.EmptyPiecesCount()}][{depth}] [{engines[turn].Name}] {board.PlayerPiecesCount()}:{board.OpponentPiecesCount()}"; Console.Title += $" {searchResult.Score}"; Console.WriteLine($"[{engines[turn].Name}][{board.EmptyPiecesCount()}] {searchResult}"); if (searchResult.Move < 0 || searchResult.Move >= Constants.StonesCount || !Rule.FindMoves(board).Contains(searchResult.Move)) { clock.Stop(); //error Console.WriteLine("----------------Error Move----------------------"); Console.WriteLine(board.Draw(colors[turn])); return(new FightResult() { WinnerName = engines[1 - turn].Name, LoserName = engines[turn].Name, WinnerStoneType = colors[turn], Score = 1, TimeSpan = clock.Elapsed }); } else { board = Rule.MoveSwitch(board, searchResult.Move); Console.WriteLine(board.Draw(colors[turn])); } turn = 1 ^ turn; var canFlip = Rule.CanMove(board); if (!canFlip) { //pass Console.WriteLine($"{engines[turn].Name} pass"); turn = 1 ^ turn; board = board.Switch(); canFlip = Rule.CanMove(board); if (!canFlip) { Console.WriteLine($"{engines[turn].Name} pass, game over!"); //both pass break; } } } clock.Stop(); Console.WriteLine("################### Game Over #######################"); for (var i = 0; i < 2; i++) { Console.WriteLine($"Total spent time({engines[i].Name}): {timespans[i]}"); } return(new FightResult(board, engines, turn) { TimeSpan = clock.Elapsed }); }