Skip to content

Commit e7b1da9

Browse files
committed
feat: zener display
1 parent d816b42 commit e7b1da9

File tree

9 files changed

+196
-18
lines changed

9 files changed

+196
-18
lines changed

Cargo.lock

Lines changed: 49 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/game-solver/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ edition = "2021"
1111
[features]
1212
"xxhash" = ["dep:twox-hash"]
1313
"rayon" = ["dep:rayon", "xxhash", "dep:sysinfo", "dep:moka"]
14-
# "reinforcement" = ["dep:rand", "dep:dfdx", "dep:itertools"]
1514
"js" = ["moka/js"]
1615

1716
[dependencies]
@@ -21,7 +20,7 @@ rand = { version = "0.8", optional = true }
2120
rayon = { version = "1.8", optional = true }
2221
sysinfo = { version = "0.30", optional = true }
2322
twox-hash = { version = "1.6", optional = true }
24-
itertools = { version = "0.13", optional = true }
23+
itertools = { version = "0.13" }
2524
futures = "0.3.30"
2625
thiserror = "1.0"
2726
castaway = "0.2.3"

crates/games-cli/src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use anyhow::Result;
22
use clap::Parser;
33
use games::{
44
chomp::Chomp, domineering::Domineering, naive_nim::Nim, order_and_chaos::OrderAndChaos,
5-
reversi::Reversi, sprouts::Sprouts, tic_tac_toe::TicTacToe, util::cli::play, Games,
5+
reversi::Reversi, sprouts::Sprouts, tic_tac_toe::TicTacToe, util::cli::play, zener::Zener,
6+
Games,
67
};
78

89
/// `game-solver` is a solving utility that helps analyze various combinatorial games.
@@ -28,6 +29,7 @@ fn main() -> Result<()> {
2829
Games::Domineering(args) => play::<Domineering<5, 5>>(args.try_into().unwrap(), cli.plain),
2930
Games::Chomp(args) => play::<Chomp>(args.try_into().unwrap(), cli.plain),
3031
Games::Sprouts(args) => play::<Sprouts>(args.try_into().unwrap(), cli.plain),
32+
Games::Zener(args) => play::<Zener>(args.try_into().unwrap(), cli.plain),
3133
};
3234

3335
Ok(())

crates/games/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ thiserror = "1.0.63"
2121
petgraph = { version = "0.6.5", features = ["serde-1"] }
2222
castaway = "0.2.3"
2323
ratatui = "0.28.1"
24-
owo-colors = "4.1.0"
24+
owo-colors = { version = "4.1.0", features = ["supports-colors"] }
2525

2626
[features]
2727
"egui" = ["dep:egui", "dep:egui_commonmark"]

crates/games/src/domineering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use array2d::Array2D;
77
use clap::Args;
88
use game_solver::{
99
game::{Game, GameState, Normal},
10-
player::{PartizanPlayer, Player},
10+
player::PartizanPlayer,
1111
};
1212
use serde::{Deserialize, Serialize};
1313
use std::{

crates/games/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::{
1717
use clap::Subcommand;
1818
use once_cell::sync::Lazy;
1919
use serde::{Deserialize, Serialize};
20+
use zener::ZenerArgs;
2021

2122
#[derive(Subcommand, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone)]
2223
pub enum Games {
@@ -27,9 +28,10 @@ pub enum Games {
2728
Domineering(DomineeringArgs),
2829
Chomp(ChompArgs),
2930
Sprouts(SproutsArgs),
31+
Zener(ZenerArgs),
3032
}
3133

32-
pub static DEFAULT_GAMES: Lazy<[Games; 7]> = Lazy::new(|| {
34+
pub static DEFAULT_GAMES: Lazy<[Games; 8]> = Lazy::new(|| {
3335
[
3436
Games::Reversi(Default::default()),
3537
Games::TicTacToe(Default::default()),
@@ -38,6 +40,7 @@ pub static DEFAULT_GAMES: Lazy<[Games; 7]> = Lazy::new(|| {
3840
Games::Domineering(Default::default()),
3941
Games::Chomp(Default::default()),
4042
Games::Sprouts(Default::default()),
43+
Games::Zener(Default::default()),
4144
]
4245
});
4346

@@ -51,6 +54,7 @@ impl Games {
5154
Self::Domineering(_) => "Domineering".to_string(),
5255
Self::Chomp(_) => "Chomp".to_string(),
5356
Self::Sprouts(_) => "Sprouts".to_string(),
57+
Self::Zener(_) => "Zener".to_string(),
5458
}
5559
}
5660

@@ -63,6 +67,7 @@ impl Games {
6367
Self::Domineering(_) => include_str!("./domineering/README.md"),
6468
Self::Chomp(_) => include_str!("./chomp/README.md"),
6569
Self::Sprouts(_) => include_str!("./sprouts/README.md"),
70+
Self::Zener(_) => include_str!("./zener/README.md"),
6671
}
6772
}
6873

@@ -112,6 +117,12 @@ impl Games {
112117
&mut cache,
113118
"crates/games/src/sprouts/README.md"
114119
),
120+
Self::Zener(_) => egui_commonmark::commonmark_str!(
121+
"zener",
122+
ui,
123+
&mut cache,
124+
"crates/games/src/zener/README.md"
125+
),
115126
};
116127
}
117128
}

crates/games/src/zener/README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
1-
Zener is
1+
Zener is a loopy finite combinatorial game played on a five by seven grid.
2+
Past `game-solver`'s demo, you can play it online at [boardgamearena](https://en.boardgamearena.com/gamepanel?game=zener).
3+
4+
The first row is where Right's unique starting pieces are located,
5+
and the last row is where Left's unique starting pieces are located.
6+
7+
The first player to move is Left, and the allowed moves per piece are only
8+
adjacent horizontal and vertical tiles.
9+
10+
After the first turn, a player makes two moves: they must move the 'type' of piece
11+
that the other player moved (there are five types: Left has the orientation `1 2 3 4 5`
12+
and Right has the orientation `5 4 3 2 1` relative to a side of the board) first,
13+
then they can freely move another piece. This alternates until either no player can make a move,
14+
or a player gets a piece past the first or last row.
15+
16+
Players can 'lock' a piece by moving on top of it: only the piece on top can move, and multiple
17+
pieces can be stacked at a time.

0 commit comments

Comments
 (0)