public void Play(IEnumerable <IBlackjackPlayer> players)
{
_shoe.Shuffle(SHUFFLES_PER_SHOE);
bool[] done = new bool[players.Count()];
while (done.Count(d => d == false) > 0)
{
if (_shoe.CardsDealt >= Settings.MinCardsDealtBeforeReshuffle)
{
_shoe.Shuffle(SHUFFLES_PER_SHOE);
}
//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
};
#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))
{
hands[i].Won = Settings.SurrenderPayoff * hands[i].Bet;
hands[i].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--;
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 (CanHit(hand) && hand.Player.Hit(info))
{
hand.AddCard(_shoe.NextCard());
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;
}
}
}
}
}
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);
}
}
}
}