RGB Jallenge

This is a clone of The Great RGB Guessing Challenge.
The challenge works like this: You are presented three numbers ranging from 0 to 255 representing a rgb color and three color bubbles. To get a point you must choose the color bubble corresponding to the rgb values. The more points you get, the higher your score.

Controls

• Click on the bubble to choose it

``````# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 8th of July, 2016``````

``````# importing needed modules
import pygame, sys, time, math, os, random, re
pygame.font.init()

""" CLASSES """
# vector class (2-dimensional)
class Vector():
def __init__(self, p1, p2 = None):
# get the vector as a 2-dimensional list
if not p2:
self.x = p1[0]
self.y = p1[0]
else:

# get the vector between two points
if type(p1) == type([]):
self.x = p2[0] - p1[0]
self.y = p2[1] - p1[1]

# get the vector as two numbers
else:
self.x = p1
self.y = p2

# calculate the vector's length
def length(self):
return math.sqrt(self.x**2 + self.y**2)

# multiply the vector by n
def multiply(self, n):
self.x *= n
self.y *= n

# unify the vector (set it's length to 1)
def unify(self):
l = self.length()
if l != 0:
self.multiply(1. / l)

# set the vector's length
def setlength(self, n):
self.unify()
self.multiply(n)

# stick the vector to a position
def stickto(self, p):
return p[0] + self.x, p[1] + self.y

# angles used in degrees!
# conversion between radians and degrees
return (phi * (math.pi/180.)) % (2*math.pi)
def degrees(self, phi):
return (phi * (180./math.pi)) % 360

# get the vector's angle
def getangle(self):
return self.degrees( math.atan2(self.y, self.x) )

# set the vector's angle
def setangle(self, phi):
l = self.length()

self.x = l * math.cos(self.radians( phi ))
self.y = l * math.sin(self.radians( phi ))

# add an angle phi to current rotation
def rotate(self, phi):
self.setangle(self.getangle() + phi)

class Screen():
def __init__(self, size = None):
if not size:
self.size = [G.Width, G.Height]
else:
self.size = size

self.width, self.height = self.size[0], self.size[1]

self.surface = pygame.Surface(self.size)

def swap(self):
pass

def render(self, surface):
pass

def tick(self):
pass

def handle(self, event):
pass

class Button():
def __init__(self, pos):
self.pos = pos
self.destsize = 40
self.size = self.destsize
self.destcolor = [255, 255, 255]
self.color = self.destcolor[:]

def render(self, surface):
pygame.draw.circle(surface, self.color, self.pos, int(self.size))

def tick(self):
self.size += (self.destsize - self.size) / 15.

for c in range(0, 3):
self.color[c] += (self.destcolor[c] - self.color[c]) / 20.

def hovered(self, mouse):
if Vector(mouse, self.pos).length() <= self.size:
return True

return False

class mainScreen(Screen):
def __init__(self):
Screen.__init__(self)

self.font = pygame.font.Font(pygame.font.match_font("Times"), 50)

self.buttons = []
for x in range(0, 3):
self.buttons.append(Button([
self.width/3*x+self.width/6,
self.height/3*2
]))

self.game = True
self.failed = False
self.score = 0
self.colornames = []
self.selectedcolor = 0
self.resetcolors()

def resetcolors(self):
self.colornames = []
for b in self.buttons:
color = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
b.destcolor = color[:]
self.colornames.append(color[:])

self.selectedcolor = random.randint(0, 2)

def resetbuttons(self):
for b in self.buttons:
b.destsize = 40

def render(self, surface):
self.surface.fill([20, 20, 20])

txt1 = self.font.render("Score: " + str(self.score), True, [255, 255, 255])
rct1 = txt1.get_rect()
pos1 = [(self.width-rct1.right)/2, 20]

txt2 = self.font.render(re.sub("\[", "(", re.sub("\]", ")", "rgb" + str(self.colornames[self.selectedcolor]))), 200, [255, 255, 255])
rct2 = txt2.get_rect()
pos2 = [(self.width-rct2.right)/2, 20 + rct1.bottom + 20 + 20]

