started implementing game element logic
This commit is contained in:
parent
ca11f3476c
commit
a334fab2c6
91
roborally.py
91
roborally.py
|
@ -93,12 +93,18 @@ class Robot:
|
||||||
self.board[(x,y)].occupant = self
|
self.board[(x,y)].occupant = self
|
||||||
|
|
||||||
|
|
||||||
def get_accessed_tiles(self, count):
|
def get_accessed_tiles(self, count, forward=True):
|
||||||
# create a list of all tiles the robot would enter if it drives <count> steps forward
|
# create a list of all tiles the robot would enter if it drives <count> steps forward
|
||||||
tiles = []
|
tiles = []
|
||||||
current_tile = self.board[(self.x, self.y)]
|
current_tile = self.board[(self.x, self.y)]
|
||||||
for i in range(1, count + 1):
|
for i in range(1, count + 1):
|
||||||
|
if forward:
|
||||||
current_tile = self.board.get(current_tile.get_neighbor_coordinates(self.orientation))
|
current_tile = self.board.get(current_tile.get_neighbor_coordinates(self.orientation))
|
||||||
|
else:
|
||||||
|
current_tile = self.board.get(current_tile.get_neighbor_coordinates(Robot.opposites[self.orientation]))
|
||||||
|
if current_tile is None:
|
||||||
|
return tiles
|
||||||
|
else:
|
||||||
tiles.append(current_tile)
|
tiles.append(current_tile)
|
||||||
return tiles
|
return tiles
|
||||||
|
|
||||||
|
@ -154,7 +160,7 @@ class Robot:
|
||||||
return "{}, forward".format(self.id)
|
return "{}, forward".format(self.id)
|
||||||
elif type == 'backward':
|
elif type == 'backward':
|
||||||
opposite_orientation = self.get_opposite_orientation()
|
opposite_orientation = self.get_opposite_orientation()
|
||||||
target_tile = tile.get_neighbor_coordinates(opposite_orientation)
|
target_tile = self.board[tile.get_neighbor_coordinates(opposite_orientation)]
|
||||||
|
|
||||||
if target_tile.occupant is not None:
|
if target_tile.occupant is not None:
|
||||||
print("error: target tile is not empty")
|
print("error: target tile is not empty")
|
||||||
|
@ -235,32 +241,46 @@ class Board:
|
||||||
if (x == 0) or (x == Board.x_dims + 1) or (y == 0) or (y == Board.y_dims + 1):
|
if (x == 0) or (x == Board.x_dims + 1) or (y == 0) or (y == Board.y_dims + 1):
|
||||||
# place walls around the board
|
# place walls around the board
|
||||||
self.board[(x, y)] = Tile(x, y, '#')
|
self.board[(x, y)] = Tile(x, y, '#')
|
||||||
elif x == 1 and (y >= 1) and (y <= 4):
|
elif x == 1 and (y >= 1) and (y < 4):
|
||||||
self.board[(x, y)] = Tile(x, y, 'v')
|
self.board[(x, y)] = Tile(x, y, 'v')
|
||||||
|
elif y == 4:
|
||||||
|
self.board[(x, y)] = Tile(x, y, '>')
|
||||||
else:
|
else:
|
||||||
self.board[(x,y)] = Tile(x,y)
|
self.board[(x,y)] = Tile(x,y)
|
||||||
|
|
||||||
self.robots = {}
|
self.robots = {}
|
||||||
self.robots[0] = Robot(3, 1, '<', 0, self.board)
|
self.robots[0] = Robot(3, 1, '>', 0, self.board)
|
||||||
self.robots[1] = Robot(2, 1, 'v', 1, self.board)
|
self.robots[1] = Robot(2, 1, 'v', 1, self.board)
|
||||||
|
|
||||||
def handle_push(self, pushing_robot, pushed_robot):
|
def handle_push(self, direction, pushed_robot, forward=True, pushing_robot=None):
|
||||||
cmd_list = []
|
cmd_list = []
|
||||||
# push robot out of the way
|
# push robot out of the way
|
||||||
if pushed_robot.orientation == pushing_robot.orientation:
|
if pushed_robot.orientation == direction:
|
||||||
|
if forward:
|
||||||
# the pushed robot can just drive forward
|
# the pushed robot can just drive forward
|
||||||
cmd_list += self.handle_single_action('forward', pushed_robot)
|
cmd_list += self.handle_single_action('forward', pushed_robot)
|
||||||
elif pushed_robot.has_opposite_orientation(pushing_robot.orientation):
|
else:
|
||||||
|
# the pushed robot can just drive backward
|
||||||
|
cmd_list += self.handle_single_action('backward', pushed_robot)
|
||||||
|
elif pushed_robot.has_opposite_orientation(direction):
|
||||||
|
if forward:
|
||||||
# the pushed robot can drive backward
|
# the pushed robot can drive backward
|
||||||
cmd_list += self.handle_single_action('backward', pushed_robot)
|
cmd_list += self.handle_single_action('backward', pushed_robot)
|
||||||
|
else:
|
||||||
|
# the pushed robot drives forward
|
||||||
|
cmd_list += self.handle_single_action('forward', pushed_robot)
|
||||||
else:
|
else:
|
||||||
# we first have to turn the pushed robot s.t. it faces in the same orientation as the
|
# we first have to turn the pushed robot s.t. it faces in the same orientation as the
|
||||||
# pushing robot
|
# pushing robot
|
||||||
turn_direction = pushed_robot.get_turn_direction(pushing_robot.orientation)
|
turn_direction = pushed_robot.get_turn_direction(direction)
|
||||||
cmd_list += self.handle_single_action(turn_direction, pushed_robot)
|
cmd_list += self.handle_single_action(turn_direction, pushed_robot)
|
||||||
|
|
||||||
|
if forward:
|
||||||
# then the pushed robot drives one step forward
|
# then the pushed robot drives one step forward
|
||||||
cmd_list += self.handle_single_action('forward', pushed_robot)
|
cmd_list += self.handle_single_action('forward', pushed_robot)
|
||||||
|
else:
|
||||||
|
# if its pushed backward it instead drives on step backward
|
||||||
|
cmd_list += self.handle_single_action('backward', pushed_robot)
|
||||||
|
|
||||||
# afterwards we turn the robot back to the original orientation
|
# afterwards we turn the robot back to the original orientation
|
||||||
if turn_direction == 'turn left':
|
if turn_direction == 'turn left':
|
||||||
|
@ -272,8 +292,12 @@ class Board:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
cmd_list += self.handle_single_action(turn_back_direction, pushed_robot)
|
cmd_list += self.handle_single_action(turn_back_direction, pushed_robot)
|
||||||
|
|
||||||
|
if pushing_robot is not None:
|
||||||
# now the tile should be empty so the pushing robot can move into the tile
|
# now the tile should be empty so the pushing robot can move into the tile
|
||||||
|
if forward:
|
||||||
cmd_list.append(pushing_robot.move('forward'))
|
cmd_list.append(pushing_robot.move('forward'))
|
||||||
|
else:
|
||||||
|
cmd_list.append(pushing_robot.move('backward'))
|
||||||
return cmd_list
|
return cmd_list
|
||||||
|
|
||||||
def handle_single_action(self, action, robot):
|
def handle_single_action(self, action, robot):
|
||||||
|
@ -302,7 +326,7 @@ class Board:
|
||||||
self.robots.values()]): # robots hits a tile occupied by another robot
|
self.robots.values()]): # robots hits a tile occupied by another robot
|
||||||
pushed_robot = next(filter(lambda r: (tile.x, tile.y) == (r.x, r.y), self.robots.values()))
|
pushed_robot = next(filter(lambda r: (tile.x, tile.y) == (r.x, r.y), self.robots.values()))
|
||||||
if pushed_robot.is_pushable(robot.orientation): # check if robot is pushable in the given direction
|
if pushed_robot.is_pushable(robot.orientation): # check if robot is pushable in the given direction
|
||||||
cmd_list += self.handle_push(pushing_robot=robot, pushed_robot=pushed_robot)
|
cmd_list += self.handle_push(direction=robot.orientation, pushed_robot=pushed_robot, forward=True, pushing_robot=robot)
|
||||||
else:
|
else:
|
||||||
cmd_list.append(robot.nop())
|
cmd_list.append(robot.nop())
|
||||||
return cmd_list
|
return cmd_list
|
||||||
|
@ -312,12 +336,47 @@ class Board:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
elif action == 'backward':
|
elif action == 'backward':
|
||||||
# basically do the same as with forward
|
# basically do the same as with forward
|
||||||
pass
|
accessed_tiles = robot.get_accessed_tiles(1, forward=False)
|
||||||
|
|
||||||
|
for tile in accessed_tiles:
|
||||||
|
if tile is None:
|
||||||
|
# this case should not happen
|
||||||
|
print("error: unknown state occured")
|
||||||
|
sys.exit(1)
|
||||||
|
elif tile.is_empty():
|
||||||
|
# if the tile is empty we can just move there
|
||||||
|
cmd_list.append(robot.move('backward'))
|
||||||
|
elif tile.modifier == '#': # robot hits a wall -> stop the robot
|
||||||
|
cmd_list.append(robot.nop())
|
||||||
|
return cmd_list
|
||||||
|
elif any([(tile.x, tile.y) == (r.x, r.y) for r in
|
||||||
|
self.robots.values()]): # robots hits a tile occupied by another robot
|
||||||
|
pushed_robot = next(filter(lambda r: (tile.x, tile.y) == (r.x, r.y), self.robots.values()))
|
||||||
|
if pushed_robot.is_pushable(Robot.opposites[robot.orientation]): # check if robot is pushable in the given direction
|
||||||
|
cmd_list += self.handle_push(direction=robot.orientation, pushed_robot=pushed_robot, forward=False, pushing_robot=robot)
|
||||||
|
else:
|
||||||
|
cmd_list.append(robot.nop())
|
||||||
|
return cmd_list
|
||||||
|
else:
|
||||||
|
# this case should not happen
|
||||||
|
print("error: unknown state occured")
|
||||||
|
sys.exit(1)
|
||||||
else: # this means we have a turn action
|
else: # this means we have a turn action
|
||||||
cmd_list.append(robot.turn(action))
|
cmd_list.append(robot.turn(action))
|
||||||
|
|
||||||
return cmd_list
|
return cmd_list
|
||||||
|
|
||||||
|
def handle_board_element(self, robot):
|
||||||
|
cmd_list = []
|
||||||
|
tile = self.board[(robot.x, robot.y)]
|
||||||
|
if tile.modifier in ['^', '>', 'v', '<']:
|
||||||
|
# board element pushes the robot to next tile
|
||||||
|
if robot.is_pushable(tile.modifier):
|
||||||
|
cmd_list += self.handle_push(direction=tile.modifier, pushed_robot=robot, forward=True)
|
||||||
|
else:
|
||||||
|
cmd_list.append(robot.nop())
|
||||||
|
return cmd_list
|
||||||
|
|
||||||
def apply_actions(self, cards):
|
def apply_actions(self, cards):
|
||||||
cmd_list = []
|
cmd_list = []
|
||||||
# apply the actions to the board and generate a list of movement commands
|
# apply the actions to the board and generate a list of movement commands
|
||||||
|
@ -335,10 +394,14 @@ class Board:
|
||||||
print("robot {} action {}".format(robot, action))
|
print("robot {} action {}".format(robot, action))
|
||||||
|
|
||||||
cmd_list += self.handle_single_action(action, robot)
|
cmd_list += self.handle_single_action(action, robot)
|
||||||
print(cmd_list)
|
|
||||||
pass
|
|
||||||
|
|
||||||
# apply the actions caused by board elements at the end of the phase
|
# apply the actions caused by board elements at the end of the phase
|
||||||
|
for robot_id in self.robots:
|
||||||
|
robot = self.robots[robot_id]
|
||||||
|
cmd_list += self.handle_board_element(robot)
|
||||||
|
|
||||||
|
print(cmd_list)
|
||||||
|
print(self)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -357,8 +420,10 @@ class Board:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
n = 5
|
n = 5
|
||||||
player_1_cards = random.sample(list(filter(lambda c: 'forward' in c.action, deck.deck.values())), n)
|
player_1_cards = random.sample(list(filter(lambda c: 'backward' in c.action, deck.deck.values())), n)
|
||||||
player_2_cards = random.sample(list(filter(lambda c: 'turn around' in c.action, deck.deck.values())), n)
|
player_2_cards = random.sample(list(filter(lambda c: 'turn around' in c.action, deck.deck.values())), n)
|
||||||
|
#player_1_cards = deck.draw_cards(40)
|
||||||
|
#player_2_cards = deck.draw_cards(40)
|
||||||
|
|
||||||
cards_1 = [(0, c) for c in player_1_cards]
|
cards_1 = [(0, c) for c in player_1_cards]
|
||||||
cards_2 = [(1, c) for c in player_2_cards]
|
cards_2 = [(1, c) for c in player_2_cards]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user