2015-07-26 11 views
5

Tôi hiểu rằng cách truy cập các phần tử trong danh sách các danh sách thường hoạt động. Tôi biết rằng nếu bạn có danh sách L = [['a', 'b'], ['c', d'],['e', 'f']], bạn có thể truy cập 'a' bằng cách sử dụng L[0][0]. Tuy nhiên, tôi không chắc tại sao cùng một điều không hoạt động trong mã trò chơi chiến hạm sau:Không thể tìm ra cách phân công lại một phần tử trong danh sách các danh sách trong mã Python này

from random import randint 
from random import choice 

# make a 5x5 board 
board = [] 
row = ['O']*5 
for x in range(5): 
    board.append(row) 

def print_board(): 
    for item in board: 
     print ' '.join(item) 

#check if input falls within 5x5 grid 
def check_valid(guess_row, guess_column): 
    return guess_row in range(5) and guess_column in range(5) 
#return True- is valid choice, return False- not valid choice 

#check that the input hasn't been guessed previously 
def check_repeat(guess_row, guess_column): 
    return board[guess_row][guess_column] != 'O' 
#return True- repeat, reurn False- new 

#check if input is a correct answer 
def check_correct(guess_row, guess_column): 
    return (guess_row, guess_column) == (row1, col1) or (guess_row, guess_column) == (row2, col2) 
#return True- is correct, return False- is not correct 

#place a 2-position ship 
while True: 
    #pick random place to start 
    row1 = randint(0,4) 
    col1 = randint(0,4) 
    #choose adjacent second position 
    move_direction = choice(['north', 'south', 'east', 'west']) 
    if move_direction == 'north': 
     row2 = row1 - 1 
     col2 = col1 
    elif move_direction == 'south': 
     row2 = row1 + 1 
     col2 = col1 
    elif move_direction == 'east': 
     row2 = row1 
     col2 = col1 + 1 
    else: # must be west 
     row2 = row1 
     col2 = col1 - 1 
    #check that the second position is valid, else pick new values 
    if row2 in range(5) and col2 in range(5): 
     break 
positions_left = 2 #how many points player needs to hit 
#you now have a ship at coordinates (row1, col1), (row2, col2) 

turns = 5 

#the gameflow itself: 
print 'let\'s play battleship!' 
while turns > 0: 
    print 'You have %i turns remaining.' % turns 
    print_board() 
    guess_row = int(raw_input('Guess a row: ')) - 1 #-1 to account for python 0-indexing 
    guess_column = int(raw_input('Guess a column: ')) - 1 

    if check_valid(guess_row, guess_column) == False: 
     print 'Sorry, those aren\'t valid coordinates' 
    else: #continue game if valid 
     turns -= 1 
     if check_repeat(guess_row, guess_column): #old guess 
      print 'You seem to have guessed that already.' 
      turns += 1 #don't count this turn 
     elif check_correct(guess_row, guess_column): 
      print 'Hit!' 
      board[guess_row][guess_column] = '!' 
      positions_left -= 1 
      if positions_left == 0: 
       'You sunk the battleship!' 
       turns = 0 #stops game 
      else: 
       print 'You can sink this ship in %i more hits!' % positions_left 
     else: 
      board[guess_row][guess_column] = 'X' 
      print 'Sorry, you missed!' 

Sự cố xảy ra khi sau khi đánh giá phỏng đoán của người chơi, tôi cố gắng gán lại 'O' cho một trong hai ' ! ' (cho biết một hit) hoặc 'X' (chỉ ra một miss). Điều này sẽ xảy ra tại địa chỉ:

elif check_correct(guess_row, guess_column): 
       print 'Hit!' 
       board[guess_row][guess_column] = '!' 

và tại địa chỉ:

else: 
     board[guess_row][guess_column] = 'X' 
     print 'Sorry, you missed!' 

Thay vào đó, những gì xảy ra là toàn bộ cột kết thúc lên được bố trí để giá trị đó. Vì vậy, khi người chơi đoán hàng 1, cột 1, đoán đó được hiểu là guess_row = 0, guess_column = 0. tôi mong đợi giá trị mới của hội đồng quản trị sau đó biến thành:

[['X', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O', 
'O'],['O', 'O', 'O', 'O', 'O'],['O', 'O', 'O', 'O', 'O']] 

Thay vào đó nó trở thành:

[['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 
'O'],['X', 'O', 'O', 'O', 'O'],['X', 'O', 'O', 'O', 'O']] 

Nó thực sự kỳ lạ bởi vì khi tôi kéo ra mảnh nhỏ của mã và cố gắng làm chỉ này điều đó, nó hoạt động tốt, nhưng tôi không thấy những gì tôi đang thiếu khi tôi cố gắng làm điều đó như là một phần của toàn bộ mã.

Trả lời

2

Vấn đề là bạn đang thêm cùng một biến số row tại mỗi lần lặp vào bảng của bạn. Bạn nên thêm một hàng mới thay vì như sau:

board = [] 
for _ in range(5): 
    board.append(['O'] * 5) 
+0

cảm ơn dường như hoạt động! Không chắc chắn tôi hiểu lý do tại sao mặc dù ... tại sao nó quan trọng mà phương pháp bạn sử dụng để làm cho ban đầu? Không có vấn đề làm thế nào hội đồng quản trị đã được xây dựng, không nên thay đổi các giá trị trong nó sau này về công việc theo cùng một cách? –

+0

Vì những gì bạn tạo ra về cơ bản là danh sách 5 tham chiếu trỏ đến cùng biến có tên 'hàng', * nói cách khác, bạn không có 5 hàng khác nhau, bạn có một hàng được thêm 5 lần vào bảng *, vì vậy khi bạn thực hiện một thay đổi trong một trong số họ, tất cả những người khác sẽ bị ảnh hưởng vì tất cả họ đều là những tham chiếu đến cùng một thứ. – ozgur

1

Vấn đề của bạn là ở đây:

row = ['O']*5 
for x in range(5): 
    board.append(row) 

Theo kết quả của hội đồng quản trị trên sẽ chứa tài liệu tham khảo 5 chèo, ví dụ cùng một danh sách. Vì vậy, thay đổi một subsist, sẽ thay đổi tất cả các tập tin. Bạn cần tạo bản sao của hàng, ví dụ:

for x in range(5): 
    board.append(row[:]) 

Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan