private List <CardAction> PossiblePlaysFromState(List <Card> hand, Game state, Game.Player activePlayer) { var actions = new List <CardAction>(); actions.AddRange(hand.Select(c => new DropCardAction(c))); var playableCards = hand .Where(c => CardAction.CanPlay(c, state.GameState[activePlayer])) .Select(c => new PlayCardAction(c)); actions.AddRange(playableCards); return(actions); }
private void SimulateGame() { // randomization var unseenCards = GameCards.Cards.Except(_root.OriginalCardsUpToHere); var deck = new Deck(unseenCards); deck.Shuffle(); var opHand = deck.GetCards(CardsPerHand); var aiHand = _root.OriginalCardsUpToHere.ToList(); var simulationGame = ObjectCopier.Clone(_game); var reward = 0; // selection var node = _root; var depth = 0; while (node.Children.Count > 0 && depth++ <= CardsPerHand + 1) { node = node.Children.ToArray() .Where(n => n.Action is DropCardAction || CardAction.CanPlay(n.Action.Card, simulationGame.GameState[Game.Player.Ai])) .MaxBy(k => k.Ucb); var myPlay = MakePlay(simulationGame, aiHand, Game.Player.Ai, deck); switch (myPlay) { case Game.ActionResult.GameWon: Backpropagation(node, 1); return; case Game.ActionResult.GameLost: Backpropagation(node, -1); return; } var opPlay = MakePlay(simulationGame, opHand, Game.Player.Opponent, deck); switch (opPlay) { case Game.ActionResult.GameWon: Backpropagation(node, -1); return; case Game.ActionResult.GameLost: return; } } if (node.Children.Count == 0) { lock (LockObj) { if (node.Children.Count == 0) { // create possible moves from this node foreach (var action in PossiblePlaysFromState(aiHand, simulationGame, Game.Player.Ai)) { var newNode = new Node(node, node.OriginalCardsUpToHere.Except(new[] { action.Card }).ToList(), action); node.Children.Add(newNode); } } } } var possibleNodes = node.Children.ToArray() .Where( n => n.Action is DropCardAction || CardAction.CanPlay(n.Action.Card, simulationGame.GameState[Game.Player.Ai])).ToArray(); node = possibleNodes.ElementAt(Rand.Next(0, possibleNodes.Length)); MakePlay(simulationGame, node.Action, aiHand, Game.Player.Ai, deck); reward = PlayGameToEnd(aiHand, opHand, simulationGame, deck, Game.Player.Opponent); Backpropagation(node, reward); }