detect hand change and render it
This commit is contained in:
parent
d506a25716
commit
3417384b86
9 changed files with 138 additions and 68 deletions
|
|
@ -3,30 +3,32 @@ use tracing::instrument;
|
||||||
|
|
||||||
use crate::tiles::{self, *};
|
use crate::tiles::{self, *};
|
||||||
|
|
||||||
mod player;
|
pub mod player;
|
||||||
pub mod wall;
|
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 {
|
impl Plugin for Riichi {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<Compass>()
|
app.init_resource::<Compass>()
|
||||||
.add_systems(Startup, init_match)
|
.add_systems(Startup, init_match)
|
||||||
.add_systems(Startup, (tiles::init_tiles, wall::build_wall).chain())
|
.add_systems(Startup, tiles::init_tiles)
|
||||||
|
.init_state::<GameState>()
|
||||||
|
.add_systems(OnEnter(GameState::Setup), (wall::build_wall, player::deal_hands).chain())
|
||||||
// semicolon stopper
|
// semicolon stopper
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq)]
|
|
||||||
enum GameState {
|
|
||||||
#[default]
|
|
||||||
Setup,
|
|
||||||
Deal,
|
|
||||||
Play,
|
|
||||||
Score,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Dice(u8, u8);
|
pub(crate) struct Dice(u8, u8);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,44 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
game::wall::{Wall, WallTiles},
|
||||||
|
tiles::Tile,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Player {
|
pub(crate) struct Player {
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spawn_players(mut commands: Commands) {}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Points(pub isize);
|
pub(crate) struct Points(pub isize);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Hand;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship_target(relationship = InHand, linked_spawn)]
|
||||||
|
pub struct HandTiles(Vec<Entity>);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship(relationship_target = HandTiles)]
|
||||||
|
pub struct InHand(pub Entity);
|
||||||
|
|
||||||
|
pub(crate) fn deal_hands(
|
||||||
|
mut commands: Commands,
|
||||||
|
wall: Single<Entity, With<Wall>>,
|
||||||
|
wall_tiles: Query<Entity, With<WallTiles>>,
|
||||||
|
tiles: Query<Entity, With<Tile>>,
|
||||||
|
) -> Result {
|
||||||
|
let hand = wall_tiles.iter().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
commands
|
||||||
|
.get_entity(*wall)?
|
||||||
|
.remove_children(hand.last_chunk::<13>().unwrap());
|
||||||
|
|
||||||
|
commands.spawn((Hand, HandTiles(hand)));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,20 @@ use bevy::log::tracing::instrument;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
use crate::game::InWall;
|
|
||||||
use crate::tiles::Tile;
|
use crate::tiles::Tile;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Wall;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[relationship_target(relationship = InWall, linked_spawn)]
|
#[relationship_target(relationship = InWall, linked_spawn)]
|
||||||
pub struct WallTiles(Vec<Entity>);
|
pub struct WallTiles(Vec<Entity>);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Wall;
|
#[relationship(relationship_target = WallTiles)]
|
||||||
|
pub struct InWall(pub Entity);
|
||||||
|
|
||||||
pub(crate) fn build_wall(mut commands: Commands, tiles: Query<Entity, With<Tile>>) -> Result {
|
pub(crate) fn build_wall(mut commands: Commands, tiles: Query<Entity, With<Tile>>) {
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let mut shuffled = tiles
|
let mut shuffled = tiles
|
||||||
|
|
@ -21,7 +24,5 @@ pub(crate) fn build_wall(mut commands: Commands, tiles: Query<Entity, With<Tile>
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
shuffled.shuffle(&mut rng);
|
shuffled.shuffle(&mut rng);
|
||||||
|
|
||||||
let mut wall = commands.spawn((Wall, WallTiles(shuffled)));
|
commands.spawn((Wall, WallTiles(shuffled)));
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ fn main() {
|
||||||
tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap();
|
tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap();
|
||||||
tui_logger::set_env_filter_from_string(FILTERSTRING);
|
tui_logger::set_env_filter_from_string(FILTERSTRING);
|
||||||
|
|
||||||
app.add_plugins(tui::RiichiTui)
|
app.add_plugins(tui::RiichiTui::default())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
10
src/tiles.rs
10
src/tiles.rs
|
|
@ -2,15 +2,7 @@ use bevy::{ecs::entity::MapEntities, prelude::*};
|
||||||
use strum::FromRepr;
|
use strum::FromRepr;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::game::wall::WallTiles;
|
use crate::game::{player::HandTiles, 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);
|
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub struct Tile {
|
pub struct Tile {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use bevy::input::keyboard::Key;
|
use bevy::input::keyboard::Key;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_ratatui::RatatuiContext;
|
use bevy_ratatui::RatatuiContext;
|
||||||
|
use ratatui::widgets::Block;
|
||||||
use tui_logger::TuiLoggerWidget;
|
use tui_logger::TuiLoggerWidget;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
|
#[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<RatatuiContext>) -> Result {
|
pub(crate) fn draw_console(mut tui_ctx: ResMut<RatatuiContext>) -> Result {
|
||||||
tui_ctx.draw(|frame| {
|
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(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,26 @@ use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
|
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
|
||||||
use bevy_ratatui::RatatuiPlugins;
|
use bevy_ratatui::RatatuiPlugins;
|
||||||
use jong::tiles::InWall;
|
|
||||||
use ratatui::{text::ToSpan, widgets::Paragraph};
|
use ratatui::{text::ToSpan, widgets::Paragraph};
|
||||||
|
|
||||||
|
use jong::game::GameState;
|
||||||
|
use jong::game::wall::InWall;
|
||||||
|
|
||||||
mod console;
|
mod console;
|
||||||
mod input;
|
mod input;
|
||||||
mod render;
|
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<String>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Plugin for RiichiTui {
|
impl Plugin for RiichiTui {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
|
|
@ -25,20 +37,19 @@ impl Plugin for RiichiTui {
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.add_plugins(StatesPlugin)
|
.add_plugins(StatesPlugin)
|
||||||
|
|
||||||
|
// setup console
|
||||||
.init_state::<console::ConsoleState>()
|
.init_state::<console::ConsoleState>()
|
||||||
.add_systems(Update, console::toggle_console)
|
.add_systems(Update, console::toggle_console)
|
||||||
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
|
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
|
||||||
|
|
||||||
.init_state::<TuiState>()
|
.init_state::<TuiState>()
|
||||||
.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::draw_ingame.run_if(in_state(TuiState::InGame)))
|
||||||
|
.add_systems(Update,render::render_changed_hand.run_if(in_state(GameState::Play)))
|
||||||
// semicolon stopper
|
// semicolon stopper
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)]
|
// fn prompt_names() {}
|
||||||
enum TuiState {
|
|
||||||
MainMenu,
|
|
||||||
#[default]
|
|
||||||
InGame,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,81 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use bevy::ecs::system::SystemParam;
|
use bevy::ecs::system::SystemParam;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_ratatui::RatatuiContext;
|
use bevy_ratatui::RatatuiContext;
|
||||||
use ratatui::widgets::Paragraph;
|
use ratatui::widgets::Paragraph;
|
||||||
|
|
||||||
use jong::game::wall::Wall;
|
use jong::{
|
||||||
use jong::game::wall::WallTiles;
|
game::{
|
||||||
use jong::tiles::Tile;
|
player::{Hand, HandTiles},
|
||||||
|
wall::{Wall, WallTiles},
|
||||||
|
},
|
||||||
|
tiles::Tile,
|
||||||
|
};
|
||||||
|
|
||||||
mod tiles;
|
mod tiles;
|
||||||
|
|
||||||
pub(crate) fn draw_ingame(
|
#[derive(Component)]
|
||||||
|
pub(crate) struct RenderedHand<'a>(Vec<Paragraph<'a>>);
|
||||||
|
|
||||||
|
pub(crate) fn render_changed_hand(
|
||||||
|
hand: Single<&HandTiles, Changed<HandTiles>>,
|
||||||
|
// hand_tiles: Query<&HandTiles, With<Hand>>,
|
||||||
tiles: Query<&Tile>,
|
tiles: Query<&Tile>,
|
||||||
wall: Option<Single<&WallTiles, With<Wall>>>,
|
mut target: Single<&'static mut RenderedHand>,
|
||||||
|
) -> Result {
|
||||||
|
let hand_tiles = hand
|
||||||
|
.iter()
|
||||||
|
.map(|inhand| -> Result<_> { Ok(tiles.get(inhand).map(tiles::draw_tile)?) })
|
||||||
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
|
target.0 = hand_tiles;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn draw_ingame(
|
||||||
|
// tiles: Query<&Tile>,
|
||||||
|
// wall_tiles: Option<Single<&WallTiles, With<Wall>>>,
|
||||||
|
// hand_tiles: Query<&HandTiles, With<Hand>>,
|
||||||
|
rendered_hand: Single<&'static RenderedHand>,
|
||||||
mut tui_ctx: ResMut<RatatuiContext>,
|
mut tui_ctx: ResMut<RatatuiContext>,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
use ratatui::layout::Flex;
|
use ratatui::layout::Flex;
|
||||||
use ratatui::prelude::*;
|
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 = if let Some(wall_tiles) = wall_tiles {
|
||||||
let wall = wall
|
// let wall_tiles = wall_tiles
|
||||||
.iter()
|
// .iter()
|
||||||
.map(|inwall| -> Result<_> { Ok(tiles.get(inwall).map(tiles::draw_tile)?) })
|
// .map(|inwall| -> Result<_> { Ok(tiles.get(inwall).map(tiles::draw_tile)?) })
|
||||||
.collect::<Result<Vec<_>>>()?;
|
// .collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
// let paragraph = Paragraph::new(wall.join(", ")).wrap(ratatui::widgets::Wrap { trim: true });
|
// // let paragraph = Paragraph::new(wall.join(", ")).wrap(ratatui::widgets::Wrap { trim: true });
|
||||||
Some(wall)
|
// Some(wall_tiles)
|
||||||
} else {
|
// } else {
|
||||||
None
|
// None
|
||||||
};
|
// };
|
||||||
|
|
||||||
tui_ctx.draw(|frame| {
|
tui_ctx.draw(|frame| {
|
||||||
// frame.render_widget(title, frame.area());
|
// frame.render_widget(title, frame.area());
|
||||||
debug!("{}", frame.area());
|
debug!("{}", frame.area());
|
||||||
|
|
||||||
if let Some(wall) = wall {
|
// if let Some(wall) = wall {
|
||||||
// let tile_area = Rect::new(0, 0, 5, 4);
|
// // let tile_area = Rect::new(0, 0, 5, 4);
|
||||||
let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start);
|
let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start);
|
||||||
let mut area = frame.area();
|
let mut area = frame.area();
|
||||||
area.height = 4;
|
area.height = 4;
|
||||||
let areas = layout.areas::<13>(area);
|
let areas = layout.areas::<13>(area);
|
||||||
// debug!("wall.len(): {}, areas.len(): {}", wall.len(), areas.len());
|
for (tile, area) in rendered_hand.0.iter().zip(areas.iter()) {
|
||||||
for (tile, rect) in wall.iter().zip(areas.iter()) {
|
frame.render_widget(tile, *area);
|
||||||
// debug!("{rect:?}");
|
|
||||||
frame.render_widget(tile, *rect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // 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(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use ratatui::widgets::Paragraph;
|
||||||
|
|
||||||
use jong::tiles::Tile;
|
use jong::tiles::Tile;
|
||||||
|
|
||||||
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'_> {
|
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'static> {
|
||||||
use ratatui::prelude::*;
|
use ratatui::prelude::*;
|
||||||
|
|
||||||
let block = ratatui::widgets::Block::bordered();
|
let block = ratatui::widgets::Block::bordered();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue