简体   繁体   中英

Python/PyGame Select a Random Boolean From List

Python version: 2.7.8

Objective: Making a Minesweeper game (trying to at least) on python with the PyGame library.

The Code:

import pygame, random, sys
from pygame.locals import *

pygame.init()
width, height = 400, 400
clock = pygame.time.Clock()
DRAWSURF = pygame.display.set_mode((width, height))
pygame.display.set_caption("Matt's Minesweeper")
background = pygame.Surface(DRAWSURF.get_size())
background.fill((255, 255, 255))
DRAWSURF.blit(background, (0, 0))
pygame.display.flip()
board = []


class Square():
    isMine = None

    val = 0
    count = 0

    def draw(self):
        BLACK = (0, 0, 0)
        val = self.val
        count = self.count
        x = 100 + val * 60
        y = 0 + 60 * count
        pygame.draw.rect(DRAWSURF, BLACK, (x, y, 60, 60), 5)
        return self.isMine



class DrawBoard():

    def draw(self, grid):
        item = Square()
        for i in range(0, grid):
            item.val = i
            select = item.draw()
            board.append(select)
            for j in range(grid):
                item.count = j
                select_2 = item.draw()
                board.append(select_2)

class MineSet():
    temp = Square()
    def mineSet(self, mines):
        temp = self.temp
        for i in range(0, mines):
            test = random.choice(board)




while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    clock.tick(30)

    # Insert drawings here
    game = DrawBoard()
    game.draw(5)
    print board
    pygame.display.update()

The Issue: I have each individual square as its own object, as seen in class Square(). In the draw function of the Square class it returns a boolean of None (variable isMine) and when I call it later in the DrawBoard class it appends the object to the list 'board'. To assign the mines for the game, I want to randomly select one of the Square objects created and change the boolean from None to True. Maybe this isn't the best way to assign mines, but I'm trying to do my best. Any help is appreciated.

just generate a random value between 0 and len(list) . Then you can access the value using this syntax: list[random_val] If you want to change a value: list[random_val] = True

 from collections import OrderedDict
 from random import sample

class Square():
    def __init__(self):
        self.val = 0
        self.count = 0
    def draw(self):
        BLACK = (0, 0, 0)
        x = 100 + self.val * 60
        y = 0 + 60 * self.count
        pygame.draw.rect(DRAWSURF, BLACK, (x, y, 60, 60), 5)


class DrawBoard():
    def __init__(self, grid, mines): # size of grid and how many mines to set
        self.grid_size = grid
        # create x,y coordinates and set all mains to False initially
        self.board = OrderedDict(((i,j),False) for i in range(grid) for j in range(grid))      
        self.mines = mines
        # pick random coords to place mines
        samp = sample(list(self.board),self.mines)
        for k in samp:
            self.board[k]=True
    def draw(self):
        item = Square()
        for i, j in self.board:
            item.val, item.count = i,j
            item.draw()

game = DrawBoard(5,5) # create board
game.draw() # draw

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    clock.tick(30)
   # game logic goes here
    pygame.display.update()

This should get you started, you need to let the user know when they are near a mine and handle how/when they win:

import pygame, sys
from pygame.locals import *

pygame.init()
width, height = 40, 40
clock = pygame.time.Clock()
DRAWSURF = pygame.display.set_mode((width, height))
pygame.display.set_caption("Matt's Minesweeper")
background = pygame.Surface(DRAWSURF.get_size())
DRAWSURF.blit(background, (0, 0))
pygame.display.flip()
size = [255, 255]
screen = pygame.display.set_mode(size)

margin = 5

from collections import OrderedDict
from random import sample


class DrawBoard():
    def __init__(self, grid, mines):
        self.grid_size = grid
        self.board = OrderedDict(((i, j), False) for i in range(grid) for j in range(grid))
        self.mines = mines
        samp = sample(list(self.board), self.mines)
        for k in samp:
            self.board[k] = True

    def draw(self):
        for i, j in self.board:
            x = 100 + i * 60
            y = 0 + 60 * j
            pygame.draw.rect(DRAWSURF,(0,0,0), (x, y, 60, 60), margin)


game = DrawBoard(5, 5)
game.draw()


def game_over():
    font = pygame.font.SysFont(None, 50)
    text = font.render('Game over!', True, (255, 0, 0), (255, 255, 255))
    text_rect = text.get_rect()
    text_rect.centerx = screen.get_rect().centerx
    text_rect.centery = screen.get_rect().centery
    screen.blit(text, text_rect)
    pygame.display.update()
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()


user_won = False
user_lost = False

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # get mouse pos 
            pos = pygame.mouse.get_pos()
            # change to grid coordinates
            column = pos[0] // (width + margin)
            row = pos[1] // (height + margin)
            print(game.board[row, column])
            if game.board[row, column]:
                user_lost = True
            else:
                game.board[row, column] = "picked"

    if user_lost:
        game_over()

    screen.fill((0, 0, 0))
    for row, column in game.board:
        color = (255, 255, 255)
        if game.board[row, column] == "picked":
            color = (0, 255, 0)
        pygame.draw.rect(screen,
                         color,
                         [(margin + width) * column + margin,
                          (margin + height) * row + margin,
                          width,
                          height])

    pygame.display.flip()
    clock.tick(30)

    pygame.display.update()

If you want a "tutorial" going over an implementation of the program, you can check out this MineSweep recipe on ActiveState's Python Cookbook. Version 2 of the code introduces the methods __push and __build_mines to handle the creation of the individual mines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM