Partially complete the highlighted card movement

Once I write a "lowest visible card" function, then it should
be easy to do the rest
This commit is contained in:
2025-06-27 23:26:01 +01:00
parent 3bc26915d1
commit 67dc528c6a
2 changed files with 74 additions and 12 deletions

View File

@@ -218,7 +218,7 @@ pub struct CardAndPosition {
pos: CardPosition, pos: CardPosition,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Copy, Clone)]
pub enum CardPosition { pub enum CardPosition {
TopWaste, // I don't think we'd ever interact with anything other than the top of the Waste TopWaste, // I don't think we'd ever interact with anything other than the top of the Waste
Pile(usize, usize), // (PileNumber, Index) Pile(usize, usize), // (PileNumber, Index)

View File

@@ -1,5 +1,6 @@
use core::panic;
use std::io; use std::io;
use card_stuffs::{self}; use card_stuffs::{self, CardPosition};
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
use ratatui::{ use ratatui::{
@@ -10,22 +11,35 @@ use ratatui::{
DefaultTerminal, Frame, DefaultTerminal, Frame,
}; };
#[derive(Debug, Default)] #[derive(Debug)]
pub struct App { pub struct App {
cards: card_stuffs::Klondike, cards: card_stuffs::Klondike,
// There aren't pretty... not sure what else I can do about that though... // There aren't pretty... not sure what else I can do about that though...
highlighted_card: Option<card_stuffs::Card>, highlighted_card: card_stuffs::CardPosition,
// I should think about making this a Vec so I can highlight a whole stack which is about to move // I should think about making this a Vec so I can highlight a whole stack which is about to move
selected_card: Option<card_stuffs::Card>, selected_card: Option<card_stuffs::CardPosition>,
exit: bool, exit: bool,
show_help: bool, show_help: bool,
show_exit: bool, show_exit: bool,
} }
impl Default for App {
fn default() -> Self {
Self {
cards: card_stuffs::Klondike::default(),
highlighted_card: card_stuffs::CardPosition::Pile(0,0),
selected_card: None,
exit: false,
show_exit: false,
show_help: false,
}
}
}
const CARD_HEIGHT: u16 = 11; const CARD_HEIGHT: u16 = 11;
const CARD_WIDTH: u16 = 15; const CARD_WIDTH: u16 = 15;
fn draw_waste(cards_in_waste: &Vec<card_stuffs::Card>, area: Rect, frame: &mut Frame) { fn draw_waste(cards_in_waste: &Vec<card_stuffs::Card>, area: Rect, frame: &mut Frame, highlight: bool) {
let horizontal = Layout::horizontal([ let horizontal = Layout::horizontal([
Constraint::Length(3), Constraint::Length(3),
Constraint::Length(3), Constraint::Length(3),
@@ -50,7 +64,7 @@ fn draw_waste(cards_in_waste: &Vec<card_stuffs::Card>, area: Rect, frame: &mut F
w2 w2
); );
frame.render_widget( frame.render_widget(
card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, false, false), card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, highlight, false),
top_waste top_waste
); );
} else if cards_in_waste.len() == 2 { } else if cards_in_waste.len() == 2 {
@@ -59,12 +73,12 @@ fn draw_waste(cards_in_waste: &Vec<card_stuffs::Card>, area: Rect, frame: &mut F
w2 w2
); );
frame.render_widget( frame.render_widget(
card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, false, false), card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, highlight, false),
top_waste top_waste
); );
} else if cards_in_waste.len() == 1 { } else if cards_in_waste.len() == 1 {
frame.render_widget( frame.render_widget(
card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, false, false), card_widget(&cards_in_waste[cards_in_waste.len() - 1], true, highlight, false),
top_waste top_waste
); );
} }
@@ -160,7 +174,7 @@ impl App {
deck_area deck_area
); );
draw_waste(&self.cards.waste, waste_area, frame); draw_waste(&self.cards.waste, waste_area, frame, self.highlighted_card == CardPosition::TopWaste);
for fa in foundation_areas { for fa in foundation_areas {
frame.render_widget( frame.render_widget(
@@ -206,8 +220,8 @@ impl App {
None => break, None => break,
Some(c) => { Some(c) => {
let is_top_card = i == self.cards.piles[pile].len() - 1; let is_top_card = i == self.cards.piles[pile].len() - 1;
let highlight = self.highlighted_card.is_some() && *c == self.highlighted_card.unwrap(); let highlight = self.highlighted_card == CardPosition::Pile(pile, i);
let selected = self.selected_card.is_some() && *c == self.selected_card.unwrap(); let selected = true; // FIXME
let a_card = match c.visible { let a_card = match c.visible {
true => card_widget(c, is_top_card, highlight, selected), true => card_widget(c, is_top_card, highlight, selected),
false => card_widget(c, is_top_card, highlight, selected), false => card_widget(c, is_top_card, highlight, selected),
@@ -253,6 +267,10 @@ impl App {
KeyCode::Char('1') => self.cards.num_cards_turned = 1, KeyCode::Char('1') => self.cards.num_cards_turned = 1,
KeyCode::Char('3') => self.cards.num_cards_turned = 3, KeyCode::Char('3') => self.cards.num_cards_turned = 3,
KeyCode::Char('h') => self.show_help = !self.show_help, // toggle KeyCode::Char('h') => self.show_help = !self.show_help, // toggle
KeyCode::Left => self.highlighted_card = handle_move_highlighted(&self.highlighted_card, Direction::Left),
KeyCode::Right => self.highlighted_card = handle_move_highlighted(&self.highlighted_card, Direction::Right),
KeyCode::Up => self.highlighted_card = handle_move_highlighted(&self.highlighted_card, Direction::Up),
KeyCode::Down => self.highlighted_card = handle_move_highlighted(&self.highlighted_card, Direction::Down),
_ => {} _ => {}
} }
} }
@@ -269,6 +287,50 @@ fn main() -> io::Result<()> {
app_result app_result
} }
enum Direction {
Up,
Down,
Left,
Right,
}
fn handle_move_highlighted(current_position: &CardPosition, direction: Direction) -> CardPosition {
match current_position {
CardPosition::TopWaste => {
match direction {
Direction::Up | Direction::Left => { CardPosition::TopWaste },
Direction::Right => { CardPosition::Foundation(0) }
Direction::Down => { CardPosition:: Pile(0, 0) }
}
},
CardPosition::Pile(p, i) => {
*current_position // FIXME
},
CardPosition::Foundation(f) => {
match direction {
Direction::Up => { CardPosition::Foundation(*f) },
Direction::Left => {
if *f == 0 { CardPosition::TopWaste }
else { CardPosition::Foundation(f - 1) }
},
Direction::Right => {
if *f >= 3 { CardPosition::Foundation(3) }
else { CardPosition::Foundation(*f + 1)}
}
Direction::Down => {
match f {
0 => *current_position, // FIXME - need a "lowest visible card" function - also need to pass more info into here
1 => *current_position,
2 => *current_position,
3 => *current_position,
_ => panic!("Should be on a higher foundation")
}
}
}
}
}
}
fn show_help(frame: &mut Frame, area: &Rect) { fn show_help(frame: &mut Frame, area: &Rect) {
let block = Block::bordered().title("Help"); let block = Block::bordered().title("Help");
let text = let text =