Skip to content

Commit

Permalink
fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
foxzool committed Dec 13, 2024
1 parent b309ea8 commit 73f2882
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 43 deletions.
78 changes: 38 additions & 40 deletions src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy::color::palettes::basic::{BLACK, GRAY};
use bevy::input::keyboard::KeyboardInput;
use bevy::input::ButtonState;
use bevy::prelude::*;
use std::ops::{BitAnd, BitAndAssign, BitOrAssign};
use std::ops::BitOrAssign;
use sudoku::bitset::Set;
use sudoku::board::{CellState, Digit};
use sudoku::strategy::StrategySolver;
Expand Down Expand Up @@ -133,7 +133,7 @@ fn spawn_board(mut commands: Commands, asset_server: Res<AssetServer>) {
)).with_children(|builder| {
// 格子
builder.spawn((
CellPosition::new(cell),
CellPosition::from_block_row_col(block_index, bi),
Node {
align_items: AlignItems::Center,
justify_items: JustifyItems::Center,
Expand Down Expand Up @@ -302,11 +302,11 @@ fn init_cells(mut commands: Commands, cell_background: Query<(Entity, &CellPosit
});

'l: for (index, cell_state) in solver.grid_state().into_iter().enumerate() {
let cell_value = CellValue(cell_state);
let cell_value = CellValue::new(cell_state);

for (entity, cell_position) in cell_background.iter() {
if cell_position.0 == index as u8 {
match &cell_value.0 {
match &cell_value.current() {
// 如果一开始就是数字,那么这个格子是固定颜色
CellState::Digit(_) => {
commands
Expand Down Expand Up @@ -374,10 +374,10 @@ fn update_cell(
if let Ok((mut visibility, _children)) = candidates_container.get_mut(*child) {
*visibility = Visibility::Hidden;
}
match cell_value.0 {
match cell_value.current() {
CellState::Digit(digit) => {
if let Ok((mut text, mut visibility)) = digit_cell.get_mut(*child) {
info!("cell {} changed value {}", cell_position, digit.get());
info!("cell {} changed to digit {}", cell_position, digit.get());
text.0 = digit.get().to_string();
*visibility = Visibility::Visible;
commands.trigger(CheckSolver);
Expand All @@ -393,7 +393,7 @@ fn update_cell(
}

info!(
"cell {} changed value {:?}",
"cell {} changed to candidates {:?}",
cell_position,
candidates.into_iter().collect::<Vec<_>>()
);
Expand Down Expand Up @@ -435,9 +435,12 @@ fn on_click_cell(

fn set_keyboard_input(
mut keyboard_input_events: EventReader<KeyboardInput>,
mut selected_cell: Single<(&mut CellValue, Option<&FixedCell>), With<SelectedCell>>,
mut selected_cell: Single<
(&mut CellValue, Option<&FixedCell>, &CellPosition),
With<SelectedCell>,
>,
) {
let (mut selected_cell, opt_fixed) = selected_cell.into_inner();
let (mut selected_cell, opt_fixed, cell_position) = selected_cell.into_inner();
if opt_fixed.is_some() {
return;
}
Expand All @@ -448,37 +451,39 @@ fn set_keyboard_input(

match event.key_code {
KeyCode::Digit0 | KeyCode::Numpad0 => {
selected_cell.0 = CellState::Digit(Digit::new(0));
selected_cell.set(CellState::Digit(Digit::new(0)));
}
KeyCode::Digit1 | KeyCode::Numpad1 => {
selected_cell.0 = CellState::Digit(Digit::new(1));
selected_cell.set(CellState::Digit(Digit::new(1)));
}
KeyCode::Digit2 | KeyCode::Numpad2 => {
selected_cell.0 = CellState::Digit(Digit::new(2));
selected_cell.set(CellState::Digit(Digit::new(2)));
}
KeyCode::Digit3 | KeyCode::Numpad3 => {
selected_cell.0 = CellState::Digit(Digit::new(3));
selected_cell.set(CellState::Digit(Digit::new(3)));
}
KeyCode::Digit4 | KeyCode::Numpad4 => {
selected_cell.0 = CellState::Digit(Digit::new(4));
selected_cell.set(CellState::Digit(Digit::new(4)));
}
KeyCode::Digit5 | KeyCode::Numpad5 => {
selected_cell.0 = CellState::Digit(Digit::new(5));
selected_cell.set(CellState::Digit(Digit::new(5)));
}
KeyCode::Digit6 | KeyCode::Numpad6 => {
selected_cell.0 = CellState::Digit(Digit::new(6));
selected_cell.set(CellState::Digit(Digit::new(6)));
}
KeyCode::Digit7 | KeyCode::Numpad7 => {
selected_cell.0 = CellState::Digit(Digit::new(7));
selected_cell.set(CellState::Digit(Digit::new(7)));
}
KeyCode::Digit8 | KeyCode::Numpad8 => {
selected_cell.0 = CellState::Digit(Digit::new(8));
selected_cell.set(CellState::Digit(Digit::new(8)));
}
KeyCode::Digit9 | KeyCode::Numpad9 => {
selected_cell.0 = CellState::Digit(Digit::new(9));
selected_cell.set(CellState::Digit(Digit::new(9)));
}
KeyCode::Delete => {
selected_cell.0 = CellState::Candidates(Set::NONE);
if let CellState::Digit(_) = selected_cell.current() {
selected_cell.rollback();
}
}

_ => {}
Expand Down Expand Up @@ -523,19 +528,16 @@ fn candidate_cell_click(
let mut candidate_cell = cell.get_mut(click.entity()).unwrap();
for ancestor in parent_query.iter_ancestors(click.entity()) {
if let Ok(mut cell_value) = q_select.get_mut(ancestor) {
match cell_value.0 {
CellState::Digit(_) => {}
CellState::Candidates(mut candidates) => {
if candidate_cell.selected {
candidate_cell.selected = false;
candidates.remove(Digit::new(candidate_cell.index).as_set());
} else {
candidate_cell.selected = true;
candidates.bitor_assign(Digit::new(candidate_cell.index).as_set());
}

cell_value.0 = CellState::Candidates(candidates);
if let CellState::Candidates(mut candidates) = cell_value.current() {
if candidate_cell.selected {
candidate_cell.selected = false;
candidates.remove(Digit::new(candidate_cell.index).as_set());
} else {
candidate_cell.selected = true;
candidates.bitor_assign(Digit::new(candidate_cell.index).as_set());
}

cell_value.set(CellState::Candidates(candidates));
}
}
}
Expand All @@ -554,7 +556,7 @@ fn check_solver(
.iter()
.sort_by::<&CellPosition>(|t1, t2| t1.0.cmp(&t2.0))
{
list[cell_position.0 as usize] = cell_value.0;
list[cell_position.0 as usize] = cell_value.current().clone();
}
sudoku_manager.solver = StrategySolver::from_grid_state(list);

Expand All @@ -581,13 +583,9 @@ fn kick_candidates(
|| kicker_position.col() == cell_position.col()
|| kicker_position.block() == cell_position.block()
{
match cell_value.0 {
CellState::Digit(_) => {}
CellState::Candidates(mut candidates) => {
candidates.remove(digit.as_set());

cell_value.0 = CellState::Candidates(candidates);
}
if let CellState::Candidates(mut candidates) = cell_value.current() {
candidates.remove(digit.as_set());
cell_value.set(CellState::Candidates(candidates));
}
}
}
Expand Down
37 changes: 35 additions & 2 deletions src/board/cell_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,41 @@ use bevy::prelude::*;
use sudoku::board::CellState;

/// 格子的值
#[derive(Component, Debug, Deref, DerefMut)]
pub struct CellValue(pub CellState);
#[derive(Component, Debug)]
pub struct CellValue {
current: CellState,
previous: CellState,
}

impl CellValue {
pub fn new(current: CellState) -> Self {
Self {
current,
previous: current,
}
}

pub fn set(&mut self, new: CellState) {
self.previous = self.current;
self.current = new;
}

pub fn current(&self) -> &CellState {
&self.current
}

pub fn rollback(&mut self) {
std::mem::swap(&mut self.current, &mut self.previous);
}

pub fn is_digit(&self) -> bool {
matches!(self.current, CellState::Digit(_))
}

pub fn is_candidates(&self) -> bool {
matches!(self.current, CellState::Candidates(_))
}
}

/// 固定的格子, 不能修改
#[derive(Component)]
Expand Down
29 changes: 28 additions & 1 deletion src/board/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ impl CellPosition {
CellPosition(cell)
}

pub fn from_block_row_col(block: u8, inner_box_pos: u8) -> CellPosition {
// 计算宫格的起始位置
let box_row = block / 3;
let box_col = block % 3;

// 计算宫格内部的位置
let inner_row = inner_box_pos / 3;
let inner_col = inner_box_pos % 3;

// 计算整体网格中的行和列
let row = box_row * 3 + inner_row;
let col = box_col * 3 + inner_col;

// 将行列转换成线性索引

CellPosition(row * 9 + col)
}

pub fn row(&self) -> u8 {
self.0 / 9
}
Expand All @@ -40,7 +58,7 @@ impl CellPosition {

impl Display for CellPosition {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "({}, {})", self.row(), self.col())
write!(f, "({}, {})[{}]", self.row(), self.col(), self.0)
}
}

Expand All @@ -52,3 +70,12 @@ fn test_row() {
assert_eq!(CellPosition::new(9).row(), 1);
assert_eq!(CellPosition::new(80).row(), 8);
}

#[test]
fn test_col() {
assert_eq!(CellPosition::new(0).col(), 0);
assert_eq!(CellPosition::new(4).col(), 4);
assert_eq!(CellPosition::new(8).col(), 8);
assert_eq!(CellPosition::new(9).col(), 0);
assert_eq!(CellPosition::new(80).col(), 8);
}

0 comments on commit 73f2882

Please sign in to comment.