HAnthonyHoyt / neon-city-overdrive-dice

A quick bit of code to test out some ideas on die rolling for Neo City Overdrive
1 stars 0 forks source link

Confirmation of Results #1

Open matfournier opened 2 years ago

matfournier commented 2 years ago

Couldn't reply to your locked reddit thread, just wanted to point out I get the same results as you based on a quick script I whipped up over lunch, not whatever the OG poster was posting.

For partial or better:

1 vs 0: 0.50
1 vs 1: 0.41
1 vs 2: 0.35
1 vs 3: 0.29
1 vs 4: 0.24
1 vs 5: 0.20
1 vs 6: 0.17
2 vs 0: 0.75
2 vs 1: 0.67
2 vs 2: 0.59
2 vs 3: 0.51
2 vs 4: 0.44
2 vs 5: 0.38
2 vs 6: 0.32
3 vs 0: 0.87
3 vs 1: 0.81
3 vs 2: 0.74
3 vs 3: 0.67
3 vs 4: 0.60
3 vs 5: 0.53
3 vs 6: 0.47
4 vs 0: 0.94
4 vs 1: 0.90
4 vs 2: 0.84
4 vs 3: 0.79
4 vs 4: 0.72
4 vs 5: 0.66
4 vs 6: 0.59
5 vs 0: 0.97
5 vs 1: 0.94
5 vs 2: 0.91
5 vs 3: 0.86
5 vs 4: 0.81
5 vs 5: 0.75
5 vs 6: 0.69
6 vs 0: 0.98
6 vs 1: 0.97
6 vs 2: 0.94
6 vs 3: 0.91
6 vs 4: 0.87
6 vs 5: 0.82
6 vs 6: 0.77

for just success (6):

1 vs 0: 0.17
1 vs 1: 0.14
1 vs 2: 0.12
1 vs 3: 0.10
1 vs 4: 0.08
1 vs 5: 0.07
1 vs 6: 0.06
2 vs 0: 0.30
2 vs 1: 0.26
2 vs 2: 0.22
2 vs 3: 0.19
2 vs 4: 0.16
2 vs 5: 0.13
2 vs 6: 0.11
3 vs 0: 0.42
3 vs 1: 0.36
3 vs 2: 0.31
3 vs 3: 0.27
3 vs 4: 0.23
3 vs 5: 0.20
3 vs 6: 0.17
4 vs 0: 0.52
4 vs 1: 0.46
4 vs 2: 0.40
4 vs 3: 0.35
4 vs 4: 0.30
4 vs 5: 0.27
4 vs 6: 0.23
5 vs 0: 0.60
5 vs 1: 0.53
5 vs 2: 0.47
5 vs 3: 0.42
5 vs 4: 0.37
5 vs 5: 0.33
5 vs 6: 0.29
6 vs 0: 0.66
6 vs 1: 0.60
6 vs 2: 0.53
6 vs 3: 0.48
6 vs 4: 0.43
6 vs 5: 0.38
6 vs 6: 0.34
matfournier commented 2 years ago
package dice

import java.util.Random

class Dice {
  val random = new Random()
  def rollD6: Int =
    random.nextInt(6) + 1
}

object NCOStats extends App {

  val dice = new Dice()

  def roll(runs: Int, nPositive: Int, nNegative: Int, threshold: Int = 4): Double = {
    val successes = Range(0, runs).inclusive.toList.map {_ =>
      val posRolls = List.fill(nPositive)("").map(_ => (dice.rollD6, 1)).groupBy(_._1).view.mapValues(v => v.map(_._2).sum)
      val negRolls = List.fill(nNegative)("").map(_ => (dice.rollD6, 1)).groupBy(_._1).view.mapValues(v => v.map(_._2).sum)

      val result = posRolls.toList.map {
        case (dice, count) =>
          (dice, negRolls.get(dice).map(sub => count - sub).getOrElse(count))
      }.filter {
        case (_, count) => count > 0
      }
      if (result.isEmpty) 0 else {
        if (result.maxBy(_._1)._1 >= threshold) 1 else 0
      }

    }
    successes.count(i => i == 1).toDouble / runs.toDouble
  }

  case class Scenario(nPositive: Int, nNegative: Int) {
    def id = s"$nPositive vs $nNegative"
  }

  val scenarios = for {
    positive <- List(1,2,3,4,5,6)
    negative <- List(0,1,2,3,4,5,6)
  } yield Scenario(positive, negative)

  val success = 6
  val partialOrBetter = 4
  val results = scenarios.map(scenario => (scenario, roll(runs = 100000, scenario.nPositive, scenario.nNegative, partialOrBetter)))

  // same results as here
  // https://github.com/HAnthonyHoyt/neon-city-overdrive-dice/blob/main/RAND_RESULTS.md
  // looking at partial success or better FYI

  results.foreach {
    case (res, result) =>
      val truncated = f"$result%1.2f"
      println(s"${res.id}: $truncated")
  }
}
HAnthonyHoyt commented 2 years ago

I'm glad to see some conformation then from another source. What language is this by the way? It looks like Java but it seems to lack semicolons. Is this Groovy?

MichaelSims commented 1 year ago

What language is this by the way? It looks like Java but it seems to lack semicolons. Is this Groovy?

It's Scala. 😁