class XYZWingStrategy implements Strategy { static getTests() { [ /* * XYZ-wing with pivot (5,3) [168] and pincers (4,3) [16] and (5,9) [18] * X = 1 * Y = 6 * Z = 8 * 1 should be eliminated from (5,2) */ new Test('159763284360018975807005136' + '970850342500040790200070560' + '485137629603580417700604853', { ! it.getCell(5, 2).hasMark(1) } ), new Test('.8.....6.1..64....7...13..8.7.9..8..96.....37..4..1.5.5..46...3....59..6.4.....9.'), new Test('.93..7.4.....6.5..5.19...3.21.......7...8...9.......64.3...96.7..7.1.....4.3..92.') ] } boolean play(Board board) { def madePlay = false for (pivot in board.cells.findAll { it.markCount == 3 }) { for (pincer1 in pivot.houses.flatten().unique().findAll { it.markCount == 2 && it.marks.every { it in pivot.marks } }) { for (pincer2 in pivot.houses.findAll { ! (pincer1 in it) }.flatten().unique().findAll { it.markCount == 2 && it.marks.every { it in pivot.marks } && (it.marks + pincer1.marks).unique().size() == 3 && ! (it in pincer1.houses.flatten()) }) { def x = pivot.marks.intersect(pincer1.marks.intersect(pincer2.marks)).first() pivot.houses.flatten().unique().intersect( pincer1.houses.flatten().intersect( pincer2.houses.flatten() ) ).findAll { it != pivot && it != pincer1 && it != pincer2 }.each { madePlay = it.removeMark(x, this) || madePlay } if (madePlay) { return true } } } } false } }