您好,登錄后才能下訂單哦!
用python制作2048游戲的方法?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!
2048游戲規則:簡單的移動方向鍵讓數字疊加,并且獲得這些數字每次疊加后的得分,當出現2048這個數字時游戲勝利。同時每次移動方向鍵時,都會在這個4*4的方格矩陣的空白區域隨機產生一個數字2或者4,如果方格被數字填滿了,那么就GameOver了。
來一步步的進行剖析:
(1)生成4*4的棋盤, 其中數據結構為列表嵌套列表
field = [[0 for j in range(4)] for i in range(4)]
(2)創建函數random_create, 在棋盤的一個隨機位置插入一個數字2或者4,其中2的幾率大
import random def random_create(): i = random.choice(range(4)) j = random.choice(range(4)) value = random.choice([2,2,2,4]) field[i][j] = value
(3)如果隨機插入數字的位置已經有內容, 如何解決覆蓋原有數字的問題
def random_creat(): while True: i = random.choice(range(4)) j = random.choice(range(4)) if li[i][j] == 0: li[i][j] = 4 if random.randint(1, 100) > 80 else 2 break random_creat() random_creat()
(4)將生成的數據, 通過圖像畫出來
def draw_sep(): print('+-----' * 4 + '+') def draw_num(row): print(''.join('|{:^5}'.format(num) if num != 0 else '| ' for num in row) + '|') for row in li: draw_sep() draw_num(row) draw_sep()
(5)矩陣的反轉
def invert(field): return [row[::-1] for row in field]
(6)矩陣的轉秩
def transpose(field): return [list(row) for row in zip(*field)]
(7)判斷棋盤是否可移動
def is_row_change(row): # row # 判斷一行內容是否可以移動 def is_change(i): # 判斷每兩個元素之間是否可以移動 if row[i] == 0 and row[i + 1] != 0: return True if row[i] != 0 and row[i + 1] == row[i]: return True else: return False return any([is_change(index) for index in range(len(row) - 1)])
(8)判斷這個棋盤是否可左右上下移動
def is_move_left(field): return any([is_row_change(row) for row in field]) def is_move_right(field): # 對于列表元素進行反轉 field = invert(field) print(field) return is_move_left(field) def is_move_up(field): # 對于列表元素進行轉置 field = transpose(field) return is_move_left(field) def is_move_down(field): # 反轉+ 轉置 field = transpose(field) return is_move_right(field)
棋盤的移動,相加
def tight(row): # [2, 0, 2, 0] # 最快的方式, 通過排序實現........... return sorted(row, key=lambda x: if x == 0 ) score = 0 # 相加 def merge(row): # [2,2,0,0] # [0,1,2] for i in range(len(row)-1): # 如果兩個值相等, 前一個元素*2, 后一個元素改為0。 if row[i] == row[i+1]: row[i] *= 2 row[i+1] = 0 # 如果覆蓋成功, 就給得分 global score score += row[i] return row
棋盤左右上下移動相加
def move_row_left(self, row): return self.tight(self.merge(self.tight(row))) def move_left(self, field): return [self.move_row_left(row) for row in field] def move_right(self, field): field = self.invert(field) return self.invert([self.move_row_left(row) for row in field]) def move_up(self, field): return self.transpose([self.move_row_left(row) for row in self.transpose(field)]) def move_down(self, field): return self.invert(self.transpose([self.move_row_left(row) for row in self.invert(self.transpose(field))]))
(9)判斷游戲的勝利與結束
#判斷游戲何時勝利:當棋盤中出現2048時,就代表著游戲勝利 def victory(field): li = [y for row in li for y in row] if max(li) >= 2048: print('Victory') def game_over(filed): if all((is_move_left(filed), is_move_right(filed), is_move_up(filed), is_move_down(filed))) == False: print('Game Over')
這樣程序的各個部分就寫好了,將各個部分封裝到一個類里面,再導入curses模塊來控制游戲,就可以了。
下面是完整的代碼:
import curses from itertools import chain from random import choice class GameField(object): # 初始化信息 def __init__(self, width=4, height=4, win_value=8): self.width = width self.height = height self.win_value = win_value self.score = 0 # 當前得分 self.highscore = 0 # 最高分 self.moves = {} self.moves['Left'] = self.is_move_left self.moves['Right'] = self.is_move_right self.moves['Down'] = self.is_move_down self.moves['Up'] = self.is_move_up self.movesDict = {} self.movesDict['Left'] = self.move_left self.movesDict['Right'] = self.move_right self.movesDict['Down'] = self.move_down self.movesDict['Up'] = self.move_up def reset(self): # 重置棋盤 if self.score > self.highscore: self.highscore = self.score # 更新最高分 self.score = 0 # 需求1: 生成4*4的棋盤, 其中數據結構選擇列表嵌套列表; self.field = [[0 for j in range(self.width)] for i in range(self.height)] # 在棋盤的一個隨機位置插入一個數字2或者4 self.random_create() self.random_create() def random_create(self): # 在棋盤的一個隨機位置插入一個數字2或者4 # field[0][3] = 2 while True: i, j = choice(range(self.height)), choice(range(self.width)) if self.field[i][j] == 0: self.field[i][j] = choice([2, 2, 2, 4]) break def draw(self, stdscr): def draw_sep(): stdscr.addstr('+' + "-----+" * self.width + '\n') def draw_one_row(row): stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "| " for num in row) + '|' + '\n') # 清屏 stdscr.clear() stdscr.addstr("2048".center(50, '-') + '\n') stdscr.addstr("當前分數:" + str(self.score) + '\n') if self.highscore != 0: stdscr.addstr("最高分:" + str(self.highscore) + '\n') for row in self.field: draw_sep() draw_one_row(row) draw_sep() # 判斷是否贏或者輸 if self.is_win(): stdscr.addstr("勝利!!!!" + '\n') if self.is_gameover(): stdscr.addstr("游戲結束!!!!" + '\n') stdscr.addstr(" 游戲幫助: 上下左右鍵 (R)Restart Q(Quit)") def is_win(self): return max(chain(*self.field)) >= self.win_value def is_gameover(self): # 任何方向都不能移動的時候, 游戲結束 return not any([self.move_is_possible(direction) for direction in self.moves]) @staticmethod def invert(field): # 矩陣進行反轉 return [row[::-1] for row in field] # print(invert(li)) @staticmethod # 矩陣的轉置 def transpose(field): return [list(row) for row in zip(*field)] @staticmethod def is_row_change(row): # row # 需求3. 判斷一行內容是否可移動。 def is_change(i): # 0 # 判斷每兩個元素之間是否可移動 if row[i] == 0 and row[i + 1] != 0: return True if row[i] != 0 and row[i] == row[i + 1]: return True return False return any([is_change(index) for index in range(len(row) - 1)]) # 判斷這個棋盤是否可向左移動 def is_move_left(self, field): return any([self.is_row_change(row) for row in field]) def is_move_right(self, field): # 對于列表元素進行反轉 field = self.invert(field) print(field) return self.is_move_left(field) def is_move_up(self, field): # 對于列表元素進行轉置 field = self.transpose(field) return self.is_move_left(field) def is_move_down(self, field): # 反轉+ 轉置 field = self.transpose(field) return self.is_move_right(field) def move_is_possible(self, direction): # 'left' # 判斷用戶選擇的方向是否可移動 if direction in self.moves: return self.moves[direction](self.field) else: return False # 將棋盤每一行的非0數向前移動, 0向后移動; @staticmethod def tight(row): # [2, 0, 2, 0] # 最快的方式, 通過排序實現........... return sorted(row, key=lambda x: 1 if x == 0 else 0) def merge(self, row): # [2,2,0,0] # [0,1,2] for i in range(len(row) - 1): # 如果兩個值相等, 前一個元素*2, 后一個元素改為0。 if row[i] == row[i + 1]: row[i] *= 2 row[i + 1] = 0 # 如果覆蓋成功, 就給得分 self.score += row[i] return row # [4, 0, 0, 0] def move_row_left(self, row): return self.tight(self.merge(self.tight(row))) def move_left(self, field): return [self.move_row_left(row) for row in field] def move_right(self, field): field = self.invert(field) return self.invert([self.move_row_left(row) for row in field]) def move_up(self, field): return self.transpose([self.move_row_left(row) for row in self.transpose(field)]) def move_down(self, field): return self.invert(self.transpose([self.move_row_left(row) for row in self.invert(self.transpose(field))])) def move(self, direction): # 'left' # 判斷用戶選擇的方向是否可移動 if direction in self.movesDict: # 判斷是否可移動 if self.move_is_possible(direction): self.field = self.movesDict[direction](self.field) self.random_create() return True else: return False def get_user_action(stdscr): action = stdscr.getch() if action == curses.KEY_UP: return 'Up' if action == curses.KEY_DOWN: return 'Down' if action == curses.KEY_LEFT: return 'Left' if action == curses.KEY_RIGHT: return 'Right' if action == ord('r'): return 'Restart' if action == ord('q'): return 'Exit' def main(stdscr): action = stdscr.getch() def init(): # 初始化棋盤的操作 game_field.reset() game_field.draw(stdscr) return 'Game' def game(): game_field.draw(stdscr) action = get_user_action(stdscr) if action == 'Restart': return 'Init' if action == 'Exit': return 'Exit' if game_field.move(action): if game_field.is_win(): return 'Win' if game_field.is_gameover(): return 'GameOver' return 'Game' def not_game(): game_field.draw(stdscr) while True: action = get_user_action(stdscr) if action == 'Restart': return 'Init' if action == 'Exit': return 'Exit' state_actions = { 'Init': init, 'Game': game, 'Win': not_game, 'GameOver': not_game, } game_field = GameField() state = 'Init' # 如果當前狀態不是退出, 那么一直執行 while state != 'Exit': # 執行當前狀態需要操作的內容, 并返回, 下一次的狀態為什么. state = state_actions[state]() curses.wrapper(main)
實現雙人版的2048游戲
import curses import random from itertools import chain class GameField(object): def __init__(self, width=4, height=4, win_value=2048): self.width = width self.height = height self.win_value = win_value self.score1 = 0 self.score2 = 0 self.highscore = 0 self.moves = {} self.moves['Left1'] = self.is_left_move self.moves['Right1'] = self.is_right_move self.moves['Up1'] = self.is_up_move self.moves['Down1'] = self.is_down_move self.moves['Left2'] = self.is_left_move self.moves['Right2'] = self.is_right_move self.moves['Up2'] = self.is_up_move self.moves['Down2'] = self.is_down_move self.movesDict1 = {} self.movesDict2 = {} self.movesDict1['Left1'] = self.left_move self.movesDict1['Right1'] = self.right_move self.movesDict1['Up1'] = self.up_move self.movesDict1['Down1'] = self.down_move self.movesDict2['Left2'] = self.left_move self.movesDict2['Right2'] = self.right_move self.movesDict2['Up2'] = self.up_move self.movesDict2['Down2'] = self.down_move def random_create1(self): while True: i, j = random.randint(0, self.height - 1), random.randint(0, self.width - 1) if self.field1[i][j] == 0: self.field1[i][j] = random.choice([2, 2, 2, 4]) break def random_create2(self): while True: i, j = random.randint(0, self.height - 1), random.randint(0, self.width - 1) if self.field2[i][j] == 0: self.field2[i][j] = random.choice([2, 2, 2, 4]) break def reset(self): self.field1 = [[0 for j in range(self.width)] for i in range(self.height)] self.score1 = 0 self.field2 = [[0 for j in range(self.width)] for i in range(self.height)] self.score2 = 0 self.random_create1() self.random_create1() self.random_create2() self.random_create2() def draw(self, stdscr): stdscr.clear() self.score1 = sum(chain(*self.field1)) self.score2 = sum(chain(*self.field2)) if max(self.score1, self.score2) > self.highscore: self.highscore = max(self.score1, self.score2) stdscr.addstr('最高分:' + str(self.highscore) + ' ') stdscr.addstr('玩家1分數:' + str(self.score1) + ' ') stdscr.addstr('玩家2分數:' + str(self.score2) + '\n') for row in self.field1: stdscr.addstr('+' + '-----+' * self.width + '\n') stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "| " for num in row) + '|' + '\n') stdscr.addstr('+' + '-----+' * self.width + '\n') if self.is_win1(): stdscr.addstr('勝利\n') if self.is_gameover1(): stdscr.addstr('游戲結束\n') for row in self.field2: stdscr.addstr('+' + '-----+' * self.width + '\n') stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "| " for num in row) + '|' + '\n') stdscr.addstr('+' + '-----+' * self.width + '\n') if self.is_win2(): stdscr.addstr('勝利\n') if self.is_gameover2(): stdscr.addstr('游戲結束\n') stdscr.addstr("玩家1:上下左右鍵 玩家2:wasd鍵(R)重置(Q)退出") def is_win1(self): return max(chain(*self.field1)) >= self.win_value def is_win2(self): return max(chain(*self.field2)) >= self.win_value def is_gameover1(self): return not any([self.is_move_possible1(direction) for direction in self.moves]) def is_gameover2(self): return not any([self.is_move_possible2(direction) for direction in self.moves]) @staticmethod def invert(field): return [row[::-1] for row in field] @staticmethod def transpose(field): return [list(row) for row in zip(*field)] @staticmethod def is_row_change(row): for i in range(len(row) - 1): if row[i] == 0 and row[i + 1] != 0: return True elif row[i] != 0 and row[i] == row[i + 1]: return True else: return False def is_left_move(self, field): return any([self.is_row_change(i) for i in field]) def is_right_move(self, field): return any([self.is_row_change(i) for i in self.invert(field)]) def is_up_move(self, field): return any([self.is_row_change(i) for i in self.transpose(field)]) def is_down_move(self, field): return any([self.is_row_change(i) for i in self.invert(self.transpose(field))]) def is_move_possible1(self, direction): if direction in self.moves: return self.moves[direction](self.field1) else: return False def is_move_possible2(self, direction): if direction in self.moves: return self.moves[direction](self.field2) else: return False @staticmethod def row_move(row): row = sorted(row, key=lambda x: 1 if x == 0 else 0) for i in range(len(row) - 1): if row[i] == row[i + 1]: row[i] *= 2 row[i + 1] = 0 return sorted(row, key=lambda x: 1 if x == 0 else 0) def left_move(self, field): return [self.row_move(i) for i in field] def right_move(self, field): return self.invert([self.row_move(i) for i in self.invert(field)]) def up_move(self, field): return self.transpose([self.row_move(i) for i in self.transpose(field)]) def down_move(self, field): return self.transpose(self.invert([self.row_move(i) for i in self.invert(self.transpose(field))])) def move1(self, direction): if direction in self.movesDict1 and self.is_move_possible1(direction): self.field1 = self.movesDict1[direction](self.field1) self.random_create1() return True else: return False def move2(self, direction): if direction in self.movesDict2 and self.is_move_possible2(direction): self.field2 = self.movesDict2[direction](self.field2) self.random_create2() return True else: return False def get_user_action(stdscr): action = stdscr.getch() if action == curses.KEY_UP: return 'Up1' elif action == curses.KEY_DOWN: return 'Down1' elif action == curses.KEY_LEFT: return 'Left1' elif action == curses.KEY_RIGHT: return 'Right1' elif action == ord('r'): return 'Restart' elif action == ord('q'): return 'Exit' elif action == ord('w'): return 'Up2' elif action == ord('s'): return 'Down2' elif action == ord('a'): return 'Left2' elif action == ord('d'): return 'Right2' def main(stdscr): def init(): game_field.reset() game_field.draw(stdscr) return 'Game' def game(): game_field.draw(stdscr) action = get_user_action(stdscr) if action == 'Restart': return 'Init' if action == 'Exit': return 'Exit' if action in ('Up1', 'Down1', 'Left1', 'Right1'): if game_field.move1(action): if game_field.is_win1(): return 'Win' if game_field.is_gameover1(): return 'GameOver' if action in ('Up2', 'Down2', 'Left2', 'Right2'): if game_field.move2(action): if game_field.is_win2(): return 'Win' if game_field.is_gameover2(): return 'GameOver' return 'Game' def not_game(): game_field.draw(stdscr) while True: action = get_user_action(stdscr) if action == 'Restart': return 'Init' if action == 'Exit': return 'Exit' game_field = GameField() state = 'Init' state_actions = { 'Init': init, 'Game': game, 'Win': not_game, 'GameOver': not_game } while state != 'Exit': state = state_actions[state]() curses.wrapper(main)
感謝各位的閱讀!看完上述內容,你們對用python制作2048游戲的方法大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。