Dictionary Referencing - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Dictionary Referencing (/thread-35588.html) |
Dictionary Referencing - nickdavis2017 - Nov-19-2021 Hi all, I'm writing a pretty rudimentary code that essentially plays chess with itself. Dictionaries are the data types used to contain all of the data about each individual piece. I have only programmed the movement of pawns this far. I've been using functions for most of the content but I'm having an issue with one of the functions referencing a dictionary. I'm trying to reference an input from the function using an if statement, but the function simply skips over it and executes the else statement. Attached below is the chess code and subsequent UDF code. The code below is the function causing issues. P.S. I am interested in hearing any good advice on optimizing the code as it is. Thanks. def pawn(board,color,which): if color == white: nr = -1 spot = 'W_pawn' else: nr = 1 spot = 'B_pawn' # empty current pos board[color['Pawns']['Pawn %s' %(which)]['Row'],color['Pawns']['Pawn %s' %(which)]['Column']] = '' # edit row value in dictionary color['Pawns']['Pawn %s' %(which)]['Row'] += nr # update new pos in board board[color['Pawns']['Pawn %s' %(which)]['Row'],color['Pawns']['Pawn %s' %(which)]['Column']] = spot return board,color RE: Dictionary Referencing - deanhystad - Nov-20-2021 Obviously color is never white. What is white? The only place I see white defined is here: # White Dictionary ------------------------------------------------------------ def white():if color == some function seems odd. Did you mean to do this? if color == "white":You are trying to make dictionaries do what classes do much better. This does somewhat the same thing you were doing using classes instead of dictionaries. To show how subclassing works I gave each chess piece a method that will return a list of available moves for the piece. The way the list is constructed is different for pawns than rooks or bishops or knights, so subclassing lets me use a different algorithm for each piece. from numpy import genfromtxt BLACK = 0 WHITE = 1 class Piece: '''Base class for chess pieces''' all_pieces = [] # List of all chess pieces black_pieces = [] # List of all black chess pieces white_pieces = [] # List of all white chess pieces @classmethod def find(cls, row, column): '''Return piece at row, column or None if no piece found''' for piece in cls.all_pieces: if piece.row == row and piece.column == column: return piece return None @classmethod def isempty(cls, row, column): '''Return True if square[row, board] is empty, else False''' return cls.find(row, column) is None @classmethod def iscolor(cls, row, column, color): '''Return True if square[row, column] contains a piece of color''' piece = cls.find(row, column) if piece and piece.color == color: return True return False @classmethod def isopen(cls, row, column, color): '''Return True if square[row, column] is empty or contains a piece of color''' piece = cls.find(row, column) return piece is None or piece.color == color def __init__(self, color, row, column): self.color = color self.moves = [] self.move(row, column) self.taken = False self.all_pieces.append(self) if color == BLACK: self.black_pieces.append(self) else: self.white_pieces.append(self) def __str__(self): '''Return string representation of piece''' color = ("Black", "White")[self.color] return f"{color} {self.__class__.__name__} ({self.row}, {self.column})" def move(self, row, column): '''Move piece to square[row, column]''' self.row = row self.column = column self.moves.append((row, column)) class Pawn(Piece): def open_moves(self): '''Return list of available moves''' moves = [] if self.color == BLACK: if self.row == 7: return moves if self.isempty(self.row+1, self.column): moves.append((self.row+1, self.column)) if self.row == 1 and self.isempty(2, self.column) and self.isempty(3, self.column): moves.append((3, self.column)) if self.column > 0 and self.iscolor(self.row+1, self.column-1, WHITE): moves.append((self.row+1, self.column-1)) if self.column < 7 and self.iscolor(self.row+1, self.column+1, WHITE): moves.append((self.row+1, self.column+1)) else: # color == White if self.row == 0: return moves if self.isempty(self.row-1, self.column): moves.append((self.row-1, self.column)) if self.row == 6 and self.isempty(5, self.column) and self.isempty(4, self.column): moves.append((4, self.column)) if self.column > 0 and self.iscolor(self.row-1, self.column-1, BLACK): moves.append((self.row-1, self.column-1)) if self.column < 7 and self.iscolor(self.row-1, self.column+1, BLACK): moves.append((self.row-1, self.column+1)) return moves class Rook(Piece): def open_moves(self): '''Return list of available moves. Castling not supported at this time''' moves = [] color = WHITE if self.color is BLACK else BLACK for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)): for x in range(1, 9): row = self.row + dr * x col = self.column + dc * x if row < 0 or row > 7 or col < 0 or col > 7: break if self.isempty(row, col): moves.append((row, col)) elif self.iscolor(row, col, color): moves.append((row, col)) break else: break return moves class Knight(Piece): def open_moves(self): '''Return list of available moves''' moves = [] color = WHITE if self.color is BLACK else BLACK for dr, dc in ((1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)): row = self.row + dr col = self.column + dc if 0 <= row <= 7 and 0 <= col <= 7 and self.isopen(row, col, color): moves.append((row, col)) return moves class Bishop(Piece): def open_moves(self): '''Return list of available moves''' moves = [] color = WHITE if self.color is BLACK else BLACK for dr, dc in ((1, 1), (1, -1), (-1, 1), (-1, -1)): for x in range(1, 9): row = self.row + dr * x col = self.column + dc * x if row < 0 or row > 7 or col < 0 or col > 7: break if self.isempty(row, col): moves.append((row, col)) elif self.iscolor(row, col, color): moves.append((row, col)) break else: break return moves class Queen(Piece): def open_moves(self): '''Return list of available moves''' return Bishop.open_moves(self) + Rook.open_moves(self) class King(Piece): def open_moves(self): '''Return list of available moves''' moves = [] color = WHITE if self.color is BLACK else BLACK for dr, dc in ((1, 1), (1, -1), (-1, 1), (-1, -1)): row = self.row + dr col = self.column + dc if row < 0 or row > 7 or col < 0 or col > 7: break if self.isempty(row, col): moves.append((row, col)) elif self.iscolor(row, col, color): moves.append((row, col)) break else: break return moves class Player: '''Create chess pieces for a player''' def __init__(self, color=BLACK): row = 1 if color == BLACK else 6 self.pawns = [Pawn(color, row, column) for column in range(8)] row = 0 if color == BLACK else 7 self.rooks = [Rook(color, row, column) for column in (0, 7)] self.knights = [Knight(color, row, column) for column in (1, 6)] self.bishops = [Bishop(color, row, column) for column in (2, 5)] self.queen = Queen(color, row, 3) self.king = King(color, row, 4) black = Player(BLACK) white = Player(WHITE) for piece in Piece.all_pieces: print(piece, piece.open_moves()) |