0

I'm trying to use flood fill but only to a certain distance (including diagonals). The flood works alright (probably not perfect). But after every movement I make up/down/left/right it is supposed to redraw the board. But instead it is redrawing over the previous board and also changing the global board that is supposed to never change.

I tried a number of different ways of assigning a fresh board before calling flood but nothing seemed to change the outcome. My guess is that it has something to do with

board = gameBoard[:]

in the gameFlow() function. But I don't know why that would be. I used[:] after reading this other stack exchange post but it didn't seem to fix the issue.

Example output from the print statements I left in:

GameBoard
#########
#..     #
#..     #
#       #
#        
#       #
#       #
#       #
#########
LightBoard
#########
#..     #
#..     #
#       #
#        
#       #
#       #
#       #
#########

Only the Light Board should be changing while the Game Board stays the same.

Code:

import random

#Sample Game Board
gameBoard = [
            ["#","#","#","#","#","#","#", "#", "#"],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#"," "," "," "," "," "," ", " ", " "],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#"," "," "," "," "," "," ", " ", "#"],
            ["#","#","#","#","#","#","#", "#", "#"]
            ]

#Defining globals
currentPlayerX = -1
currentPlayerY = -1
lightRadiusMax = -1

#function flood
#Params:
#   lightBoard: array, starts off empty
#   x: int, current x position to check, starts off as players starting x
#   y: int, current y position to check, starts off as players starting y
#   oldChard: char, character to replace
#   fillChar: char, character to replace with
#Return:
#   returns the completed lightBoard
def flood(lightBoard, x, y, oldChar, fillChar):
    global currentPlayerX
    global currentPlayerY
    global lightRadiusMax
    global gameBoard
    width = len(gameBoard[0])
    height = len(gameBoard)

    if gameBoard[y][x] == " ":
            oldChar = lightBoard[y][x]
    if gameBoard[y][x] == oldChar:
        if (lightRadiusMax >= abs(currentPlayerX-x)) and (lightRadiusMax >= abs(currentPlayerY-y)):
            lightBoard[y][x] = fillChar
            if (lightRadiusMax == abs(currentPlayerX-x)) and (lightRadiusMax == abs(currentPlayerY-y)):
                flood(lightBoard, x+1, y+1, oldChar, fillChar)
            if x > 0:
                flood(lightBoard, x-1, y, oldChar, fillChar)
            if y > 0:
                flood(lightBoard, x, y-1, oldChar, fillChar)
            if x < width-1:
                flood(lightBoard, x+1, y, oldChar, fillChar)
            if y < height-1:
                flood(lightBoard, x, y+1, oldChar, fillChar)
    print("GameBoard")
    for row in gameBoard:
                for item in row:
                    print(item,end="")
                print("")
    print("LightBoard")
    for row in lightBoard:
                for item in row:
                    print(item,end="")
                print("")
    return lightBoard


def gameFlow():
    global currentPlayerX
    global currentPlayerY
    global gameBoard
    while(1):
        board = gameBoard[:]
        board = flood(board, currentPlayerX, currentPlayerY, None, ".")
        board[currentPlayerY][currentPlayerX] = "@"
        for row in board:
                for item in row:
                    print(item,end="")
                print("")
        moveDirection = input("What would you like to do?\nMove (N,S,E,W) or (Q)uit: ")
        moveDirection = moveDirection.lower()
        if moveDirection == "n":
            currentPlayerY -= 1
        if moveDirection == "s":
            currentPlayerY += 1
        if moveDirection == "e":
            currentPlayerX += 1
        if moveDirection == "w":
            currentPlayerX -= 1
        if moveDirection == "q":
            print("Thanks for playing!")
            exit(0)


def startGame():
    global currentPlayerX
    global currentPlayerY
    global lightRadiusMax
    #randXStart = random.randint(1, len(gameBoard[0])-2)
    #randYStart = random.randint(1, len(gameBoard)-2)
    currentPlayerX = 1
    currentPlayerY = 1
    print(currentPlayerX)
    print(currentPlayerY)
    lightRadiusMax = int(input("Enter your light radius: "))
    gameFlow()

startGame()

Credits to inventwithpython.com for teaching me the basics of flood fill

Community
  • 1
  • 1
canpan14
  • 1,181
  • 1
  • 14
  • 36

1 Answers1

0

I think you're looking for this, it'll make a copy of all elements, not just a copy of the reference. Tried it on your code (replacing line 70 with "board=copy.deepcopy(gameBoard)", and now the gameBoard does stay blank the first iteration.

import copy
board = copy.deepcopy(gameBoard)

Both are actually mentioned in the answer that you refer to.

joosteto
  • 198
  • 5