4

I'm writing a program that is supposed to simulate a game board made up of a row of squares. On each square, the player rolls a 3-sided die that can come up 1, 2, or 3. Based on the roll, the player moves ahead that many spaces. To simulate this, each square links to 3 other squares: the one in front of it, the next one over, and the one after that. So for example...

square 1: 
roll 1 -> square 2 ... 
roll 2 -> square 3 ...
roll 3 -> square 4

The problem is, whenever I set the links for one square, it also sets the links for all the squares. In other words, the program is acting as though the list of links is a global variable instead of a class variable. I am totally puzzled by this.

When I print out the results, this is what I expect:

Square 1: 1 -> 2 ... 2 -> 3 ... 3 -> 4 
Square 2: 1 -> 3 ... 2 -> 4 ... 3 -> 5 
Square 3: 1 -> 4 ... 2 -> 5 ... 3 -> 6 

But instead, this is what I get:

Square 1: 1 -> 2 ... 2 -> 3 ... 3 -> 4 
Square 2: 1 -> 2 ... 2 -> 3 ... 3 -> 4 
Square 3: 1 -> 2 ... 2 -> 3 ... 3 -> 4 

Here is the total code:

class Square:
    links = {}
    number = -1

    def __init__(self, num):
        self.number = num 

    def addLink(self, destination, distance):
        if(distance < 0 or distance > 3):
            print("ERROR: invalid distance " + str(distance) + " being linked from Square " + str(self.number) + " to " + str(destination.number))
            return;
        while(destination.hasJump()):
            destination = destination.getJumpDest()
        self.links[distance] = destination

    def getLink(self, n):
        return self.links[n]

    def hasJump(self):
        return 0 in self.links 

    def getJumpDest(self):
        return self.links[0]

    def printSummary(self):
        if(self.hasJump()):
            print("Square " + str(self.number) + ": 0 -> " + str(self.getJumpDest().number))
        else:
            print("Square " + str(self.number) + ":")
            if(1 in self.links):
                  print("1 -> " + str(self.getLink(1).number))
            if(2 in self.links):
                  print("2 -> " + str(self.getLink(2).number))
            if(3 in self.links):
                  print("3 -> " + str(self.getLink(3).number))

class Board:
    squares = {}
    size = 0

    def __init__(self, boardSize = 5):
        self.size = boardSize
        for n in range(boardSize, 0, -1):
            thisSquare = Square(n); 
            if(n < boardSize-1):            
               thisSquare.addLink(self.squares[(n+1)], 1)
            if(n < boardSize-2):
               thisSquare.addLink(self.squares[(n+2)], 2)
            if(n < boardSize-3):
               thisSquare.addLink(self.squares[(n+3)], 3)
            self.squares[n] = thisSquare

    def createJump(start, finish):
        self.squares[start].addLink(self.squares[finish],True)

game = Board()
for n in range(1,5):
    game.squares[n].printSummary()

I've been working on this bug for about an hour and a half now and I've concluded that either I am missing something obvious, or there is something I don't understand about class variables in Python. I would very much appreciate any assistance.

Thank you so much!

SemperCallide
  • 1,950
  • 6
  • 26
  • 42

1 Answers1

3

links seems to be a class variable, not an instance variable. You can fix that by initializing it in __init__():

def __init__(self, num):
    self.number = num
    self.links = {}
KSFT
  • 1,774
  • 11
  • 17