class Game: LEDS = None SWITCHES = None COUNTDOWN = None GAME_TIME = None FINISH_TIME = 0 RAND = -1 RANDS = [] BUTTONS_STATE = False BUTTONS_PRESSED = [] GAMEOVER = False BUTTON_ACTION_ALL = 'all' BUTTON_ACTION_SNAKE = 'snake' LEVEL = 1 SCORE_INCREMENT = None gpio = None lcd = None db = None def __init__(self, leds, switches, countdown, game_time, score_increment): self.LEDS = leds self.SWITCHES = switches self.COUNTDOWN = countdown self.GAME_TIME = game_time self.SCORE_INCREMENT = score_increment self.gpio = Gpio self.lcd = Lcd() self.db = TinyDB('data/database.json') if len(self.LEDS) != len(self.SWITCHES): print( "[Game][error] There isn't the same number of LEDS as SWITCHES" ) exit() try: self.gpio.setmode(self.gpio.BCM) for switch in self.SWITCHES: self.gpio.setup(switch, self.gpio.IN) self.gpio.add_event_detect(switch, self.gpio.RISING, bouncetime=300) self.gpio.add_event_callback(switch, self.__button_press) for led in self.LEDS: self.gpio.setup(led, self.gpio.OUT) self.gpio.output(led, False) except AttributeError: print("[Game][error] An error occurred initialising game") def start(self, run_once=False): print("[Game][info] Starting game") self.lcd.print("Press lit button", self.lcd.LINE_1) self.lcd.print("to start", self.lcd.LINE_2) try: self.gpio.output(self.LEDS[2], True) while self.gpio.input(self.SWITCHES[2]) == self.gpio.LOW: time.sleep(0.01) for led in self.LEDS: self.gpio.output(led, True) except AttributeError: print("[Game][error] An error occurred starting game") self.__countdown() self.__loop() self.finish() if run_once is not True: self.start() def __countdown(self): print("[Game][info] Starting game countdown") try: self.lcd.clear() for i in range(self.COUNTDOWN, -1, -1): if i == 0: self.lcd.print("Go Go Go!", self.lcd.LINE_1) elif i == self.COUNTDOWN: self.lcd.print("Starting in %d!" % i, self.lcd.LINE_1) else: self.lcd.print("%d!" % i, self.lcd.LINE_1) time.sleep(1) self.gpio.output(self.LEDS[(i - 1)], False) self.lcd.clear() except AttributeError: print("[Game][error] An error occurred starting game countdown") def __loop(self): print("[Game][info] Starting game loop") self.FINISH_TIME = time.time() + (self.GAME_TIME + 1) try: while time.time() < self.FINISH_TIME and self.GAMEOVER is not True: print("[Game][info] Game loop iteration") self.BUTTONS_STATE = False self.BUTTONS_PRESSED = [] for i in range(self.LEVEL): self.print_information("Repeat following") if len(self.RANDS) >= (i + 1): self.RAND = self.SWITCHES.index(self.RANDS[i]) else: self.RAND = random.randint(0, (len(self.LEDS) - 1)) self.RANDS.append(self.SWITCHES[self.RAND]) print("[Game][info] Activating button: %s" % (self.SWITCHES[self.RAND])) self.gpio.output(self.LEDS[self.RAND], True) time.sleep(0.5) self.gpio.output(self.LEDS[self.RAND], False) start = time.time() print("[Game][info] Waiting for button press") while len(self.BUTTONS_PRESSED) < self.LEVEL: self.print_information() if time.time() >= self.FINISH_TIME: break end = time.time() time_taken = end - start time.sleep(0.5) print("[Game][info] Button presses time taken: %f" % time_taken) if time.time() < self.FINISH_TIME: if self.BUTTONS_STATE is True: print("[Game][info] Level increased by %d" % 1) self.LEVEL += 1 else: self.GAMEOVER = True except AttributeError: print("[Game][error] An error occurred during game loop") def __button_press(self, channel): print("[Game][info] Button pressed: %d" % channel) if len(self.RANDS) == 0: return self.BUTTONS_PRESSED.append(channel) if len(self.BUTTONS_PRESSED) <= len( self.RANDS) and channel == self.RANDS[( len(self.BUTTONS_PRESSED) - 1)]: self.BUTTONS_STATE = True else: self.BUTTONS_STATE = False def get_score(self): print("[Game][info] Calculating score") level = self.LEVEL - 1 if level < 1: return 0 return (level * (level + 1) / level) * self.SCORE_INCREMENT def print_information(self, message=None): print("[Game][info] Printing information") score = self.get_score() remaining = int(self.FINISH_TIME - time.time()) try: self.lcd.print("Remaining: %ds" % remaining, self.lcd.LINE_1) if message is None: self.lcd.print("Score: %d" % score, self.lcd.LINE_2) else: self.lcd.print(message, self.lcd.LINE_2) except AttributeError: print("[Game][error] An error occurred printing information") def print_score(self, high_score=False): print("[Game][info] Printing score") score = self.get_score() try: if high_score: self.lcd.print("High score: %d!" % self.get_score(), self.lcd.LINE_1) self.flash_buttons(self.BUTTON_ACTION_ALL) time.sleep(3) else: self.lcd.print("Your score: %d" % score, self.lcd.LINE_1) time.sleep(3) except AttributeError: print("[Game][error] An error occurred printing score") def flash_buttons(self, action): print("[Game][info] Flashing buttons '%s'" % action) try: if action == self.BUTTON_ACTION_SNAKE: for x in range(0, 4): for y in range(0, len(self.LEDS)): self.gpio.output(self.LEDS[y], True) time.sleep(0.2) self.gpio.output(self.LEDS[y], False) elif action == self.BUTTON_ACTION_ALL: for x in range(0, 4): for y in range(0, len(self.LEDS)): self.gpio.output(self.LEDS[y], True) time.sleep(0.2) for y in range(0, len(self.LEDS)): self.gpio.output(self.LEDS[y], False) time.sleep(0.2) except AttributeError: print("[Game][error] An error occurred flashing buttons") def finish(self): print("[Game][info] Finishing game") score = self.get_score() self.lcd.clear() if self.db.contains(Query().score >= score): self.print_score() else: self.print_score(True) self.db.insert({'score': score}) self.reset() def reset(self): print("[Game][info] Resetting game") self.GAMEOVER = False self.RAND = -1 self.RANDS = [] self.LEVEL = 1 self.FINISH_TIME = 0 self.BUTTONS_STATE = False self.BUTTONS_PRESSED = [] self.flash_buttons(self.BUTTON_ACTION_SNAKE) self.lcd.clear() def cleanup(self): print("[Lcd][info] Game clean up") try: self.gpio.cleanup() self.lcd.cleanup() except AttributeError: print("[Game][error] An error occurred cleaning up") def __exit__(self): print("[Game][info] Game exit") self.cleanup()
class Jeux_sins(): """ classe gestion du jeux """ def __init__(self): """ constructeur """ print('Démarrage jeux ... ') self.lcd = Lcd() # affichage LCD du jeux self.lcd.write_char('robot_ok', pos=(0, 0)) self.lcd.msg_centre('SinS', 'Initialisation') self.lcd.write_char('robot_ok', pos=(15, 0)) self.buzzer = Buzz() # buzzer du jeux self.rackleds = RackLeds() # rack de leds self.rackbuttons = RackButtons(self.rackleds, self.buzzer) # rack de boutons self.color = ['V', 'B', 'J', 'R'] # couleur du jeux self.dic_color = {'V': 0, 'B': 1, 'J': 2, 'R': 3} self.file_scores = '/flash/scores.txt' # fichier des records self.scores = self.read_scores() # dictionnaire des record self.total_keys = 10 # nb_clés à trouver #mode de difficulté du jeux self.dic_mode = { 'V': ['Vert', 'Facile'], 'B': ['Bleu', 'Moyen'], 'J': ['Jaune', 'Difficile'], 'R': ['Rouge', 'Expert'], } self.mode = 'V' self.nb_portes = 3 # nb de portes par niveau à ouvrir self.niveau = self.nb_portes # nb de leds dans la séquence en cours self.init_seq() # initialise séquences def init_seq(self): """ réinitialise les séquences à vide""" self.seq_led_droid = [] self.seq_led_joueur = [] #seed(randint(0,32000)) #initialize random number generator t = utime.localtime() #format (y,m,d,h,m,s,ss,sss) s = t[3] * 3600 + t[4] * 60 + t[5] # conversion hh:mn:ss en secondes seed(s % 2048) # initialise table random non reproductibles def add_seq(self): """ ajoute une séquence de nb_portes aléatoires au jeux""" for _ in range(self.nb_portes): self.seq_led_droid.append(self.color[randint(0, 3)]) def nouvelle_seq(self): """ détermine la nouvelle séquence de couleurs à trouver""" self.seq_led_joueur = [] # remise à zéro de la séquence du joueur if self.mode in ['J', 'R']: # séquences aléatoires depuis le début self.seq_led_droid = [] for n in range(self.niveau // self.nb_portes): self.add_seq() else: # sinon on ajoute nb_portes couleurs au hasard self.add_seq() def add_sequence_joueur(self, color): """ ajoute la couleur jouée par le joueur""" self.seq_led_joueur.append(color) def read_scores(self): """ retourne le dictionaires des records à battre par mode V,B,J,R""" dic_scores = {'V': 0, 'B': 0, 'J': 0, 'R': 0} #scores par niveaux try: with open(self.file_scores, 'r') as f: for line in f.readlines(): l = line.strip() mode, score = l[0], int(l[2:]) dic_scores[mode] = score except: #création du fichier score.txt s'il n'existe pas print('création fichier des scores') self.write_scores(dic_scores) print('record à battre par mode:', dic_scores) return dic_scores def write_scores(self, scores): """ sauvegarde des record à battre""" with open(self.file_scores, 'w') as f: f.write('V:' + str(scores['V']) + '\n') f.write('B:' + str(scores['B']) + '\n') f.write('J:' + str(scores['J']) + '\n') f.write('R:' + str(scores['R']) + '\n') def loop(self): """ boucle principale du jeux""" while True: #initialisations self.init_seq() self.niveau = self.nb_portes self.lcd.clear() self.rackbuttons.desactivate_buzzer() self.lcd.msg_centre('Choix du mode', 'Quelle couleur ?') # choix du mode de jeux self.rackbuttons.pressed = False while not (self.rackbuttons.pressed ): #attente appui sur un bouton du rack time.sleep(0.2) self.mode = self.rackbuttons.button_pressed self.lcd.clear() self.lcd.msg_centre('Tu as choisi', 'mode: ' + self.dic_mode[self.mode][1]) if self.mode in ['V', 'J']: self.rackbuttons.activate_buzzer( ) #buzzer activé uniquement pour les modes V et J time.sleep(2) self.lcd.clear() #boucle de jeux tant que le joueur trouve la bonne séquence continuer = True while (continuer): #création d'une nouvelle séquence à trouver self.nouvelle_seq() #self.lcd.msg('Niveau:'+str(self.niveau), 'Record:'+ str(self.scores[self.mode])) self.lcd.msg('Niveau:', 'Record:') self.lcd.write_key(self.niveau // self.nb_portes, 0) # niveau self.lcd.write_key(self.scores[self.mode], 1) # record du mode joué time.sleep(1) #affichage de la séquence à trouver for rang, color in enumerate(self.seq_led_droid): self.rackleds.get_led(color).smooth_on() # led allumée if self.mode in ['V', 'J']: self.buzzer.buzzId( color ) # son correspondant à la couleur uniquement pour les modes V et J time.sleep(0.5) # temps d'attente en 2 leds self.buzzer.mute() # buzzer mute self.rackleds.get_led(color).smooth_off() # led éteinte time.sleep(0.5) # temps d'attente if ( rang + 1 ) % self.nb_portes == 0: # attente supplémentaires entre 2 séries de nb_portes time.sleep(0.3) #mémorisation séquence du joueur #print('à toi de jouer') self.rackbuttons.pressed = False for n in range(self.niveau): #attente qu'un bouton du rack de boutons soit pressée while not (self.rackbuttons.pressed): time.sleep(0.2) self.add_sequence_joueur(self.rackbuttons.button_pressed) self.rackbuttons.pressed = False #print('Voici ton jeu: ', self.jeux.seq_led_joueur) #comparaison des listes self.rackbuttons.pressed = True #empêche la saisie sur une touche time.sleep(1) if (self.seq_led_joueur == self.seq_led_droid): #print('Bien joué! niveau suivant') self.rackleds.win() #animation gagné if (self.scores[self.mode] < self.niveau // self.nb_portes): # le record du mode est battu self.scores[ self. mode] = self.niveau // self.nb_portes # maj du dictionnaire des records self.write_scores( self.scores) # enregistrement des records if self.niveau == self.total_keys * self.nb_portes: # toutes les clés sont trouvées self.buzzer.welcome_sound() self.lcd.clear() self.lcd.msg_centre('BRAVO!') self.lcd.write_char('robot_ok', pos=(0, 0)) self.lcd.write_char('robot_ok', pos=(15, 0)) for n in range(10): self.lcd.write_char('key', pos=(3 + n, 1)) time.sleep(0.3) time.sleep(2) continuer = False else: self.niveau += self.nb_portes else: #print('Perdu!') self.lcd.clear() self.lcd.msg_centre('Et non!') for l in range(6, 9): self.lcd.write_char('robot_ko', pos=(l, 1)) self.buzzer.loose_sound() self.rackleds.loose() # animation perdu time.sleep(1) continuer = False
elif buttons == Lcd.BUTTON_UP: if player.getStatus() == "playing": player.pause() else: player.play() logging.basicConfig(filename=LOG_FILE, format=LOG_FORMAT, level=LOG_LEVEL) logging.info("Starting BluePlayer") #gobject.threads_init() #dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) lcd = Lcd() lcd.begin(16, 2, handler=navHandler) lcd.backlight(Lcd.TEAL) lcd.clear() lcd.writeLn("Starting", 0) lcd.writeLn("BluePlayer", 1) time.sleep(2) player = None try: player = BluePlayer(lcd) player.start() except KeyboardInterrupt as ex: logging.info("BluePlayer cancelled by user") except Exception as ex: logging.error("How embarrassing. The following error occurred {}".format(ex)) traceback.print_exc() finally: player.shutdown()