brinkiepie
3/31/2016 - 8:32 AM

samDistance.py

import random
import copy
#import time

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

lightBoard = []


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

def distanceFromPlayer(startX, startY, goalX, goalY):
    global gameBoard
    cellsToCheck = []
    distances = []
    width = len(gameBoard[0])
    height = len(gameBoard)

    for y in range(height):
        distances.append([None]*width)


    def drawMap(initialY=None, initialX=None):
        for y in range(height):
            for x in range(width):
                if x == initialX and y == initialY:
                    cell = '-'
                elif x == startX and y == startY:
                    cell = '*'
                elif gameBoard[y][x] == "#":
                    cell = "#"
                else:
                    cell = distances[y][x] or '.'
                print( "%s " % cell, end='' ) 
            print()
        print("-----------------------------")

    def addSurroundedCells(initialY, initialX):
        # set distance of surrounding cells
        distance = distances[initialY][initialX]
        for y in range(-1,2):
            for x in range(-1,2):
                #if abs(x + y) == 1: # disallow diagonal movements
                if x != 0 or y != 0:
                    if gameBoard[y+initialY][x+initialX] != "#" and distances[y+initialY][x+initialX] is None:
                        cellsToCheck.append([y+initialY, x+initialX])
                        distances[y+initialY][x+initialX] = distance + 1

        # for testing
        #print(cellsToCheck)
        #drawMap(initialY, initialX)
        #time.sleep(0.5)

        # check next cell, if any
        if len(cellsToCheck) > 0:
            addSurroundedCells(*cellsToCheck.pop(0))


    # start cell checking
    distances[startY][startX] = 0
    addSurroundedCells(startY, startX)

    # draw map (for debugging)
    drawMap()

    return distances[goalY][goalX]

#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):
    #Calling globals in function
    global currentPlayerX
    global currentPlayerY
    global lightRadiusMax
    global gameBoard
    #Defining length and width of board
    width = len(gameBoard[0])
    height = len(gameBoard)

    #Ensures only empty spaces get overwritten
    if oldChar == None:
        oldChar = lightBoard[y][x]
    if lightBoard[y][x] == "#":
        return
    if lightBoard[y][x] == " ":
            oldChar = lightBoard[y][x]
    if lightBoard[y][x] == oldChar:
        #Restricts flooding to within the light radius
        if (lightRadiusMax >= abs(currentPlayerX-x)) and (lightRadiusMax >= abs(currentPlayerY-y)):
            if distanceFromPlayer(currentPlayerX,currentPlayerY,x,y) <= lightRadiusMax:
                #Change to empty space into a '.'
                lightBoard[y][x] = fillChar
                #The following if statements recursively call flood depending on the x/y values
                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)


def gameFlow():
    #Calling Globals in function
    global currentPlayerX
    global currentPlayerY
    global gameBoard
    global lightRadiusMax
    global lightBoard
    #Game Loop
    while(1):
        #Creates a copy of the gameBoard
        lightBoard = copy.deepcopy(gameBoard)
        #Calls flood
        flood(lightBoard, currentPlayerX, currentPlayerY, None, ".")
        #Gets rid of walls outside light radius
        for y,i in enumerate(lightBoard):
            for x,j in enumerate(i):
                if not (lightRadiusMax >= abs(currentPlayerX-x)) or not (lightRadiusMax >= abs(currentPlayerY-y)):
                    #print("Player X is " + str(currentPlayerX) + " and x is " + str(x))
                    #print("Player Y is " + str(currentPlayerY) + " and y is " + str(y))
                    if j == "#":
                        lightBoard[y][x] = " "
        #Places the player
        lightBoard[currentPlayerY][currentPlayerX] = "@"
        #Prints the new board
        for row in lightBoard:
                for item in row:
                    print(item,end="")
                print("")
        #Asks for movement
        moveDirection = input("What would you like to do?\nMove (N,S,E,W) or (Q)uit: ")
        moveDirection = moveDirection.lower()
        #Sets the new player position according to the input
        if moveDirection == "n":
            if gameBoard[currentPlayerY-1][currentPlayerX] == "#":
                print("Don't move into walls!")
            else:
                currentPlayerY -= 1
        if moveDirection == "s":
            if gameBoard[currentPlayerY+1][currentPlayerX] == "#":
                print("Don't move into walls!")
            else:
                currentPlayerY += 1
        if moveDirection == "e":
            if gameBoard[currentPlayerY][currentPlayerX+1] == "#":
                print("Don't move into walls!")
            else:
                currentPlayerX += 1
        if moveDirection == "w":
            if gameBoard[currentPlayerY][currentPlayerX-1] == "#":
                print("Don't move into walls!")
            else:
                currentPlayerX -= 1
        if moveDirection == "q":
            print("Thanks for playing!")
            exit(0)

def startGame():
    #Calling Globals in function
    global currentPlayerX
    global currentPlayerY
    global lightRadiusMax
    currentPlayerX = 4
    currentPlayerY = 4
    #Asks for light radius, -1 because the players position counts as 1 (assuming from the sample output)
    lightRadiusMax = int(input("Enter your light radius: "))-1
    #Avoids a negative radius
    if lightRadiusMax < 0:
        print("Please enter a light radius larger than 0")
        exit(0)
    #distanceFromPlayer(currentPlayerX, currentPlayerY, 4, 4)
    gameFlow()


startGame()