Now that the BlackJackPlayerView is complete, we need to make the final changes to the BlackJackGameView so it can create and access multiple player hands.
Open the Composition Editor for the BlackJackGameView visual part. Add an Ordered Collection part and change its name to Players. This part will keep track of all players that are created.
Add a View Wrapper part to the free-form surface. Change its type to BlackJackPlayerView. Change its name to Player Hand.
Switch to the Script Editor view and add the playerCount, playerCount:, newPlayer, deal, and reshuffle scripts.
playerCount "Answer the player count." playerCount == nil ifTrue: [self playerCount: 0]. ^playerCount
The playerCount script is used in computing a player's name.
playerCount: anInteger "Save the player count." playerCount := anInteger.
The playerCount: script is used to maintain the count of players that have been created.
newPlayer "Create a new player hand window and an empty card deck to go with it. Add the new player hand to the ordered collection of player hands." | count hand | count := self playerCount. self playerCount: (count + 1). hand := CardDeck new.
BlackJackPlayerView new valueOfAttributeNamed: #name selector: #'IS_name' ifAbsent: [] put: ('Player ', count printString); valueOfAttributeNamed: #playerHand selector: #'IS_playerHand' ifAbsent: [] put: hand; valueOfAttributeNamed: #cardDeck selector: #'IS_cardDeck' ifAbsent: [] put: (self subpartNamed: 'Deal Deck'); openOwnedWidget.
(self subpartNamed: 'Players') abtPerformAction: #add: with: hand.
deal "Remove the cards from each hand and place them in the discard deck face-up. Deal each player 2 new cards, one face-down and the other face-up. Use a temporary card deck when manipulating the decks to minimize screen painting and improve performance." | oc tempDeck | oc := (self subpartNamed: 'Players') abtAtAttribute: #self. tempDeck := CardDeck new. oc do: [:hand | hand moveCards: (hand deck) to: tempDeck]. tempDeck faceUp: true. tempDeck moveCards: (tempDeck deck) to: (self subpartNamed: 'Discard Deck').
oc do: [:hand | (self subpartNamed: 'Deal Deck') deck size < 2 ifTrue: [self reshuffle]. (self subpartNamed: 'Deal Deck') deal: 2 to: tempDeck. tempDeck faceUp: false. tempDeck deck first faceUp: true. tempDeck moveCards: (tempDeck deck) to: hand.]
reshuffle "Move all cards from the discard deck to the deal deck and reshuffle it." (self subpartNamed: 'Discard Deck') faceUp: (self subpartNamed: 'Deal Deck') faceUp. (self subpartNamed: 'Discard Deck') moveCards: ((self subpartNamed: 'Discard Deck') deck) to: (self subpartNamed: 'Deal Deck'). (self subpartNamed: 'Deal Deck') shuffle.
Complete the BlackJackGameView part by switching back to the Composition Editor and making the following connections.
When you finish, your connections should look like this:
Save the part.