CipherMaze: The Ultimate Code Cracking Quest Game Using Python

Introduction:
You can make CipherMaze, a fun and brain-boosting puzzle game, with Python and tkinter. The goal is simple: to get out of the maze, you have to solve different code puzzles to get to each level. The game tests your brainpower by using old cipher methods like the Caesar Cipher, Morse Code, word shifts, and logic questions.
The player begins the game by typing in their name. There is a different code or riddle at each level. If the player figures out the code, they smoothly move on to the next level. If they don’t, they can try again or skip and lose points. During the game, scores are kept track of, and the best ones are saved on a local leaderboard.
The UI has a dark theme that looks modern and buttons that say “Start,” “Retry,” and “Exit.” You can only enter information through text boxes, and messages pop up in windows so you can easily understand them. The game is easy for beginners to learn, but puzzle fans will still find it fun and challenging.
CipherMaze’s blend of entertaining gameplay and education is what sets it apart. It’s not just a game; it helps you learn basic cyphers and logic while also sharpening your mind. Ideal for anyone who enjoys a good brainteaser, including students and programmers.
Required Modules Or Packages:
1. Random: It Provides functions to generate the random numbers.
2. Time: This function Allows the time-related functions like timestamp handling.
3. Tkinter: It is Used to create a GUI applications with windows, buttons, and dialogs.
4. tkinter.messagebox & simpledialog: It Provides a pop-up windows for messages and user input in GUI.
5. Os: It Offers the functions to interact with the operating system.
How To Run The Code:
Method 1:
Step 1 . First , You Download and Install Visual Studio Code or VS Code In your PC or Laptop by VS Code Official Website .
Step 2 . Now Open CMD As Administrator and install the above packages using Pip .
Step 3 . Now Open Visual Studio Code .
Step 4. Now Make The file named as main.py .
Step 5 . Now Copy And Paste The Code from the Link Given Below ⬇️
Step 6 . After pasting The Code , Save This & Click On Run Button .
Step 7 . Now You will See The Output .
Method 2:
Step 1 . First , You Download and Install Visual Studio Code or VS Code In your PC or Laptop by VS Code Official Website .
Step 2 . Now Open CMD As Administrator and install the above packages using Pip .
Step 3 . Now Open the link , which is provided below.
Step 4. Now download the ZIP file of the code.
Step 5 . Now Extract the ZIP file and Open in VS Code.
Step 6 . Now go to the main file and click on run button.
Step 7 . Now You will See The Output .
Code Explanation:
This Python code is used to Create a CipherMaze: The Ultimate Code Cracking Quest Game.
Importing Required Libraries:
import random
import time
import tkinter as tk
from tkinter import messagebox, simpledialog
import os
1. Random: It Provides functions to generate the random numbers.
2. Time: This function Allows the time-related functions like timestamp handling.
3. Tkinter: It is Used to create a GUI applications with windows, buttons, and dialogs.
4. tkinter.messagebox & simpledialog: It Provides a pop-up windows for messages and user input in GUI.
5. Os: It Offers the functions to interact with the operating system.
1. Puzzle Logic Functions:
These functions will define the different types of puzzles which the player will solve. Each logic function will returns a prompt for the player and the correct answer.
🔹 Example:
def caesar_cipher_puzzle():
shift = random.randint(1, 5)
words = ["escape", "secret", "python", "cipher", "maze"]
word = random.choice(words)
encoded = ''.join([chr((ord(char) - 97 + shift) % 26 + 97) for char in word])
prompt = f"Decode this: {encoded} (Shift: -{shift})"
return prompt, word
This block of the code will generates a Caesar cipher puzzle by shifting the characters in a word and asks the player to decode it.
Other puzzle types include:
- Binary Puzzle
- Pattern-based Number Puzzle
- Logic Puzzle
- Morse Code Puzzle
All these types are stored in puzzle_list:
puzzle_list = [caesar_cipher_puzzle, binary_puzzle, pattern_puzzle, logic_puzzle, morse_puzzle]
2. CipherMazeGame Class:
This is the core game class which manages the UI of the game and gameplay.
Constructor (_init_)
It will Initializes the game window, takes the player’s name, and then prepares the interface.
self.root.title("CipherMaze - Puzzle Adventure")
self.root.attributes('-fullscreen', True)
self.player_name = simpledialog.askstring("Player Name", "Enter your name:")
3. GUI Widget Creation:
def create_widgets(self):
...
self.title_label = tk.Label(...)
self.answer_entry = tk.Entry(...)
self.submit_btn = tk.Button(..., command=self.check_answer)
These are the player input and display elements shown during gameplay.
4. Start Screen and Navigation:
def show_start_screen(self):
...
start_btn = tk.Button(..., command=self.fade_in_game)
leaderboard_btn = tk.Button(..., command=self.show_leaderboard)
It will Displays the buttons for starting the game, viewing scores, or exiting.
5. Game Flow and Puzzle Loading:
def load_puzzle(self):
...
self.current_puzzle = random.choice(puzzle_list)
self.prompt, self.correct_answer = self.current_puzzle()
It will Loads a random puzzle and displays it to the player.
6. Answer Checking:
def check_answer(self):
if answer == self.correct_answer:
...
self.score += ...
self.level += 1
It will Compares the user or player inputs with the correct answer, then updates the score, and then loads the next puzzle.
7. Game End and Score Saving:
def end_game(self):
self.save_score()
messagebox.showinfo("Game Over", ...)
self.root.quit()
When all levels are completed, the score is saved to a file and the game will ends.
8. Leaderboard:
def show_leaderboard(self):
if os.path.exists("highscores.txt"):
...
It will Reads and displays the top scores of all the players from a text file.
Source Code:
import random
import time
import tkinter as tk
from tkinter import messagebox, simpledialog
import os
# ---------------- Puzzle Logic Functions ---------------- #
def caesar_cipher_puzzle():
shift = random.randint(1, 5)
words = ["escape", "secret", "python", "cipher", "maze"]
word = random.choice(words)
encoded = ''.join([chr((ord(char) - 97 + shift) % 26 + 97) for char in word])
prompt = f"Decode this: {encoded} (Shift: -{shift})"
return prompt, word
def binary_puzzle():
text = random.choice(["hi", "ok", "go", "no"])
binary = ' '.join([format(ord(c), '08b') for c in text])
prompt = f"Decode this binary to text: {binary}"
return prompt, text
def pattern_puzzle():
start = random.randint(2, 5)
pattern = [start * (2 ** i) for i in range(4)]
prompt = f"Sequence: {pattern[:-1]} ?"
return prompt, str(pattern[-1])
def logic_puzzle():
prompt = "One of these is true. Which switch opens the door? A: Switch 1 B: Switch 2"
return prompt, "1"
def morse_puzzle():
morse_dict = {
"a": ".-", "b": "-...", "c": "-.-.", "d": "-..", "e": ".", "f": "..-.",
"g": "--.", "h": "....", "i": "..", "j": ".---", "k": "-.-", "l": ".-..",
"m": "--", "n": "-.", "o": "---", "p": ".--.", "q": "--.-", "r": ".-.",
"s": "...", "t": "-", "u": "..-", "v": "...-", "w": ".--", "x": "-..-",
"y": "-.--", "z": "--.."
}
word = random.choice(["run", "code", "key"])
morse = ' '.join([morse_dict[char] for char in word])
prompt = f"Decode this Morse: {morse}"
return prompt, word
puzzle_list = [caesar_cipher_puzzle, binary_puzzle, pattern_puzzle, logic_puzzle, morse_puzzle]
# ---------------- GUI Game Class ---------------- #
class CipherMazeGame:
def __init__(self, root):
self.root = root
self.root.title("CipherMaze - Puzzle Adventure")
self.root.attributes('-fullscreen', True)
self.root.configure(bg="#1e1e2f")
self.player_name = simpledialog.askstring("Player Name", "Enter your name:")
if not self.player_name:
self.player_name = "Player"
self.level = 1
self.score = 0
self.create_widgets()
self.show_start_screen()
def create_widgets(self):
self.main_frame = tk.Frame(self.root, bg="#1e1e2f")
self.main_frame.pack(fill=tk.BOTH, expand=True)
self.title_label = tk.Label(self.main_frame, text="🌀 CipherMaze – The Puzzle Adventure 🌀", font=("Helvetica", 16, "bold"), fg="white", bg="#1e1e2f")
self.level_label = tk.Label(self.main_frame, text="", font=("Helvetica", 12), fg="#00ffcc", bg="#1e1e2f")
self.puzzle_text = tk.Label(self.main_frame, text="", font=("Helvetica", 14), fg="white", bg="#1e1e2f", wraplength=900)
self.answer_entry = tk.Entry(self.main_frame, font=("Helvetica", 14))
self.submit_btn = tk.Button(self.main_frame, text="Submit", font=("Helvetica", 12), command=self.check_answer, bg="#00cc99", fg="white")
self.status_label = tk.Label(self.main_frame, text="", font=("Helvetica", 12), fg="yellow", bg="#1e1e2f")
def show_start_screen(self):
self.clear_screen()
title = tk.Label(self.main_frame, text="Welcome to CipherMaze", font=("Helvetica", 24, "bold"), fg="white", bg="#1e1e2f")
start_btn = tk.Button(self.main_frame, text="▶ Start Game", font=("Helvetica", 16), bg="#00cc99", fg="white", command=self.fade_in_game)
leaderboard_btn = tk.Button(self.main_frame, text="🏆 Leaderboard", font=("Helvetica", 14), bg="#4455aa", fg="white", command=self.show_leaderboard)
exit_btn = tk.Button(self.main_frame, text="❌ Exit", font=("Helvetica", 14), bg="#cc3333", fg="white", command=self.root.quit)
title.pack(pady=40)
start_btn.pack(pady=10)
leaderboard_btn.pack(pady=10)
exit_btn.pack(pady=10)
def show_leaderboard(self):
self.clear_screen()
title = tk.Label(self.main_frame, text="🏆 High Scores", font=("Helvetica", 20), fg="white", bg="#1e1e2f")
title.pack(pady=10)
if os.path.exists("highscores.txt"):
with open("highscores.txt", "r") as f:
scores = sorted(f.readlines(), key=lambda x: int(x.strip().split(": ")[1]), reverse=True)[:5]
for score in scores:
tk.Label(self.main_frame, text=score.strip(), font=("Helvetica", 14), fg="cyan", bg="#1e1e2f").pack()
else:
tk.Label(self.main_frame, text="No scores yet!", font=("Helvetica", 14), fg="gray", bg="#1e1e2f").pack()
tk.Button(self.main_frame, text="🔙 Back", font=("Helvetica", 12), command=self.show_start_screen).pack(pady=20)
def clear_screen(self):
for widget in self.main_frame.winfo_children():
widget.destroy()
def fade_in_game(self):
self.clear_screen()
self.main_frame.update()
self.load_puzzle()
def load_puzzle(self):
self.clear_screen()
self.title_label.pack(pady=10)
self.level_label.config(text=f"Room: {self.level}")
self.level_label.pack()
self.current_puzzle = random.choice(puzzle_list)
self.prompt, self.correct_answer = self.current_puzzle()
self.start_time = time.time()
self.puzzle_text.config(text=self.prompt)
self.puzzle_text.pack(pady=20)
self.answer_entry.delete(0, tk.END)
self.answer_entry.pack()
self.submit_btn.pack(pady=10)
self.status_label.pack()
def check_answer(self):
answer = self.answer_entry.get().strip().lower()
end_time = time.time()
if answer == self.correct_answer:
elapsed = int(end_time - self.start_time)
self.status_label.config(text=f"✅ Correct! Time: {elapsed} sec")
self.score += max(100 - self.level * 5 - elapsed, 10)
self.level += 1
if self.level > 5:
self.end_game()
else:
self.root.after(1000, self.load_puzzle)
else:
self.status_label.config(text="❌ Wrong! Try again")
def end_game(self):
self.save_score()
messagebox.showinfo("Game Over", f"Well done, {self.player_name}!\nScore: {self.score}")
self.root.quit()
def save_score(self):
with open("highscores.txt", "a") as f:
f.write(f"{self.player_name}: {self.score}\n")
# ---------------- Main ---------------- #
if __name__ == "__main__":
root = tk.Tk()
game = CipherMazeGame(root)
root.mainloop()
Output:


