-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.R
505 lines (446 loc) · 18 KB
/
server.R
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# Execute our custom script for loading packages
source("usePackages.R")
source("setAWSPassword.R")
source("cardmatrix.R")
source("questions.R")
source("instructionModal.R")
source("resourcesModal.R")
source("endModal.R")
# Name of the packages
pkgnames1 <- c("shiny")
# Use our custom load function
loadPkgs(pkgnames1)
# Define server logic for random distribution application
shinyServer(function(input, output, session) {
vals <- reactiveValues(
#which tab is opened
tabOpen = NULL)
playerVals <- reactiveValues(
#player names
player1Name = "Player 1",
player2Name = "Player 2",
#card scores
player1Score = NULL,
player2Score = NULL
)
gameVals <- reactiveValues(
#whose turn is it; 1 or 2, representing player 1 or 2
playerTurn = NULL,
#name of player in turn
playerName = NULL,
#game state (e.g. is it to pick card or answer question)
# PC1: pick first card
# PC2: pick second card
# WC: wrong card
# AQ: answer question
# EG: end game
gameState = NULL,
#action card, if we ever get to that state
actionCard = F,
#stores order of cards, whether if it is opened
cardMatrix = NULL,
#stores the order of the cards on the board
cardMatrixTemp = NULL,
#stores the first unflipped card
firstCard = list("row" = FALSE, "col" = FALSE),
#stores the second unflipped card
secondCard = list("row" = FALSE, "col" = FALSE),
#stores questions that are answered
questionsAnswered = c(),
#stores question answered Now
questionAnsweredNow = NULL,
#stores answer
answerCorrect = NULL,
#stores answer text
answerCorrectText = NULL,
#stores cards that are opened
cardsOpened = c(),
#proportion of cards completed
gameProgress = 0
)
#determine next turn
nextTurn <- function(){
gameVals$playerTurn <- (gameVals$playerTurn %% 2) + 1
gameVals$playerName <- switch(gameVals$playerTurn, playerVals$player1Name, playerVals$player2Name)
}
#games tab is hidden by default
hideTab(inputId = "tabsPanel", target = "GameTab")
#track which tab is open
observe({
vals$tabOpen <- input$tabsPanel
})
#reset game
gameReset <- function(){
#initialise game settingswhen new game starts
gameVals$cardMatrix <- generateMatrix()
gameVals$cardMatrixTemp <- NULL
gameVals$playerTurn <- 1
gameVals$playerName <- playerVals$player1Name
gameVals$gameState <- "PC1"
gameVals$questionsAnswered <- c()
gameVals$cardsOpened <- c()
gameVals$gameProgress <- 0
firstCard = list("row" = FALSE, "col" = FALSE)
secondCard = list("row" = FALSE, "col" = FALSE)
playerVals$player1Score <- 0
playerVals$player2Score <- 0
}
observeEvent(input$startButt, {
#unhide game tab and switches to it
showTab(inputId = "tabsPanel", target = "GameTab")
updateTabsetPanel(session, "tabsPanel", selected = "GameTab")
#sets player names, or playerN if input is empty
if (nchar(input$player1Name) > 0){playerVals$player1Name <- input$player1Name}
if (nchar(input$player2Name) > 0){playerVals$player2Name <- input$player2Name}
#reset game
gameReset()
})
#output vals for player names
output$player1Name <- renderUI(playerVals$player1Name)
output$player2Name <- renderUI(playerVals$player2Name)
#output for game progress
output$gameProgress <- renderUI(tags$b(paste0("Game progress: ", gameVals$gameProgress*100, "%")))
#output for side panel
output$sidebarInstruction <- renderUI(
if (vals$tabOpen == "MenuTab"){
fluidPage(
img(src = "Mindmatchlogo.png", height = 75, width = 150 ),
tags$hr(),
tags$h5("About our game:"),
tags$p("MindMatch is a memory-quiz game that aims to help reduce mental health stigmatisation by spreading awareness about the common struggles people with mental health issues face and teach us ways that we can support them. "),
actionButton("instructButt", "Instructions"),
tags$br(),
actionButton("resourcesButt", "Resources")
)
}
else if (vals$tabOpen == "GameTab"){
if (gameVals$gameState == "PC1") {
#prompt for choices if game state is AQ
tabPanel("gameInfoDisplay",
paste0(gameVals$playerName, " pick first card."))
}
else if (gameVals$gameState == "PC2") {
#prompt for choices if game state is AQ
tabPanel("gameInfoDisplay",
paste0(gameVals$playerName, " pick second card."))
}
else if (gameVals$gameState == "WC") {
#prompt for choices if game state is AQ
tabPanel("gameInfoDisplay",
"Cards don't match! Click on any card to end turn")
}
else if (gameVals$gameState == "AQ") {
#retrieve question
questionOut <- questionRetrieve(gameVals$questionsAnswered)
print(questionOut)
print("STOP HELLO")
#sets correct value for answer and updates questions answered
gameVals$questionAnsweredNow <- questionOut[["questionID"]]
gameVals$answerCorrect <- questionOut[["correct_option_index"]]
gameVals$answerCorrectText <- questionOut[["options"]][questionOut[["correct_option_index"]]]
#prompt for choices if game state is AQ
tabPanel("gameInfoDisplay",
paste0(gameVals$playerName, " answer this question"),
radioButtons("answerChoice",
questionOut[["question"]],
choiceNames = c(questionOut[["options"]], "Show Answer"),
choiceValues = c(1, 2, 3, 4, 5),
selected = 5),
actionButton("answerButt", "Answer"))
}
})
#launches instruction modal
observeEvent(input$instructButt,{
showModal(modalDialog(instructionModal()
))
})
observeEvent(input$resourcesButt,{
showModal(modalDialog(resourcesModal()
))
})
#making image matrix
renderCell <- function(gridrow,gridcol){
renderImage({
# checks for game completeness on the first cell
if (gridrow == 1 & gridcol == 1){
# checks if all cards are opened or all questions are answered
noCardsOpened <- length(gameVals$cardsOpened)
gameVals$gameProgress <- noCardsOpened/input$gameSize
if ( gameVals$gameProgress >= 1 |
length(gameVals$questionsAnswered) == 35){
#if (T){ # use this as short cut to check end modal
endGame()
}
}
row <- toString(gridrow)
col <- toString(gridcol)
#select the icon appropriate for this cell
card <- gameVals$cardMatrix[[row]][[col]]
#show real card if its already opened
if (card[["open"]]){ #if card is opened
imgsrc <- paste0("www/patterns/", card["img"])
# adds image into cardsOpened list if its not already inside
gameVals$cardsOpened <- union(gameVals$cardsOpened, card["img"])
}
else{
#show real card if flipped open by game action
if ((gameVals$firstCard[["row"]] == row & gameVals$firstCard[["col"]] == col) |
(gameVals$secondCard[["row"]] == row & gameVals$secondCard[["col"]] == col)){
imgsrc <- paste0("www/patterns/", card["img"])
}
#show closed card if flipped if its closed
else{
imgsrc <- "www/closed.png"
}
}
# Unfortunately, we are not able to re-size the image and still have the click event work.
# So the image files must have exactly the size we want.
# Also, z-order works only if 'position' is set.
list(src=imgsrc,style="position:relative;z-order:999")
},deleteFile=FALSE)
}
#creates and maintains images for cells
output$cell11 <- renderCell(1,1)
output$cell12 <- renderCell(1,2)
output$cell13 <- renderCell(1,3)
output$cell14 <- renderCell(1,4)
output$cell15 <- renderCell(1,5)
output$cell16 <- renderCell(1,6)
output$cell21 <- renderCell(2,1)
output$cell22 <- renderCell(2,2)
output$cell23 <- renderCell(2,3)
output$cell24 <- renderCell(2,4)
output$cell25 <- renderCell(2,5)
output$cell26 <- renderCell(2,6)
output$cell31 <- renderCell(3,1)
output$cell32 <- renderCell(3,2)
output$cell33 <- renderCell(3,3)
output$cell34 <- renderCell(3,4)
output$cell35 <- renderCell(3,5)
output$cell36 <- renderCell(3,6)
output$cell41 <- renderCell(4,1)
output$cell42 <- renderCell(4,2)
output$cell43 <- renderCell(4,3)
output$cell44 <- renderCell(4,4)
output$cell45 <- renderCell(4,5)
output$cell46 <- renderCell(4,6)
output$cell51 <- renderCell(5,1)
output$cell52 <- renderCell(5,2)
output$cell53 <- renderCell(5,3)
output$cell54 <- renderCell(5,4)
output$cell55 <- renderCell(5,5)
output$cell56 <- renderCell(5,6)
output$cell61 <- renderCell(6,1)
output$cell62 <- renderCell(6,2)
output$cell63 <- renderCell(6,3)
output$cell64 <- renderCell(6,4)
output$cell65 <- renderCell(6,5)
output$cell66 <- renderCell(6,6)
#track clicking of images
processClickEvent <- function(gridrow,gridcol){
row <- toString(gridrow)
col <- toString(gridcol)
card <- gameVals$cardMatrix[[row]][[col]]
#if state is wrong card
if (gameVals$gameState == "WC"){
# change state and player
gameVals$gameState <- "PC1"
nextTurn()
#Erases first and second card VAR
gameVals$firstCard <- list("row" = FALSE, "col" = FALSE)
gameVals$secondCard <- list("row" = FALSE, "col" = FALSE)
showNotification(paste0("Pick some cards, ", gameVals$playerName))
}
#only react if card is closed (check from matrix and first card opened)
else if (!card[["open"]] &
!(gameVals$firstCard[["row"]] == row &
gameVals$firstCard[["col"]] == col)){
#if its second card
if (gameVals$gameState == "PC2"){
gameVals$secondCard <- list("row" = row, "col" = col)
#checks results
outcome <- checkCard(gameVals$cardMatrix, gameVals$firstCard, gameVals$secondCard)
if (outcome[["check"]]){
#NOTE: reset first and second row after answering question (see answeringbutt function)
#check for action card
if (outcome[["action"]]){
gameVals$actionCard <- sample(c("Skip", "Together", "Bonus"), 1)
if (gameVals$actionCard == "Skip"){
# show skip notification
showNotification("You have picked a skip action card! Your turn is skipped!", type = "warning")
# updates cardMatrix directly
gameVals$cardMatrix <- outcome[["cardMatrix"]]
# change state and player
gameVals$gameState <- "PC1"
nextTurn()
#Erases first, second card, and Bonus card VAR
gameVals$firstCard <- list("row" = FALSE, "col" = FALSE)
gameVals$secondCard <- list("row" = FALSE, "col" = FALSE)
showNotification(paste0("Pick some cards, ", gameVals$playerName))
gameVals$actionCard <- F
}
else if (gameVals$actionCard == "Bonus"){
# show bonus notification
showNotification("You have picked a Bonus action card! Free points for you!", type = "warning")
#give player points
if (gameVals$playerTurn == 1){
playerVals$player1Score <- playerVals$player1Score + 1
}
else{
playerVals$player2Score <- playerVals$player2Score + 1
}
# updates cardMatrix directly
gameVals$cardMatrix <- outcome[["cardMatrix"]]
# change state and player
gameVals$gameState <- "PC1"
nextTurn()
#Erases first, second card, and Bonus card VAR
gameVals$firstCard <- list("row" = FALSE, "col" = FALSE)
gameVals$secondCard <- list("row" = FALSE, "col" = FALSE)
showNotification(paste0("Pick some cards, ", gameVals$playerName))
gameVals$actionCard = F
}
else if (gameVals$actionCard == "Together"){
# show success notification
showNotification("You have picked an Answer Together action card! Please answer questions in prompt", type = "warning")
#changes game state and updates cardMatrix
gameVals$gameState <- "AQ"
gameVals$cardMatrixTemp <- outcome[["cardMatrix"]]
}
}
else{
# show success notification
showNotification("Success! Please answer questions in prompt")
#changes game state and updates cardMatrix
gameVals$gameState <- "AQ"
gameVals$cardMatrixTemp <- outcome[["cardMatrix"]]
}
}
else{
#if cards don't match, change state to wrong card
gameVals$gameState <- "WC"
showNotification("Cards don't match. Click on any card to end turn")
}
}
#if its first card
else if (gameVals$gameState == "PC1"){
#advance to pick second card
gameVals$gameState <- "PC2"
gameVals$firstCard <- list("row" = row, "col" = col)
}
}
}
#process clicks of images
observeEvent(input$click11,{processClickEvent(1,1)})
observeEvent(input$click12,{processClickEvent(1,2)})
observeEvent(input$click13,{processClickEvent(1,3)})
observeEvent(input$click14,{processClickEvent(1,4)})
observeEvent(input$click15,{processClickEvent(1,5)})
observeEvent(input$click16,{processClickEvent(1,6)})
observeEvent(input$click21,{processClickEvent(2,1)})
observeEvent(input$click22,{processClickEvent(2,2)})
observeEvent(input$click23,{processClickEvent(2,3)})
observeEvent(input$click24,{processClickEvent(2,4)})
observeEvent(input$click25,{processClickEvent(2,5)})
observeEvent(input$click26,{processClickEvent(2,6)})
observeEvent(input$click31,{processClickEvent(3,1)})
observeEvent(input$click32,{processClickEvent(3,2)})
observeEvent(input$click33,{processClickEvent(3,3)})
observeEvent(input$click34,{processClickEvent(3,4)})
observeEvent(input$click35,{processClickEvent(3,5)})
observeEvent(input$click36,{processClickEvent(3,6)})
observeEvent(input$click41,{processClickEvent(4,1)})
observeEvent(input$click42,{processClickEvent(4,2)})
observeEvent(input$click43,{processClickEvent(4,3)})
observeEvent(input$click44,{processClickEvent(4,4)})
observeEvent(input$click45,{processClickEvent(4,5)})
observeEvent(input$click46,{processClickEvent(4,6)})
observeEvent(input$click51,{processClickEvent(5,1)})
observeEvent(input$click52,{processClickEvent(5,2)})
observeEvent(input$click53,{processClickEvent(5,3)})
observeEvent(input$click54,{processClickEvent(5,4)})
observeEvent(input$click55,{processClickEvent(5,5)})
observeEvent(input$click56,{processClickEvent(5,6)})
observeEvent(input$click61,{processClickEvent(6,1)})
observeEvent(input$click62,{processClickEvent(6,2)})
observeEvent(input$click63,{processClickEvent(6,3)})
observeEvent(input$click64,{processClickEvent(6,4)})
observeEvent(input$click65,{processClickEvent(6,5)})
observeEvent(input$click66,{processClickEvent(6,6)})
#process clicks of answerbutton
observeEvent(input$answerButt,{##only react if there is input
#compares score
if (length(input$answerChoice) == 0){
#nothing happens if there is no input
}
else {
# unions questionanswerednow and questionanswered
gameVals$questionsAnswered <- append(gameVals$questionsAnswered, gameVals$questionAnsweredNow)
if (input$answerChoice == gameVals$answerCorrect){
#Adds score for player if correct
showNotification("That is the correct answer!")
#checks for bonus card
if (gameVals$actionCard == "Together"){
playerVals$player1Score <- playerVals$player1Score + 1
playerVals$player2Score <- playerVals$player2Score + 1
#reset bonus card
gameVals$actionCard <- F
}
else{
#assigns points if there is no action card
if (gameVals$playerTurn == 1){
playerVals$player1Score <- playerVals$player1Score + 1
}
else{
playerVals$player2Score <- playerVals$player2Score + 1
}
}
#sets open card
gameVals$cardMatrix <- gameVals$cardMatrixTemp
gameVals$cardMatrixTemp <- NULL
}
else {
#if incorrect, add score of other player
showNotification(paste0("The choice was not correct. The correct choice was ", gameVals$answerCorrectText, "."))
#checks for bonus card
if (gameVals$actionCard == "Together"){
playerVals$player1Score <- playerVals$player1Score - 1
playerVals$player2Score <- playerVals$player2Score - 1
#reset bonus card
gameVals$actionCard <- F
}
else{
#assigns points if there is no action card
if (gameVals$playerTurn == 1){
playerVals$player2Score <- playerVals$player2Score + 1
}
else{
playerVals$player1Score <- playerVals$player1Score + 1
}
}
}
# advance to answer question and turn
nextTurn()
gameVals$gameState <- "PC1"
#Erases first and second card VAR
gameVals$firstCard <- list("row" = FALSE, "col" = FALSE)
gameVals$secondCard <- list("row" = FALSE, "col" = FALSE)
}
})
#output vals for player scores
output$player1Score <- renderUI(as.character(playerVals$player1Score))
output$player2Score <- renderUI(as.character(playerVals$player2Score))
#end game function
endGame <- function(){
gameVals$gameState <- "EG"
showModal(
modalDialog(
endModal(playerVals$player1Score, playerVals$player1Name, playerVals$player2Score, playerVals$player2Name)
)
)
#hide game tab and switches to menu tab
hideTab(inputId = "tabsPanel", target = "GameTab")
updateTabsetPanel(session, "tabsPanel", selected = "MenuTab")
gameReset()
}
})