private static double simulatePlay(Node simulateNode) { Node tempNode = simulateNode; if (tempNode.getNodeTask().PlayerTaskType == PlayerTaskType.END_TURN) { return(Reward.getReward(tempNode.getState(), tree.getRoot().getState())); } List <PlayerTask> options = tempNode.getState().CurrentPlayer.Options(); Dictionary <PlayerTask, POGame.POGame> states = tempNode.getState().Simulate(options); Random random = new Random(); int rnd; rnd = random.Next(options.Count); POGame.POGame state = null; while (options[rnd].PlayerTaskType != PlayerTaskType.END_TURN) { if (state == null) { state = states.GetValueOrDefault(options[rnd]); } else { state.Process(options[rnd]); } options = state.CurrentPlayer.Options(); rnd = random.Next(options.Count); } if (state == null) { state = states.GetValueOrDefault(options[rnd]); } else { state.Process(state.CurrentPlayer.Options()[rnd]); } return(Reward.getReward(state, tree.getRoot().getState())); }
/// <summary> /// simulate the chosen move and update scorematrix with it /// </summary> /// <param name="poGame"></param> /// <param name="task"></param> /// <param name="options"></param> /// <returns>returns different Task if simulated Task produces errors</returns> PlayerTask SimulateNextTaskAndUpdateScoreMatrix(POGame.POGame poGame, PlayerTask task, List <PlayerTask> options) { POGame.POGame simulatedGame = poGame.getCopy(); try { Dictionary <PlayerTask, POGame.POGame> simulatedGames = simulatedGame.Simulate(new List <PlayerTask>() { task }); int tries = 0; while ((simulatedGames[task] == null || simulatedGames[task].State == SabberStoneCore.Enums.State.INVALID) && options.Count > 1) { if (tries > 3) { break; } task = options[Rnd.Next(options.Count)]; simulatedGames = simulatedGame.Simulate(new List <PlayerTask>() { task }); tries++; } simulatedGame.Process(task); } catch { } if (simulatedGame != null) { gameStateScoreMatrix.VisitState(GetExtensiveScoreParametersOfGame(simulatedGame)); } // check if game is ending to computer reward if (simulatedGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON) { Log(LogLevel.INFO, "Might be winning next round, with health: " + simulatedGame.CurrentPlayer.Hero.Health); float additionalReward = Math.Clamp(simulatedGame.CurrentPlayer.Hero.Health / 30, 0, 1) * 100f; reward = 100f + additionalReward; } return(task); }