Hi everyone! I joined these forums about a week ago so I could try and learn more about Python, and thankfully I can say that I have learned a bit. Enough to try and create a Mastermind game, although I'm having trouble with converting the code into Pygame and give it the graphics I have.

The code for the game is already set up and works, have played it through multiple times without fail. My only problem now is that whenever I attempt to play the game and post the corresponding keys to place the selected jewel in the slot, it instead places the background instead of the jewel.

Here is the code I have so far for the board...

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


#colorkey=None is the default transparency
def load_image(name, colorkey=None):
    #assume resources directory is named "data"
    #concatenate with the image file name
    #fullname = os.path.join('chad', name)
    try:#use try when an error could occur
        #load the image from disk to a surface
        background = pygame.image.load('mastermind_empty_board.jpg').convert()
    except pygame.error, message:
        #error message if we can't find the image
        raise SystemExit, message
        #the convers the bit format for efficent display
    images = background.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = background.get_at((0,0))
        background.set_colorkey(colorkey, RLEACCEL)
    return images, background.get_rect()


def drawBoard(counters):
    x=0
    y=0
    cnt=0
    for key in counters:
        if cnt == 4:
            y+=32
            x=0
        elif cnt == 8:
            y+=32
            x=0
        elif cnt == 12:
            y+=32
            x=0
        elif cnt == 16:
            y+=32
            x=0
        elif cnt == 20:
            y+=32
            x=0
        elif cnt == 24:
            y+=32
            x=0
        elif cnt == 28:
            y+=32
            x=0
        elif cnt == 32:
            y+=32
            x=0
        if (key == "r") or (key == "R"):
            #print "r"
            screen.blit(red_image, (x,y))
        if (key == "g") or (key == "G"):
            screen.blit(green_image, (x,y))
            #print "g"
        if (key == "b") or (key == "B"):
            screen.blit(blue_image, (x,y))
            #print "b"
        if (key == "y") or (key == "Y"):
            screen.blit(yellow_image, (x,y))
            #print "y"
    #   if (key == " "):
            #print "nothing"
        cnt+=1
        x+=45

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
font = pygame.font.SysFont("arial", 32);
font_height = font.get_linesize()

counterlist=[" "]*32

red_image, red_rect = load_image('red.png', -1)
red_rect.topleft = (10,10)

green_image, green_rect = load_image('green.png', -1)
green_rect.topleft = (0,0)

blue_image, blue_rect = load_image('blue.png', -1)
blue_rect.topleft = (0,0)

yellow_image, yellow_rect = load_image('yellow.png', -1)
yellow_rect.topleft = (0,0)

count=0
while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYUP:
            if event.key == K_r:
                counterlist[count] ="r"
                count+=1
                print red_rect
            if event.key == K_g:
                counterlist[count] ="g"
                count+=1
                print green_rect
            if event.key == K_b:
                counterlist[count] ="b"
                count+=1
                print blue_rect
            if event.key == K_y:
                counterlist[count] ="y"
                count+=1
                print yellow_rect
    drawBoard(counterlist)
    pygame.display.update()

So basically, the problem I'm having is when I put this in the background is appear for the corresponding keys instead of the red, green, blue, or yellow gems popping up. The background goes 4 over and then one line down to do 4 again, overlapping each time.

Any and all tips/suggestions/help to maybe clean up the code a little more or anything else would be welcome! I'd just like to get this up and running, if you'd like to see my Mastermind game code itself since I would be integrating that in to make the full fledged game, please just ask and I'd be more than happy to provide it.

I will also attach the pictures that I have been using to put together the background/images for the jewels if you wish to download them.

Edited 4 Years Ago by Nevicar: n/a

Might as well update my progress for the sake of progress..

I have changed the code at the beginning to finally end up showing the background like I wanted to. =) New problem: Getting the Red/Yellow/Blue/Green pieces to show up on the board when the buttons are pressed.

background_image_filename = 'mastermind_empty_board.jpg'

import pygame
from pygame.locals import *
from sys import exit

SCREEN_SIZE = (640, 480)

pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)

background = pygame.image.load(background_image_filename).convert()

