'''
流程思路:2048游戏
游戏规则
4*4
在空的地方随机出现2,4
操作(上下左右)
输赢
设计流程
棋盘:用一个字符串表示
棋子:矩阵 嵌套的列表来表示
操作:根据方向,操作不同行
游戏流程:
开始
初始化
生成棋子
输出棋盘
等待用户的操作
根据用户的操作计算
是否赢了
是否输了
'''
import random
class Game:
def __init__(self):
self.scores = 0 #分数
#用一个嵌套列表来表示数字方块
self.board_list=[
[' ',' ',' ',' '],
[' ',' ',' ',' '],
[' ',' ',' ',' '],
[' ',' ',' ',' '],
]
self.restart() #回调函数,初始化
self.empty_board=set([]) #空白位置
#重新
def restart(self):
self.board_list = [
[' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' '],
]
self.scores = 0
while True: #添加两个随机的数
t1 = (random.randint(0,3),random.randint(0,3))
t2 = (random.randint(0, 3), random.randint(0, 3))
if t1!=t2: #t1 t2是位置
break
self.board_list[t1[0]][t1[1]]=random.randrange(2,5,2)
self.board_list[t2[0]][t2[1]] = random.randrange(2, 5, 2)
def move(self,direct):
if direct == 'U':
pass
if direct == 'D':
pass
if direct == 'L':
pass
if direct == 'R':
pass
def move_left(self):
for i in range(4):
self.board_list[i] = self.row_left_oper(self.board_list[i])
def move_right(self):
for i in range(4):
self.board_list[i].reverse() #反向每一行
self.board_list[i] = self.row_left_oper(self.board_list[i])
self.board_list[i].reverse()
def move_up(self): #把矩阵转置zip,向左移动计算,再转置 zip
self.board_list = self.turn_left(self.board_list)
self.move_left()
self.board_list = self.turn_right(self.board_list)
def move_down(self): #把矩阵转置zip,然后翻转reverse,向左计算,再翻转,转置
self.board_list=self.turn_right(self.board_list)
self.move_left()
self.board_list = self.turn_left(self.board_list)
# 向左处理每一行
def row_left_oper(self,row):
temp = []
#先挤到一起
for item in row:
if item != ' ':
temp.append(item)
# 将相邻一样的数字合并
new_row = []
flag = True
for i in range(len(temp)):
if flag:
if i + 1 < len(temp) and temp[i] == temp[i+1]:
new_row.append(temp[i]*2)
flag = False
self.scores += temp[i]*2 # 只要有合并就会有分数
else:
new_row.append(temp[i])
else:
flag = True
# 补齐列表中的元素
n = len(new_row)
for i in range(len(row) - n):
new_row.append(' ')
return new_row
def is_win(self):
# 把所有的空位添加进去
# for i in range(len(self.board_list)):
# for j in range(len(self.board_list[i])):
# if self.board_list[i][j] == ' ':
# self.empty_position.add((i, j))
#更新空白位置
self.empty_board.clear()
for i in range(4):
for j in range(4):
if self.board_list[i][j] == 2048:
return True
elif self.board_list[i][j] == ' ':
self.empty_board.add((i,j))
# 游戏是否GAMEOVER
def is_gameover(self):
flag=True
if len(self.empty_board) == 0:
for l in self.board_list:
for i in range(len(l)-1):
if l[i]==l[i+1]:
flag=False
for l in self.turn_right(self.board_list):
for i in range(len(l)-1):
if l[i]==l[i+1]:
flag=False
else:
flag=False
return flag
def turn_right(self,matrix):
return [list(x)[::-1] for x in zip(*matrix)] #zip 把行变成列
def turn_left(self, matrix):
temp=self.turn_right(self.turn_right(matrix))
return self.turn_right(temp)
#随机增加两个棋子
def add_piece(self):
for i in range(2):
try:
temp = self.empty_board.pop()
# print(temp)
self.board_list[temp[0]][temp[1]]=random.randrange(2,5,2)
except:
break
def start(self):
while True:
self.print_game_board()
code = input('please input operate>>>>:')
if code == 'U':
self.move_up()
elif code == 'D':
self.move_down()
elif code == 'L':
self.move_left()
elif code == 'R':
self.move_right()
elif code == 'r':
self.restart()
continue
elif code == 'q':
exit('退出')
else:
print('please input right indiction')
continue
if self.is_win():
print('游戏得分%s'%self.scores)
print('恭喜你,赢的游戏!')
break
if self.is_gameover():
exit('gameover')
self.add_piece()
def print_game_board(self):
"""通过字符串格式化的话是输出棋盘"""
game_str = """
SCORE:{}
+-----+-----+-----+-----+
|{: ^5}|{: ^5}|{: ^5}|{: ^5}|
+-----+-----+-----+-----+
|{: ^5}|{: ^5}|{: ^5}|{: ^5}|
+-----+-----+-----+-----+
|{: ^5}|{: ^5}|{: ^5}|{: ^5}|
+-----+-----+-----+-----+
|{: ^5}|{: ^5}|{: ^5}|{: ^5}|
+-----+-----+-----+-----+
U(up),D(down),L(left),R(right)
r(restart),q(exit)
""".format(self.scores,
*self.board_list[0],
*self.board_list[1],
*self.board_list[2],
*self.board_list[3], )
print(game_str)
if __name__ == '__main__':
game=Game() #实例化
game.start()