Skip to content

Instantly share code, notes, and snippets.

@jodersky
Created September 5, 2016 22:11
Show Gist options
  • Save jodersky/b62ae654173371f7ac96c8430340f309 to your computer and use it in GitHub Desktop.
Save jodersky/b62ae654173371f7ac96c8430340f309 to your computer and use it in GitHub Desktop.
Simulate attack scenarios in a classic Risk game.
#!/usr/bin/env scala
import math._
import scala.util.Random
val Iterations = 100000
val MaxAttackers = 15
val MaxDefenders = 15
/** Randomly simulates a complete attack (until there are either no attackers or defenders left).
* Returns the total number of attacker units lost in the process.
*/
def attack(attackers: Int, defenders: Int): Int = {
val atts = Array.fill(min(3, attackers))(Random.nextInt(6) + 1).sorted.reverse
val defs = Array.fill(min(2, defenders))(Random.nextInt(6) + 1).sorted.reverse
if (attackers == 0 || defenders == 0) {
attackers
} else {
val attackLosses: Int = atts.zip(defs).map { case (a, d) =>
if (a > d) 0 else 1
}.sum
val defenseLosses = math.min(atts.length, defs.length) - attackLosses
attack(attackers - attackLosses, defenders - defenseLosses)
}
}
//fill results
val results =
for(attackers <- 0 until MaxAttackers) yield {
for (defenders <- 0 until MaxDefenders) yield {
(0 until Iterations).map(_ => attack(attackers, defenders)).sum.toDouble / Iterations
}
}
println("Expected remaining attacker units")
println("att\\def\t|" + (0 until MaxDefenders).mkString("\t"))
println("========" + "="*8 * (MaxDefenders + 1))
for (i <- 0 until MaxAttackers) {
println("\t|")
//if (i % 2 != 0) print("\u001B[7m")
//else print("\u001B[0m")
print(s"$i\t|")
for (j <- 0 until MaxDefenders) {
print(results(i)(j) formatted "%.2f")
print("\t")
}
println("")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment