Python/PyGame Выберите случайное логическое значение из списка

Версия Python: 2.7.8

Цель: Сделать игру Minesweeper (хотя бы попытаться) на python с библиотекой PyGame.

Код:

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()

Проблема: у меня есть каждый отдельный квадрат как отдельный объект, как показано в классе Square(). В функции рисования класса Square она возвращает логическое значение None (переменная isMine), и когда я вызываю ее позже в классе DrawBoard, она добавляет объект в список «доска». Чтобы назначить мины для игры, я хочу случайным образом выбрать один из созданных объектов Square и изменить логическое значение с None на True. Может быть, это не лучший способ назначать мины, но я стараюсь изо всех сил. Любая помощь приветствуется.


person Adam    schedule 20.02.2015    source источник
comment
Итак, у вас есть список логических значений, и вы хотите выбрать одно из них случайным образом?   -  person Dominik Schmidt    schedule 20.02.2015
comment
может быть проще просто создать позиции сопоставления dict как ключи к тому, взорвалась ли мина или нет, как логические значения   -  person Padraic Cunningham    schedule 20.02.2015
comment
Вы также никогда не используете temp или test в MineSet.   -  person Padraic Cunningham    schedule 20.02.2015
comment
У меня есть список логических значений, которые мне нужно случайным образом выбрать определенное количество (параметр мин) и заменить его другим значением   -  person Adam    schedule 20.02.2015
comment
что select = item.draw() должен делать? Метод ничего не возвращает (по умолчанию None), поэтому вы устанавливаете select на None   -  person Padraic Cunningham    schedule 20.02.2015
comment
Код беспорядочный из-за бесчисленных тестов @Padraid Cunningham   -  person Adam    schedule 20.02.2015
comment
Думал, что мне нужно назначить переменную, чтобы я мог добавить в список.   -  person Adam    schedule 20.02.2015
comment
Вы можете добавить все, что хотите, в список напрямую. Я все еще думаю, что глобальный диктофон, в котором вы случайным образом устанавливаете квадратные позиции в True, будет намного проще.   -  person Padraic Cunningham    schedule 20.02.2015
comment
Это намного лучше для хранения местоположений и логических значений.. как теперь выбрать их случайным образом?..? Извините за непонимание   -  person Adam    schedule 20.02.2015
comment
сколько вы хотите установить в True?   -  person Padraic Cunningham    schedule 20.02.2015
comment
Я пытался использовать метод в классе MineSet, чтобы быть гибким с количеством мин.   -  person Adam    schedule 20.02.2015
comment
@Adam, я добавил ответ, я объясню, что именно происходит через несколько минут, в основном вы передаете размер сетки и количество мин для установки и использования выборки для случайной установки True   -  person Padraic Cunningham    schedule 20.02.2015


Ответы (3)


 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()

Это должно помочь вам начать, вам нужно сообщить пользователю, когда он находится рядом с миной, и справиться с тем, как/когда он выигрывает:

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()
person Padraic Cunningham    schedule 20.02.2015

просто сгенерируйте случайное значение между 0 и len(list). Затем вы можете получить доступ к значению, используя этот синтаксис: list[random_val] Если вы хотите изменить значение: list[random_val] = True

person Dominik Schmidt    schedule 20.02.2015

Если вам нужен «учебник» по реализации программы, вы можете ознакомиться с этим рецептом MineSweep в поваренной книге Python от ActiveState. Версия 2 кода вводит методы __push и __build_mines для управления созданием отдельных мин.

person Noctis Skytower    schedule 20.02.2015