C-Love511 C-Love511 - 7 days ago 5
Python Question

Python Referencing Object Inside Object Incorrectly

I have 2 python classes: Player, and Board. The board contains a dict with "A1" reference style for spaces.

player.py's Player class:

from board import Board

class Player:
def __init__(self):
self.name = input("Name: ")
self.board = Board(3, ["A", "B", "C"])


board.py's Board class:

class Board:
EMPTY = "0"
spaces = {}
def __init__(self, size, letters):
for let in letters:
for num in range(1, size + 1):
self.spaces["{}{}".format(let, num)] = self.EMPTY

def place_piece(self, spot):
self.spaces[spot] = "X"

def display_board(self):
for let in letters:
for num in range(1, size + 1):
print("\n" + self.spaces["{}{}".format(let, num)]


When Player is instantiated, it creates a Board object inside.
2 players are created, and each is added to the list players[]. Each player's turn is selected with a simple 1/0 variable called current_player.

from player import *
from board import *

current_player = 1
players = []
player_1 = Player()
player_2 = Player()
players.append(player_1)
players.append(player_2)

while True:
# Switches players
current_player = abs(current_player - 1)

# Prints the current player's name
print(players[current_player].name)

# Calls some method which should alter the current player's board
players[current_player].board.place_piece(input("> "))

# Calls some method which should show the current player's board
players[current_player].board.show_board()


Obviously, very simplified. The name prints out correctly every single time. The board, however, only uses the first player's board for both players. I know it's working because the players' name prints correctly.

The issue persists even if the boards are created separately and placed in their own list.

What am I doing wrong?

Answer

As it is written now the code posted shouldn't be working. The two methods in Board, place_piece and display_board, need to accept 'self' as a first argument.

Assuming this is a typo here's what's happening. The class Board is created with a class member spaces. Each time you're referencing self.spaces in an object, it is not found in the object is instead looked up in the class. Meaning you're using the same dict for all object of the class Board. Instead, to create a regular member place the declaration in the init method as you do in the Player class:

class Board:
    EMPTY = "0"
    # Remove spaces = {}

    def __init__(self, size, letters):
        self.spaces = {}
        ...

Finally, since you're using Python 2x please let me encourage you to always use new style classes (i.e. write class Board(object)). See What is the difference between old style and new style classes in Python?