diff --git a/src/game.rs b/src/game.rs index c75aa68..9f11fff 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,7 +1,8 @@ use crate::color::*; use crate::game::board::play_board; use crate::game::cell_state::{ - CellMode, CellValue, CellValueBundle, CellValueNew, DigitValueCell, FixedCell, ManualCandidates, + AutoCandidates, CellMode, CellValue, CellValueBundle, CellValueNew, DigitValueCell, FixedCell, + ManualCandidates, }; use crate::game::control::control_board; use crate::game::input::keyboard_input; @@ -412,14 +413,14 @@ pub struct DigitCellMarker; #[derive(Component, Debug)] pub struct AutoCandidateCellMarker { pub index: u8, - pub selected: bool + pub selected: bool, } /// 手动选择的候选数字 #[derive(Component, Debug)] pub struct ManualCandidateCellMarker { pub index: u8, - pub selected: bool + pub selected: bool, } /// 冲突红点 @@ -500,31 +501,61 @@ fn on_unselect_cell( fn on_new_digit( trigger: Trigger, - mut q_cell: Query<(&mut DigitValueCell, &mut CellMode, Option<&FixedCell>)>, + mut q_cell: Query<(&mut DigitValueCell, &mut CellMode), Without>, mut commands: Commands, ) { - if let Ok((mut cell_value, mut cell_mode, opt_fixed)) = q_cell.get_mut(trigger.entity()) { - if opt_fixed.is_none() { - *cell_mode = CellMode::Digit; - let new_digit = trigger.event().0; + if let Ok((mut cell_value, mut cell_mode)) = q_cell.get_mut(trigger.entity()) { + *cell_mode = CellMode::Digit; + let new_digit = trigger.event().0; - if let Some(old_digit) = cell_value.0 { - commands.trigger_targets(RemoveDigit(old_digit), vec![trigger.entity()]); - } - - cell_value.0 = Some(new_digit); + if let Some(old_digit) = cell_value.0 { + commands.trigger_targets(RemoveDigit(old_digit), vec![trigger.entity()]); } + + cell_value.0 = Some(new_digit); } } fn on_new_candidate( trigger: Trigger, - mut q_cell: Query<(&mut CellValue, Option<&FixedCell>)>, + mut q_cell: Query< + ( + &mut DigitValueCell, + &mut ManualCandidates, + &mut AutoCandidates, + &mut CellMode, + ), + Without, + >, auto_mode: Res, + mut commands: Commands, ) { - if let Ok((mut cell_value, opt_fixed)) = q_cell.get_mut(trigger.entity()) { - if opt_fixed.is_none() { - cell_value.insert(CellState::Candidates(trigger.event().0), **auto_mode); + if let Ok((mut digit_value, mut manual_candidates, mut auto_candidates, mut cell_mode)) = + q_cell.get_mut(trigger.entity()) + { + let new_candidate = trigger.event().0; + match cell_mode.as_ref() { + CellMode::Digit => { + if let Some(digit) = digit_value.0 { + commands.trigger_targets(RemoveDigit(digit), vec![trigger.entity()]); + } + digit_value.0 = None; + if **auto_mode { + *cell_mode = CellMode::AutoCandidates; + auto_candidates.insert(new_candidate); + } else { + *cell_mode = CellMode::ManualCandidates; + manual_candidates.insert(new_candidate); + } + } + CellMode::AutoCandidates => { + auto_candidates.insert(new_candidate); + } + CellMode::ManualCandidates => { + println!("manual_candidates: {:?} {:?}", manual_candidates.0, new_candidate); + manual_candidates.insert(new_candidate); + println!("manual_candidates: {:?}", manual_candidates.0); + } } } } @@ -583,11 +614,11 @@ fn check_solver( pub struct CleanCell; #[derive(Event)] -pub struct NewCandidate(pub Set); +pub struct NewCandidate(pub Digit); impl NewCandidate { pub fn new(digit: u8) -> NewCandidate { - NewCandidate(Digit::new(digit).as_set()) + NewCandidate(Digit::new(digit)) } } diff --git a/src/game/board.rs b/src/game/board.rs index d5d13cd..0dc9d55 100644 --- a/src/game/board.rs +++ b/src/game/board.rs @@ -330,9 +330,12 @@ fn show_manual_candidates( if manual_candidates .0 .contains(Digit::new(cell_marker.index).as_set()) - && cell_marker.selected { + cell_marker.selected = true; *text_color = TextColor(*GRAY2); + } else { + cell_marker.selected = false; + *text_color = TextColor(TRANSPARENT); } } else { *text_color = TextColor(TRANSPARENT); @@ -348,7 +351,6 @@ fn show_preview_number( mut commands: Commands, ) { for (entity, mut text_color, mut preview) in candidate_cell.iter_mut() { - if preview.hold { *text_color = TextColor(*GRAY); continue; @@ -474,10 +476,7 @@ fn manual_candidate_cell_click( candidate_cell.selected = !candidate_cell.selected; for ancestor in parent_query.iter_ancestors(click.entity()) { if let Ok(mut cell_value) = q_select.get_mut(ancestor) { - let mut old_set = cell_value.0; - old_set.bitor_assign(Digit::new(candidate_cell.index).as_set()); - - cell_value.0 = old_set; + cell_value.insert(Digit::new(candidate_cell.index)); commands.entity(click.entity()).remove::(); } @@ -494,7 +493,6 @@ fn manual_candidate_cell_move( for ancestor in parent_query.iter_ancestors(trigger.entity()) { if let Ok(_cell_value) = q_select.get(ancestor) { if let Ok(manual_marker) = cell.get(trigger.entity()) { - println!("manual candidate cell move {:?}", manual_marker); if !manual_marker.selected { commands .entity(trigger.entity()) @@ -503,5 +501,4 @@ fn manual_candidate_cell_move( } } } - } diff --git a/src/game/cell_state.rs b/src/game/cell_state.rs index 64a5d24..1e99652 100644 --- a/src/game/cell_state.rs +++ b/src/game/cell_state.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use std::ops::BitOrAssign; +use std::ops::{BitOrAssign, BitXorAssign}; use sudoku::bitset::Set; use sudoku::board::{CellState, Digit}; @@ -43,9 +43,22 @@ pub struct DigitValueCell(pub Option); #[derive(Component, Debug)] pub struct AutoCandidates(pub Set); +impl AutoCandidates { + pub fn insert(&mut self, digit: Digit) { + self.0.bitxor_assign(digit); + } +} + #[derive(Component, Debug)] pub struct ManualCandidates(pub Set); +impl ManualCandidates { + pub fn insert(&mut self, digit: Digit) { + self.0.bitxor_assign(digit); + } + +} + #[derive(Component, Debug, PartialEq, Eq)] pub enum CellMode { Digit,