From 1d9577ba4244f4eb9bcb27b491f5fc3e442e3591 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:37:12 -0800 Subject: [PATCH] render pond --- jong-line/src/reducers/hand.rs | 2 ++ jong/src/riichi.rs | 28 ++++++++++++++++++++ jong/src/riichi/player.rs | 2 +- jong/src/tui.rs | 4 +-- jong/src/tui/render.rs | 47 +++++++++++++++++++++++++++++++--- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/jong-line/src/reducers/hand.rs b/jong-line/src/reducers/hand.rs index 1e3f18a..842926a 100644 --- a/jong-line/src/reducers/hand.rs +++ b/jong-line/src/reducers/hand.rs @@ -49,6 +49,7 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { let dealt_tile = if let Some(dealt) = ctx.db.tile().id().find(tile_id) { if let Some(drawn) = player.drawn_tile { if drawn.id == dealt.id { + // dealt from drawn tile dealt } else if let Some((i, _)) = player .hand @@ -56,6 +57,7 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { .enumerate() .find(|(_, t)| t.id == tile_id) { + // dealt from hand let dealt = player.hand.remove(i); player.hand.push(drawn); player.hand.sort_by_key(|t| t.tile); diff --git a/jong/src/riichi.rs b/jong/src/riichi.rs index 0cd9eb9..61ad092 100644 --- a/jong/src/riichi.rs +++ b/jong/src/riichi.rs @@ -101,15 +101,24 @@ fn on_player_insert_update( mut messages: ReadInsertUpdateMessage, mut commands: Commands, + pond: Option>>, hand: Option>>, tiles: Query<(Entity, &TileId)>, ) { let hand = if hand.is_none() { let hand = commands.spawn(Hand).id(); + commands.spawn(Pond); hand } else { *hand.unwrap() }; + let pond = if pond.is_none() { + let pond = commands.spawn(Pond).id(); + commands.spawn(Pond); + pond + } else { + *pond.unwrap() + }; for msg in messages.read() { let hand_tiles: Vec<_> = msg @@ -125,11 +134,30 @@ fn on_player_insert_update( }) .collect(); + let pond_tiles: Vec<_> = msg + .new + .pond + .iter() + .map(|dbt| { + tiles + .iter() + .find_map(|(e, t)| if *t == TileId(dbt.id) { Some(e) } else { None }) + .expect(&format!( + "dealt tiles should still be around, couldn't find {:?}. Tiles: {:?}", + dbt, + tiles.iter().map(|(_, t)| t).collect::>() + )) + }) + .collect(); + debug!("hand_tiles: {hand_tiles:?}"); commands.entity(hand).replace_children(&hand_tiles); + commands.entity(pond).replace_children(&pond_tiles); + // drawn tile is always a new tile to us until wall isn't fake if let Some(dbt) = &msg.new.drawn_tile { + debug!("drew tile with id: {}", dbt.id); commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id), Drawn)); } } diff --git a/jong/src/riichi/player.rs b/jong/src/riichi/player.rs index 8c7ee4c..1622423 100644 --- a/jong/src/riichi/player.rs +++ b/jong/src/riichi/player.rs @@ -9,7 +9,7 @@ pub struct MainPlayer; #[derive(Component)] pub struct CurrentPlayer; -#[derive(Component, PartialEq, Eq)] +#[derive(Component, PartialEq, Eq, Debug)] pub struct TileId(pub u32); #[derive(Component)] diff --git a/jong/src/tui.rs b/jong/src/tui.rs index 18b994c..9198051 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -85,7 +85,7 @@ impl Plugin for TuiPlugin { .add_systems( Update, ( - render::render_hand.run_if(in_state(GameState::Play)), + (render::render_hand, render::render_pond).run_if(in_state(GameState::Play)), render::render, ) .chain() @@ -106,7 +106,7 @@ fn discard_tile( while let Some(message) = selected.read().next() { if let Ok(tile_id) = tiles.get(message.0) { stdb.reducers().discard_tile(tile_id.0).unwrap(); - commands.get_entity(drawn.0).unwrap().despawn(); + commands.entity(drawn.0).remove::(); } } } diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index f1a243c..409f7e2 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -6,10 +6,8 @@ use ratatui::layout::{Constraint, Flex, Layout, Offset, Rect, Size}; use ratatui::style::{Modifier, Stylize}; use ratatui::widgets::{Block, Borders, Clear, Paragraph}; -use jong::riichi::player::{CurrentPlayer, MainPlayer, Player}; -use jong::riichi::player::{Drawn, Hand}; -// use jong::riichi::round::Wind; -// use jong_types::*; +use jong::riichi::player::*; +use jong_types::*; use crate::tui::input::Hovered; use crate::tui::layout::*; @@ -197,3 +195,44 @@ pub(crate) fn render_hand( Ok(()) } + +pub(crate) fn render_pond( + mut commands: Commands, + mut tui: ResMut, + + hovered: Query>, + layouts: Res, + + pond: Single<(&Children, Entity), With>, + tiles: Query<&Tile>, +) -> Result { + let mut frame = tui.get_frame(); + + let pond: Vec<_> = pond + .0 + .iter() + .map(|entity| -> Result<_> { + let tile = tiles.get(entity).unwrap(); + let widget = render_tile(tile, false); + + Ok((entity, widget)) + }) + .collect::>()?; + + let mut this_pond = layouts.this_pond; + let row_constraints = [Constraint::Max(4); 3]; + let col_constraints = [Constraint::Max(5); 6]; + let row_layouts = Layout::vertical(row_constraints).flex(Flex::Start); + let col_layouts = Layout::horizontal(col_constraints).flex(Flex::Start); + let mut rows = row_layouts.areas::<3>(this_pond); + + for (rect, (_, tile)) in rows + .iter() + .flat_map(|row| col_layouts.areas::<6>(*row)) + .zip(pond) + { + frame.render_widget(tile, rect); + } + + Ok(()) +}