Crea una cuadrícula similar a un juego de mesa en Python

Estoy pensando en crear un juego de mesa en Python, uno que tenga una cuadrícula de espacios, cada uno con diferentes propiedades, y que pueda tener o no piezas sobre ellos. Estas piezas deben poder moverse entre espacios, aunque sujetas a varias reglas. (El ajedrez o las damas serían buenos ejemplos de lo que estoy pensando, aunque mi juego tendría reglas diferentes / más complicadas, y la cuadrícula puede no ser cuadrada, incluso si los espacios son).

Escribí una implementación Java de algo similar para una clase de estructuras de datos, utilizando una versión modificada de listas vinculadas. Pero esto es Python, así que imagino que hay una mejor manera de hacerlo (¿tal vez incluso una biblioteca?)

Dibujar un tablero de ajedrez es bastante trivial con Tkinter. Aquí hay un ejemplo muy simple:

import Tkinter as tk class GameBoard(tk.Frame): def __init__(self, parent, rows=8, columns=8, size=32, color1="white", color2="blue"): '''size is the size of a square, in pixels''' self.rows = rows self.columns = columns self.size = size self.color1 = color1 self.color2 = color2 self.pieces = {} canvas_width = columns * size canvas_height = rows * size tk.Frame.__init__(self, parent) self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0, width=canvas_width, height=canvas_height, background="bisque") self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2) # this binding will cause a refresh if the user interactively # changes the window size self.canvas.bind("", self.refresh) def addpiece(self, name, image, row=0, column=0): '''Add a piece to the playing board''' self.canvas.create_image(0,0, image=image, tags=(name, "piece"), anchor="c") self.placepiece(name, row, column) def placepiece(self, name, row, column): '''Place a piece at the given row/column''' self.pieces[name] = (row, column) x0 = (column * self.size) + int(self.size/2) y0 = (row * self.size) + int(self.size/2) self.canvas.coords(name, x0, y0) def refresh(self, event): '''Redraw the board, possibly in response to window being resized''' xsize = int((event.width-1) / self.columns) ysize = int((event.height-1) / self.rows) self.size = min(xsize, ysize) self.canvas.delete("square") color = self.color2 for row in range(self.rows): color = self.color1 if color == self.color2 else self.color2 for col in range(self.columns): x1 = (col * self.size) y1 = (row * self.size) x2 = x1 + self.size y2 = y1 + self.size self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", fill=color, tags="square") color = self.color1 if color == self.color2 else self.color2 for name in self.pieces: self.placepiece(name, self.pieces[name][0], self.pieces[name][1]) self.canvas.tag_raise("piece") self.canvas.tag_lower("square") # image comes from the silk icon set which is under a Creative Commons # license. For more information see http://www.famfamfam.com/lab/icons/silk/ imagedata = ''' R0lGODlhEAAQAOeSAKx7Fqx8F61/G62CILCJKriIHM+HALKNMNCIANKKANOMALuRK7WOVLWPV9eR ANiSANuXAN2ZAN6aAN+bAOCcAOKeANCjKOShANKnK+imAOyrAN6qSNaxPfCwAOKyJOKyJvKyANW0 R/S1APW2APW3APa4APe5APm7APm8APq8AO28Ke29LO2/LO2/L+7BM+7BNO6+Re7CMu7BOe7DNPHA P+/FOO/FO+jGS+/FQO/GO/DHPOjBdfDIPPDJQPDISPDKQPDKRPDIUPHLQ/HLRerMV/HMR/LNSOvH fvLOS/rNP/LPTvLOVe/LdfPRUfPRU/PSU/LPaPPTVPPUVfTUVvLPe/LScPTWWfTXW/TXXPTXX/XY Xu/SkvXZYPfVdfXaY/TYcfXaZPXaZvbWfvTYe/XbbvHWl/bdaPbeavvadffea/bebvffbfbdfPvb e/fgb/Pam/fgcvfgePTbnfbcl/bfivfjdvfjePbemfjelPXeoPjkePbfmvffnvbfofjlgffjkvfh nvjio/nnhvfjovjmlvzlmvrmpvrrmfzpp/zqq/vqr/zssvvvp/vvqfvvuPvvuvvwvfzzwP////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH+FUNyZWF0ZWQgd2l0aCBU aGUgR0lNUAAh+QQBCgD/ACwAAAAAEAAQAAAIzAD/CRxIsKDBfydMlBhxcGAKNIkgPTLUpcPBJIUa +VEThswfPDQKokB0yE4aMFiiOPnCJ8PAE20Y6VnTQMsUBkWAjKFyQaCJRYLcmOFipYmRHzV89Kkg kESkOme8XHmCREiOGC/2TBAowhGcAyGkKBnCwwKAFnciCAShKA4RAhyK9MAQwIMMOQ8EdhBDKMuN BQMEFPigAsoRBQM1BGLjRIiOGSxWBCmToCCMOXSW2HCBo8qWDQcvMMkzCNCbHQga/qMgAYIDBQZU yxYYEAA7 ''' if __name__ == "__main__": root = tk.Tk() board = GameBoard(root) board.pack(side="top", fill="both", expand="true", padx=4, pady=4) player1 = tk.PhotoImage(data=imagedata) board.addpiece("player1", player1, 0,0) root.mainloop() 

Puede considerar la implementación de su placa subyacente como diferentes tipos de estructuras de datos.

  1. Lista de listas – l1 = [[1,2,3], [4,5,6], [7,8,9]]
  2. Dict con los valores como lista = d1 = {a: [1,2,3], b: [4,5,6], c: [7,8,9]}
  3. Dict con teclas son coordenadas y valores que puede asignar.
  4. Como una grafica

Aquí hay un diseño de un tablero de ajedrez vacío.

 >>> chessboard = {} >>> for row in range(8): ... for col in range(8): ... chessboard[(row,col)] = 0 ... >>> 

Puedes usar cualquiera de estos y diseñar la lógica de tu juego. Para los elementos de nivel superior, puedes vincular estos objetos o elementos dentro de los spites de pygame.