azul: fix add_color
This commit is contained in:
parent
75447b6176
commit
a0edf8f87e
|
@ -632,6 +632,7 @@ dependencies = [
|
|||
"rand",
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -10,3 +10,4 @@ rocket = { version = "0.5.0", features = ["json"] }
|
|||
serde = "1.0.196"
|
||||
|
||||
rand = "0.8.5"
|
||||
serde_json = "1.0.113"
|
||||
|
|
122
src/azul.rs
122
src/azul.rs
|
@ -6,11 +6,8 @@ use serde::{Deserialize, Serialize};
|
|||
use rand::distributions::WeightedIndex;
|
||||
use rand::prelude::*;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct GameState {
|
||||
#[serde(skip)]
|
||||
#[serde(default = "make_rng")]
|
||||
rng: StdRng,
|
||||
n_players: usize,
|
||||
current_player: usize,
|
||||
starting_player: usize,
|
||||
|
@ -22,10 +19,32 @@ struct GameState {
|
|||
factories: Vec<TileSet>,
|
||||
market: TileSetWithStart,
|
||||
players: Vec<Player>,
|
||||
#[serde(skip)]
|
||||
#[serde(default = "make_rng")]
|
||||
rng: Box<dyn RngCore>,
|
||||
}
|
||||
|
||||
fn make_rng() -> StdRng {
|
||||
StdRng::from_entropy()
|
||||
fn make_rng() -> Box<dyn RngCore> {
|
||||
Box::new(StdRng::from_entropy())
|
||||
}
|
||||
|
||||
impl Clone for GameState {
|
||||
fn clone(&self) -> Self {
|
||||
GameState {
|
||||
n_players: self.n_players,
|
||||
current_player: self.current_player,
|
||||
starting_player: self.starting_player,
|
||||
game_end: self.game_end,
|
||||
rounds: self.rounds,
|
||||
days: self.days,
|
||||
bag: self.bag.clone(),
|
||||
lid: self.lid.clone(),
|
||||
factories: self.factories.clone(),
|
||||
market: self.market.clone(),
|
||||
players: self.players.clone(),
|
||||
rng: make_rng(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
|
@ -56,7 +75,6 @@ impl GameState {
|
|||
}
|
||||
|
||||
let game = GameState {
|
||||
rng: StdRng::from_entropy(),
|
||||
n_players,
|
||||
current_player: 0,
|
||||
starting_player: 0,
|
||||
|
@ -81,6 +99,7 @@ impl GameState {
|
|||
white: 0,
|
||||
},
|
||||
players,
|
||||
rng: Box::new(StdRng::from_entropy()),
|
||||
};
|
||||
|
||||
Ok(game)
|
||||
|
@ -90,7 +109,7 @@ impl GameState {
|
|||
/// Will replenish the bag from the lid when empty
|
||||
/// Will return with partially filled factories if out of tiles
|
||||
fn fill(&mut self) -> Result<(), &'static str> {
|
||||
if !self.is_empty() {
|
||||
if !self.only_start() {
|
||||
return Err("Cannot fill, there are still tiles left to be picked");
|
||||
}
|
||||
|
||||
|
@ -101,28 +120,29 @@ impl GameState {
|
|||
self.lid = TileSet::default();
|
||||
} else if self.bag.is_empty() {
|
||||
return Ok(());
|
||||
} else {
|
||||
let choices = [
|
||||
Color::Blue,
|
||||
Color::Yellow,
|
||||
Color::Red,
|
||||
Color::Black,
|
||||
Color::White,
|
||||
];
|
||||
let weights = [
|
||||
self.bag.blue,
|
||||
self.bag.yellow,
|
||||
self.bag.red,
|
||||
self.bag.black,
|
||||
self.bag.white,
|
||||
];
|
||||
|
||||
let dist = WeightedIndex::new(&weights).unwrap();
|
||||
let picked = choices[dist.sample(&mut self.rng)];
|
||||
|
||||
self.bag.add_color(picked, 1)?;
|
||||
factory.add_color(picked, 1)?;
|
||||
}
|
||||
let choices = [
|
||||
Color::Blue,
|
||||
Color::Yellow,
|
||||
Color::Red,
|
||||
Color::Black,
|
||||
Color::White,
|
||||
];
|
||||
let weights = [
|
||||
self.bag.blue,
|
||||
self.bag.yellow,
|
||||
self.bag.red,
|
||||
self.bag.black,
|
||||
self.bag.white,
|
||||
];
|
||||
|
||||
let dist = WeightedIndex::new(&weights).unwrap();
|
||||
let picked = choices[dist.sample(&mut self.rng)];
|
||||
|
||||
eprintln!("picked {:?}", picked);
|
||||
|
||||
self.bag.add_color(picked, -1)?;
|
||||
factory.add_color(picked, 1)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,6 +157,16 @@ impl GameState {
|
|||
factories && market
|
||||
}
|
||||
|
||||
/// Returns whether or not only the start tile is in play
|
||||
fn only_start(&self) -> bool {
|
||||
let factories = self.factories.iter().all(|f| f.is_empty());
|
||||
let market = Color::Blue
|
||||
.into_iter()
|
||||
.all(|c| self.market.get_color(c) == 0);
|
||||
|
||||
factories && market
|
||||
}
|
||||
|
||||
/// Scores the game and clears the boards into the lid
|
||||
/// Doesn't check if game is ready to be scored!
|
||||
fn score_unchecked(&mut self) -> Result<(), &'static str> {
|
||||
|
@ -378,16 +408,16 @@ impl TileSet {
|
|||
self.blue = usize::checked_add_signed(self.blue, n).ok_or("would overflow!")?
|
||||
}
|
||||
Color::Yellow => {
|
||||
self.blue = usize::checked_add_signed(self.yellow, n).ok_or("would overflow")?
|
||||
self.yellow = usize::checked_add_signed(self.yellow, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Red => {
|
||||
self.blue = usize::checked_add_signed(self.red, n).ok_or("would overflow")?
|
||||
self.red = usize::checked_add_signed(self.red, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Black => {
|
||||
self.blue = usize::checked_add_signed(self.black, n).ok_or("would overflow")?
|
||||
self.black = usize::checked_add_signed(self.black, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::White => {
|
||||
self.blue = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||
self.white = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Start => return Err("tried to add Start tiles to TileSet"),
|
||||
}
|
||||
|
@ -483,16 +513,16 @@ impl TileSetWithStart {
|
|||
self.blue = usize::checked_add_signed(self.blue, n).ok_or("would overflow!")?
|
||||
}
|
||||
Color::Yellow => {
|
||||
self.blue = usize::checked_add_signed(self.yellow, n).ok_or("would overflow")?
|
||||
self.yellow = usize::checked_add_signed(self.yellow, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Red => {
|
||||
self.blue = usize::checked_add_signed(self.red, n).ok_or("would overflow")?
|
||||
self.red = usize::checked_add_signed(self.red, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Black => {
|
||||
self.blue = usize::checked_add_signed(self.black, n).ok_or("would overflow")?
|
||||
self.black = usize::checked_add_signed(self.black, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::White => {
|
||||
self.blue = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||
self.white = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||
}
|
||||
Color::Start if n == 1 && self.start == 0 => {
|
||||
self.start = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||
|
@ -800,3 +830,21 @@ enum Destination {
|
|||
#[serde(rename = "floor")]
|
||||
Floor,
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
||||
use serde_json::to_string_pretty;
|
||||
|
||||
#[test]
|
||||
fn test_fill() {
|
||||
let mut game = GameState::new(2).unwrap();
|
||||
|
||||
// println!("{}", to_string_pretty(&game).unwrap());
|
||||
assert!(game.only_start());
|
||||
|
||||
game.fill();
|
||||
//println!("{}", to_string_pretty(&game).unwrap());
|
||||
|
||||
assert_eq!(game.bag.len(), 100 - (5 * 4));
|
||||
assert_eq!(game.factories.iter().map(|f| f.len()).sum::<usize>(), 5 * 4);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue