public static float Evaluate(LogicBoard logicBoard, Stone.ColorType corrent) { board = logicBoard; var currentBit = board.CurrentBitBoards[(int)corrent]; int currentMovable = CountMovableCells(corrent); EdgeEvaluator.Setup(currentBit); int currentStable = EdgeEvaluator.CountStableStone(currentBit); int currentCMove = EdgeEvaluator.CountCMove(currentBit); int currentXMove = EdgeEvaluator.CountXMove(currentBit); var opponentColor = Stone.GetReverseColor(corrent); var opponentBit = board.CurrentBitBoards[(int)opponentColor]; int opponentMovable = CountMovableCells(opponentColor); EdgeEvaluator.Setup(opponentBit); int opponentStable = EdgeEvaluator.CountStableStone(opponentBit); int opponentCMove = EdgeEvaluator.CountCMove(opponentBit); int opponentXMove = EdgeEvaluator.CountXMove(opponentBit); float eval = (currentMovable - opponentMovable) * mobilityWeight + (currentStable - opponentStable) * stableWeight + (currentCMove - opponentCMove) * cMoveWeight + (currentXMove - opponentXMove) * xMoveWeight; return(eval); }
/// <summary> /// Retrieves a new PinController for a given board. /// </summary> /// <param name="logicBoard">The board to retrieve a Pin controller for.</param> /// <returns></returns> public IPinController GetPinController(LogicBoard logicBoard) { if (this._dictionary.ContainsKey(logicBoard)) { return(this._dictionary[logicBoard].Invoke()); } else { throw new NotImplementedException($"{nameof(PinControllerFactory)} cannot create an instance {nameof(IPinController)} for {logicBoard}"); } }
//最善手を探す public Vector2Int Search(LogicBoard logicBoard, Stone.ColorType color) { board = logicBoard; ulong found = 0; var maxEval = Mathf.NegativeInfinity; var beta = Mathf.Infinity; var a = Mathf.NegativeInfinity; var b = beta; var movables = GetSortedMovailable(color, a, b); if (movables.Count == 1) { return(LogicBoard.BitToPoints(movables[0])[0]); } for (int i = 0; i < movables.Count; i++) { var p = movables[i]; board.Log(); board.Reverse(p, color); var eval = -NegaScout(Stone.GetReverseColor(color), depth - 1, -b, -a); //最初の子ノードは再探索しない(ソートがうまくいっていれば評価が最大だから?) //葉から2つ以内のノードは再探索しない(なぜ?) if (i != 0 && depth > 2 && eval > a && eval < beta) { eval = -NegaScout(Stone.GetReverseColor(color), depth - 1, -beta, -eval); } board.Undo(); if (maxEval < eval) { a = Mathf.Max(a, eval); maxEval = eval; found = p; } b = a + 1; } return(LogicBoard.BitToPoints(found)[0]); }
private int CountValidPlay(bool isWhite) { int countValidPlay = 0; for (int i = 0; i < LogicBoard.GetLength(0) - 1; i++) { for (int j = 0; j < LogicBoard.GetLength(1) - 1; j++) { if (IsPlayable(i, j, isWhite)) { countValidPlay++; } } } return(countValidPlay); }
//NegaAlpha法 private float NegaAlpha(Stone.ColorType color, int depth, float alpha, float beta) { if (depth == 0) { return(Evaluator.Evaluate(board, color)); } var movable = board.GetMovableBitBoard(color); if (LogicBoard.CountBit(movable) == 0) { board.Log(); var eval = -NegaAlpha(Stone.GetReverseColor(color), depth - 1, -beta, -alpha); board.Undo(); return(eval); } while (movable != 0) { ulong next = GetLeastSignificantBit(movable); board.Log(); board.Reverse(next, color); var eval = -NegaAlpha(Stone.GetReverseColor(color), depth - 1, -beta, -alpha); board.Undo(); if (beta <= eval) { return(eval); } alpha = Mathf.Max(eval, alpha); movable ^= next; } return(alpha); }
//合法手の数を取得 private static int CountMovableCells(Stone.ColorType color) { var movable = board.GetMovableBitBoard(color); return(LogicBoard.CountBit(movable)); }
/// <summary> /// Creates a specific logic board. /// </summary> /// <param name="logicBoard">Defines the logic board to create.</param> /// <returns></returns> public ILogicBoard GetLogicBoard(LogicBoard logicBoard, IPinController controller) { return(logicBoard switch { LogicBoard.RaspberryPi2 => GetRaspberryPi2(controller), _ => throw new NotImplementedException(logicBoard.ToString()) });