begin jiang

This commit is contained in:
Tao Tien 2026-02-13 10:11:17 -08:00
parent 8c4132e628
commit 042975e561
7 changed files with 134 additions and 16 deletions

8
Cargo.lock generated
View file

@ -1229,6 +1229,7 @@ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"color-eyre", "color-eyre",
"ratatui", "ratatui",
"smol_str",
"tracing", "tracing",
] ]
@ -3710,6 +3711,13 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "jiang"
version = "0.1.0"
dependencies = [
"jong-types",
]
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"

View file

@ -1,6 +1,6 @@
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["jong", "jong-types", "spacetimedb"] members = ["jiang","jong", "jong-types", "spacetimedb"]
[workspace.dependencies] [workspace.dependencies]
jong = { version = "0.1.0", path = "jong" } jong = { version = "0.1.0", path = "jong" }

7
jiang/Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "jiang"
version = "0.1.0"
edition = "2024"
[dependencies]
jong-types.workspace = true

68
jiang/src/lib.rs Normal file
View file

@ -0,0 +1,68 @@
use std::collections::HashMap;
use jong_types::*;
// pub fn check_valid() {}
pub enum Meldable {
Ron,
Chii(Tile, Tile),
Pon,
Kan,
}
pub fn find_meldables(hand: &[Tile], dealt: Tile) -> Vec<Meldable> {
let counts = hand.iter().fold(HashMap::new(), |mut m, t| {
let e = m.entry(t).or_insert(0);
*e += 1;
m
});
let mut calls = vec![];
// find pon & kan
if let Some(&count) = counts.get(&dealt) {
if count == 3 {
calls.push(Meldable::Kan)
} else if count == 2 {
calls.push(Meldable::Pon)
}
}
// find chii
if let Some(next_outer) = dealt.next_rank() {
if let Some(next_inner) = next_outer.next_rank()
&& counts.contains_key(&next_outer)
&& counts.contains_key(&next_inner)
{
calls.push(Meldable::Chii(next_outer, next_inner));
}
if let Some(prev_inner) = next_outer.prev_rank()
&& counts.contains_key(&next_outer)
&& counts.contains_key(&prev_inner)
{
calls.push(Meldable::Chii(next_outer, prev_inner));
}
}
if let Some(prev_outer) = dealt.prev_rank()
&& let Some(prev_inner) = prev_outer.prev_rank()
&& counts.contains_key(&prev_outer)
&& counts.contains_key(&prev_inner)
{
calls.push(Meldable::Chii(prev_outer, prev_inner));
}
// find ron
calls
}
fn count_shapes(hand: &[Tile]) {
let hand = if !hand.is_sorted() {
let mut hand = hand.to_vec();
hand.sort();
&hand
} else {
hand
};
}

View file

@ -4,7 +4,7 @@ mod derive_alias {
Eq = ::core::cmp::PartialEq, ::core::cmp::Eq; Eq = ::core::cmp::PartialEq, ::core::cmp::Eq;
Ord = ..Eq, ::core::cmp::PartialOrd, ::core::cmp::PartialEq, ::core::cmp::Ord; Ord = ..Eq, ::core::cmp::PartialOrd, ::core::cmp::PartialEq, ::core::cmp::Ord;
Base = ::core::fmt::Debug, ..Copy, ..Ord; Base = ::core::fmt::Debug, ..Copy, ..Ord, ::core::hash::Hash;
} }
} }
use derive_aliases::derive; use derive_aliases::derive;
@ -13,7 +13,7 @@ use bevy::prelude::*;
use spacetimedb::SpacetimeType; use spacetimedb::SpacetimeType;
use strum::{EnumCount, FromRepr}; use strum::{EnumCount, FromRepr};
#[derive(..Base, Hash, Default, FromRepr)] #[derive(..Base, Default, FromRepr)]
#[derive(States, SpacetimeType)] #[derive(States, SpacetimeType)]
pub enum GameState { pub enum GameState {
#[default] #[default]
@ -41,18 +41,6 @@ pub enum Suit {
Dragon(Dragon), Dragon(Dragon),
} }
impl Suit {
pub fn rank(&self) -> Option<Rank> {
match self {
Suit::Man(rank) => Some(*rank),
Suit::Pin(rank) => Some(*rank),
Suit::Sou(rank) => Some(*rank),
// Suit::Wind(wind) | Suit::Dragon(dragon) => None,
_ => None,
}
}
}
#[derive( #[derive(
..Base, ..Base,
Deref, Deref,
@ -63,6 +51,49 @@ pub struct Rank {
pub number: u8, pub number: u8,
} }
impl Tile {
pub fn next_rank(self) -> Option<Self> {
match self.suit {
Suit::Man(rank) if rank.number < 9 => Some(Tile {
suit: Suit::Man(Rank {
number: rank.number + 1,
}),
}),
Suit::Pin(rank) if rank.number < 9 => Some(Tile {
suit: Suit::Pin(Rank {
number: rank.number + 1,
}),
}),
Suit::Sou(rank) if rank.number < 9 => Some(Tile {
suit: Suit::Sou(Rank {
number: rank.number + 1,
}),
}),
_ => None,
}
}
pub fn prev_rank(self) -> Option<Self> {
match self.suit {
Suit::Man(rank) if rank.number > 1 => Some(Tile {
suit: Suit::Man(Rank {
number: rank.number - 1,
}),
}),
Suit::Pin(rank) if rank.number > 1 => Some(Tile {
suit: Suit::Pin(Rank {
number: rank.number - 1,
}),
}),
Suit::Sou(rank) if rank.number > 1 => Some(Tile {
suit: Suit::Sou(Rank {
number: rank.number - 1,
}),
}),
_ => None,
}
}
}
#[derive( #[derive(
..Base, ..Base,
FromRepr, FromRepr,

View file

@ -227,7 +227,9 @@ fn on_lobby_insert_update(
} }
stdb::TurnState::Menzen => todo!(), stdb::TurnState::Menzen => todo!(),
stdb::TurnState::RiichiKan => todo!(), stdb::TurnState::RiichiKan => todo!(),
stdb::TurnState::Discard => todo!(), stdb::TurnState::Discard => {
// TODO check if can call reducer here maybe?
}
stdb::TurnState::RonChiiPonKan => todo!(), stdb::TurnState::RonChiiPonKan => todo!(),
stdb::TurnState::End => todo!(), stdb::TurnState::End => todo!(),
} }

View file

@ -4,6 +4,7 @@ use spacetimedb::{SpacetimeType, table};
use super::DbTile; use super::DbTile;
// FIXME this shant be public, use views // FIXME this shant be public, use views
// TODO split up tables so we aren't sending this over the wire every update, or is differencial handled already
#[table(name = player, public)] #[table(name = player, public)]
#[derive(Debug)] #[derive(Debug)]
pub struct Player { pub struct Player {
@ -26,6 +27,7 @@ pub struct Player {
pub pond: Vec<DbTile>, pub pond: Vec<DbTile>,
pub drawn_tile: Option<DbTile>, pub drawn_tile: Option<DbTile>,
pub actionable: Option<()>,
} }
#[table(name = bot)] #[table(name = bot)]