我做了一个2048年游戏的复制品。这正是游戏应该如何运作的。不过,我只是想知道在哪里可以清理代码,或者提高代码的效率。
import random
board =([0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0])
def pieces_test(board):
places = find_non_zeros(board)
print(places)
def combine_numbers(board, value, new_y, new_x, del_y, del_x):
value *= 2
board[new_y][new_x] = value
board[del_y][del_x] = 0
return board
def find_zeros(board):
good_places = []
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] == 0:
good_places.append([i,j])
return good_places
def find_non_zeros(board):
good_places = []
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] != 0:
good_places.append([i,j])
return good_places
def start_of_game(board):
for i in range(2):
places = find_zeros(board)
new_coord = random.choice(places)
board[new_coord[0]][new_coord[1]] = 2
return board
def move_left(board):
not_left = True
unusable_pieces = []
while not_left:
not_left = False
pieces_positions = find_non_zeros(board)
#pieces_positions = [[piece1_y, piece1_x],[piece2_y, piece2_x]...]
for i in range(len(pieces_positions)):
if pieces_positions[i][1] != 0:
if board[pieces_positions[i][0]][pieces_positions[i][1]-1] == 0:
if [pieces_positions[i][0],pieces_positions[i][1]] in unusable_pieces:
index_value = unusable_pieces.index([pieces_positions[i][0],pieces_positions[i][1]])
unusable_pieces[index_value][1] -= 1
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
board[pieces_positions[i][0]][pieces_positions[i][1]-1] = value
board[pieces_positions[i][0]][pieces_positions[i][1]] = 0
not_left = True
elif board[pieces_positions[i][0]][pieces_positions[i][1]-1] == board[pieces_positions[i][0]][pieces_positions[i][1]]:
if [pieces_positions[i][0],pieces_positions[i][1]] not in unusable_pieces:
if [pieces_positions[i][0], pieces_positions[i][1]-1] not in unusable_pieces:
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
combine_numbers(board, value, pieces_positions[i][0], pieces_positions[i][1]-1, pieces_positions[i][0], pieces_positions[i][1])
unusable_pieces.append([pieces_positions[i][0], pieces_positions[i][1]-1])
not_left = True
# combine_numbers(board, value_of_board_pieces, new_y, new_x, del_y, del_x)
return board
def move_right(board):
not_right = True
unusable_pieces = []
while not_right:
not_right = False
pieces_positions = find_non_zeros(board)
pieces_positions = pieces_positions[::-1]
#pieces_positions = [[piece1_y, piece1_x],[piece2_y, piece2_x]...]
for i in range(len(pieces_positions)):
if pieces_positions[i][1] != 3:
if board[pieces_positions[i][0]][pieces_positions[i][1]+1] == 0:
if [pieces_positions[i][0],pieces_positions[i][1]] in unusable_pieces:
index_value = unusable_pieces.index([pieces_positions[i][0],pieces_positions[i][1]])
unusable_pieces[index_value][1] += 1
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
board[pieces_positions[i][0]][pieces_positions[i][1]+1] = value
board[pieces_positions[i][0]][pieces_positions[i][1]] = 0
not_right = True
elif board[pieces_positions[i][0]][pieces_positions[i][1]+1] == board[pieces_positions[i][0]][pieces_positions[i][1]]:
if [pieces_positions[i][0],pieces_positions[i][1]] not in unusable_pieces:
if [pieces_positions[i][0], pieces_positions[i][1]+1] not in unusable_pieces:
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
combine_numbers(board, value, pieces_positions[i][0], pieces_positions[i][1]+1, pieces_positions[i][0], pieces_positions[i][1])
unusable_pieces.append([pieces_positions[i][0], pieces_positions[i][1]+1])
not_right = True
return board
def move_up(board):
not_up = True
unusable_pieces = []
while not_up:
not_up = False
pieces_positions = find_non_zeros(board)
#pieces_positions = [[piece1_y, piece1_x],[piece2_y, piece2_x]...]
for i in range(len(pieces_positions)):
if pieces_positions[i][0] != 0:
if board[pieces_positions[i][0]-1][pieces_positions[i][1]] == 0:
if [pieces_positions[i][0],pieces_positions[i][1]] in unusable_pieces:
index_value = unusable_pieces.index([pieces_positions[i][0],pieces_positions[i][1]])
unusable_pieces[index_value][0] -= 1
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
board[pieces_positions[i][0]-1][pieces_positions[i][1]] = value
board[pieces_positions[i][0]][pieces_positions[i][1]] = 0
not_up = True
elif board[pieces_positions[i][0]-1][pieces_positions[i][1]] == board[pieces_positions[i][0]][pieces_positions[i][1]]:
if [pieces_positions[i][0],pieces_positions[i][1]] not in unusable_pieces:
if [pieces_positions[i][0]-1, pieces_positions[i][1]] not in unusable_pieces:
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
combine_numbers(board, value, pieces_positions[i][0]-1, pieces_positions[i][1], pieces_positions[i][0], pieces_positions[i][1])
unusable_pieces.append([pieces_positions[i][0]-1, pieces_positions[i][1]])
not_up = True
return board
def move_down(board):
not_down = True
unusable_pieces = []
while not_down:
not_down = False
pieces_positions = find_non_zeros(board)
pieces_positions = pieces_positions[::-1]
#pieces_positions = [[piece1_y, piece1_x],[piece2_y, piece2_x]...]
for i in range(len(pieces_positions)):
if pieces_positions[i][0] != 3:
if board[pieces_positions[i][0]+1][pieces_positions[i][1]] == 0:
if [pieces_positions[i][0],pieces_positions[i][1]] in unusable_pieces:
index_value = unusable_pieces.index([pieces_positions[i][0],pieces_positions[i][1]])
unusable_pieces[index_value][0] += 1
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
board[pieces_positions[i][0]+1][pieces_positions[i][1]] = value
board[pieces_positions[i][0]][pieces_positions[i][1]] = 0
not_down = True
elif board[pieces_positions[i][0]+1][pieces_positions[i][1]] == board[pieces_positions[i][0]][pieces_positions[i][1]]:
if [pieces_positions[i][0],pieces_positions[i][1]] not in unusable_pieces:
if [pieces_positions[i][0]+1, pieces_positions[i][1]] not in unusable_pieces:
value = board[pieces_positions[i][0]][pieces_positions[i][1]]
combine_numbers(board, value, pieces_positions[i][0]+1, pieces_positions[i][1], pieces_positions[i][0], pieces_positions[i][1])
unusable_pieces.append([pieces_positions[i][0]+1, pieces_positions[i][1]])
not_down = True
return board
def add_piece(board):
free_spots = find_zeros(board)
chosen_spot = random.choice(free_spots)
board[chosen_spot[0]][chosen_spot[1]] = 2
return board
def main(board):
board = start_of_game(board)
game_finished= False
while game_finished == False:
if find_zeros(board) == []:
game_finished = True
continue
print(board[0],"\n",board[1],"\n",board[2],"\n",board[3])
move = input("do you want to move up, down, left or right")
if move == "up":
move_up(board)
if move == "down":
move_down(board)
if move == "left":
move_left(board)
if move == "right":
move_right(board)
board = add_piece(board)
main(board)发布于 2018-08-12 21:29:49
阅读时跳出来的是索引器的使用:像这样的代码片段:
if board[pieces_positions[i][0]][pieces_positions[i][1]-1] == 0:
if [pieces_positions[i][0],pieces_positions[i][1]] in unusable_pieces:
index_value = unusable_pieces.index([pieces_positions[i][0],pieces_positions[i][1]])
unusable_pieces[index_value][1] -= 1由于括号的大量使用(作为一种非正式的经验规则,如果代码在StackOverflow代码窗口中向右滚动,这是一个迹象,您应该看到如何将其收紧),因此很难阅读(因此也很难调试)。
您可以通过使用python的内置解压缩语法来消除其中的许多问题。由于pieces_positions是一个列表列表,您可以这样循环遍历它来驯服它:
for y, x in pieces_positions:
#.....现在很难读懂像
board[pieces_positions[i][0]][pieces_positions[i][1]-1]变成了
board[y][x-1]随着这一变化,您的四个主要函数看起来更加可读性:
def move_right(board):
not_right = True
unusable_pieces = []
while not_right:
not_right = False
pieces_positions = find_non_zeros(board)
pieces_positions = pieces_positions[::-1]
#pieces_positions = [[piece1_y, piece1_x],[piece2_y, piece2_x]...]
for y, x in pieces_positions:
if x != 3:
if board[y][x+1] == 0:
if [y,x] in unusable_pieces:
index_value = unusable_pieces.index([y,x])
unusable_pieces[index_value][1] += 1
value = board[y][x]
board[y][x+1] = value
board[y][x] = 0
not_right = True
elif board[y][x+1] == board[y][x]:
if [y,x] not in unusable_pieces:
if [y, x+1] not in unusable_pieces:
value = board[y][x]
combine_numbers(board, value, y, x+1, y, x)
unusable_pieces.append([y, x+1])
not_right = True
return board然而,这四种主要功能基本上都是对称的--它们只是在运动方向和极限条件上有所不同。如果您可以将它们简化为任何地方都使用的单个函数,就会更干净和更容易调试。
在这种情况下,您可以更清楚地表示移动,方法是将其视为添加到x和y值中的一对偏移量--例如,一个move(board, offset_x, offset_y)函数,而不是当前的4个。然后你可以用这样的方式概括边界:
for y, x in pieces_positions:
next_y = y + offset_y
next_x = x + offset_x
# python has a nice chained comparison that
# is great for checking a range
valid_x = -1 < next_x < 4
valid_y = -1 < next_y < 4
if not (valid_x and valid_y):
continue这样做的另一个好处是使董事会的实际变动更加明确:
if board[next_y][next_x] == 0:
if [y,x] in unusable_pieces:
index_value = unusable_pieces.index([y,x])
if offset_y = 0: # this means an x-move
unusable_pieces[index_value][1] += offset_x
else: # a y move
unusable_pieces[index_value][0] += offset_y
value = board[y][x]
board[next_y][next_x] = value
board[y][x] = 0使用解压的值而不是range()和单一的通用函数,而不是仅在两个数字位置上变化的四个函数,将使游戏更易于阅读,从而便于调试和维护。
发布于 2018-08-13 19:31:30
作为最后的回顾,我祝贺你把任务分开了,除了@the正统的观点外,如果有些事情不是一成不变的,你可以把它包装在一个列表中。
从…
([0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0])至
[[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]]因为它向代码读取器发送了错误的消息
https://codereview.stackexchange.com/questions/201515
复制相似问题