use smart pointers for cards instead of cloning

This commit is contained in:
Adam 2024-08-14 23:14:57 -04:00
parent 51943f35d2
commit 5499a854b0

View file

@ -59,10 +59,6 @@ impl GameHandler {
// Send updates for all players
for player in this_game.read().unwrap().players.values() {
// Create update for user's game view
let mut black_card = ("Error".to_string(), 0u8);
if let Some(ref current_black) = this_game.read().unwrap().current_black {
black_card = (current_black.text.to_owned(), current_black.pick)
}
let meta = GameStateMeta {
uuid: id.clone(),
name: this_game.read().unwrap().name.clone(),
@ -75,7 +71,10 @@ impl GameHandler {
.map(|player| player.user.read().unwrap().name.clone())
.collect(),
czar: this_game.read().unwrap().host.read().unwrap().name.clone(),
black: black_card,
black: (
this_game.read().unwrap().current_black.text.clone(),
this_game.read().unwrap().current_black.pick,
),
white: player.white.iter().map(|card| card.text.clone()).collect(),
packs: this_game.read().unwrap().packs.clone(),
};
@ -101,10 +100,10 @@ impl GameHandler {
async fn new_game(&self, addr: SocketAddr, new_game: NewGameRequest) {
if new_game.packs.is_empty() {
tracing::debug!("Cards are empty");
tracing::error!("New game cards are empty!");
return;
} else if new_game.name.is_empty() {
tracing::debug!("Name are empty");
tracing::error!("New game name is empty!");
return;
}
@ -136,10 +135,6 @@ impl GameHandler {
.clone();
// Create update for user's game view
let mut black_card = ("Error".to_string(), 0u8);
if let Some(ref current_black) = new_game_object.current_black {
black_card = (current_black.text.to_owned(), current_black.pick)
}
let meta = GameStateMeta {
uuid: new_game_object.uuid.to_string(),
name: new_game_object.name.clone(),
@ -161,7 +156,10 @@ impl GameHandler {
})
.collect(),
czar: new_game_object.host.read().unwrap().name.clone(),
black: black_card,
black: (
new_game_object.current_black.text.clone(),
new_game_object.current_black.pick,
),
white: new_game_object
.players
.get(&new_game_object.host.read().unwrap().uuid)
@ -202,8 +200,8 @@ impl GameHandler {
/// Card Set
#[derive(Debug)]
struct CardSet {
white: Option<Vec<CardWhite>>,
black: Option<Vec<CardBlack>>,
white: Option<Vec<Arc<CardWhite>>>,
black: Option<Vec<Arc<CardBlack>>>,
}
/// Card Packs
@ -265,9 +263,9 @@ pub struct Player {
/// Pointer to user
user: Arc<RwLock<User>>,
/// The player's hand
white: Vec<CardWhite>,
white: Vec<Arc<CardWhite>>,
/// The player's wins
black: Vec<CardBlack>,
black: Vec<Arc<CardBlack>>,
}
/// The game master
@ -280,19 +278,17 @@ pub struct Game {
/// The host user of the game
pub host: Arc<RwLock<User>>,
/// White draw pile
white: Vec<CardWhite>,
white: Vec<Arc<CardWhite>>,
/// Black draw pile
black: Vec<CardBlack>,
black: Vec<Arc<CardBlack>>,
pub players: HashMap<Uuid, Player>,
/// Black card for the current round
current_black: Option<CardBlack>,
current_black: Arc<CardBlack>,
pub packs: Vec<u8>,
}
impl Game {
fn new(state: Arc<AppState>, request: NewGameManifest) -> Result<Self> {
tracing::debug!("{:#?}", request.packs);
tracing::debug!("{:#?}", request.packs.len());
let mut game = Game {
uuid: Uuid::now_v7(),
name: request.host.read().unwrap().name.clone(),
@ -300,7 +296,11 @@ impl Game {
white: vec![],
black: vec![],
players: HashMap::new(),
current_black: Option::None,
current_black: Arc::new(CardBlack {
text: "test".to_string(),
pack: 0u8,
pick: 0u8,
}),
packs: request.packs.clone(),
};
tracing::debug!(
@ -313,7 +313,7 @@ impl Game {
game.build_decks(state, request.packs)?;
game.create_player(request.host)?;
game.deal_black()?;
game.deal_black();
Ok(game)
}
@ -344,41 +344,37 @@ impl Game {
}
/// Draw one white card at random from play deck.
fn draw_one_white(&mut self) -> Result<CardWhite> {
fn draw_one_white(&mut self) -> Option<Arc<CardWhite>> {
let deck = &mut self.white;
// TODO: this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
Some(deck.swap_remove(index))
} else {
Ok(CardWhite {
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
pack: 0,
})
tracing::error!("Tried to draw white card that doesn't exist!");
None
}
}
/// Draw one black card at random from play deck.
fn draw_one_black(&mut self) -> Result<CardBlack> {
fn draw_one_black(&mut self) -> Option<Arc<CardBlack>> {
let deck = &mut self.black;
// TODO: this feels sloppy
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
Ok(deck.swap_remove(index))
Some(deck.swap_remove(index))
} else {
Ok(CardBlack {
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
pick: 0,
pack: 0,
})
tracing::error!("Tried to draw black card that doesn't exist!");
None
}
}
/// Deal a black card and use it for the current round
fn deal_black(&mut self) -> Result<()> {
self.current_black = Some(self.draw_one_black()?);
Ok(())
fn deal_black(&mut self) {
if let Some(black_card) = self.draw_one_black() {
self.current_black = black_card;
} else {
tracing::error!("Tried to deal black card that doesn't exist!");
}
}
/// Create a new player and add them to the game.
@ -394,7 +390,9 @@ impl Game {
let mut hand_buf = vec![];
for _ in 0..10 {
hand_buf.push(self.draw_one_white()?);
if let Some(card) = self.draw_one_white() {
hand_buf.push(card);
}
}
tracing::debug!("Dealing hand to {}", &new_player_name);
@ -438,7 +436,18 @@ pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
num_white = white.len();
if num_white > 0 {
pack = Some(white[0].pack);
newset.white = Some(set.white.unwrap());
newset.white = Some(
set.white
.unwrap()
.iter()
.map(|card| {
Arc::new(CardWhite {
text: card.text.clone(),
pack: card.pack.clone(),
})
})
.collect(),
);
}
}
@ -446,7 +455,19 @@ pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
num_black = black.len();
if num_black > 0 {
pack = Some(black[0].pack);
newset.black = Some(set.black.unwrap());
newset.black = Some(
set.black
.unwrap()
.iter()
.map(|card| {
Arc::new(CardBlack {
text: card.text.clone(),
pick: card.pick.clone(),
pack: card.pack.clone(),
})
})
.collect(),
);
}
}