Skip to content

Commit

Permalink
Fixed #709: Random basic data types
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Apr 20, 2024
1 parent 8860268 commit 17f3767
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 6 deletions.
23 changes: 17 additions & 6 deletions indigo/indigo/src/main/scala/indigo/shared/datatypes/Point.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package indigo.shared.datatypes

import indigo.Dice
import indigo.shared.geometry.Vertex

final case class Point(x: Int, y: Int) derives CanEqual:
Expand Down Expand Up @@ -51,7 +52,7 @@ final case class Point(x: Int, y: Int) derives CanEqual:
def moveBy(x: Int, y: Int): Point =
moveBy(Point(x, y))

def rotateBy(angle: Radians): Point = {
def rotateBy(angle: Radians): Point =
val a = angle.wrap.toDouble
val s = Math.sin(a)
val c = Math.cos(a)
Expand All @@ -60,18 +61,17 @@ final case class Point(x: Int, y: Int) derives CanEqual:
Math.round(this.x * c - this.y * s).toInt,
Math.round(this.x * s + this.y * c).toInt
)
}

def rotateBy(angle: Radians, origin: Point): Point =
(this - origin).rotateBy(angle) + origin

def rotateTo(angle: Radians): Point = {
def rotateTo(angle: Radians): Point =
val a = angle.wrap.toDouble
val r = this.distanceTo(Point.zero)
Point(
Math.round(r * Math.cos(a)).toInt,
Math.round(r * Math.sin(a)).toInt
)
}

def angle: Radians = Radians(Math.atan2(this.y, this.x))

Expand Down Expand Up @@ -102,7 +102,7 @@ object Point:
Point(a.x + (((b.x - a.x) / divisor) * multiplier).toInt, a.y + (((b.y - a.y) / divisor) * multiplier).toInt)

def distanceBetween(a: Point, b: Point): Double =
(a, b) match {
(a, b) match
case (Point(x1, y1), Point(x2, y2)) if x1 == x2 =>
Math.abs((y2 - y1).toDouble)

Expand All @@ -114,7 +114,6 @@ object Point:
val bb = y2.toDouble - y1.toDouble

Math.sqrt(Math.abs((aa * aa) + (bb * bb)))
}

def fromSize(size: Size): Point =
Point(size.width, size.height)
Expand All @@ -130,3 +129,15 @@ object Point:
x = (dividend.x % divisor.x + divisor.x) % divisor.x,
y = (dividend.y % divisor.y + divisor.y) % divisor.y
)

def random(dice: Dice, max: Int): Point =
Point(dice.rollFromZero(max), dice.rollFromZero(max))

def random(dice: Dice, max: Point): Point =
Point(dice.rollFromZero(max.x), dice.rollFromZero(max.y))

def random(dice: Dice, min: Int, max: Int): Point =
Point(dice.rollFromZero(max - min) + min, dice.rollFromZero(max - min) + min)

def random(dice: Dice, min: Point, max: Point): Point =
Point(dice.rollFromZero(max.x - min.x) + min.x, dice.rollFromZero(max.y - min.y) + min.y)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package indigo.shared.datatypes

import indigo.shared.dice.Dice
import indigo.shared.time.Seconds

import annotation.targetName
Expand Down Expand Up @@ -30,6 +31,9 @@ object Radians:
def mod(dividend: Radians, divisor: Radians): Radians =
Radians((dividend % divisor + divisor) % divisor)

def random(dice: Dice): Radians =
TAU * dice.rollDouble

extension (r: Radians)
def +(other: Radians): Radians =
Radians(r + other)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indigo.shared.datatypes

import indigo.shared.collections.Batch
import indigo.shared.dice.Dice
import indigo.shared.geometry.BoundingBox
import indigo.shared.geometry.BoundingCircle

Expand Down Expand Up @@ -262,3 +263,15 @@ object Rectangle:
a.toBoundingBox.overlaps(b.toBoundingBox)
def overlapping(a: Rectangle, b: Circle): Boolean =
a.toBoundingBox.overlaps(b.toBoundingCircle)

def random(dice: Dice, max: Int): Rectangle =
Rectangle(Point.random(dice, max), Size.random(dice, max))

def random(dice: Dice, max: Rectangle): Rectangle =
Rectangle(Point.random(dice, max.position), Size.random(dice, max.size))

def random(dice: Dice, min: Int, max: Int): Rectangle =
Rectangle(Point.random(dice, min, max), Size.random(dice, min, max))

def random(dice: Dice, min: Rectangle, max: Rectangle): Rectangle =
Rectangle(Point.random(dice, min.position, max.position), Size.random(dice, min.size, max.size))
13 changes: 13 additions & 0 deletions indigo/indigo/src/main/scala/indigo/shared/datatypes/Size.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package indigo.shared.datatypes

import indigo.shared.dice.Dice
import indigo.shared.geometry.Vertex

final case class Size(width: Int, height: Int) derives CanEqual:
Expand Down Expand Up @@ -80,3 +81,15 @@ object Size:
width = (dividend.width % divisor.width + divisor.width) % divisor.width,
height = (dividend.height % divisor.height + divisor.height) % divisor.height
)

def random(dice: Dice, max: Int): Size =
Size(dice.rollFromZero(max), dice.rollFromZero(max))

def random(dice: Dice, max: Size): Size =
Size(dice.rollFromZero(max.width), dice.rollFromZero(max.height))

def random(dice: Dice, min: Int, max: Int): Size =
Size(dice.rollFromZero(max - min) + min, dice.rollFromZero(max - min) + min)

def random(dice: Dice, min: Size, max: Size): Size =
Size(dice.rollFromZero(max.width - min.width) + min.width, dice.rollFromZero(max.height - min.height) + min.height)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indigo.shared.datatypes

