Last active
December 11, 2021 15:18
-
-
Save sudojunior/429b3309803593c80c55cabf25ec004d to your computer and use it in GitHub Desktop.
Demo code for https://sudojunior.github.io/2021/12/10/number-limits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace RoleDistribution | |
{ | |
public struct Role { | |
// type decimal can be exchanged for double or float with their respective unit conversion, the outcome will not change | |
public Role(string name, decimal ratio) { | |
Name = name; | |
Ratio = ratio; | |
} | |
public string Name; | |
public decimal Ratio; | |
} | |
class Program | |
{ | |
static Role[] DefaultRoles = new [] { | |
new Role("Villager", 0.5m), | |
new Role("Werewolf", 0.3m), | |
new Role("Spotter", 0.1m), | |
new Role("Hunter", 0.1m), | |
}; | |
static void Main(string[] args) | |
{ | |
for (int i = 6; i < 20; i++) | |
{ | |
var roles = GetRoles(i); | |
decimal sum = 0; | |
foreach (var role in DefaultRoles) | |
{ | |
sum += role.Ratio; | |
} | |
decimal scaleFactor = i / sum; | |
Console.WriteLine($"players: {i}, difference: {roles.Length - i}, scale: {scaleFactor}"); | |
} | |
} | |
static string[] GetRoles(int count) | |
{ | |
List<string> roles = new (); | |
decimal sum = 0; | |
foreach (var role in DefaultRoles) | |
{ | |
sum += role.Ratio; | |
} | |
decimal scaleFactor = count / sum; | |
foreach (Role role in DefaultRoles) | |
{ | |
int quantity = (int)Math.Round(role.Ratio * scaleFactor); | |
for (int i = 0; i < quantity; i++) | |
{ | |
roles.Add(role.Name); | |
} | |
} | |
return roles.ToArray(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#region Configure | |
const FROM = 6; | |
const UNTIL = 20; | |
const DEBUG = true; | |
//#endregion | |
//#region Roles | |
const ROLES = [ | |
{ name: "Citizen", ratio: 0.5 }, | |
{ name: "Werewolf", ratio: 0.3 }, | |
{ name: "Spotter", ratio: 0.1 }, | |
{ name: "Hunter", ratio: 0.1 } | |
] | |
//#endregion | |
for (let i = FROM; i < UNTIL; i++) { | |
const sum = ROLES.reduce((sum, role) => sum + role.ratio, 0); | |
const scaleFactor = i / sum; | |
const roles = ROLES.flatMap((role) => { | |
const roleCount = Math.round(role.ratio * scaleFactor); | |
return Array(roleCount).fill(role.name); | |
}); | |
console.log(`players: ${i}, difference: ${roles.length - i}, scaleFactor: ${scaleFactor}`); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import namedtuple, Counter | |
Role = namedtuple('Role', 'name, ratio') | |
ROLES = [ | |
Role("Citizen", 0.5), | |
Role("Werewolf", 0.3), | |
Role("Spotter", 0.1), | |
Role("Hunter", 0.1), | |
] | |
for player_count in range(6, 21): | |
ratio_total = sum(role.ratio for role in ROLES) | |
scale_factor = player_count / ratio_total | |
roles = [] | |
for role in ROLES: | |
for _ in range(round(role.ratio * scale_factor)): | |
roles.append(role.name) | |
print(f"players: {player_count}, difference: {len(roles) - player_count}, scale_factor: {scale_factor}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Role { | |
name: String, | |
ratio: f64, | |
} | |
fn main() { | |
let default_roles: [Role; 4] = [ | |
Role { name: String::from("Citizen"), ratio: 0.5 }, | |
Role { name: String::from("Werewolf"), ratio: 0.3 }, | |
Role { name: String::from("Spotter"), ratio: 0.1 }, | |
Role { name: String::from("Hunter"), ratio: 0.1 } | |
]; | |
// loop over range | |
for i in 0..20 { | |
let mut sum = 0.0; | |
let mut final_roles : Vec<String> = Vec::new(); | |
for role in &default_roles { | |
sum += role.ratio; | |
} | |
let scale_factor = f64::from(i) / sum; | |
for role in &default_roles { | |
let quantity = (role.ratio * scale_factor).round() as i32; | |
for _ in 0..quantity { | |
final_roles.push(role.name.clone()); | |
} | |
} | |
println!("players: {}, difference: {}, scale: {}", i, final_roles.len() as i32 - i, scale_factor); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment