Skip to content

Commit 4abf82f

Browse files
committed
init
1 parent a3c27fb commit 4abf82f

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

crates/games/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod order_and_chaos;
77
pub mod reversi;
88
pub mod sprouts;
99
pub mod tic_tac_toe;
10+
pub mod zener;
1011

1112
use crate::{
1213
chomp::ChompArgs, domineering::DomineeringArgs, naive_nim::NimArgs,

crates/games/src/zener/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Zener is

crates/games/src/zener/gui.rs

Whitespace-only changes.

crates/games/src/zener/mod.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#![doc = include_str!("./README.md")]
2+
3+
#[cfg(feature = "egui")]
4+
pub mod gui;
5+
6+
use array2d::Array2D;
7+
use game_solver::{game::{Game, GameState}, player::PartizanPlayer};
8+
use thiserror::Error;
9+
10+
#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
11+
pub enum InnerCellType {
12+
Wave,
13+
Cross,
14+
Circle,
15+
Square,
16+
Star
17+
}
18+
19+
#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
20+
pub struct CellType(InnerCellType, PartizanPlayer);
21+
22+
#[derive(Clone, Hash, Eq, PartialEq)]
23+
pub struct Zener {
24+
/// [0] is the piece on the bottom, [len - 1] is the piece on top.
25+
board: Array2D<Vec<CellType>>,
26+
player: PartizanPlayer,
27+
compulsory: Option<InnerCellType>,
28+
move_count: usize,
29+
gutter: Option<CellType>,
30+
}
31+
32+
const NUM_ROWS: usize = 7;
33+
const NUM_COLS: usize = 5;
34+
35+
impl Default for Zener {
36+
fn default() -> Self {
37+
let mut board = Array2D::filled_with(vec![], NUM_ROWS, NUM_COLS);
38+
// TODO: make this generic
39+
board[(0, 0)] = vec![CellType(InnerCellType::Star, PartizanPlayer::Right)];
40+
board[(0, 1)] = vec![CellType(InnerCellType::Square, PartizanPlayer::Right)];
41+
board[(0, 2)] = vec![CellType(InnerCellType::Wave, PartizanPlayer::Right)];
42+
board[(0, 3)] = vec![CellType(InnerCellType::Cross, PartizanPlayer::Right)];
43+
board[(0, 4)] = vec![CellType(InnerCellType::Circle, PartizanPlayer::Right)];
44+
45+
board[(NUM_ROWS - 1, 4)] = vec![CellType(InnerCellType::Star, PartizanPlayer::Right)];
46+
board[(NUM_ROWS - 1, 3)] = vec![CellType(InnerCellType::Square, PartizanPlayer::Right)];
47+
board[(NUM_ROWS - 1, 2)] = vec![CellType(InnerCellType::Wave, PartizanPlayer::Right)];
48+
board[(NUM_ROWS - 1, 1)] = vec![CellType(InnerCellType::Cross, PartizanPlayer::Right)];
49+
board[(NUM_ROWS - 1, 0)] = vec![CellType(InnerCellType::Circle, PartizanPlayer::Right)];
50+
51+
Self {
52+
board,
53+
player: PartizanPlayer::Left,
54+
compulsory: None,
55+
move_count: 0,
56+
57+
gutter: None
58+
}
59+
}
60+
}
61+
62+
#[derive(Error, Clone, Debug)]
63+
pub enum ZenerMoveError {
64+
#[error("can not move at {0:?} since there's no piece!")]
65+
NoPiece(ZenerPosition)
66+
}
67+
68+
/// (row, col)
69+
pub type ZenerPosition = (usize, usize);
70+
71+
#[derive(Clone, Copy)]
72+
pub struct ZenerMove {
73+
from: ZenerPosition,
74+
to: ZenerPosition
75+
}
76+
77+
impl Game for Zener {
78+
type Move = ZenerMove;
79+
type Iter<'a> = std::vec::IntoIter<Self::Move>;
80+
/// Left is bottom, Right is top
81+
type Player = PartizanPlayer;
82+
type MoveError = ZenerMoveError;
83+
84+
fn max_moves(&self) -> Option<usize> {
85+
// TODO
86+
None
87+
}
88+
89+
fn move_count(&self) -> usize {
90+
self.move_count
91+
}
92+
93+
fn make_move(&mut self, m: &Self::Move) -> Result<(), Self::MoveError> {
94+
// get the piece to move
95+
let from_piece = self.board[m.from]
96+
.last()
97+
.ok_or(ZenerMoveError::NoPiece(m.from))?.clone();
98+
99+
// add it on the 'to' stack.
100+
self.board[m.to].push(from_piece);
101+
102+
Ok(())
103+
}
104+
105+
fn possible_moves(&self) -> Self::Iter<'_> {
106+
unimplemented!()
107+
}
108+
109+
fn player(&self) -> Self::Player {
110+
self.player
111+
}
112+
113+
fn state(&self) -> GameState<Self::Player> {
114+
match self.gutter {
115+
None => GameState::Playable,
116+
Some(CellType(_, player)) => GameState::Win(player)
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)