R-Cade Games: Simulating the Legendary Game of Pong

Pong is one of the earliest arcade games on the market, first released in 1972. From the day I first saw this miracle box, I wanted to know more about computers.

I learnt how to write code from the 1983 book Dr. C. Wacko’s Miracle Guide to Designing and Programming your own Atari Computer Arcade Games. This book explains in a very clear and humorous way how to write computer games in Atari basic. I devoured this book and spent many hours developing silly games. This article is an ode to Dr Wacko, a computer geek’s midlife-crisis and an attempt to replicate the software I developed thirty years ago.

I showed in a previous post that R can be used for board games or play a game of elliptical pool. The question is whether we create arcade games in R. My challenge is to recreate the look and feel of 1980s arcade games, or R-Cade games, using R? The code shown below simulates the legendary game of pong.

Dr. C. Wacko's miracle guide to designing and programming your own Atari computer arcade games (R Games)

Playing Pong in R

The code is based on the Wacko’s Boing Program in the above-mentioned book. The R code is fully commented and speaks for itself. Please note that the animation is very clunky when you run it in RStudio. Only the native R Terminal displays the animation correctly.

Perhaps somebody can help me perfect this little ditty. I love to know how to read real-time USB input to control the game, so we get a step closer to the first R-Cade game.

The Pong Code

You can view the code below or download the latest version from GitHub.

library(beepr)

skill <- 0.87 # Skill (0-1)
score <- 0
high.score <- 0

par(mar = rep(1,4), bg = "black")
plot.new()
plot.window(xlim = c(0, 30), ylim = c(0, 30))
lines(c(1, 30, 30, 1), c(0, 0, 30, 30), type = "l", lwd = 5, col = "white")

xmin <- 0.5
xmax <- 29.4
ymin <- 0.5
ymax <- 29.4

x <- sample(5:25, 1)
y <- sample(5:25, 1)
points(x, y, pch = 15, col = "white", cex = 2)

psize <- 4
ypaddle <- y

dx <- runif(1, .5, 1)
dy <- runif(1, .5, 1)

while (x > xmin - 1) {
    sound <- 0 # Silence
    Sys.sleep(.05) # Pause screen. Reduce to increase speed
    points(x, y, pch = 15, col = "black", cex = 2) # Erase ball
    # Move ball
    x <- x + dx
    y <- y + dy 
    # Collision detection 
    if (x > xmax) {
        dx <- -dx * runif(1, .9, 1.1) # Bounce 
        if (x > xmin) x <- xmax # Boundary
        sound <- 10 # Set sound
        }
    if (y < ymin | y > ymax) {
        if (y < ymin) y <- ymin 
        if (y < ymax) y <- ymax
        dy <- -dy * runif(1, .9, 1.1)
        sound <- 10
    }
    # Caught by paddle?
    if (x < xmin & (y > ypaddle - (psize / 2)) & y < ypaddle + (psize / 2)) {
        if (x < xmin) 
            x <- xmin
        dx <- -dx * runif(1, .9, 1.1)
        sound <- 2
        score <- score + 1
        }
    # Draw ball
    points(x, y, pch = 15, col = "white", cex = 2)
    if (sound !=0) beep(sound)
    # Move paddle
    if (runif(1, 0, 1) < skill)
        ypaddle <- ypaddle + dy # Imperfect follow
    # Draw paddle
    # Erase back line
    lines(c(0, 0), c(0, 30), type = "l", lwd = 8, col = "black")
    # Keep paddle inside window
    if (ypaddle < (psize / 2)) ypaddle <- (psize / 2) 
    if (ypaddle > 30 - (psize / 2)) ypaddle <- 30 - (psize / 2) 
    # Draw paddle 
    lines(c(0, 0), c(ypaddle - (psize / 2), ypaddle + (psize / 2)), type = "l", lwd = 8, col = "white") 
} 
beep(8) 
text(15,15, "GAME OVER", cex = 5, col = "white") 
s <- ifelse(score == 1, "s ")
text(15,5, paste0(score, " Point", s), cex=3, col = "white") 

 

7 thoughts on “R-Cade Games: Simulating the Legendary Game of Pong

  1. Thank you – this is such a lovely idea! I remember the marvel of seeing Pong for the first time.

    I tried running it with Rgui on an aged windows laptop, but it had a few problems updating and crashed. I haven’t delved into the cause. Perhaps someone could take the logic and implement it as a Shiny app or similar.

      1. Yes that would be nice. I just tried putting the scan function inside a withTimeout (R.utils package) call to simulate a background thread watching for keystrokes (e.g. ‘k’ for up, ‘j’ for down) but couldn’t get it to work. However it could be done with a little C or Rcpp function.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.