ipuz export

This commit is contained in:
2025-06-20 10:42:30 +03:00
parent 5af6fb764e
commit 10125139a9
2 changed files with 78 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
use serde_json::{json, Value};
use crate::grid::Cell;
use crate::puzzle::Puzzle;
/// Serialize a puzzle to ipuz JSON format.
/// Spec: http://www.ipuz.org/
pub fn to_ipuz(puzzle: &Puzzle, title: &str) -> Value {
let mut puzzle_grid = Vec::new();
let mut solution_grid = Vec::new();
// build cell number map
let mut cell_numbers = std::collections::HashMap::new();
for word in &puzzle.words {
cell_numbers.entry((word.row, word.col)).or_insert(word.clue_number);
}
for r in 0..puzzle.height {
let mut puzzle_row = Vec::new();
let mut solution_row = Vec::new();
for c in 0..puzzle.width {
match puzzle.grid.get(r, c) {
Cell::Black => {
puzzle_row.push(json!("#"));
solution_row.push(json!("#"));
}
Cell::Letter(ch) => {
let num = cell_numbers.get(&(r, c));
if let Some(&n) = num {
puzzle_row.push(json!(n));
} else {
puzzle_row.push(json!(0));
}
solution_row.push(json!(ch.to_string()));
}
Cell::Empty => {
let num = cell_numbers.get(&(r, c));
if let Some(&n) = num {
puzzle_row.push(json!(n));
} else {
puzzle_row.push(json!(0));
}
solution_row.push(json!(null));
}
}
}
puzzle_grid.push(puzzle_row);
solution_grid.push(solution_row);
}
let across_clues: Vec<Value> = puzzle.clues_across.iter().map(|c| {
json!([c.number, c.text])
}).collect();
let down_clues: Vec<Value> = puzzle.clues_down.iter().map(|c| {
json!([c.number, c.text])
}).collect();
json!({
"version": "http://ipuz.org/v2",
"kind": ["http://ipuz.org/crossword#1"],
"title": title,
"dimensions": {
"width": puzzle.width,
"height": puzzle.height,
},
"puzzle": puzzle_grid,
"solution": solution_grid,
"clues": {
"Across": across_clues,
"Down": down_clues,
},
"difficulty": puzzle.difficulty_score,
})
}
+3
View File
@@ -0,0 +1,3 @@
pub mod puz;
pub mod ipuz;
pub mod pdf;