diff --git a/src/app/helpers/cells_area.rs b/src/app/helpers/cells_area.rs index c2f245b..aed40d2 100644 --- a/src/app/helpers/cells_area.rs +++ b/src/app/helpers/cells_area.rs @@ -9,7 +9,7 @@ pub fn cells_area_helper(area: &Rect) -> Rect { .borders(Borders::LEFT | Borders::TOP | Borders::RIGHT) .inner(skirmish_layout(*area)[1]) .inner(Margin { - horizontal: 3, + horizontal: 1, vertical: 1, }) } diff --git a/src/app/states/skirmish_states/board.rs b/src/app/states/skirmish_states/board.rs index 1ce46ab..77df666 100644 --- a/src/app/states/skirmish_states/board.rs +++ b/src/app/states/skirmish_states/board.rs @@ -1,7 +1,7 @@ use crate::app::{ helpers::{CellSizes, cell_size_helper, cells_area_helper}, states::{FocusedCell, Offset, ZoomLevel, skirmish_states::MoveFocusedCell}, - widgets::CellWidget, + widgets::{CellTag, CellWidget, Players}, }; use ratatui::layout::Rect; @@ -19,6 +19,8 @@ pub struct BoardState { pub cells: Vec>, pub zoom_level: ZoomLevel, focused_cell: FocusedCell, + player_base_coords: (usize, usize), + enemy_base_coords: (usize, usize), } impl BoardState { @@ -35,25 +37,34 @@ impl BoardState { let h_max_offset: usize = Self::max_offset(map_width, cols); let vertical_offset: Offset = Offset::new( - Some((map_height - rows as usize) / 2 + 1), + Some((map_height - rows as usize + 1) / 2), Some(v_max_offset), ); let horizontal_offset: Offset = Offset::new(None, Some(h_max_offset)); - let focused_cell: FocusedCell = FocusedCell::new(map_height / 2, 2, map_height, map_width); + let focused_cell: FocusedCell = + FocusedCell::new((map_height) / 2, 2, map_height, map_width); let mut cells: Vec> = Vec::new(); + let player_base_coords: (usize, usize) = ((map_height) / 2, 1); + let enemy_base_coords: (usize, usize) = ((map_height) / 2, map_width - 2); + for row in 0..map_height { let mut rows: Vec = Vec::new(); for col in 0..map_width { - rows.push(CellWidget::new( - row, - col, - row == focused_cell.get_row() && col == focused_cell.get_col(), - zoom_level, - )); + let selected: bool = row == focused_cell.get_row() && col == focused_cell.get_col(); + + let tag: CellTag = if row == player_base_coords.0 && col == player_base_coords.1 { + CellTag::Base(Players::Player) + } else if row == enemy_base_coords.0 && col == enemy_base_coords.1 { + CellTag::Base(Players::Enemy) + } else { + CellTag::Stone + }; + + rows.push(CellWidget::new(row, col, zoom_level, selected, tag)); } cells.push(rows); @@ -72,6 +83,8 @@ impl BoardState { cells, zoom_level, focused_cell, + player_base_coords, + enemy_base_coords, } } diff --git a/src/app/views/skirmish.rs b/src/app/views/skirmish.rs index 21567f9..587144f 100644 --- a/src/app/views/skirmish.rs +++ b/src/app/views/skirmish.rs @@ -89,11 +89,22 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) { board_block.render(main_area, buf); let cells_area: Rect = board_area.inner(Margin { - horizontal: 3, + horizontal: 1, vertical: 1, }); - BoardWidget::new(&states.skirmish.board).render(cells_area, buf); + // TODO: add actual (effective) board sizes as Constraints + BoardWidget::new(&states.skirmish.board).render( + cells_area.centered( + Constraint::Length( + (states.skirmish.board.cell_width * states.skirmish.board.cols) as u16, + ), + Constraint::Length( + (states.skirmish.board.cell_height * states.skirmish.board.rows) as u16, + ), + ), + buf, + ); } { diff --git a/src/app/widgets/cell.rs b/src/app/widgets/cell.rs index 284f62b..9e23ddf 100644 --- a/src/app/widgets/cell.rs +++ b/src/app/widgets/cell.rs @@ -3,17 +3,22 @@ use ratatui::{ buffer::Buffer, layout::{Alignment, Rect}, style::{Color, Style, Stylize}, - text::Line, + text::{Line, Span, ToSpan}, widgets::{Block, Borders, Paragraph, Widget}, }; -// pub enum CellTags { -// Player, -// Enemy, -// Dirt, -// Tunnel, -// Base, -// } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CellTag { + Base(Players), + Tunel, + Stone, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Players { + Player, + Enemy, +} #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CellWidget { @@ -21,16 +26,23 @@ pub struct CellWidget { col: usize, selected: bool, zoom_level: ZoomLevel, - // pub tags: Vec, + tag: CellTag, } impl CellWidget { - pub fn new(row: usize, col: usize, selected: bool, zoom_level: ZoomLevel) -> Self { + pub fn new( + row: usize, + col: usize, + zoom_level: ZoomLevel, + selected: bool, + tag: CellTag, + ) -> Self { Self { row, col, selected, zoom_level, + tag, } } @@ -42,6 +54,10 @@ impl CellWidget { self.zoom_level = zoom_level; } + pub fn set_tag(&mut self, tag: CellTag) { + self.tag = tag; + } + fn col_to_letters(&self) -> String { let mut col: usize = self.col + 1; let mut letters: Vec = Vec::new(); @@ -54,36 +70,49 @@ impl CellWidget { letters.iter().rev().collect() } - fn display_coords(&self) -> String { - format!("{}{}", self.col_to_letters(), self.row) + fn display_coords(&self) -> Span<'_> { + if self.selected || self.tag != CellTag::Stone { + format!("{}{}", self.col_to_letters(), self.row).green() + } else { + "".to_span() + } } fn fg_color(&self) -> Color { - if self.selected { - Color::Red - } else { - Color::White + match self.tag { + _ if self.selected => Color::LightYellow, + CellTag::Base(Players::Player) if !self.selected => Color::LightBlue, + CellTag::Base(Players::Enemy) if !self.selected => Color::LightRed, + CellTag::Tunel if !self.selected => Color::Gray, + _ => Color::White, } } fn get_text_area(&self) -> Vec> { + let tag: &str = match self.tag { + CellTag::Base(_) => "B", + CellTag::Tunel => "T", + CellTag::Stone => " ", + }; + let units: &str = " "; // TODO: units count on that cell + let mut text_area: Vec> = Vec::new(); match self.zoom_level { ZoomLevel::ZoomedIn => { - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); + text_area.push(Line::from(format!(" {}", units))); + text_area.push(Line::from(format!(" "))); + text_area.push(Line::from(format!(" {} ", tag))); + text_area.push(Line::from(format!(" "))); + text_area.push(Line::from(format!(" "))); } ZoomLevel::Default => { - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); - text_area.push(Line::from(" ")); + text_area.push(Line::from(format!(" {}", units))); + text_area.push(Line::from(format!(" {} ", tag))); + text_area.push(Line::from(format!(" "))); } ZoomLevel::ZoomedOut => { - text_area.push(Line::from(" ")); + text_area.push(Line::from(format!(" {} ", tag))); } } @@ -94,7 +123,7 @@ impl CellWidget { Block::default() .borders(Borders::ALL) .style(Style::default().fg(self.fg_color())) - .title(self.display_coords().green()) + .title(self.display_coords()) } } diff --git a/src/app/widgets/mod.rs b/src/app/widgets/mod.rs index b325419..ebbe432 100644 --- a/src/app/widgets/mod.rs +++ b/src/app/widgets/mod.rs @@ -3,5 +3,5 @@ pub mod cell; pub mod keybindings; pub use board::BoardWidget; -pub use cell::CellWidget; +pub use cell::{CellTag, CellWidget, Players}; pub use keybindings::KeybindingsWidget; diff --git a/src/cli.rs b/src/cli.rs index f1d0a01..5f9081c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -49,18 +49,18 @@ pub struct Cli { long, help = "Map width", value_name = "Positive integer [36; 108]", - default_value = "36", + default_value = "42", value_parser = value_parser!(u8).range(36..=108) )] pub map_width: u8, - /// Height of the generated map (13–50 tiles). + /// Height of the generated map (11–50 tiles). #[arg( long, help = "Map height", - value_name = "Positive integer [13; 39]", - default_value = "13", - value_parser = value_parser!(u8).range(13..=39) + value_name = "Positive integer [11; 39]", + default_value = "11", + value_parser = value_parser!(u8).range(11..=39) )] pub map_height: u8,