#!/usr/bin/env python import pygame, os, sys, random from pygame.locals import * def centeron( x, y, w, h ): return x - w/2, y - h/2 class JBoard: vals = [] qlist = [] clist = [] alist = [] covered = [] remaining = 0 def __init__(self, fn): lns = open( fn ).readlines() [cats, qs] = [int(x) for x in lns.pop(0).split()] for v in range(qs): self.vals.append( int(lns.pop(0).strip()) ) for c in range(cats): self.clist.append( lns.pop(0).strip() ) self.qlist.append( [] ) self.alist.append( [] ) self.covered.append( [] ) for q in range(qs): self.qlist[c].append( lns.pop(0).strip() ) self.alist[c].append( lns.pop(0).strip() ) self.covered[c].append( True ) self.remaining = cats*qs def getq(self, c, v): return self.qlist[c][v] class GraphicalJep( JBoard ): teams = [ ('Team 1', (150,150,10)), ('Team 2', (10,150,150)), ('Team 3', (150,10,150)) ] pal = [ ( 200, 0, 30 ), ( 200, 40, 30 ), ( 200, 80, 30 ), ( 200, 120, 30 ), ( 200, 160, 30 ), ( 200, 200, 30 ), ( 160, 200, 30 ), ( 120, 200, 30 ), ( 80, 200, 30 ), ( 40, 200, 30 ), ( 0, 200, 30 ) ] def loadres(self): self.backimg = pygame.image.load( os.path.join('img', 'grad.jpeg') ).convert() self.qimg = pygame.image.load( os.path.join('img', 'cov.png') ).convert() self.valbox = pygame.image.load( os.path.join('img', 'val.png') ).convert() self.valbox.set_colorkey( (255,255,255) ) self.qbox = pygame.image.load( os.path.join('img', 'qbox.png') ).convert() self.qbox.set_colorkey( (255,255,255) ) self.medals = [ pygame.image.load( os.path.join('img', i) ).convert() \ for i in 'gold.png silver.png bronze.png'.split() ] for x in self.medals: x.set_colorkey( (255,255,255) ) self.qfont = pygame.font.Font( os.path.join('font','veraserif.ttf'), 32 ) self.cfont = pygame.font.Font( os.path.join('font','Vera.ttf'), 32 ) self.vfont = pygame.font.Font( os.path.join('font','VeraMono.ttf'), 32 ) self.sfont = pygame.font.Font( os.path.join('font','cosmetica.ttf'), 54 ) self.boardsnd = pygame.mixer.Sound( os.path.join('snd','board.wav') ) self.timeup = pygame.mixer.Sound( os.path.join('snd','timeup.wav') ) self.closing = pygame.mixer.Sound( os.path.join('snd','closing.wav') ) self.ding = pygame.mixer.Sound( os.path.join('snd','ding.wav') ) self.qcol = (240,240,240) self.valcol = (220,180,40) def drawboard( self, sf ): h = sf.get_height() w = sf.get_width() dw = w / len(self.clist) th = h / 10 lh = h*2 / 10 qh = h*7 / 10 dh = qh / len(self.vals) for c in range( len(self.clist) ): cat = self.cfont.render( self.clist[c], True, (10,100,10) ) sf.blit( cat, (dw*c + dw/2 - cat.get_width()/2, th/2 - cat.get_height()/2) ) for q in range( len(self.vals) ): if self.covered[c][q]: val = self.vfont.render( str(self.vals[q]), True, self.valcol ) sf.blit( self.valbox, (dw*c + dw/2 - self.valbox.get_width()/2, th + dh*q + dh/2 - self.valbox.get_height()/2) ) sf.blit( val, (dw*c + dw/2 - val.get_width()/2, th + dh*q + dh/2 - val.get_height()/2) ) dw = w / len(self.teams) for t in range( len(self.teams)): tn = self.cfont.render( '%s: %s' % (self.teams[t][0], self.scores[t]), True, self.teams[t][1] ) left,top = dw*t + dw/2 - tn.get_width()/2, th + qh + lh/2 - tn.get_height()/2 sf.blit( tn, (left, top) ) if t == self.rrpos: pygame.draw.rect( sf, self.teams[t][1], pygame.Rect( left-3, top-3, tn.get_width()+6, tn.get_height()+6 ), 3 ) def qselect( self ): c,q = -1,-1 while c not in range(len(self.clist)) \ or q not in range(len(self.vals)) \ or not self.covered[c][q]: c = -1 while c == -1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: if e.key == 27: return -1,-1 if e.key >= 48 and e.key < 58 and (e.key-49) < len(self.clist): c = e.key-49 q = -1 while q == -1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: if e.key == 27: return -1,-1 if e.key >= 48 and e.key < 58 and (e.key-49) < len(self.vals): q = e.key-49 return c,q def animateslots( self, sf ): h = sf.get_height() w = sf.get_width() dw = w / len(self.clist) th = h / 10 lh = h*2 / 10 qh = h*7 / 10 dh = qh / len(self.vals) slots = [] for c in range(len(self.clist)): for v in range(len(self.vals)): slots.append( (c,v) ) random.shuffle( slots ) self.boardsnd.play() pygame.time.set_timer( USEREVENT, 100 ) while len(slots): pygame.event.pump() e = pygame.event.wait() if e.type == USEREVENT: (c,v) = slots.pop() val = self.vfont.render( str(self.vals[v]), True, self.valcol ) sf.blit( self.valbox, (dw*c + dw/2 - self.valbox.get_width()/2, th + dh*v + dh/2 - self.valbox.get_height()/2) ) sf.blit( val, (dw*c + dw/2 - val.get_width()/2, th + dh*v + dh/2 - val.get_height()/2) ) pygame.display.flip() pygame.time.set_timer( USEREVENT, 0 ) def waitkey( self ): while 1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: if e.key == 27: return True return False def showq( self, sf, qtext ): wrds = qtext.split() qlines = [] u = 0 for w in range(len(wrds)): qln = self.qfont.render( ' '.join( wrds[u:w+1] ), True, self.qcol ) if qln.get_width() > (sf.get_width()*9/10): qlines.append( self.qfont.render( ' '.join( wrds[u:w] ), True, self.qcol ) ) u = w qlines.append( self.qfont.render( ' '.join( wrds[u:] ), True, self.qcol ) ) sf.blit( self.qbox, (10,10) ) h = sf.get_height()/10 for q in qlines: sf.blit( q, ( sf.get_width()/2 - q.get_width()/2, h ) ) h += self.qfont.get_linesize()*11/10 def steal( self, sf ): print "stealing" ticks = 5 running = True pygame.time.set_timer( USEREVENT, 1000 ) left,top,width,height = 0, sf.get_height()*17/20, sf.get_width(), sf.get_height()/20 wrecked = pygame.Rect( left, top, width, sf.get_height() ) sf.set_clip( wrecked ) sf.blit( self.backimg, (0,0) ) pygame.draw.rect( sf, self.pal[ticks*2-1], pygame.Rect( width/2 - (width/2)*ticks/5, top, width*ticks/5, height ) ) prompt = self.cfont.render( 'STEAL', True, (230,30,30) ) sf.blit( prompt, ( width/2 - prompt.get_width()/2, top+height+5 ) ) pygame.display.flip() while 1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: if e.key == 32 and not running: pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return -1 if e.key == 32 and running: self.ding.play() pygame.time.set_timer( USEREVENT, 0 ) running = False if e.key >= 48 and e.key < 58 and (e.key-49) < len(self.teams): pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return e.key-49 if e.type == USEREVENT: ticks -= 1 sf.blit( self.backimg, (0,0) ) pygame.draw.rect( sf, self.pal[ticks*2-1], pygame.Rect( width/2 - (width/2)*ticks/5, top, width*ticks/5, height ) ) sf.blit( prompt, ( width/2 - prompt.get_width()/2, top+height+5 ) ) pygame.display.flip() if ticks <= 0: self.timeup.play() pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return -1 print "Counted to infinity" pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) def buzzer( self, sf, team ): print "waiting" ticks = 10 running = True pygame.time.set_timer( USEREVENT, 1000 ) left,top,width,height = 0, sf.get_height()*17/20, sf.get_width(), sf.get_height()/20 wrecked = pygame.Rect( left, top, width, sf.get_height() ) sf.set_clip( wrecked ) sf.blit( self.backimg, (0,0) ) prompt = self.cfont.render( self.teams[team][0], True, self.teams[team][1] ) pygame.draw.rect( sf, self.pal[ticks-1], pygame.Rect( width/2 - (width/2)*ticks/10, top, width*ticks/10, height ) ) sf.blit( prompt, ( width/2 - prompt.get_width()/2, top+height+5 ) ) pygame.display.flip() while 1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: if e.key == 32 and not running: pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return False if e.key == 32 and running: self.ding.play() pygame.time.set_timer( USEREVENT, 0 ) running = False if e.key == 10 or e.key == 13: pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return True if e.type == USEREVENT: ticks -= 1 sf.blit( self.backimg, (0,0) ) pygame.draw.rect( sf, self.pal[ticks-1], pygame.Rect( width/2 - (width/2)*ticks/10, top, width*ticks/10, height ) ) sf.blit( prompt, ( width/2 - prompt.get_width()/2, top+height+5 ) ) pygame.display.flip() if ticks <= 0: self.timeup.play() pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) return False print "Counted to infinity" pygame.time.set_timer( USEREVENT, 0 ) sf.set_clip( None ) def victory( self, sf ): def score(x): return x[1] scorelist = [ (i,self.scores[i]) for i in range(len(self.scores)) ] scorelist.sort( key=score, reverse=True ) place = [0] for x in range(len(scorelist)-1): if scorelist[x][1] == scorelist[x+1][1]: place.append( place[-1] ) else: place.append( place[-1]+1 ) h = sf.get_height() dh = h/(len(scorelist)+1) top = dh/2 w = sf.get_width() medal_left = w/3 - self.medals[0].get_width()/2 text_left = w/3 + self.medals[0].get_width()/2 + 6 for x in range(len(scorelist)): sf.blit( self.medals[ place[x] ], (medal_left,top) ) p=self.sfont.render( '%s: %s' % (self.teams[scorelist[x][0]][0], scorelist[x][1]), True, self.teams[scorelist[x][0]][1] ) sf.blit( p, (text_left, (dh-p.get_height())/2 + top) ) top += dh self.closing.play() def run(self, scr): self.loadres() self.scores = [0 for t in self.teams] self.rrpos = int( random.random()*len(self.teams) ) scr.blit( self.backimg, (0,0) ) self.animateslots( scr ) while self.remaining > 0: scr.blit( self.backimg, (0,0) ) self.drawboard( scr ) pygame.display.flip() c,q = self.qselect() if c == -1: break self.remaining -= 1 self.covered[c][q] = False scr.blit( self.backimg, (0,0) ) self.showq( scr, self.qlist[c][q] ) pygame.display.flip() if self.buzzer( scr, self.rrpos ): self.scores[ self.rrpos ] += self.vals[q] else: x = self.steal( scr ) if x > -1: self.scores[ x ] += self.vals[q] print self.scores scr.set_clip( scr.get_rect() ) scr.blit( self.backimg, (0,0) ) pygame.display.flip() self.showq( scr, self.alist[c][q] ) pygame.display.flip() print "see answer" quit = self.waitkey() if quit: break print "next question" self.rrpos = (self.rrpos+1) % len(self.teams) scr.blit( self.backimg, (0,0) ) self.victory(scr) pygame.display.flip() self.waitkey() if __name__ == '__main__': fn = os.path.join('data', 'default.jbd') if len(sys.argv) == 2: fn = sys.argv[1] pygame.init() scr = pygame.display.set_mode( (800,600), FULLSCREEN ) pygame.event.set_allowed( (KEYUP, USEREVENT) ) pygame.display.flip() img = pygame.image.load( os.path.join('img', 'ivcjep.jpeg') ).convert() theme = pygame.mixer.Sound( os.path.join('snd','jep.wav') ) scr.blit( img, (0,0) ) pygame.display.flip() theme.play() pygame.time.set_timer( USEREVENT, 15000 ) while 1: pygame.event.pump() e = pygame.event.wait() if e.type == KEYUP: break if e.type == USEREVENT: break theme.fadeout(50) pygame.time.set_timer( USEREVENT, 0 ) gj = GraphicalJep( fn ) gj.run( scr )