2020.06.28
- 参考:
有哪些适合新手练手的Python项目?
Python实例浅谈之八2048游戏(字符界面) - 运行环境:
- 代码
# -*- coding: utf-8 -*-
import random
class Game2048(object):
def __init__(self):
print("Welcome to the 2048 game!")
print("Input: w(up) s(down) a(left) d(right) q(quit)")
self.DIRECTIONS = ['w', 's', 'a', 'd']
self.ROW = 4
self.COL = 4
self.matrix = []
for row in range(self.ROW):
# Python random模块sample、randint、shuffle、choice随机函数概念和应用:
# https://www.cnblogs.com/dylancao/p/8202888.html
self.matrix.append([random.choice([0,0,0,0,0,2,2,4]) for col in range(self.COL)])
self.score = 0
def PrintMatrix(self):
for row in self.matrix:
for e in row:
print("\t %d" % e, end = "")
print("\n")
print("Total score: %-08d " % self.score, end = "")
self.operator = input("operator: ").lower()
def CalNextMatrix(self):
self.next_matrix = dict()
self.next_score = dict()
# 按direction对齐mlist中的数字
def align(mlist, direction):
new_list = [0 for e in mlist]
if direction == 'w' or direction == 'a':
op_list = mlist
now_index = 0
dindex = 1
else:
op_list = reversed(mlist)
now_index = len(mlist) - 1
dindex = -1
for e in op_list:
if e:
new_list[now_index] = e
now_index += dindex
return new_list
# 按direction查找mlist中相邻且相同的数字并将其相加
def addSame(mlist, direction):
is_add = False
mlen = len(mlist)
if direction == 'w' or direction == 'a':
ilist = list(range(mlen - 1))
di = 1
else:
ilist = list(reversed(range(1, mlen)))
di = -1
self.next_score[direction] = 0
for i in ilist:
if mlist[i] and mlist[i] == mlist[i + di]:
self.next_score[direction] += mlist[i]
mlist[i] *= 2
mlist[i + di] = 0
is_add = True
return is_add
############################主体部分##########################
have_next = False
mlists_w = []
for direction in self.DIRECTIONS:
# matrix是按行存储的,这里要生成按列存储的mlists
# 转换之后'w'和'a'的操作一致,'s'和'd'的操作一致
if direction == 'w':
mlists = []
for col in range(self.COL):
mlist = []
for row in self.matrix:
mlist.append(row[col])
mlists.append(mlist)
mlists_w = mlists[:]
elif direction == 's':
mlists = mlists_w[:]
else:
mlists = self.matrix[:]
# 计算变换后的矩阵
is_move = False
is_add = False
for i, mlist in enumerate(mlists):
# Python传参传什么?
# https://zhuanlan.zhihu.com/p/64628390
mlists[i] = align(mlist, direction)
is_move = is_move or (mlist != mlists[i])
is_this_add = addSame(mlists[i], direction)
is_add = is_add or is_this_add
mlists[i] = align(mlists[i], direction)
have_this_next = is_move or is_add
# 随机加一格2
if have_this_next:
have_next = True
ilist = list(range(len(mlists)))
# Python3.x中数据随机重排基本方法
# https://blog.csdn.net/jerrygaoling/article/details/79897414
random.shuffle(ilist)
is_addnew = False
for i in ilist:
if not is_addnew:
zero_indices = []
for ei, e in enumerate(mlists[i]):
if not e:
zero_indices.append(ei)
if zero_indices:
is_addnew = True
zero_pos = random.choice(zero_indices)
mlists[i][zero_pos] = 2
else:
break
# 将按列存储的mlists复原成按行存储的
if direction == 'w' or direction == 's':
tmp_mlists = []
for row in range(self.ROW):
mlist = []
for col in mlists:
mlist.append(col[row])
tmp_mlists.append(mlist)
self.next_matrix[direction] = tmp_mlists[:]
else:
self.next_matrix[direction] = mlists[:]
return have_next
def Play(self):
while self.CalNextMatrix():
self.PrintMatrix()
if self.operator == "q":
break
elif self.operator in self.DIRECTIONS:
self.matrix = self.next_matrix[self.operator][:]
self.score += self.next_score[self.operator]
else:
while self.operator not in self.DIRECTIONS + ["q"]:
print("Wrong Input! available operator: w(up) s(down) a(left) d(right) q(quit)")
self.operator = input("operator: ").lower()
if self.operator == "q":
break
if self.operator == "q":
print("Bye!")
else:
print("Can't continue.")
game = Game2048()
game.Play()