Helpers.fs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. namespace RL
  2. open RL.Components
  3. module Random =
  4. let MakeRandomState =
  5. let rand = System.Random()
  6. rand.NextInt64() |> uint64
  7. /// A pseudo-random number generator built off of the splitmix64 algorithm.
  8. type RandomNumberGenerator(s : uint64) =
  9. let mutable state = s
  10. member private _.nextInt =
  11. let p1 r = (r ^^^ (r >>> 30)) * 0xbf58476d1ce4e5b9UL
  12. let p2 r = (r ^^^ (r >>> 27)) * 0x94d049bb133111ebUL
  13. let p3 r = r ^^^ (r >>> 31)
  14. state <- state + (0x9e3779b97f4a7c15UL)
  15. state |> p1 |> p2 |> p3
  16. member private r.nextFloat =
  17. (float(r.nextInt) / 2.0 ** 64)
  18. member _.GetState = state
  19. member r.Next(low : int, high : int) =
  20. floor((r.nextFloat * float(high - low)) + float low) |> int
  21. module Helpers =
  22. let distance2DSq(x1 : int, x2 : int, y1 : int, y2 : int) =
  23. let dx = single((max x1 x2) - (min x1 x2))
  24. let dy = single((max y1 y2) - (min y1 y2))
  25. (dx * dx) + (dy * dy)
  26. let distance2D(x1 : int, x2 : int, y1 : int, y2 : int) =
  27. sqrt <| distance2DSq(x1, x2, y1, y2)
  28. // Returns a list of points in a diagonal line.
  29. let pointLineDiag(p1 : Point2D, p2 : Point2D) =
  30. let dx, dy = p2.x - p1.x, p2.y - p1.y
  31. let N = abs(dx) |> max <| abs(dy)
  32. let divN = if N = 0 then 0.0F else 1.0F / single N
  33. let xstep, ystep = single dx * divN, single dy * divN
  34. let mutable x, y = single p1.x, single p1.y
  35. [for _step in 0..N do
  36. let pt = { x = int(round x); y = int(round y) }
  37. x <- x + xstep
  38. y <- y + ystep
  39. yield pt]
  40. // Returns a list of points using only orthagonal points.
  41. let pointLineOrtho(p1 : Point2D, p2 : Point2D) =
  42. let dx, dy = p2.x - p1.x, p2.y - p1.y
  43. let nx, ny = abs dx, abs dy
  44. let sign_x, sign_y = (if dx > 0 then 1 else -1), (if dy > 0 then 1 else -1)
  45. let mutable px, py = p1.x, p1.y
  46. let mutable ix, iy = 0, 0
  47. [while ix < nx || iy < ny do
  48. if (1 + 2 * ix) * ny < (1 + 2 * iy) * nx then
  49. px <- px + sign_x
  50. ix <- ix + 1
  51. else
  52. py <- py + sign_y
  53. iy <- iy + 1
  54. yield { x = px; y = py }]