juegos-python/Minesweeper/Minesweeper.py
2023-04-10 00:48:44 +02:00

254 lines
7.7 KiB
Python

# -----------------------------------------------------------------------------
#
# Minesweeper
# Language - Python
# Modules - pygame, sys, random
#
# Controls - Single Mouse Click on any box, r to reset the grid
#
# By - Jatin Kumar Mandav
#
# Website - https://jatinmandav.wordpress.com
#
# YouTube Channel - https://www.youtube.com/channel/UCdpf6Lz3V357cIZomPwjuFQ
# Twitter - @jatinmandav
#
# -----------------------------------------------------------------------------
import pygame
import sys
import random
pygame.init()
width = 510
height = 510
display = pygame.display.set_mode((width, height))
pygame.display.set_caption("Minesweeper")
clock = pygame.time.Clock()
background = (51, 51, 51)
white = (236, 240, 241)
darkWhite = (174, 182, 191)
gray = (52, 73, 94)
yellow = (244, 208, 63)
lightred = (236, 112, 99)
grid = []
size = 10
mineProb = 30
safeSpots = 0
revealedSpots = 0
numberFont = pygame.font.SysFont("Times New Roman", width/(size*2))
font = pygame.font.SysFont("Times New Roman", 35)
# Property of Each Cell on Grid
class Spot:
def __init__(self, x, y, w, h, mineState):
self.x = x
self.y = y
self.w = w
self.h = h
self.isMine = mineState
self.neighbors = 0
self.reveal = False
# Draw Cells
def draw(self):
if not self.reveal:
pygame.draw.rect(display, white, (self.x, self.y, self.w, self.h))
else:
pygame.draw.rect(display, darkWhite, (self.x, self.y, self.w, self.h))
if self.reveal:
if self.isMine:
pygame.draw.ellipse(display, gray, (self.x + self.w/4, self.y + self.h/4, self.w/2, self.h/2))
else:
if not self.neighbors == 0:
num = numberFont.render(str(self.neighbors), True, gray)
display.blit(num, (self.x + self.w/4, self.y + self.h/4))
# Check if the Cell is a Mine and reveal others if Block has no Mine Surrounding
def checkForMine(self, i, j):
global revealedSpots
self.reveal = True
revealedSpots += 1
if self.isMine:
for i in range(size):
for j in range(size):
grid[i][j].reveal = True
drawGrid()
pygame.display.update()
gameLost()
elif grid[i][j].neighbors == 0:
if i > 0:
if not grid[i-1][j].isMine:
grid[i-1][j].reveal = True
revealedSpots += 1
if j > 0:
if not grid[i][j-1].isMine:
grid[i][j-1].reveal = True
revealedSpots += 1
if i < size - 1:
if not grid[i+1][j].isMine:
grid[i+1][j].reveal = True
revealedSpots += 1
if j < size - 1:
if not grid[i][j+1].isMine:
grid[i][j+1].reveal = True
revealedSpots += 1
if i > 0 and j > 0:
if not grid[i-1][j-1].isMine:
grid[i-1][j-1].reveal = True
revealedSpots += 1
if i > 0 and j < size - 1:
if not grid[i-1][j+1].isMine:
grid[i-1][j+1].reveal = True
revealedSpots += 1
if i < size - 1 and j > 0:
if not grid[i+1][j-1].isMine:
grid[i+1][j-1].reveal = True
revealedSpots += 1
if i < size - 1 and j < size - 1:
if not grid[i+1][j+1].isMine:
grid[i+1][j+1].reveal = True
revealedSpots += 1
# Count Neighboring Mines
def countNeighborMines(self, i, j):
if not self.isMine:
if i > 0:
if grid[i-1][j].isMine:
self.neighbors += 1
if j > 0:
if grid[i][j-1].isMine:
self.neighbors += 1
if i < size - 1:
if grid[i+1][j].isMine:
self.neighbors += 1
if j < size - 1:
if grid[i][j+1].isMine:
self.neighbors += 1
if i > 0 and j > 0:
if grid[i-1][j-1].isMine:
self.neighbors += 1
if i > 0 and j < size - 1:
if grid[i-1][j+1].isMine:
self.neighbors += 1
if i < size - 1 and j > 0:
if grid[i+1][j-1].isMine:
self.neighbors += 1
if i < size - 1 and j < size - 1:
if grid[i+1][j+1].isMine:
self.neighbors += 1
# Initialize the Grid
def generateGrid():
global grid, safeSpots
grid = []
for i in range(size):
grid.append([])
for j in range(size):
prob = random.randint(1, 100)
if prob < mineProb:
newObj = Spot((width/size)*(j), (height/size)*(i), width/size - 3, height/size - 3, True)
else:
safeSpots += 1
newObj = Spot((width/size)*(j), (height/size)*(i), width/size - 3, height/size - 3, False)
grid[i].append(newObj)
for i in range(size):
for j in range(size):
grid[i][j].countNeighborMines(i, j)
# Check if Grid is solved
def gameWon():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
reset()
font.set_bold(True)
text = font.render("You Won the Minesweeper!", True, yellow)
display.blit(text, (width/2 - 250, height/2))
pygame.display.update()
clock.tick(60)
# Check if Game is Lost
def gameLost():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
reset()
font.set_bold(True)
text = font.render("You Lost the Game!", True, (236, 112, 99))
display.blit(text, (width/2 - 250, height/2))
pygame.display.update()
clock.tick(60)
# Draw the Grid
def drawGrid():
for i in range(size):
for j in range(size):
grid[i][j].draw()
# Reset the Grid
def reset():
minesweeper()
# Close the Game
def close():
pygame.quit()
sys.exit()
# The Game
def minesweeper():
loop = True
generateGrid()
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
reset()
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
j = pos[0]/(width/size)
i = pos[1]/(width/size)
grid[i][j].checkForMine(i, j)
display.fill(background)
drawGrid()
if revealedSpots == safeSpots:
gameWon()
pygame.display.update()
clock.tick(60)
minesweeper()