classmethod
classmethod

Reputation: 53

How to identify the values of indexes around a specific array coordinate?

If I had a 2-D array, representing a world, that looked something like:

. . . . . . . . . . . . . . .
. P . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . t . . . . . . . . .
. . . . . t . . . . . . . . .
. . . . . . t . . . . . . . .
. . . . . . . t . . . . . . .
. . . . . . . t t . . . . . .
. . . . . m . . . . . . . . .
. . . . . . m m . . . . . . .
. . . . . . . . m m . . . . .
. . . . . . . . . . m . . . .
. . . . . . . . . . m . . . .
. . . . . . . . . . . m . . .
. . . . . . . . . . . . . . .

m stands for mountains, t for trees and P for Player.

Now, let's say we have a Player class that tracks the userpos or user position in an array, which is currently (1, 1):

class Player(object):
    def __init__(self, x, y, array):
        self.x = x
        self.y = y
        self.userpos = array[x][y] 

If I were to write a method inside of the Player class that deals with basic movement controls to edit the location of the P value inside of the array, how could I go about tracking the 8 tiles around the P value? For example, we can see all of the tiles around the current player userpos is all .'s.

I want to restrict the player from moving onto m tiles, being that they are mountains. It is easy to identify the current tile with the userpos variable, since the P value is only added to a string version of the map, and not the actual array. However, the issue comes from trying to move the player to a previous position. I want to be able to return the player to the nearest empty or . tile, but do not know how to decide what index inside of the array that the player should be moved to.

Is there an easier way of doing this, or would tracking the tiles around the player be the easiest way?

Upvotes: 0

Views: 95

Answers (3)

Uriel
Uriel

Reputation: 16184

Since you got the x and y and the original array, you should be able to iterate through this points with code like:

tiles_to_move = []
for i in range(x-1, x+2):
    for j in range(y-1, y+2):
         if i != x or j != y:
             if array[i][j] != 'm': # depends on how you manage your array
                 tiles_to_move.append([i, j])

and use the tiles stored in tiles_to_move to determine your next optional move.

Upvotes: 0

Morgan Saville
Morgan Saville

Reputation: 61

You can add a method to your Player class which will move a given number of steps vertically and/or horizontally. It could achieve this by calculating what the new coordinates of the Player object would be and checking the matrix at that index to make sure it's not a mountain (I'm also assuming you don't want your Player object to walk into trees).

class Player(object):

    def __init__(self, x, y, array):
        self.x = x
        self.y = y
        self.userpos = array[x][y]

        # Make a list of the different items that can block the player
        self.obstacles = ['m', 't']

    def move(self xOffset, yOffset, array):
        newX = self.x + xOffset
        newY = self.y + yOffset

        # The following two conditionals make sure that the position
        # that the player is trying to move to is within the actual
        # bounds of the array
        if 0 <= newX < len(array):
            if 0 <= newY < len(array[newX]):

                # Check if the position that the player is trying to
                # move to is not filled by an obstacle
                if array[newX][newY] not in self.obstacles:
                    self.x = newX
                    self.y = newY

Upvotes: 0

mitoRibo
mitoRibo

Reputation: 4548

I think a better solution would be to have a method which tries to move the player in the desired direction and have that method be outside the player class since the player class shouldn't know about the map (code not tested):

def try_to_move_player(direction,map,player):
    desired_x = player.x
    desired_y = player.y

    if direction == "Left":
        desired_x -= 1
    elif direction == "Right":
        desired_x += 1
    #etc

    #Prevent player from moving off map left or right
    if desired_x < 0 or desired_x > len(map): #<-- map length might not be right
        return False
    #do the same for going above or below

    #Prevent the player from moving into mountains
    if map[desired_x][desired_y] == "m":
        print "Tried to walk into a mountain"
        return False

    #After all incorrect moving is taken care of
    player.x = desired_x
    player.y = desired_y
    return True

class Player(object):
    def __init__(self, x, y, array):
        self.x = x
        self.y = y
        self.userpos = array[x][y] 

#Try to move the player left
moved_successfully = try_to_move_player("Left",map,player)
if moved_successfully:
    print "The player was moved successfully w/ an updated position"
else:
    print "The player was not moved correctly"

Upvotes: 0

Related Questions