def setUp(self): self.group1 = PartialGroup() self.group2 = PartialGroup('3bk') self.group3 = PartialGroup(['3bk', '3bl'])
def findPlays(rack, existing_sets = None, required_tiles = None): if existing_sets == None: existing_sets = [] current_best_sets = existing_sets current_best_remaining = rack[:] if required_tiles == None or required_tiles == []: tiles_satisfied = True else: tiles_satisfied = False for tile in rack: remaining_tiles = rack[:] remaining_tiles.remove(tile) if required_tiles != None: remaining_required = required_tiles[:] if tile in remaining_required: remaining_required.remove(tile) else: remaining_required = None ## try adding to existing sets for tileSet in existing_sets: if tile in tileSet.validAdds(): produced_sets, produced_remaining_tiles = findPlays(remaining_tiles, create_new_set(existing_sets, tileSet, tile), remaining_required) if produced_sets != None: #used all required tiles if len(produced_remaining_tiles) == 0: return produced_sets, produced_remaining_tiles elif len(produced_remaining_tiles) < len(current_best_remaining): current_best_sets = produced_sets current_best_remaining = produced_remaining_tiles tiles_satisfied = True ## we have found a solution that does satisfy ## try creating a new run putative_run = PartialRun(tile) for pair in try_set(remaining_tiles, putative_run): test_run = putative_run.clone() test_run.addTile(pair[0]) test_run.addTile(pair[1]) test_tiles = remaining_tiles[:] test_tiles.remove(pair[0]) test_tiles.remove(pair[1]) test_sets = existing_sets[:] test_sets.append(test_run) if remaining_required != None: test_required = remaining_required[:] if pair[0] in test_required: test_required.remove(pair[0]) if pair[1] in test_required: test_required.remove(pair[1]) else: test_required = None produced_sets, produced_remaining_tiles = findPlays(test_tiles, test_sets, test_required) if produced_sets != None: # we found a valid solution if len(produced_remaining_tiles) == 0: return produced_sets, produced_remaining_tiles elif len(produced_remaining_tiles) < len(current_best_remaining): current_best_sets = produced_sets current_best_remaining = produced_remaining_tiles tiles_satisfied = True ## we have found a solution that does satisfy ## try creating a new group putative_group = PartialGroup(tile) for pair in try_set(remaining_tiles, putative_group): test_group = putative_group.clone() test_group.addTile(pair[0]) test_group.addTile(pair[1]) test_tiles = remaining_tiles[:] test_tiles.remove(pair[0]) test_tiles.remove(pair[1]) test_sets = existing_sets[:] test_sets.append(test_group) if remaining_required != None: test_required = remaining_required[:] if pair[0] in test_required: test_required.remove(pair[0]) if pair[1] in test_required: test_required.remove(pair[1]) else: test_required = None produced_sets, produced_remaining_tiles = findPlays(test_tiles, test_sets, test_required) if produced_sets != None: ## we used all required tiles if len(produced_remaining_tiles) == 0: return produced_sets, produced_remaining_tiles elif len(produced_remaining_tiles) < len(current_best_remaining): current_best_sets = produced_sets current_best_remaining = produced_remaining_tiles tiles_satisfied = True ## we have found a solution that does satisfy if tiles_satisfied: return current_best_sets, current_best_remaining else: ## this was not a successful path return None, None
class TestPartialGroup(TestCase): def setUp(self): self.group1 = PartialGroup() self.group2 = PartialGroup('3bk') self.group3 = PartialGroup(['3bk', '3bl']) def test_addTile(self): self.group1.addTile('4yw') self.assertEqual(len(self.group1), 1) self.group3.addTile('3yw') self.assertEqual(len(self.group3), 3) def test_addTile_bad(self): with self.assertRaises(ValueError): self.group2.addTile('4yw') with self.assertRaises(ValueError): self.group2.addTile('3bk') def test_validAdds(self): self.assertEqual(self.group1.validAdds(), None) self.assertEqual(self.group2.validAdds(), ['3bl', '3rd', '3yw']) self.assertEqual(self.group3.validAdds(), ['3rd', '3yw'])