Skip to content

Instantly share code, notes, and snippets.

@sudojunior
Last active December 11, 2021 15:18
Show Gist options
  • Save sudojunior/429b3309803593c80c55cabf25ec004d to your computer and use it in GitHub Desktop.
Save sudojunior/429b3309803593c80c55cabf25ec004d to your computer and use it in GitHub Desktop.
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();
}
}
}
//#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}`);
}
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}")
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