import indigo.shared.collections.Batch
import indigo.shared.dice.Dice
import indigo.shared.geometry.Vertex

final case class Vector2(x: Double, y: Double) derives CanEqual:
Expand Down Expand Up @@ -192,3 +193,6 @@ object Vector2:
x = (dividend.x % divisor.x + divisor.x) % divisor.x,
y = (dividend.y % divisor.y + divisor.y) % divisor.y
)

def random(dice: Dice): Vector2 =
Vector2(dice.rollDouble, dice.rollDouble)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indigo.shared.datatypes

import indigo.shared.collections.Batch
import indigo.shared.dice.Dice

final case class Vector3(x: Double, y: Double, z: Double) derives CanEqual:

Expand Down Expand Up @@ -158,3 +159,6 @@ object Vector3:
y = (dividend.y % divisor.y + divisor.y) % divisor.y,
z = (dividend.z % divisor.z + divisor.z) % divisor.z
)

def random(dice: Dice): Vector3 =
Vector3(dice.rollDouble, dice.rollDouble, dice.rollDouble)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indigo.shared.datatypes

import indigo.shared.collections.Batch
import indigo.shared.dice.Dice

final case class Vector4(x: Double, y: Double, z: Double, w: Double) derives CanEqual:

Expand Down Expand Up @@ -185,3 +186,6 @@ object Vector4:
z = (dividend.z % divisor.z + divisor.z) % divisor.z,
w = (dividend.w % divisor.w + divisor.w) % divisor.w
)

def random(dice: Dice): Vector4 =
Vector4(dice.rollDouble, dice.rollDouble, dice.rollDouble, dice.rollDouble)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import indigo.shared.datatypes.Point
import indigo.shared.datatypes.Radians
import indigo.shared.datatypes.Size
import indigo.shared.datatypes.Vector2
import indigo.shared.dice.Dice

/** A `Vertex` is another co-ordinate-like type that specifically represents a point on a graph.
*/
Expand Down Expand Up @@ -170,3 +171,6 @@ object Vertex:
x = (dividend.x % divisor.x + divisor.x) % divisor.x,
y = (dividend.y % divisor.y + divisor.y) % divisor.y
)

def random(dice: Dice): Vertex =
Vertex(dice.rollDouble, dice.rollDouble)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package indigo.shared.datatypes

import indigo.shared.dice.Dice
import org.scalacheck._

class PointSpecification extends Properties("Dice") {

property("all random values are within the max range and >= 0") = Prop.forAll(Gen.choose(0, 500)) { max =>
val dice = Dice.fromSeed(0)
val value = Point.random(dice, max)

value.x >= 0 && value.y >= 0 && value.x <= max && value.y <= max
}

property("all random values are within the max range (Point) and >= 0") = Prop.forAll(Gen.choose(0, 500)) { max =>
val dice = Dice.fromSeed(0)
val value = Point.random(dice, Point(max))

value.x >= 0 && value.y >= 0 && value.x <= Point(max).x && value.y <= Point(max).y
}

property("all random values are within the min / max range") = Prop.forAll(Gen.choose(-500, 0), Gen.choose(0, 500)) {
(min, max) =>
val dice = Dice.fromSeed(0)
val value = Point.random(dice, min, max)

value.x >= min && value.y >= min && value.x <= max && value.y <= max
}

property("all random values are within the min / max range (Point)") = Prop.forAll(Gen.choose(-500, 0), Gen.choose(0, 500)) {
(min, max) =>
val dice = Dice.fromSeed(0)
val value = Point.random(dice, Point(min), Point(max))

value.x >= Point(min).x && value.y >= Point(min).y && value.x <= Point(max).x && value.y <= Point(max).y
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package indigo.shared.datatypes

import indigo.shared.dice.Dice
import org.scalacheck._

class RadiansSpecification extends Properties("Dice") {

property("all random values are within the range of TAU / 2*PI") = Prop.forAll(Gen.long) { seed =>
val dice = Dice.fromSeed(seed)
val value = Radians.random(dice)

value.toDouble >= 0.0 && value.toDouble <= Radians.TAU.toDouble
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package indigo.shared.datatypes

import indigo.shared.dice.Dice
import org.scalacheck._

class SizeSpecification extends Properties("Dice") {

property("all random values are within the max range and >= 0") = Prop.forAll(Gen.choose(0, 500)) { max =>
val dice = Dice.fromSeed(0)
val value = Size.random(dice, max)

value.width >= 0 && value.height >= 0 && value.width <= max && value.height <= max
}

property("all random values are within the max range (Size) and >= 0") = Prop.forAll(Gen.choose(0, 500)) { max =>
val dice = Dice.fromSeed(0)
val value = Size.random(dice, Size(max))

value.width >= 0 && value.height >= 0 && value.width <= Size(max).width && value.height <= Size(max).height
}

property("all random values are within the min / max range") = Prop.forAll(Gen.choose(-500, 0), Gen.choose(0, 500)) {
(min, max) =>
val dice = Dice.fromSeed(0)
val value = Size.random(dice, min, max)

value.width >= min && value.height >= min && value.width <= max && value.height <= max
}

property("all random values are within the min / max range (Size)") = Prop.forAll(Gen.choose(-500, 0), Gen.choose(0, 500)) {
(min, max) =>
val dice = Dice.fromSeed(0)
val value = Size.random(dice, Size(min), Size(max))

value.width >= Size(min).width && value.height >= Size(min).height && value.width <= Size(max).width && value.height <= Size(max).height
}

}

0 comments on commit 17f3767

Please sign in to comment.