Adding the view wrapper
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.
Making the connections
Complete the BlackJackGameView part by switching back to the Composition Editor and making the following connections.
Connect the clicked event of the New hand menu item to the deal script.
Connect the clicked event of the New player menu item to the newPlayer script.
Connect the clicked event of the New deck menu item to the reshuffle script.
Connect the isEmpty event of the Deal Deck part to the click action of the New deck menu item.
When you finish, your connections should look like this:
BlackJackGame with connections
Save the part.
Last modified date: 06/11/2018