Files
functional-programming-snake/fsharp/src/Pong/Model.fs
T

69 lines
1.9 KiB
FSharp

/// m11 pong model: the same ideas as the snake model, for a different game.
module Snake.Pong.Model
open Snake.Model
/// The ball's direction of travel, one cell per frame on each axis.
type Velocity = { Dx: int; Dy: int }
/// Which of the player's two keys are being held down right now.
type Held = { Up: bool; Down: bool }
type Score = { Player: int; Cpu: int }
// RequireQualifiedAccess: write `PongStatus.Playing`, `Paddle.Up`, `PongAction.Frame`, so these cases never get
// mixed up with the snake's `Playing`, `Up` and `Frame`.
[<RequireQualifiedAccess>]
type PongStatus =
| Playing
| Over
/// The two keys that move the player's paddle.
[<RequireQualifiedAccess>]
type Paddle =
| Up
| Down
/// A whole match. Positions are in cells: `Ball` is a cell of the 80x50 court; `Player` and `Cpu` are the y of the
/// top cell of each paddle. `Seed` is the unsigned 32-bit random seed used to pick the direction of each serve.
type PongState =
{ Ball: Point
Vel: Velocity
Player: int
Cpu: int
Held: Held
Score: Score
Status: PongStatus
Seed: uint32
Frame: int }
/// Everything that can happen in a match, as data.
[<RequireQualifiedAccess>]
type PongAction =
| Press of Paddle
| Release of Paddle
| Frame
| Restart
// The court, in cells.
let W = 80
let H = 50
/// Pixels per cell.
let PCELL = 8
/// Paddle height in cells.
let PADDLE = 8
/// Column of the player's paddle (left) and of the cpu's paddle (right).
let PLAYER_X = 2
let CPU_X = 77
/// Points needed to win the match.
let WIN = 5
/// A fresh match: ball at (40, 25) moving `{ Dx = 1; Dy = 1 }`, both paddles at y 21, no keys held,
/// score 0 to 0, status Playing, the given seed, frame 0.
/// (Hint: PongState also has `Player` and `Cpu` fields, so write the score as `{ Score.Player = 0; Cpu = 0 }`.)
let initialPong (seed: uint32) : PongState = failwith "TODO m11"