added sodoku game first draft

This commit is contained in:
2023-04-28 15:11:21 +02:00
parent c4c6c34709
commit 33059b0a95
12 changed files with 221 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ from farm import Farm
from magic import Magic from magic import Magic
from craft import Craft from craft import Craft
from mine import Mine from mine import Mine
from sodoku import Sodoku
from fruit import Fruit from fruit import Fruit
@@ -55,7 +56,7 @@ def run():
mine = Mine(overlay) mine = Mine(overlay)
mine.execute_main_loop() mine.execute_main_loop()
elif overlay.rb_int.get() == 7: elif overlay.rb_int.get() == 7:
fruit = Fruit(overlay) fruit = Sodoku(overlay)
fruit.execute_main_loop() fruit.execute_main_loop()

219
sodoku.py Normal file
View File

@@ -0,0 +1,219 @@
import cv2 as cv
import numpy as np
from utils import mse
from game_base_class import GameBase
GREEN = 1
YELLOW = 2
RED = 3
BLUE = 4
ORANGE = 5
class Sodoku(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
self.data_coordinates = np.zeros((9, 9), dtype=object)
self.observation = np.zeros((9, 9), dtype=int)
self.colors = [1, 2, 3, 4, 5, 6, 7, 8, 9]
self.offset_left = 860
self.offset_down = 180
self.fill_data_coordinates()
self.needles = {1: cv.imread("sodoku/1.jpg", cv.IMREAD_COLOR),
2: cv.imread("sodoku/2.jpg", cv.IMREAD_COLOR),
3: cv.imread("sodoku/3.jpg", cv.IMREAD_COLOR),
4: cv.imread("sodoku/4.jpg", cv.IMREAD_COLOR),
5: cv.imread("sodoku/5.jpg", cv.IMREAD_COLOR),
6: cv.imread("sodoku/6.jpg", cv.IMREAD_COLOR),
7: cv.imread("sodoku/7.jpg", cv.IMREAD_COLOR),
8: cv.imread("sodoku/8.jpg", cv.IMREAD_COLOR),
9: cv.imread("sodoku/9.jpg", cv.IMREAD_COLOR)
}
def fill_data_coordinates(self):
# 860 to 1690 = 830 - 40 / 9 = 88
# 180 to 1010 = 830 - 40 / 9 = 88
# spacing 2 * 20
dim = 88
e_spacing = 0
i_spacing = 0
for e in range(0, 9, 1):
if e >= 4:
e_spacing = 20
elif e >= 7:
e_spacing = 20
for i in range(0, 9, 1):
if i >= 4:
i_spacing = 20
elif i >= 7:
i_spacing = 20
self.data_coordinates[e][i] = [(i * dim) + i_spacing, (e * dim) + e_spacing, dim, dim]
def assess_playfield_and_make_move(self):
new_observation, new_screenshot = self.get_current_board_state()
self.find_patterns_and_valid_moves(new_observation)
self.observation = new_observation
return new_observation
def get_current_board_state(self):
# get an updated image of the game
#screenshot = self.capture_window.get_screenshot()
#screenshot = screenshot[900:1030, 540:1870]
#screenshot = cv.imread("sodoku/screen_shot.jpg")
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
#if self.check_for_button_and_execute(screenshot, self.ok_button):
# cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[180:1010, 860:1690]
#cv.imshow("screenshot", screenshot)
#cv.waitKey(150)
#continue
data_coords = np.zeros((9, 9), dtype=object)
# field = Field()
for needle_key in self.needles.keys():
# gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.85, 56)
if len(rectangles) == 0:
continue
points = self.vision_stun.get_click_points(rectangles)
for point in points:
x, y = self.point_in_rect(point)
if x is not None and y is not None:
data_coords[x][y] = int(needle_key)
# self.change_value(x, y, int(needle_key))
# print(field.data_value_grid)
# cv.circle(screenshot, points[0], 7, (0, 255, 0), -1)
#output_image = self.vision_stun.draw_rectangles(screenshot, rectangles)
#cv.imshow("output_image", output_image)
#cv.waitKey(150)
return data_coords, screenshot
def point_in_rect(self, point):
for e in range(0, 9, 1):
for i in range(0, 9, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None
# per pos
# select from row,column and quadrant (1-9)
# find missing pieces per row, column, quadrant
def find_patterns_and_valid_moves(self, state):
while self.is_empty_pieces_in_state(state):
for e in range(0, 9, 1):
for i in range(0, 9, 1):
if state[e, i] not in self.colors:
#color in self.colors:
store = self.collect_existing_pieces(state, e, i)
if len(store) == 8:
for color in self.colors:
if color not in store:
state[e, i] = color
self.deploy_finding_to_game(e, i, color)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
def deploy_finding_to_game(self, e, i, color):
cv.waitKey(5000)
click_pt = self.get_click_point(self.data_coordinates[e, i])
self.dig_point(click_pt[0] + self.offset_left, click_pt[1] + self.offset_down, 100)
y = 1100
x = 880 + ((color - 1) * 100) # +100
self.dig_point(x, y, 100)
def is_empty_pieces_in_state(self, state):
for e in range(0, 9, 1):
for i in range(0, 9, 1):
if state[e, i] not in self.colors:
return True
return False
def collect_existing_pieces(self, state, e, i):
store = []
for ee in range(0, 9, 1):
if state[ee, i] != 0:
store.append(state[ee, i])
for ii in range(0, 9, 1):
if state[e, ii] != 0:
store.append(state[e, ii])
# quad 1
if e <= 2 and i <= 2:
for eee in range(0, 3, 1):
for iii in range(0, 3, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 2
elif e <= 2 and i <= 5:
for eee in range(0, 3, 1):
for iii in range(3, 6, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 3
elif e <= 2 and i <= 8:
for eee in range(0, 3, 1):
for iii in range(6, 9, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 4
elif e <= 5 and i <= 2:
for eee in range(3, 6, 1):
for iii in range(0, 3, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 5
elif e <= 5 and i <= 5:
for eee in range(3, 6, 1):
for iii in range(3, 6, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 6
elif e <= 5 and i <= 8:
for eee in range(3, 6, 1):
for iii in range(6, 9, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 7
elif e <= 8 and i <= 2:
for eee in range(6, 9, 1):
for iii in range(0, 3, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 8
elif e <= 8 and i <= 5:
for eee in range(6, 9, 1):
for iii in range(3, 6, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
# quad 9
elif e <= 8 and i <= 8:
for eee in range(6, 9, 1):
for iii in range(6, 9, 1):
if state[eee, iii] != 0:
store.append(state[eee, iii])
unique_numbers = list(set(store))
return unique_numbers

BIN
sodoku/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

BIN
sodoku/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
sodoku/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
sodoku/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
sodoku/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
sodoku/6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sodoku/7.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
sodoku/8.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sodoku/9.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sodoku/screen_shot.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB