[This article was first published on stotastic » R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

So why should R only be used for ’serious’ stuff? No longer! I’ve written the following code in R which executes a little gravitational physics game. The goal of the game is simple. You supply a velocity and direction to a spaceship with the goal of getting the ship to the winning area without crashing into a planet.

To give you an idea of how this game works, below is a screenshot of the 3rd level. In this screenshot, the blue dot represents the starting position of the ship. The black curve is the ships path. The red circles are the planets where the number represents the mass. Finally, the green circle is the winning area. In this example, the ship made it to the winning area safe and sound!

# Gravity Game Code

Just copy and paste the code below into R and make a call to the function ` gravity() ` and enjoy! Also, you can easily add your own levels by putting your own game parameters in the ‘define level’ code blocks.

```## gravity game in R
gravity <-
function(level=1){
## prompt user for level
cat("Enter Level (1-3)n")
level <- scan(n=1, quiet=T)

## simulation constants
G <- 1000         # gravitational constant
n <- 10000        # simulation steps
dt <- .01         # time step size
limit <- 50       # window limit
m <- 1            # mass of space craft

## define level 1
if(level==1){
## fixed mass 1
Q1m <- 1        # mass
Q1x <- 0        # x location
Q1y <- -20      # y location
Q1r <- 5        # radius

## fixed mass 2
Q2m <- 1        # mass
Q2x <- -10      # x location
Q2y <- 30       # y location
Q2r <- 5        # radius

## win zone
winx <- 30      # x location
winy <- 20      # y location
winr <- 2       # radius

## start
startx <- -40   # x location
starty <- 20    # y location
}

## define level 2
if(level==2){
## fixed mass 1
Q1m <- 10       # mass
Q1x <- -20      # x location
Q1y <- 20       # y location
Q1r <- 25       # radius

## fixed mass 2
Q2m <- 1        # mass
Q2x <- 20       # x location
Q2y <- -30      # y location
Q2r <- 5        # radius

## win zone
winx <- 30      # x location
winy <- 20      # y location
winr <- 2       # radius

## start
startx <- -20   # x location
starty <- -40   # y location
}

## define level 3
if(level==3){
## fixed mass 1
Q1m <- 5        # mass
Q1x <- 0        # x location
Q1y <- 0        # y location
Q1r <- 10       # radius

## fixed mass 2
Q2m <- 1        # mass
Q2x <- 30       # x location
Q2y <- -0       # y location
Q2r <- 5        # radius

## win zone
winx <- 20      # x location
winy <- 20      # y location
winr <- 2       # radius

## start
startx <- 20    # x location
starty <- -20   # y location
}

## plot game map
plot(startx, starty, col="blue", main=paste("Gravity: level", level),
xlim=c(-limit, limit), ylim=c(-limit, limit),
xlab="X", ylab="Y")
circle(Q1x, Q1y, Q1r, "red")
text(Q1x, Q1y, labels=Q1m)
circle(Q2x, Q2y, Q2r, "red")
text(Q2x, Q2y, labels=Q2m)
circle(winx, winy, winr, "green")
text(winx, winy, labels="w")

## prompt user for velocity and angle
cat("Enter Velocity (0-10, but no restrictions so don't cheat)n")
velocity <- scan(n=1, quiet=T)
cat("Enter Angle (in degrees, remember your trigonometry)n")
angle <- scan(n=1, quiet=T)

## define location paths, velocity, and distance vectors
x <- rep(0,n)     # x location
y <- rep(0,n)     # y location
v <- c(0,0)       # velocity vector
r1 <- c(0,0)      # distance vector to mass 1
r2 <- c(0,0)      # distance vector to mass 2

## set initial values
x <- startx
y <- starty
v <- c(velocity*cos(angle*pi/180), velocity*sin(angle*pi/180))

for(i in 2:n){
## calculate distance to fixed masses and win zone
r1 <- c(x[i-1]-Q1x, y[i-1]-Q1y)
r2 <- c(x[i-1]-Q2x, y[i-1]-Q2y)
rw <- c(x[i-1]-winx, y[i-1]-winy)

## break out of loop if ship crashed
if(sqrt(r1 %*% r1)<Q1r | sqrt(r2 %*% r2)<Q2r){
x[i:n] <- x[i-1]
y[i:n] <- y[i-1]
cat("You crashed!n")
break
}

## break out of loop if reach window limit
if(abs(x[i-1])>limit*2 | abs(y[i-1])>limit*2){
x[i:n] <- x[i-1]
y[i:n] <- y[i-1]
cat("Lost in space!n")
break
}

## break out of loop if reach win zone
if(sqrt(rw %*% rw)<winr){
x[i:n] <- x[i-1]
y[i:n] <- y[i-1]
cat("You win!n")
break
}

## calculate force vectors
## force from mass 1
f1 <- (r1/sqrt(r1 %*% r1))*(-G*Q1m*m)/(r1 %*% r1)

## force from mass 2
f2 <- (r2/sqrt(r2 %*% r2))*(-G*Q2m*m)/(r2 %*% r2)

## combined forces
f <- f1 + f2

## update velocity
v <- v + dt*f

## update location
x[i] <- x[i-1] + dt*v/m
y[i] <- y[i-1] + dt*v/m
}

## plot flight path
lines(x,y)
}

## utlity function to draw a circle
circle <-
function(x,y,r,col){
theta <- seq(0, 2*pi, .001)
xv <- r*cos(theta) + x
yv <- r*sin(theta) + y
lines(xv,yv, col=col)
}```