Skip to content

Commit

Permalink
Merge pull request #15 from Nervonment/v0.3.x
Browse files Browse the repository at this point in the history
v0.3.5
  • Loading branch information
Nervonment authored Jun 21, 2024
2 parents 36e146b + 525bd15 commit 1a13ae2
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 17 deletions.
2 changes: 1 addition & 1 deletion app/start/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ export default function Start() {
/>
<ToolBoxItem icon={<Undo />} desc={"撤销(Z)"} onClick={handleUndo} />
<ToolBoxItem icon={<Redo />} desc={"重做(X)"} onClick={handleRedo} />
<ToolBoxItem icon={<RefreshCcw />} desc={"换一道题"} onClick={newPuzzle} />
<ToolBoxItem icon={<RefreshCcw />} desc={"换一道题"} onClick={() => { if (grid) newPuzzle(); }} />
<ToolBoxItem icon={<Trash2 />} desc={"清空"} onClick={clear} />
<ToolBoxItem icon={<Undo2 />} desc={"返回首页"} onClick={() => router.replace("/")} />
</div>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sudoxide",
"version": "0.3.4",
"version": "0.3.5",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
16 changes: 13 additions & 3 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 51 additions & 6 deletions src-tauri/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use serde::Serialize;
use sudoku::state::full_state::FullState;
use sudoku::techniques::{DirectOption, House, ReducingCandidatesOption, Technique};

pub mod fish;
pub mod hidden_subsets;
pub mod locked_candidates;
pub mod naked_subsets;
Expand Down Expand Up @@ -35,19 +36,19 @@ pub trait GetHint: Technique<FullState> {
fn get_hint(&self) -> Option<Hint>;
}

#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub struct Segment {
pub text: String,
pub color: Color,
}

#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub struct Element {
pub kind: ElementType,
pub color: Color,
}

#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub enum Color {
TextDefault,
House1,
Expand All @@ -58,7 +59,7 @@ pub enum Color {
CandidateToRemove,
}

#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub enum ElementType {
#[serde(with = "HouseDef")]
House(House),
Expand Down Expand Up @@ -92,6 +93,51 @@ pub trait To<T> {
fn candidate_to_reserve(&self) -> T;
}

impl To<Segment> for &str {
fn text_default(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::TextDefault,
}
}
fn house1(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::House1,
}
}
fn house2(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::House2,
}
}
fn cell1(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::Cell1,
}
}
fn num_to_fill(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::NumToFill,
}
}
fn candidate_to_remove(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::CandidateToRemove,
}
}
fn candidate_to_reserve(&self) -> Segment {
Segment {
text: (*self).to_owned(),
color: Color::CandidateToReserve,
}
}
}

