我正在重新制作我的战舰游戏,我有一个不变的变量叫做SEA,它能容纳一个空板。但是,变量正在被修改,我不知道为什么(或者在哪里)。我怀疑它是通过引用player_board传递的,当player_board被修改时,SEA也是如此。我怎么才能阻止这一切的发生?这是我的密码。你会看到,在海底我打印出海,它被修改了。
from random import randint
#Constants and globals
OCEAN = "O"
FIRE = "X"
HIT = "*"
SIZE = 10
SHIPS = [5, 4, 3, 3, 2]
player_radar = []
player_board = []
player_ships = []
ai_radar = []
ai_board = []
ai_ships = []
#Classes
class Ship(object):
def set_board(self, b):
self.ship_board = b
def edit(self, row, col, x):
self.ship_board[row][col] = x
def __repre__(self):
return self.ship_board
#Set up variables
last_ship = Ship() #Holds the last ship made in make_ship()
SEA = [] # Blank Board
for x in range(SIZE):
SEA.append([OCEAN] * SIZE)
#Functions
def print_board():
for row in range(SIZE):
print " ".join(player_radar[row]), "||" , " ".join(player_board[row])
def random_row(is_vertical, size):
if is_vertical:
return randint(0, SIZE - size)
else:
return randint(0, SIZE -1)
def random_col(is_vertical, size):
if is_vertical:
return randint(0, SIZE - 1)
else:
return randint(size-1, SIZE -1)
def exists(row, col, b): # true if ocean
if row < 0 or row >= SIZE:
return 0
elif col < 0 or col >= SIZE:
return 0
if b[row][col] == OCEAN:
return 1
else:
return 0
def make_ship(size, board):
#Find an unoccupied spot, then place ship on board
#Also put ship in last_ship
temp = []
temp = board
is_vertical = randint(0, 1) # vertical ship if true
occupied = True
while(occupied):
occupied = False
ship_row = random_row(is_vertical, size)
ship_col = random_col(is_vertical, size)
if is_vertical:
for p in range(size):
if not exists(ship_row+p, ship_col, temp):
occupied = True
else:
for p in range(size):
if not exists(ship_row, ship_col-p, temp):
occupied = True
#Place ship on boards
last_ship.set_board(SEA)
if is_vertical:
last_ship.edit(ship_row, ship_col, "^")
last_ship.edit(ship_row+size-1, ship_col, "v")
temp[ship_row][ship_col] = "^"
temp[ship_row+size-1][ship_col] = "v"
for p in range(size -2):
last_ship.edit(ship_row+p+1, ship_col, "+")
temp[ship_row+p+1][ship_col] = "+"
else:
last_ship.edit(ship_row, ship_col, ">")
last_ship.edit(ship_row, ship_col-size+1, "<")
temp[ship_row][ship_col] = ">"
temp[ship_row][ship_col-size+1] = "<"
for p in range(size -2):
last_ship.edit(ship_row, ship_col-p-1, "+")
temp[ship_row][ship_col-p-1] = "+"
return temp
# Make the boards
player_radar = SEA
player_board = SEA
ai_radar = SEA
ai_board = SEA
print_board()
for x in SHIPS:
player_board = make_ship(x, player_board)
#player_ships.append(last_ship)
#ai_board = make_ship(x, ai_board)
#ai_ships.append(last_ship)
print "Let's play Battleship!"
for row in range(SIZE):
print " ".join(SEA[row])发布于 2013-07-23 19:49:52
SEA及其成员是列表,而Python中的列表是可变的。当您说player_radar = SEA等时,您不是在复制SEA,而是在对其进行新的引用。然后对player_radar所做的任何更改都将反映在SEA中。
copy.deepcopy经常用于递归复制嵌套的可变数据结构。然而,就我个人而言,我更喜欢复制我知道我需要的层数。例如,要复制列表及其所有成员的列表,可以这样做:
player_radar = [sublist[:] for sublist in SEA]这是一个列表理解。每个子列表都是使用[:]复制的,这会使每个子列表都有一个浅拷贝。
发布于 2013-07-23 19:49:25
SEA是一份清单,所以复制一份:
player_radar = SEA[:]
player_board = SEA[:]
ai_radar = SEA[:]
ai_board = SEA[:]或者更深层次的拷贝,如果你需要的话。
编辑:所谓“更深的拷贝”,我的意思是,如果你的列表包含其他列表,那么仅仅创建一个顶级副本就会创建一个新的列表,但是它的成员将引用原始列表中相同的成员,因此要创建一个深拷贝,还需要复制这些成员的副本。
为了说明:
>>> list1 = [[1,2,3]]
>>> list2 = list1[:] # Make a shallow copy
>>> print(list1)
[[1,2,3]]
>>> print(list2)
[[1,2,3]]
>>> list2[0][0] = 4 # Also changing list1's first member, here
>>> print(list2)
[[4,2,3]]
>>> print(list1)
[[4,2,3]] # So list1 has also changed.发布于 2013-07-23 19:52:50
Python变量是事物的名称,而不是放置东西的位置。
player_radar = SEAplayer_radar并不能像SEA那样成为SEA的副本,比如C++。相反,player_radar和SEA都是同一个list对象的名称。如果更改player_radar,您将看到SEA和引用同一个对象的所有其他变量上的更改。
https://stackoverflow.com/questions/17819653
复制相似问题