while True:
    
    event = pygame.event.wait()
    if event.type == QUIT:
        exit()
    if event.type == VIDEORESIZE:
        SCREEN_SIZE = event.size
        screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)
        pygame.display.set_caption("Window resized to "+str(event.size))

    screen_width, screen_height = SCREEN_SIZE
    for y in range(0, screen_height, background.get_height()):
        for x in range(0, screen_width, background.get_width()):
            screen.blit(background, (x, y))
            
    pygame.display.update()

def drawBoard(counters):
    x=0
    y=0
    cnt=0
    for key in counters:
        if cnt == 4:
            y+=32
            x=0
        elif cnt == 8:
            y+=32
            x=0
        elif cnt == 12:
            y+=32
            x=0
        elif cnt == 16:
            y+=32
            x=0
        elif cnt == 20:
            y+=32
            x=0
        elif cnt == 24:
            y+=32
            x=0
        elif cnt == 28:
            y+=32
            x=0
        elif cnt == 32:
            y+=32
            x=0
        if (key == "r") or (key == "R"):
            #print "r"
            screen.blit(red_image, (x,y))
        if (key == "g") or (key == "G"):
            screen.blit(green_image, (x,y))
            #print "g"
        if (key == "b") or (key == "B"):
            screen.blit(blue_image, (x,y))
            #print "b"
        if (key == "y") or (key == "Y"):
            screen.blit(yellow_image, (x,y))
            #print "y"
    #   if (key == " "):
            #print "nothing"
        cnt+=1
        x+=45

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
font = pygame.font.SysFont("arial", 32);
font_height = font.get_linesize()

counterlist=[" "]*32

red_image, red_rect = load_image('red.png', -1)
red_rect.topleft = (10,10)

green_image, green_rect = load_image('green.png', -1)
green_rect.topleft = (0,0)

blue_image, blue_rect = load_image('blue.png', -1)
blue_rect.topleft = (0,0)

yellow_image, yellow_rect = load_image('yellow.png', -1)
yellow_rect.topleft = (0,0)

count=0
while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYUP:
            if event.key == K_r:
                counterlist[count] ="r"
                count+=1
                print red_rect
            if event.key == K_g:
                counterlist[count] ="g"
                count+=1
                print green_rect
            if event.key == K_b:
                counterlist[count] ="b"
                count+=1
                print blue_rect
            if event.key == K_y:
                counterlist[count] ="y"
                count+=1
                print yellow_rect
    drawBoard(counterlist)
    pygame.display.update()

Again, any and all advise/help/suggestions to help clean up the code or anything else would be greatly appreciated!

So in all my work over the last few days I have FINALLY been able to get it to work the way I want on the game board, now my only question is: How do I integrate the game code I have laid out already into the game itself and combine them?

Your code looked too difficult for me to understand, so I cut it to bare essentials. I did however get buttons to appear in current turns rows with buttons and I put in pygame.quit() for clean finish with also Q and escape.

However, I never coded in PyGame my own thing.

import pygame
from pygame.locals import *


def drawBoard(counters):
    y = turn * spacing[1] + corner[1]
    for count, key in enumerate(counters):
        screen.blit(images[key], (corner[0] + count * spacing[0], y))

images = { 'r': pygame.image.load('red.png'), 'g': pygame.image.load('green.png'),
           'b': pygame.image.load('blue.png'), 'y': pygame.image.load('yellow.png')
         }


pygame.init()

SCREEN_SIZE = (640, 480)
background_image_filename = 'mastermind_empty_board.jpg'
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)
background = pygame.image.load(background_image_filename).convert()
screen.blit(background, (0, 0))
pygame.display.update()

counterlist=[]

margin = 5, 3
spacing = [x + m for m, x in zip(margin, images['r'].get_size())]
corner = 74, 77
turn = 0
quit = False


while not quit:
    for event in pygame.event.get():
        if event.type == QUIT:
            quit = True
            break
        if event.type == KEYUP:
            if event.key in (K_r, K_g, K_b, K_y):
                #print event.key
                if event.key == K_r:
                    counterlist.append("r")
                elif event.key == K_g:
                    counterlist.append("g")
                elif event.key == K_b:
                    counterlist.append("b")
                else:
                    counterlist.append("y")
                # update
                drawBoard(counterlist)
                if len(counterlist) == 4:
                    turn += 1
                    counterlist = []
                    # 1 better than 0 as first for humans
                    print('Turn %i' % (turn + 1))
                pygame.display.update()
            elif event.key in (K_q, K_ESCAPE):
                 quit = True
                 break

