feat(fsharp): m01-m06 util, model, rules, random, spawn, game, view with Expecto tests
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
183821737e
commit
9cbefeb2be
@@ -0,0 +1,31 @@
|
||||
/// m04 random: a tiny "state monad" for randomness. A Random<'a> wraps a function seed -> (value, nextSeed),
|
||||
/// so every draw is a pure function and the seed is passed along explicitly instead of hidden.
|
||||
/// Seeds and values are unsigned 32-bit numbers (uint32).
|
||||
module Snake.Random
|
||||
|
||||
type Random<'a> = Random of (uint32 -> 'a * uint32)
|
||||
|
||||
let run (seed: uint32) (Random f: Random<'a>) : 'a * uint32 = f seed
|
||||
|
||||
let pure (a: 'a) : Random<'a> = Random(fun seed -> (a, seed))
|
||||
|
||||
let map (f: 'a -> 'b) (r: Random<'a>) : Random<'b> =
|
||||
Random(fun seed ->
|
||||
let a, next = run seed r
|
||||
(f a, next))
|
||||
|
||||
let bind (f: 'a -> Random<'b>) (r: Random<'a>) : Random<'b> =
|
||||
Random(fun seed ->
|
||||
let a, next = run seed r
|
||||
run next (f a))
|
||||
|
||||
// mulberry32. uint32 arithmetic wraps around at 2^32 (F# operators are unchecked) and `>>>` on uint32 is an
|
||||
// unsigned shift, so the formula can be written down as it is.
|
||||
let nextUint32: Random<uint32> =
|
||||
Random(fun seed ->
|
||||
let s = seed + 0x6D2B79F5u
|
||||
let t1 = (s ^^^ (s >>> 15)) * (s ||| 1u)
|
||||
let t2 = t1 ^^^ (t1 + (t1 ^^^ (t1 >>> 7)) * (t1 ||| 61u))
|
||||
(t2 ^^^ (t2 >>> 14), s))
|
||||
|
||||
let intBelow (n: int) : Random<int> = map (fun v -> int (v % uint32 n)) nextUint32
|
||||
Reference in New Issue
Block a user