aboutsummaryrefslogtreecommitdiff
path: root/src/player.rs
diff options
context:
space:
mode:
authorDylan <boss@tehbox.org>2026-11-09 16:56:33 +1300
committerDylan <boss@tehbox.org>2026-11-09 16:56:33 +1300
commit76fde82da0ef09d3635362e1fbf2a289c3d2c6dd (patch)
treef8f03ea61cf339bf76de293de481a34a39679abe /src/player.rs
parent478e7568f5eda9780d1409bb8dccc86221126281 (diff)
downloadtigers-and-sheep-76fde82da0ef09d3635362e1fbf2a289c3d2c6dd.tar.gz
tigers-and-sheep-76fde82da0ef09d3635362e1fbf2a289c3d2c6dd.zip
feat: Colour the game result and show scores to 5 significant figures
The game-over line is bold green for a win, naming the winning player, and bold yellow for a draw. The last-turn panel shows a minimax player's score to 5 significant figures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/player.rs')
-rw-r--r--src/player.rs39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/player.rs b/src/player.rs
index 1766d24..4ac7a10 100644
--- a/src/player.rs
+++ b/src/player.rs
@@ -581,7 +581,7 @@ impl<P: MinimaxPlayer> Player for P
}
else
{
- format!("{:+.1} (+ favours tigers)", r.score)
+ format!("{} (+ favours tigers)", significant(r.score, 5))
};
Paragraph::new(format!("Played {}\nSearched to depth {}\nScore: {score}", r.mv, r.depth))
.wrap(Wrap { trim: true }).render(area, buf);
@@ -589,12 +589,49 @@ impl<P: MinimaxPlayer> Player for P
}
+/// `x` to `digits` significant figures, with its sign: 1234.5678 to 5 is "+1234.6", 0.012345678
+/// is "+0.012346", and 1234567 is "+1234600".
+fn significant(x: f32, digits: usize) -> String
+{
+ if x == 0.0
+ {
+ return format!("{:.*}", digits.saturating_sub(1), 0.0);
+ }
+ // The power of ten of the first significant digit
+ let magnitude = (x.abs() as f64).log10().floor() as i32;
+ let decimals = digits as i32 - 1 - magnitude;
+ if decimals >= 0
+ {
+ // Rounding can carry into a new digit (9.99999 to 10.000), which needs one decimal fewer
+ let rounded = format!("{:+.*}", decimals as usize, x);
+ let carried = rounded.trim_start_matches(['+', '-']).trim_start_matches(['0', '.']).chars().filter(char::is_ascii_digit).count() > digits;
+ if carried && decimals > 0 { format!("{:+.*}", decimals as usize - 1, x) } else { rounded }
+ }
+ else
+ {
+ let unit = 10f64.powi(-decimals);
+ format!("{:+.0}", (x as f64 / unit).round() * unit)
+ }
+}
+
#[cfg(test)]
mod tests
{
use super::*;
use crate::board::PieceType;
+ #[test]
+ fn significant_keeps_five_figures()
+ {
+ assert_eq!(significant(1234.5678, 5), "+1234.6");
+ assert_eq!(significant(-212.0, 5), "-212.00");
+ assert_eq!(significant(0.012345678, 5), "+0.012346");
+ assert_eq!(significant(-0.5, 5), "-0.50000");
+ assert_eq!(significant(1234567.0, 5), "+1234600");
+ assert_eq!(significant(9.999999, 5), "+10.000");
+ assert_eq!(significant(0.0, 5), "0.0000");
+ }
+
/// A minimax player with a cheap evaluation that still varies a lot between positions.
struct TestPlayer
{