#MASTERMIND GAME BY ANDREW HOROBIN #REQUIRES PYTHON 2.7 & PYGAME 1.9.1 import pygame import random import colorsys import math from pygame.locals import * from sys import exit #initialize window and rando seed pygame.init() random.seed() #cover screen with very transparent black for fade effect def bgfade(): rec = pygame.Surface(screensize) if frame != 0: rec.set_alpha(5) rec.fill((0,0,0)) else: rec.set_alpha(255) rec.fill(draw_color) screen.blit(rec,(0,0)) del rec #all mathmatical shapes class shape(): xy = [0,0] #location rot = [0.0,0.0] #rotation color = '.' #color/shape value #constructor def __init__(self,xy,color): self.xy = xy #self.rot = [(random.random()*(math.pi*2)),(random.random()*(360/(math.pi*2)))+.1] self.rot = [(random.random()*(math.pi*2)),.02] self.color = color #define shape def set_shape(self,color): self.color = color #draw shape def draw(self): #rotation self.rot[0] += self.rot[1] if self.rot[0] > math.pi*2: self.rot[0] -= math.pi*2 #red/square if self.color == 'r': for x in range(4): #print self.rot[0] pygame.draw.aaline(screen,(255,0,0),\ (((math.cos(self.rot[0]+(x*(math.pi/2)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*(math.pi/2)))*20)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+1)*(math.pi/2)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+1)*(math.pi/2)))*20)+self.xy[1])),\ 1) #orange/triangle if self.color == 'o': for x in range(3): pygame.draw.aaline(screen,(255,128,0),\ (((math.cos(self.rot[0]+(x*((math.pi*2)/3)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*((math.pi*2)/3)))*20)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+1)*((math.pi*2)/3)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+1)*((math.pi*2)/3)))*20)+self.xy[1])),\ 1) #yellow/hexagon if self.color == 'y': for x in range(6): pygame.draw.aaline(screen,(255,255,0),\ (((math.cos(self.rot[0]+(x*((math.pi*2)/6)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*((math.pi*2)/6)))*20)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+1)*((math.pi*2)/6)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+1)*((math.pi*2)/6)))*20)+self.xy[1])),\ 1) #blue/star if self.color == 'b': for x in range(5): pygame.draw.aaline(screen,(0,0,255),\ (((math.cos(self.rot[0]+(x*((math.pi*2)/5)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*((math.pi*2)/5)))*20)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+2)*((math.pi*2)/5)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+2)*((math.pi*2)/5)))*20)+self.xy[1])),\ 1) #purple/diamond if self.color == 'p': for x in (0,2): pygame.draw.aaline(screen,(128,0,255),\ (((math.cos(self.rot[0]+(x*((math.pi*2)/4)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*((math.pi*2)/4)))*20)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+1)*((math.pi*2)/4)))*10)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+1)*((math.pi*2)/4)))*10)+self.xy[1])),\ 1) for x in (1,3): pygame.draw.aaline(screen,(128,0,255),\ (((math.cos(self.rot[0]+(x*((math.pi*2)/4)))*10)+self.xy[0]),\ ((math.sin(self.rot[0]+(x*((math.pi*2)/4)))*10)+self.xy[1])),\ (((math.cos(self.rot[0]+((x+1)*((math.pi*2)/4)))*20)+self.xy[0]),\ ((math.sin(self.rot[0]+((x+1)*((math.pi*2)/4)))*20)+self.xy[1])),\ 1) #unfilled circle if self.color == 'wh': pygame.draw.circle(screen,(0,255,0),(int(self.xy[0]),int(self.xy[1])),int(15),int(2)) #filled circle if self.color == 'bl': for x in range(2): pygame.draw.circle(screen,(0,255,0),(int(self.xy[0]),int(self.xy[1]+x)),15,15) pygame.draw.line(screen,(0,255,0),self.xy,self.xy,1) #dot if self.color == '.': for x in range(2): pygame.draw.circle(screen,(0,255,0),(int(self.xy[0]),int(self.xy[1]+x)),2,2) pygame.draw.line(screen,(0,255,0),self.xy,self.xy,1) #for the sweeping background lines class line(): x = 0 xp = 0 speed = 0 shade = 0 def __init__(self,speed): self.x = random.random()*screensize[1] self.xp = self.x #self.speed = (round(random.random())*2)+1 self.speed = speed self.shade = random.random()*255 #move line across screen at defined speed, loop around when off screen def update(self): self.xp = self.x self.x += self.speed if self.x > screensize[0]: self.x -= screensize[0] variation = 10 self.shade += (random.random()*variation)-(variation/2) if self.shade > 255: self.shade = 255 if self.shade < 0: self.shade = 0 #for x in range(int(self.speed)+1): # pygame.draw.line(screen,(0,self.shade,0),(self.x+x,0),(self.x+x,screensize[1]),1) rec = pygame.Surface((self.speed,screensize[1])) rec.set_alpha(self.shade) rec.fill((0,255,0)) screen.blit(rec,(self.x,0)) del rec #MAIN GAME LOOP while 1: #system variables screensize = (500,600) screen = pygame.display.set_mode(screensize, 0, 32) clock = pygame.time.Clock() frame = 0 reftime = pygame.time.get_ticks() text = pygame.font.Font(None,25) #display variables draw_color = [0,255,0] gridsize = 10 grid = [0,0] grid[0] = screensize[0]/10 grid[1] = screensize[1]/10 #background lines = 4 cline = [0]*lines for x in range(lines): cline[x] = line(x+1) #------------------------PRE PROCESS------------------------------- letters = ['r','o','y','b','p'] sequence = '' #where the master sequence is stored #create master sequence out of 4 unique shapes while len(sequence) < 4: letter = int(math.floor(random.random()*len(letters))) if not letters[letter] == 0: sequence += letters[letter] letters[letter] = 0 print sequence letters = ['r','o','y','b','p'] #setup process variables rounds = 8 print '' black = 0 white = 0 progress = ['.']*(rounds*4) hints = ['.']*(rounds*4) matches = ['.']*4 cround = 0 pegs = [0]*(rounds*4) hintpegs = [0]*(rounds*4) selection = 0 selectiontimer = 0 spacexy = grid spacetab = [0,0] key = 0 press = 0 pressprev = 0 query = shape((screensize[0]/2,grid[1]/2),'b') timer = [text.render('',1,(0,255,0)),0,0] #------------------------INSTRUCTIONS----------------------------- textline = [0]*20 textline[0] = 'Welcome to Mastermind!' textline[1] = '' textline[2] = 'Your goal is to guess' textline[3] = 'the random sequence of' textline[4] = 'shapes.' textline[5] = '' textline[6] = 'Use the left and right' textline[7] = 'arrow keys to pick a' textline[8] = 'shape and space bar' textline[9] = 'to put it in the next slot.' textline[10] = '' textline[11] = 'Solid circles mean a' textline[12] = 'correct peg in place,' textline[13] = 'hollow circles mean a' textline[14] = 'correct peg out of place.' textline[15] = '' textline[16] = '' textline[17] = '' textline[18] = '' textline[19] = ' Solid Hollow' for x in range(20): textline[x] = text.render(textline[x],1,(0,255,0)) testshape1 = shape((grid[0]*6.5,grid[1]*7.75),'bl') testshape2 = shape((grid[0]*8.5,grid[1]*7.75),'wh') #GO! while 1: clock.tick(30) #---------------------------PROCESS-------------------------------- #check keys pygame.event.get() if pygame.key.get_pressed()[pygame.K_LEFT]: key = 1 if pygame.key.get_pressed()[pygame.K_RIGHT]: key = 2 if pygame.key.get_pressed()[pygame.K_SPACE]: key = 3 pressprev = press press = key if press == pressprev: key = 0 #escape key if pygame.key.get_pressed()[pygame.K_ESCAPE]: pygame.quit() exit() #selection if key == 1: selection -= 1 if selection < 0: selection = (len(letters)-1) if key == 2: selection += 1 if selection == (len(letters)): selection = 0 query.set_shape(letters[selection]) #input guess if key == 3: #make next peg progress[cround] = letters[selection] pegs[cround] = shape(((grid[0]*1.5)+(grid[0]*spacetab[0]),\ (grid[1]*1.5)+(grid[1]*spacetab[1])),\ letters[selection]) hintpegs[cround] = shape(((grid[0]*6)+(grid[0]*spacetab[0]),\ (grid[1]*1.5)+(grid[1]*spacetab[1])),\ '.') #-----------------------CALCULATE HINTS---------------------------- if spacetab[0] == 3: black = 0 white = 0 matchesb = [0]*4 matchesw = [0]*4 for x in range(4): if pegs[cround-3+x].color == sequence[x]: black += 1 matchesb[x] = 1 for x in range(4): for y in range(4): if matchesb[x] == 0 and matchesb[y] == 0 and matchesw[y] == 0: if pegs[cround-3+x].color == sequence[y]: white += 1 matchesw[y] = 1 if black == 4: break #------------------------------------------------------------------ #apply hints if spacetab[0] == 3: if black > 0: for x in range(black): hintpegs[cround-3+x].set_shape('bl') if white > 0: for x in range(white): hintpegs[cround-3+black+x].set_shape('wh') spacetab[0] += 1 if spacetab[0] == 4: spacetab[0] = 0 spacetab[1] += 1 cround += 1 if spacetab[1] == 8: break #-----------------------------DRAW--------------------------------- #bg lines for x in range(lines): cline[x].update() #border draw_color = (0,255,0) rec = pygame.Surface((grid[0]*4,grid[1]*8)) rec.set_alpha(5) rec.fill((0,0,0)) screen.blit(rec,(grid[0],grid[1])) del rec pygame.draw.line(screen,draw_color,(grid[0],grid[1]),\ ((grid[0]),(grid[1])*9),3) pygame.draw.line(screen,draw_color,((grid[0])*5,grid[1]),\ ((grid[0])*5,(grid[1])*9),3) pygame.draw.line(screen,draw_color,(grid[0],grid[1]),\ ((grid[0])*5,(grid[1])),3) pygame.draw.line(screen,draw_color,(grid[0],(grid[1])*9),\ ((grid[0])*5,(grid[1])*9),3) #grid for x in range(7): pygame.draw.line(screen,draw_color,(grid[0],grid[1]*(x+2)),\ (grid[0]*5,grid[1]*(x+2)),1) for x in range(3): pygame.draw.line(screen,draw_color,(grid[0]*(x+2),grid[1]),\ (grid[0]*(x+2),grid[1]*9),1) #pegs for x in range(cround): pegs[x].draw() hintpegs[x].draw() #timer rec = pygame.Surface((grid[0]*3,grid[1]/2)) rec.set_alpha(20) rec.fill((0,0,0)) screen.blit(rec,(grid[0]*3.5,grid[1]*9.4)) del rec pygame.draw.rect(screen,(255,0,0),(grid[0]*3.5,grid[1]*9.4,grid[0]*3,grid[1]/2),3) timer[2] = int(math.floor(((pygame.time.get_ticks()-reftime)/1000)/60)) timer[1] = int(math.floor(((pygame.time.get_ticks()-reftime)/1000)-(timer[2]*60))) if timer[1] < 10: timer[1] = '0'+str(timer[1]) timertext = ('Time: '+str(timer[2])+':'+str(timer[1])) timer[0] = text.render(timertext,1,(255,0,0)) screen.blit(timer[0],(grid[0]*4,grid[1]*9.5)) #selection query.draw() #arrows xy = query.xy draw_color = (0,255,0) pygame.draw.line(screen,draw_color,(xy[0]-30,xy[1]+10),(xy[0]-30,xy[1]-10),2) pygame.draw.line(screen,draw_color,(xy[0]-30,xy[1]-10),(xy[0]-60,xy[1]-10),2) pygame.draw.line(screen,draw_color,(xy[0]-60,xy[1]-10),(xy[0]-60,xy[1]-20),2) pygame.draw.line(screen,draw_color,(xy[0]-60,xy[1]-20),(xy[0]-80,xy[1]),2)#< pygame.draw.line(screen,draw_color,(xy[0]-30,xy[1]+10),(xy[0]-60,xy[1]+10),2) pygame.draw.line(screen,draw_color,(xy[0]-60,xy[1]+10),(xy[0]-60,xy[1]+20),2) pygame.draw.line(screen,draw_color,(xy[0]-60,xy[1]+20),(xy[0]-80,xy[1]),2) pygame.draw.line(screen,draw_color,(xy[0]+30,xy[1]+10),(xy[0]+30,xy[1]-10),2) pygame.draw.line(screen,draw_color,(xy[0]+30,xy[1]-10),(xy[0]+60,xy[1]-10),2) pygame.draw.line(screen,draw_color,(xy[0]+60,xy[1]-10),(xy[0]+60,xy[1]-20),2) pygame.draw.line(screen,draw_color,(xy[0]+60,xy[1]-20),(xy[0]+80,xy[1]),2)#< pygame.draw.line(screen,draw_color,(xy[0]+30,xy[1]+10),(xy[0]+60,xy[1]+10),2) pygame.draw.line(screen,draw_color,(xy[0]+60,xy[1]+10),(xy[0]+60,xy[1]+20),2) pygame.draw.line(screen,draw_color,(xy[0]+60,xy[1]+20),(xy[0]+80,xy[1]),2) #next space spacing = 5 selectiontimer += 1 if selectiontimer == 30 and spacetab[1] < 8: selectiontimer = 0 pygame.draw.rect(screen,(255,0,0),((grid[0]+spacing)+(grid[0]*spacetab[0]),\ (grid[1]+spacing)+(grid[1]*spacetab[1]),\ (grid[0]-(spacing*2)),\ (grid[1]-(spacing*2))),2) #instructions if cround == 0: rec = pygame.Surface((grid[0]*4.5,grid[1]*7.5)) rec.set_alpha(20) rec.fill((0,0,0)) screen.blit(rec,(grid[0]*5.25,grid[0]*1.5)) del rec pygame.draw.rect(screen,draw_color,(grid[0]*5.25,grid[0]*1.5,grid[0]*4.5,grid[1]*7.5),2) for x in range(20): screen.blit(textline[x],(grid[0]*5.5,(grid[1]*2)+(x*20))) testshape1.draw() testshape2.draw() #grid noise rany = (random.random()*(grid[1]*8))+grid[1] rec = pygame.Surface((grid[0]*4,1)) rec.set_alpha(255/4) rec.fill((0,255,0)) screen.blit(rec,(grid[0],rany)) del rec #print clock.get_fps() pygame.display.set_caption(str(clock.get_fps())) pygame.display.update() #fade background bgfade() frame += 1 #--------------------------WIN/LOSE LOOP-------------------------- #this just spams the screen with words #just to be obnoxious frame = 0 loops = 0 text = pygame.font.Font(None,75) if black == 4: win = text.render('YOU WIN!',1,(0,0,0)) else: win = text.render('YOU LOSE!',1,(0,0,0)) while 1: screen.blit(win,(random.random()*(screensize[0])-(win.get_width()/2)\ ,random.random()*screensize[1])) pygame.display.update() bgfade() frame += 1 if frame == 20: frame = 0 loops += 1 if loops == 15: break