Skip to content

Commit

Permalink
Adds additional scaladocs to the Dice class, and comments to Dice tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hobnob authored and davesmith00000 committed Nov 8, 2024
1 parent ab393d1 commit c39ae32
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ final class GameEngine[StartUpData, GameModel, ViewModel](

audioPlayer.addAudioAssets(accumulatedAssetCollection.sounds)

val time = if (firstRun) 0 else gameLoopInstance.runningTimeReference
val time = (if (firstRun) 0 else gameLoopInstance.runningTimeReference) + gameLoopInstance.initialSeed

if (firstRun)
platform = new Platform(parentElement, gameConfig, globalEventStream, dynamicText)
Expand Down
7 changes: 5 additions & 2 deletions indigo/indigo/src/main/scala/indigo/gameengine/GameLoop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import indigo.shared.time.Millis
import indigo.shared.time.Seconds

import scala.collection.mutable
import scala.scalajs.js.Date
import scala.scalajs.js.JSConverters._

val initialDate = new Date()

final class GameLoop[StartUpData, GameModel, ViewModel](
rebuildGameLoop: AssetCollection => Unit,
boundaryLocator: BoundaryLocator,
Expand All @@ -35,7 +38,7 @@ final class GameLoop[StartUpData, GameModel, ViewModel](
startFrameLocked: Boolean,
renderer: => Renderer
):

val initialSeed = initialDate.valueOf()
@SuppressWarnings(Array("scalafix:DisableSyntax.var"))
private var _gameModelState: GameModel = initialModel
@SuppressWarnings(Array("scalafix:DisableSyntax.var"))
Expand Down Expand Up @@ -131,7 +134,7 @@ final class GameLoop[StartUpData, GameModel, ViewModel](
gameTime,
events,
_inputState,
Dice.fromSeconds(gameTime.running),
Dice.fromSeconds(gameTime.running + initialSeed),
boundaryLocator,
renderer
)
Expand Down
52 changes: 50 additions & 2 deletions indigo/indigo/src/main/scala/indigo/shared/dice/Dice.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,33 +168,81 @@ object Dice:

val r: Random = new Random(seed)

def roll: Int = roll(sides)
/** Roll an Int from 1 to the number of sides on the dice (inclusive)
*
* @return
*/
def roll: Int =
roll(sides)

/** Roll an Int from 1 to the specified number of sides (inclusive)
*
* @param sides
* @return
*/
def roll(sides: Int): Int =
r.nextInt(sanitise(sides)) + 1

/** Roll an Int from 0 to the number of sides on the dice (exclusive)
*
* @return
*/
def rollFromZero: Int =
roll - 1
rollFromZero(sides)

/** Roll an Int from 0 to the specified number of sides (exclusive)
*
* @param sides
* @return
*/
def rollFromZero(sides: Int): Int =
roll(sides) - 1

/** Roll an Int from the range provided (inclusive)
*
* @param from
* @param to
* @return
*/
def rollRange(from: Int, to: Int): Int =
val f = Math.min(from, to)
val t = Math.max(from, to)
roll(t - f + 1) + f - 1

/** Produces a random Float from 0.0 to 1.0
*
* @return
*/
def rollFloat: Float =
r.nextFloat()

/** Produces a random Double from 0.0 to 1.0
*
* @return
*/
def rollDouble: Double =
r.nextDouble()

/** Produces a random alphanumeric string of the specified length
*
* @param length
* @return
*/
def rollAlphaNumeric(length: Int): String =
r.alphanumeric.take(length).mkString

/** Produces a random alphanumeric string 16 characters long
*
* @return
*/
def rollAlphaNumeric: String =
rollAlphaNumeric(16)

/** Shuffles a list of values into a random order
*
* @param items
* @return
*/
def shuffle[A](items: List[A]): List[A] =
r.shuffle(items)
}
Expand Down
32 changes: 19 additions & 13 deletions indigo/indigo/src/test/scala/indigo/shared/dice/DiceTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ class DiceTests extends munit.FunSuite {
}

test("all dice rolls have an approximately uniform distribution") {
val diceSides = 64
val numRuns = 200_000_000
val dice = Dice.diceSidesN(diceSides, 0)
val diceSides = 63
val numRuns = 200_000_000
val dice = Dice.diceSidesN(diceSides, 0)
val expectedDistribution = 1.0 / diceSides
val generatedNums =
Array
.range(0, numRuns)
Expand All @@ -73,11 +74,12 @@ class DiceTests extends munit.FunSuite {
acc.updated(roll, acc.getOrElse(roll, 0) + 1)
}

// Ensure that we have the right numbers generated (they should all have been created)
assertEquals(generatedNums.size, diceSides)
assertEquals(generatedNums.head._1, 1)
assertEquals(generatedNums.last._1, diceSides)

val expectedDistribution = 1.0 / diceSides
// Check the even distribution of the generated numbers
generatedNums.foreach { case (num, count) =>
val distribution = count.toDouble / numRuns
assert(
Expand All @@ -88,10 +90,11 @@ class DiceTests extends munit.FunSuite {
}

test("all dice rolls in rollRange have an approximately uniform distribution") {
val diceSides = 64
val halfSides = diceSides / 2
val numRuns = 200_000_000
val dice = Dice.diceSidesN(diceSides, 0)
val diceSides = 63
val halfSides = Math.floor(diceSides / 2.0).toInt
val numRuns = 200_000_000
val dice = Dice.diceSidesN(diceSides, 0)
val expectedDistribution = 1.0 / halfSides
val generatedNums =
Array
.range(0, numRuns)
Expand All @@ -100,11 +103,12 @@ class DiceTests extends munit.FunSuite {
acc.updated(roll, acc.getOrElse(roll, 0) + 1)
}

assertEquals(generatedNums.size, halfSides + 1)
// Ensure that we have the right numbers generated (only numbers from just before half way through the number of sides should have een created)
assertEquals(generatedNums.size, (diceSides - halfSides) + 1)
assertEquals(generatedNums.head._1, halfSides)
assertEquals(generatedNums.last._1, diceSides)

val expectedDistribution = 1.0 / halfSides
// Check the even distribution of the generated numbers
generatedNums.foreach { case (num, count) =>
val distribution = count.toDouble / numRuns
assert(
Expand All @@ -115,8 +119,9 @@ class DiceTests extends munit.FunSuite {
}

test("all dice rolls in rollRange(1, 4) have an approximately uniform distribution") {
val numRuns = 200_000_000
val dice = Dice.diceSidesN(4, 0)
val numRuns = 200_000_000
val dice = Dice.diceSidesN(4, 0)
val expectedDistribution = 0.25
val generatedNums =
Array
.range(0, numRuns)
Expand All @@ -125,11 +130,12 @@ class DiceTests extends munit.FunSuite {
acc.updated(roll, acc.getOrElse(roll, 0) + 1)
}

// Ensure that we have the right numbers generated (they should all have been created)
assertEquals(generatedNums.size, 4)
assertEquals(generatedNums.head._1, 1)
assertEquals(generatedNums.last._1, 4)

val expectedDistribution = 0.25
// Check the even distribution of the generated numbers
generatedNums.foreach { case (num, count) =>
val distribution = count.toDouble / numRuns
assert(
Expand Down

0 comments on commit c39ae32

Please sign in to comment.