Skip to content

Commit

Permalink
New version to check if the old is still working. Redoing everything …
Browse files Browse the repository at this point in the history
…following the booklet (to be updated).
  • Loading branch information
Ducasse committed Feb 20, 2021
1 parent 3cbc875 commit abaa651
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/BaselineOfMemory/BaselineOfMemory.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Class {
#name : #BaselineOfMemory,
#superclass : #BaselineOf,
#category : #BaselineOfMemory
}

{ #category : #baselines }
BaselineOfMemory >> baseline: spec [
<baseline>

spec for: #'common' do: [
spec package: #'Bloc-Memory' ]

]
1 change: 1 addition & 0 deletions src/BaselineOfMemory/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : #BaselineOfMemory }
96 changes: 96 additions & 0 deletions src/Bloc-Memory/MGCard.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"
I am a card model that can be flipped to show its back or face.
When card is flipped on the face a player should see a symbol that is used to compare two cards.
!! Examples:
[[[
| cardModel |
cardModel := MGCard new symbol: $a.
cardModel flip.
cardModel disappear
]]]
"
Class {
#name : #MGCard,
#superclass : #Object,
#instVars : [
'symbol',
'flipped',
'announcer'
],
#category : #'Bloc-Memory-Model'
}

{ #category : #accessing }
MGCard >> announcer [
"Return my announcer that is used to notify my observers"

^ announcer ifNil: [ announcer := Announcer new ]
]

{ #category : #actions }
MGCard >> disappear [
"Ask card to disapper"

self notifyDisappear
]

{ #category : #actions }
MGCard >> flip [
"Flip the card on the other side (toggle flipped state)"

flipped := flipped not.
self notifyFlipped
]

{ #category : #initialization }
MGCard >> initialize [
super initialize.
flipped := false
]

{ #category : #testing }
MGCard >> isFlipped [
"Return true if card is flipped and its face (symbol) is visible, false otherwise"

^ flipped
]

{ #category : #notifying }
MGCard >> notifyDisappear [
"Notify all observers that I disappeared from the game"

self announcer announce: MGCardDisappearAnnouncement new
]

{ #category : #notifying }
MGCard >> notifyFlipped [
"Notify all observers that my flipped state was changed (from flipped to not or the other way around)"

self announcer announce: MGCardFlippedAnnouncement new
]

{ #category : #printing }
MGCard >> printOn: aStream [
aStream
nextPutAll: 'Card';
nextPut: Character space;
nextPut: $(;
nextPut: self symbol;
nextPut: $)
]

{ #category : #accessing }
MGCard >> symbol [
"Return a symbol that should be displayed when card is flipped and face is visible"

^ symbol
]

{ #category : #accessing }
MGCard >> symbol: aCharacter [
"Initialize the card with a given symbol as a character"

symbol := aCharacter
]
8 changes: 8 additions & 0 deletions src/Bloc-Memory/MGCardDisappearAnnouncement.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"
Is sent by ==MgdCardModel== after the card is removed from the ==MgdGameModel==
"
Class {
#name : #MGCardDisappearAnnouncement,
#superclass : #Announcement,
#category : #'Bloc-Memory-Events'
}
169 changes: 169 additions & 0 deletions src/Bloc-Memory/MGCardElement.class.st

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/Bloc-Memory/MGCardFlippedAnnouncement.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"
Is sent by ==MgdCardModel== after the card is flipped
"
Class {
#name : #MGCardFlippedAnnouncement,
#superclass : #Announcement,
#category : #'Bloc-Memory-Events'
}
158 changes: 158 additions & 0 deletions src/Bloc-Memory/MGGame.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
"
I am a memory game model
"
Class {
#name : #MGGame,
#superclass : #Object,
#instVars : [
'availableCards',
'chosenCards'
],
#category : #'Bloc-Memory-Model'
}

{ #category : #factory }
MGGame class >> withChinese [
^ self new initializeForSymbols: '为从公家里地个时'
]

{ #category : #factory }
MGGame class >> withEmoji [
^ self new initializeForSymbols: '💰🏡🎅🍪🍕🚀😸🙈'
]

{ #category : #factory }
MGGame class >> withNumbers [
^ self new initializeForSymbols: '12345678'
]

{ #category : #adding }
MGGame >> addCard: aCard [
"Add card to the list of available cards"

availableCards add: aCard
]

{ #category : #accessing }
MGGame >> availableCards [

^ availableCards
]

{ #category : #accessing }
MGGame >> cardsCount [
"Return how many cards there should be."

^ self gridSize * self gridSize
]

{ #category : #actions }
MGGame >> chooseCard: aCard [
"This is the main logic of the game.
The user pick a card, if this is a new one it is added to the chosen ones,
then flipped. At this point the game check if all the cards have been chosen and
if they are good, remove them.
Else the cards are flipped back and remove from the chosen list."

(self chosenCards includes: aCard)
ifTrue: [ ^ self ].
self chosenCards add: aCard.
aCard flip.
self shouldCompleteStep
ifTrue: [ ^ self completeStep ].
self shouldResetStep
ifTrue: [ self resetStep ]
]

{ #category : #testing }
MGGame >> chosenCardMatch [
"Return whether the chosen cards match."
"The implementation is handling the fact that we could want to have a game where more than two matches are needed e.g., three cards of the same symbol."

| firstCard |
firstCard := self chosenCards first.
^ self chosenCards allSatisfy: [ :aCard |
aCard isFlipped and: [ firstCard symbol = aCard symbol ] ]
]

{ #category : #accessing }
MGGame >> chosenCards [
^ chosenCards
]

{ #category : #actions }
MGGame >> completeStep [
"The player found the same cards so the step is complete. The cards should be removed from the board."

self chosenCards
do: [ :aCard | aCard disappear ];
removeAll.
]

{ #category : #accessing }
MGGame >> gridSize [
"Return grid size, total amount of card is gridSize^2"

^ 4
]

{ #category : #initialization }
MGGame >> initialize [
super initialize.

availableCards := OrderedCollection new.
chosenCards := OrderedCollection new
]

{ #category : #initialization }
MGGame >> initializeForSymbols: aCollectionOfCharacters [

"Initialize game model with the cards that are represented by character symbols taken from a given
collection of symbols.
Note, amount of characters must correspond to amount of possible card combinations
which is in fact = (total card count / how many card to match).
So, if grid size is 4, then total card count is 4^2 = 16. If player should match 2 cards,
then collection size must be 16 / 2 = 8"

aCollectionOfCharacters size = (self cardsCount / self matchesCount)
ifFalse: [ self error: 'Amount of characters must be equal to possible all combinations' ].

availableCards := (aCollectionOfCharacters asArray
collect: [ :aSymbol |
(1 to: self matchesCount) collect: [ :i |
MGCard new symbol: aSymbol ] ] ) flattened shuffled asOrderedCollection
]

{ #category : #accessing }
MGGame >> matchesCount [
"How many chosen cards should match to disappear"

^ 2
]

{ #category : #actions }
MGGame >> resetStep [
""

| lastCard |
lastCard := self chosenCards last.
self chosenCards
allButLastDo: [ :aCard | aCard flip ];
removeAll;
add: lastCard
]

{ #category : #testing }
MGGame >> shouldCompleteStep [
"Return true if current step should be completed, false otherwise.
According to game rules step is done when all chosen cards match
and their amount corresponds to a specific number (#matchesCount)"

^ self chosenCards size = self matchesCount
and: [ self chosenCardMatch ]
]

{ #category : #testing }
MGGame >> shouldResetStep [
^ self chosenCards size > self matchesCount
]
52 changes: 52 additions & 0 deletions src/Bloc-Memory/MGGameElement.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"
| board space |
board := MGGameElement example.
space := BlSpace new.
space extent: 420@420.
space addChild: board.
space show.
{ board . space } inspect
"
Class {
#name : #MGGameElement,
#superclass : #BlElement,
#instVars : [
'memoryGame'
],
#category : #'Bloc-Memory-Elements'
}

{ #category : #example }
MGGameElement class >> example [
"self example"
<example>

| game board |
game := MGGame withNumbers.
board := MGGameElement new.
board memoryGame: game.
^ board
]

{ #category : #initialization }
MGGameElement >> initialize [
super initialize.
self layout: BlGridLayout horizontal.
]

{ #category : #accessing }
MGGameElement >> memoryGame [
^ memoryGame
]

{ #category : #accessing }
MGGameElement >> memoryGame: anObject [
memoryGame := anObject.
memoryGame availableCards
do: [ :aCard | self addChild: (self newCardElement card: aCard) ]
]

{ #category : #accessing }
MGGameElement >> newCardElement [
^ MGCardElement new
]
1 change: 1 addition & 0 deletions src/Bloc-Memory/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : #'Bloc-Memory' }

0 comments on commit abaa651

Please sign in to comment.