/// <summary> /// Updates the opponent's history of played cards and returns the last played cards of the opponent. /// This cards will be used for the prediction. /// </summary /// <param name="decayFactor">the decay factor by which the probability will be decrease</param> /// <param name="opponent">the controller of the opponent</param> /// <returns>the last played cards</returns> private PlayedCards updateTasks(double decayFactor, Controller opponent) { double initValue = 1; // add cards which were in the opponent's board and weren't played Minion[] oppBoard = opponent.BoardZone.GetAll(); oppBoard.Select(b => b.Card) .Where(c => !_oppBoardCards.Cards.Contains(c)).ToList() .ForEach(c => { _oppBoardCards.Add(c, initValue); }); List <PlayHistoryEntry> history = opponent.PlayHistory; history.Where(h => !_oppHistory.Contains(h)).ToList() .Select(h => h.SourceCard) .Where(c => !_oppBoardCards.Cards.Contains(c)).ToList() .ForEach(c => { _oppBoardCards.Add(c, initValue); }); PlayHistoryEntry[] copyHistory = new PlayHistoryEntry[history.Count]; history.CopyTo(copyHistory); _oppHistory = copyHistory.ToList(); return(_oppBoardCards); }
public void Initialize(POGame game) { if (_oppHistory == null) { List <PlayHistoryEntry> history = game.CurrentOpponent.PlayHistory; var copyHistory = new PlayHistoryEntry[history.Count]; history.CopyTo(copyHistory); _oppHistory = copyHistory.ToList(); } }
/// <summary> /// TODO: API /// </summary> /// <param name="game"></param> /// <returns></returns> public override MCTSNode simulate(POGame.POGame game) { POGame.POGame gameCopy = game.getCopy(); // initials root node var initLeafs = new List <MCTSNode>(); var root = new MCTSNode(_playerId, new List <MCTSNode.ScoreExt> { new MCTSNode.ScoreExt(1.0, _scoring) }, gameCopy, null, null); // simulate MCTSNode bestNode = simulate(_deltaTime, root, ref initLeafs); // initials opponent's history if (_oppHistory == null) { List <PlayHistoryEntry> history = gameCopy.CurrentOpponent.PlayHistory; PlayHistoryEntry[] copyHistory = new PlayHistoryEntry[history.Count]; history.CopyTo(copyHistory); _oppHistory = copyHistory.ToList(); } var simulationQueue = new Queue <KeyValuePair <POGame.POGame, List <MCTSNode> > >(); simulationQueue.Enqueue(new KeyValuePair <POGame.POGame, List <MCTSNode> >(gameCopy, initLeafs)); int i = 0; while (i < _predictionParameters.SimulationDepth && simulationQueue.Count > 0) { // calculate the lower and upper time bound of the current depth double lowerSimulationTimeBound = _deltaTime + i * (2 * _deltaTime); KeyValuePair <POGame.POGame, List <MCTSNode> > simulation = simulationQueue.Dequeue(); POGame.POGame simulationGame = simulation.Key; List <MCTSNode> leafs = simulation.Value; leafs = leafs.Where(l => l.Game != null) .OrderByDescending(l => l.Score) .Take((leafs.Count > _predictionParameters.LeafCount) ? _predictionParameters.LeafCount : leafs.Count) .ToList(); if (leafs.Count() < 0) { return(bestNode); } Controller opponent = getOpponent(simulationGame); List <Prediction> predicitionMap = getPredictionMap(simulationGame, opponent); var oldSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >(); // the simulation time for one leaf double timePerLeaf = (2 * _deltaTime) / leafs.Count; // get all games from all leaf nodes for (int j = 0; j < leafs.Count; j++) { // calculate the lower time bound of the current leaf double lowerLeafTimeBound = lowerSimulationTimeBound + j * timePerLeaf; MCTSNode leafNode = leafs[j]; POGame.POGame oppGame = leafNode.Game; double leafScore; // XXX: game can be null leafScore = simulateOpponentWithPrediction(lowerLeafTimeBound, timePerLeaf, oppGame, opponent, predicitionMap, ref oldSimulations); // back-propagate score backpropagate(leafNode, leafScore); } var newSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >(); oldSimulations.ToList() .OrderByDescending(s => s.Value.Sum(l => l.TotalScore)) .Take((leafs.Count > _predictionParameters.OverallLeafCount) ? _predictionParameters.OverallLeafCount : leafs.Count) .ToList() .ForEach(l => newSimulations.Add(l.Key, l.Value)); // add new simulations foreach (KeyValuePair <POGame.POGame, List <MCTSNode> > sim in oldSimulations) { simulationQueue.Enqueue(sim); } i++; } return(root.Children .OrderByDescending(c => c.TotalScore) .First()); }