Я понимаю, что обычно работает доступ к элементам в списке списков. Я знаю, что если у вас есть список L = [['a', 'b'], ['c', d'],['e', 'f']]
, вы можете получить доступ к 'a', используя L[0][0]
. Тем не менее, я не знаю, почему то же самое не работают в следующем коде линкора игры:Не удается выяснить, как переназначить элемент в списке списков в этом коде Python
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!'
Проблема возникает, когда после оценки догадки игрока, я пытаюсь переназначить «O» либо ' !» (с указанием удара) или «X» (с указанием промаха). Это должно произойти в:
elif check_correct(guess_row, guess_column):
print 'Hit!'
board[guess_row][guess_column] = '!'
и на сайте:
else:
board[guess_row][guess_column] = 'X'
print 'Sorry, you missed!'
Вместо того, что происходит, вся колонна заканчивается переподчиняемых к этому значению. Поэтому, когда игрок угадывает строку 1, столбец 1, эта догадка интерпретируется как guess_row = 0, guess_column = 0
. Я ожидаю, что новое значение поля, то, чтобы превратиться в:
[['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']]
Вместо этого он становится:
[['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']]
Это действительно странно, потому что, когда я достаю небольшие фрагменты кода и попытаться сделать именно это вещь, это прекрасно работает, но я не вижу, что мне не хватает, когда я пытаюсь сделать это как часть всего кода.
спасибо, что это сработало! Не уверен, что я понимаю, почему, хотя ... почему имеет значение, какой метод вы используете для создания оригинальной платы? Независимо от того, как была построена доска, не следует ли впоследствии менять значения в ней, работать одинаково? –
Поскольку вы создали в основном список из 5 ссылок, указывающих на одну и ту же переменную с именем 'row', * другими словами, у вас нет 5 разных строк, у вас есть одна строка, добавленная 5 раз в доску *, поэтому, когда вы внести изменения в один из них, все остальные будут затронуты, поскольку все они ссылаются на одно и то же. – ozgur