/// <summary> /// Called by the engine when a player needs to make a bet. /// Derived classes must place player betting logic in overriden implementation. /// </summary> /// <param name="player">The current player which needs to bet</param> /// <param name="action">The player betting action which contains the current betting restrictions</param> /// <remarks> /// The action must be used to notify the engine of the player action. In the derived implementation take notice to /// the action <see cref="PlayerBettingAction.IsAllInMode"/>, <see cref="PlayerBettingAction.CanRaise"/> and /// <see cref="PlayerBettingAction.RaiseAmount"/> (which holds the minimal raise amount at first) /// </remarks> public void WaitPlayerBettingAction(Player player, PlayerBettingAction action) { Player safeCopy = GetSafePlayer(player); forEachBut(player, (cur) => cur.NotifyPlayerIsThinking(safeCopy)); PlayerBettingAction result = waitAction <PlayerBettingAction>(player, (cur) => cur.WaitPlayerBettingAction(player, action)); // if the request failed, fold the player if (result == null) { action.Fold(); } else { // pass the response back to the action switch (result.Action) { case BetAction.CheckOrCall: action.Call(); break; case BetAction.Fold: action.Fold(); break; case BetAction.Raise: action.Raise(result.RaiseAmount); break; } } }
/// <summary> /// Called by the client when a bet decision should be made. /// </summary> /// <param name="player">The automated player. /// </param> /// <param name="action">The betting action which must be modified to pass the client response</param> /// <remarks> /// The limit strategy looks at the hand value first. If it is low, /// the player will fold when the money needed to bet is below the limit. When the hand value is high, the player will call for /// the first couple of times and will raise for the rest /// </remarks> public override void Bet(Player player, PlayerBettingAction action) { // check to see the player hand Hand hand = client.GetBestHand(player.Cards); // the hand good, call at first and raise near the end. if (hand.Family.FamilyValue > 3) { if (synchTimes < 5) { action.Call(); } else { action.Raise(action.RaiseAmount); } } else // the hand is bad, watch for the limit { if (action.CallAmount > 0 && player.Money - action.CallAmount < preparedLimit) { action.Fold(); } else { action.Call(); } } }
/// <summary> /// Called by the client when a bet decision should be made. /// </summary> /// <param name="player">The automated player. /// </param> /// <param name="action">The betting action which must be modified to pass the client response</param> /// <remarks> /// Looks at the current bet and folds if the bet amount will reduce the player money below the deined limit. /// </remarks> public override void Bet(Player player, PlayerBettingAction action) { if (action.CallAmount > 0 && player.Money - action.CallAmount < preparedLimit) { action.Fold(); } else { action.Call(); } }
/// <summary> /// Called by the client to get the current player betting action. Derived classes must implement it and respond with a /// proper action /// </summary> /// <param name="player">The player which needs to bet</param> /// <param name="action">The action to use to pass the player response</param> public void WaitPlayerBettingAction(Player player, PlayerBettingAction action) { Console.WriteLine("===================="); Console.WriteLine("{0}, would you like to:", player.Name); // the index which will be the fold action: int foldIndex = 3; if (!action.CanRaise) { foldIndex = 2; // no "raise", fold will be in 2. } if (action.CallAmount == 0) { // no amount of money to call, only check Console.WriteLine("1. Check."); } else if (action.IsAllInMode && action.CanRaise) { // the action is all in, can't check or call less than the player amount of money Console.WriteLine("1. All In {0}$", player.Money); // no "raise" fold will be in 2 foldIndex = 2; } else { // there is an amount of money to call, print it: Console.WriteLine("1. Call {0}$", action.CallAmount); } if (!action.IsAllInMode && action.CanRaise) { // can raise, print the minimal amount Console.WriteLine("2. Raise {0}$", action.RaiseAmount); } // can always fold: Console.WriteLine("{0}. Fold", foldIndex); if (!action.IsAllInMode && action.CanRaise) { // when the player isn't forced to go "all in", it is the last option. Console.WriteLine("4. All In {0}$", player.Money); } Console.WriteLine("Enter a choice number or another amount to RAISE"); int option; // loop until a valid int is parsed while (!int.TryParse(Console.ReadLine(), out option)) { Console.WriteLine("[only numbers]"); } // handle the user result: switch (option) { case 1: action.Call(); break; case 2: // fold or raise: if (foldIndex == 2) { action.Fold(); } else { action.Raise(action.RaiseAmount); } break; case 3: action.Fold(); break; case 4: // raise or call: if (action.CanRaise) { action.Raise(player.Money - action.CallAmount); } else { action.Call(); } break; default: // verify other manual options if (option < action.CallAmount || !action.CanRaise) { // can't raise, or the raise amount is lower than the call amount. change the option to call. action.Call(); } else if (option < action.RaiseAmount) { // validate an amount which is lower than the minimal raise. option = action.RaiseAmount; } // in any case of a raise, make sure not to raise an amount which exceeds the player money. if (option > player.Money - action.CallAmount) { option = player.Money - action.CallAmount; } if (action.Action != BetAction.CheckOrCall) { action.Raise(option); } break; } }