Reputation: 1108
I am programming a turn-based strategy, like Fire Emblem, game in Python using pygame, but I am running into a problem with movement of players. The way that it works is that you select a player and it will show you all allowed moves highlighted in Blue, but my problem is that I am having a problem coming up with a list for all possible moves.
def showPerson(tilex, tiley, personAtTile):
global ALLOWEDMOVES
ALLOWEDMOVES = []
prepare = {k:v for v,k in PLAYERSPOSITION.items()}
z = PLAYERDISTANCE[personAtTile]
#get all coords for the possible moves
currentNewSpots = []
oldSpots = []
a = PLAYERSPOSITION[personAtTile][0]
b = PLAYERSPOSITION[personAtTile][1]
c = a + 1
test = findTileLetter(c, b)
if test:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = a -1
test = findTileLetter(c, b)
if test:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = b + 1
test = findTileLetter(a, c)
if test:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
c = b - 1
test = findTileLetter(a, c)
if test:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
for x in range(PLAYERDISTANCE[prepare[(tilex, tiley)]]):
for y in range(len(currentNewSpots) - 1):
a = currentNewSpots[y][0]
b = currentNewSpots[y][1]
c = a + 1
test = findTileLetter(c, b)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = a -1
test = findTileLetter(c, b)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = b + 1
test = findTileLetter(a, c)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
c = b - 1
test = findTileLetter(a, c)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
Upvotes: 0
Views: 1453
Reputation: 3736
Because I don't know what you have in mind, I'll proceed under the following assumptions:
findTileLetter(x, y)
tells me if the square at (x, y)
is passable. That is, it tells me if a unit could pass through or end their turn on that square.PLAYERDISTANCE[unit] + 1
times per turn. Each step can be taken up, down, left, or right. Diagonal steps are not allowed, but instead must be accomplished by stepping e.g. left and up.With that in mind, we note that on the line
for y in range(len(currentNewSpots) - 1):
you iterate over one fewer element of currentNewSpots
than you should, and thus every x
loop you omit stepping from the element in currentNewSpots
that was added last in the preceding x
loop. Hence you leave out potential destination squares.
Changing the line to
for y in range(len(currentNewSpots))
fixes this issue.
Additionally, your delta-y tests in the y
loop are not quite right:
c = b + 1
test = findTileLetter(a, c)
if test and ((c, b)) not in ALLOWEDMOVES: ### <--- should be (a, c)
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
Blob of working test code follows. The grid
defines a world of tiles: 0
tiles are impassable, while 1
tiles are passable. The MY_X
and MY_Y
define where we're searching from. After every step, we output the map to stdout, illustrating which squares we've found so far.
import sys
MY_X = 3
MY_Y = 4
MY_RNG = 2
grid = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 0, 1, 1, 0, 0, 1],
[0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
def findTileLetter(x, y):
return grid[y][x]
class Person:
pass
def showMap():
for y in range(len(grid)):
for x in range(len(grid[y])):
if grid[y][x] == 0:
sys.stdout.write(' ')
elif x == MY_X and y == MY_Y:
sys.stdout.write('x')
elif (x, y) in ALLOWEDMOVES:
sys.stdout.write('o')
else:
sys.stdout.write('-')
sys.stdout.write('\n')
me = Person()
ALLOWEDMOVES = []
PLAYERDISTANCE = {}
PLAYERDISTANCE[me] = MY_RNG
PLAYERSPOSITION = {}
PLAYERSPOSITION[me] = (MY_X, MY_Y)
def showPerson(tilex, tiley, personAtTile):
global ALLOWEDMOVES
ALLOWEDMOVES = []
prepare = {k:v for v,k in PLAYERSPOSITION.items()}
z = PLAYERDISTANCE[personAtTile]
#get all coords for the possible moves
currentNewSpots = []
oldSpots = []
a = PLAYERSPOSITION[personAtTile][0]
b = PLAYERSPOSITION[personAtTile][1]
c = a + 1
test = findTileLetter(c, b)
if test:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = a -1
test = findTileLetter(c, b)
if test:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = b + 1
test = findTileLetter(a, c)
if test:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
c = b - 1
test = findTileLetter(a, c)
if test:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
showMap()
for x in range(PLAYERDISTANCE[prepare[(tilex, tiley)]]):
for y in range(len(currentNewSpots)):
a = currentNewSpots[y][0]
b = currentNewSpots[y][1]
c = a + 1
test = findTileLetter(c, b)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = a - 1
test = findTileLetter(c, b)
if test and ((c, b)) not in ALLOWEDMOVES:
currentNewSpots.append((c, b))
ALLOWEDMOVES.append((c, b))
c = b + 1
test = findTileLetter(a, c)
if test and ((a, c)) not in ALLOWEDMOVES:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
c = b - 1
test = findTileLetter(a, c)
if test and ((a, c)) not in ALLOWEDMOVES:
currentNewSpots.append((a, c))
ALLOWEDMOVES.append((a, c))
showMap()
showPerson(MY_X, MY_Y, me)
print ALLOWEDMOVES
Upvotes: 1