Amazing Learning

krakenimages-Br-ayoAxFuQ-unsplash.jpg

Photo by krakenimages on Unsplash Learning should be fun. For this reason I created this toy game to challenge students at my courses. While it starts as a simple visual game it can be run headless to develop an intelligent algorithm autonomously. Help your poor robot escape the maze!

Table of Contents

The Challenge

mika-baumeister-HUyICL8qbEE-unsplash.jpg
Photo by Mika Baumeister on Unsplash Can you find your way out when you only can see the walls near to you and your coordinates? This is a typical robot challenge: organize your activity when you only know your environment. There are some questions that may lead you to the solution:
  • can I model this environment effectively?
  • how can I use my model to plan a strategy?
  • how can I translate my strategy into code?
There may be many correct answers to these question. This also opens up a possible second challenge: which solution performs best?

The implementation

First I chose the Kruskal algorithm to generate a maze, with no particular reason, but with the intention of implementing also other algorithms: the same escape strategy may perform differently with different maze kind. The maze will be defined within a rectangular grid of square cells which may be limited by walls; while the Kruskal algorithm may be used on any graph this will simplify the design of the game
maze_plan.png
I searched for a simple visualization solution which would allow:
  • interaction from a python CLI
  • the smallest list of dependencies
Tkinter turned out to satisfy both. I would warmly recommend the Effbot documentation site to learn about it. The next step was to choose a single compact data structure to represent both the concept of a grid cell and of the walls (partially) surrounding it. I choose to represent

Installation

This game is designed to use only packages from standard python library; this installation procedure does just install one package I assume there is already a python installation.
pip install git+https://github.com/noiseOnTheNet/maze_robot.git

Basic Usage

Launch a command python command line then type the following
# imports the robot object and 4 directions
from maze_robot import Robot, N, S, E, W
# create a new robot instance
r = Robot()
# shows the maze
r.view()
A tk window with a 10×10 random maze appears: the maze is all connected.
maze0.png
The robot is represented by a circle while the exit is represented by a square Coordinates start from 0,0 in the top left corner and grow moving right (x coordinate) or down (y coordinate) The robot will always start at 0,0 while the exit is put randomly somewhere In case you want to launch it within an ipython shell please execute the following command in advance:
%gui tk

Moving around the maze

You can move around your robot by using the move method, passing one direction (N, S, W, E) enumeration object
r.move(N)
if there is no wall in that direction the operation succeeds returning a true value, otherwise a false value is returned The robot has a “geolocation” functionality: it knows where it is in the grid. To get its position you can look at the “position” read-only attribute
r.position
# it returns a tuple of integers e.g. (1, 2)

Escaping the maze

You can guide the robot to the exit by moving it around until you reach the exit. The exit is sensed by the robot using the exit method
r.exit()
this method returns true if the robot is in the same grid cell as the exit. But this is not the funniest way to use the robot: I think the funniest way is to see the robot find the exit by itself. While you can see the whole maze, the robot does not. It just see the walls around its position.
r.walls
# returns a tuple of directions where walls are e.g.(N, W, S)

Leaving a trace

If you want to see where your robot moves you can leave a graphical trace on the maze floor by using the down_pen() method.
r.down_pen()
Now the robot will leave a red track behind. The robot cannot sense this track so it is only for you to see
maze1.png
When you want to stop littering the maze you can use up_pen()
r.up_pen()

Advanced Usage

As the main goal is to create algorithms it may be convenient to have a finer control on the environment

Changing Maze size

you can provide your own maze by using the Maze class
from maze_robot.robot import Maze
maze = Maze.kruskal(cols=20,rows=10)
r = Robot(maze)
r.view()
maze2.png
Have fun with larger mazes! Warning: the current implementation of the maze generation is not the most efficient, larger mazes may be slow to create.

Deterministic Random Maze Creation

If you want to test your algorithm on a specific maze you can provide a seed which will generate always the same maze.
from maze_robot.robot import Maze
maze = Maze.kruskal(cols=20,rows=10, seed=0)
r = Robot(maze)
r.view()

Conclusions

So far student’s response looks positive: I will update this post when I collect more feedbacks

marco.p.v.vezzoli

Self taught assembler programming at 11 on my C64 (1983). Never stopped since then -- always looking up for curious things in the software development, data science and AI. Linux and FOSS user since 1994. MSc in physics in 1996. Working in large semiconductor companies since 1997 (STM, Micron) developing analytics and full stack web infrastructures, microservices, ML solutions

You may also like...