diff --git a/idriz/assistant.py b/idriz/assistant.py index 2ca4f71..6a9ae27 100644 --- a/idriz/assistant.py +++ b/idriz/assistant.py @@ -28,8 +28,11 @@ Govoriš toplo, kratko i jasno, kao strpljivi stariji brat. Rečenice su kratke. Kako se igra Superheroji: - NE objašnjavaj pravila na početku. Pretpostavi da djeca znaju igrati. Pravila objasni samo ako te izričito pitaju. - Kad djeca kažu da žele igrati: prvo pitaj koliko igrača igra (od 1 do 5), pa ih pitaj za imena. Onda pozovi superheroji_nova_partija sa listom imena. Alat ti vrati broj rundi i redoslijed biranja za prvu rundu. -- U svakoj rundi traži od igrača, TAČNO onim redoslijedom koji ti je alat dao, da svaki kaže jednog superheroja. Definicija superheroja je široka: bilo koji izmišljeni lik iz bilo kog medija (Supermen, Mario, La Linea, Mad Max, Gandalf...). Zadnji igrač ima prednost jer bira zadnji, zato se redoslijed mijenja svaku rundu — uvijek koristi redoslijed koji ti alat da. -- Čim igrač kaže heroja, pozovi superheroji_izbor (igrac, heroj). Alat potvrdi ili odbije (npr. ako je taj heroj već pobijedio ranije u partiji, ili je već izabran u rundi). Ako je odbijen, kratko reci zašto i traži od tog igrača drugog heroja. Ako je prihvaćen, kratko potvrdi ("Supermen, zabilježeno!") i pitaj sljedećeg igrača. +- U svakoj rundi traži od igrača, TAČNO onim redoslijedom koji ti je alat dao, da svaki kaže jednog lika. Definicija je široka: bilo koji izmišljeni lik iz bilo kog medija — ne samo klasični superheroji. To su i crtani likovi, likovi iz video igara, animea, filmova, knjiga, memova (npr. Kuromi, Pikaču, Goku, La Linea, Mario, Gandalf, Baba Jaga, Mad Max). Zadnji igrač ima prednost jer bira zadnji, zato se redoslijed mijenja svaku rundu — uvijek koristi redoslijed koji ti alat da. +- VRLO VAŽNO ZA IMENA: djeca često biraju likove neobičnih ili stranih imena. Slušaj TAČNO ime koje dijete kaže i NE zamjenjuj ga poznatim superherojem koji zvuči slično (ako dijete kaže "Kuromi", ne smiješ čuti "Hulk"). Ako ime nisi jasno čuo ili ga ne razumiješ, NE POGAĐAJ — reci "Nisam dobro čuo ime, možeš li ponoviti?" i sačekaj. Tek kad si siguran u ime, pozovi alat. +- Čim igrač jasno kaže lika, pozovi superheroji_izbor (igrac, heroj) sa imenom TAČNO kako ga je dijete reklo. Alat ti onda kaže šta dalje. UVIJEK prvo naglas potvrdiš ime tako što ga izgovoriš ("Kuromi, zabilježeno!"), da dijete čuje jesi li dobro razumio — to radiš za SVAKOG igrača, i za zadnjeg u rundi. +- Ako dijete kaže da si pogriješio ime (npr. "nisam rekao Hulk, rekao sam Kuromi"), ODMAH ponovo pozovi superheroji_izbor sa ispravnim imenom za istog igrača. Ne prelazi dalje dok ime nije tačno. +- Ako alat odbije izbor (lik je već pobijedio ranije, ili je već izabran u rundi), kratko reci zašto i traži od tog igrača drugog lika. - Kad su SVI igrači u rundi izabrali, pozovi superheroji_presudi. Alat ti da pobjednika runde i obrazloženje. Objavi to djeci veselo: reci ko je pobijedio i zašto. Pobjednički heroj se više NE može koristiti do kraja te partije (o tome brine alat). - Alat ti kaže da li slijedi nova runda (i s kojim redoslijedom) ili je partija gotova. Kad je gotova, objavi konačnog pobjednika partije i čestitaj. - Ako djeca žele stati ranije, pozovi superheroji_kraj. @@ -213,10 +216,18 @@ class Assistant: if not self.match: return "Nema aktivne partije. Prvo pokreni igru sa superheroji_nova_partija." res = await self.match.record_pick(args.get("igrac", ""), args.get("heroj", "")) - if res.get("ok"): - return (f"{res['poruka']} Kratko potvrdi to djetetu i pitaj sljedećeg igrača po redoslijedu. " - f"Kad SVI igrači u rundi izaberu, pozovi superheroji_presudi.") - return res.get("poruka", "Taj izbor ne može proći, neka igrač izabere drugog heroja.") + if not res.get("ok"): + return (res.get("poruka", "Taj izbor ne može proći.") + + " Kad ti dijete kaže drugog lika, ponovo pozovi superheroji_izbor.") + name = res["heroj"] + # UVIJEK prvo potvrdi ime (i za zadnjeg igrača), da dijete čuje jesi li dobro razumio + confirm = (f'OBAVEZNO prvo reci djetetu tačno ovo ime naglas: "{name}, zabilježeno!" — koristi baš to ime ' + f'da dijete čuje kako si ga razumio. Ako dijete kaže da to nije taj lik, ponovo pozovi ' + f'superheroji_izbor sa ispravnim imenom za istog igrača.') + if self.match.round_complete: + return confirm + " Svi igrači su izabrali u ovoj rundi. Zatim ODMAH pozovi superheroji_presudi." + nxt = self.match.next_picker() + return confirm + f" Zatim pitaj igrača {nxt} da kaže svog lika." async def game_presudi(self, args: dict) -> str: if not self.match: @@ -416,7 +427,11 @@ class Assistant: elif t == "input_audio_buffer.speech_stopped": log.info("govor stao") elif t == "error": - log.error("realtime greška: %s", event.error) + code = getattr(event.error, "code", "") if event.error else "" + if code == "response_cancel_not_active": + log.debug("cancel bez aktivnog odgovora (bezopasno)") + else: + log.error("realtime greška: %s", event.error) elif t == "session.created": log.info("sesija: %s", t) elif t == "session.updated": diff --git a/idriz/game.py b/idriz/game.py index 0cc8c28..a1bca08 100644 --- a/idriz/game.py +++ b/idriz/game.py @@ -205,6 +205,16 @@ class Match: def current_order(self) -> list[str]: return self.order_for(self.round_index) + @property + def round_complete(self) -> bool: + return len(self.players) > 0 and all(p in self.picks for p in self.players) + + def next_picker(self) -> str | None: + for p in self.current_order: + if p not in self.picks: + return p + return None + @property def finished(self) -> bool: return self.round_index >= self.rounds