Got refactor to compile⚙️

This commit is contained in:
2025-03-02 04:57:58 -06:00
parent e329b1f223
commit 159126e7ca
2 changed files with 176 additions and 123 deletions

View File

@ -47,7 +47,7 @@ enum Event {
Shuffle(Player),
Draw(Player, usize),
Pass(Player, Player),
ChangeLifeTotal(Player, i32, i32),
ChangeLifeTotal(Player, isize, isize),
FadeFromHand(Player),
PlayFromHand(Player),
Bounce(Player),
@ -69,6 +69,15 @@ struct CountedEvent {
event: Event,
}
macro_rules! gen_event {
($list:expr,$event:expr) => {
$list.push(CountedEvent {
id: $list.len(),
event: $event,
})
};
}
#[derive(Clone, Debug)]
pub struct GameState {
deck: VecDeque<Uuid>,
@ -76,7 +85,7 @@ pub struct GameState {
shadow_realm: Vec<Uuid>,
play: HashMap<Uuid, InPlay>,
hands: Vec<Hand>,
life_totals: Vec<i32>,
life_totals: Vec<isize>,
turn_player: Player,
events: Vec<CountedEvent>,
}
@ -87,7 +96,7 @@ pub struct OnePlayerGameState {
shadow_realm: Vec<Uuid>,
play: Vec<InPlay>,
hand: Vec<Uuid>,
life_totals: Vec<i32>,
life_totals: Vec<isize>,
turn_player: Player,
opponent_cards_in_hand: usize,
you: Player,
@ -150,21 +159,21 @@ pub fn new() -> GameState {
}
}
pub fn draw(game_state: &mut GameState, count: usize, player: Player) {
pub fn draw(game_state: &mut GameState, count: usize, player: Player) -> Result<(), String> {
let player_hand = match player {
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Draw(player.clone(), count.clone()),
});
player_hand.cards.extend_from_slice(
game_state
.deck
.split_off(game_state.deck.len() - count)
.make_contiguous(),
let remaining_cards =
std::cmp::max(0, game_state.deck.len() as isize - count as isize) as usize;
gen_event!(
game_state.events,
Event::Draw(player.clone(), count.clone())
);
player_hand
.cards
.extend_from_slice(game_state.deck.split_off(remaining_cards).make_contiguous());
Ok(())
}
pub fn yoink(game_state: &mut GameState, deck_index: usize, player: Player) -> Result<(), String> {
@ -172,10 +181,7 @@ pub fn yoink(game_state: &mut GameState, deck_index: usize, player: Player) -> R
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Yoink(player.clone()),
});
gen_event!(game_state.events, Event::Yoink(player.clone()));
match game_state.deck.remove(deck_index) {
Some(card) => Ok(player_hand.cards.push(card)),
None => Err(format!("Yoink index out of bounds: {}", deck_index)),
@ -196,10 +202,7 @@ pub fn yoink_mill(
))
}
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::YoinkMill(card.clone()),
});
gen_event!(game_state.events, Event::YoinkMill(card.clone()));
if shadow {
game_state.shadow_realm.push(card);
} else {
@ -209,10 +212,7 @@ pub fn yoink_mill(
}
pub fn shuffle(game_state: &mut GameState, player: Player) {
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Shuffle(player),
});
gen_event!(game_state.events, Event::Shuffle(player));
game_state.deck.make_contiguous().shuffle(&mut rng());
}
@ -230,22 +230,22 @@ pub fn pass(game_state: &mut GameState) {
Player::A => Player::B,
Player::B => Player::A,
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Pass(*current_player, new_player.clone()),
});
gen_event!(
game_state.events,
Event::Pass(*current_player, new_player.clone())
);
game_state.turn_player = new_player;
}
pub fn change_life(game_state: &mut GameState, diff: i32, player: Player) {
pub fn change_life(game_state: &mut GameState, diff: isize, player: Player) {
let mut player_life = match player {
Player::A => game_state.life_totals[0].clone(),
Player::B => game_state.life_totals[1].clone(),
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::ChangeLifeTotal(player, player_life.clone(), player_life.clone() + diff),
});
gen_event!(
game_state.events,
Event::ChangeLifeTotal(player, player_life.clone(), player_life.clone() + diff)
);
player_life += diff;
match player {
Player::A => game_state.life_totals[0] = player_life,
@ -253,21 +253,28 @@ pub fn change_life(game_state: &mut GameState, diff: i32, player: Player) {
};
}
pub fn fade_from_hand(game_state: &mut GameState, hand_index: usize, player: Player, bottom: bool) {
pub fn fade_from_hand(
game_state: &mut GameState,
hand_index: usize,
player: Player,
bottom: bool,
) -> Result<(), String> {
let player_hand = match player {
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::FadeFromHand(player.clone()),
});
gen_event!(game_state.events, Event::FadeFromHand(player.clone()));
if None == player_hand.cards.get(hand_index) {
return Err(format!("Fade index out of bounds: {}", hand_index));
}
let card = player_hand.cards.remove(hand_index);
if bottom {
game_state.deck.push_front(card);
} else {
game_state.deck.push_back(card);
}
Ok(())
}
pub fn play_from_hand(
@ -279,12 +286,9 @@ pub fn play_from_hand(
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::PlayFromHand(player.clone()),
});
gen_event!(game_state.events, Event::PlayFromHand(player.clone()));
if None == player_hand.cards.get(hand_index) {
return Err(format!("Yoink index out of bounds: {}", hand_index));
return Err(format!("Play index out of bounds: {}", hand_index));
}
let card = player_hand.cards.remove(hand_index);
let play_uuid = Uuid::new_v4();
@ -311,18 +315,12 @@ pub fn bounce(game_state: &mut GameState, play_id: Uuid) -> Result<(), String> {
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Bounce(played_card.owner),
});
gen_event!(game_state.events, Event::Bounce(played_card.owner));
Ok(player_hand.cards.push(played_card.id))
}
pub fn tap(game_state: &mut GameState, play_id: Uuid) -> Result<(), String> {
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Tap(play_id.clone()),
});
gen_event!(game_state.events, Event::Tap(play_id.clone()));
match game_state.play.get_mut(&play_id) {
Some(played_card) => {
played_card.tapped = !played_card.tapped;
@ -338,6 +336,7 @@ pub fn move_played_card(
position_x: u8,
position_y: u8,
) -> Result<(), String> {
// no event made, intentionally
match game_state.play.get_mut(&play_id) {
Some(played_card) => {
played_card.position_x = position_x;
@ -348,64 +347,94 @@ pub fn move_played_card(
}
}
pub fn discard(game_state: &mut GameState, hand_index: usize, player: Player, shadow: bool) {
pub fn discard(
game_state: &mut GameState,
hand_index: usize,
player: Player,
shadow: bool,
) -> Result<(), String> {
let player_hand = match player {
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Discard(player.clone()),
});
gen_event!(game_state.events, Event::Discard(player.clone()));
if None == player_hand.cards.get(hand_index) {
return Err(format!("Discard index out of bounds: {}", hand_index));
}
let card = player_hand.cards.remove(hand_index);
if shadow {
game_state.shadow_realm.push(card);
} else {
game_state.discard_pile.push(card);
}
Ok(())
}
pub fn undiscard(game_state: &mut GameState, pile_index: usize, player: Player, shadow: bool) {
pub fn undiscard(
game_state: &mut GameState,
pile_index: usize,
player: Player,
shadow: bool,
) -> Result<(), String> {
let player_hand = match player {
Player::A => &mut game_state.hands[0],
Player::B => &mut game_state.hands[1],
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Undiscard(player.clone()),
});
let card = if shadow {
game_state.shadow_realm.remove(pile_index)
let pile = if shadow {
&mut game_state.shadow_realm
} else {
game_state.discard_pile.remove(pile_index)
&mut game_state.discard_pile
};
player_hand.cards.push(card);
if None == pile.get(pile_index) {
return Err(format!("Discard index out of bounds: {}", pile_index));
}
gen_event!(game_state.events, Event::Undiscard(player.clone()));
player_hand.cards.push(pile.remove(pile_index));
Ok(())
}
pub fn kill(game_state: &mut GameState, play_id: Uuid, shadow: bool) {
let played_card = game_state.play.remove(&play_id).unwrap();
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Kill(played_card.id.clone(), shadow),
});
pub fn kill(game_state: &mut GameState, play_id: Uuid, shadow: bool) -> Result<(), String> {
let played_card = match game_state.play.remove(&play_id) {
Some(played_card) => played_card,
None => return Err(format!("Nonexistant play id: {}", play_id)),
};
gen_event!(
game_state.events,
Event::Kill(played_card.id.clone(), shadow)
);
if shadow {
game_state.shadow_realm.push(played_card.id);
} else {
game_state.discard_pile.push(played_card.id);
}
Ok(())
}
pub fn unkill(game_state: &mut GameState, player: Player, pile_index: usize, shadow: bool) {
let card = if shadow {
game_state.shadow_realm.remove(pile_index)
pub fn unkill(
game_state: &mut GameState,
player: Player,
pile_index: usize,
shadow: bool,
) -> Result<(), String> {
let pile = if shadow {
&mut game_state.shadow_realm
} else {
game_state.discard_pile.remove(pile_index)
&mut game_state.discard_pile
};
if None == pile.get(pile_index) {
let pile_name = if shadow {
"shadow realm"
} else {
"discard pile"
};
return Err(format!(
"Transfer index out of bounds: {} ({})",
pile_index, pile_name
));
}
let card = pile.remove(pile_index);
gen_event!(game_state.events, Event::Unkill(card, shadow));
let play_uuid = Uuid::new_v4();
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::Unkill(card, shadow),
});
game_state.play.insert(
play_uuid,
InPlay {
@ -417,31 +446,43 @@ pub fn unkill(game_state: &mut GameState, player: Player, pile_index: usize, sha
play_id: play_uuid,
},
);
Ok(())
}
pub fn transfer_dead_card(game_state: &mut GameState, pile_index: usize, shadow_to_discard: bool) {
let card_id = if shadow_to_discard {
let card = game_state.shadow_realm.remove(pile_index);
let ret = card.clone();
game_state.discard_pile.push(card);
ret
pub fn transfer_dead_card(
game_state: &mut GameState,
pile_index: usize,
shadow_to_discard: bool,
) -> Result<(), String> {
let (source, target) = if shadow_to_discard {
(&mut game_state.shadow_realm, &mut game_state.discard_pile)
} else {
let card = game_state.discard_pile.remove(pile_index);
let ret = card.clone();
game_state.shadow_realm.push(card);
ret
(&mut game_state.discard_pile, &mut game_state.shadow_realm)
};
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::TransferDeadCard(card_id, shadow_to_discard),
});
if pile_index >= source.len() {
let direction = if shadow_to_discard {
"shadow realm -> discard pile"
} else {
"discard pile -> shadow realm"
};
return Err(format!(
"Transfer index out of bounds: {} ({})",
pile_index, direction
));
}
let card = source.remove(pile_index);
let card_id = card.clone();
gen_event!(
game_state.events,
Event::TransferDeadCard(card_id, shadow_to_discard)
);
target.push(card);
Ok(())
}
pub fn untap_all(game_state: &mut GameState, player: Player) {
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::UntapAll(player),
});
gen_event!(game_state.events, Event::UntapAll(player));
for (_, card) in game_state.play.iter_mut() {
if card.owner == player {
card.tapped = false;
@ -450,10 +491,7 @@ pub fn untap_all(game_state: &mut GameState, player: Player) {
}
pub fn get_deck(game_state: &mut GameState, player: Player) -> String {
game_state.events.push(CountedEvent {
id: game_state.events.len(),
event: Event::ViewDeck(player),
});
gen_event!(game_state.events, Event::ViewDeck(player));
let deck_copy = game_state.deck.clone();
serde_json::to_string(&deck_copy).unwrap()
}

View File

@ -39,10 +39,16 @@ macro_rules! get_player {
};
}
macro_rules! respond_ok {
() => {
(Status::Ok, (ContentType::Plain, "Ok!".to_string()))
};
}
macro_rules! respond {
($state:expr) => {
match $state {
Ok(()) => (Status::Ok, (ContentType::Plain, "Ok!".to_string())),
Ok(()) => respond_ok!(),
Err(err_string) => (Status::BadRequest, (ContentType::Plain, err_string)),
}
};
@ -67,7 +73,7 @@ fn index(player_uuids: &State<PlayerUuids>) -> content::RawHtml<String> {
content::RawHtml(format!(
"<a href=\"/{}/\">/{}</a><br /><a href=\"/{}/\">/{}</a>",
player_uuids.a, player_uuids.a, player_uuids.b, player_uuids.b
))
))
}
#[get("/get_events")]
@ -84,7 +90,8 @@ fn shuffle(
) -> (Status, (ContentType, String)) {
let player = get_player!(player_uuids, uuid);
unlock_state_mut!(game_state_arc, mutex, game_state);
respond!(game::shuffle(&mut game_state, player.clone()))
game::shuffle(&mut game_state, player.clone());
respond_ok!()
}
#[post("/<uuid>/pass")]
@ -95,7 +102,8 @@ fn pass(
) -> (Status, (ContentType, String)) {
assert_player!(player_uuids, uuid);
unlock_state_mut!(game_state_arc, mutex, game_state);
respond!(game::pass(&mut game_state))
game::pass(&mut game_state);
respond_ok!()
}
#[post("/<uuid>/bounce/<play_id>")]
@ -322,10 +330,13 @@ fn get_state(
) -> (Status, (ContentType, String)) {
let player = get_player!(player_uuids, uuid);
unlock_state!(game_state_arc, mutex, game_state);
(Status::Ok, (ContentType::JSON, format!(
"{}",
game::get_game_one_player(&game_state, player.clone())
)))
(
Status::Ok,
(
ContentType::JSON,
format!("{}", game::get_game_one_player(&game_state, player.clone())),
),
)
}
#[post("/<uuid>/get_deck")]
@ -336,10 +347,13 @@ fn get_deck(
) -> (Status, (ContentType, String)) {
let player = get_player!(player_uuids, uuid);
unlock_state_mut!(game_state_arc, mutex, game_state);
(Status::Ok, (ContentType::JSON, format!(
"{}",
game::get_deck(&mut game_state, player.clone())
)))
(
Status::Ok,
(
ContentType::JSON,
format!("{}", game::get_deck(&mut game_state, player.clone())),
),
)
}
#[post("/<uuid>/untap_all")]
@ -350,7 +364,8 @@ fn untap_all(
) -> (Status, (ContentType, String)) {
let player = get_player!(player_uuids, uuid);
unlock_state_mut!(game_state_arc, mutex, game_state);
respond!(game::untap_all(&mut game_state, player.clone()))
game::untap_all(&mut game_state, player.clone());
respond_ok!()
}
#[post("/<uuid>/draw/<count>")]
@ -402,13 +417,14 @@ fn fade_bottom(
#[post("/<uuid>/life/<count>")]
fn life(
uuid: Uuid,
count: i32,
count: isize,
game_state_arc: &State<ArcMutexGameState>,
player_uuids: &State<PlayerUuids>,
) -> (Status, (ContentType, String)) {
let player = get_player!(player_uuids, uuid);
unlock_state_mut!(game_state_arc, mutex, game_state);
respond!(game::change_life(&mut game_state, count, player.clone()))
game::change_life(&mut game_state, count, player.clone());
respond_ok!()
}
struct ArcMutexGameState {
@ -427,13 +443,12 @@ fn rocket() -> _ {
let game_state_arc = Arc::new(Mutex::new(game_state));
#[cfg(debug_assertions)]
let a_uuid: Uuid = uuid!("9b0a2a95-72a9-4e03-930e-a9583d2a2a5a");
let (a_uuid, b_uuid) = (
uuid!("9b0a2a95-72a9-4e03-930e-a9583d2a2a5a"),
uuid!("2efc0332-975d-4f71-9dd0-ffc9213098a5"),
);
#[cfg(not(debug_assertions))]
let a_uuid: Uuid = Uuid::new_v4();
#[cfg(debug_assertions)]
let b_uuid: Uuid = uuid!("2efc0332-975d-4f71-9dd0-ffc9213098a5");
#[cfg(not(debug_assertions))]
let b_uuid: Uuid = Uuid::new_v4();
let (a_uuid, b_uuid) = (Uuid::new_v4(), Uuid::new_v4());
let uuid_map = HashMap::from([(a_uuid, Player::A), (b_uuid, Player::B)]);
println!("A: {}", a_uuid);