if self.game:
self.surface.blit(txt1, pos1)
self.surface.blit(txt2, pos2)

for b in self.buttons:
b.render(self.surface)

if not self.game:
if not self.failed:
txt3 = self.font.render("That's right!", True, [255, 255, 255])
rct3 = txt3.get_rect()
pos3 = [(self.width-rct3.right)/2, 20]
self.surface.blit(txt3, pos3)
else:
txt4 = self.font.render("Too bad :(", True, [255, 255, 255])
rct4 = txt4.get_rect()
pos4 = [(self.width-rct4.right)/2, 20]

txt5 = self.font.render("Score: " + str(self.score), True, [255, 255, 255])
rct5= txt5.get_rect()
pos5 = [(self.width-rct5.right)/2, 20 + rct4.height + 20 + 20]

self.surface.blit(txt4, pos4)
self.surface.blit(txt5, pos5)

surface.blit(self.surface, [0, 0])

def tick(self):
if self.game:
for b in self.buttons:
if b.hovered(intpos(pygame.mouse.get_pos())):
b.destsize = 50
else:
b.destsize = 40

for b in self.buttons:
b.tick()

def handle(self, event):
if self.game:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for b in self.buttons:
if b.hovered(intpos(pygame.mouse.get_pos())):
self.game = False
b.destsize = (self.width + self.height)
self.buttons.remove(b)
self.buttons.append(b)

if b.destcolor == self.colornames[self.selectedcolor]:
self.score += 1
else:
self.failed = True

break

else:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
self.resetcolors()
self.resetbuttons()

self.game = True
if self.failed:
self.score = 0
self.failed = False

""" FUNCTIONS """
# returns an integer version of given position
def intpos(_pos):
return [int(_pos[0]), int(_pos[1])]

""" GAME """
# game class
class Game():
def __init__(self):
# screen (class)
self.screenname = "main"

# screen (window)
self.Width, self.Height = 600, 400
self.Size = [self.Width, self.Height]
self.Screen = pygame.display.set_mode(self.Size)

# running variables
self.ticks = 0
self.running = True

# functions
pygame.display.set_caption("RGB Jallenge")

# further initialization
def init(self):
self.screens = {
"main": mainScreen()
}

# get the screen based on name
def screen(self):
if self.screenname in self.screens:
return self.screens[self.screenname]
else:
return Screen()

def swapscreen(self, name = ""):
self.screenname = name
self.screen().swap()

# tick function
def tick(self):
# handle events
for event in pygame.event.get():

# quit when window is closed
if event.type == pygame.QUIT:
self.quit()

# handle key presses
if event.type == pygame.KEYDOWN:
# F12 quits
if event.key == pygame.K_F12:
self.quit()

# F1 screenshots
if event.key == pygame.K_F1:
self.screenshot()

# handle screen
self.screen().handle(event)

# tick screen
self.screen().tick()

# render function
def render(self):
# fill
self.Screen.fill([0, 0, 0])

#render screen
self.screen().render(self.Screen)

# flip
pygame.display.flip()

# quits
def quit(self):
self.running = False

# takes a screenshot
def screenshot(self):
# define path
path = os.getcwd() + "/out/"

# try to save
try:
# create path
if not os.path.isdir(path):
os.mkdir(path)

# define name
name = "img" + str(len(os.listdir(path))) + ".png"

# save image
pygame.image.save(self.Screen, path + name)

# save failed somehow
except:
pass

# run function (uses tick() and render())
def run(self):
ticksPerSecond = 60
lastTime = time.time() * 1000000000
nsPerTick =  1000000000.0 / float(ticksPerSecond)

ticks = 0
frames = 0

lastTimer = time.time() * 1000
delta = 0.0

while self.running:
now = time.time() * 1000000000
delta += float(now - lastTime) / float(nsPerTick)
lastTime = now
shouldRender = False

while delta >= 1:
ticks += 1
self.ticks += 1
self.tick()
delta -= 1
shouldRender = True

if shouldRender:
frames += 1
self.render()

if time.time() * 1000 - lastTimer >= 1000:
lastTimer += 1000

frames = 0
ticks = 0

# start game
G = Game()
G.init()
G.run()``````