commit a19d8a5cda427b868112ad4d94fe76950904f7ba Author: Dominic DiTaranto Date: Thu Aug 28 09:56:00 2025 -0400 ini commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe3dded --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# PYSOKOBAN diff --git a/main.py b/main.py new file mode 100644 index 0000000..1d896ac --- /dev/null +++ b/main.py @@ -0,0 +1,174 @@ +import os + +from pynput import keyboard + +from maps import levels, logo + +# TODO: reset option with point loss +# TODO: actually give points +# TODO: only allow 3 resets then gameover +# TODO: win + loss screens (just simple text under map or something) +# TODO: ^^ maybe cute emojis for win and loss screens +# TODO: Create more maps + +STATS = { + 'lives': 3, + 'points': 0, + 'total_moves': 0, + 'level_moves': {} +} + + +class Map: + def __init__(self, level=1): + self.level = level + self.level_map = levels[self.level - 1] + self.map_array = [] + self.storage_locations = [] + + self.listener = None + + self.player_x = None + self.player_y = None + self.previous_element = ' ' + + self.win = False + self.break_condition = True + + def generate_map_array(self): + STATS['level_moves'][self.level] = 0 + + level_array = self.level_map.split('\n') + + for idx, line in enumerate(level_array): + if idx == 0 or idx == len(level_array) - 1: + continue + + row_elements = list(line) + + if '@' in row_elements: + self.player_y = idx - 1 + self.player_x = row_elements.index('@') + + if '.' in row_elements: + for xidx, element in enumerate(row_elements): + if element == '.': + self.storage_locations.append((idx-1, xidx)) + + self.map_array.append(row_elements) + + def display(self): + os.system('clear') + for storage_location in self.storage_locations: + if self.map_array[storage_location[0]][storage_location[1]] == ' ': + self.map_array[storage_location[0]][storage_location[1]] = '.' + print(logo) + print(f' lvl: {self.level} | mvs: {STATS["level_moves"][self.level]} | pts: {STATS["points"]}') + for row in self.map_array: + print('\t', ''.join(row)) + + if self.win: + print('\n\n NICE! Press [w] to continue!') + else: + print('\n\n h = ← | j = ↓ | k = ↑ | l = →') + + def on_release(self, key): + self.listener = None + if 'char' in dir(key): + if key.char == 'h': + self.move('left') + if key.char == 'l': + self.move('right') + if key.char == 'j': + self.move('down') + if key.char == 'k': + self.move('up') + if self.win: + if key.char == 'w': + self.break_condition = False + + return False + + def wait_for_input(self): + with keyboard.Listener(on_release=self.on_release) as self.listener: + self.listener.join() + + def move(self, direction): + STATS['level_moves'][self.level] += 1 + STATS['total_moves'] += 1 + + tmp_player_x = self.player_x + tmp_player_y = self.player_y + + if direction == 'right' or direction == 'left': + + if direction == 'right': + tmp_player_x += 1 + else: + tmp_player_x -= 1 + + if direction == 'up' or direction == 'down': + if direction == 'down': + tmp_player_y += 1 + else: + tmp_player_y -= 1 + + future_position = self.map_array[tmp_player_y][tmp_player_x] + + if future_position not in ['#']: + can_move = True + if future_position == '0': + future_position = ' ' + can_move = self.push_boulder(tmp_player_y, tmp_player_x, direction) + + if can_move: + self.map_array[self.player_y][self.player_x] = self.previous_element + self.previous_element = future_position + self.map_array[tmp_player_y][tmp_player_x] = '@' + self.player_x = tmp_player_x + self.player_y = tmp_player_y + + def push_boulder(self, tmp_player_y, tmp_player_x, direction): + tmp_boulder_x = tmp_player_x + tmp_boulder_y = tmp_player_y + + if direction == 'right' or direction == 'left': + + if direction == 'right': + tmp_boulder_x += 1 + else: + tmp_boulder_x -= 1 + + if direction == 'up' or direction == 'down': + if direction == 'down': + tmp_boulder_y += 1 + else: + tmp_boulder_y -= 1 + + future_position = self.map_array[tmp_boulder_y][tmp_boulder_x] + + if future_position not in ['#', '0']: + self.map_array[tmp_boulder_y][tmp_boulder_x] = '0' + return True + else: + return False + + def check_win_condition(self): + self.win = True + for yidx, line in enumerate(self.map_array): + for xidx, element in enumerate(line): + if element == '0': + if (yidx, xidx) not in self.storage_locations: + self.win = False + + +if __name__ == '__main__': + for level in range(len(levels)): + m = Map(level + 1) + m.generate_map_array() + while m.break_condition: + m.display() + m.wait_for_input() + m.check_win_condition() + + os.system('clear') diff --git a/maps.py b/maps.py new file mode 100644 index 0000000..2d477bd --- /dev/null +++ b/maps.py @@ -0,0 +1,26 @@ +logo = ''' +█▀█ █▄█ █▀ █▀█ █▄▀ █▀█ █▄▄ ▄▀█ █▄░█ +█▀▀ ░█░ ▄█ █▄█ █░█ █▄█ █▄█ █▀█ █░▀█ +''' + +level_1 = ''' +############# +# # +#@ 0 . # +# # +############# +''' + +level_2 = ''' +############# +#. # +#@ 00 . # +# # +############# +''' + +levels = [ + level_1, + level_2 +] + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bdfdb3e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +evdev==1.9.2 +pynput==1.8.1 +python-xlib==0.33 +six==1.17.0