def apply_strategy(self, values, constraints): """ Applies the simple spaces strategy. :param values: The array of values. :param constraints: the constraints put on the values. :return: The new values after the application of the algorithm. """ scores = Board.get_score(values) new_vals = list(values) if Utilities.all_blocks_present( values, constraints): # only apply when all blocks are present taken_spots = [v != Board.Unknown for v in values ] # array to keep track of which spots are taken diffs = [c - s for s, c in zip(scores, constraints) ] # array to see how far each score still has to go score_positions = Utilities.get_positions_of_scores(values) for diff, (s_s, s_e) in zip(diffs, score_positions): for p in range(max(0, s_s - diff), min(len(values), s_e + 1 + diff)): taken_spots[ p] = True # set each possible spot where a cross could go to True for idx, t in enumerate(taken_spots): # calculate the result if not t: new_vals[idx] = Board.Empty return new_vals
def all_blocks_present(values, constraints): """ Check if we definitely know that all the separate blocks are there already. :param values: The array of values. :param constraints: The constraints put on the array of values. :return: True if all the blocks of scores are present, False if not or if we cannot know. """ scores = Board.get_score(values) if scores == constraints: # simplest case where the scores are all done already return True if len(scores) == len(constraints): return not Utilities._blocks_may_join(values, scores, constraints) return False
def test_get_score(self): self.assertListEqual(Board.get_score([]), []) self.assertListEqual(Board.get_score([Board.Unknown]), []) self.assertListEqual(Board.get_score([Board.Empty]), []) self.assertListEqual(Board.get_score([Board.Cross]), [1]) self.assertListEqual( Board.get_score([ Board.Cross, Board.Empty, Board.Cross, Board.Cross, Board.Unknown ]), [1, 2]) self.assertListEqual( Board.get_score( [Board.Cross, Board.Cross, Board.Cross, Board.Cross]), [4])