TransWikia.com

TypeError no Python, preciso modificar um string

Stack Overflow em Português Asked by Ezequiel on November 5, 2021

Estou fazendo um tabuleiro de xadrez bem simples sem nenhum regra, apenas modifico as posições para jogar.
Fiz um lista com as casa disponíveis no tabuleiro e com a função mover eu altero as posições,enfim, ainda ta bem simples. o problema é que eu não consigo alterar a posição anterior para uma vazia, evitando que as peças se dupliquem.
recebo o erro:

boardnumFrom[positionFrom] = '[]'
TypeError: 'str' object does not support item assignment 

preciso definir as posições de saída da peça para uma casa vazia e não sei como.
Codigo do tabuleiro:

board8 = {
    'a8': [], 'b8': [], 'c8': [], 'd8': [], 'e8': [], 'f8': [], 'g8': [], 'h8': []
}
board7 = {
    'a7': [], 'b7': [], 'c7': [], 'd7': [], 'e7': [], 'f7': [], 'g7': [], 'h7': []
}
board6 = {
    'a6': [], 'b6': [], 'c6': [], 'd6': [], 'e6': [], 'f6': [], 'g6': [], 'h6': []
}
board5 = {
    'a5': [], 'b5': [], 'c5': [], 'd5': [], 'e5': [], 'f5': [], 'g5': [], 'h5': []
}
board4 = {
    'a4': [], 'b4': [], 'c4': [], 'd4': [], 'e4': [], 'f4': [], 'g4': [], 'h4': []
}
board3 = {
    'a3': [], 'b3': [], 'c3': [], 'd3': [], 'e3': [], 'f3': [], 'g3': [], 'h3': []
}
board2 = {
    'a2': [], 'b2': [], 'c2': [], 'd2': [], 'e2': [], 'f2': [], 'g2': [], 'h2': []
}
board1 = {
    'a1': [], 'b1': [], 'c1': [], 'd1': [], 'e1': [], 'f1': [], 'g1': [], 'h1': []
}


def setBoard():
    # white
    board1['a1'] = 'T'
    board1['b1'] = 'B'
    board1['c1'] = 'N'
    board1['d1'] = 'Q'
    board1['e1'] = 'K'
    board1['f1'] = 'N'
    board1['g1'] = 'B'
    board1['h1'] = 'T'
    board2['a2'] = 'P'
    board2['b2'] = 'P'
    board2['c2'] = 'P'
    board2['d2'] = 'P'
    board2['e2'] = 'P'
    board2['f2'] = 'P'
    board2['g2'] = 'P'
    board2['h2'] = 'P'
    # black
    board8['a8'] = 'T'
    board8['b8'] = 'B'
    board8['c8'] = 'N'
    board8['d8'] = 'K'
    board8['e8'] = 'Q'
    board8['f8'] = 'N'
    board8['g8'] = 'B'
    board8['h8'] = 'T'
    board7['a7'] = 'P'
    board7['b7'] = 'P'
    board7['c7'] = 'P'
    board7['d7'] = 'P'
    board7['e7'] = 'P'
    board7['f7'] = 'P'
    board7['g7'] = 'P'
    board7['h7'] = 'P'

while True:

    def mover(boardnumFrom, boardnumTo, positionFrom, positionTo):
        boardnumFrom[positionFrom] = '[]'
        boardnumTo[positionTo] = piece


    def start():
        setBoard()
        print(board8)
        print(board7)
        print(board6)
        print(board5)
        print(board4)
        print(board3)
        print(board2)
        print(board1)


    start()
    piece = input("""
Digite 'sair' ou digite 
Qual peça deseja mover? 
>""")
    if (piece == 'sair'):
        print('Adeus, obrigado por jogar.')
        break
    else:
        boardnumFrom = input('Qual fileira voce esta? ')
        boardnumTo = input('Para qual fileira voce vai? ')
        positionFrom = input('Qual casa voce esta? ')
        positionTo = input('Para qual casa voce vai? ')
        mover(boardnumFrom, boardnumTo, positionFrom, positionTo)

