Reputation: 23
I'm trying to make a chess game, I'm watching a tutorial of 2021 using Python 3.9. I'm using 3.10 and maybe thats the reason thats not working. Anyways, let me show you the code:
import pygame as p
import Engine
WIDTH = HEIGHT = 512
DIMENSION = 8 # Las dimensiones del tablero son 8x8
SQ_SIZE = HEIGHT // DIMENSION
MAX_FPS = 15 # Para las animaciones
IMAGES = {}
def loadImages():
pieces = ["bR", "bN", "bB", "bQ", "bK", "wR", "wN", "wB", "wQ", "wK"]
for piece in pieces:
IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQ_SIZE, SQ_SIZE))
# Nota: Podemos acceder a una imagen diciendo "IMAGES[pieza]"
def main():
p.init()
screen = p.display.set_mode((WIDTH, HEIGHT))
clock = p.time.Clock()
screen.fill(p.Color("white"))
gs = Engine.GameState()
print(gs.board)
loadImages() # Solo hazlo una vez, antes del loop
running = True
while running:
for e in p.event.get():
if e.type == p.QUIT:
running = False
drawGameState(screen, gs)
clock.tick(MAX_FPS)
p.display.flip()
def drawGameState(screen, gs):
drawBoard(screen) # Dibuja los cuadrados del tablero
# Pon que se puedan marcar algunas piezas (despues)
drawPieces(screen, gs.board) # Dibuja las piezas encima de los cuadrados
def drawBoard(screen):
colors = [p.Color("#f0d9b5"), p.Color("#b58863")]
for r in range(DIMENSION):
for c in range(DIMENSION):
color = colors[((r+c) % 2)]
p.draw.rect(screen, color, p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
def drawPieces(screen, board):
for r in range(DIMENSION):
for c in range(DIMENSION):
piece = board[[r][c]]
if piece != "--": # No es un cuadrado vacío
screen.blit(IMAGES[piece], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
if __name__ == "__main__":
main()
Thats the main file, and here's the engine file:
class GameState():
def __init__(self):
# El tablero es una lista 2D de 8x8, cada elemento tiene 2 caracteres
# El primero caracter representa el color, ya sea "w" para blanco o "b" para negro
# El segundo caracter representra la figura ya sea "R" para torre, "N" para caballo, "B" para alfil, "Q" para reyna, "K" para rey y "P" para peon
# "--" Representa un espacio vacio
self.board = [
["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
["bP", "bP", "bP", "bP", "bP", "bP"," bP", "bP"],
["--", "--", "--", "--", "--", "--", "--", "--"],
["--", "--", "--", "--", "--", "--", "--", "--"],
["--", "--", "--", "--", "--", "--", "--", "--"],
["--", "--", "--", "--", "--", "--", "--", "--"],
["wP", "wP", "wP", "wP", "wP", "wP"," wP", "wP"],
["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]]
self.whiteToMove = True
self.moveLog = []
The error is on line 54:
screen.blit(IMAGES[piece], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
TypeError: unhashable type: 'list'
The code is exactly the same as in the tutorial. Sorry if I don't understand many things, I'm relatively new in Python.
Upvotes: 0
Views: 382
Reputation: 1054
The error message comes down to that you were using piece
, which is a List, to index the IMAGES
dictionary, in the line IMAGES[piece] = ...
. Unhashasble mutable data type like "List" can't be used as a dictionary key, so Python errors out.
The deeper bug where the error message stems from is in your drawPieces
function, where you are using board[[r][c]]
, which is wrong. Fix it by changing to piece = board[r][c]
. When doing double indexing, you do not need to wrap in another square bracket (In fact, it is logically wrong to do that). Kindly refer to this article for more info on how to index a 2d Array (since your board
variable is a 2d array)
The reason why board[[r][c]]
is wrong is because:
[r][c]
[r][c]
to one single value. So Python will read it as "The list [r] (list of one element r
) at index c
". For example, when r = 0 and c = 0 --> [0][0]
--> is going to be equivalent tolist_of_one_elem = [0]
value_at_index_0 = list_of_one_elem[0] # --> value = [0][0] = 0
Therefore, eventually [r][c]
, if not index out of range, will returns an Integer
[r][c] -> [0][0] -> 0
, Python evaluation will become board[[r][c]] --> board[0]
piece = board[0]
is a LIST, because the 0th index of variable board
is the list ["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"]
IMAGES[piece]
. IMAGES
is a dictionary, so IMAGES[piece]
means you were trying to use piece
as a key to this IMAGES
dictionary. However, list
is not hashable, thus can't be used as a dictionary key, so Python errors out. The rule is only immutable data types can be used as dictionary keys, like string, tuple, integer, etc.Case in point, when doing multiple indexing, just use board[1][2][3]
, no need to wrap the indexes in another big bracket pair (unless you have very specific special logic)
Upvotes: 2