Skip to content

Commit

Permalink
Created a maze game (#687)
Browse files Browse the repository at this point in the history
## Pull Request for PyVerse 💡

### Requesting to submit a pull request to the PyVerse repository.

---

#### Issue Title
**Please enter the title of the issue related to your pull request.**  
[Code Addition Request]: Addition of a maze game in game development

- [x] I have provided the issue title.

---

#### Info about the Related Issue
**What's the goal of the project?**  To create a game using python 
*Describe the aim of the project.* To understand that games can be
developed using python

- [x] I have described the aim of the project.

---

#### Name
**Please mention your name.**  
Vuppu Chinmay

- [x] I have provided my name.

---

#### GitHub ID
**Please mention your GitHub ID.**  
[*Enter your GitHub ID here.*](https://github.com/Chin-may02)

- [x] I have provided my GitHub ID.

---

#### Email ID
**Please mention your email ID for further communication.**  
[email protected]

- [x] I have provided my email ID.

---

#### Identify Yourself
**Mention in which program you are contributing (e.g., WoB, GSSOC, SSOC,
SWOC).**
- Contributor and gssoc-ext and hacktoberfest 

- [x] I have mentioned my participant role.

---

#### Closes
**Enter the issue number that will be closed through this PR.**  
*Closes: #668 

- [x] I have provided the issue number.

---

#### Describe the Add-ons or Changes You've Made
**Give a clear description of what you have added or modified.**  
Game using python to solve a maze 

- [x] I have described my changes.

---

#### Type of Change
**Select the type of change:**  
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Code style update (formatting, local variables)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

---

#### How Has This Been Tested?
**Describe how your changes have been tested.**  
Locally ran it in my computer 

- [x] I have described my testing process.

---

#### Checklist
**Please confirm the following:**  
- [x] My code follows the guidelines of this project.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly wherever it was hard to
understand.
- [x] I have made corresponding changes to the documentation.
- [x] My changes generate no new warnings.
- [x] I have added things that prove my fix is effective or that my
feature works.
- [x] Any dependent changes have been merged and published in downstream
modules.
  • Loading branch information
UTSAVS26 authored Oct 19, 2024
2 parents 9b2b6ef + ba57fa7 commit 2a7eb35
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 0 deletions.
193 changes: 193 additions & 0 deletions Game_Development/Maze/Maze.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import random
import ipywidgets as widgets
from IPython.display import display, clear_output, HTML
import time

def generate_maze(size):
maze = [["#" for _ in range(size)] for _ in range(size)]

def carve_passages(x, y):
directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
random.shuffle(directions)
for dx, dy in directions:
nx, ny = x + dx, y + dy
if 1 <= nx < size - 1 and 1 <= ny < size - 1 and maze[nx][ny] == "#":
maze[x + dx // 2][y + dy // 2] = " "
maze[nx][ny] = " "
carve_passages(nx, ny)

maze[1][1] = " "
carve_passages(1, 1)
maze[size - 2][size - 2] = " "

for _ in range(size // 2):
x, y = random.randint(1, size - 2), random.randint(1, size - 2)
if maze[x][y] == " ":
maze[x][y] = "#"

return maze

def print_maze(maze, player_position):
output = ""
for i, row in enumerate(maze):
line = ""
for j, cell in enumerate(row):
if (i, j) == player_position:
line += "<span style='color: green;'>🧍</span>"
else:
line += "<span style='color: white;'>{}</span>".format(cell)
output += line + "<br>"
return output

class MazeGame:
def __init__(self):
self.size = 0
self.maze = []
self.position = (1, 1)
self.exit_point = None
self.move_limit = 0
self.move_count = 0
self.user_path = []
self.desired_path = []
self.output_widget = widgets.Output()
self.start_game()

def start_game(self):
clear_output(wait=True)
print("🎮 Select difficulty level: ")
print("1. Intermediate (11x11)")
print("2. Hard (15x15)")
print("3. Very Hard (21x21)")

self.difficulty_dropdown = widgets.Dropdown(
options=['1', '2', '3'],
description='Difficulty:',
)
self.start_button = widgets.Button(description="Start Game")
self.start_button.on_click(self.set_difficulty)

display(self.difficulty_dropdown, self.start_button, self.output_widget)

def set_difficulty(self, b):
if self.difficulty_dropdown.value == '1':
self.size = 11
self.move_limit = 20
elif self.difficulty_dropdown.value == '2':
self.size = 15
self.move_limit = 30
else:
self.size = 21
self.move_limit = 40

self.maze = generate_maze(self.size)
self.exit_point = (self.size - 2, self.size - 2)
self.position = (1, 1)
self.move_count = 0
self.user_path = []
self.desired_path = self.calculate_desired_path()

self.play_game()

def calculate_desired_path(self):
from collections import deque

queue = deque([(1, 1, [])])
visited = set()
visited.add((1, 1))

while queue:
x, y, path = queue.popleft()
if (x, y) == self.exit_point:
return path

directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for dx, dy in directions:
nx, ny = x + dx, y + dy
if (0 <= nx < self.size and 0 <= ny < self.size and
self.maze[nx][ny] == " " and (nx, ny) not in visited):
visited.add((nx, ny))
queue.append((nx, ny, path + [(nx, ny)]))

return []

def play_game(self):
clear_output(wait=True)
self.start_time = time.time()
with self.output_widget:
display(HTML("<h2 style='color: blue;'>Welcome to the Maze Game!</h2>"))
self.update_maze()

button_box = widgets.HBox([
widgets.Button(description="Up"),
widgets.Button(description="Down"),
widgets.Button(description="Left"),
widgets.Button(description="Right"),
])

for button in button_box.children:
button.on_click(self.move_player)

display(button_box)

def move_player(self, button):
direction = button.description.lower()
new_position = self.position

if direction == "up":
new_position = (self.position[0] - 1, self.position[1])
elif direction == "down":
new_position = (self.position[0] + 1, self.position[1])
elif direction == "left":
new_position = (self.position[0], self.position[1] - 1)
elif direction == "right":
new_position = (self.position[0], self.position[1] + 1)

if (0 <= new_position[0] < self.size and
0 <= new_position[1] < self.size and
self.maze[new_position[0]][new_position[1]] != "#"):
self.position = new_position
self.user_path.append(new_position)
self.move_count += 1

if self.position == self.exit_point:
self.display_win_message()
elif self.move_count >= self.move_limit:
self.display_loss_message()
else:
self.update_maze()
else:
with self.output_widget:
print("<span style='color: red;'>🚫 Invalid move! Can't go that way. Try again.</span>")

def update_maze(self):
with self.output_widget:
clear_output(wait=True)
print(HTML(print_maze(self.maze, self.position)))
print(f"<span style='color: yellow;'>Moves left: {self.move_limit - self.move_count}</span>")
print("<span style='color: cyan;'>Use the buttons to move.</span>")

def display_win_message(self):
clear_output(wait=True)
score = self.calculate_score()
with self.output_widget:
print("<span style='color: green;'>🎉 Congratulations! You've reached the exit! 🎉</span>")
print(f"<span style='color: white;'>Total moves: {self.move_count}</span>")
print(f"<span style='color: gold;'>Your score: {score}</span>")
self.start_game()

def display_loss_message(self):
clear_output(wait=True)
with self.output_widget:
print("<span style='color: red;'>🛑 Time's up or you've run out of moves! 🛑</span>")
print(f"<span style='color: white;'>Total moves: {self.move_count}</span>")
score = self.calculate_score()
print(f"<span style='color: gold;'>Your score: {score}</span>")
self.start_game()

def calculate_score(self):
correct_moves = len(set(self.user_path) & set(self.desired_path))
total_moves = len(self.user_path)
score = correct_moves * 10 - (total_moves - correct_moves) * 5
return max(score, 0)

MazeGame()
27 changes: 27 additions & 0 deletions Game_Development/Maze/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
*Maze Runner*


🎯 Goal

The goal of this project is to create an interactive maze game that allows users to navigate through a procedurally generated maze using directional commands.

🧾 Description

This project is Maze Runner, where users can engage with a maze, trying to find the exit while managing their moves. The application generates a random maze based on selected difficulty levels and keeps track of user movements, providing feedback on their progress.

🧮 What I Have Done!

1. Implemented a maze generation algorithm to create a playable maze with walls and paths.
2. Developed a player movement system that allows users to navigate through the maze using directional buttons.
3. Integrated a scoring system that evaluates player performance based on the path taken and moves made.
4. Included a user interface with clear visual feedback and messages for winning or losing the game.

📚 Libraries Needed

1. random - For generating random maze layouts.
2. ipywidgets - To create interactive buttons and display elements in Jupyter Notebook.
3. IPython.display - For rendering HTML and managing output in the notebook.

📢 Conclusion

In conclusion, the Maze Runner project highlights an engaging way for users to challenge themselves in navigating mazes. The code serves as a foundational platform for potential enhancements, such as different maze designs, additional features, or multiplayer options.

0 comments on commit 2a7eb35

Please sign in to comment.