如何用 Python 写出简单的 2048 小遊戏
大家好,我是一个喜欢研究算法、机械学习和生物计算的小青年,我的CSDN博客是:一骑代码走天涯 如果您喜欢我的笔记,那么请点一下关注、点赞和收藏。如果内容有错或者有改进的空间,也可以在评论让我知道。😄
平时工作太忙,为了舒缓下身心,有空的时候我就会写些杂七杂八的东西😂一方面可以放空下自己的,另一方面顺便训练下自己的写代码能力👨🏻?💻。
下面是我之前自己用 Python3 复现了一个之前挺火的小游戏 — 2048。因为只是纯粹觉得有趣才写,没有考虑复杂度的问题,也没有用多余的 Python packages来辅助 (只用了Python3 自己的 built-in packages),所以美观和算法上不怎麽好,勿见怪。
接下来,介绍一下这个程序的整个构成:
1. 大纲
整个程序其实就是一个 Class 物件,不需要其它参数,只需要定义Class 方法就能运行。
整个程序的大纲如下 (细节后面会讲):
class Playboard2048:
def __init__(self):
self.row = 4
self.col = 4
self.field = [[0 for c in range(self.col)] for r in range(self.row)]
def __generate_number(self)
def __check_stuck(self)
def get_maximum(self)
def show(self)
def move_left(self)
def move_up(self)
def move_right(self)
def move_down(self)
def play(self)
game = Playboard2048()
game.play()
2. 准备遊戏
代码里有两个物件方法直接与遊戏运行相关,分別是show(self) 和play(self) 。
show(self) 是用来显示2048的遊戏数格,把数格里面的 "0"换成空格,以便辨认哪儿是可以移动的方向。
def show(self):
for r in range(self.row):
temp = self.field[r].copy()
for i in range(len(temp)):
if temp[i] == 0:
temp[i] = " "
print(temp)
play(self) 用是用来初始化遊戏和管理遊戏进行时的控制。
def play(self):
exit_ = False
stuck_ = False
step = ""
print("Generating a playboard...")
while not exit_ and not stuck_:
step = ""
stuck_ = self.__check_stuck()
if stuck_:
self.show()
print("Game over! You are stuck.")
return
self.__generate_number()
self.show()
while step == "":
step = input("Your step (Up/Down/Left/Right/Exit): ")
step = step.lower()
if step == "exit":
print("Thanks for playing, now ending...")
return
print(step)
if step != "up" and step != "down" and step != "left" and step != "right":
step = ""
print("Only Up/Down/Left/Right/Exit is accepted... please re-input: ")
if step == "left":
self.move_left()
elif step == "right":
self.move_right()
elif step == "up":
self.move_up()
elif step == "down":
self.move_down()
max_ = self.get_maximum()
if max_ == 2048:
self.show()
print("You win!!!")
return
3. 移动数字
在平时我们玩的 2048 遊戏中,每个回合玩家都可以选择把数字往上、下、左、右四个方向其中一个推。只要该方向还有空位,数字就可以往该方向。
下面用 往左移动做一個例子,另外三个写法大同小异:
def move_left(self):
for r in range(self.row):
diff = 0
for c in range(self.col):
if self.field[r][c] == 0:
diff += 1
elif self.field[r][c] != 0 and diff > 0:
self.field[r][c - diff] = self.field[r][c]
self.field[r][c] = 0
for r in range(self.row):
for c in range(1, self.col):
if self.field[r][c] == self.field[r][c - 1] and c != 0:
self.field[r][c - 1] += self.field[r][c]
self.field[r][c] = 0
if self.field[r][c - 1] == 0:
self.field[r][c - 1] = self.field[r][c]
self.field[r][c] = 0
4. 数字生成 & 系统检查
这段代码远用了random 和math 的built-in packages,可以让系统在任意空格中隨机生成数字
p.s.: 生成数字的计算方法是我自己想出来的,效果未必很好。
def __generate_number(self):
import random
import math
empty = []
for r in range(self.row):
for c in range(self.col):
if self.field[r][c] == 0:
empty.append([r, c])
[picked_r, picked_c] = random.choice(empty)
max_ = 0
for r in range(self.row):
if max_ <= max(self.field[r]):
max_ = max(self.field[r])
self.field[picked_r][picked_c] = 2**(max(0, int(math.log(max_ + 0.00000001, 2)) - 1))
当然,这遊戏是有机会死局的,所以每个回合都要检查数格上还有没有空格子给玩家移动。如果四个方向没有,那就返回 stuck = True 。
def __check_stuck(self):
stuck = True
for r in range(self.row):
for c in range(self.col):
current = self.field[r][c]
if 0 <= r < self.row - 1:
if current == self.field[r + 1][c]:
stuck = False
if 0 < r <= self.row - 1:
if current == self.field[r - 1][c]:
stuck = False
if 0 <= c < self.col - 1:
if current == self.field[r][c + 1]:
stuck = False
if 0 < c <= self.col - 1:
if current == self.field[r][c - 1]:
stuck = False
return stuck
5. 玩遊戏
最后,所有代码都写好的话,保存成Python 文件 (.py)。如果在 Linux,可以直接用 python3 -i 這类工具在terminal运行;在Windows也很简单 只要系统里有Python,双击2048.py文件就能进入遊戏。
源代码可Github上下载/参考:https://github.com/6x16/Little-games
|