Last active
September 16, 2017 23:58
-
-
Save samm81/3995325511f4dc09f63b8135d5b57000 to your computer and use it in GitHub Desktop.
An automatic solver for facebook messenger's brickpop game. The code is a mess. Don't judge.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pyautogui # this will require some packages or something to be installed | |
import time | |
cmap = { (253, 178, 54): 'y', (255, 109, 114): 'r', (14, 177, 156): 'g', (79, 150, 242): 'b', (179, 111, 238): 'p', (151, 136, 116): 'l', (247, 239, 228): '0', (20, 179, 158) : 'g' } | |
hgap = 49 | |
vgap = 49 | |
xo, yo = pyautogui.position() | |
def getColor(x, y, s): | |
return cmap[s.getpixel((x, y))] | |
def getBoard(): | |
screenshot = pyautogui.screenshot() | |
return [ [ getColor(xo + j * hgap, yo + i * vgap, screenshot) for j in range(10) ] for i in range(10) ] | |
def executeMove(row, column): | |
row, column = row - 1, column - 1 | |
x, y = xo + (column * hgap), yo + (row * vgap) | |
pyautogui.click(x=x, y=y) | |
def executeMoves(moves): | |
for move in moves: | |
executeMove(*move) | |
time.sleep(2) | |
pyautogui.moveTo(xo, yo) | |
def pp(board): | |
print('\n'.join([''.join(l) for l in board])) | |
def transpose(board): | |
return [ list(row) for row in zip(*board) ] | |
def popable(transposed_board, row, column): | |
if transposed_board[column][row] == ' ' or transposed_board[column][row] == '0': | |
return False | |
neighbors = [ (row+ri, column+ci) for ri, ci in zip([-1, 1, 0, 0], [0, 0, -1, 1]) ] | |
return any([ transposed_board[nc][nr] == transposed_board[column][row] for nr, nc in neighbors ]) | |
def pop(boardt, r, c): | |
if not popable(boardt, r, c): | |
return boardt | |
def popcolor(boardt, r, c, color): | |
to_visit = [(r, c)] | |
while len(to_visit) > 0: | |
r, c = to_visit.pop(0) | |
if boardt[c][r] == '0' or boardt[c][r] == ' ': | |
continue | |
if boardt[c][r] == color: | |
boardt[c][r] = ' ' | |
to_visit += [ (r + ri, c + ci) for ri, ci in zip([-1, 1, 0, 0], [0, 0, -1, 1]) ] | |
return boardt | |
def drop(boardt): | |
c = 1 | |
while c < len(boardt): | |
col = boardt[c] | |
if all([ ch == ' ' for ch in col[1:-1] ]): | |
boardt.pop(c) | |
else: | |
c += 1 | |
while len(boardt) < 12: | |
boardt.insert(len(boardt) - 1, ['0'] + [' '] * 10 + ['0']) | |
return boardt | |
def dropv(boardt): | |
def dropcol(column): | |
if column[1] == '0': # side column | |
return column | |
column = [ c for c in column if c != ' ' and c != '0' ] | |
column = [' '] * (10 - len(column)) + column | |
column = ['0'] + column + ['0'] | |
return column | |
return [ dropcol(column) for column in boardt ] | |
boardt = popcolor(boardt, r, c, boardt[c][r]) | |
boardt = dropv(boardt) | |
boardt = drop(boardt) | |
return boardt | |
def accept(boardt): # also works on board | |
for c in range(1,11): | |
for r in range(1,11): | |
if boardt[c][r] != ' ': | |
return False | |
return True | |
def reject(boardt): | |
for c in range(1,11): | |
for r in range(1,11): | |
if popable(boardt, r, c): | |
return False | |
return True | |
import random | |
def rand(boardt): | |
r = random.randint(1,10) | |
c = random.randint(1,10) | |
while not popable(boardt, r, c): | |
r = random.randint(1,10) | |
c = random.randint(1,10) | |
return (r, c) | |
import sys | |
def solve(boardt): | |
while True: | |
b = [ list(col) for col in boardt ] | |
moves = [] | |
while not reject(b): | |
move = rand(b) | |
moves.append(move) | |
b = pop(b, *move) | |
if accept(b): | |
return moves | |
while True: | |
board = getBoard() | |
board = [ ['0'] + l + ['0'] for l in board ] | |
board.insert(0, ['0' for i in range(12)]) | |
board.append(['0' for i in range(12)]) | |
pp(board) | |
boardt = transpose(board) | |
bestmoves = solve(boardt) | |
bestlen = len(bestmoves) | |
endt = time.time() + 5 | |
while time.time() < endt: | |
moves = solve(boardt) | |
if len(moves) < bestlen: | |
bestlen = len(moves) | |
bestmoves = moves | |
moves = bestmoves | |
print('final moves: {}'.format(moves)) | |
pyautogui.click(x = xo, y = yo - 100) | |
time.sleep(1) | |
executeMoves(moves) | |
print('done!') | |
time.sleep(10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment