0

私は戦艦ゲームを作り直しており、空のボードを保持する SEA という定数変数があります。ただし、変数は変更されており、その理由 (または場所) がわかりません。player_board への参照によって渡されていると思われます。player_board が変更されると、SEA も変更されます。どうすればそれが起こらないようにできますか? これが私のコードです。下部に表示されるのは、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])
4

3 に答える 3

4

SEAそのメンバーはリストであり、Python のリストは変更可能です。などと言うときはplayer_radar = SEA、のコピーを作成していませんSEA。あなたはそれへの新しい参照を作成しています。その後に行った変更は、player_radarに反映されSEAます。

copy.deepcopyネストされた変更可能なデータ構造を再帰的にコピーするためによく使用されます。ただし、個人的には、必要になるとわかっているレイヤーの数だけをコピーすることを好みます。たとえば、リストのリストとそのすべてのメンバーのコピーを作成するには、次のようにします。

player_radar = [sublist[:] for sublist in SEA]

これはリスト内包表記です。各サブリストは を使用してコピーされ[:]、それぞれの浅いコピーが作成されます。

于 2013-07-23T19:49:52.577 に答える
1

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-23T19:49:25.247 に答える
0

Python 変数は物の名前であり、物を置く場所ではありません。

player_radar = SEA

たとえば、C++ の場合のようにplayer_radar、 のコピーを作成しません。SEAむしろ、player_radarSEAは両方とも同じリスト オブジェクトの名前です。を変更すると、 、および同じオブジェクトを参照する他のすべての変数にplayer_radar変更が表示されます。SEA

于 2013-07-23T19:52:50.627 に答える