Add separate player hands

This commit is contained in:
Tobias Berger 2024-04-10 07:45:23 +02:00
parent e119885dbc
commit 78e4dedf21
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
2 changed files with 85 additions and 52 deletions

View file

@ -1,4 +1,9 @@
#![warn(clippy::all, clippy::pedantic, clippy::nursery)] #![warn(clippy::all, clippy::pedantic, clippy::nursery)]
#![allow(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::too_many_lines
)]
mod card; mod card;
mod player; mod player;
@ -6,7 +11,7 @@ pub(crate) mod rect_helper;
use std::sync::RwLock; use std::sync::RwLock;
use crate::rect_helper::RectHelper; use crate::{card::Stat, rect_helper::RectHelper};
use card::Card; use card::Card;
use nannou::{ use nannou::{
image::{self, ImageFormat}, image::{self, ImageFormat},
@ -30,7 +35,8 @@ struct Model {
texture: wgpu::Texture, texture: wgpu::Texture,
ups: f64, ups: f64,
just_clicked: RwLock<bool>, just_clicked: RwLock<bool>,
hand: RwLock<[Card; HAND_CARD_COUNT]>, red_hand: RwLock<[Card; HAND_CARD_COUNT]>,
black_hand: RwLock<[Card; HAND_CARD_COUNT]>,
current_player: RwLock<Player>, current_player: RwLock<Player>,
red_stats: RwLock<Stats>, red_stats: RwLock<Stats>,
black_stats: RwLock<Stats>, black_stats: RwLock<Stats>,
@ -68,7 +74,8 @@ impl Model {
.expect("Failed to load font"), .expect("Failed to load font"),
ups: 0f64, ups: 0f64,
just_clicked: RwLock::default(), just_clicked: RwLock::default(),
hand: RwLock::new(random()), red_hand: RwLock::new(random()),
black_hand: RwLock::new(random()),
current_player: RwLock::default(), current_player: RwLock::default(),
red_stats: RwLock::default(), red_stats: RwLock::default(),
black_stats: RwLock::default(), black_stats: RwLock::default(),
@ -81,6 +88,13 @@ impl Model {
Player::Black => &self.black_stats, Player::Black => &self.black_stats,
} }
} }
const fn hand_of(&self, player: Player) -> &'_ RwLock<[Card; HAND_CARD_COUNT]> {
match player {
Player::Red => &self.red_hand,
Player::Black => &self.black_hand,
}
}
} }
fn update(_app: &App, model: &mut Model, update: Update) { fn update(_app: &App, model: &mut Model, update: Update) {
@ -103,7 +117,15 @@ fn event(_app: &App, model: &mut Model, event: WindowEvent) {
} }
} }
KeyPressed(Key::R) => { KeyPressed(Key::R) => {
*model.hand.write().expect("hand poisoned") = random(); *model
.hand_of(
*model
.current_player
.read()
.expect("current player poisoned"),
)
.write()
.expect("hand poisoned") = random();
} }
_ => {} _ => {}
} }
@ -123,16 +145,15 @@ fn player_panel(
font: Font, font: Font,
) { ) {
let rect = Rect::from_x_y_w_h(bounds.x(), bounds.y(), 1f32, 5f32).fit_into(&bounds); let rect = Rect::from_x_y_w_h(bounds.x(), bounds.y(), 1f32, 5f32).fit_into(&bounds);
let rect = if player == Player::Red { let rect = match player {
rect.align_right_of(bounds) Player::Red => rect.align_right_of(bounds),
} else { Player::Black => rect.align_left_of(bounds),
rect.align_left_of(bounds)
}; };
let player_stats = player_stats.read().expect("player stats poisoned"); let player_stats = player_stats.read().expect("player stats poisoned");
let status = if player == Player::Red { let status = match player {
format!( Player::Red => format!(
"{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence", "{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence",
player_stats.builders, player_stats.builders,
player_stats.bricks, player_stats.bricks,
@ -142,9 +163,8 @@ fn player_panel(
player_stats.crystals, player_stats.crystals,
player_stats.castle, player_stats.castle,
player_stats.fence, player_stats.fence,
) ),
} else { Player::Black => format!(
format!(
"Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}", "Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}",
player_stats.builders, player_stats.builders,
player_stats.bricks, player_stats.bricks,
@ -166,12 +186,14 @@ fn player_panel(
.font_size((rect.h() * 0.02f32).trunc() as u32) .font_size((rect.h() * 0.02f32).trunc() as u32)
.align_text_middle_y() .align_text_middle_y()
.font(font) .font(font)
.color(if player == Player::Red { RED } else { WHITE }); .color(match player {
Player::Red => RED,
Player::Black => WHITE,
});
let drawing = if player == Player::Red { let drawing = match player {
drawing.right_justify() Player::Red => drawing.right_justify(),
} else { Player::Black => drawing.left_justify(),
drawing.left_justify()
}; };
drawing.finish(); drawing.finish();
} }
@ -194,12 +216,16 @@ fn hand(
.fit_into(&bounds) .fit_into(&bounds)
.align_bottom_of(bounds); .align_bottom_of(bounds);
let current_player = *model
.current_player
.read()
.expect("current player poisoned");
for (idx, rect) in hand_rect for (idx, rect) in hand_rect
.split_horizontal::<HAND_CARD_COUNT>() .split_horizontal::<HAND_CARD_COUNT>()
.iter() .iter()
.enumerate() .enumerate()
{ {
let card = model.hand.read().expect("hand poisoned")[idx]; let card = model.hand_of(current_player).read().expect("hand poisoned")[idx];
draw.rect() draw.rect()
.xy(rect.xy()) .xy(rect.xy())
.wh(rect.wh()) .wh(rect.wh())
@ -219,28 +245,35 @@ fn hand(
.fit_into(rect) .fit_into(rect)
.align_bottom_of(*rect); .align_bottom_of(*rect);
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] draw.text(&format!(
{ "{:?}\n{}{}",
draw.text(&format!("{:?}\n+{}", card.effect.0, card.effect.1)) card.effect.0,
.color( if matches!(card.effect.0, Stat::Attack) {
if *model ""
.current_player } else {
.read() "+"
.expect("current player poisoned") },
== Player::Red card.effect.1
{ ))
RED .color(
} else { if matches!(
BLACK *model
}, .current_player
) .read()
.align_text_top() .expect("current player poisoned"),
.xy(rect.xy()) Player::Red
.wh(rect.wh()) ) {
.font_size((rect.h() * 0.08f32).trunc() as u32) RED
.font(model.font.clone()) } else {
.finish(); BLACK
} },
)
.align_text_top()
.xy(rect.xy())
.wh(rect.wh())
.font_size((rect.h() * 0.08f32).trunc() as u32)
.font(model.font.clone())
.finish();
draw.texture(&model.texture) draw.texture(&model.texture)
.xy(image_rect.xy()) .xy(image_rect.xy())
@ -252,22 +285,27 @@ fn hand(
if *can_click { if *can_click {
*can_click = false; *can_click = false;
let mut current_player = model
.current_player
.write()
.expect("current player poisoned");
let damage = if matches!(card.effect.0, card::Stat::Attack) { let damage = if matches!(card.effect.0, card::Stat::Attack) {
card.effect.1 card.effect.1
} else { } else {
model model
.stats_of(*current_player) .stats_of(current_player)
.write() .write()
.expect("player stats poisoned") .expect("player stats poisoned")
.apply(card.effect); .apply(card.effect);
0 0
}; };
model
.hand_of(current_player)
.write()
.expect("hand poisoned")[idx] = random();
let mut current_player = model
.current_player
.write()
.expect("current player poisoned");
*current_player = (*current_player).next(); *current_player = (*current_player).next();
let mut other_player_stats = model let mut other_player_stats = model
@ -277,11 +315,6 @@ fn hand(
drop(current_player); drop(current_player);
other_player_stats.damage(damage); other_player_stats.damage(damage);
other_player_stats.apply_gains(); other_player_stats.apply_gains();
drop(other_player_stats);
println!("Click! {idx} {card:?}");
model.hand.write().expect("hand poisoned")[idx] = random();
break;
} }
} }
} }

View file

@ -59,7 +59,7 @@ impl Stats {
} }
} }
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] #[derive(Default, Debug, Clone, Copy)]
pub enum Player { pub enum Player {
#[default] #[default]
Red, Red,