how to store mouse button selections in a list?

Viewed 56

So i was trying to create a more interactive version of the mastermind game in python using pygame. basically, the CPU will generate a random list of tuples (length 4), wherein each tuple represents an RGB combination (e.g. [(255,0,0), (135,6,79), (45,67,18), (12,90,235,4)] ). The program will allow the user to select 4 colors from a 3x3 grid of colors. if the choices match those generated by the CPU, the user wins.

i tried to loop through each cases differentiated by coordinates (x,y) wherein i tried to append the tuples to a guess_list. however, what i get are lists with 4 same tuples (e.g. [(255,0,0), (255,0,0), (255,0,0), (255,0,0)]). also, i would like to handle cases where the user clicked a region outside the colored square (black regions)

#main game loop
execute = True
while execute:
    game_screen.fill(black) #black background

    #display the rectangles. args: ((screen where the object is to be displayed), (color), (position(x,y)), (dimensions))
    pygame.draw.rect(game_screen, red, ((1/7)*screen_width, (screen_height//2) - 80, 40, 40))
    pygame.draw.rect(game_screen, green, ((3/7)*screen_width - 80, (screen_height//2) - 80, 40, 40))
    pygame.draw.rect(game_screen, blue, ((5/7)*screen_width - 160, (screen_height//2) - 80, 40, 40))
    pygame.draw.rect(game_screen, yellow, ((1/7)*screen_width, (screen_height//2), 40, 40))
    pygame.draw.rect(game_screen, orange, ((3/7)*screen_width - 80, (screen_height//2), 40, 40))
    pygame.draw.rect(game_screen, purple, ((5/7)*screen_width - 160, (screen_height//2), 40, 40))
    pygame.draw.rect(game_screen, maroon, ((1/7)*screen_width, (screen_height//2) + 80, 40, 40))
    pygame.draw.rect(game_screen, pink, ((3/7)*screen_width - 80, (screen_height//2) + 80, 40, 40))
    pygame.draw.rect(game_screen, brown, ((5/7)*screen_width - 160, (screen_height//2) + 80, 40, 40))

    #event block
    for event in pygame.event.get(): #loop through user events i.e. keyboard, mouse
        if event.type == pygame.QUIT: #exit button
            execute = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            i = 1
            while i <= 12: #gets inputs 12 times
                black_count = 0
                white_count = 0
                guess_list = []
                x_mouse, y_mouse = pygame.mouse.get_pos()

                for clicks in range(5): #gets clicks 4 times
                    if 80 <= x_mouse <= 120 and 235 <= y_mouse <= 275:
                        guess_list.append(red)
                    elif 160 <= x_mouse <= 200 and 235 <= y_mouse <= 275:
                        guess_list.append(green)
                    elif 240 <= x_mouse <= 280 and 235 <= y_mouse <= 275:
                        guess_list.append(blue)
                    elif 80 <= x_mouse <= 120 and 315 <= y_mouse <= 365:
                        guess_list.append(yellow)
                    elif 160 <= x_mouse <= 200 and 315 <= y_mouse <= 365:
                        guess_list.append(orange)
                    elif 240 <= x_mouse <= 280 and 315 <= y_mouse <= 365:
                        guess_list.append(purple)
                    elif 80 <= x_mouse <= 120 and 395 <= y_mouse <= 435:
                        guess_list.append(maroon)
                    elif 160 <= x_mouse <= 200 and 395 <= y_mouse <= 435:
                        guess_list.append(pink)
                    elif 240 <= x_mouse <= 280 and 395 <= y_mouse <= 435:
                        guess_list.append(brown)
                    else: #clicks outside the squares
                        print("Only click on the colored squares!!") #this loops 48 times (fix ASAP)

                #scoring block i.e. for updating black_count, white_count (code ASAP)
                i += 1
            print(guess_list)


    pygame.display.update()

    clock.tick(40) #sets fps
pygame.quit()
1 Answers

Your game runs in a loop, so when the player clicks somewhere, you have to keep track if it in your game state. The game state could be anything from a complex object graph to a simple variable.

You just have to keep in mind that when things happen over time (like the player clicking multiple times), you have to keep track of it somehow.

Here's a simple example I hacked together. You'll get the idea. Note the comments.

import pygame
import random

def main():

    # first, we create a simple list of the possible colors
    # pygame has a big internal list of predefined colors we 
    # can use, like 'blue' or 'lightgrey' etc
    # also note that we can easily extend our game by adding
    # other colors; and we don't have to touch any other code
    # since we use lists and loop over them to draw the game
    # and handle inputs. No big if/else monsters
    colors = ['blue', 'red', 'green', 'yellow', 'white']

    # next, we create a list of rects that represent the part
    # of the screen where the user can click to select a color.
    # the first one is located at (10, 10), and each rect has a 
    # size of (32, 32), with a gab of 10 between them
    # We use pygame's Rect class so we don't have to do the math 
    # ourself
    rects = {}
    x, y = 10, 10
    for color in colors:
        rects[color] = pygame.Rect(x, y, 32, 32)
        x += 32 + 10

    # since your game runs in a loop, we have to store the choices
    # of the player somewhere. We create a list of the colors the 
    # user picked this turn, and list of where we store the picks
    # of previous turns.
    picked = []
    history = []

    # pick the solution the player has to guess
    solution = colors[:]
    random.shuffle(solution)
    solution = solution[:4]
    # let's print the solution so we can cheat :-)
    print(solution)

    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    while True:
        ## EVENT HANDLING
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
            if e.type == pygame.MOUSEBUTTONDOWN:
                # the use clicked somewhere, so here we decide what happens
                # first, check if a color was clicked. Since we have the list
                # of rects, it's quite easy.
                # we make use of the collidepoint function of the Rect class
                # which will return True of the coordinate is inside the Rect
                clicked_list = [color for color in rects if rects[color].collidepoint(e.pos)]
                if clicked_list:
                    # the expression above returned a list, and
                    # the clicked color is the first and only element
                    color = clicked_list[0]
                    # so the user clicked a color button
                    # now add the color to the list of clicked buttons
                    # we don't allow duplicates
                    if not color in picked:
                        picked.append(color)
                    # that's it. We don't need to do anything more
                    # here in this event handling part

        ## DRAWING
        screen.fill((50, 50, 50))
        # draw the buttons
        for color in rects:
            pygame.draw.rect(screen, pygame.Color(color), rects[color])

        # draw the history
        # again, 32 is the size of the buttons, and 10 is the gap between tem
        # feel free to use constants and/or extract a function for drawing
        # instead of using magic numbers.
        x, y = 300, 500 - 32 - 10
        for turn in history:
            for color in turn:
                pygame.draw.rect(screen, pygame.Color(color), (x, y, 32, 32))
                x += 32 + 10
            y -= 32 + 10
            x = 300

        # draw what the player picked
        x, y = 300, 500
        for color in picked:
            pygame.draw.rect(screen, pygame.Color(color), (x, y, 32, 32))
            x += 32 + 10

        pygame.display.flip()

        ## GAME LOGIC
        # check if the player has picked 4 colors
        if len(picked) == 4:
            # check if the player has won
            # this works because picked and solution are 
            # simple lists of strings
            if picked == solution:
                print("WIN!")
                return

            # move the picked colors to the history list
            history.append(picked)
            picked = []

if __name__ == '__main__':
    main()

enter image description here

Related