-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory.fg
183 lines (146 loc) · 5.48 KB
/
memory.fg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!syntax:pythonic
#==========================================
# Utility functions
#==========================================
def makeCardDeck(p_numberOfCopy, p_numberOfDistinct):
# Each card has a back and a face
js (p_numberOfCopy, p_numberOfDistinct):
const cardDeck = []
for(let copy=1; copy<=p_numberOfCopy; copy++){
for( let cardNum=1; cardNum<=p_numberOfDistinct; cardNum++){
cardDeck.push({back : "cardBack.svg", face : "card"+ cardNum +".jpg" });
}
}
return cardDeck
def shuffleCards(p_cardDeck):
# shuffle the deck
js (p_cardDeck):
//~ copied from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
for (let i = p_cardDeck.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[p_cardDeck[i], p_cardDeck[j]] = [p_cardDeck[j], p_cardDeck[i]];
}
def distributeCards(p_cardDeck):
# place all the cards face downward onto the game table
js (p_cardDeck):
const gameTable = document.getElementById("gameTable");
gameTable.innerHTML = ''
gameTable.scrollIntoView()
for(let card of p_cardDeck){
const cardElement = document.createElement('img');
cardElement.src= "img/" + card.back
card.cardElement = cardElement
gameTable.appendChild(cardElement)
}
def showFace(p_card):
js (p_card):
p_card.cardElement.src = "img/" + p_card.face
def showBack(p_card):
js (p_card):
p_card.cardElement.src = "img/" + p_card.back
def awaitClickOnNewButton(p_label):
var lButton := js (p_label):
const lElt = document.createElement('button')
lElt.innerHTML = p_label
document.body.appendChild(lElt)
//~ lElt.scrollIntoView()
return lElt
awaitClickBeep(lButton)
lButton
#==========================================
# Game Course
#==========================================
def gameCourse(p_numberOfCopy, p_numberOfDistinct, p_SIGNAL_memorizeDuration, p_SIGNAL_clickOnCard):
# Prepare game table
#======================
var cardDeck := makeCardDeck(p_numberOfCopy, p_numberOfDistinct)
# shuffle deck
shuffleCards(cardDeck)
# place cards face downward onto the game table
distributeCards(cardDeck)
# Start of game
#=======================
# transform JavaScript Array into FuncSug "parallel list"
var allRemainingCards := listToPar(cardDeck)
# now, allRemainingCards is a "parallel list" of all cards placed on the table
while not isNovalue(allRemainingCards):
# choose p_numberOfCopy cards
#--------------------------
# This block:
# parallel(forEachValueOf <variable>, select <number>):
# select:
# <instructions1>
# do:
# <instructions2>
# launch, in parallel, a sequence of "<instructions1> then <instructions2>" for each value of <variable>
# and when <number> branches (called "selected branches") have reached the end of <instructions1>, all others branches are definitively interrupted
# When all the "selected branches" are finished, the block finished and return an union of the returns of all the "selected branches"
var allClickedCards := parallel(for anyCard in allRemainingCards, select p_numberOfCopy):
# In the following code, anyCard is only a single card
select:
awaitClickBeep(anyCard.cardElement)
bip(p_SIGNAL_clickOnCard)
do:
# now, anyCard can only be a clicked card
# show the face of the clicked card
showFace(anyCard)
# return the clicked card (which is then "union-ed" to allClickedCards by "allClickedCards := parallelOfSelected...")
anyCard
# Compare visible faces
#----------------------
if allEqual(allClickedCards.face):
print('OK')
js (allClickedCards):
allClickedCards.cardElement.classList.add('OK')
allRemainingCards := valuesFrom(allRemainingCards, 'butNotFrom', allClickedCards)
else:
print('Missed')
addCssClassTo('theClickedCards', allClickedCards.cardElement)
waitSeconds(get(p_SIGNAL_memorizeDuration))
DelCssClassFrom('theClickedCards', allClickedCards.cardElement)
showBack(allClickedCards)
#==========================================
# Main
#==========================================
var SIGNAL_clickOnCard
var LABEL_ChangeCopyNumber
var LABEL_ChangeDistinctNumber
var LABEL_gameCourse
var congratMessage
var restartButton
var numberOfCopy
var numberOfDistinct
var SIGNAL_numberOfSeconds
parallel:
# Game course
#------------
sequence: @LABEL_gameCourse
removeElt(congratMessage)
# The main part of the game
if not isEmpty(numberOfCopy) and not isEmpty(numberOfDistinct):
gameCourse(numberOfCopy, numberOfDistinct, 'SIGNAL_numberOfSeconds', 'SIGNAL_clickOnCard')
congratMessage := displayNewMessage('Congratulations, you have found all identical cards!')
awaitForever()
# Change of parameters
#---------------------
while true: @LABEL_ChangeCopyNumber
numberOfCopy := awaitSelectedOptionBeep('#copyNumber')
restart LABEL_gameCourse
while true: @LABEL_ChangeDistinctNumber
numberOfDistinct := awaitSelectedOptionBeep('#distinctNumber')
restart LABEL_gameCourse
while true:
SIGNAL_numberOfSeconds := awaitSelectedOptionBeep('#memorizeDuration')
# Blocking of parameters and restart management
#----------------------------------------------
while true:
awaitBip SIGNAL_clickOnCard
# As soon as a first card is clicked
pause LABEL_ChangeCopyNumber
pause LABEL_ChangeDistinctNumber
restartButton := awaitClickOnNewButton('Restart')
# As soon as the restart button is clicked
removeElt(restartButton)
resume LABEL_ChangeCopyNumber
resume LABEL_ChangeDistinctNumber
restart LABEL_gameCourse