public void PopulateActions() { if (!Current.Equals(possibleActions.Player)) { possibleActions.Player = Current; possibleActions.CardActions = new List <CardActions>(); foreach (Card c in Current.Hand) { CardActions cardActions = new CardActions(); cardActions.Card = c; cardActions.IsThrowable = ValidateThrow(c); cardActions.PossibleTricks = new List <List <Card> >(); if (!cardActions.IsThrowable) { List <List <Card> > possibles = ScopaGame.EnumerateAll(table, c); foreach (List <Card> possible in possibles) { if (ValidateTrick(c, possible)) { cardActions.PossibleTricks.Add(possible); } } } possibleActions.CardActions.Add(cardActions); } possibleActions.CanThrow = possibleActions.CardActions.Any <CardActions>(a => a.IsThrowable); possibleActions.CanTrick = possibleActions.CardActions.Any <CardActions>(a => !a.IsThrowable); } }
public Card SelectCard(ScopaGame game, AIScopaPlayer player) { if (selection.SelectedCard != null && player.IsHolding((Card)selection.SelectedCard)) { return((Card)selection.SelectedCard); } return((Card)(selection.SelectedCard = player.Hand[(int)Random.Default.Ranged(player.Hand.Count)])); }
public AbstractScopaPlayer(string name, ScopaGame game) { this.game = game; this.name = name; hand = new List <Card>(); trickTracker = new TrickTracker(); points = 0; roundScore = 0; }
public List <Card> SelectTrick(ScopaGame game, AIScopaPlayer player, Card selectedCard) { if (selection.SelectedCard != null && player.IsHolding((Card)selection.SelectedCard)) { return(selection.SelectedTrick); } selection = DoTrickSelection(game, player, selectedCard); return(selection.SelectedTrick); }
public Card SelectCard(ScopaGame game, AIScopaPlayer player) { if (selection.SelectedCard != null && player.IsHolding((Card)selection.SelectedCard)) { return((Card)selection.SelectedCard); } DoSelection(game, player); return((Card)selection.SelectedCard); }
public List <Card> SelectTrick(ScopaGame game, AIScopaPlayer player, Card selectedCard) { if (selection.SelectedCard != null && player.IsHolding((Card)selection.SelectedCard)) { return(selection.SelectedTrick); } List <List <Card> > possibleTricks = game.PossibleActions[selectedCard].PossibleTricks; return(selection.SelectedTrick = possibleTricks[(int)Random.Default.Ranged(possibleTricks.Count)]); }
/// <summary> /// Validate the card thrown against the cards on the table to assure that it can not /// take a trick from the cards that are on the table. /// </summary> /// <param name="set">The set of cards to validate the possible throw against</param> /// <param name="thrownCard">The card being thrown from the players hand</param> /// <returns>Flag indicating the validity of the throw (i.e. if it is possible or not)</returns> public static bool ValidateThrow(List <Card> set, Card thrownCard) { Debug.Assert(set != null); // If there is a card of equal value on the table it is not a valid throw List <Card> table = new List <Card>(set); if (!table.Any <Card>(a => (int)a == (int)thrownCard)) { // If there is any combination of cards of equal value to the thrown card is it not a valid throw return(!ScopaGame.Enumerate(table, thrownCard)); } return(false); }
private Card DoSelection(ScopaGame game, AIScopaPlayer player) { if (player.Hand.Count == 1) { selection = DoTrickSelection(game, player, (Card)player.Hand[0]); return((Card)selection.SelectedCard); } List <Card> playable = player.Hand.FindAll(a => !game.PossibleActions[a].IsThrowable); if (playable.Count > 0) { // Always take the Sette Bello if (playable.Contains <Card>(Card.SetteBello)) { selection = DoTrickSelection(game, player, Card.SetteBello); return(Card.SetteBello); } List <WeightedSelection> possibles = new List <WeightedSelection>(); foreach (Card card in playable) { possibles.Add(DoTrickSelection(game, player, card)); } List <WeightedSelection> actuals = Utilities.MaximumElements <WeightedSelection>(possibles, a => a.Weight); selection = actuals[0]; return((Card)actuals[0].SelectedCard); } // All cards in hand are throwable Card?bestThrow = null; int maxWeight = Int32.MinValue; foreach (Card card in player.Hand) { // TODO: This does not take into account that throwing a card can enable a trick, // which should be given more weight than throwing a card that does not do so. int weight = -CalculateWeight(player, card, new List <Card> (), false); if (weight > maxWeight) { bestThrow = card; maxWeight = weight; } } selection = new WeightedSelection(); selection.SelectedCard = bestThrow; selection.SelectedTrick = new List <Card> (); selection.Weight = maxWeight; return((Card)bestThrow); }
public WeightedTreeNode BuildTree(ScopaGame game, IScopaPlayer player, int maxDepth) { WeightedTreeNode root = new WeightedTreeNode(null); GameState state = new GameState(); state.Table = game.Table; state.PossibleActions = game.PossibleActions; state.Tracker = player.GetPossibleScores(new List <Card>(), false); state.Hand = new List <Card>(player.Hand); List <object[]> queue = new List <object[]>() { new object[] { root, state, 0, }, }; while (queue.Count > 0) { WeightedTreeNode currNode = queue[0][0] as WeightedTreeNode; GameState currState = queue[0][1] as GameState; int depth = (int)(queue[0][1] as int?); queue.RemoveAt(0); if (depth > 0 && depth < maxDepth) { WeightedSelection selection = DoLevelSelection(currState); List <Card> trick = new List <Card>(selection.SelectedTrick); trick.Add((Card)selection.SelectedCard); GameState childState = new GameState(); childState.Table = new List <Card>(game.Table); childState.Table.RemoveAll(a => trick.Contains(a)); childState.PossibleActions = new PlayerActions(); // AbstractScopaGame.EnumerateAll(childState.Table, selection.SelectedCard); childState.Tracker = currState.Tracker.GetPossibleScores(trick, currState.Table.Count == selection.SelectedTrick.Count); childState.Hand = new List <Card>(currState.Hand); childState.Hand.Remove((Card)selection.SelectedCard); queue.Add(new object[] { new WeightedTreeNode(currNode), childState, depth + 1, }); currNode.Selection = selection; } } return(root); }
private WeightedSelection DoTrickSelection(ScopaGame game, AIScopaPlayer player, Card selectedCard) { List <List <Card> > possibleTricks = game.PossibleActions[selectedCard].PossibleTricks; List <Card> bestTrick = null; int maxWeight = Int32.MinValue; foreach (List <Card> trick in possibleTricks) { int weight = CalculateWeight(player, selectedCard, trick, game.Table.Count == trick.Count); if (weight > maxWeight) { bestTrick = trick; maxWeight = weight; } } WeightedSelection selection = new WeightedSelection(); selection.SelectedCard = selectedCard; selection.SelectedTrick = bestTrick; selection.Weight = maxWeight; return(selection); }
public AIScopaPlayer(string name, ScopaGame game) : base(name, game) { // selector = new RandomSelectorAI(); selector = new WeightedSelectorAI(); }
public AIScopaPlayer(ScopaGame game) : this("Computer", game) { }
public List <Card> SelectTrick(ScopaGame game, AIScopaPlayer player, Card selectedCard) { List <List <Card> > possibleTricks = game.PossibleActions[selectedCard].PossibleTricks; return(possibleTricks[0]); }
public Card SelectCard(ScopaGame game, AIScopaPlayer player) { return(player.Hand[0]); }
/// <summary> /// Validate the card thrown against the cards on the table to assure that it can not /// take a trick from the cards that are on the table. /// </summary> /// <param name="thrownCard">The card being thrown from the players hand</param> /// <returns>Flag indicating the validity of the throw (i.e. if it is possible or not)</returns> public bool ValidateThrow(Card thrownCard) { return(ScopaGame.ValidateThrow(table, thrownCard)); }
public UIScopaPlayer(string name, ScopaGame game, IPlaySelection selection) : base(name, game) { this.selection = selection; }
/// <summary> /// Validate the card being played from the players hand can take the cards in the trick. /// It is not valid to take a trick in the following cases: /// A trick whose sum of the value of the cards does not equal the value of the card used to play the trick. /// A trick that consists of multiple cards when the is a card of equals value to the card being played on the table. /// A trick that does not contain any cards from the table. /// </summary> /// <param name="playedCard">The card being played from the players hand</param> /// <param name="trickSet">The set of cards from the table involved in the trick</param> /// <returns>Flag indicating the validity of the trick (i.e. is it is possible or not)</returns> public bool ValidateTrick(Card playedCard, List <Card> trickSet) { return(ScopaGame.ValidateTrick(table, playedCard, trickSet)); }