int AlphaBeta(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes, int alpha, int beta, uint limit) { if (limit == 0) { return(GetScore(board, myState)); } foreach (var index in indexes) { var temporaryBoard = board.Clone(); temporaryBoard.TurnOverWith(index, myState); var enemyState = Stone.GetReverseState(myState); var enemyIndexes = temporaryBoard.CanTurnOverIndexes(enemyState).ToList(); if (enemyIndexes.Count == 0) { return(AlphaBeta(board, myState, temporaryBoard.CanTurnOverIndexes(myState).ToList(), alpha, beta, limit - 1)); } var score = -AlphaBeta(board, enemyState, enemyIndexes, -beta, -alpha, limit - 1); alpha = Math.Max(alpha, score); if (alpha >= beta) { return(alpha); } } return(alpha); }
public async override Task <TableIndex> Turn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes) { if (Delay > 0) { await Task.Delay(Delay); } return(OnTurn(board, myState, indexes)); }
void OnGameEnd(Stone.StoneState winner) { var player0 = game.GetPlayer(new Coset(Game.PlayerNumber, 0)); var player1 = game.GetPlayer(new Coset(Game.PlayerNumber, 1)); var winnerName = winner == Stone.StoneState.None ? "Nobody" : game.GetPlayer(winner).Name; Log($"{game.PlayCount} Won by {winnerName}; Game Count ({player0.Name} {Game.WinninngCount(player0)} : {player1.Name} {Game.WinninngCount(player1)})"); gameHistory.End(winner); }
protected override TableIndex OnTurn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes) { var bestPrediction = (index : new TableIndex(), prediction : float.MinValue); indexes.ForEach(index => { var temporaryBoard = board.Clone(); temporaryBoard.TurnOverWith(index, myState); var inputData = CreateInput(temporaryBoard, myState); var outputData = predictionEngine.Predict(inputData); if (outputData.Prediction > bestPrediction.prediction) { bestPrediction = (index, outputData.Prediction); } }); return(bestPrediction.index); }
static int GetScoreWithScoreTable(Board board, Stone.StoneState myState) { #if DEBUG GettingScoreCount++; #endif // DEBUG var enemyState = Stone.GetReverseState(myState); var myScore = 0; var enemyScore = 0; foreach (var index in board.AllIndexes) { var cellState = board[index].State; if (cellState == myState) { myScore += scoreTable[index]; } else if (cellState == enemyState) { enemyScore += scoreTable[index]; } } return(myScore - enemyScore); }
//void DoTurn(Board board, Stone.StoneState myState, IEnumerable<TableIndex>? indexes = null) //{ // var (index, _) = GetMaximumScore(board, myState, indexes); // board.TurnOverWith(index, myState); //} TableIndex GetMaximumScoreIndex(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes) { const int alpha = int.MinValue; const int beta = int.MaxValue; const uint limit = 3U; var bestScore = int.MinValue; var bestScoreIndexes = new List <TableIndex>(); indexes.ForEach(index => { var temporaryBoard = board.Clone(); temporaryBoard.TurnOverWith(index, myState); var enemyState = Stone.GetReverseState(myState); var enemyIndexes = temporaryBoard.CanTurnOverIndexes(enemyState).ToList(); var score = enemyIndexes.Count == 0 ? AlphaBeta(board, myState, temporaryBoard.CanTurnOverIndexes(myState).ToList(), alpha, beta, limit - 1) : -AlphaBeta(board, enemyState, enemyIndexes, alpha, beta, limit - 1); if (score == bestScore) { bestScoreIndexes.Add(index); } else if (score > bestScore) { bestScore = score; bestScoreIndexes.Clear(); bestScoreIndexes.Add(index); } }); var index = random.Next(bestScoreIndexes.Count); Debug.Assert(0 <= index && index < bestScoreIndexes.Count); return(bestScoreIndexes[index]); }
static float ToFloat(Stone.StoneState myState, Stone.StoneState state) => state switch {
static float ToCell(Stone.StoneState myState, Board board, int row, int column) => ToFloat(myState, board[new TableIndex { Row = row, Column = column }].State);
protected override TableIndex OnTurn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes) { var indexList = indexes.ToList(); return(indexList[random.Next(indexList.Count)]); }
protected abstract TableIndex OnTurn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes);
static int GetScoreWithStoneNumber(Board board, Stone.StoneState myState) => board.GetStoneNumber(myState);
static float ToVictory(float isBlack, Stone.StoneState winner) => winner switch {
public void SetWinner(Stone.StoneState winner) => moves.ForEach(move => move.Victory = ToVictory(move.IsBlack, winner));
protected override TableIndex OnTurn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes) => GetMaximumScoreIndex(board, myState, indexes);
ModelInput CreateInput(Board board, Stone.StoneState myState) => new ModelInput { Cell00 = ToCell(myState, board, 0, 0), Cell01 = ToCell(myState, board, 0, 1), Cell02 = ToCell(myState, board, 0, 2), Cell03 = ToCell(myState, board, 0, 3), Cell04 = ToCell(myState, board, 0, 4), Cell05 = ToCell(myState, board, 0, 5), Cell06 = ToCell(myState, board, 0, 6), Cell07 = ToCell(myState, board, 0, 7), Cell10 = ToCell(myState, board, 1, 0), Cell11 = ToCell(myState, board, 1, 1), Cell12 = ToCell(myState, board, 1, 2), Cell13 = ToCell(myState, board, 1, 3), Cell14 = ToCell(myState, board, 1, 4), Cell15 = ToCell(myState, board, 1, 5), Cell16 = ToCell(myState, board, 1, 6), Cell17 = ToCell(myState, board, 1, 7), Cell20 = ToCell(myState, board, 2, 0), Cell21 = ToCell(myState, board, 2, 1), Cell22 = ToCell(myState, board, 2, 2), Cell23 = ToCell(myState, board, 2, 3), Cell24 = ToCell(myState, board, 2, 4), Cell25 = ToCell(myState, board, 2, 5), Cell26 = ToCell(myState, board, 2, 6), Cell27 = ToCell(myState, board, 2, 7), Cell30 = ToCell(myState, board, 3, 0), Cell31 = ToCell(myState, board, 3, 1), Cell32 = ToCell(myState, board, 3, 2), Cell33 = ToCell(myState, board, 3, 3), Cell34 = ToCell(myState, board, 3, 4), Cell35 = ToCell(myState, board, 3, 5), Cell36 = ToCell(myState, board, 3, 6), Cell37 = ToCell(myState, board, 3, 7), Cell40 = ToCell(myState, board, 4, 0), Cell41 = ToCell(myState, board, 4, 1), Cell42 = ToCell(myState, board, 4, 2), Cell43 = ToCell(myState, board, 4, 3), Cell44 = ToCell(myState, board, 4, 4), Cell45 = ToCell(myState, board, 4, 5), Cell46 = ToCell(myState, board, 4, 6), Cell47 = ToCell(myState, board, 4, 7), Cell50 = ToCell(myState, board, 5, 0), Cell51 = ToCell(myState, board, 5, 1), Cell52 = ToCell(myState, board, 5, 2), Cell53 = ToCell(myState, board, 5, 3), Cell54 = ToCell(myState, board, 5, 4), Cell55 = ToCell(myState, board, 5, 5), Cell56 = ToCell(myState, board, 5, 6), Cell57 = ToCell(myState, board, 5, 7), Cell60 = ToCell(myState, board, 6, 0), Cell61 = ToCell(myState, board, 6, 1), Cell62 = ToCell(myState, board, 6, 2), Cell63 = ToCell(myState, board, 6, 3), Cell64 = ToCell(myState, board, 6, 4), Cell65 = ToCell(myState, board, 6, 5), Cell66 = ToCell(myState, board, 6, 6), Cell67 = ToCell(myState, board, 6, 7), Cell70 = ToCell(myState, board, 7, 0), Cell71 = ToCell(myState, board, 7, 1), Cell72 = ToCell(myState, board, 7, 2), Cell73 = ToCell(myState, board, 7, 3), Cell74 = ToCell(myState, board, 7, 4), Cell75 = ToCell(myState, board, 7, 5), Cell76 = ToCell(myState, board, 7, 6), Cell77 = ToCell(myState, board, 7, 7), //Index = index.LinearIndex };
public int GetStoneNumber(Stone.StoneState state) => stones.Count(stone => stone.State == state);
public abstract Task <TableIndex> Turn(Board board, Stone.StoneState myState, IEnumerable <TableIndex> indexes);
void OnGameUpdate(Stone.StoneState state) => gameHistory.Add(game.Board, state);
static int GetScore(Board board, Stone.StoneState myState) => GetScoreWithScoreTable(board, myState) * scoreRateTable[0] + GetScoreWithStoneNumber(board, myState) * scoreRateTable[1];