diff --git a/Graph/graph/maze.py b/Graph/graph/maze.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba0f60a3e4d882a5d856701fc69d215a19d905e8
--- /dev/null
+++ b/Graph/graph/maze.py
@@ -0,0 +1,58 @@
+import random
+
+class Maze:
+
+    def __init__(self, nb_rows, nb_cols):
+        self.nb_rows = nb_rows
+        self.nb_cols = nb_cols
+
+        self.maze = [["."]*nb_cols for _ in range(nb_rows)]
+
+
+    """ Fill randomly the maze regarding the wall_proba
+        @param wall_proba Independent probability for each tile to be a wall
+        @param seed Random seed for reproducibility
+    """
+    def fill_random(self, wall_proba=0.5, seed=None):
+        if seed:
+            random.seed(seed)
+
+        for row in self.maze:
+            for idx in range(self.nb_cols):
+                row[idx] = "#" if random.random() < wall_proba else "."
+
+
+    """ Save a maze to a file """
+    def save(self, filename):
+        with open(filename, "w") as out:
+            out.write(f"{self.nb_rows} {self.nb_cols}")
+            for row in self.maze:
+                out.write("".join(row) + "\n")
+
+
+    """ Load a maze from a file """
+    def load(self, filename):
+        with open(filename) as input:
+            # Parse header
+            header = input.readline()
+            header = [int(x) for x in header.strip().split(" ")]
+            # Construct maze properties
+            self.nb_rows, self.nb_cols = header
+            self.maze = [["."] * self.nb_cols for _ in range(self.nb_rows)]
+            # Fill the maze
+            for row_idx in range(self.nb_rows):
+                line = input.readline()
+                for col_idx in range(self.nb_cols):
+                    self.maze[row_idx][col_idx] = line[col_idx]
+
+
+    def __repr__(self):
+        rows_str = []
+        for row in self.maze:
+            rows_str.append("".join(row))
+        return "\n".join(rows_str)
+
+
+if __name__ == "__main__":
+    m = Maze(10, 10)
+    print(m)