class TestPartialRun(TestCase): def setUp(self): self.run1 = PartialRun() self.run2 = PartialRun('1bk') self.run3 = PartialRun('5rd') self.run4 = PartialRun('13yw') def test_add(self): self.run2.addTile('2bk') self.assertEqual(len(self.run2), 2) def test_add_bad(self): with self.assertRaises(ValueError): self.run2.addTile('3bk') with self.assertRaises(ValueError): self.run2.addTile('2yw') def test_validAdds(self): self.assertEqual(self.run1.validAdds(), None) self.assertEqual(self.run2.validAdds(), ['2bk']) self.assertEqual(self.run3.validAdds(), ['4rd', '6rd']) self.assertEqual(self.run4.validAdds(), ['12yw'])
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
def setUp(self): self.run1 = PartialRun() self.run2 = PartialRun('1bk') self.run3 = PartialRun('5rd') self.run4 = PartialRun('13yw')