public void SetActionForPair(Card.Ranks upcardRank, Card.Ranks pairRank, ActionToTake action) { int upIndex = IndexFromRank(upcardRank); int pairIndex = IndexFromRank(pairRank); pairsStrategy[upIndex, pairIndex] = action; }
public void EnsureNextCardIsnt(Card.Ranks rank) { // similar to ForceNextCardToBe, this is used for stacking the deck while (Cards[currentCard].Rank == rank) { currentCard++; ShuffleIfNeeded(); } }
private void LoadPairHolding(Card.Ranks pairRank, string actionString) { var actions = GetActionsFromString(actionString); for (int i = 0; i < actions.Count; i++) { SetActionForPair(i, IndexFromRank(pairRank), actions[i]); } }
public int IndexFromRank(Card.Ranks rank) { // we collapse certain ranks together because they're the same value switch (rank) { case Card.Ranks.Ace: return(9); case Card.Ranks.King: case Card.Ranks.Queen: case Card.Ranks.Jack: case Card.Ranks.Ten: return(8); case Card.Ranks.Nine: return(7); case Card.Ranks.Eight: return(6); case Card.Ranks.Seven: return(5); case Card.Ranks.Six: return(4); case Card.Ranks.Five: return(3); case Card.Ranks.Four: return(2); case Card.Ranks.Three: return(1); case Card.Ranks.Two: return(0); } throw new InvalidOperationException(); }
public void ForceNextCardToBe(Card.Ranks rank) { // this function used when stacking the deck // it compensates for the fact that pairs and soft hands don't happen that often, // we may wish to force a card to be dealt next // first, look for the rank in the remaining cards int foundAt = -1; for (int i = currentCard; i < Cards.Count; i++) { if (Cards[i].Rank == rank) { foundAt = i; break; } } // if not found, start over from the start of the deck if (foundAt == -1) { for (int i = 0; i < currentCard; i++) { if (Cards[i].Rank == rank) { foundAt = i; break; } } } // now swap that card with the next-to-be-dealt Card temp = Cards[foundAt]; Cards[foundAt] = Cards[currentCard]; Cards[currentCard] = temp; }
private CandidateSolution <bool, ProblemState> FindStrategyForUpcard(Card dealerCard) { currentDealerUpcardRank = dealerCard.Rank; // create the engine. each tree (and node within the tree) will return a bool. // we also indicate the type of our problem state data (used by terminal functions and stateful functions) var engine = new Engine <bool, ProblemState>(settings.GPsettings); // for a boolean tree, we use the standard operators engine.AddFunction((a, b) => a || b, "Or"); engine.AddFunction((a, b, c) => a || b || c, "Or3"); engine.AddFunction((a, b) => a && b, "And"); engine.AddFunction((a, b, c) => a && b && c, "And3"); engine.AddFunction((a) => !a, "Not"); // then add functions to indicate a strategy engine.AddStatefulFunction(SplitIf, "SplitIf"); engine.AddStatefulFunction(HitIf, "HitIf"); engine.AddStatefulFunction(StandIf, "StandIf"); engine.AddStatefulFunction(DoubleIf, "DoubleIf"); // details of pair engine.AddTerminalFunction(HasPairTwos, "HasPair2"); engine.AddTerminalFunction(HasPairThrees, "HasPair3"); engine.AddTerminalFunction(HasPairFours, "HasPair4"); engine.AddTerminalFunction(HasPairFives, "HasPair5"); engine.AddTerminalFunction(HasPairSixes, "HasPair6"); engine.AddTerminalFunction(HasPairSevens, "HasPair7"); engine.AddTerminalFunction(HasPairEights, "HasPair8"); engine.AddTerminalFunction(HasPairNines, "HasPair9"); engine.AddTerminalFunction(HasPairTens, "HasPairT"); engine.AddTerminalFunction(HasPairAces, "HasPairA"); // terminal functions to indicate the other card's rank engine.AddTerminalFunction(AcePlus2, "AcePlus2"); engine.AddTerminalFunction(AcePlus3, "AcePlus3"); engine.AddTerminalFunction(AcePlus4, "AcePlus4"); engine.AddTerminalFunction(AcePlus5, "AcePlus5"); engine.AddTerminalFunction(AcePlus6, "AcePlus6"); engine.AddTerminalFunction(AcePlus7, "AcePlus7"); engine.AddTerminalFunction(AcePlus8, "AcePlus8"); engine.AddTerminalFunction(AcePlus9, "AcePlus9"); // hard hand totals engine.AddTerminalFunction(HandVal5, "Hard5"); engine.AddTerminalFunction(HandVal6, "Hard6"); engine.AddTerminalFunction(HandVal7, "Hard7"); engine.AddTerminalFunction(HandVal8, "Hard8"); engine.AddTerminalFunction(HandVal9, "Hard9"); engine.AddTerminalFunction(HandVal10, "Hard10"); engine.AddTerminalFunction(HandVal11, "Hard11"); engine.AddTerminalFunction(HandVal12, "Hard12"); engine.AddTerminalFunction(HandVal13, "Hard13"); engine.AddTerminalFunction(HandVal14, "Hard14"); engine.AddTerminalFunction(HandVal15, "Hard15"); engine.AddTerminalFunction(HandVal16, "Hard16"); engine.AddTerminalFunction(HandVal17, "Hard17"); engine.AddTerminalFunction(HandVal18, "Hard18"); engine.AddTerminalFunction(HandVal19, "Hard19"); engine.AddTerminalFunction(HandVal20, "Hard20"); // pass a fitness evaluation function and run engine.AddFitnessFunction((t) => EvaluateCandidate(t)); // and add something so we can track the progress engine.AddProgressFunction((p, b) => PerGenerationCallback(p, b)); return(engine.FindBestSolution()); }
private bool HasPairOf(Card.Ranks rankNeeded, Hand hand) { return((hand.Cards.Count == 2) && (hand.Cards[0].Rank == rankNeeded) && (hand.Cards[1].Rank == rankNeeded)); }
private static void AddStrategyForUpcard(Card.Ranks upcardRank, Strategy result, CandidateSolution <bool, ProblemState> candidate) { Card dealerCard = new Card(upcardRank, Card.Suits.Diamonds); // do pairs for (var pairedRank = Card.Ranks.Ace; pairedRank >= Card.Ranks.Two; pairedRank--) { // build player hand Hand playerHand = new Hand(); playerHand.AddCard(new Card(pairedRank, Card.Suits.Hearts)); playerHand.AddCard(new Card(pairedRank, Card.Suits.Spades)); // find strategy SetupStateData(candidate.StateData, playerHand, dealerCard); candidate.Evaluate(); // get the decision and store in the strategy object var action = GetActionFromCandidate(candidate.StateData); result.SetActionForPair(upcardRank, pairedRank, action); } // then soft hands // we don't start with Ace, because that would be AA, which is handled in the pair zone // we also don't start with 10, since that's blackjack. So 9 is our starting point for (int otherCard = 9; otherCard > 1; otherCard--) { // build player hand Hand playerHand = new Hand(); // first card is an ace, second card is looped over playerHand.AddCard(new Card(Card.Ranks.Ace, Card.Suits.Hearts)); playerHand.AddCard(new Card((Card.Ranks)otherCard, Card.Suits.Spades)); // find strategy SetupStateData(candidate.StateData, playerHand, dealerCard); candidate.Evaluate(); // get the decision and store in the strategy object var action = GetActionFromCandidate(candidate.StateData); result.SetActionForSoftHand(upcardRank, otherCard, action); } // hard hands. for (int hardTotal = 20; hardTotal > 4; hardTotal--) { // build player hand Hand playerHand = new Hand(); // divide by 2 if it's even, else add one and divide by two int firstCardRank = ((hardTotal % 2) != 0) ? (hardTotal + 1) / 2 : hardTotal / 2; int secondCardRank = hardTotal - firstCardRank; // 20 is always TT, which is a pair, so we handle that by building a 3 card hand if (hardTotal == 20) { playerHand.AddCard(new Card(Card.Ranks.Ten, Card.Suits.Diamonds)); firstCardRank = 6; secondCardRank = 4; } // we don't want pairs, so check for that if (firstCardRank == secondCardRank) { firstCardRank++; secondCardRank--; } playerHand.AddCard(new Card((Card.Ranks)firstCardRank, Card.Suits.Diamonds)); playerHand.AddCard(new Card((Card.Ranks)secondCardRank, Card.Suits.Spades)); // find strategy SetupStateData(candidate.StateData, playerHand, dealerCard); candidate.Evaluate(); // get the decision and store in the strategy object var action = GetActionFromCandidate(candidate.StateData); result.SetActionForHardHand(upcardRank, hardTotal, action); } }
public void Set_card(Card.Ranks ran, Card.Suits sui, bool reveal) { card_in_component.Set_card(ran, sui, reveal); update_card_sprite(); }
//public Card.Suits debug_suit; ////{ //// get { return card_in_component.get_suit(); } //// set { set_suit(value); } ////} //public Card.Ranks debug_rank; ////{ //// get { return card_in_component.get_rank(); } //// set { set_rank(value); } ////} //public bool revelation; public void set_rank(Card.Ranks ran) { card_in_component.set_rank(ran); update_card_sprite(); }
public void SetActionForHardHand(Card.Ranks upcardRank, int hardTotal, ActionToTake action) { int upIndex = IndexFromRank(upcardRank); hardStrategy[upIndex, hardTotal] = action; }
public void SetActionForSoftHand(Card.Ranks upcardRank, int softRemainder, ActionToTake action) { int upIndex = IndexFromRank(upcardRank); softStrategy[upIndex, softRemainder] = action; }