Skip to content

Instantly share code, notes, and snippets.

@zlsun
Last active March 10, 2016 08:54
Show Gist options
  • Select an option

  • Save zlsun/69e4657b0c14b0431f13 to your computer and use it in GitHub Desktop.

Select an option

Save zlsun/69e4657b0c14b0431f13 to your computer and use it in GitHub Desktop.
Terminal 2048 game in 50 lines of Python
#!/bin/python3
from random import choice
from os import system
from readchar import readchar, readkey
from colorama import init
from termcolor import colored
from math import log2
N = 4
SEED = [2] * 9 + [4]
FGS = ['white', 'green', 'yellow', 'blue', 'cyan', 'magenta', 'red']
TERM = (24, 80)
OFFSET = (TERM[0] // 2 - 2, TERM[1] // 2 - 10)
pos = lambda y, x: '\x1b[%d;%dH' % (y, x)
color = lambda i: colored('%4d' % i, FGS[int(log2(i)) % len(FGS)] if i else 'grey')
formatted = lambda m: '\n'.join(pos(y, OFFSET[1]) + ' '.join(color(i) for i in l) for l, y in zip(m, range(OFFSET[0], OFFSET[0] + 4)))
combine = lambda l: ([l[0] * 2] + combine(l[2:]) if l[0] == l[1] else [l[0]] + combine(l[1:])) if len(l) >= 2 else l
expand = lambda l: [l[i] if i < len(l) else 0 for i in range(N)]
merge_left = lambda l: expand(combine(list(filter(bool, list(l)))))
merge_right = lambda l: merge_left(l[::-1])[::-1]
left = lambda m: list(map(merge_left, m))
right = lambda m: list(map(merge_right, m))
up = lambda m: list(map(list, zip(*left(zip(*m)))))
down = lambda m: list(map(list, zip(*right(zip(*m)))))
add_num_impl = lambda m, p: m[p[0]].__setitem__(p[1], choice(SEED))
add_num = lambda m: add_num_impl(m, choice([(x, y) for x in range(N) for y in range(N) if not m[x][y]]))
win = lambda m: 2048 in sum(m, [])
gameover = lambda m: all(m == t(m) for t in trans.values())
draw = lambda m: system("clear") or print(formatted(m))
trans = {'a': left, 'd': right, 'w': up, 's': down}
m = [[0] * N for _ in range(N)]
init()
add_num(m)
draw(m)
while True:
while True:
move = readkey()
if move in list(trans.keys()) + ['q']:
break
if move == 'q':
print('Quit!')
break
n = trans[move](m)
if n != m:
add_num(n)
m = n
draw(m)
if win(m):
print(colored('(^_^) You Win!', 'yellow'))
break
elif gameover(m):
print(colored('(>﹏<) Game Over!', 'red'))
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment