import curses import math import random # h a left key_left = [104, 97, 68] # l d right key_right = [108, 100, 67] # j s down key_down = [106, 115, 66] # k w up key_up = [107, 119, 65] maxX = 4 maxY = 4 scaleX = 6 scaleY = 3 offsetX = 1 offsetY = 1 gamestate = [[0 for mx in range(maxX)] for my in range(maxY)] # INIT global score score = 0 stdscr = curses.initscr() curses.noecho() curses.curs_set(0) height, width = stdscr.getmaxyx() distanceX = width - (maxX * scaleX + offsetX * 2) distanceY = height - (maxY * scaleY + offsetY * 2) gamewin = curses.newwin(0, 0, distanceY, distanceX) gamewin.mvwin(math.floor(distanceY / 2), math.floor(distanceX / 2)) curses.start_color() # COLORS curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_YELLOW, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(4, curses.COLOR_CYAN, curses.COLOR_BLACK) curses.init_pair(5, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(6, curses.COLOR_MAGENTA, curses.COLOR_BLACK) curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK) # GRAPHICS def DrawSquare(x, y, val, box_color): val_len = len(str(val)) if val_len > 4: val_len = 4 gamewin.addstr(y, x, "+" + "-" * (scaleX - 2) + "+", box_color) gamewin.addstr(y + 1, x, "|" + " " * math.ceil((4-val_len)/2) + str(val) + " " * math.floor((4-val_len)/2) + "|", box_color) gamewin.addstr(y + 2, x, "+" + "-" * (scaleX - 2) + "+", box_color) def FullDraw(): gamewin.clear() gamewin.box() gamewin.addstr(0, math.floor((maxX * scaleX - len(str(score))) / 2), str(score), curses.A_BOLD) for i in range(maxY): for j in range(maxX): if gamestate[i][j] == 0: continue color = 1 try: color = int(math.log(gamestate[i][j]) / math.log(2)) - 1 # I gotta subtract one here so I can add it back in a few lines cuz the modulus will return zero in one instance. except: pass DrawSquare(offsetX + j * scaleX, offsetY + i * scaleY, gamestate[i][j], curses.color_pair((color % 8) + 1) + curses.A_BOLD * math.floor(color / 7)) # PROCESSING def Process(list_in): i = 0 while i < len(list_in) - 1: if list_in[i] == list_in[i + 1]: list_in[i] = 2 * list_in[i] del list_in[i + 1] global score score += list_in[i] i += 1 return list_in def ScrapeLeft(line): out_list = [] for num in gamestate[line]: if num == 0: continue out_list.append(num) return out_list def ScrapeRight(line): out_list = [] for num in gamestate[line][::-1]: if num == 0: continue out_list.append(num) return out_list def ScrapeUp(line): out_list = [] for num in range(maxY): if gamestate[num][line] == 0: continue out_list.append(gamestate[num][line]) return out_list def ScrapeDown(line): out_list = [] for num in range(maxY): if gamestate[maxY - 1 - num][line] == 0: continue out_list.append(gamestate[maxY - 1 - num][line]) return out_list def PasteLeft(line, list_in): for i in range(maxX): if i < len(list_in): gamestate[line][i] = list_in[i] else: gamestate[line][i] = 0 def PasteRight(line, list_in): for i in range(maxX): if i < len(list_in): gamestate[line][maxX - 1 - i] = list_in[i] else: gamestate[line][maxX - 1 - i] = 0 def PasteUp(line, list_in): for i in range(maxY): if i < len(list_in): gamestate[i][line] = list_in[i] else: gamestate[i][line] = 0 def PasteDown(line, list_in): for i in range(maxY): if i < len(list_in): gamestate[maxY - 1 - i][line] = list_in[i] else: gamestate[maxY - 1 - i][line] = 0 def MoveLeft(): for i in range(maxY): PasteLeft(i, Process(ScrapeLeft(i))) def MoveRight(): for i in range(maxY): PasteRight(i, Process(ScrapeRight(i))) def MoveUp(): for i in range(maxY): PasteUp(i, Process(ScrapeUp(i))) def MoveDown(): for i in range(maxY): PasteDown(i, Process(ScrapeDown(i))) # GAMEPLAY def GetEmptySpace(): zero_list = [] for y in range(maxY): for x in range(maxX): if gamestate[y][x] == 0: coord = [x, y] zero_list.append(coord) return zero_list blocks = [2, 2, 2, 4, 4, 8] def SpawnBlock(): chosen = random.choice(GetEmptySpace()) gamestate[chosen[1]][chosen[0]] = random.choice(blocks) # WIN AND LOSE def CheckWin(): for line in gamestate: for item in line: if item == 2048: return True return False def End(text): gamewin.clear() gamewin.refresh() gamewin.box() gamewin.addstr(math.ceil(maxY * scaleY / 2), math.ceil((maxX * scaleX - len(text)) / 2 ) , text) gamewin.getch() # GAMEPLAY userin = 0 while True: FullDraw() userin = gamewin.getch() if userin == 81: # Q break if userin in key_left: MoveLeft() elif userin in key_right: MoveRight() elif userin in key_up: MoveUp() elif userin in key_down: MoveDown() else: continue if CheckWin(): End("YOU WIN!") break height, width = stdscr.getmaxyx() distanceX = width - (maxX * scaleX + offsetX * 2) distanceY = height - (maxY * scaleY + offsetY * 2) gamewin.mvwin(math.floor(distanceY / 2), math.floor(distanceX / 2)) stdscr.clear() stdscr.refresh() try: SpawnBlock() except: End("YOU LOSE!") break curses.endwin()