Spaghetti code, not working
This commit is contained in:
parent
39b689d8f0
commit
deeba7c740
@ -10,16 +10,27 @@ from src.game.TerrainTile import TerrainTile
|
|||||||
|
|
||||||
class AutomaticMovement:
|
class AutomaticMovement:
|
||||||
|
|
||||||
def __init__(self, player, gameMap):
|
def __init__(self, player, gameMap, leftUiWidth):
|
||||||
self.map = gameMap
|
self.map = gameMap
|
||||||
self.player = player
|
self.player = player
|
||||||
self.nextMove = None
|
self.nextMove = None
|
||||||
self.movesList = None
|
self.movesList = None
|
||||||
self.actualTarget = None
|
self.actualTarget = None
|
||||||
self.moveOffset = self.player.rect.w
|
self.moveOffset = self.player.rect.w
|
||||||
|
self.leftUiWidth = leftUiWidth
|
||||||
|
self.targetCoords = None
|
||||||
|
|
||||||
|
self.testCount = 0
|
||||||
|
|
||||||
def gotoToTarget(self, target: Entity):
|
def gotoToTarget(self, target: Entity):
|
||||||
self.actualTarget = target
|
if self.actualTarget is None:
|
||||||
|
self.actualTarget = target
|
||||||
|
self.targetCoords = (self.actualTarget.rect.x - self.leftUiWidth, self.actualTarget.rect.y)
|
||||||
|
self.movesList = self.a_Star()
|
||||||
|
if self.movesList is not None:
|
||||||
|
self.nextMove = self.movesList[0]
|
||||||
|
else:
|
||||||
|
self.actualTarget = None
|
||||||
|
|
||||||
def updatePlayerCoords(self):
|
def updatePlayerCoords(self):
|
||||||
if self.actualTarget is not None:
|
if self.actualTarget is not None:
|
||||||
@ -32,50 +43,85 @@ class AutomaticMovement:
|
|||||||
self.actualTarget = None
|
self.actualTarget = None
|
||||||
|
|
||||||
def a_Star(self):
|
def a_Star(self):
|
||||||
|
self.testCount = 0
|
||||||
|
|
||||||
fringe = PriorityQueue()
|
fringe = PriorityQueue()
|
||||||
explored = []
|
explored = []
|
||||||
|
|
||||||
startingState = (self.player.x, self.player.y, self.player.rotation)
|
startingState = (self.player.rect.x - self.leftUiWidth, self.player.rect.y, self.player.rotation)
|
||||||
startingPriority = 0
|
startingPriority = 0
|
||||||
|
|
||||||
fringe.put((startingPriority, AStarNode(None, None, startingState)))
|
|
||||||
|
|
||||||
|
fringe.put((startingPriority, self.testCount, AStarNode(None, None, startingState)))
|
||||||
|
self.testCount += 1
|
||||||
while True:
|
while True:
|
||||||
|
print("DEBUG: A* in progress")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if fringe.empty():
|
if fringe.empty():
|
||||||
# target is unreachable
|
# target is unreachable
|
||||||
self.movesList = None
|
self.movesList = None
|
||||||
self.nextMove = None
|
self.nextMove = None
|
||||||
|
print("PATH NOT FOUND")
|
||||||
|
return None
|
||||||
|
|
||||||
elem: AStarNode = fringe.get()
|
|
||||||
|
|
||||||
|
|
||||||
|
elem: AStarNode = fringe.get()[2]
|
||||||
|
|
||||||
|
print("CURRENT STATE: {}, ACTION: {}".format(elem.state, elem.action))
|
||||||
|
for (pr, count, node) in fringe.queue:
|
||||||
|
print("PR: {}, ST: {}, AC: {}".format(pr, node.state, node.action))
|
||||||
|
|
||||||
if self.goalTest(elem.state):
|
if self.goalTest(elem.state):
|
||||||
result = []
|
movesList = []
|
||||||
p = elem.parent
|
p = elem.parent
|
||||||
while p is not None:
|
while p is not None:
|
||||||
result.append((elem.parent, elem.action))
|
movesList.append(elem.action)
|
||||||
return result
|
p = elem.parent
|
||||||
|
return movesList
|
||||||
|
|
||||||
explored.append(elem)
|
explored.append(elem)
|
||||||
|
|
||||||
for (movement, newState) in self.succesor(elem.state):
|
for (movement, newState) in self.succesor(elem.state):
|
||||||
newNode = AStarNode(elem, movement, newState)
|
# Sprawdzam czy nie jest poza mapa
|
||||||
newPriority = self.priority(newNode)
|
coordsWithUiOffset = [newState[0] + self.leftUiWidth, newState[1]]
|
||||||
|
|
||||||
# Check if state is not in fringe queue ...
|
# DEBUG
|
||||||
if not any(newNode.state == node[1].state for node in fringe.queue):
|
if movement == Movement.FORWARD:
|
||||||
# ... and is not in explored list
|
a = 1
|
||||||
if not any(newNode.state == node[1].state for node in explored):
|
a+=1
|
||||||
fringe.put((newPriority, newNode))
|
|
||||||
# If state is in fringe queue ...
|
if 0 <= newState[0] <= self.map.width - self.moveOffset and 0 <= newState[1] <= self.map.height - self.moveOffset:
|
||||||
else:
|
#if self.map.getTileOnCoord(coordsWithUiOffset) is not None:
|
||||||
node: AStarNode
|
newNode = AStarNode(elem, movement, newState)
|
||||||
for (pr, node) in fringe.queue:
|
newPriority = self.priority(newNode)
|
||||||
# Compare nodes
|
|
||||||
if node.state == newNode.state and node.parent is newNode.parent and node.action == newNode.action:
|
# Check if state is not in fringe queue ... # ... and is not in explored list
|
||||||
# ... and if it has priority > newPriority
|
if not any(newNode.state == node[2].state for node in fringe.queue) \
|
||||||
if pr > newPriority:
|
and not any(newNode.state == node.state for node in explored):
|
||||||
# Replace it with new priority
|
# there can't be nodes with same priority
|
||||||
fringe.queue.remove((pr, node))
|
'''
|
||||||
fringe.put((newPriority, node))
|
while any(newPriority == item[0] for item in fringe.queue):
|
||||||
|
newPriority -= 1'''
|
||||||
|
fringe.put((newPriority, self.testCount, newNode))
|
||||||
|
self.testCount += 1
|
||||||
|
# If state is in fringe queue ...
|
||||||
|
elif any(newNode.state == node[2].state for node in fringe.queue):
|
||||||
|
node: AStarNode
|
||||||
|
for (pr, count, node) in fringe.queue:
|
||||||
|
# Compare nodes
|
||||||
|
if node.state == newNode.state and node.action == newNode.action:
|
||||||
|
# ... and if it has priority > newPriority
|
||||||
|
if pr > newPriority:
|
||||||
|
# Replace it with new priority
|
||||||
|
fringe.queue.remove((pr, count, node))
|
||||||
|
fringe.put((newPriority, count, node))
|
||||||
|
self.testCount += 1
|
||||||
|
break
|
||||||
|
|
||||||
def succesor(self, elemState):
|
def succesor(self, elemState):
|
||||||
'''
|
'''
|
||||||
@ -86,29 +132,42 @@ class AutomaticMovement:
|
|||||||
(Movement.ROTATE_L, self.newStateAfterAction(elemState, Movement.ROTATE_L))]
|
(Movement.ROTATE_L, self.newStateAfterAction(elemState, Movement.ROTATE_L))]
|
||||||
|
|
||||||
stateAfterForward = self.newStateAfterAction(elemState, Movement.FORWARD)
|
stateAfterForward = self.newStateAfterAction(elemState, Movement.FORWARD)
|
||||||
facingEntity = self.map.getEntityOnCoord(stateAfterForward)
|
if 0 <= stateAfterForward[0] <= self.map.width - self.moveOffset and 0 <= stateAfterForward[1] <= self.map.height - self.moveOffset:
|
||||||
|
coordsWithUiOffset = [stateAfterForward[0] + self.leftUiWidth, stateAfterForward[1]]
|
||||||
if facingEntity is not None:
|
facingEntity = self.map.getEntityOnCoord(coordsWithUiOffset)
|
||||||
result.append((Movement.FORWARD, stateAfterForward))
|
if facingEntity is None:
|
||||||
|
result.append((Movement.FORWARD, stateAfterForward))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def goalTest(self, coords):
|
def goalTest(self, coords):
|
||||||
entity = self.map.getEntityOnCoord(coords)
|
|
||||||
|
|
||||||
if entity.id == self.actualTarget.id:
|
# with left ui width
|
||||||
|
coordsWithUiOffset = [coords[0] + self.leftUiWidth, coords[1]]
|
||||||
|
entity = self.map.getEntityOnCoord(coordsWithUiOffset)
|
||||||
|
'''if entity is not None:
|
||||||
|
if entity.id == self.actualTarget.id:
|
||||||
|
return True'''
|
||||||
|
|
||||||
|
if coords[0] == self.targetCoords[0] and coords[1] == self.targetCoords[1]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def approximateDistanceFromTarget(self, tileX, tileY):
|
def approximateDistanceFromTarget(self, tileX, tileY):
|
||||||
return abs(tileX - self.actualTarget.x) + abs(tileY - self.actualTarget.y)
|
return abs(tileX - self.targetCoords[0]) + abs(tileY - self.targetCoords[1])
|
||||||
|
|
||||||
def stepCost(self, terrainTile: TerrainTile):
|
def stepCost(self, terrainTile: TerrainTile):
|
||||||
return terrainTile.cost
|
|
||||||
|
# TODO: Nie znajduje terraina na ktorym stoi player
|
||||||
|
if terrainTile is None:
|
||||||
|
return 0
|
||||||
|
#return terrainTile.cost
|
||||||
|
return 0
|
||||||
|
|
||||||
def priority(self, elem: AStarNode):
|
def priority(self, elem: AStarNode):
|
||||||
return self.approximateDistanceFromTarget(elem.state[0], elem.state[1]) + self.stepCost(self.map.getTileOnCoord(elem.state))
|
coordsWithUiOffset = [elem.state[0] + self.leftUiWidth, elem.state[1]]
|
||||||
|
return self.approximateDistanceFromTarget(elem.state[0], elem.state[1]) + self.stepCost(self.map.getTileOnCoord(coordsWithUiOffset))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
state[0] - x
|
state[0] - x
|
||||||
@ -117,20 +176,26 @@ class AutomaticMovement:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def newStateAfterAction(self, state, action: Movement):
|
def newStateAfterAction(self, state, action: Movement):
|
||||||
newState = copy(state)
|
|
||||||
|
newX = state[0]
|
||||||
|
newY = state[1]
|
||||||
|
newRotation = state[2]
|
||||||
|
|
||||||
if action == Movement.FORWARD:
|
if action == Movement.FORWARD:
|
||||||
if state[2] == Rotations.NORTH:
|
if state[2] == Rotations.NORTH:
|
||||||
newState[1] -= self.moveOffset
|
newY -= self.moveOffset
|
||||||
elif state[2] == Rotations.EAST.value:
|
elif state[2] == Rotations.EAST:
|
||||||
newState[0] += self.moveOffset
|
newX += self.moveOffset
|
||||||
elif state[2] == Rotations.SOUTH.value:
|
elif state[2] == Rotations.SOUTH:
|
||||||
newState[1] += self.moveOffset
|
newY += self.moveOffset
|
||||||
elif state[2] == Rotations.WEST.value:
|
elif state[2] == Rotations.WEST:
|
||||||
newState[0] -= self.moveOffset
|
newX -= self.moveOffset
|
||||||
elif action == Movement.ROTATE_L:
|
elif action == Movement.ROTATE_L:
|
||||||
newState[2] = Rotations((state[2] + 1) % 4)
|
newRotation = Rotations((state[2].value - 1) % 4)
|
||||||
elif action == Movement.ROTATE_R:
|
elif action == Movement.ROTATE_R:
|
||||||
newState[2] = Rotations((state[2] - 1) % 4)
|
newRotation = Rotations((state[2].value + 1) % 4)
|
||||||
|
|
||||||
|
|
||||||
|
newState = (newX, newY, newRotation)
|
||||||
|
|
||||||
return newState
|
return newState
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from random import Random
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
@ -90,5 +91,8 @@ class EventManager:
|
|||||||
if keys[pygame.K_d]:
|
if keys[pygame.K_d]:
|
||||||
self.player.move(Movement.ROTATE_R)
|
self.player.move(Movement.ROTATE_R)
|
||||||
|
|
||||||
|
if keys[pygame.K_u]:
|
||||||
|
self.game.movement.gotoToTarget(self.game.map.entities[Random().randint(0, len(self.game.map.entities))])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from os import path
|
|||||||
|
|
||||||
from src.AI.AutomaticMovement import AutomaticMovement
|
from src.AI.AutomaticMovement import AutomaticMovement
|
||||||
from src.game.EventManager import EventManager
|
from src.game.EventManager import EventManager
|
||||||
from src.game.Screen import Screen
|
from src.game.Screen import Screen, Locations
|
||||||
from src.game.Map import Map
|
from src.game.Map import Map
|
||||||
|
|
||||||
from src.entities.Player import Player
|
from src.entities.Player import Player
|
||||||
@ -51,10 +51,17 @@ class Game:
|
|||||||
mapFile = Path(str(filesPath) + "/data/mapdata/")
|
mapFile = Path(str(filesPath) + "/data/mapdata/")
|
||||||
self.map = Map(path.join(mapFile, 'map.txt'), self.screen)
|
self.map = Map(path.join(mapFile, 'map.txt'), self.screen)
|
||||||
self.player = Player((6, 2), self.map.tileSize)
|
self.player = Player((6, 2), self.map.tileSize)
|
||||||
self.map.addEntity(self.player)
|
self.map.addEntity(self.player, DONTADD=True)
|
||||||
self.eventManager = EventManager(self, self.player)
|
self.eventManager = EventManager(self, self.player)
|
||||||
|
|
||||||
self.movement = AutomaticMovement(self.player, self.map)
|
self.movement = AutomaticMovement(self.player, self.map, self.screen.getUiWidth(Locations.LEFT_UI))
|
||||||
|
|
||||||
|
|
||||||
|
testTarget = self.map.entities[0]
|
||||||
|
if testTarget is self.player:
|
||||||
|
testTarget = self.map.entities[1]
|
||||||
|
|
||||||
|
self.movement.gotoToTarget(testTarget)
|
||||||
|
|
||||||
self.mainLoop()
|
self.mainLoop()
|
||||||
|
|
||||||
@ -64,5 +71,6 @@ class Game:
|
|||||||
self.ingameTimer.updateTime(self.pgTimer.tick())
|
self.ingameTimer.updateTime(self.pgTimer.tick())
|
||||||
self.spritesList.update()
|
self.spritesList.update()
|
||||||
self.eventManager.handleEvents()
|
self.eventManager.handleEvents()
|
||||||
|
self.movement.updatePlayerCoords()
|
||||||
self.spritesList.draw(self.screen.pygameScreen)
|
self.spritesList.draw(self.screen.pygameScreen)
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
@ -19,6 +19,8 @@ class Map:
|
|||||||
self.terrainTilesList = []
|
self.terrainTilesList = []
|
||||||
self.collidables = pygame.sprite.Group()
|
self.collidables = pygame.sprite.Group()
|
||||||
|
|
||||||
|
self.entities = []
|
||||||
|
|
||||||
with open(filename, 'rt') as f:
|
with open(filename, 'rt') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
self.terrain.append(line)
|
self.terrain.append(line)
|
||||||
@ -101,27 +103,32 @@ class Map:
|
|||||||
|
|
||||||
def getEntityOnCoord(self, coord):
|
def getEntityOnCoord(self, coord):
|
||||||
result = None
|
result = None
|
||||||
for entity in self.collidables:
|
for entity in self.entities:
|
||||||
if entity.rect.x == coord[0] and entity.rect.y == coord[1]:
|
if entity.rect.x == coord[0] and entity.rect.y == coord[1]:
|
||||||
result = entity
|
result = entity
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def getTileOnCoord(self, coord):
|
def getTileOnCoord(self, coord):
|
||||||
result = None
|
result = None
|
||||||
for entity in self.:
|
for entity in self.terrainTilesList:
|
||||||
if entity.rect.x == coord[0] and entity.rect.y == coord[1]:
|
if entity.rect.x == coord[0] and entity.rect.y == coord[1]:
|
||||||
result = entity
|
result = entity
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def addEntity(self, entity):
|
# TODO: REMOVE DONT ADD
|
||||||
|
def addEntity(self, entity, DONTADD=False):
|
||||||
self.screen.draw(entity, Locations.MAP, 0, 0)
|
self.screen.draw(entity, Locations.MAP, 0, 0)
|
||||||
self.collidables.add(entity)
|
self.collidables.add(entity)
|
||||||
|
if not DONTADD:
|
||||||
|
self.entities.append(entity)
|
||||||
|
|
||||||
def removeSpriteFromMap(self, entity):
|
def removeSpriteFromMap(self, entity):
|
||||||
if self.collidables.has(entity):
|
if self.collidables.has(entity):
|
||||||
self.collidables.remove(entity)
|
self.collidables.remove(entity)
|
||||||
self.screen.removeSprite(entity)
|
self.screen.removeSprite(entity)
|
||||||
|
|
||||||
|
self.entities.remove(entity)
|
||||||
|
|
||||||
# add object to map.collidables list to be collidable
|
# add object to map.collidables list to be collidable
|
||||||
def collision(self, x, y):
|
def collision(self, x, y):
|
||||||
for b in self.collidables:
|
for b in self.collidables:
|
||||||
|
Loading…
Reference in New Issue
Block a user