impl To<Segment> for String {
fn text_default(&self) -> Segment {
Segment {
Expand Down Expand Up @@ -227,7 +273,6 @@ impl To<Element> for (usize, usize) {
}
}


impl To<Element> for (usize, usize, i8) {
fn text_default(&self) -> Element {
Element {
Expand Down Expand Up @@ -271,4 +316,4 @@ impl To<Element> for (usize, usize, i8) {
color: Color::CandidateToReserve,
}
}
}
}
118 changes: 118 additions & 0 deletions src-tauri/src/hint/fish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use sudoku::{
state::full_state::FullState,
techniques::{
fish::{FishInfo, Jellyfish, Swordfish, XWing},
ReducingCandidates, ReducingCandidatesOption, Technique,
},
};

use super::{house_to_string, GetHint, Hint, HintOption, To};

fn fish_info_to_hint(info: FishInfo, option: ReducingCandidatesOption) -> Hint {
Hint {
name: match info.size {
2 => "X-Wing",
3 => "Swordfish",
4 => "Jellyfish",
_ => "Fish",
}
.into(),
description: vec![
"在".text_default(),
info.base_set
.iter()
.map(|house| house_to_string(*house))
.collect::<Vec<_>>()
.join(" ")
.house1(),
"中,所有可以填".text_default(),
info.candidate.to_string().candidate_to_reserve(),
"的格子都在".text_default(),
"它们".house1(),
"与".text_default(),
info.cover_set
.iter()
.map(|house| house_to_string(*house))
.collect::<Vec<_>>()
.join(" ")
.house2(),
"的".text_default(),
"交叉区域".cell1(),
"中。无论".text_default(),
info.candidate.to_string().candidate_to_reserve(),
"在".text_default(),
"交叉区域".cell1(),
"中如何排列,".text_default(),
info.cover_set
.iter()
.map(|house| house_to_string(*house))
.collect::<Vec<_>>()
.join(" ")
.house2(),
"中的".text_default(),
info.candidate.to_string().candidate_to_reserve(),
"都只能填在".text_default(),
"交叉区域".cell1(),
"中,进而可以从其他格子的候选数中移除".text_default(),
info.candidate.to_string().candidate_to_remove(),
"。".text_default(),
],
visual_elements: vec![
info.base_set
.iter()
.map(|house| house.house1())
.collect::<Vec<_>>(),
info.cover_set
.iter()
.map(|house| house.house2())
.collect::<Vec<_>>(),
info.overlap
.iter()
.map(|cell| cell.cell1())
.collect::<Vec<_>>(),
info.overlap
.iter()
.map(|(r, c)| (*r, *c, info.candidate).candidate_to_reserve())
.collect::<Vec<_>>(),
info.rem_cells
.iter()
.map(|(r, c)| (*r, *c, info.candidate).candidate_to_remove())
.collect::<Vec<_>>(),
]
.concat(),
option: HintOption::ReducingCandidates(option),
}
}

impl GetHint for XWing {
fn get_hint(&self) -> Option<super::Hint> {
if <Self as Technique<FullState>>::appliable(&self) {
let info = self.0.clone().unwrap();
let option = <Self as ReducingCandidates<FullState>>::option(&self).unwrap();
return Some(fish_info_to_hint(info, option));
}
None
}
}

impl GetHint for Swordfish {
fn get_hint(&self) -> Option<super::Hint> {
if <Self as Technique<FullState>>::appliable(&self) {
let info = self.0.clone().unwrap();
let option = <Self as ReducingCandidates<FullState>>::option(&self).unwrap();
return Some(fish_info_to_hint(info, option));
}
None
}
}

impl GetHint for Jellyfish {
fn get_hint(&self) -> Option<super::Hint> {
if <Self as Technique<FullState>>::appliable(&self) {
let info = self.0.clone().unwrap();
let option = <Self as ReducingCandidates<FullState>>::option(&self).unwrap();
return Some(fish_info_to_hint(info, option));
}
None
}
}
10 changes: 5 additions & 5 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ use sudoku::{
solver::{advanced::AdvancedSolver, Solver},
state::full_state::FullState,
techniques::{
hidden_subsets::HiddenPair,
locked_candidates::{Claiming, Pointing},
naked_subsets::{NakedPair, NakedSubset},
singles::{HiddenSingle, NakedSingle},
fish::{Jellyfish, Swordfish, XWing}, hidden_subsets::HiddenPair, locked_candidates::{Claiming, Pointing}, naked_subsets::{NakedPair, NakedSubset}, singles::{HiddenSingle, NakedSingle}
},
Grid,
};
Expand Down Expand Up @@ -98,14 +95,17 @@ fn get_hint(grid: [[i8; 9]; 9], candidates: [[[bool; 10]; 9]; 9]) -> (Option<Hin
return (None, GetHintResult::WrongMark);
}

let techniques: [&mut dyn GetHint; 7] = [
let techniques: [&mut dyn GetHint; 10] = [
&mut NakedSingle::default(),
&mut HiddenSingle::default(),
&mut Pointing::default(),
&mut Claiming::default(),
&mut NakedPair::default(),
&mut XWing::default(),
&mut HiddenPair::default(),
&mut NakedSubset::default(),
&mut Swordfish::default(),
&mut Jellyfish::default(),
];

for technique in techniques {
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "Sudoxide",
"version": "0.3.4"
"version": "0.3.5"
},
"tauri": {
"allowlist": {
Expand Down

0 comments on commit 1a13ae2

Please sign in to comment.