// Function: bkw_DoWork // Runs the BlackJack game private void bkw_DoWork(object sender, DoWorkEventArgs e) { // create a shoe of cards containing 7 decks shoe = new CardStack(7); // shuffle the shoe shoe.Shuffle(); // create dealer's hand CardStack dealerCards = new CardStack(); // loop until cancelled while (!bkw.CancellationPending) { // if shoe contains 52 cards or less, then reset the shoe to 7 decks if (shoe.Count() <= 52) { // reset (refill with cards) shoe.Reset(); // shuffle cards shoe.Shuffle(); } // update server GUI UpdateCardsLeft(shoe.Count()); // create copy of current player list so that it doesn't change during the round List <Player> thisRoundPlayers = new List <Player>(playerList); foreach (Player serverPlayer in thisRoundPlayers) { if (!serverPlayer.isPlaying) { playerList.Remove(serverPlayer); } } // if no players, then stop the game if (playerList.Count == 0) { return; } // create copy of current player list so that it doesn't change during the round thisRoundPlayers = new List <Player>(playerList); // get each player's bet foreach (Player serverPlayer in thisRoundPlayers) { if (serverPlayer.GetMoney() <= 0) { serverPlayer.OutOfMoney(); DisconnectPlayer(serverPlayer); continue; } // ask for player's bet serverPlayer.AskForBet(); string[] playerMessage; try { // split the message to parse it playerMessage = serverPlayer.Read().Split(":".ToCharArray()); } catch { // remove them from the lists if (playerList.Contains(serverPlayer)) { playerList.Remove(serverPlayer); } // mark player as not playing serverPlayer.isPlaying = false; // update status to disconnected SetPlayerStatus(serverPlayer.GetPlayerNum(), "Disconnected"); // go to next player continue; } // if disconnected if (playerMessage[0] == "disconnect") { // disconnected them DisconnectPlayer(serverPlayer); // go to next player continue; } // get bet from the player if (playerMessage[0] != "bet") { throw new Exception("expected a bet."); } int bet; // parse the second part of message for bet amount if (!int.TryParse(playerMessage[1], out bet)) { throw new Exception("expected a number for the bet."); } // clear their hand serverPlayer.ClearCards(); try { // place the bet PlayerBet(serverPlayer, bet); } catch { // disconnect them DisconnectPlayer(serverPlayer); // go to next player continue; } } // give each player first card foreach (Player serverPlayer in thisRoundPlayers) { // give them the card GivePlayerCard(serverPlayer, shoe.DrawCard()); // update server GUI UpdateCardsLeft(shoe.Count()); } // give each player 2nd card and, if they hit, other cards foreach (Player serverPlayer in thisRoundPlayers) { string playerMessage = ""; do { // give them a card GivePlayerCard(serverPlayer, shoe.DrawCard()); // update cards left server GUI UpdateCardsLeft(shoe.Count()); // stop if busted if (serverPlayer.GetPoints() >= 21) { break; } // ask for hit or stand serverPlayer.AskHitOrStand(); try { // get their response playerMessage = serverPlayer.Read(); } catch { // disconnected player DisconnectPlayer(serverPlayer); // go to next player continue; } // while they hit, haven't busted, and have less than 5 cards: keep dealing them cards } while (playerMessage == "hit" && serverPlayer.GetPoints() <= 21 && serverPlayer.GetCards().Count() < 5); // check if they busted if (serverPlayer.GetPoints() > 21) { serverPlayer.Bust(); } // if disconnect message else if (playerMessage == "disconnect") { // disconnect them DisconnectPlayer(serverPlayer); } // check if they gave a bad response else if (playerMessage != "stand" && playerMessage != "hit" && playerMessage != "" && playerMessage != null) { throw new Exception("expected hit, stand, or disconnect response"); } } // check if all players busted bool allBusted = true; foreach (Player serverPlayer in thisRoundPlayers) { allBusted = allBusted && serverPlayer.IsBusted(); } // If all players busted, the hand ends automatically without the dealer having to play their hand if (allBusted) { foreach (Player serverPlayer in thisRoundPlayers) { theServer.SendAll(serverPlayer.GetPlayerNum() + ":lost"); } // clear each player's hand foreach (Player serverPlayer in thisRoundPlayers) { serverPlayer.Clear(); ClearCardList(serverPlayer.GetPlayerNum()); } // clear dealer's hand dealerCards.Clear(); ClearCardList(-100); // end this round theServer.SendAll("roundover"); continue; } // if not all players busted: // give dealer first card Card drawnCard = shoe.DrawCard(); dealerCards.Add(drawnCard); // update cards left label UpdateCardsLeft(shoe.Count()); // send card to clients theServer.SendAll("dealer:card:" + drawnCard.GetSymbol() + ":" + drawnCard.GetSuit()); // give dealer second card, and hit while points < 17 do { // draw card from the shoe drawnCard = shoe.DrawCard(); // add the card to dealer's hand dealerCards.Add(drawnCard); // send the card to clients theServer.SendAll("dealer:card:" + drawnCard.GetSymbol() + ":" + drawnCard.GetSuit()); // update server GUI AddCardToList(listBox_Dealer, drawnCard); UpdateCardsLeft(shoe.Count()); } while (dealerCards.GetPoints() < 17); // check if dealer busted bool dealerBusted = !(dealerCards.GetPoints() <= 21); // check for winners foreach (Player serverPlayer in thisRoundPlayers) { // if player got blackjack and dealer did not, then 3 to 2 bet return if ((serverPlayer.GetCards().Count == 2) && (serverPlayer.GetPoints() == 21) && ((dealerCards.GetPoints() != 21) || dealerBusted)) { // calculate new amount of money int newMoney = serverPlayer.GetMoney() + serverPlayer.GetBet() + (3 / 2) * serverPlayer.GetBet(); // set player's bet to 0 PlayerBet(serverPlayer, 0); // update gui and send money to clients UpdatePlayerMoney(serverPlayer, newMoney); // send clients message that this player won with a "blackjack" theServer.SendAll(serverPlayer.GetPlayerNum() + ":blackjack"); } // if dealer busted and player did not, or neither busted but player got more points, then 1 to 1 bet return else if ((dealerBusted || (serverPlayer.GetPoints() > dealerCards.GetPoints())) && !serverPlayer.IsBusted()) { // calculate new amount of money int newMoney = serverPlayer.GetMoney() + 2 * serverPlayer.GetBet(); // set player's bet to 0 PlayerBet(serverPlayer, 0); // update gui and send money to clients UpdatePlayerMoney(serverPlayer, newMoney); // send clients message that this player won theServer.SendAll(serverPlayer.GetPlayerNum() + ":won"); } // if tied (push), then just return bet else if ((dealerCards.GetPoints() <= 21) && (serverPlayer.GetPoints() == dealerCards.GetPoints())) { // calculate new amount of money int newMoney = serverPlayer.GetMoney() + serverPlayer.GetBet(); // set player's bet to 0 PlayerBet(serverPlayer, 0); // update gui and send money to clients UpdatePlayerMoney(serverPlayer, newMoney); // send clients message that this player pushed theServer.SendAll(serverPlayer.GetPlayerNum() + ":push"); } // otherwise, player lost their bet else { // set player's bet to 0 PlayerBet(serverPlayer, 0); // send clients message that this player lost theServer.SendAll(serverPlayer.GetPlayerNum() + ":lost"); } } // clear each player's hand foreach (Player serverPlayer in thisRoundPlayers) { serverPlayer.Clear(); ClearCardList(serverPlayer.GetPlayerNum()); } // clear dealer's hand dealerCards.Clear(); ClearCardList(-100); // send round over message theServer.SendAll("roundover"); } }