|
|
|
|
@ -10,6 +10,7 @@ impl Plugin for GamePlugin {
|
|
|
|
|
app.add_event::<Move>()
|
|
|
|
|
.add_event::<Selection>()
|
|
|
|
|
.add_state::<TurnState>()
|
|
|
|
|
.insert_resource(Score { ..default() })
|
|
|
|
|
.add_systems(Startup, setup_board)
|
|
|
|
|
.add_systems(
|
|
|
|
|
Update,
|
|
|
|
|
@ -28,6 +29,7 @@ impl Plugin for GamePlugin {
|
|
|
|
|
}),
|
|
|
|
|
show_valid_moves.run_if(any_component_added::<Selected>),
|
|
|
|
|
hide_valid_moves.run_if(any_component_removed::<Selected>()),
|
|
|
|
|
manage_score.run_if(any_component_added::<Captured>),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.add_systems(
|
|
|
|
|
@ -105,6 +107,29 @@ pub(crate) enum GameError {
|
|
|
|
|
InvalidMove,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Tracks the score of each side of the game
|
|
|
|
|
#[derive(Debug, Resource, Default)]
|
|
|
|
|
pub(crate) struct Score {
|
|
|
|
|
a: usize,
|
|
|
|
|
b: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Score {
|
|
|
|
|
fn increment(&mut self, side: Side) {
|
|
|
|
|
match side {
|
|
|
|
|
Side::A => self.a += 1,
|
|
|
|
|
Side::B => self.b += 1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn get(&self, side: Side) -> usize {
|
|
|
|
|
match side {
|
|
|
|
|
Side::A => self.a,
|
|
|
|
|
Side::B => self.b,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The board is setup like this:
|
|
|
|
|
/// ```text
|
|
|
|
|
/// 0 1 2 3 4 5 6 7
|
|
|
|
|
@ -166,6 +191,17 @@ pub(crate) enum Side {
|
|
|
|
|
B,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::ops::Not for Side {
|
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
|
|
fn not(self) -> Self::Output {
|
|
|
|
|
match self {
|
|
|
|
|
Side::A => Side::B,
|
|
|
|
|
Side::B => Side::A,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Board {
|
|
|
|
|
/// Returns the piece at the given location
|
|
|
|
|
pub(crate) fn at(&self, BoardIndex { x, y }: BoardIndex) -> Option<&Piece> {
|
|
|
|
|
@ -445,13 +481,13 @@ fn debug_board(board: Res<Board>, mut debug_info: ResMut<debug::DebugInfo>) {
|
|
|
|
|
pub(crate) fn update_board(
|
|
|
|
|
mut audio_events: EventWriter<AudioEvent>,
|
|
|
|
|
mut events: EventReader<Move>,
|
|
|
|
|
mut pieces: Query<(Entity, &mut BoardIndex), With<Piece>>,
|
|
|
|
|
mut pieces: Query<(Entity, &mut BoardIndex, &Side), With<Piece>>,
|
|
|
|
|
selected: Query<Entity, With<Selected>>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
mut played: Local<bool>,
|
|
|
|
|
) {
|
|
|
|
|
events.read().for_each(|Move { from, to, .. }| {
|
|
|
|
|
pieces.iter_mut().for_each(|(entity, mut index)| {
|
|
|
|
|
pieces.iter_mut().for_each(|(entity, mut index, side)| {
|
|
|
|
|
if *index == *from {
|
|
|
|
|
match to {
|
|
|
|
|
Some(to_idx) => {
|
|
|
|
|
@ -481,6 +517,18 @@ pub(crate) fn update_board(
|
|
|
|
|
*played = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We only track 3D (hack, for now) to prevent duplicates
|
|
|
|
|
fn manage_score(
|
|
|
|
|
events: Query<&Side, (Added<Captured>, With<display3d::Display3d>)>,
|
|
|
|
|
mut debug_info: ResMut<debug::DebugInfo>,
|
|
|
|
|
mut score: ResMut<Score>,
|
|
|
|
|
) {
|
|
|
|
|
events.iter().for_each(|side| {
|
|
|
|
|
score.increment(!*side);
|
|
|
|
|
debug_info.set("score".into(), format!("A:{}|B:{}", score.a, score.b));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn set_side(mut events: Query<(&mut Side, &BoardIndex), Changed<BoardIndex>>) {
|
|
|
|
|
events
|
|
|
|
|
.iter_mut()
|
|
|
|
|
|