diff --git a/.gitmodules b/.gitmodules index 4696c1b..b725a7e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "libstormgames"] - path = libstormgames - url = https://git.stormux.org/storm/libstormgames +[submodule "pygstormgames"] + path = pygstormgames + url = https://git.stormux.org/storm/pygstormgames diff --git a/libstormgames b/libstormgames deleted file mode 160000 index 155ed6e..0000000 --- a/libstormgames +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 155ed6ec390f5e6109b3358683e8f5d1ed367db0 diff --git a/numnastics b/numnastics deleted file mode 100755 index 82a6b20..0000000 --- a/numnastics +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from libstormgames import * - -# Initial variable settings -mode = "menu" -sounds = initialize_gui("Numnastics") - -def game(mode): - pygame.mixer.music.pause() - i = 0 - startTime = time.time() - tries = 0 - numberList = list("123456789") - random.shuffle(numberList) - speak(' '.join(numberList)) - while ''.join(numberList) != "123456789": - event = pygame.event.wait() - if event.type == pygame.KEYDOWN: - # Escape is the back/exit key, close the game if not playing, or return to menu if playing. - if event.key == pygame.K_ESCAPE: - if mode != "menu": - mode = "menu" - return mode - elif mode == "menu": exit_game() - elif event.key in [pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5, pygame.K_6,pygame.K_7, pygame.K_8, pygame.K_9]: - i = numberList.index((pygame.key.name(event.key))) - speak(numberList[i]) - elif event.key in [pygame.K_LEFT, pygame.K_UP]: - if i > 0: i = i - 1 - speak(numberList[i]) - elif event.key in [pygame.K_RIGHT, pygame.K_DOWN]: - if i < len(numberList) - 1: i = i + 1 - speak(numberList[i]) - elif event.key == pygame.K_SPACE: - speak(str(' '.join(numberList[i:len(numberList)]))) - continue - elif event.key == pygame.K_RETURN: - if i != -1: - reversedNumberList = numberList[i:len(numberList)] - reversedNumberList.reverse() - del numberList[i:len(numberList)] - numberList.extend(reversedNumberList) - tries = tries + 1 - sounds['flip'].play() - speak(str(' '.join(numberList[i:len(numberList)]))) - else: - i = -1 - sounds['error'].play() - endTime = round(time.time() - startTime, 2) - message = ["Congratulations! You beat Numnastics in " + str(tries) + " tries."] - if int(endTime / 60) == 1: - message.append("Your time was " + str(int(endTime / 60)) + " minute and " + str(round(endTime % 60, 2)) + " seconds.") - else: - message.append("Your time was " + str(int(endTime / 60)) + " minutes and " + str(round(endTime % 60, 2)) + " seconds.") - display_text(message) - cut_scene(sounds, 'win') - return "menu" - -# Game starts at main menu -mode = game_menu(sounds, "start game", "instructions", "donate", "credits", "learn sounds", "exit_game") -while mode != "exit_game": - if mode == "menu": mode = game_menu(sounds, "start game", "instructions", "donate", "credits", "learn sounds", "exit_game") - if mode == "start game": mode = game(mode) - if mode == "learn sounds": mode = learn_sounds(sounds) - time.sleep(.001) - diff --git a/numnastics.py b/numnastics.py new file mode 100755 index 0000000..8f54063 --- /dev/null +++ b/numnastics.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Numnastics - A number sorting puzzle game. + +The goal is to arrange numbers 1-9 in order by flipping sequences of numbers. +""" + +import time +import random +from pygstormgames import pygstormgames +from pyglet.window import key + +class Numnastics: + """Main game class for Numnastics.""" + + def __init__(self): + """Initialize the game.""" + # Initialize game framework + self.game = pygstormgames("Numnastics") + + self.currentIndex = 0 + self.numberList = [] + self.startTime = 0 + self.tries = 0 + self.playing = False + + def handle_game_input(self, keyInput): + """Handle keyboard input during gameplay. + + Args: + keyInput: Pyglet key symbol + """ + # Number keys (1-9) + if key._1 <= keyInput <= key._9: + number = str(keyInput - key.NUMBER_0) # Convert key code to string + try: + self.currentIndex = self.numberList.index(number) + self.game.speech.speak(self.numberList[self.currentIndex]) + except ValueError: + self.currentIndex = -1 + self.game.sound.play_sound('error') + + # Navigation + elif keyInput in (key.LEFT, key.UP): + if self.currentIndex > 0: + self.currentIndex -= 1 + self.game.speech.speak(self.numberList[self.currentIndex]) + + elif keyInput in (key.RIGHT, key.DOWN): + if self.currentIndex < len(self.numberList) - 1: + self.currentIndex += 1 + self.game.speech.speak(self.numberList[self.currentIndex]) + + # Speak remaining sequence + elif keyInput == key.SPACE: + sequence = ' '.join(self.numberList[self.currentIndex:]) + self.game.speech.speak(sequence) + + # Flip sequence + elif keyInput == key.RETURN: + if self.currentIndex != -1: + # Reverse the subsequence from currentIndex to end + reversedNumbers = self.numberList[self.currentIndex:] + reversedNumbers.reverse() + self.numberList[self.currentIndex:] = reversedNumbers + + self.tries += 1 + self.game.sound.play_sound('flip') + sequence = ' '.join(self.numberList[self.currentIndex:]) + self.game.speech.speak(sequence) + + # Check for win condition + if ''.join(self.numberList) == "123456789": + self.game_won() + return True + + # Exit to menu + elif keyInput == key.ESCAPE: + self.playing = False + return True + + return False + + def game_won(self): + """Handle win condition.""" + self.playing = False + endTime = round(time.time() - self.startTime, 2) + minutes = int(endTime / 60) + seconds = round(endTime % 60, 2) + + # Build victory message + message = [f"Congratulations! You beat Numnastics in {self.tries} tries."] + timeMsg = "minute" if minutes == 1 else "minutes" + message.append(f"Your time was {minutes} {timeMsg} and {seconds} seconds.") + + # Display victory message + self.game.display.display_text(message, self.game.speech) + + # Add score and play win sequence + if self.game.scoreboard.check_high_score(): + self.game.scoreboard.add_high_score() + + try: + self.game.sound.cut_scene('win') + except: + pass + + def run(self): + """Main game loop.""" + while True: + # Show main menu and handle selection + choice = self.game.menu.game_menu() + + if choice == "play": + self.start_game() + + def start_game(self): + """Start a new game.""" + self.playing = True + self.currentIndex = 0 + self.tries = 0 + self.startTime = time.time() + + # Initialize shuffled numbers + self.numberList = list("123456789") + random.shuffle(self.numberList) + + # Stop menu music and speak initial sequence + self.game.sound.pause_bgm() + self.game.speech.speak(' '.join(self.numberList)) + + # Define valid keys for the game + validKeys = [ + key.ESCAPE, + key.RETURN, + key.SPACE, + key.LEFT, + key.RIGHT, + key.UP, + key.DOWN, + key._1, key._2, key._3, key._4, key._5, + key._6, key._7, key._8, key._9 + ] + + while self.playing: + keyPress, _ = self.game.wait(validKeys) + if self.handle_game_input(keyPress): + break + +if __name__ == "__main__": + game = Numnastics() + game.run() diff --git a/pygstormgames b/pygstormgames new file mode 160000 index 0000000..998e319 --- /dev/null +++ b/pygstormgames @@ -0,0 +1 @@ +Subproject commit 998e319d92f991994b4935cdc5a940372e088f53