public static Tuple <Color, int, long, long>[] Games(Board board, PlayerAbstract white, PlayerAbstract black, int numberOfGames, bool debugPrint = false, bool boardPrint = false) { var tasks = new List <Task <Tuple <Color, int, long, long> > >(); for (var i = 0; i < numberOfGames; i++) { var bC = board.Clone(); var wC = white.Clone(bC); var blC = black.Clone(bC); tasks.Add(new Task <Tuple <Color, int, long, long> >(() => Game(bC, wC, blC, boardPrint, debugPrint))); } tasks.ForEach(task => task.Start()); while (!tasks.All(task => task.IsCompleted)) { } return(tasks.ConvertAll(task => task.Result).ToArray()); }
private IEnumerable <Board> EnumerateBoardsFromNode(SimNode node, Board b, int numMovesAhead) { if (!String.IsNullOrEmpty(node.Move)) { node.Move = node.Move.Replace("{", ""); node.Move = node.Move.Replace("}", ""); string[] nums = node.Move.Split(':'); string[] fromCellParts = nums[0].Split(','); string[] toCellParts = nums[1].Split(','); foreach (string part in fromCellParts) { part.Trim(); } foreach (string part in toCellParts) { part.Trim(); } Cell fromCell = new Cell(int.Parse(fromCellParts[0]), int.Parse(fromCellParts[1])); Cell toCell = new Cell(int.Parse(toCellParts[0]), int.Parse(toCellParts[1])); b.MovePiece(fromCell, toCell); } if (node.MoveNumber == numMovesAhead) { yield return(b); } else { foreach (SimNode childNode in node.NextMoves) { Board newBoard = b.Clone() as Board; foreach (Board childBoard in EnumerateBoardsFromNode(childNode, newBoard, numMovesAhead)) { yield return(childBoard); } } } }
/// <summary> /// Chooses the *best* move from a set of moves. /// </summary> /// <param name="board"></param> /// <param name="moves"></param> /// <returns></returns> public Move ChooseMove(Board board, HashSet <Move> moves) { if (moves.Count == 0) { Godot.GD.Print("oh no"); } AIConstants constants = AIConstants.Default; float highestScore = float.NegativeInfinity; Move bestMove = moves.First(); foreach (var move in moves) { var b = board.Clone(); b.DoMove(move, _ => Piece.PieceType.Queen); float min = float.PositiveInfinity; var nextMoves = b.GetMoves(Player.Opposite()); foreach (var nm in nextMoves) { var b2 = b.Clone(); b2.DoMove(nm, _ => Piece.PieceType.Queen); var score = BoardScorer.Score(b2, Player, constants); if (score < min) { min = score; } } // This stops the AI from oscilalting between positions if (History.Count > 2) { if (move == History[History.Count - 2]) { // Godot.GD.Print("repeat >:("); min += constants.RepeatMoveScore; } } if (min > highestScore) { highestScore = min; bestMove = move; } // var score = BoardScorer.Score(b, Player, constants); // if (score > highestScore) // { // highestScore = score; // bestMove = move; // } } History.Add(bestMove); return(bestMove); }