public List <Move> GetCalculatedNextMoves(CellState[,] board, Team team, List <List <Move> > beats, List <List <Move> > moves, CancellationToken token) { var firstPredictions = new List <PredictionNode>(); try { var predictions = new List <PredictionNode>(); foreach (var beat in beats) { if (beat.Count > 0) { var updatedBoard = board.UpdateFromMoves(beat); if (updatedBoard.CountEnemies(team) == 0) { return(beat); } var ranking = _getMoveWeight.CalculateMoveWeight(beat, board, updatedBoard, team, true); var node = new PredictionNode { InitialMoves = beat, NextTeam = team.GetNextTeam(), NextBoard = updatedBoard, Depth = 0, AccumulatedWeight = ranking.weight, StatsForPlayer = ranking.stats }; firstPredictions.Add(node); predictions.AddRange(_predictionBuilder.GetDepthwisePrediction(node, team, 3, token)); } } foreach (var move in moves) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } var updatedBoard = board.UpdateFromMoves(move); var ranking = _getMoveWeight.CalculateMoveWeight(move, board, updatedBoard, team); var node = new PredictionNode { InitialMoves = move, NextTeam = team.GetNextTeam(), NextBoard = updatedBoard, Depth = 0, AccumulatedWeight = ranking.weight, StatsForPlayer = ranking.stats }; firstPredictions.Add(node); predictions.AddRange(_predictionBuilder.GetDepthwisePrediction(node, team, 3, token)); } return(GetBestForRandom(predictions)); } catch (TaskCanceledException) { Console.WriteLine("Task cancelled"); } return(GetBestForRandom(firstPredictions)); }
public List <PredictionNode> GetDepthwisePrediction(PredictionNode node, Team teamPlaying, int predictionDepth, CancellationToken token) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } var teamNext = node.NextTeam; var boardNext = node.NextBoard; var toKill = boardNext.CountEnemies(teamNext); var depth = node.Depth + 1; var beats = _beatsCalc.GetPossibleBeats(boardNext, teamNext); var nextPossibilities = new List <PredictionNode>(); foreach (var beat in beats) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } if (beat.Count > 0) { var updatedBoard = boardNext.UpdateFromMoves(beat); var rank = _getMoveWeight.CalculateMoveWeight(beat, boardNext, updatedBoard, teamNext, true); if (rank.stats > -2) { var nodeNext = new PredictionNode { InitialMoves = node.InitialMoves, NextTeam = teamNext.GetNextTeam(), NextBoard = updatedBoard, Depth = depth, AccumulatedWeight = node.AccumulatedWeight + (teamNext == teamPlaying ? +rank.weight : -rank.weight), StatsForPlayer = teamNext == teamPlaying ? +rank.weight : -rank.weight }; if (depth == predictionDepth || toKill == 0) { nextPossibilities.Add(nodeNext); } if (depth < predictionDepth && toKill > 0) { nextPossibilities.AddRange(GetDepthwisePrediction(nodeNext, teamPlaying, predictionDepth, token)); } } } } var moves = _movesCalc.GetPossibleMoves(boardNext, teamNext); foreach (var move in moves) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } var updatedBoard = boardNext.UpdateFromMoves(move); var rank = _getMoveWeight.CalculateMoveWeight(move, boardNext, updatedBoard, teamNext); var nodeNext = new PredictionNode { InitialMoves = node.InitialMoves, NextTeam = teamNext.GetNextTeam(), NextBoard = updatedBoard, Depth = depth, AccumulatedWeight = node.AccumulatedWeight + (teamNext == teamPlaying ? +rank.weight : -rank.weight), StatsForPlayer = teamNext == teamPlaying ? +rank.weight : -rank.weight }; if (depth == predictionDepth) { nextPossibilities.Add(nodeNext); } if (depth < predictionDepth) { nextPossibilities.AddRange(GetDepthwisePrediction(nodeNext, teamPlaying, predictionDepth, token)); } } return(nextPossibilities); }