@@ -15,11 +15,8 @@ enum ExtraKind {
15
15
GEXT ,
16
16
}
17
17
18
- #[ derive( Debug ) ]
19
- enum BoardKind {
20
- Blank ,
21
- Solution ,
22
- }
18
+ const FREE_SQUARE : char = '-' ;
19
+ const TAKEN_SQUARE : char = '.' ;
23
20
24
21
const EXTRAS : [ ( & str , ExtraKind ) ; 3 ] = [
25
22
( "GRBS" , ExtraKind :: GRBS ) ,
@@ -28,13 +25,13 @@ const EXTRAS: [(&str, ExtraKind); 3] = [
28
25
] ;
29
26
30
27
#[ wasm_bindgen]
31
- pub async fn read_file ( file : web_sys:: File ) -> JsValue {
28
+ pub async fn read_file ( file : web_sys:: File ) -> String {
32
29
let data = gloo_file:: futures:: read_as_bytes ( & file. into ( ) )
33
30
. await
34
31
. expect_throw ( "Error while reading the file" ) ;
35
32
return match parse_puz ( data. as_slice ( ) ) {
36
- Ok ( parsed) => JsValue :: from_str ( & parsed. to_string ( ) ) ,
37
- Err ( e) => JsValue :: from_str ( & e. to_string ( ) ) ,
33
+ Ok ( parsed) => parsed. to_string ( ) ,
34
+ Err ( e) => e. to_string ( ) ,
38
35
} ;
39
36
}
40
37
@@ -57,61 +54,55 @@ pub fn parse_puz(buffer: impl Read) -> std::io::Result<Value> {
57
54
( 0x02 , None , "unknown_bitmask" ) ,
58
55
( 0x02 , None , "scrambled_tag" ) ,
59
56
] ;
60
- let mut header_data: Vec < ( & str , String ) > = vec ! [ ] ;
61
- for ( offset, conversion, label) in header_offsets. iter ( ) {
57
+
58
+ let mut header_data: Vec < usize > = vec ! [ ] ;
59
+ for ( offset, conversion, _) in header_offsets. iter ( ) {
62
60
let mut buffer = vec ! [ 0 ; * offset] ;
63
61
reader. read_exact ( & mut buffer) ?;
64
62
if let Some ( c_type) = conversion {
65
63
match c_type {
66
- PieceKind :: Natural => header_data. push ( ( label, buffer[ 0 ] . to_string ( ) ) ) ,
67
- PieceKind :: Number => {
68
- header_data. push ( ( label, LittleEndian :: read_u16 ( & buffer) . to_string ( ) ) )
69
- }
64
+ PieceKind :: Natural => header_data. push ( buffer[ 0 ] as usize ) ,
65
+ PieceKind :: Number => header_data. push ( LittleEndian :: read_u16 ( & buffer) as usize ) ,
70
66
}
71
67
}
72
68
}
73
69
74
- let width = header_data[ 0 ]
75
- . 1
76
- . parse :: < usize > ( )
77
- . expect ( "Width was unable to be converted to a number." ) ;
78
- let height = header_data[ 1 ]
79
- . 1
80
- . parse :: < usize > ( )
81
- . expect ( "Height was unable to be converted to a number." ) ;
70
+ let width = header_data[ 0 ] ;
71
+ let height = header_data[ 1 ] ;
82
72
let board_size = width * height;
83
73
84
- let mut board_data : Vec < ( & BoardKind , String ) > = vec ! [ ] ;
85
- let boards = vec ! [ BoardKind :: Solution , BoardKind :: Blank ] ;
86
- for board in boards . iter ( ) {
74
+ let mut boards = Vec :: new ( ) ;
75
+ // [solution, blank]
76
+ for _ in 0 .. 2 {
87
77
let mut buffer = vec ! [ 0 ; board_size] ;
88
78
reader. read_exact ( & mut buffer) ?;
89
79
if let Ok ( s) = std:: str:: from_utf8 ( & buffer) {
90
- board_data. push ( ( board, s. to_owned ( ) ) ) ;
91
- } else {
92
- println ! ( "Board (type: {:?}) could not read from the buffer." , board) ;
80
+ boards. push (
81
+ s. chars ( )
82
+ . collect :: < Vec < char > > ( )
83
+ . chunks ( width)
84
+ . map ( |chunk| chunk. iter ( ) . collect :: < String > ( ) )
85
+ . collect :: < Vec < String > > ( ) ,
86
+ )
93
87
}
94
88
}
95
89
96
- let mut info_data : Vec < ( & str , String ) > = vec ! [ ] ;
97
- let info_items = vec ! [ "title" , "author" , "copyright" ] ;
98
- for item in info_items . iter ( ) {
99
- info_data. push ( ( item , read_string_till_nul ( & mut reader) ) ) ;
90
+ // [title, author, copyright, note]
91
+ let mut info_data = Vec :: new ( ) ;
92
+ for _ in 0 .. 3 {
93
+ info_data. push ( read_string_till_nul ( & mut reader) ) ;
100
94
}
101
95
102
- let num_clues = header_data[ 2 ]
103
- . 1
104
- . parse :: < usize > ( )
105
- . expect ( "Cannot parse number of clues as a number." ) ;
96
+ let num_clues = header_data[ 2 ] ;
106
97
let mut clue_data: Vec < String > = vec ! [ ] ;
107
98
for _ in 1 ..=num_clues {
108
99
clue_data. push ( read_string_till_nul ( & mut reader) )
109
100
}
110
101
111
- // add in the note that's at the end of the clues
112
- info_data. push ( ( "note" , read_string_till_nul ( & mut reader) ) ) ;
102
+ // add note after clues
103
+ info_data. push ( read_string_till_nul ( & mut reader) ) ;
113
104
114
- let mut extras_data: Vec < u8 > = Vec :: new ( ) ;
105
+ let mut extras_data = Vec :: new ( ) ;
115
106
reader. read_to_end ( & mut extras_data) ?;
116
107
117
108
let mut grbs = Vec :: new ( ) ;
@@ -155,64 +146,34 @@ pub fn parse_puz(buffer: impl Read) -> std::io::Result<Value> {
155
146
}
156
147
}
157
148
158
- let mut empty: Vec < String > = Vec :: new ( ) ;
159
- let mut solution: Vec < String > = Vec :: new ( ) ;
160
149
let mut clues: Vec < Vec < Vec < String > > > =
161
150
vec ! [ vec![ vec![ String :: new( ) , String :: new( ) ] ; width] ; height] ;
162
151
163
- for ( kind, data) in board_data. iter ( ) {
164
- let mut board_rows = data
165
- . chars ( )
166
- . collect :: < Vec < char > > ( )
167
- . chunks ( 15 )
168
- . map ( |chunk| chunk. iter ( ) . collect :: < String > ( ) )
169
- . collect :: < Vec < String > > ( ) ;
170
-
171
- match kind {
172
- BoardKind :: Blank => empty. append ( & mut board_rows) ,
173
- BoardKind :: Solution => solution. append ( & mut board_rows) ,
174
- }
175
- }
176
-
177
152
for ( row, cols) in clues. iter_mut ( ) . enumerate ( ) {
178
153
for ( col, clue_tuple) in cols. iter_mut ( ) . enumerate ( ) {
179
- if let Some ( current_tile) = empty[ row] . chars ( ) . nth ( col) {
180
- if current_tile != '.' {
181
- if row == 0 {
182
- clue_tuple[ 0 ] = clue_data. remove ( 0 ) ;
183
- } else {
184
- if let Some ( square) = empty[ row - 1 ] . chars ( ) . nth ( col) {
185
- if square == '.' {
186
- clue_tuple[ 0 ] = clue_data. remove ( 0 ) ;
187
- }
188
- }
189
- }
190
- if col == 0 {
191
- clue_tuple[ 1 ] = clue_data. remove ( 0 ) ;
192
- } else {
193
- if let Some ( square) = empty[ row] . chars ( ) . nth ( col - 1 ) {
194
- if square == '.' {
195
- clue_tuple[ 1 ] = clue_data. remove ( 0 ) ;
196
- }
197
- }
198
- }
199
- }
154
+ if cell_needs_across_clue ( & boards[ 1 ] , row, col) {
155
+ clue_tuple[ 0 ] = clue_data. remove ( 0 ) ;
156
+ }
157
+ if cell_needs_down_clue ( & boards[ 1 ] , row, col) {
158
+ clue_tuple[ 1 ] = clue_data. remove ( 0 ) ;
200
159
}
201
160
}
202
161
}
203
162
204
163
let puz = json ! ( {
205
164
"info" : {
206
- "title" : info_data[ 0 ] . 1 ,
207
- "author" : info_data[ 1 ] . 1 ,
165
+ "title" : info_data[ 0 ] ,
166
+ "author" : info_data[ 1 ] ,
167
+ "copyright" : info_data[ 2 ] ,
168
+ "note" : info_data[ 3 ] ,
208
169
} ,
209
170
"size" : {
210
171
"width" : width,
211
172
"height" : height,
212
173
} ,
213
174
"boards" : {
214
- "blank" : empty ,
215
- "solution" : solution ,
175
+ "blank" : boards [ 1 ] ,
176
+ "solution" : boards [ 0 ] ,
216
177
} ,
217
178
"clues" : clues,
218
179
"extras" : {
@@ -225,6 +186,42 @@ pub fn parse_puz(buffer: impl Read) -> std::io::Result<Value> {
225
186
Ok ( puz)
226
187
}
227
188
189
+ fn cell_needs_across_clue ( board : & Vec < String > , row : usize , col : usize ) -> bool {
190
+ if let Some ( this_square) = & board[ row] . chars ( ) . nth ( col) {
191
+ if this_square == & FREE_SQUARE {
192
+ if let Some ( next_square) = & board[ row] . chars ( ) . nth ( col + 1 ) {
193
+ if next_square == & FREE_SQUARE {
194
+ if col == 0 {
195
+ return true ;
196
+ } else if let Some ( previous_square) = & board[ row] . chars ( ) . nth ( col - 1 ) {
197
+ return previous_square == & TAKEN_SQUARE ;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ false
204
+ }
205
+
206
+ fn cell_needs_down_clue ( board : & Vec < String > , row : usize , col : usize ) -> bool {
207
+ if let Some ( this_square) = & board[ row] . chars ( ) . nth ( col) {
208
+ if this_square == & FREE_SQUARE {
209
+ if let Some ( next_row) = board. get ( row + 1 ) {
210
+ if let Some ( next_square) = & next_row. chars ( ) . nth ( col) {
211
+ if next_square == & FREE_SQUARE {
212
+ if row == 0 {
213
+ return true ;
214
+ } else if let Some ( previous_square) = & board[ row - 1 ] . chars ( ) . nth ( col) {
215
+ return previous_square == & TAKEN_SQUARE ;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ false
223
+ }
224
+
228
225
fn read_string_till_nul ( reader : & mut BufReader < impl Read > ) -> String {
229
226
let mut text = String :: new ( ) ;
230
227
loop {
0 commit comments