The Rock-Paper-Scissors game with R and Shiny

D.Dakhno
16.Aug. 2016

Course Project “Developing Data Products”
Data Science Specialization by Johns Hopkins University

Introduction and main concepts

The course project is all about building and deploying Shiny application, accessible over Web, dynamic and reactive toward user input. I use the well known simple game to build a sample application with a touch of statistics.

The main features are:

  • self-explanatory, responsive user interface (ui.R)
  • reactive elements, triggered by user submit
  • internal separation of site rendering (shiny) and application logic (server.R)
  • “session persistence” over iterations

Reactivity and rendering

Following elements are used as user input:

checkboxInput(inputId = 'userReset', label = "Start again (reset all counters to zero)",value = FALSE ),
radioButtons(inputId = 'userChoice1', label = "", choices = arms,selected = character(0)),
submitButton('Fire away!')

Reaction is asynchron and triggered with user submit (button “Fire away!”), so user has a an option to change his choice or to start the next iteration with a blanked history.
Taking into account the non-conventional behavior of the rendering in shiny, I separate strictly the rendering itself and application logic

shinyServer(function(input, output, session) {
    renderSite <- function(x) {
        dynout <- wonOrLost(x) 
        output$oid1 <- renderPrint({dynout[[1]]})
        output$oid2 <- renderPrint({dynout[[2]]})
        ...

Reactivity and rendering

Function renderSite() is triggered by observer event

#reacting at user triggered reset
    observe({
        if (input$userReset == TRUE) {
            renderSite(NULL)
        }
    })
#reacting at user choice
    observe({
        if (!is.null(input$userChoice1)) {
            renderSite(input$userChoice1)
        }
    })

It is not the user input itself, rendered to the output, but the return list of the function wonOrLost()

Logical layer and session persistence

Function wonOrLost() takes the actual user choice as a single argument, generates the random choice of application player, compares and returns a list of values (actual result as text, overall number of attempts, number of user wins, plays won by user in percent, the same in series, number of ties, all user choices)

for (ch in c("Rock","Scissors")) wonOrLost(ch)
paste(wonOrLost("Paper"))
[1] "Paper of You against  Scissors of mine :(( You, sore looser!"
[2] "3"                                                           
[3] "1"                                                           
[4] "50"                                                          
[5] "c(0, 100, 50)"                                               
[6] "1"                                                           
[7] "Paper, Scissors, Rock, "                                     

Good luck playing online!