def internal(): ssize = self.screen_size() curses.init_pair(8, fgcolor, bgcolor) mycolor = curses.color_pair(8) for i in range(ssize.y - 5, ssize.y): for j in range(ssize.x): self.s.insch(i, j, " ", mycolor) self.write(heading, at=ani.Coord((ssize.x - len(heading)) // 2, ssize.y - 3), c=mycolor) self.write(left, at=ani.cj * (ssize.y - 1), c=mycolor) self.write(right[:-1], at=ani.Coord(ssize.x - len(right), ssize.y - 1), c=mycolor) self.s.insch(ssize.y - 1, ssize.x - 1, right[-1], mycolor)
def draw(t, pos, score, highscore): # print("Scorecard draw at {0}".format(pos), file=sys.stderr) t.write("-Score----", at=pos + ani.Coord(0, 0), c=t.sboxc) t.write("|", at=pos + ani.Coord(9, 1), c=t.sboxc) t.write("|", at=pos + ani.Coord(0, 1), c=t.sboxc) t.write(str(score), at=pos + ani.Coord(1, 1), c=t.yellow) t.write("-High-----", at=pos + ani.Coord(0, 2), c=t.sboxc) t.write("|", at=pos + ani.Coord(9, 3), c=t.sboxc) t.write("|", at=pos + ani.Coord(0, 3), c=t.sboxc) t.write(str(highscore), at=pos + ani.Coord(1, 3), c=t.yellow if highscore > score else t.red) t.write("----------", at=pos + ani.Coord(0, 4), c=t.sboxc)
def addrand(grid, anims): triples = [triple for triple in grid.triples if not triple.v] if len(triples) > 1: triples = random.sample(triples, 1) for triple in triples: c = Cell(random.sample([1, 1, 1, 1, 1, 1, 1, 1, 1, 2], 1)[0]) anims.insert( 0, ani.TileSpawn(c, ani.Coord(2 + triple.x * 7, 2 + triple.y * 4))) grid[triple[0], triple[1]] = c
def __init__(self, diff, pos, *args, **kwargs): self.pos = pos self.dpos = pos + ani.Coord(1, 2) # position of +12, etc. self.diff = "+{}".format(diff) if diff > 0 else None self.args = args self.kwargs = kwargs
def __enter__(self): y, x = self.scr.getyx() self.stk.append(ani.Coord(x, y)) self.scr.move(*self.dest.rtuple())
def screen_size(self): y, x = self.s.getmaxyx() return ani.Coord(x, y)
def location(self, x=0, y=0): return Mover(self.pos_stack, self.s, ani.Coord(x, y))
def write_number_only(self, t, coord, truncate=False): text = center(4, 2**self.power) if truncate: text = text[1:-1] t.write(text, at=coord + ani.Coord(1, 2), c=self.get_color(t))
def main(t, per): animationrate = .009 for arg in sys.argv: if arg in ['-h', '--help']: t.done() import blessings t = blessings.Terminal() print("""{b}2048{n} Implementation in python by Samuel Phillips <*****@*****.**> Based on 2048 by Gabriele Cirulli. <gabrielecirulli.com> To play: Use hjkl to push the tiles: ^ < {b}h j k l{n} > v The objective is to combine tiles to form a 2048 tile. Press {b}q{n} to quit. {b}!{n} will start a Python debugger. Use -A{u}xxx{n} or --animrate{u}xxx{n} to speed up or slow down the animations. The default rate is {animrate}. The game's high score is soted in ~/.2048tty by default. You can change this location be setting the 2048TTY_FILE environment varible. """.format(b=t.bold, n=t.normal, u=t.underline, animrate=animationrate)) sys.exit(0) elif arg.startswith('-A'): animationrate = float(arg[2:]) elif arg.startswith('--animrate'): animationrate = float(arg[len('--animrate'):]) debug = False inspect = ani.Coord(0, 0) score = Score(hiscore=per["hiscore"]) # Class needed because no pointers grid = Grid(x=GAME_WIDTH, y=GAME_HEIGHT) if "savegame" in per: for i, row in enumerate(per["savegame"]): for j, cell in enumerate(row): grid[j, i] = Cell(cell) if cell else None won_already = get_practical_state(grid) if "score" in per: score.score = per["score"] else: addrand(grid, []) addrand(grid, []) won_already = False tx = '_' tilesiz = ani.Coord(7, 4) stepx = tilesiz * ani.ci stepy = tilesiz * ani.cj tl = ani.Coord(2, 2) anims = None while not tx.startswith("q"): t.clear() # main grid for trip in grid.triples: if trip.v: trip.v.render(t, tl + tilesiz * ani.Coord(trip.x, trip.y)) # score card score.diff = 0 scorecard.draw(t, tl + tilesiz * ani.ci * 4 + ani.Coord(10, 5), score.score, score.hiscore) # check practical state winlose = get_practical_state(grid) if winlose == 1 and not won_already: won_already = True k = t.popup("YOU WON!", left="press c to continue", right="press q to quit", accept="cq") if k == 'c': continue elif k == 'q': per["hiscore"] = max(per["hiscore"], score.hiscore) del per["savegame"] del per["score"] raise EndOfGame() elif winlose == -1: t.popup("YOU LOST", right="press any key to quit", bgcolor=t.c.COLOR_WHITE) break # debug if debug: for i, row in enumerate(grid.rows): t.write(repr(row), at=ani.Coord(30, 2 + i)) for i, anim in enumerate(anims): t.write(repr(anim), at=ani.Coord(30, 3 + len(grid.rows) + i)) ic = tl + tilesiz * inspect t.write('#', at=ic, c=t.red) t.write(repr(ic), at=ani.Coord(30, 3 + len(grid.rows) + len(anims))) # refresh screen t.go() # clear anims anims = [] # get & process input tx = t.getch() # movement if tx.startswith('h'): ok = [] for i, row in enumerate(grid.rows): ok.append(pushrow(row, tl + stepy * i, stepx, anims, score)) if any(ok): addrand(grid, anims) elif tx.startswith('l'): ok = [] for i, row in enumerate(grid.rows): ok.append( pushrow(WrapperRev(row), tl + stepy * i + stepx * len(grid.rows) - stepx, -stepx, anims, score)) if any(ok): addrand(grid, anims) elif tx.startswith('k'): ok = [] for i, col in enumerate(grid.cols): ok.append(pushrow(col, tl + stepx * i, stepy, anims, score)) if any(ok): addrand(grid, anims) elif tx.startswith('j'): ok = [] for i, col in enumerate(grid.cols): ok.append( pushrow(WrapperRev(col), tl + stepx * i + stepy * len(grid.cols) - stepy, -stepy, anims, score)) if any(ok): addrand(grid, anims) # quit w/o saveing elif tx.startswith('x'): k = t.popup("Are you sure you want to quit and clear the board?", right="press y to confirm", bgcolor=t.c.COLOR_MAGENTA) if k == 'y': del per["savegame"] del per["score"] raise EndOfGame() # debug mode elif tx.startswith('d'): debug = not debug # start pdb if things are really bad elif tx.startswith('!'): import pdb with t.location(): t.c.curs_set(1) t.c.nocbreak() t.s.keypad(False) pdb.set_trace() t.s.keypad(True) t.c.cbreak() t.c.curs_set(0) elif debug: # move location indicator if tx.startswith('H'): inspect -= ani.ci elif tx.startswith('L'): inspect += ani.ci elif tx.startswith('K'): inspect -= ani.cj elif tx.startswith('J'): inspect += ani.cj elif tx.isdigit(): grid[inspect.x, inspect.y] = Cell(int(tx)) score.score += score.diff score.hiscore = max(score.score, score.hiscore) anims.append( scorecard.ScoreCardAnim( score.diff, tl + tilesiz * ani.ci * 4 + ani.Coord(10, 5), score.score, score.hiscore)) # don't want any suprise motions t.input_flush() ani.play(t, animationrate, anims) per["hiscore"] = max(per["hiscore"], score.hiscore) if get_practical_state(grid) == 0: per["savegame"] = [[c.power if c else None for c in r] for r in grid.rows] per["score"] = score.score else: del per["savegame"] del per["score"]