Guess the Number 2

My second attempt at creating a "Guess the Number" game using pygame.

Python Pygame

Overview

Guess the Number 2 is my second ever Python project and my first attempt at building a graphical game using Pygame. After creating a console‑only version, I wanted to understand how to structure a small application using object‑oriented programming and how to manage state, events, and user interaction in a real game loop. This project became a practical way to apply those concepts while building something simple, visual, and interactive.

Project Structure

The repository is organised into small, focused modules that each handle a specific responsibility:

  • main.py — the entry point that initialises Pygame, sets up the game window, and starts the main loop.
  • game.py — the core game logic, including number generation, guess checking, state transitions, and rendering text to the screen.
  • button.py — a reusable Button class that handles drawing, hover states, and click detection.
  • history.csv — a simple log of previous guesses and outcomes, used to experiment with basic persistence.

This structure helped me understand how to break a project into components instead of writing everything in one file

Technical Breakdown

The game uses Pygame to render text, handle events, and update the screen. The logic is encapsulated in classes, which was my main learning goal:

  • Object‑oriented design — separating the game logic (Game class) from UI elements (Button class).
  • Event handling — capturing keyboard input and button clicks through the Pygame event loop.
  • State management — tracking the current guess, the target number, win/loss conditions, and resetting the game.
  • Rendering — drawing text, updating the screen, and refreshing the UI each frame.
  • Basic persistence — writing results to history.csv to understand file I/O

Challenges and How I Solved Them

  • - Structuring the game loop — initially everything lived in main.py, but moving logic into game.py made the code easier to follow and extend.
  • - Button interactions — detecting clicks reliably required separating drawing from event handling, which led to the dedicated Button class.
  • - Managing state cleanly — I learned to avoid global variables and instead store state inside the Game object.
  • These challenges taught me how to think about small applications as systems rather than scripts.

Button Class

Python - Pygame
class ButtonStd():
  def __init__(self, colour, x, y, width, height, text =""):
    self.colour = colour
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.text = text
    self.clicked = False
    self.rect = pygame.Rect(x, y, width, height)

  def draw(self, surface, font, outlined=False):
    # Hover: brighten colour when mouse is over button
    pos = pygame.mouse.get_pos()
    if self.rect.collidepoint(pos):
      draw_colour = tuple(min(v + 45, 255) for v in self.colour)
    else:
      draw_colour = self.colour

    # Darker border derived from button colour
    if outlined:
      border_colour = tuple(max(v - 55, 0) for v in self.colour)
      pygame.draw.rect(surface, border_colour, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0, 10)

    # Button body with rounded corners
    pygame.draw.rect(surface, draw_colour, (self.x, self.y, self.width, self.height), 0, 8)

    # White text centred on button
    if self.text != "":
      text_surf = font.render(self.text, True, (255, 255, 255))
      surface.blit(text_surf, (
        self.x + (self.width / 2 - text_surf.get_width() / 2),
        self.y + (self.height / 2 - text_surf.get_height() / 2)
      ))

    if self.clicked == True:
      self.clicked = False
      return True
    else: pass

  def isclicked(self, event):
    pos = pygame.mouse.get_pos()
    if event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.FINGERDOWN:
      if event.button == 1:
        if self.rect.collidepoint(pos):
          self.clicked = True
        else:
          self.clicked = False

What I Learned

This project was a major step in my early Python journey. It helped me:

  • Understand how classes interact in a real program
  • Build confidence with Pygame’s event loop
  • Separate logic, UI, and state into clear components
  • Move from “just writing code” to designing small, maintainable modules

It also showed me how much easier it is to extend a project when the structure is clean.

Future Improvements

  • Add difficulty levels or timed modes
  • Improve UI layout and typography
  • Add sound effects and animations
  • Replace CSV logging with a small JSON or SQLite history
  • Package the game as a standalone executable

Home Screen

Home Screen

Gameplay

Gameplay

Win

Win

Lose

Lose

Game History

Game History

Game Options

Game Options