let drawGameOver playerX playerY =
Console.SetCursorPosition(playerX, playerY + Console.WindowTop)
Console.Write("*")
let gameOver = " G A M E O V E R "
Console.SetCursorPosition(Console.WindowWidth / 2 - gameOver.Length / 2, Console.WindowTop + Console.WindowHeight / 2)
Console.Write(gameOver)
while Console.ReadKey().Key <> ConsoleKey.Escape do ignore ()
let rnd = new Random()
let genPit x w score =
let maxW = if score < (Console.BufferWidth / 2 * 100 - 300) then Console.BufferWidth / 2 - (score / 100) else 3
let r = rnd.Next(90)
let newX = x + (if r < 30 then -1 else if r > 60 then 1 else 0)
let newW = w + (if w > maxW then -1 else if r < (90 / 2) then -1 else 1)
if (newW < 2) || (newW > Console.BufferWidth - 4) || (newX < 2) || (newX > Console.BufferWidth - newW - 4) then (x, w)
else (newX, newW)
let rec updateScreen (screen:(int*int) list) x w =
if screen.Length = Console.WindowHeight then
screen.Tail @ [(x, w)]
else if screen.Length > Console.WindowHeight then
updateScreen screen.Tail x w
else
screen @ [(x, w)]
let checkCollision (screen:(int*int) list) playerX playerY =
let (x, w) =
if screen.Length > playerY then
screen.[playerY]
else if playerY > Console.WindowHeight - screen.Length then
screen.[playerY - (Console.WindowHeight - screen.Length)]
else
(-1, -1)
if w = -1 then
false
else if (playerX > x) && (playerX < (x + w)) then
false
else
true
let constrainPlayerX x =
if Console.WindowWidth < 80 then Console.WindowWidth <- 80
if x < 2 then
2
else if x > Console.WindowWidth - 2 then
Console.WindowWidth - 2
else
x
let constrainPlayerY y =
if Console.WindowHeight < 3 then Console.WindowHeight <- 3
if y < 2 then
2
else if y > Console.WindowHeight - 2 then
Console.WindowHeight - 2
else
y
let readKeys playerX playerY =
if Console.KeyAvailable then
let key = Console.ReadKey(true)
while Console.KeyAvailable do Console.ReadKey(true) |> ignore
match key.Key with
| ConsoleKey.LeftArrow -> (playerX - 1, playerY, false)
| ConsoleKey.RightArrow -> (playerX + 1, playerY, false)
| ConsoleKey.DownArrow -> (playerX, playerY + 1, false)
| ConsoleKey.UpArrow -> (playerX, playerY - 1, false)
| ConsoleKey.Escape -> (playerX, playerY, true)
| _ -> (playerX, playerY, false)
else
(playerX, playerY, false)
let rec gameLoop (screen:(int*int) list) playerX playerY x w score speed =
let start = new DateTime(DateTime.Now.Ticks)
let (newPlayerX, newPlayerY, quit) = readKeys playerX playerY
if quit = false then
let (newX, newW) = genPit x w score
let leftWall = (getWallChar x newX)
let rightWall = (getWallChar (x + w) (newX + newW))
let newScreen = updateScreen screen x w
drawPit x w leftWall rightWall
drawScore score
drawPlayer (constrainPlayerX newPlayerX) (constrainPlayerY newPlayerY) playerX playerY
if (checkCollision newScreen (constrainPlayerX newPlayerX) (constrainPlayerY newPlayerY)) = false then
let elapsed = DateTime.Now.Subtract(start).Milliseconds
Thread.Sleep((1000 / speed) - elapsed)
gameLoop newScreen (constrainPlayerX newPlayerX) (constrainPlayerY newPlayerY) newX newW (score + 1) (10 + (score / 100))
else
drawGameOver (constrainPlayerX newPlayerX) (constrainPlayerY newPlayerY)