diff --git a/src/game/hand.rs b/src/game/hand.rs index 434fe16..898e6de 100644 --- a/src/game/hand.rs +++ b/src/game/hand.rs @@ -1,13 +1,16 @@ use bevy::{ecs::relationship::RelationshipSourceCollection, prelude::*}; use crate::{ - game::{player::Player /* wall::WallTiles */}, + game::{GameState, player::Player, wall::Wall /* wall::WallTiles */}, tile::Tile, }; #[derive(Component)] pub struct Hand; +#[derive(Component)] +pub struct Drawn(pub Entity); + // #[derive(Component, Default)] // enum SortHand { // #[default] @@ -26,3 +29,38 @@ pub(crate) fn sort_hands( } Ok(()) } + +pub(crate) fn shuffle_deal( + mut commands: Commands, + tiles: Populated>, + players: Populated>, + wall_ent: Single>, + mut next_gamestate: ResMut>, +) -> Result { + use rand::seq::SliceRandom; + + let mut rng = rand::rng(); + let mut walltiles: Vec<_> = tiles.iter().collect(); + walltiles.shuffle(&mut rng); + + // commands.get_entity(*wall_ent)?.replace_children(&walltiles); + + for player_ent in players { + let handtiles = walltiles.split_off(walltiles.len() - 13); + // commands.get_entity(*wall_ent)?.remove_children(&handtiles); + + let hand_ent = commands.spawn(Hand).add_children(&handtiles).id(); + debug!("hand_ent: {hand_ent:?}"); + + commands + .get_entity(player_ent)? + .replace_children(&[hand_ent]); + + debug!("dealt to player_ent {player_ent:?}"); + } + + commands.get_entity(*wall_ent)?.replace_children(&walltiles); + + next_gamestate.set(GameState::Play); + Ok(()) +} diff --git a/src/game/mod.rs b/src/game/mod.rs index e42c311..23e9711 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,9 +1,12 @@ use bevy::prelude::*; +use strum::{EnumCount, FromRepr}; use crate::{ + EnumNextCycle, game::{ - hand::Hand, + hand::{Drawn, Hand}, player::{MainPlayer, Player}, + round::{CurrentPlayer, TurnState, Wind}, wall::Wall, }, tile::{self, *}, @@ -29,50 +32,45 @@ impl Plugin for Riichi { app // start stopper .init_state::() + .add_sub_state::() .init_resource::() .init_resource::() .add_systems(Startup, tile::init_tiles) .add_systems(OnEnter(GameState::Setup), setup) - .add_systems(OnEnter(GameState::Deal), shuffle_deal) + .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal) .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play))) + // .add_systems(Update, turn_manager.run_if(in_state(GameState::Play))) + .add_systems(OnEnter(TurnState::Tsumo), tsumo) // semicolon stopper ; } } -fn shuffle_deal( +// struct TurnEvent { +// pub next: Option, +// pub prev: Option, +// } + +// fn turn_manager() {} + +fn tsumo( mut commands: Commands, - tiles: Populated>, - players: Populated>, + curr_player: Res, + // players: Populated>, wall_ent: Single>, - mut next_gamestate: ResMut>, -) -> Result { - use rand::seq::SliceRandom; + walltiles: Single<&Children, With>, + curr_turnstate: Res>, + mut next_turnstate: ResMut>, +) { + trace!("tsumo for: {:?}", curr_player.0); - let mut rng = rand::rng(); - let mut walltiles: Vec<_> = tiles.iter().collect(); - walltiles.shuffle(&mut rng); + let drawn = walltiles.last().unwrap(); + commands.entity(*wall_ent).remove_child(*drawn); + commands.entity(curr_player.0).insert(Drawn(*drawn)); - // commands.get_entity(*wall_ent)?.replace_children(&walltiles); + debug!("wall: {:?}", *walltiles); - for player_ent in players { - let handtiles = walltiles.split_off(walltiles.len() - 13); - // commands.get_entity(*wall_ent)?.remove_children(&handtiles); - - let hand_ent = commands.spawn(Hand).add_children(&handtiles).id(); - debug!("hand_ent: {hand_ent:?}"); - - commands - .get_entity(player_ent)? - .replace_children(&[hand_ent]); - - debug!("dealt to player_ent {player_ent:?}"); - } - - commands.get_entity(*wall_ent)?.replace_children(&walltiles); - - next_gamestate.set(GameState::Play); - Ok(()) + next_turnstate.set(curr_turnstate.next()); } pub(crate) fn setup( @@ -88,10 +86,16 @@ pub(crate) fn setup( }; let points = player::Points(matchsettings.starting_points); - let bundle = (player, points, Hand); + let bundle = ( + player, + points, + Hand, + Wind::from_repr((i - 1) as usize).unwrap(), + ); if i == 1 { - commands.spawn((bundle, MainPlayer)); + let player = commands.spawn((bundle, MainPlayer)).id(); + commands.insert_resource(CurrentPlayer(player)); } else { commands.spawn(bundle); } diff --git a/src/game/player.rs b/src/game/player.rs index c7c3e6c..d241ba6 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -10,3 +10,9 @@ pub struct Points(pub isize); #[derive(Component)] pub struct MainPlayer; + +#[derive(Component)] +pub struct Dealer; + +#[derive(Component)] +pub struct Tsumo(pub Entity); diff --git a/src/game/round.rs b/src/game/round.rs index 5f8a3be..0d50e3f 100644 --- a/src/game/round.rs +++ b/src/game/round.rs @@ -1,6 +1,7 @@ use bevy::prelude::*; +use strum::{EnumCount, FromRepr}; -use crate::tile::*; +use crate::{EnumNextCycle, game::GameState}; #[derive(Component)] pub(crate) struct Dice(u8, u8); @@ -40,3 +41,46 @@ impl Default for MatchSettings { } } } + +#[derive(Component, Clone, Copy, FromRepr, EnumCount)] +pub enum Wind { + Ton, + Nan, + Shaa, + Pei, +} + +impl EnumNextCycle for Wind { + fn next(&self) -> Self { + if (*self as usize + 1) >= Self::COUNT { + Self::from_repr(0).unwrap() + } else { + Self::from_repr(*self as usize + 1).unwrap() + } + } +} + +#[derive(Resource)] +pub(crate) struct CurrentPlayer(pub Entity); + +#[derive(SubStates, Default, Clone, Copy, PartialEq, Eq, Hash, Debug, FromRepr, EnumCount)] +#[source(GameState = GameState::Play)] +pub(crate) enum TurnState { + #[default] + Tsumo, + Menzen, + RiichiKan, + Discard, + RonChiiPonKan, + End, +} + +impl EnumNextCycle for TurnState { + fn next(&self) -> Self { + if (*self as usize + 1) >= Self::COUNT { + Self::from_repr(0).unwrap() + } else { + Self::from_repr(*self as usize + 1).unwrap() + } + } +} diff --git a/src/game/wall.rs b/src/game/wall.rs index de6ac75..e382cf6 100644 --- a/src/game/wall.rs +++ b/src/game/wall.rs @@ -1,7 +1,7 @@ use bevy::prelude::*; -use rand::seq::SliceRandom; - -use crate::tile::Tile; #[derive(Component)] pub struct Wall; + +#[derive(Component)] +pub struct Dead; diff --git a/src/lib.rs b/src/lib.rs index a64f794..480c8a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ -#![allow(unused)] - pub mod game; pub mod tile; pub mod yakus; + +trait EnumNextCycle { + fn next(&self) -> Self; +} diff --git a/src/main.rs b/src/main.rs index 1a8dd9a..aa4e2ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -#![allow(unused)] - use bevy::{log::LogPlugin, prelude::*}; use clap::{Parser, Subcommand}; use tracing::Level;