é grande mas é bem simples.

One Answer

Ao fazer:

boardnumFrom = input('Qual fileira voce esta? ')

A variável boardnumFrom será uma string, pois é isso que input retorna. Depois, você passa essa string para a função mover:

mover(boardnumFrom, boardnumTo, positionFrom, positionTo)

E dentro desta função, tenta mudar uma posição desta string:

boardnumFrom[positionFrom] = '[]'

Só que em Python strings são imutáveis e você não pode mudar nenhuma posição da mesma. Qualquer tentativa de fazê-lo dará esse erro que você viu. Ex:

s = 'uma string qualquer'
s[1] = 'x' # TypeError: 'str' object does not support item assignment

Enfim, essa é a causa do erro. Dito isso, acho que você deveria rever tudo que está fazendo.

Primeiro, o tabuleiro não deveria estar dividido em 8 dicionários diferentes. Porque não usar simplemente uma lista de listas?

Além disso, para denotar uma posição vazia, você está usando [], que é uma lista vazia (e não uma string). Mas como as peças são strings, então por que não fazer a posição vazia ser uma string também? Poderia ser um espaço em branco, por exemplo (' '). Ficaria assim:

def setBoard():
    def peoes():
        return ['P'] * 8
    def pecas(): # desculpe, não sei se essa fileira tem um nome específico
        return ['T', 'N', 'B', 'Q', 'K', 'B', 'N', 'T']

    # tabuleiro 8 x 8: é uma lista com 8 elementos, sendo que cada elemento é uma lista com 8 espaços em branco

    # primeiro cria as 4 fileiras vazias do "meio"
    tabuleiro = [[' '] * 8 for _ in range(4)]
    # white
    tabuleiro.insert(0, pecas())
    tabuleiro.insert(1, peoes())
    # black
    tabuleiro.append(peoes())
    tabuleiro.append(pecas())
    return tabuleiro

def imprime(tabuleiro):
    def separador():
        print('+'.join(['---'] * 9))

    def letras():
        print(' ', ' | '.join(chr(ord('a') + i) for i in range(8)), sep='', end=' |n')
        separador()

    letras()
    i = 7
    while i >= 0:
        linha = tabuleiro[i]
        print(' ', ' | '.join(linha), sep='', end='')
        print(f' | {i + 1}')
        separador()
        i -= 1

def mover(tabuleiro, colunaFrom, linhaFrom, colunaTo, linhaTo):
    def converteColuna(c): # converte a-h para 0-7
        return ord(c) - ord('a')

    colOrig = converteColuna(colunaFrom)
    linOrig = int(linhaFrom) - 1
    # move a peça para a nova posição
    tabuleiro[int(linhaTo) - 1][converteColuna(colunaTo)] = tabuleiro[linOrig][colOrig]
    # deixa a posição original vazia
    tabuleiro[linOrig][colOrig] = ' '

tabuleiro = setBoard()
while True:
    imprime(tabuleiro)
    piece = input("Deseja sair? s/n > ")
    if piece == 's':
        print('Adeus, obrigado por jogar.')
        break
    else:
        colunaFrom = input('Qual coluna você está? (a-h) ')
        linhaFrom = input('Qual linha você está? (1-8) ')
        colunaTo = input('Para qual coluna você vai? (a-h) ')
        linhaTo = input('Para qual linha você vai? (1-8) ')
        mover(tabuleiro, colunaFrom, linhaFrom, colunaTo, linhaTo)

Claro que há muito o que melhorar. Eu não verifico se as posições digitadas são válidas, nem se a posição de origem tem uma peça, ou se a posição de destino já está ocupada (sem contar que precisaria verificar se o movimento é válido para a peça escolhida, e só apresentar os movimentos válidos como opções, por exemplo).

Mas só de ter o tabuleiro mais organizado, já ajuda bastante. Escolher a estrutura de dados adequada é meio caminho andado para um código melhor.

Answered by hkotsubo on November 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP