|
|
@@ -13,16 +13,17 @@ MIN_COLUMN_VAL = 120
|
|
|
|
|
|
COLUMN_VSHIFT = [-2, -2, -1, -1, 0, 0, 0]
|
|
|
|
|
|
-RED, PINK, GREEN, BLUE, YELLOW, NONE = range(6)
|
|
|
-BOMB_OFFSET = NONE + 1
|
|
|
+RED, PINK, GREEN, BLUE, YELLOW, NOBLOCK = range(6)
|
|
|
+BOMB_OFFSET = NOBLOCK + 1
|
|
|
BASIC_HUES = [248, 224, 118, 158, 26]
|
|
|
-BOMB_HUES = [250, 219, 131, 174, 38]
|
|
|
+BOMB_HUES = [250, 219, 132, 174, 38]
|
|
|
HUE_TOLERANCE = 5
|
|
|
DETECT_BASIC_X = 9
|
|
|
DETECT_BASIC_Y = 15
|
|
|
-DETECT_BOMB_X = 25
|
|
|
-DETECT_BOMB_Y = 44
|
|
|
+DETECT_BOMB_X = 22
|
|
|
+DETECT_BOMB_Y = 45
|
|
|
MIN_BASIC_SAT = 180
|
|
|
+MIN_BOMB_SAT = 130
|
|
|
|
|
|
DETECT_EXA_X = 30
|
|
|
DETECT_EXA_Y = 547
|
|
|
@@ -39,6 +40,19 @@ def is_hue(h, hexpect):
|
|
|
return abs(h - hexpect) <= HUE_TOLERANCE
|
|
|
|
|
|
|
|
|
+def is_basic(block):
|
|
|
+ return RED <= block <= YELLOW
|
|
|
+
|
|
|
+
|
|
|
+def is_bomb(block):
|
|
|
+ return block > NOBLOCK
|
|
|
+
|
|
|
+
|
|
|
+def bomb_to_basic(block):
|
|
|
+ assert is_bomb(block)
|
|
|
+ return block - BOMB_OFFSET
|
|
|
+
|
|
|
+
|
|
|
def detect_columns(board):
|
|
|
def saturated(x, y):
|
|
|
h, s, v = board.getpixel((x, y))
|
|
|
@@ -55,11 +69,10 @@ def detect_columns(board):
|
|
|
|
|
|
|
|
|
def detect_block_type(board, x, y):
|
|
|
- h, s, v = board.getpixel((x + DETECT_BASIC_X,
|
|
|
- y + DETECT_BASIC_Y))
|
|
|
-
|
|
|
# check for basic blocks first, use saturation filter to avoid confusing
|
|
|
# green blocks with background
|
|
|
+ h, s, v = board.getpixel((x + DETECT_BASIC_X,
|
|
|
+ y + DETECT_BASIC_Y))
|
|
|
if s >= MIN_BASIC_SAT:
|
|
|
for ty, hexpect in enumerate(BASIC_HUES):
|
|
|
if is_hue(h, hexpect):
|
|
|
@@ -68,12 +81,13 @@ def detect_block_type(board, x, y):
|
|
|
# if no basic block is detected, check another pixel for bomb contents
|
|
|
h, s, v = board.getpixel((x + DETECT_BOMB_X,
|
|
|
y + DETECT_BOMB_Y))
|
|
|
- for ty, hexpect in enumerate(BOMB_HUES):
|
|
|
- if is_hue(h, hexpect):
|
|
|
- return ty + BOMB_OFFSET
|
|
|
+ if s >= MIN_BOMB_SAT:
|
|
|
+ for ty, hexpect in enumerate(BOMB_HUES):
|
|
|
+ if is_hue(h, hexpect):
|
|
|
+ return ty + BOMB_OFFSET
|
|
|
|
|
|
# no basic block or bomb -> empty slot
|
|
|
- return NONE
|
|
|
+ return NOBLOCK
|
|
|
|
|
|
|
|
|
def detect_blocks(board):
|
|
|
@@ -101,7 +115,7 @@ def detect_held(board, exa):
|
|
|
if not is_hue(h, EXA_LIGHT_HUE) or v < MIN_EXA_LIGHT_VAL:
|
|
|
return detect_block_type(board, exa * BLOCK_SIZE, DETECT_HELD_Y)
|
|
|
|
|
|
- return NONE
|
|
|
+ return NOBLOCK
|
|
|
|
|
|
|
|
|
def print_board(blocks, exa, held):
|
|
|
@@ -113,12 +127,12 @@ def print_board(blocks, exa, held):
|
|
|
|
|
|
if exa is not None:
|
|
|
print(' ' * exa + ' |')
|
|
|
- print('-' * exa, '(', 'rpgby RPGBY'[held], ')',
|
|
|
- '-' * (COLUMNS - exa - 1), sep='')
|
|
|
+ print(' ', '-' * (exa - 1), '(', 'rpgby RPGBY'[held], ')',
|
|
|
+ '-' * (COLUMNS - exa - 2), sep='')
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
- from iteraction import get_exapunks_window, screenshot_board
|
|
|
+ from interaction import get_exapunks_window, screenshot_board
|
|
|
|
|
|
win = get_exapunks_window()
|
|
|
win.raise_window()
|