diff --git a/src/game/mod.rs b/src/game/mod.rs index 7f65cd7..09bf4e6 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -3,30 +3,32 @@ use tracing::instrument; use crate::tiles::{self, *}; -mod player; +pub mod player; pub mod wall; -pub struct Riichi; +#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq)] +pub enum GameState { + #[default] + None, + Setup, + // Deal, + Play, + Score, +} +pub struct Riichi; impl Plugin for Riichi { fn build(&self, app: &mut App) { app.init_resource::() .add_systems(Startup, init_match) - .add_systems(Startup, (tiles::init_tiles, wall::build_wall).chain()) + .add_systems(Startup, tiles::init_tiles) + .init_state::() + .add_systems(OnEnter(GameState::Setup), (wall::build_wall, player::deal_hands).chain()) // semicolon stopper ; } } -#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq)] -enum GameState { - #[default] - Setup, - Deal, - Play, - Score, -} - #[derive(Component)] pub(crate) struct Dice(u8, u8); diff --git a/src/game/player.rs b/src/game/player.rs index 45d3c04..17b4c66 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -1,9 +1,44 @@ use bevy::prelude::*; +use crate::{ + game::wall::{Wall, WallTiles}, + tiles::Tile, +}; + #[derive(Component)] pub(crate) struct Player { pub(crate) name: String, } +fn spawn_players(mut commands: Commands) {} + #[derive(Component)] pub(crate) struct Points(pub isize); + +#[derive(Component)] +pub struct Hand; + +#[derive(Component)] +#[relationship_target(relationship = InHand, linked_spawn)] +pub struct HandTiles(Vec); + +#[derive(Component)] +#[relationship(relationship_target = HandTiles)] +pub struct InHand(pub Entity); + +pub(crate) fn deal_hands( + mut commands: Commands, + wall: Single>, + wall_tiles: Query>, + tiles: Query>, +) -> Result { + let hand = wall_tiles.iter().collect::>(); + + commands + .get_entity(*wall)? + .remove_children(hand.last_chunk::<13>().unwrap()); + + commands.spawn((Hand, HandTiles(hand))); + + Ok(()) +} diff --git a/src/game/wall.rs b/src/game/wall.rs index ce54ec5..96a4e6e 100644 --- a/src/game/wall.rs +++ b/src/game/wall.rs @@ -2,17 +2,20 @@ use bevy::log::tracing::instrument; use bevy::prelude::*; use rand::seq::SliceRandom; -use crate::game::InWall; use crate::tiles::Tile; +#[derive(Component)] +pub struct Wall; + #[derive(Component)] #[relationship_target(relationship = InWall, linked_spawn)] pub struct WallTiles(Vec); #[derive(Component)] -pub struct Wall; +#[relationship(relationship_target = WallTiles)] +pub struct InWall(pub Entity); -pub(crate) fn build_wall(mut commands: Commands, tiles: Query>) -> Result { +pub(crate) fn build_wall(mut commands: Commands, tiles: Query>) { let mut rng = rand::rng(); let mut shuffled = tiles @@ -21,7 +24,5 @@ pub(crate) fn build_wall(mut commands: Commands, tiles: Query .collect::>(); shuffled.shuffle(&mut rng); - let mut wall = commands.spawn((Wall, WallTiles(shuffled))); - - Ok(()) + commands.spawn((Wall, WallTiles(shuffled))); } diff --git a/src/main.rs b/src/main.rs index 1a8dd9a..0481b30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ fn main() { tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap(); tui_logger::set_env_filter_from_string(FILTERSTRING); - app.add_plugins(tui::RiichiTui) + app.add_plugins(tui::RiichiTui::default()) } }; diff --git a/src/tiles.rs b/src/tiles.rs index 4c6eb3c..655f74d 100644 --- a/src/tiles.rs +++ b/src/tiles.rs @@ -2,15 +2,7 @@ use bevy::{ecs::entity::MapEntities, prelude::*}; use strum::FromRepr; use tracing::instrument; -use crate::game::wall::WallTiles; - -#[derive(Component)] -#[relationship(relationship_target = WallTiles)] -pub struct InWall(pub Entity); - -// #[derive(Component)] -// #[relationship(relationship_target = WallTiles)] -// pub(crate) struct InHand(pub Entity); +use crate::game::{player::HandTiles, wall::WallTiles}; #[derive(Component, Debug)] pub struct Tile { diff --git a/src/tui/console.rs b/src/tui/console.rs index 8112010..0b1ceab 100644 --- a/src/tui/console.rs +++ b/src/tui/console.rs @@ -1,6 +1,7 @@ use bevy::input::keyboard::Key; use bevy::prelude::*; use bevy_ratatui::RatatuiContext; +use ratatui::widgets::Block; use tui_logger::TuiLoggerWidget; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)] @@ -33,7 +34,8 @@ pub(crate) fn toggle_console( pub(crate) fn draw_console(mut tui_ctx: ResMut) -> Result { tui_ctx.draw(|frame| { - frame.render_widget(TuiLoggerWidget::default(), frame.area()); + let block = Block::bordered().title("console"); + frame.render_widget(TuiLoggerWidget::default().block(block), frame.area()); })?; Ok(()) diff --git a/src/tui/mod.rs b/src/tui/mod.rs index 6b10813..37c9315 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -2,14 +2,26 @@ use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; use bevy_ratatui::RatatuiPlugins; -use jong::tiles::InWall; use ratatui::{text::ToSpan, widgets::Paragraph}; +use jong::game::GameState; +use jong::game::wall::InWall; + mod console; mod input; mod render; -pub struct RiichiTui; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)] +enum TuiState { + MainMenu, + #[default] + InGame, +} + +#[derive(Default)] +pub struct RiichiTui { + // player_names: Vec, +} impl Plugin for RiichiTui { fn build(&self, app: &mut App) { @@ -25,20 +37,19 @@ impl Plugin for RiichiTui { }, )) .add_plugins(StatesPlugin) + + // setup console .init_state::() .add_systems(Update, console::toggle_console) .add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open))) + .init_state::() - .add_systems(Update, input::keyboard_input_system) + // .add_systems(Update, input::keyboard_input_system) .add_systems(Update, render::draw_ingame.run_if(in_state(TuiState::InGame))) + .add_systems(Update,render::render_changed_hand.run_if(in_state(GameState::Play))) // semicolon stopper ; } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)] -enum TuiState { - MainMenu, - #[default] - InGame, -} +// fn prompt_names() {} diff --git a/src/tui/render.rs b/src/tui/render.rs index a7bece1..e3fe942 100644 --- a/src/tui/render.rs +++ b/src/tui/render.rs @@ -1,54 +1,81 @@ -use std::marker::PhantomData; - use bevy::ecs::system::SystemParam; use bevy::prelude::*; use bevy_ratatui::RatatuiContext; use ratatui::widgets::Paragraph; -use jong::game::wall::Wall; -use jong::game::wall::WallTiles; -use jong::tiles::Tile; +use jong::{ + game::{ + player::{Hand, HandTiles}, + wall::{Wall, WallTiles}, + }, + tiles::Tile, +}; mod tiles; -pub(crate) fn draw_ingame( +#[derive(Component)] +pub(crate) struct RenderedHand<'a>(Vec>); + +pub(crate) fn render_changed_hand( + hand: Single<&HandTiles, Changed>, + // hand_tiles: Query<&HandTiles, With>, tiles: Query<&Tile>, - wall: Option>>, + mut target: Single<&'static mut RenderedHand>, +) -> Result { + let hand_tiles = hand + .iter() + .map(|inhand| -> Result<_> { Ok(tiles.get(inhand).map(tiles::draw_tile)?) }) + .collect::>>()?; + + target.0 = hand_tiles; + + Ok(()) +} + +pub(crate) fn draw_ingame( + // tiles: Query<&Tile>, + // wall_tiles: Option>>, + // hand_tiles: Query<&HandTiles, With>, + rendered_hand: Single<&'static RenderedHand>, mut tui_ctx: ResMut, ) -> Result { use ratatui::layout::Flex; use ratatui::prelude::*; - let title = ratatui::text::Text::raw("tiny riichi"); + // let title = ratatui::text::Text::raw("tiny riichi"); - let wall = if let Some(wall) = wall { - let wall = wall - .iter() - .map(|inwall| -> Result<_> { Ok(tiles.get(inwall).map(tiles::draw_tile)?) }) - .collect::>>()?; + // let wall = if let Some(wall_tiles) = wall_tiles { + // let wall_tiles = wall_tiles + // .iter() + // .map(|inwall| -> Result<_> { Ok(tiles.get(inwall).map(tiles::draw_tile)?) }) + // .collect::>>()?; - // let paragraph = Paragraph::new(wall.join(", ")).wrap(ratatui::widgets::Wrap { trim: true }); - Some(wall) - } else { - None - }; + // // let paragraph = Paragraph::new(wall.join(", ")).wrap(ratatui::widgets::Wrap { trim: true }); + // Some(wall_tiles) + // } else { + // None + // }; tui_ctx.draw(|frame| { // frame.render_widget(title, frame.area()); debug!("{}", frame.area()); - if let Some(wall) = wall { - // let tile_area = Rect::new(0, 0, 5, 4); - let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start); - let mut area = frame.area(); - area.height = 4; - let areas = layout.areas::<13>(area); - // debug!("wall.len(): {}, areas.len(): {}", wall.len(), areas.len()); - for (tile, rect) in wall.iter().zip(areas.iter()) { - // debug!("{rect:?}"); - frame.render_widget(tile, *rect); - } + // if let Some(wall) = wall { + // // let tile_area = Rect::new(0, 0, 5, 4); + let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start); + let mut area = frame.area(); + area.height = 4; + let areas = layout.areas::<13>(area); + for (tile, area) in rendered_hand.0.iter().zip(areas.iter()) { + frame.render_widget(tile, *area); } + + // // debug!("wall.len(): {}, areas.len(): {}", wall.len(), areas.len()); + // for (tile, rect) in wall.iter().zip(areas.iter()) { + // // debug!("{rect:?}"); + // frame.render_widget(tile, *rect); + // } + // } })?; Ok(()) diff --git a/src/tui/render/tiles.rs b/src/tui/render/tiles.rs index 802b38d..620a2d1 100644 --- a/src/tui/render/tiles.rs +++ b/src/tui/render/tiles.rs @@ -2,7 +2,7 @@ use ratatui::widgets::Paragraph; use jong::tiles::Tile; -pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'_> { +pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'static> { use ratatui::prelude::*; let block = ratatui::widgets::Block::bordered();