azul: fix add_color
This commit is contained in:
parent
75447b6176
commit
a0edf8f87e
|
@ -632,6 +632,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"rocket",
|
"rocket",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -10,3 +10,4 @@ rocket = { version = "0.5.0", features = ["json"] }
|
||||||
serde = "1.0.196"
|
serde = "1.0.196"
|
||||||
|
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
serde_json = "1.0.113"
|
||||||
|
|
86
src/azul.rs
86
src/azul.rs
|
@ -6,11 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||||
use rand::distributions::WeightedIndex;
|
use rand::distributions::WeightedIndex;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct GameState {
|
struct GameState {
|
||||||
#[serde(skip)]
|
|
||||||
#[serde(default = "make_rng")]
|
|
||||||
rng: StdRng,
|
|
||||||
n_players: usize,
|
n_players: usize,
|
||||||
current_player: usize,
|
current_player: usize,
|
||||||
starting_player: usize,
|
starting_player: usize,
|
||||||
|
@ -22,10 +19,32 @@ struct GameState {
|
||||||
factories: Vec<TileSet>,
|
factories: Vec<TileSet>,
|
||||||
market: TileSetWithStart,
|
market: TileSetWithStart,
|
||||||
players: Vec<Player>,
|
players: Vec<Player>,
|
||||||
|
#[serde(skip)]
|
||||||
|
#[serde(default = "make_rng")]
|
||||||
|
rng: Box<dyn RngCore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_rng() -> StdRng {
|
fn make_rng() -> Box<dyn RngCore> {
|
||||||
StdRng::from_entropy()
|
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 {
|
impl GameState {
|
||||||
|
@ -56,7 +75,6 @@ impl GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
let game = GameState {
|
let game = GameState {
|
||||||
rng: StdRng::from_entropy(),
|
|
||||||
n_players,
|
n_players,
|
||||||
current_player: 0,
|
current_player: 0,
|
||||||
starting_player: 0,
|
starting_player: 0,
|
||||||
|
@ -81,6 +99,7 @@ impl GameState {
|
||||||
white: 0,
|
white: 0,
|
||||||
},
|
},
|
||||||
players,
|
players,
|
||||||
|
rng: Box::new(StdRng::from_entropy()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(game)
|
Ok(game)
|
||||||
|
@ -90,7 +109,7 @@ impl GameState {
|
||||||
/// Will replenish the bag from the lid when empty
|
/// Will replenish the bag from the lid when empty
|
||||||
/// Will return with partially filled factories if out of tiles
|
/// Will return with partially filled factories if out of tiles
|
||||||
fn fill(&mut self) -> Result<(), &'static str> {
|
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");
|
return Err("Cannot fill, there are still tiles left to be picked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +120,7 @@ impl GameState {
|
||||||
self.lid = TileSet::default();
|
self.lid = TileSet::default();
|
||||||
} else if self.bag.is_empty() {
|
} else if self.bag.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
}
|
||||||
let choices = [
|
let choices = [
|
||||||
Color::Blue,
|
Color::Blue,
|
||||||
Color::Yellow,
|
Color::Yellow,
|
||||||
|
@ -120,11 +139,12 @@ impl GameState {
|
||||||
let dist = WeightedIndex::new(&weights).unwrap();
|
let dist = WeightedIndex::new(&weights).unwrap();
|
||||||
let picked = choices[dist.sample(&mut self.rng)];
|
let picked = choices[dist.sample(&mut self.rng)];
|
||||||
|
|
||||||
self.bag.add_color(picked, 1)?;
|
eprintln!("picked {:?}", picked);
|
||||||
|
|
||||||
|
self.bag.add_color(picked, -1)?;
|
||||||
factory.add_color(picked, 1)?;
|
factory.add_color(picked, 1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -137,6 +157,16 @@ impl GameState {
|
||||||
factories && market
|
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
|
/// Scores the game and clears the boards into the lid
|
||||||
/// Doesn't check if game is ready to be scored!
|
/// Doesn't check if game is ready to be scored!
|
||||||
fn score_unchecked(&mut self) -> Result<(), &'static str> {
|
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!")?
|
self.blue = usize::checked_add_signed(self.blue, n).ok_or("would overflow!")?
|
||||||
}
|
}
|
||||||
Color::Yellow => {
|
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 => {
|
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 => {
|
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 => {
|
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"),
|
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!")?
|
self.blue = usize::checked_add_signed(self.blue, n).ok_or("would overflow!")?
|
||||||
}
|
}
|
||||||
Color::Yellow => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
Color::Start if n == 1 && self.start == 0 => {
|
||||||
self.start = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
self.start = usize::checked_add_signed(self.white, n).ok_or("would overflow")?
|
||||||
|
@ -800,3 +830,21 @@ enum Destination {
|
||||||
#[serde(rename = "floor")]
|
#[serde(rename = "floor")]
|
||||||
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