pygame.quit()

Edited 4 Years Ago by pyTony: n/a

Changed to use directly the event keys and to draw only added man.

import pygame
from pygame.locals import *


def draw_current(men, turn, spacing, corner):
    current = len(men) - 1
    pos = corner[0] + current * spacing[0], turn * spacing[1] + corner[1]
    screen.blit(images[men[-1]], pos)

images = { K_r: pygame.image.load('red.png'), K_g: pygame.image.load('green.png'),
           K_b: pygame.image.load('blue.png'), K_y: pygame.image.load('yellow.png'),
           K_SPACE: pygame.image.load('empty.png') }

pygame.init()

SCREEN_SIZE = (640, 480)
background_image_filename = 'mastermind_empty_board.jpg'
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
background = pygame.image.load(background_image_filename).convert()
screen.blit(background, (0, 0))
pygame.display.update()

men = []

margin = 5, 3
spacing = [x + m for m, x in zip(margin, images[K_r].get_size())]
corner = 74, 74
turn = 0
quit = False

while not quit:
    for event in pygame.event.get():
        if event.type == QUIT:
            quit = True
            break
        if event.type == KEYUP:
            if event.key in images:
                #print event.key
                men.append(event.key)
                # update
                draw_current(men,turn, spacing, corner)
                if len(men) == 4:
                    turn += 1
                    men = []
                pygame.display.update()
            elif event.key in (K_q, K_ESCAPE):
                 quit = True
                 break

pygame.quit()

Edited 4 Years Ago by pyTony: n/a

Thanks so much! That's so much more clear and easier to read, not to mention works perfectly. Now my only question would be taking this code and adding it into the game to have them work with one another, any ideas?

import random

class InvalidMove(Exception):pass

class Game:
    def __init__(self): 
        self.colors=('r','g','b','y')
        self.to_guess=[random.choice(self.colors) for i in range(4)] 

    def match_guess(self,guess):
        if len(guess)!=len(self.to_guess) or [g for g in guess if g not in self.colors]:
            raise InvalidMove()
        ret=[0,0] 
        usedindexes=[] 
        for i,g in enumerate(guess):
            if g==self.to_guess[i]:
                ret[0]+=1
                usedindexes.append(i)
        for i,g in enumerate(guess):
            if i in usedindexes: continue
            for j,c in enumerate(self.to_guess):
                if c==g and j not in usedindexes:
                    ret[1]+=1
                    usedindexes.append(j)
        return ret            
    
class UI:
    def make_move(self): 
        guess=raw_input("Guess: ")
        return guess.split()

    def main(self):
        print("The game begins...")
        print("Possible colors (enter first letter): [r]ed [g]reen [b]lue [y]ellow")
        print("Enter your guess like: r g b y")
        g=Game()
        while True:
            guess=self.make_move()
            try:
                bp,wp=g.match_guess(guess)
            except InvalidMove:
                print("Invalid guess, try again")
                continue
            print("Black pegs %s"%bp)
            print("White pegs %s"%wp)
            if bp==4:
                print("You won!")

if __name__=="__main__":
    u=UI()
    u.main()

Ah! I think I've got it... merely by naming my board, board, and having it in the same folder then importing it I was able to get them to work together! Awesome!

Thank you so much for the help. <3

Edited 4 Years Ago by Nevicar: n/a

Ah! I think I've got it... merely by naming my board, board, and having it in the same folder then importing it I was able to get them to work together! Awesome!

Thank you so much for the help. <3

Nice that it worked out. i quite like your analyzing function. I prepared my own only few days ago for thread about lingo. it would be kind of you to post the finished code as code snippet after you finalize it. You could mention my contribution and if you think any reply helpful, it is allways possible to upvote and give reputation as you seem fit.

This question has already been answered. Start a new discussion instead.