Skip to content

Instantly share code, notes, and snippets.

@jsbain
Forked from henryiii/h2048.py
Created July 21, 2014 04:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsbain/ead0f93e5f0d3b971b32 to your computer and use it in GitHub Desktop.
Save jsbain/ead0f93e5f0d3b971b32 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 12 09:33:29 2014
@author: henryiii
"""
import random
import numpy as np
from functools import partial
class Board (object):
def __init__(self, data=np.zeros((4,4),dtype=int)):
self.data = data
def add_tile(self):
data = self.data.reshape(-1)
locs = np.nonzero(data == 0)[0]
if len(locs):
data[random.choice(locs)] = random.randint(1,2)
return True
return False
def check_move(self):
'Checks to see if move available'
if np.count_nonzero(self.data == 0):
return True
for row in self.data:
if np.count_nonzero(np.ediff1d(row) == 0):
return True
for row in self.data.T:
if np.count_nonzero(np.ediff1d(row) == 0):
return True
return False
def __repr__(self):
return self.__class__.__name__+ '(' +repr(self.data) + ')'
def __str__(self):
return str(self.traditional_data) + '\nScore: {}'.format(self.score)
@property
def traditional_data(self):
data = 2**self.data
data[data == 1] = 0
return data
@property
def score(self):
return (self.traditional_data).sum()
def move(self, dir, test = False):
'right,up,left,down as 0,1,2,3'
made_move = False
data = self.data
if dir%2:
data = data.T
if (dir-1)//2 != 0:
data = np.fliplr(data)
for row in data:
vals = row[row!=0]
for n in range(len(vals)-1):
if vals[n]==vals[n+1]:
vals[n]+=1
vals[n+1]=0
vals = vals[vals!=0]
vals.resize(row.shape)
made_move |= not np.all(vals == row)
if not test:
row[:] = vals
return made_move
def directions(self):
return {x for x in range(4) if self.move(x,True)}
def auto_simple(self, pattern=(0,1,2,3)):
for d in pattern:
if self.move(d):
return True
return False
def run_console():
board = Board()
board.add_tile()
while True:
print board
x = raw_input('wasd:').lower()
if len(x)==1 and x in 'wasd':
v = 'dwas'.find(x)
if board.move(v):
board.add_tile()
if not board.check_move():
print 'game over'
break
else:
break
print 'done'
return board
def _ui_setup(board, labels, v):
for i in range(board.data.shape[0]):
for j in range(board.data.shape[1]):
lab = board.traditional_data[i,j]
labels[i,j].text = str(lab) if lab else ''
labels[i,j].background_color = (lab/11.,1-lab/11.,1,.3) if lab else 'white'
v.name = 'Score: {}'.format(board.score)
def _ui_move(board, labels, v, dir, buts, sender):
if board.move(dir):
board.add_tile()
if not board.check_move():
print 'Game over.'
print board
v.close()
_ui_setup(board, labels, v)
_setup_buts(board, buts)
def _ui_move_auto(board, labels, v, buts, sender):
if board.auto_simple():
board.add_tile()
if not board.check_move():
print 'Game over.'
print board
v.close()
_ui_setup(board, labels, v)
_setup_buts(board, buts)
def _setup_buts(board,buts):
valid_dirs = board.directions()
for d in range(4):
buts[d].enabled = d in valid_dirs
def run_ui():
import ui
v = ui.View(frame=(0,0,100,140))
v.background_color = 'white'
board=Board()
board.add_tile()
labels = np.empty_like(board.data,dtype=object)
for i in range(board.data.shape[0]):
for j in range(board.data.shape[1]):
labels[i,j] = ui.Label()
labels[i,j].flex = 'HWLRTB'
labels[i,j].alignment = ui.ALIGN_CENTER
labels[i,j].border_width = 1
labels[i,j].corner_radius = 2
labels[i,j].font = ('<system-bold>',24)
labels[i,j].frame = (
100/board.data.shape[1]*(j+.04),
100/board.data.shape[0]*(i+.04),
100/board.data.shape[1]*.92,
100/board.data.shape[0]*.92)
v.add_subview(labels[i,j])
_ui_setup(board,labels,v)
buts = []
for i in range(4):
but = ui.Button()
but.title = ('RIGHT','UP','LEFT','DOWN')[i]
but.frame = ((60,110,20,20),
(40,100,20,20),
(20,110,20,20),
(40,120,20,20))[i]
but.flex = 'WHTBLR'
but.action = partial(_ui_move,board,labels,v,i,buts)
v.add_subview(but)
buts.append(but)
but = ui.ButtonItem()
but.title = 'Auto Move'
but.action = partial(_ui_move_auto,board,labels,v,buts)
v.right_button_items = [but]
_setup_buts(board,buts)
v.present()
if __name__ == '__main__':
#self = run_console()
run_ui()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment