Skip to content

Instantly share code, notes, and snippets.

@sht0rmx
Last active November 27, 2025 06:09
Show Gist options
  • Select an option

  • Save sht0rmx/a5b978856bc948622d48906c150e4dc7 to your computer and use it in GitHub Desktop.

Select an option

Save sht0rmx/a5b978856bc948622d48906c150e4dc7 to your computer and use it in GitHub Desktop.
demonstration of the calculation of Pi using the Monte Carlo method
import pygame
import math
from random import randint
WIDTH, HEIGHT = 800, 800
RED = (255, 100, 100)
GREEN = (50, 255, 50)
WHITE = (255, 255, 255)
BLACK = (20, 20, 20)
calculate_pi = lambda inside, total: 4 * (inside / total) if total > 0 else 0
rnd_coords = lambda max_x, max_y: {"x": randint(0, max_x), "y": randint(0, max_y)}
class Circle:
def __init__(self, x, y, radius, color, width=0):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.width = width
self.center = (x, y)
def draw(self, surface):
pygame.draw.circle(surface, self.color, self.center, self.radius, self.width)
class Rice(Circle):
def __init__(self):
super().__init__(radius=5, color=RED, width=5, **rnd_coords(WIDTH, HEIGHT))
self.is_inside = False
class Dish(Circle):
def __init__(self):
super().__init__(WIDTH // 2, HEIGHT // 2, HEIGHT // 2, WHITE, width=2)
def check_contains(self, rice_obj):
dx = self.x - rice_obj.x
dy = self.y - rice_obj.y
distance = math.sqrt(dx ** 2 + dy ** 2)
return distance <= self.radius
rices = []
dish = Dish()
def spawn_rice(amount):
for _ in range(amount):
new_rice = Rice()
if dish.check_contains(new_rice):
new_rice.is_inside = True
new_rice.color = GREEN
else:
new_rice.is_inside = False
new_rice.color = RED
rices.append(new_rice)
def draw_text(scr):
inside_count = sum(1 for r in rices if r.is_inside)
total_count = len(rices)
current_pi = calculate_pi(inside_count, total_count)
font = pygame.font.SysFont("Calibri", 32)
text_surf = font.render(f"Total: {total_count} | Inside: {inside_count}", True, WHITE)
pi_surf = font.render(f"PI: {current_pi:.5f}", True, (255, 255, 0))
helpers = font.render(f"J rerun; L +count; K -count", True, (200, 200, 200))
bg_width = max(text_surf.get_width(), pi_surf.get_width() + helpers.get_width() + 10)
bg_height = text_surf.get_height() + pi_surf.get_height() + helpers.get_height() + 20
bg_surface = pygame.Surface((bg_width, bg_height))
bg_surface.set_alpha(180)
bg_surface.fill((0, 0, 0))
scr.blit(bg_surface, (5, 5))
scr.blit(text_surf, (15, 15))
scr.blit(pi_surf, (15, 15 + text_surf.get_height()))
scr.blit(helpers, (15, 15 + text_surf.get_height() + pi_surf.get_height()))
if __name__ == "__main__":
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PIDemo")
clock = pygame.time.Clock()
drawn = 0
count = 100
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_j:
rices.clear()
drawn = 0
elif event.key == pygame.K_l:
count += 100
elif event.key == pygame.K_k:
new_count = max(0, count - 100)
if new_count < len(rices):
del rices[new_count:]
count = new_count
if drawn < count:
added = max(1, int((count-drawn) * 0.05))
spawn_rice(added)
drawn += added
screen.fill(BLACK)
dish.draw(screen)
for rice in rices:
rice.draw(screen)
draw_text(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment