From e7c7e81b4ed309a6a1c3430f6a90d19bfaa7c3f6 Mon Sep 17 00:00:00 2001 From: mehbark <terezi@pyrope.net> Date: Tue, 11 Mar 2025 21:52:54 -0400 Subject: [PATCH] fix: much better now --- src/main.rs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8625995..b5290c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use clap::Parser; use image::{ImageBuffer, Rgb}; use rand::{ distr::{Distribution, StandardUniform}, - Rng, RngCore, + Rng, }; use serde::Deserialize; @@ -33,13 +33,9 @@ fn main() { 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(); for i in 0..steps { - rng.fill_bytes(&mut rolls); - - let GameStep { old, new } = game.step(last, &mut rng, &rolls); + let GameStep { old, new } = game.step(last, &mut rng); game = new; last = old; @@ -106,14 +102,13 @@ impl Game { } fn set(&mut self, x: i64, y: i64, to: Type) { - if self.in_bounds(x, y) { - self.field[(x + y * self.width) as usize] = to; - } + assert!(self.in_bounds(x, y)); + self.field[(x + y * self.width) as usize] = to; } // let's see if we can get away with not swapping the field // 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 y in 0..self.height { let dx = rng.random_range(-1..=1); @@ -134,12 +129,13 @@ impl Game { continue; } - let roll = rolls[x as usize + y as usize * self.width as usize]; - let won = roll <= here.win_chance(other); + let won = rng.random::<f32>() <= here.win_chance(other); if won { + next.set(x, y, here); next.set(ox, oy, here); } else { next.set(x, y, other); + next.set(ox, oy, other); } } } @@ -238,20 +234,20 @@ impl Type { } // 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}; let self_eff = self.efficacy(other); 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 four times as effective, you should win four times as often: 4/5 vs 1/5 match (self_eff, def_eff) { - (Strong, Strong) | (Neutral, Neutral) | (Weak, Weak) | (Zero, Zero) => u8::MAX / 2, - (Zero, _) => 0, - (_, Zero) => u8::MAX, - (Strong, Neutral) | (Neutral, Weak) => 170, // 2/3 - (Neutral, Strong) | (Weak, Neutral) => 85, // 1/3 - (Strong, Weak) => 204, // 4/5 - (Weak, Strong) => 51, // 1/5 + (Strong, Strong) | (Neutral, Neutral) | (Weak, Weak) | (Zero, Zero) => 0.5, + (Zero, _) => 0.0, + (_, Zero) => 1.0, + (Strong, Neutral) | (Neutral, Weak) => 2. / 3., + (Neutral, Strong) | (Weak, Neutral) => 1. / 3., + (Strong, Weak) => 4. / 5., + (Weak, Strong) => 1. / 5., } }