69 lines
1.9 KiB
FSharp
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"
|