fix: much better now

This commit is contained in:
mehbark 2025-03-11 21:52:54 -04:00
parent f3ec466003
commit e7c7e81b4e

View file

@ -11,7 +11,7 @@ use clap::Parser;
use image::{ImageBuffer, Rgb}; use image::{ImageBuffer, Rgb};
use rand::{ use rand::{
distr::{Distribution, StandardUniform}, distr::{Distribution, StandardUniform},
Rng, RngCore, Rng,
}; };
use serde::Deserialize; use serde::Deserialize;
@ -33,13 +33,9 @@ fn main() {
let mut buffer = ImageBuffer::new(u32::from(width), u32::from(height)); let mut buffer = ImageBuffer::new(u32::from(width), u32::from(height));
let mut rolls = vec![0; width as usize * height as usize];
let step_digits = format!("{steps}").len(); let step_digits = format!("{steps}").len();
for i in 0..steps { for i in 0..steps {
rng.fill_bytes(&mut rolls); let GameStep { old, new } = game.step(last, &mut rng);
let GameStep { old, new } = game.step(last, &mut rng, &rolls);
game = new; game = new;
last = old; last = old;
@ -106,14 +102,13 @@ impl Game {
} }
fn set(&mut self, x: i64, y: i64, to: Type) { fn set(&mut self, x: i64, y: i64, to: Type) {
if self.in_bounds(x, y) { assert!(self.in_bounds(x, y));
self.field[(x + y * self.width) as usize] = to; self.field[(x + y * self.width) as usize] = to;
}
} }
// let's see if we can get away with not swapping the field // let's see if we can get away with not swapping the field
// nah it's easy // nah it's easy
fn step(self, mut next: Self, rng: &mut impl Rng, rolls: &[u8]) -> GameStep { fn step(self, mut next: Self, rng: &mut impl Rng) -> GameStep {
for x in 0..self.width { for x in 0..self.width {
for y in 0..self.height { for y in 0..self.height {
let dx = rng.random_range(-1..=1); let dx = rng.random_range(-1..=1);
@ -134,12 +129,13 @@ impl Game {
continue; continue;
} }
let roll = rolls[x as usize + y as usize * self.width as usize]; let won = rng.random::<f32>() <= here.win_chance(other);
let won = roll <= here.win_chance(other);
if won { if won {
next.set(x, y, here);
next.set(ox, oy, here); next.set(ox, oy, here);
} else { } else {
next.set(x, y, other); next.set(x, y, other);
next.set(ox, oy, other);
} }
} }
} }
@ -238,20 +234,20 @@ impl Type {
} }
// nothing is immune to itself, phew // nothing is immune to itself, phew
fn win_chance(self, other: Type) -> u8 { fn win_chance(self, other: Type) -> f32 {
use Efficacy::{Neutral, Strong, Weak, Zero}; use Efficacy::{Neutral, Strong, Weak, Zero};
let self_eff = self.efficacy(other); let self_eff = self.efficacy(other);
let def_eff = other.efficacy(self); let def_eff = other.efficacy(self);
// if you are twice as effective, you should win twice as often: 2/3 vs 1/3 // if you are twice as effective, you should win twice as often: 2/3 vs 1/3
// if you are four times as effective, you should win four times as often: 4/5 vs 1/5 // if you are four times as effective, you should win four times as often: 4/5 vs 1/5
match (self_eff, def_eff) { match (self_eff, def_eff) {
(Strong, Strong) | (Neutral, Neutral) | (Weak, Weak) | (Zero, Zero) => u8::MAX / 2, (Strong, Strong) | (Neutral, Neutral) | (Weak, Weak) | (Zero, Zero) => 0.5,
(Zero, _) => 0, (Zero, _) => 0.0,
(_, Zero) => u8::MAX, (_, Zero) => 1.0,
(Strong, Neutral) | (Neutral, Weak) => 170, // 2/3 (Strong, Neutral) | (Neutral, Weak) => 2. / 3.,
(Neutral, Strong) | (Weak, Neutral) => 85, // 1/3 (Neutral, Strong) | (Weak, Neutral) => 1. / 3.,
(Strong, Weak) => 204, // 4/5 (Strong, Weak) => 4. / 5.,
(Weak, Strong) => 51, // 1/5 (Weak, Strong) => 1. / 5.,
} }
} }