Repository: ASPP/pelita

Issue:
Better Bot repr
For reference, this is the current `repr(bot)`:

    <pelita.team.Bot object at 0x102778b90>

This is `str(bot)`:

```
Playing on red side. Current turn: 1. Bot: y. Round: 1, score: 0:0. timeouts: 0:0
################################
#.  . #.   .              . #.y#
#     #  #### ###  .    #  . .x#
#    .  ##..#     #########    #
#.    #  #  #.### . ..  .. .#  #
######## #. #     ####  #.### ##
# .#     #. #     .#    .   #  #
#    ## ##.    ##..#  # .#  # ##
## #  #. #  #..##    .## ##    #
#a #   .    #.     # .#     #. #
##b###.#  ####     # .# ########
#  #. ..  .. . ###.#  #  #    .#
#    #########     #..##  .    #
# . .  #    .  ### ####  #     #
# .# .              .   .# .  .#
################################
Bots: {'a': (1, 9), 'x': (30, 2), 'b': (2, 10), 'y': (30, 1)}
Noisy: {'a': True, 'x': False, 'b': True, 'y': False}
Food: [(30, 14), (21, 10), (24, 4), (20, 14), (26, 1), (24, 7), (27, 4), (29, 9), (18, 6), (21, 8), (20, 12), (21, 4), (25, 4), (27, 2), (18, 4), (24, 14), (17, 7), (18, 7), (29, 1), (20, 4), (27, 14), (21, 9), (21, 12), (18, 11), (24, 6), (25, 5), (29, 2), (19, 2), (26, 12), (30, 11), (11, 1), (10, 5), (10, 11), (13, 4), (12, 13), (2, 13), (7, 9), (10, 6), (6, 10), (10, 3), (4, 1), (13, 11), (11, 11), (2, 14), (13, 8), (14, 8), (7, 1), (4, 13), (6, 11), (5, 14), (1, 1), (11, 3), (10, 7), (1, 4), (13, 9), (2, 6), (5, 3), (4, 11), (7, 11), (7, 8)]
```

At the least I think it should be something like:

    <Bot: y (red), (30, 1), turn: 1, round: 1>

Discussion:
@otizonaizit: > At the least I think it should be something like:
> ```
><Bot: y (red), (30, 1), turn: 1, round: 1>
> ```

but that is what is there already in the first line, no?
> ```
> Playing on red side. Current turn: 1. Bot: y. Round: 1, score: 0:0. timeouts: 0:0
> ```

The strings can be reshuffled, yes, but all the info is there already.

Should we short circuit `__repr__` to `__str__`, so that we can use that representation in the exceptions too? @Debilski: I think `__repr__` should only include the first line of `__str__`, but even this might be too verbose. We should see that code like

    print([b, b.other])

stays readable.@Debilski: (Discussion can also be postponed; I’m in the middle of restructuring the network code and we can approach this part later.)

Solution patch:
diff --git a/pelita/team.py b/pelita/team.py
index a3ef1138f..aea973275 100644
--- a/pelita/team.py
+++ b/pelita/team.py
@@ -726,6 +726,9 @@ def __str__(self):
             out.write(footer)
             return out.getvalue()
 
+    def __repr__(self):
+        return f'<Bot: {self.char} ({"blue" if self.is_blue else "red"}), {self.position}, turn: {self.turn}, round: {self.round}>'
+
 
 # def __init__(self, *, bot_index, position, initial_position, walls, homezone, food, is_noisy, score, random, round, is_blue):
 def make_bots(*, walls, shape, initial_positions, homezone, team, enemy, round, bot_turn, rng, graph):


Test patch:
diff --git a/test/test_team.py b/test/test_team.py
index f6db4eb9f..babe7cccb 100644
--- a/test/test_team.py
+++ b/test/test_team.py
@@ -695,3 +695,34 @@ def asserting_team(bot, state):
     # check that all is good
     assert state['fatal_errors'] == [[], []]
 
+
+def test_bot_repr():
+    test_layout = """
+        ##################
+        #.#... .##.     y#
+        # # #  .  .### #x#
+        # ####.   .      #
+        #      .   .#### #
+        #a# ###.  .  # # #
+        #b     .##. ...#.#
+        ##################
+    """
+
+    parsed = parse_layout(test_layout)
+
+    def asserting_team(bot, state):
+        bot_repr = repr(bot)
+        if bot.is_blue and bot.round == 1:
+            assert bot_repr == f"<Bot: {bot.char} (blue), {bot.position}, turn: {bot.turn}, round: 1>"
+        elif not bot.is_blue and bot.round == 1:
+            assert bot_repr == f"<Bot: {bot.char} (red), {bot.position}, turn: {bot.turn}, round: 1>"
+        else:
+            assert False, "Should never be here."
+
+        return bot.position
+
+    state = run_game([asserting_team, asserting_team], max_rounds=1, layout_dict=parsed,
+                     allow_exceptions=True)
+    # assertions might have been caught in run_game
+    # check that all is good
+    assert state['fatal_errors'] == [[], []]