merged jakfit-feature-treesearch and jak-dev
This commit is contained in:
parent
3b69b78d11
commit
da9fdc0bb9
106
actions.py
106
actions.py
@ -1,69 +1,47 @@
|
||||
# Funkcja konwertujaca wspolrzedne nastepnego pola do odwiedzenia
|
||||
#na kolejke akcji do wykonania
|
||||
|
||||
# tl - turn left, tr - turn right, fwd - forward, op - open
|
||||
#queue - kolejka akcji do zrobienia, pole klasy Player
|
||||
#path - kolejka pol do odwiedzenia, pole klasy Player
|
||||
|
||||
# pole to element wziety z kolejki path
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
|
||||
def actionPlanner(self,pole):
|
||||
x0 = self.pos[0]
|
||||
y0 = self.pos[1]
|
||||
x = pole[0]
|
||||
y = pole[1]
|
||||
if (x > x0):
|
||||
if (self.direction == 1):
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 0):
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 2):
|
||||
self.queue.insert("tl")
|
||||
self.queue.insert("fwd")
|
||||
def actionsInterpreter(actionIndex, defaultState, directions):
|
||||
|
||||
if actionIndex == -1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().counterClockwise()
|
||||
)
|
||||
elif actionIndex == 0:
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if defaultState.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif defaultState.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif defaultState.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif defaultState.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
return AgentState(
|
||||
defaultState.get_x() + move_x, # directions[defaultState.get_direction()[0]], - is not subscriptable ???
|
||||
defaultState.get_y() + move_y, # directions[defaultState.get_direction()][1], - is not subscriptable ???
|
||||
defaultState.get_direction()
|
||||
)
|
||||
elif actionIndex == 1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().clockwise()
|
||||
)
|
||||
else:
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
elif (x < x0):
|
||||
if (self.direction == 3):
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 0):
|
||||
self.queue.insert("tl")
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 2):
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
else:
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
else:
|
||||
if (y > y0):
|
||||
if (self.direction == 0):
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 1):
|
||||
self.queue.insert("tl")
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 3):
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
else:
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
else:
|
||||
if (self.direction == 2):
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 3):
|
||||
self.queue.insert("tl")
|
||||
self.queue.insert("fwd")
|
||||
elif (self.direction == 1):
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
else:
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("tr")
|
||||
self.queue.insert("fwd")
|
||||
if (self.path.empty()):
|
||||
self.queue.insert("op")
|
||||
return defaultState
|
||||
|
||||
|
||||
actions = {
|
||||
"rotateLeft": -1,
|
||||
"moveForward": 0,
|
||||
"rotateRight": 1
|
||||
}
|
||||
|
15
direction.py
Normal file
15
direction.py
Normal file
@ -0,0 +1,15 @@
|
||||
from enum import Enum
|
||||
|
||||
class Direction(Enum):
|
||||
N = 0
|
||||
E = 1
|
||||
S = 2
|
||||
W = 3
|
||||
|
||||
def clockwise(self):
|
||||
v = (self.value+1)%4
|
||||
return Direction(v)
|
||||
|
||||
def counterClockwise(self):
|
||||
v = (self.value-1)%4
|
||||
return Direction(v)
|
338
hero.py
338
hero.py
@ -1,8 +1,15 @@
|
||||
import random
|
||||
|
||||
from mesa import Agent
|
||||
|
||||
from othercharacters import dice, Box, Creature, Armor, Weapon
|
||||
from actions import actions, actionsInterpreter
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
|
||||
|
||||
class Player(Creature):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3, listOfChests):
|
||||
super().__init__(unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
@ -17,35 +24,18 @@ class Player(Creature):
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = False
|
||||
self.directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
|
||||
self.direction = 0
|
||||
self.directions = {
|
||||
Direction.N : [0, 1],
|
||||
Direction.E : [1, 0],
|
||||
Direction.S : [0, -1],
|
||||
Direction.W : [-1, 0]
|
||||
}
|
||||
self.direction = Direction.N
|
||||
self.queue = []
|
||||
self.hasgoalchest = False
|
||||
self.openedchests = 0
|
||||
|
||||
def rotate(self, clockwise=True):
|
||||
if clockwise:
|
||||
self.direction = (self.direction + 1) % 4
|
||||
else:
|
||||
self.direction = (self.direction + 3) % 4
|
||||
|
||||
def moveFwd(self):
|
||||
possible_steps = self.model.grid.get_neighborhood(
|
||||
self.pos,
|
||||
moore=False,
|
||||
include_center=False)
|
||||
new_position = (self.pos[0] + self.directions[self.direction][0],
|
||||
self.pos[1] + self.directions[self.direction][1])
|
||||
if new_position in possible_steps:
|
||||
self.model.grid.move_agent(self, new_position)
|
||||
print("moved to ", new_position)
|
||||
# def move(self): # OLD
|
||||
# possible_steps = self.model.grid.get_neighborhood(
|
||||
# self.pos,
|
||||
# moore=True,
|
||||
# include_center=False)
|
||||
# new_position = self.random.choice(possible_steps)
|
||||
# self.model.grid.move_agent(self, new_position)
|
||||
self.__listOfChests = listOfChests
|
||||
self.__actionsCollection = []
|
||||
|
||||
def meleeAttack(self, opponent):
|
||||
attackValue = self.strength + dice(6)
|
||||
@ -132,7 +122,7 @@ class Player(Creature):
|
||||
self.openedchests += 1
|
||||
self.hasgoalchest = False
|
||||
chest.model.grid.remove_agent(chest)
|
||||
self.direction=0 #po osiągnięciu jednego celu 'restartuje sie' na szukanie ścieżki do kolejnego
|
||||
#self.direction = 0 # po osiągnięciu jednego celu 'restartuje sie' na szukanie ścieżki do kolejnego -- NIE ZEROWAĆ OBROTU - to psuje goldState w bfs!!!
|
||||
# if isinstance(chest.loot,Armor):
|
||||
# buffer = self.armor
|
||||
# self.armor = chest.loot
|
||||
@ -151,160 +141,172 @@ class Player(Creature):
|
||||
# self.weapon3 = chest.loot
|
||||
# chest.loot = buffer
|
||||
|
||||
def findShortestPathToTarget(self):
|
||||
visited = []
|
||||
precedessors = {}
|
||||
queue = [self.pos]
|
||||
found_target = False
|
||||
#- - - - bfs & successor - - - -#
|
||||
def successor(self, append):
|
||||
|
||||
while queue:
|
||||
cur_pos = queue.pop(0)
|
||||
rotateLeft = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().counterClockwise()
|
||||
)
|
||||
|
||||
#check for target
|
||||
cell_contents = self.model.grid.get_cell_list_contents([cur_pos])
|
||||
if cell_contents and any([isinstance(thing, Box) for thing in cell_contents]):
|
||||
found_target = cur_pos
|
||||
self.hasgoalchest=True
|
||||
break
|
||||
rotateRight = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().clockwise()
|
||||
)
|
||||
|
||||
#enqueue safe unvisited neighbours
|
||||
neighbours = self.model.grid.get_neighborhood(
|
||||
cur_pos,
|
||||
moore=False,
|
||||
include_center=False)
|
||||
for cell in neighbours:
|
||||
#if cell hasn't been visited and the contents don't include creatures
|
||||
if cell not in visited and not any([isinstance(thing, Creature) for thing in self.model.grid.get_cell_list_contents([cell])]):
|
||||
queue.append(cell)
|
||||
precedessors[cell] = cur_pos
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
visited.append(cur_pos)
|
||||
if append.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif append.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif append.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif append.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
if found_target:
|
||||
path = [found_target]
|
||||
while True:
|
||||
if path[0] == self.pos:
|
||||
break
|
||||
precedessor = precedessors[path[0]]
|
||||
path.insert(0, precedessor)
|
||||
return path
|
||||
|
||||
return "no chests left"
|
||||
|
||||
# Funkcja konwertujaca wspolrzedne nastepnego pola do odwiedzenia
|
||||
# na kolejke akcji do wykonania
|
||||
|
||||
# tl - turn left, tr - turn right, fwd - forward, op - open
|
||||
# queue - kolejka akcji do zrobienia, pole klasy Player
|
||||
# path - kolejka pol do odwiedzenia, pole klasy Player
|
||||
|
||||
# pole to element wziety z kolejki path
|
||||
|
||||
def actionPlanner(self, cell_from, cell_to):
|
||||
x0 = cell_from[0]
|
||||
y0 = cell_from[1]
|
||||
x = cell_to[0]
|
||||
y = cell_to[1]
|
||||
if (x > x0):
|
||||
if (self.direction == 1):
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 0):
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 2):
|
||||
self.queue.append("tl")
|
||||
self.rotate(False)
|
||||
self.queue.append("fwd")
|
||||
if append.get_x() + move_x >= 0 and append.get_x() + move_x < 10 and append.get_y() + move_y >=0 and append.get_y() + move_y < 10:
|
||||
moveForward = AgentState(
|
||||
append.get_x() + move_x,
|
||||
append.get_y() + move_y,
|
||||
append.get_direction()
|
||||
)
|
||||
else:
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.insert("fwd")
|
||||
elif (x < x0):
|
||||
if (self.direction == 3):
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 0):
|
||||
self.queue.append("tl")
|
||||
self.rotate(False)
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 2):
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
moveForward = None
|
||||
|
||||
return [
|
||||
[actions["rotateLeft"], rotateLeft],
|
||||
[actions["moveForward"], moveForward],
|
||||
[actions["rotateRight"], rotateRight]
|
||||
]
|
||||
|
||||
def graphsearch(self, fringe, explored, istate, succesorFunction, goalState):
|
||||
finalActionList = []
|
||||
fringe.append([None, istate]) # at beginning do nothing
|
||||
|
||||
while len(fringe) != 0:
|
||||
_flag = True
|
||||
|
||||
if len(fringe) == 0:
|
||||
return False
|
||||
|
||||
tmpState = fringe.pop(0)
|
||||
|
||||
# build dictionary
|
||||
parent = tmpState[1].get_predecessor() #fetch paren state
|
||||
tmpState[1].set_predecessor(None) # clear predecessor - don't build a tree chain
|
||||
if parent is None:
|
||||
finalActionList.append([parent, tmpState])
|
||||
else:
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
elif (y > y0):
|
||||
if (self.direction == 0):
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 1):
|
||||
self.queue.append("tl")
|
||||
self.rotate(False)
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 3):
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
else:
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
elif (y < y0):
|
||||
if (self.direction == 2):
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 3):
|
||||
self.queue.append("tl")
|
||||
self.rotate(False)
|
||||
self.queue.append("fwd")
|
||||
elif (self.direction == 1):
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
else:
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("tr")
|
||||
self.rotate(True)
|
||||
self.queue.append("fwd")
|
||||
elif (len(self.path)==0):
|
||||
self.queue.append("op")
|
||||
finalActionList.append([parent[1], tmpState]) # pair(key, value) - key: parent state, value: current state + action
|
||||
|
||||
|
||||
if tmpState[1].get_x() == goalState.get_x() and tmpState[1].get_y() == goalState.get_y():
|
||||
return finalActionList
|
||||
|
||||
explored.append(tmpState)
|
||||
|
||||
tmpList = succesorFunction(tmpState[1])
|
||||
for newState in tmpList:
|
||||
_flag = True
|
||||
|
||||
if newState[1] is None:
|
||||
continue
|
||||
|
||||
for fringeState in fringe:
|
||||
if fringeState[1].get_x() == newState[1].get_x() and fringeState[1].get_y() == newState[1].get_y() and fringeState[1].get_direction() == newState[1].get_direction():
|
||||
_flag = False
|
||||
|
||||
for exploredState in explored:
|
||||
if exploredState[1].get_x() == newState[1].get_x() and exploredState[1].get_y() == newState[1].get_y() and exploredState[1].get_direction() == newState[1].get_direction():
|
||||
_flag = False
|
||||
|
||||
if _flag:
|
||||
newState[1].set_predecessor(tmpState)
|
||||
fringe.append(newState)
|
||||
|
||||
|
||||
return None
|
||||
|
||||
def step(self):
|
||||
if self.health > 0:
|
||||
print("position: ", self.pos)
|
||||
# print("direction: ", self.direction)
|
||||
if not self.hasgoalchest: # jeśli nie ma wyznaczonej skrzynki do której idzie to robi bfs żeby ją wyznaczyć
|
||||
self.path=self.findShortestPathToTarget()
|
||||
if self.path=="no chests left":
|
||||
print("no chests left, life has lost meaning")
|
||||
# self.path=self.findShortestPathToTarget()
|
||||
if len(self.__listOfChests) != 0:
|
||||
# select and remove element from list
|
||||
randomChest = random.choice(self.__listOfChests)
|
||||
self.__listOfChests.remove(randomChest)
|
||||
self.hasgoalchest = True
|
||||
|
||||
currentState = AgentState(self.pos[0], self.pos[1], self.direction)
|
||||
|
||||
goalState = AgentState(randomChest[1][0], randomChest[1][1], self.direction)
|
||||
# find way to goal state
|
||||
self.__actionsCollection = self.graphsearch([],
|
||||
[],
|
||||
currentState,
|
||||
self.successor,
|
||||
goalState)
|
||||
|
||||
if self.__actionsCollection is None:
|
||||
raise Exception("CRITICAL ERROR - Algorithm error - Path doesn't exist!!! ://")
|
||||
|
||||
else: #build list from dictionary by last element
|
||||
goalActionsList = []
|
||||
#keysList = list(self.__actionsCollection.keys())
|
||||
#valuesList = list(self.__actionsCollection.values())
|
||||
|
||||
stateWithChest = self.__actionsCollection[-1] # fetch last item
|
||||
|
||||
#stateWithChest:
|
||||
# [
|
||||
# [0] key - parent ActionState: object,
|
||||
# [1] value - node successor:
|
||||
# {
|
||||
# [0] action: string - action to get state
|
||||
# [1] AgentState: object - current state
|
||||
# }
|
||||
# ]
|
||||
|
||||
goalActionsList.append(stateWithChest[1][0]) # save action
|
||||
tmpState = stateWithChest[0]
|
||||
while tmpState is not None: # iterate while key (parent state) != None
|
||||
|
||||
index = 0
|
||||
for valeState in self.__actionsCollection: # find new key(parent status) index in array data
|
||||
if valeState[1][1].get_x() == tmpState.get_x() and valeState[1][1].get_y() == tmpState.get_y() and valeState[1][1].get_direction() == tmpState.get_direction():
|
||||
break
|
||||
index += 1
|
||||
|
||||
|
||||
goalActionsList.append(self.__actionsCollection[index][1][0]) # get action
|
||||
tmpState = self.__actionsCollection[index][0] # get state - and next we will find key equal it's value
|
||||
|
||||
self.__actionsCollection = list(reversed(goalActionsList))
|
||||
self.__actionsCollection = [action for action in self.__actionsCollection if action is not None] # remove first None action
|
||||
else:
|
||||
print("the player should follow this path:", self.path)
|
||||
for i in range(len(self.path)-1): #iteruje po kolejnych krotkach ze współrzędnymi pól
|
||||
#actionPlanner ma się wykonać i-1 razy, bo dla ostatniego pola już nie
|
||||
self.actionPlanner(self.path[i], self.path[i+1]) #dla każdego pola dodaje do kolejki kilka akcji potrzebnych żeby do niego dojść
|
||||
print(self.queue)
|
||||
self.direction=0 # bo po obrotach w wyznaczaniu ścieżki trzeba wrócić do orientacji takiej, jaka była na starcie wyznaczania
|
||||
#to znaczy, że po otwarciu skrzynki też się zeruje żeby zacząć wyznaczanie i chodzenie od takiej samej
|
||||
while len(self.queue)!=0:
|
||||
self.action=self.queue.pop(0)
|
||||
if self.action=="tr":
|
||||
self.rotate(True)
|
||||
print("tr'd, direction: ", self.direction)
|
||||
break
|
||||
elif self.action=="tl":
|
||||
self.rotate(False)
|
||||
print("tl'd, direction: ", self.direction)
|
||||
break
|
||||
elif self.action=="fwd":
|
||||
self.moveFwd()
|
||||
break
|
||||
raise Exception("WIN!!! :D")
|
||||
|
||||
elif len(self.__actionsCollection) == 0: # jeśli jest wyznaczona skrzynka - cel & nie ma akcji do wykonania - cel osiągnięty
|
||||
self.hasgoalchest = False
|
||||
|
||||
elif len(self.__actionsCollection) != 0: # jeśli jest wyznaczona skrzynka - cel & są akcje do wykoannia to je realizuje
|
||||
|
||||
actionIndex = self.__actionsCollection[0] # ignore -1 because it's None
|
||||
self.__actionsCollection.remove(actionIndex)
|
||||
|
||||
newState = actionsInterpreter(actionIndex, AgentState(self.pos[0], self.pos[1], self.direction), self.directions)
|
||||
|
||||
self.model.grid.move_agent(self, (newState.get_x(), newState.get_y()))
|
||||
self.direction = newState.get_direction()
|
||||
|
||||
print("moved to - ", [newState.get_x(), newState.get_y()])
|
||||
|
||||
cellmates = self.model.grid.get_cell_list_contents([self.pos])
|
||||
if len(cellmates) > 1:
|
||||
if isinstance(cellmates[0], Box):
|
||||
|
8
model.py
8
model.py
@ -16,6 +16,7 @@ creatures_number = 5
|
||||
|
||||
class GameMap(Model):
|
||||
def __init__(self, x, y):
|
||||
self.listOfChests = []
|
||||
self.grid = MultiGrid(x, y, False)
|
||||
self.schedule = RandomActivation(self) # agenci losowo po kolei wykonują swoje akcje
|
||||
# to jest potrzebne przy założeniu, że potwory chodzą?
|
||||
@ -23,12 +24,13 @@ class GameMap(Model):
|
||||
self.creatures_number = creatures_number
|
||||
self.running = True
|
||||
# player = Player(1000, self)
|
||||
player = Player(1000, self, "Janusz", 3, 3, 3, 20, 20, WM1, A1, 0, WR1, S1)
|
||||
player = Player(1000, self, "Janusz", 3, 3, 3, 20, 20, WM1, A1, 0, WR1, S1, self.listOfChests)
|
||||
self.schedule.add(player)
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
self.grid.place_agent(player, (x, y))
|
||||
|
||||
|
||||
for i in range(self.boxes_number):
|
||||
box = Box(i, self)
|
||||
# self.schedule.add(box)
|
||||
@ -37,6 +39,7 @@ class GameMap(Model):
|
||||
if self.grid.is_cell_empty((x, y)):
|
||||
self.grid.place_agent(box, (x, y))
|
||||
self.schedule.add(box)
|
||||
self.listOfChests.append([i, [x, y]]) #fetching chest position - [index, [OX, OY]]
|
||||
else:
|
||||
pass
|
||||
|
||||
@ -54,6 +57,9 @@ class GameMap(Model):
|
||||
|
||||
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
|
||||
|
||||
def get_listOfChests(self):
|
||||
return self.listOfChests
|
||||
|
||||
def step(self):
|
||||
self.schedule.step()
|
||||
# self.datacollector.collect(self) #na razie niepotrzebne
|
||||
|
@ -18,5 +18,5 @@ server = ModularServer(GameMap,
|
||||
[grid],
|
||||
"Map",
|
||||
{"x":10, "y":10})
|
||||
server.port = 8521
|
||||
server.port = 8080
|
||||
server.launch()
|
36
state.py
Normal file
36
state.py
Normal file
@ -0,0 +1,36 @@
|
||||
class AgentState:
|
||||
def __init__(self, x, y, direction, predecessor = None):
|
||||
self.__x = x
|
||||
self.__y = y
|
||||
self.__direction = direction
|
||||
self.__predecessor = predecessor
|
||||
|
||||
def get_x(self):
|
||||
return self.__x
|
||||
|
||||
def increment_x(self, value):
|
||||
self.__x += value
|
||||
|
||||
def set_x(self, x):
|
||||
self.__x = x
|
||||
|
||||
def get_y(self):
|
||||
return self.__y
|
||||
|
||||
def increment_y(self, value):
|
||||
self.__y += value
|
||||
|
||||
def set_y(self, y):
|
||||
self.__y = y
|
||||
|
||||
def get_direction(self):
|
||||
return self.__direction
|
||||
|
||||
def set_direction(self, direction):
|
||||
self.__direction = direction
|
||||
|
||||
def get_predecessor(self):
|
||||
return self.__predecessor
|
||||
|
||||
def set_predecessor(self, predecessor):
|
||||
self.__predecessor = predecessor
|
Loading…
Reference in New Issue
Block a user