diff --git a/farm/Field_Representation.py b/farm/Field_Representation.py index 791305f..eb8494f 100644 --- a/farm/Field_Representation.py +++ b/farm/Field_Representation.py @@ -20,6 +20,7 @@ ARROW_RIGHT = 10 ROCK_1 = 11 ROCK_2 = 12 ROCK_3 = 13 +MAGINENT = 21 class Field: data_value_grid = [] @@ -32,10 +33,19 @@ class Field: explosives.append(ARROW_DOWN) explosives.append(BIGBOMB) explosives.append(BOMB) + colors = [] + colors.append(GREEN) + colors.append(YELLOW) + colors.append(BLUE) + colors.append(RED) + colors.append(PINK) + colors.append(MAGINENT) + def __init__(self): self.data_value_grid = np.zeros((8, 14), dtype=int) self.data_coordinates = np.zeros((8, 14), dtype=object) + self.observation = np.zeros((8, 14), dtype=int) # 230 to 2110 = 1883 / 14 = 134.5 # 60 to 1130 = 1076 / 8 = 134.5 @@ -64,75 +74,28 @@ class Field: ARROW_RIGHT: cv.imread("arrow_right.jpg", cv.IMREAD_COLOR), ROCK_1: cv.imread("rock1.jpg", cv.IMREAD_COLOR), ROCK_2: cv.imread("rock2.jpg", cv.IMREAD_COLOR), - ROCK_3: cv.imread("rock3.jpg", cv.IMREAD_COLOR) + ROCK_3: cv.imread("rock3.jpg", cv.IMREAD_COLOR), + MAGINENT: cv.imread("maginent.jpg", cv.IMREAD_COLOR) + } def reset(self): - self.episode_step = 0 - self.last_reward = 0 - self.last_score = 0 - self.kill_counter = 0 - # hit reset button and confirm - # self.check_for_button_and_click_it("needles/repeat.jpg") - # self.check_for_button_and_click_it("needles/reset.jpg") + self.observation = [] - self.dig_point(1800, 160, 600) - self.dig_point(1800, 1000, 300) - self.observation, screen = self.get_current_board_state() - return self.observation + def assess_playfield_and_make_move(self): - def shift_playfield(self, action): - self.episode_step += 1 - # move to indicated direction - self.action(action) - # get new field status new_observation, new_screenshot = self.get_current_board_state() - current_score = 0 - reward = 0 # wrong movement detection # last board state is same as actual if mse(new_observation, self.observation) == 0.0: - # no movement detected -> punish - if len(new_observation[new_observation == 0]) >= 1: - reward = -100 - else: - self.kill_counter = self.kill_counter + 1 - reward = -5 - else: - # calculate current board score - self.kill_counter = 0 - for e in range(0, 4, 1): - for i in range(0, 4, 1): - current_score = current_score + (2 ** new_observation[e][i] - 1) - bonus_for_empty_cells = len(new_observation[new_observation == 0]) - reward = current_score - self.last_score + bonus_for_empty_cells - self.last_score = current_score + # no movement detected -> blow explosives or reset + self.detonate_explosive_when_stuck(new_observation) + cv.waitKey(500) - if self.kill_counter >= 5: - self.kill_counter = 0 - done = True - else: - done = False + self.find_patterns_and_valid_moves(new_observation) self.observation = new_observation - return new_observation, reward, done - - def action(self, choice): - ''' - Gives us 4 total movement options. (0,1,2,3) - ''' - if choice == 0: - # right - self.move_to(1200, 598) - elif choice == 1: - # left - self.move_to(1000, 598) - elif choice == 2: - # up - self.move_to(1113, 498) - elif choice == 3: - # down - self.move_to(1113, 698) + return new_observation def move_to(self, x, y): point_src = (1113, 598) @@ -171,8 +134,8 @@ class Field: def get_current_board_state(self): try: # get an updated image of the game - #screenshot = self.capture_window.get_screenshot() - screenshot = cv.imread("field_farm.jpg") + screenshot = self.capture_window.get_screenshot() + #screenshot = cv.imread("field_farm.jpg") screenshot = screenshot[58:1134, 230:2113] # 1883,1076 # gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY) # thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1] @@ -214,7 +177,7 @@ class Field: # cv.waitKey(150) return data_coords, screenshot - def analyse_boardstate(self, state): + def find_patterns_and_valid_moves(self, state): for e in range(0, 8, 1): for i in range(0, 14, 1): if self.check_explosives(state, e, i): @@ -222,7 +185,7 @@ class Field: for e in range(0, 8, 1): for i in range(0, 14, 1): - for color in range(1, 6, 1): + for color in self.colors: if self.check_5_horizontal(state, e, i, color): return if self.check_5_vertical(state, e, i, color): @@ -230,11 +193,35 @@ class Field: for e in range(0, 8, 1): for i in range(0, 14, 1): - for color in range(1, 6, 1): + for color in self.colors: if self.check_3_horizontal(state, e, i, color): return if self.check_3_vertical(state, e, i, color): return + if self.check_3_with_gap(state, e, i, color): + return + + def detonate_explosive_when_stuck(self, state): + for e in range(0, 8, 1): + for i in range(0, 14, 1): + for explosive in self.explosives: + if self.local_pos_check(state, e, i, 0, 0, explosive): + dest_pt = self.get_click_point(self.data_coordinates[e, i]) + if self.local_pos_checks(state, e, i, 1, 0, self.colors): + src_pt = self.get_click_point(self.data_coordinates[e + 1, i]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, 0, 1, self.colors): + src_pt = self.get_click_point(self.data_coordinates[e, i + 1]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, -1, 0, self.colors): + src_pt = self.get_click_point(self.data_coordinates[e - 1, i]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, 0, -1, self.colors): + src_pt = self.get_click_point(self.data_coordinates[e, i - 1]) + self.move_tile(src_pt, dest_pt) + else: + continue + return def check_explosives(self, state, e, i): for explosive in self.explosives: @@ -316,6 +303,46 @@ class Field: except: return False + def check_3_with_gap(self, state, e, i, color): + try: + # second color next to starting point + if i + 2 <= 13: + if state[e, i] == color and state[e, i + 2] == color: + # third upper + if e - 1 >= 0 and i + 1 <= 13: + #if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5): + if state[e - 1, i + 1] == color and (state[e, i + 1] in self.colors): + src_pt = self.get_click_point(self.data_coordinates[e - 1, i + 1]) + dest_pt = self.get_click_point(self.data_coordinates[e, i + 1]) + self.move_tile(src_pt, dest_pt) + return True + # third left lower + if e + 1 <= 7 and i + 1 <= 13: + if state[e + 1, i + 1] == color and (state[e, i + 1] in self.colors): + src_pt = self.get_click_point(self.data_coordinates[e + 1, i + 1]) + dest_pt = self.get_click_point(self.data_coordinates[e, i + 1]) + self.move_tile(src_pt, dest_pt) + return True + if e + 2 <= 7: + if state[e, i] == color and state[e + 2, i] == color: + # third upper + if e + 1 >= 0 and i + 1 <= 13: + #if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5): + if state[e + 1, i + 1] == color and (state[e + 1, i] in self.colors): + src_pt = self.get_click_point(self.data_coordinates[e + 1, i + 1]) + dest_pt = self.get_click_point(self.data_coordinates[e + 1, i]) + self.move_tile(src_pt, dest_pt) + return True + # third left lower + if e + 1 <= 7 and i - 1 >= 0: + if state[e + 1, i - 1] == color and (state[e + 1, i] in self.colors): + src_pt = self.get_click_point(self.data_coordinates[e + 1, i - 1]) + dest_pt = self.get_click_point(self.data_coordinates[e + 1, i]) + self.move_tile(src_pt, dest_pt) + return True + except: + return False + def check_3_horizontal(self, state, e, i, color): try: # second color next to starting point diff --git a/farm/maginent.jpg b/farm/maginent.jpg new file mode 100644 index 0000000..ab83d91 Binary files /dev/null and b/farm/maginent.jpg differ diff --git a/farm/main_farm.py b/farm/main_farm.py index 75087a6..1f25a98 100644 --- a/farm/main_farm.py +++ b/farm/main_farm.py @@ -24,8 +24,8 @@ def run(): continue - cords, screenshot = field.get_current_board_state() - field.analyse_boardstate(cords) + #cords, screenshot = field.get_current_board_state() + cords = field.assess_playfield_and_make_move() print(cords) cv.waitKey(1000)