From 4e0f3bd43669d7c1515499d187675d321d71171d Mon Sep 17 00:00:00 2001 From: Babis Trapalis Date: Mon, 15 Aug 2022 14:20:12 +0300 Subject: [PATCH] Class implementation --- g2048.py | 278 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 141 insertions(+), 137 deletions(-) diff --git a/g2048.py b/g2048.py index 1245307..e922afe 100755 --- a/g2048.py +++ b/g2048.py @@ -2,158 +2,162 @@ import random, copy, curses -def game_logic(l): - oldHash = hash(tuple(l)) +class G2048(): + def __init__(self): + self.board = [] - line_active= True - global moved - merged = False - while line_active: - for i in range(board_line-1): - if l[i] == None and l[i+1] != None: - l.pop(i) - l.insert(i+1,None) - elif l[i] != None and l[i] == l[i+1] and merged != True: - mi=l.pop(i) - l.insert(i,int(mi)*2) + self.board_line = 3 + self.board_size = self.board_line**2 + for i in range(self.board_size): + self.board.insert(i,None) + + self.moved = False + self.stdscr = curses.initscr() - l.pop(i+1) - l.insert(i+1,None) + self.undo = ['u','r'] + + self.up = ['k','w'] #straight + self.left = ['h','a'] #straight + self.down = ['j','s'] #back + self.right = ['l','d'] #back - merged = True - oldHash = hash(tuple(l)) - moved = True + self.line = self.left + self.right + self.column = self.up + self.down - newHash = hash(tuple(l)) + def game_logic(self, l): + oldHash = hash(tuple(l)) + + line_active= True + merged = False + while line_active: + for i in range(self.board_line-1): + if l[i] == None and l[i+1] != None: + l.pop(i) + l.insert(i+1,None) + elif l[i] != None and l[i] == l[i+1] and merged != True: + mi=l.pop(i) + l.insert(i,int(mi)*2) + + l.pop(i+1) + l.insert(i+1,None) + + merged = True + oldHash = hash(tuple(l)) + self.moved = True + + newHash = hash(tuple(l)) + + if oldHash == newHash: + # print('Exiting: Boxes didn't move') + line_active = False + else: + # print('Repeating: Boxes moved') + oldHash = newHash + self.moved = True + + return l - if oldHash == newHash: - # print('Exiting: Boxes didn't move') - line_active = False + def reverse(self, rl, m): + if m in self.left + self.up: + gl = self.game_logic(rl) #k else: - # print('Repeating: Boxes moved') - oldHash = newHash - moved = True - - return l - -def movement(): - stdscr.addstr(10, 0, '\nMove the numbers: ') - m = stdscr.getkey() - global moved - global board - global board_reset - moved=False - board_temp=copy.deepcopy(board) - - undo = ['u','r'] - - up = ['k','w'] #straight - left = ['h','a'] #straight - down = ['j','s'] #back - right = ['l','d'] #back - - line = left + right - column = up + down - - def rev(rl): - if m in left + up: - gl = game_logic(rl) #k - else: - gl = game_logic(rl[::-1])[::-1] #j + gl = self.game_logic(rl[::-1])[::-1] #j return gl + + def movement(self): + self.stdscr.addstr(10, 0, '\nMove the numbers: ') + m = self.stdscr.getkey() + self.moved=False + board_temp=copy.deepcopy(self.board) + self.move(m) - if m in line: - for i in range(0,board_size,board_line): - rl = board[i:i+board_line] - board[i:i+board_line] = rev(rl) - elif m in column: - for i in range(board_line): - rl = board[i::board_line] - board[i::board_line] = rev(rl) - elif m in undo: - board=board_reset - else: - raise ValueError('Can not move this way') + if m not in self.undo and self.moved == True: + self.board_reset = copy.deepcopy(board_temp) - if m not in undo and moved == True: - board_reset=copy.deepcopy(board_temp) - - -def print_board(): - for i in range(0,board_size,board_line): - stdscr.addstr(i, 0, '{!s:<4}'.join(' '*(board_line+1)).format(*board[i:i+board_line])) - stdscr.refresh() - -def add_number(): - try: - global board - global li + def move(self, m): + if m in self.line: + for i in range(0,self.board_size,self.board_line): + rl = self.board[i:i+self.board_line] + self.board[i:i+self.board_line] = self.reverse(rl,m) + elif m in self.column: + for i in range(self.board_line): + rl = self.board[i::self.board_line] + self.board[i::self.board_line] = self.reverse(rl,m) + elif m in self.undo: + self.board = self.board_reset + else: + raise ValueError('Can not move this way') + + + def print_board(self): + for i in range(0,self.board_size,self.board_line): + self.stdscr.addstr(i, 0, '{!s:<4}'.join(' '*(self.board_line+1)).format(*self.board[i:i+self.board_line])) + self.stdscr.refresh() + + def add_number(self): indices = [] - indices = [i for i, x in enumerate(board) if x == None] - li=len(indices) + indices = [i for i, x in enumerate(self.board) if x == None] + self.li=len(indices) p = random.choice(indices) - board[p] = random.choices([2,4],weights=[80,20])[0] - stdscr.addstr(13, 0, '\nNew number at position '+str(p+1)) - stdscr.addstr(15,0,str(li)+str(p)+str(indices)+' ') - except e: - print(e) + self.board[p] = random.choices([2,4],weights=[80,20])[0] + self.stdscr.addstr(13, 0, '\nNew number at position '+str(p+1)) + self.stdscr.addstr(15, 0,str(self.li)+str(p)+str(indices)+' ') -def run(*args): - #TODO: Make a class so i can remove globals and simplify code - # class Game(): - # def init(): - global li - global board - global board_reset - game_state = True - board = [] - global board_size - global board_line - board_line = 2 - board_size = board_line**2 - for i in range(board_size): - board.insert(i,None) + def run(self, *args): + self.game_state = True + self.add_number() + self.board_reset = copy.deepcopy(self.board) - global stdscr - stdscr = curses.initscr() - add_number() - board_reset = copy.deepcopy(board) + while self.game_state: + + self.print_board() + #self.check_playable() + + try: + self.movement() + except ValueError: + #continue + pass + - global moved - while game_state: + self.stdscr.addstr(13, 0, 'MOVED ') + if self.moved == False: + self.stdscr.addstr(13, 0, 'DID NOT MOVE') + #TODO: Fix continue breaks game over but fixes undo + continue + + try: + self.add_number() + except IndexError: + # catch game over here + self.game_state = False + self.stdscr.addstr(15, 0, 'Game Over') + #print('Game Over') + + def check_playable(self): + l=0 + for i in ['h','j','k','l']: + if self.li == 1 and self.moved == False: + self.move(i) + l=l+1 + self.game_state = False + #print('Game Over') + #curses.endwin() + #self.print_board() - print_board() + if l==4: + self.stdscr.addstr(15, 0, 'Game Over') - try: - movement() - except ValueError: - # continue - pass + def close(self): + state = True + while state: + self.stdscr.addstr(16, 0, 'Press q to exit: ') + m = self.stdscr.getkey() + if m == 'q': + state = False + curses.endwin() - if moved == False and li == 0: - #game_state = False - stdscr.addstr(15, 0, 'Game Over') - #print('Game Over') - #curses.endwin() - return - stdscr.addstr(13, 0, 'MOVED ') +game = G2048() +curses.wrapper(game.run) +game.close() - if moved == False: - stdscr.addstr(13, 0, 'DID NOT MOVE') - continue - - try: - add_number() - except IndexError: - # catch game over here - game_state = False - print('Game Over') - -curses.wrapper(run) - -state = True -while state: - m = stdscr.getkey() - if m == 'q': - state = False - curses.endwin()