github.com/joshprzybyszewski/masyu@v0.0.0-20230508015604-f31a025f6e7e/solve/rule_default_test.go (about) 1 package solve 2 3 import ( 4 "testing" 5 6 "github.com/joshprzybyszewski/masyu/model" 7 "github.com/stretchr/testify/assert" 8 ) 9 10 func TestRuleDefault(t *testing.T) { 11 12 const ( 13 right uint8 = 1 << iota 14 down 15 left 16 up 17 18 none uint8 = 0 19 all = right | down | left | up 20 ) 21 22 testCases := []struct { 23 name string 24 startLines uint8 25 startAvoids uint8 26 expInvalid bool 27 expLines uint8 28 expAvoids uint8 29 }{{ 30 name: `none set`, 31 }, { 32 name: `one line: right`, 33 startLines: right, 34 expLines: right, 35 }, { 36 name: `one line: down`, 37 startLines: down, 38 expLines: down, 39 }, { 40 name: `one line: left`, 41 startLines: left, 42 expLines: left, 43 }, { 44 name: `one line: up`, 45 startLines: up, 46 expLines: up, 47 }, { 48 name: `one avoid: right`, 49 startAvoids: right, 50 expAvoids: right, 51 }, { 52 name: `one avoid: down`, 53 startAvoids: down, 54 expAvoids: down, 55 }, { 56 name: `one avoid: left`, 57 startAvoids: left, 58 expAvoids: left, 59 }, { 60 name: `one avoid: up`, 61 startAvoids: up, 62 expAvoids: up, 63 }, { 64 name: `one lines and one avoid: right & down`, 65 startLines: right, 66 startAvoids: down, 67 expLines: right, 68 expAvoids: down, 69 }, { 70 name: `one lines and one avoid: right & left`, 71 startLines: right, 72 startAvoids: left, 73 expLines: right, 74 expAvoids: left, 75 }, { 76 name: `one lines and one avoid: right & up`, 77 startLines: right, 78 startAvoids: up, 79 expLines: right, 80 expAvoids: up, 81 }, { 82 name: `one lines and one avoid: down & left`, 83 startLines: down, 84 startAvoids: left, 85 expLines: down, 86 expAvoids: left, 87 }, { 88 name: `one lines and one avoid: down & up`, 89 startLines: down, 90 startAvoids: up, 91 expLines: down, 92 expAvoids: up, 93 }, { 94 name: `one lines and one avoid: left & up`, 95 startLines: left, 96 startAvoids: up, 97 expLines: left, 98 expAvoids: up, 99 }, { 100 name: `two lines: right & down`, 101 startLines: right | down, 102 expLines: right | down, 103 expAvoids: left | up, 104 }, { 105 name: `two lines: right & left`, 106 startLines: right | left, 107 expLines: right | left, 108 expAvoids: down | up, 109 }, { 110 name: `two lines: right & up`, 111 startLines: right | up, 112 expLines: right | up, 113 expAvoids: down | left, 114 }, { 115 name: `two lines: down & left`, 116 startLines: down | left, 117 expLines: down | left, 118 expAvoids: up | right, 119 }, { 120 name: `two lines: down & up`, 121 startLines: down | up, 122 expLines: down | up, 123 expAvoids: left | right, 124 }, { 125 name: `two lines: left & up`, 126 startLines: left | up, 127 expLines: left | up, 128 expAvoids: down | right, 129 }, { 130 name: `two Avoids: right & down`, 131 startAvoids: right | down, 132 expAvoids: right | down, 133 }, { 134 name: `two Avoids: right & left`, 135 startAvoids: right | left, 136 expAvoids: right | left, 137 }, { 138 name: `two Avoids: right & up`, 139 startAvoids: right | up, 140 expAvoids: right | up, 141 }, { 142 name: `two Avoids: down & left`, 143 startAvoids: down | left, 144 expAvoids: down | left, 145 }, { 146 name: `two Avoids: down & up`, 147 startAvoids: down | up, 148 expAvoids: down | up, 149 }, { 150 name: `two Avoids: left & up`, 151 startAvoids: left | up, 152 expAvoids: left | up, 153 }, { 154 name: `one line and two Avoids: left vs. right & down`, 155 startLines: left, 156 startAvoids: right | down, 157 expLines: left | up, 158 expAvoids: right | down, 159 }, { 160 name: `one line and two Avoids: up vs. right & down`, 161 startLines: up, 162 startAvoids: right | down, 163 expLines: left | up, 164 expAvoids: right | down, 165 }, { 166 name: `one line and two Avoids: down vs. right & left`, 167 startLines: down, 168 startAvoids: right | left, 169 expLines: up | down, 170 expAvoids: right | left, 171 }, { 172 name: `one line and two Avoids: up vs. right & left`, 173 startLines: up, 174 startAvoids: right | left, 175 expLines: up | down, 176 expAvoids: right | left, 177 }, { 178 name: `one line and two Avoids: left vs. right & up`, 179 startLines: left, 180 startAvoids: right | up, 181 expLines: left | down, 182 expAvoids: right | up, 183 }, { 184 name: `one line and two Avoids: down vs. right & up`, 185 startLines: down, 186 startAvoids: right | up, 187 expLines: left | down, 188 expAvoids: right | up, 189 }, { 190 name: `one line and two Avoids: right vs. down & left`, 191 startLines: right, 192 startAvoids: down | left, 193 expLines: up | right, 194 expAvoids: down | left, 195 }, { 196 name: `one line and two Avoids: up vs. down & left`, 197 startLines: up, 198 startAvoids: down | left, 199 expLines: up | right, 200 expAvoids: down | left, 201 }, { 202 name: `one line and two Avoids: left vs. down & up`, 203 startLines: left, 204 startAvoids: down | up, 205 expLines: left | right, 206 expAvoids: down | up, 207 }, { 208 name: `one line and two Avoids: right vs. down & up`, 209 startLines: right, 210 startAvoids: down | up, 211 expLines: left | right, 212 expAvoids: down | up, 213 }, { 214 name: `one line and two Avoids: right vs. left & up`, 215 startLines: right, 216 startAvoids: left | up, 217 expLines: down | right, 218 expAvoids: left | up, 219 }, { 220 name: `one line and two Avoids: down vs. left & up`, 221 startLines: down, 222 startAvoids: left | up, 223 expLines: down | right, 224 expAvoids: left | up, 225 }, { 226 name: `one avoid and two lines: left vs. right & down`, 227 startAvoids: left, 228 startLines: right | down, 229 expLines: right | down, 230 expAvoids: left | up, 231 }, { 232 name: `one avoid and two lines: up vs. right & down`, 233 startAvoids: up, 234 startLines: right | down, 235 expLines: right | down, 236 expAvoids: left | up, 237 }, { 238 name: `one avoid and two lines: down vs. right & left`, 239 startAvoids: down, 240 startLines: right | left, 241 expLines: right | left, 242 expAvoids: up | down, 243 }, { 244 name: `one avoid and two lines: up vs. right & left`, 245 startAvoids: up, 246 startLines: right | left, 247 expLines: right | left, 248 expAvoids: up | down, 249 }, { 250 name: `one avoid and two lines: left vs. right & up`, 251 startAvoids: left, 252 startLines: right | up, 253 expLines: right | up, 254 expAvoids: left | down, 255 }, { 256 name: `one avoid and two lines: down vs. right & up`, 257 startAvoids: down, 258 startLines: right | up, 259 expLines: right | up, 260 expAvoids: left | down, 261 }, { 262 name: `one avoid and two lines: right vs. down & left`, 263 startAvoids: right, 264 startLines: down | left, 265 expLines: down | left, 266 expAvoids: up | right, 267 }, { 268 name: `one avoid and two lines: up vs. down & left`, 269 startAvoids: up, 270 startLines: down | left, 271 expLines: down | left, 272 expAvoids: up | right, 273 }, { 274 name: `one avoid and two lines: left vs. down & up`, 275 startAvoids: left, 276 startLines: down | up, 277 expLines: down | up, 278 expAvoids: left | right, 279 }, { 280 name: `one avoid and two lines: right vs. down & up`, 281 startAvoids: right, 282 startLines: down | up, 283 expLines: down | up, 284 expAvoids: left | right, 285 }, { 286 name: `one avoid and two lines: right vs. left & up`, 287 startAvoids: right, 288 startLines: left | up, 289 expLines: left | up, 290 expAvoids: down | right, 291 }, { 292 name: `one avoid and two lines: down vs. left & up`, 293 startAvoids: down, 294 startLines: left | up, 295 expLines: left | up, 296 expAvoids: down | right, 297 }, { 298 name: `three lines: RDL`, 299 startLines: right | down | left, 300 expInvalid: true, 301 }, { 302 name: `three lines: RDU`, 303 startLines: right | down | up, 304 expInvalid: true, 305 }, { 306 name: `three lines: RLU`, 307 startLines: right | left | up, 308 expInvalid: true, 309 }, { 310 name: `three lines: DLU`, 311 startLines: down | left | up, 312 expInvalid: true, 313 }, { 314 name: `three Avoids: RDL`, 315 startAvoids: right | down | left, 316 expAvoids: all, 317 }, { 318 name: `three Avoids: RDU`, 319 startAvoids: right | down | up, 320 expAvoids: all, 321 }, { 322 name: `three Avoids: RLU`, 323 startAvoids: right | left | up, 324 expAvoids: all, 325 }, { 326 name: `three Avoids: DLU`, 327 startAvoids: down | left | up, 328 expAvoids: all, 329 }, { 330 name: `four lines: RDLU`, 331 startLines: all, 332 expInvalid: true, 333 }, { 334 name: `four avoid: RDLU`, 335 startAvoids: all, 336 expAvoids: all, 337 }} 338 339 for _, tc := range testCases { 340 tc := tc 341 t.Run(tc.name, func(t *testing.T) { 342 s := newState( 343 6, 344 nil, 345 ) 346 c := model.Coord{ 347 Row: 3, 348 Col: 3, 349 } 350 351 if tc.startLines&right == right { 352 s.lineHor(c.Row, c.Col) 353 } 354 if tc.startAvoids&right == right { 355 s.avoidHor(c.Row, c.Col) 356 } 357 358 if tc.startLines&down == down { 359 s.lineVer(c.Row, c.Col) 360 } 361 if tc.startAvoids&down == down { 362 s.avoidVer(c.Row, c.Col) 363 } 364 365 if tc.startLines&left == left { 366 s.lineHor(c.Row, c.Col-1) 367 } 368 if tc.startAvoids&left == left { 369 s.avoidHor(c.Row, c.Col-1) 370 } 371 372 if tc.startLines&up == up { 373 s.lineVer(c.Row-1, c.Col) 374 } 375 if tc.startAvoids&up == up { 376 s.avoidVer(c.Row-1, c.Col) 377 } 378 379 assert.Equal(t, tc.startLines|tc.startAvoids != 0, s.rules.hasPending) 380 381 ss := settle(&s) 382 383 if tc.expInvalid { 384 assert.Equal(t, invalid, ss) 385 return 386 } 387 assert.False(t, s.rules.hasPending) 388 assert.Equal(t, validUnsolved, ss) 389 390 l, a := s.horAt(c.Row, c.Col) 391 assert.Equal(t, tc.expLines&right == right, l, `right should be a Line`) 392 assert.Equal(t, tc.expAvoids&right == right, a, `right should be an Avoid`) 393 394 l, a = s.verAt(c.Row, c.Col) 395 assert.Equal(t, tc.expLines&down == down, l, `down should be a Line`) 396 assert.Equal(t, tc.expAvoids&down == down, a, `down should be an Avoid`) 397 398 l, a = s.horAt(c.Row, c.Col-1) 399 assert.Equal(t, tc.expLines&left == left, l, `left should be a Line`) 400 assert.Equal(t, tc.expAvoids&left == left, a, `left should be an Avoid`) 401 402 l, a = s.verAt(c.Row-1, c.Col) 403 assert.Equal(t, tc.expLines&up == up, l, `up should be a Line`) 404 assert.Equal(t, tc.expAvoids&up == up, a, `up should be an Avoid`) 405 }) 406 } 407 }