public void Play(IEnumerable<IBlackjackPlayer> players)
{
_shoe.Shuffle(SHUFFLES_PER_SHOE);
foreach (var player in players)
player.Reshuffle();
bool[] done = new bool[players.Count()];
while (done.Count(d => d == false) > 0)
{
if (_shoe.CardsDealt >= Settings.MinCardsDealtBeforeReshuffle)
{
_shoe.Shuffle(SHUFFLES_PER_SHOE);
foreach (var player in players)
player.Reshuffle();
}
//get bets
List<PlayerHand> hands = new List<PlayerHand>();
for (int i = 0; i < players.Count(); i++)
{
if (done[i])
continue;
var player = players.ElementAt(i);
bool play = player.PlayAnotherHand();
if (!play)
{
done[i] = true;
continue;
}
var bet = player.GetBet(Settings.MinimumBet, Settings.MaximumBet);
if (bet < Settings.MinimumBet)
bet = Settings.MinimumBet;
else if (bet > Settings.MaximumBet)
bet = Settings.MaximumBet;
hands.Add(new PlayerHand()
{
Player = player,
Bet = bet
});
}
//deal cards
foreach (var hand in hands)
{
hand.AddCard(_shoe.NextCard());
hand.AddCard(_shoe.NextCard());
}
DealerHand dealerHand = new DealerHand();
dealerHand.HiddenCard = _shoe.NextCard();
dealerHand.AddCard(_shoe.NextCard());
HandInfo info = new HandInfo()
{
DealerHand = dealerHand,
PlayerHands = hands
};
try
{
#region offer insurance
if (Settings.InsuranceOffered && dealerHand.Cards.ElementAt(0).Rank == Ranks.Ace)
{
for (int i = 0; i < hands.Count; i++)
{
if (hands[i].Finished)
continue;
info.HandToPlay = i;
if (hands[i].Player.BuyInsurance(info))
{
hands[i].Insured = true;
hands[i].Won -= hands[i].Bet * Settings.InsuranceCost;
}
}
//payoff insurance --> everyone else loses
if (dealerHand.HiddenCard.HighValue == 10)
{
dealerHand.FlipHiddenCard();
foreach (var hand in hands)
{
if (hand.Insured)//payoff insurance bets
hand.Won += hand.Bet * Settings.InsuranceCost * Settings.InsurancePayoff;
if (hand.Value == 21)//blackjack pushes
hand.Won += hand.Bet;
hand.Finished = true;//game's over
}
}
}
#endregion
//payoff blackjacks --> remove from hand
foreach (var hand in hands)
{
if (hand.Finished)
continue;
if (hand.Value == 21)
{
hand.Won += hand.Bet * Settings.BlackjackPayoff;
hand.Finished = true;
}
}
//each player acts
for (int i = 0; i < hands.Count; i++)
{
if (hands[i].Finished)
continue;
info.HandToPlay = i;
var hand = hands[i];
//accept surrenders
if (CanSurrender(hand))
{
if (hand.Player.Surrender(info))
{
hand.Won = Settings.SurrenderPayoff * hand.Bet;
hand.Finished = true;
continue;
}
}
//split loop
if (CanSplit(hand) && hand.Player.Split(info))
{
var secondHand = hand.Split();
hand.AddCard(_shoe.NextCard());
secondHand.AddCard(_shoe.NextCard());
hands.Insert(i + 1, secondHand);
i--;
hand.Player.Splits++;
continue;
}
//double down
if (CanDoubleDown(hand) && hand.Player.DoubleDown(info))
{
hand.Bet *= 2;
hand.AddCard(_shoe.NextCard());
if (hand.Value > 21)
hand.Finished = true;
continue;
}
//hit/stand loop
while (!hand.Finished && CanHit(hand) && hand.Player.Hit(info))
{
var next = _shoe.NextCard();
hand.AddCard(next);
if (hand.Value > 21)
hand.Finished = true;
}
}
//dealer acts (only if everyone hasn't busted or hit BJ)
if (hands.Count(h => !h.Finished) > 0)
{
dealerHand.FlipHiddenCard();
while (DealerMustHit(dealerHand))
dealerHand.AddCard(_shoe.NextCard());
//if the dealer busted, everyone wins
if (dealerHand.Value > 21)
{
foreach (var hand in hands)
if (!hand.Finished)
hand.Won += hand.Bet * 2;
}
else
{
//if the dealer didn't bust, then players win if they're closer to 21
foreach (var hand in hands)
if (!hand.Finished)
{
if (hand.Value > dealerHand.Value)
hand.Won += hand.Bet * 2;
else if (hand.Value == dealerHand.Value)
hand.Won += hand.Bet;
}
}
}
}
catch (Exception e)
{
LogError(info);
throw new Exception("", e);
}
foreach (var hand in hands)
hand.Player.Profit += hand.Won - hand.Bet;
for (int i = 0; i < done.Length; i++)
if (!done[i])
{
players.ElementAt(i).HandOver(info);
players.ElementAt(i).Splits = 0;
}
}
}