Skip to content

Commit

Permalink
Merge pull request #73 from ASPP/feature/graph-attribute
Browse files Browse the repository at this point in the history
use the newly introduced `bot.graph` attribute
  • Loading branch information
Debilski authored May 17, 2024
2 parents 6cf28db + 388c664 commit 491a2e4
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 21 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,13 @@ Note that the `Bot` object is read-only, i.e. any modifications you make to that
(3, 9) in bot.walls
```

The maze can be represented as a graph. If you want to use [networkx](https://networkx.github.io) for shortest path algorithms, you can use the `walls_to_graph` function in `pelita.utils`.
The maze is also represented as a graph in the attribute `bot.graph`.

Examples for using a graph representation for shortest path calculations can be found in [demo04_basic_attacker.py](demo04_basic_attacker.py) and [demo05_basic_defender.py](demo05_basic_defender.py).

- **`bot.shape`** is a tuple with the size of the maze. The ususal maze size will be `32x16`, that is `(32, 16)`, unless other layouts are specified.
- **`bot.graph`** is a representation of the maze as a graph. The graph represents the free squares in the maze –i.e. all the non-wall coordinates– and their connections. The `bot.graph` object is an instance of the [`Graph`](https://networkx.org/documentation/stable/reference/classes/graph.html) class from the [networkx](https://networkx.github.io) library. `bot.graph` is immutable: an editable copy of the graph is returned by the `bot.graph.copy()` method if you need it.
Examples for using a graph representation for shortest path calculations using the [networkx](https://networkx.github.io) library can be found in [demo04_basic_attacker.py](demo04_basic_attacker.py) and [demo05_basic_defender.py](demo05_basic_defender.py).
- **`bot.shape`** is a tuple with the size of the maze. The usual maze size will be `32x16`, that is `(32, 16)`, unless other layouts are specified.
- **`bot.homezone`** is a tuple of all the coordinates of your side of the maze that are not a wall. If for example you are the red team in a `32×16` maze, your homezone might be:
```python
Expand Down
8 changes: 1 addition & 7 deletions demo04_basic_attacker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

import networkx

from pelita.utils import walls_to_graph


TEAM_NAME = 'Basic Attacker Bots'

def init_attack_state():
Expand All @@ -25,9 +22,6 @@ def move(bot, state):
# food targets.
state[0] = init_attack_state()
state[1] = init_attack_state()
# Initialize a graph representation of the maze.
# This can be shared among our bots.
state['graph'] = walls_to_graph(bot.walls)

# define a few variables for less typing
enemy = bot.enemy
Expand All @@ -42,7 +36,7 @@ def move(bot, state):
target = bot.random.choice(enemy[0].food)
# use networkx to get the shortest path from here to the target
# we do not use the first position, which is always equal to bot_position
path = networkx.shortest_path(state['graph'], bot.position, target)[1:]
path = networkx.shortest_path(bot.graph, bot.position, target)[1:]
state[bot.turn]["attack_path"] = path
state[bot.turn]["attack_target"] = target

Expand Down
6 changes: 1 addition & 5 deletions demo05_basic_defender.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

import networkx

from pelita.utils import walls_to_graph


TEAM_NAME = 'Basic Defender Bots'

Expand All @@ -20,8 +18,6 @@ def init_defend_state():

def move(bot, state):
if state == {}:
# store the graph representation of the maze in the state object
state['graph'] = walls_to_graph(bot.walls)
state[0] = init_defend_state()
state[1] = init_defend_state()

Expand All @@ -39,7 +35,7 @@ def move(bot, state):
raise Exception('We should never be here!')

# get the next position along the shortest path to our target enemy bot
next_pos = networkx.shortest_path(state['graph'], bot.position, target)[1]
next_pos = networkx.shortest_path(bot.graph, bot.position, target)[1]
# we save the current target in our state dictionary
state[bot.turn]["defend_target"] = target

Expand Down
6 changes: 1 addition & 5 deletions demo06_switching_bots.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# strategy. Once the attacking bot is killed, it restarts as a defender, while
# the previous defender changes its personality and becomes the new attacker.

from pelita.utils import walls_to_graph

from demo05_basic_defender import move as move_defender
from demo04_basic_attacker import move as move_attacker

Expand Down Expand Up @@ -34,9 +32,7 @@ def move(bot, state):
# (and each of the functions only works with “their” prefixed version).

if state == {}:
# here each bot has its own state dictionary (0 and 1) and they share
# the same game state information in the "graph"
state['graph'] = walls_to_graph(bot.walls)
# here each bot has its own state dictionary (0 and 1)
state[0] = init_state("attacker")
state[1] = init_state("defender")

Expand Down

0 comments on commit 491a2e4

Please sign in to comment.