public TankAction GetBestAction(Grid grid, SignalWeights weights) { long turnStartTime = Stopwatch.GetTimestamp(); bool successfulActionFound = false; int depth = 1; List<Beam> beams = new List<Beam>(); { foreach (var operation in operations) //TankOperation operation = operations[1]; { Beam beam = new Beam(operation, grid, weights); beams.Add(beam); successfulActionFound = (successfulActionFound || beam.WasSuccessful()); } } int beamCompletedCount = 0; while (!successfulActionFound && (beamCompletedCount < beams.Count) && !IsTimeout(turnTimeout, turnStartTime)) { depth++; Parallel.ForEach(beams, (beam) => { if (beam.StillSearching()) { foreach (EvalState state in beam.Iterate()) { state.Grid.Health--; foreach (TankOperation operation in operations) { EvalState opState = operation.GetScore(state, weights); beam.Add(opState); } } beam.Evaluate(); beamCompletedCount += (beam.StillSearching() ? 0 : 1); successfulActionFound = (successfulActionFound || beam.WasSuccessful()); } }); } EvalState bestState = new EvalState(TankAction.Noop, grid); foreach (var beam in beams) { EvalState operationBest = beam.GetBest(); gameOutput.WriteLine(" Beam {0} ({3} pts) - depth: {1}, candidates: {2} - {4}", beam.StartAction, depth, beam.CandidateCount, operationBest.Score, operationBest); if (bestState.Score < operationBest.Score) { bestState = operationBest; } } gameOutput.WriteLine("TURN {0} - Best: ({1}) {2}", numberOfTurns, bestState.Score, bestState); return bestState.GetRootAction(); }