import sys
from math import floor
from random import randint
import pygame
from pygame.locals import QUIT, MOUSEBUTTONDOWN

WIDTH = 20
HEIGHT = 15
SIZE = 50
NUM_OF_BOMBS = 20
EMPTY = 0
BOMB = 1
OPENED = 2
OPENED_COUNT = 0
CHECKED = [
    [
        0 for _ in range(WIDTH)
    ]
    for _ in range(HEIGHT)
]

pygame.init()
SURFACE = pygame.display.set_mode(([WIDTH * SIZE, HEIGHT * SIZE]))
FPSCLOCK = pygame.time.Clock()

def num_of_bomb(field, x_pos, y_pos):
    cnt = 0
    for y_off in range(-1, 2):
        for x_off in range(-1, 2):
            xpos, ypos = (x_pos + x_off, y_pos + y_off)
            if 0 <= xpos < WIDTH and 0 <= ypos < HEIGHT and\
                field[ypos][xpos] == BOMB:
                cnt +=1
    return cnt

def open_tile(field, x_pos, y_pos):
    global OPENED_COUNT
    if CHECKED[y_pos][x_pos]:
        return
    CHECKED[y_pos][x_pos] = True

    for y_off in range(-1, 2):
        for x_off in range(-1, 2):
            xpos, ypos = (x_pos + x_off, y_pos + y_off)
            if 0 <= xpos < WIDTH and 0 <= ypos < HEIGHT and\
                field[ypos][xpos] == EMPTY:
                field[ypos][xpos] = OPENED
                OPENED_COUNT += 1
                cnt = num_of_bomb(field, xpos, ypos)
                if cnt == 0 and not (xpos == x_pos and ypos == y_pos):
                    open_tile(field, xpos, ypos)

def main():
    small_font = pygame.font.SysFont(None, 36)
    large_font = pygame.font.SysFont(None, 72)
    msg_clear = large_font.render("!!CLEARED!!", True, (0, 255, 255))
    msg_over = large_font.render("GAME OVER!!", True, (0, 255, 255))
    msg_rect = msg_clear.get_rect()
    msg_rect.center = (WIDTH*SIZE/2, HEIGHT*SIZE/2)
    game_over = False

    field = [
        [
            EMPTY for x_pos in range(WIDTH)
        ]
        for y_pos in range(HEIGHT)
        ]
    cnt = 0
    while cnt < NUM_OF_BOMBS:
        x_pos, y_pos = randint(0, WIDTH-1), randint(0, HEIGHT - 1)
        if field[y_pos][x_pos] == EMPTY:
            field[y_pos][x_pos] = BOMB
            cnt +=1
    
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1:
                x_pos, y_pos = floor(event.pos[0] / SIZE),\
                            floor(event.pos[1] / SIZE)
                if field[y_pos][x_pos] == BOMB:
                    game_over = True
                else:
                    open_tile(field, x_pos, y_pos)
        

        SURFACE.fill((0, 0, 0))
        for y_pos in range(HEIGHT):
            for x_pos in range(WIDTH):
                tile = field[y_pos][x_pos]
                rect = (x_pos * SIZE, y_pos * SIZE, SIZE, SIZE)
                if tile == EMPTY or tile == BOMB:
                    pygame.draw.rect(SURFACE, (192, 192, 192), rect)
                    if game_over and tile == BOMB:
                        pygame.draw.ellipse(SURFACE, (225, 225, 0), rect)
                elif tile == OPENED:
                    cnt = num_of_bomb(field, x_pos, y_pos)
                    if cnt > 0:
                        num_img = small_font.render(
                            "{}".format(cnt), True, (255, 255, 0)
                        )
                        SURFACE.blit(num_img, (x_pos * SIZE + 10, y_pos * SIZE + 10))

        for idx in range(0, WIDTH*SIZE, SIZE):
            pygame.draw.line(SURFACE, (96, 96, 96), (idx, 0), (idx, HEIGHT * SIZE))
        for idx in range(0, HEIGHT*SIZE, SIZE):
            pygame.draw.line(SURFACE, (96, 96, 96), (0, idx), (WIDTH*SIZE, idx))
        
        if OPENED_COUNT == WIDTH*HEIGHT - NUM_OF_BOMBS:
            SURFACE.blit(msg_clear, msg_rect.topleft)
        elif game_over:
            SURFACE.blit(msg_over, msg_rect.topleft)
        
        pygame.display.update()
        FPSCLOCK.tick(15)
    
if __name__ == "__main__":
    main()

+ Recent posts