Skip to content

Instantly share code, notes, and snippets.

@samm81
Last active September 16, 2017 23:58
Show Gist options
  • Save samm81/3995325511f4dc09f63b8135d5b57000 to your computer and use it in GitHub Desktop.
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.
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