improvements and stuff you know
This commit is contained in:
parent
a19d8a5cda
commit
74bb1a6bf6
2 changed files with 195 additions and 83 deletions
226
main.py
226
main.py
|
@ -2,27 +2,42 @@ import os
|
||||||
|
|
||||||
from pynput import keyboard
|
from pynput import keyboard
|
||||||
|
|
||||||
from maps import levels, logo
|
from maps import levels, logo, lose, win, help
|
||||||
|
|
||||||
# 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 = {
|
class Game:
|
||||||
'lives': 3,
|
def __init__(self):
|
||||||
'points': 0,
|
self.map_instance = None
|
||||||
'total_moves': 0,
|
self.level = 0
|
||||||
'level_moves': {}
|
self.lives = 3
|
||||||
}
|
self.points = 0
|
||||||
|
self.total_moves = 0
|
||||||
|
self.level_moves = {}
|
||||||
|
|
||||||
|
def initialize_level(self):
|
||||||
|
self.map_instance = Map()
|
||||||
|
self.map_instance.generate_map_array()
|
||||||
|
self.loop()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while self.map_instance.break_condition:
|
||||||
|
self.map_instance.display()
|
||||||
|
self.map_instance.wait_for_input()
|
||||||
|
self.map_instance.check_win_condition()
|
||||||
|
|
||||||
|
self.initialize_level()
|
||||||
|
|
||||||
|
def handle_points(self, points):
|
||||||
|
self.points += points
|
||||||
|
if self.points + points < 0:
|
||||||
|
self.points = 0
|
||||||
|
|
||||||
|
|
||||||
class Map:
|
class Map:
|
||||||
def __init__(self, level=1):
|
def __init__(self):
|
||||||
self.level = level
|
self.level = g.level
|
||||||
self.level_map = levels[self.level - 1]
|
self.level_map = levels[self.level][0]
|
||||||
|
self.level_par = levels[self.level][1]
|
||||||
self.map_array = []
|
self.map_array = []
|
||||||
self.storage_locations = []
|
self.storage_locations = []
|
||||||
|
|
||||||
|
@ -33,10 +48,14 @@ class Map:
|
||||||
self.previous_element = ' '
|
self.previous_element = ' '
|
||||||
|
|
||||||
self.win = False
|
self.win = False
|
||||||
|
self.lose = False
|
||||||
self.break_condition = True
|
self.break_condition = True
|
||||||
|
|
||||||
|
self.total_win = g.level + 1 == len(levels)
|
||||||
|
self.final_points_given = False
|
||||||
|
|
||||||
def generate_map_array(self):
|
def generate_map_array(self):
|
||||||
STATS['level_moves'][self.level] = 0
|
g.level_moves[self.level] = 0
|
||||||
|
|
||||||
level_array = self.level_map.split('\n')
|
level_array = self.level_map.split('\n')
|
||||||
|
|
||||||
|
@ -58,60 +77,82 @@ class Map:
|
||||||
self.map_array.append(row_elements)
|
self.map_array.append(row_elements)
|
||||||
|
|
||||||
def display(self):
|
def display(self):
|
||||||
|
if self.total_win and self.win and not self.final_points_given:
|
||||||
|
self.final_points_given = True
|
||||||
|
g.handle_points(self.calculate_points())
|
||||||
|
|
||||||
os.system('clear')
|
os.system('clear')
|
||||||
for storage_location in self.storage_locations:
|
for storage_location in self.storage_locations:
|
||||||
if self.map_array[storage_location[0]][storage_location[1]] == ' ':
|
if self.map_array[storage_location[0]][storage_location[1]] == ' ':
|
||||||
self.map_array[storage_location[0]][storage_location[1]] = '.'
|
self.map_array[storage_location[0]][storage_location[1]] = '.'
|
||||||
print(logo)
|
print(logo)
|
||||||
print(f' lvl: {self.level} | mvs: {STATS["level_moves"][self.level]} | pts: {STATS["points"]}')
|
print(f'lvl: {g.level} | mvs: {g.level_moves[self.level]} | pts: {g.points} | lives: {g.lives}')
|
||||||
for row in self.map_array:
|
|
||||||
print('\t', ''.join(row))
|
if self.lose:
|
||||||
|
print(lose)
|
||||||
if self.win:
|
elif self.total_win and self.win:
|
||||||
print('\n\n NICE! Press [w] to continue!')
|
print(win)
|
||||||
else:
|
else:
|
||||||
print('\n\n h = ← | j = ↓ | k = ↑ | l = →')
|
for row in self.map_array:
|
||||||
|
print('\t', ''.join(row))
|
||||||
|
|
||||||
|
if self.total_win:
|
||||||
|
print('\n\n Press [r] to to play again or [q] to quit')
|
||||||
|
elif self.win:
|
||||||
|
print('\n\n NICE! Press [w] to continue!')
|
||||||
|
elif self.lose:
|
||||||
|
print('\n\n Press [r] to retry')
|
||||||
|
else:
|
||||||
|
print('\n\npress [r] to reset the map')
|
||||||
|
|
||||||
def on_release(self, key):
|
def on_release(self, key):
|
||||||
self.listener = None
|
self.listener = None
|
||||||
if 'char' in dir(key):
|
if 'char' in dir(key):
|
||||||
if key.char == 'h':
|
if key.char == 'q':
|
||||||
self.move('left')
|
self.quit()
|
||||||
if key.char == 'l':
|
if key.char == '?':
|
||||||
self.move('right')
|
os.system('clear')
|
||||||
if key.char == 'j':
|
print(help)
|
||||||
self.move('down')
|
response = input('Back to the game? Press any key to contiue: ')
|
||||||
if key.char == 'k':
|
os.system('clear')
|
||||||
self.move('up')
|
|
||||||
if self.win:
|
if (self.total_win and self.win) or self.lose:
|
||||||
if key.char == 'w':
|
if key.char == 'r':
|
||||||
self.break_condition = False
|
self.retry()
|
||||||
|
else:
|
||||||
|
if key.char == 'h' or key.char == '4':
|
||||||
|
self.move('left')
|
||||||
|
if key.char == 'l' or key.char == '6':
|
||||||
|
self.move('right')
|
||||||
|
if key.char == 'j' or key.char == '2':
|
||||||
|
self.move('down')
|
||||||
|
if key.char == 'k' or key.char == '8':
|
||||||
|
self.move('up')
|
||||||
|
if key.char == 'y' or key.char == '7':
|
||||||
|
self.move('up left')
|
||||||
|
if key.char == 'u' or key.char == '9':
|
||||||
|
self.move('up right')
|
||||||
|
if key.char == 'b' or key.char == '1':
|
||||||
|
self.move('down left')
|
||||||
|
if key.char == 'n' or key.char == '3':
|
||||||
|
self.move('down right')
|
||||||
|
if key.char == 'r':
|
||||||
|
self.reset_level()
|
||||||
|
if self.win:
|
||||||
|
if key.char == 'w':
|
||||||
|
self.win_level()
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def wait_for_input(self):
|
def wait_for_input(self):
|
||||||
with keyboard.Listener(on_release=self.on_release) as self.listener:
|
with keyboard.Listener(on_press=self.on_release) as self.listener:
|
||||||
self.listener.join()
|
self.listener.join()
|
||||||
|
|
||||||
def move(self, direction):
|
def move(self, direction):
|
||||||
STATS['level_moves'][self.level] += 1
|
g.level_moves[self.level] += 1
|
||||||
STATS['total_moves'] += 1
|
g.total_moves += 1
|
||||||
|
|
||||||
tmp_player_x = self.player_x
|
tmp_player_x, tmp_player_y = self.calculate_future_position(self.player_x, self.player_y, direction)
|
||||||
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]
|
future_position = self.map_array[tmp_player_y][tmp_player_x]
|
||||||
|
|
||||||
|
@ -128,22 +169,23 @@ class Map:
|
||||||
self.player_x = tmp_player_x
|
self.player_x = tmp_player_x
|
||||||
self.player_y = tmp_player_y
|
self.player_y = tmp_player_y
|
||||||
|
|
||||||
|
def calculate_future_position(self, x, y, direction):
|
||||||
|
dir_list = direction.split(' ')
|
||||||
|
|
||||||
|
if 'right' in dir_list:
|
||||||
|
x += 1
|
||||||
|
elif 'left' in dir_list:
|
||||||
|
x -= 1
|
||||||
|
|
||||||
|
if 'down' in dir_list:
|
||||||
|
y += 1
|
||||||
|
elif 'up' in dir_list:
|
||||||
|
y -= 1
|
||||||
|
|
||||||
|
return x, y
|
||||||
|
|
||||||
def push_boulder(self, tmp_player_y, tmp_player_x, direction):
|
def push_boulder(self, tmp_player_y, tmp_player_x, direction):
|
||||||
tmp_boulder_x = tmp_player_x
|
tmp_boulder_x, tmp_boulder_y = self.calculate_future_position(tmp_player_x, tmp_player_y, direction)
|
||||||
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]
|
future_position = self.map_array[tmp_boulder_y][tmp_boulder_x]
|
||||||
|
|
||||||
|
@ -161,14 +203,46 @@ class Map:
|
||||||
if (yidx, xidx) not in self.storage_locations:
|
if (yidx, xidx) not in self.storage_locations:
|
||||||
self.win = False
|
self.win = False
|
||||||
|
|
||||||
|
def win_level(self):
|
||||||
|
if not self.total_win:
|
||||||
|
g.handle_points(self.calculate_points())
|
||||||
|
g.level += 1
|
||||||
|
self.break_condition = False
|
||||||
|
|
||||||
|
def calculate_points(self):
|
||||||
|
multiplier = 1
|
||||||
|
penality = 0
|
||||||
|
|
||||||
|
if g.level_moves[g.level] < self.level_par:
|
||||||
|
multiplier = 1.5
|
||||||
|
elif g.level_moves[g.level] == self.level_par:
|
||||||
|
multiplier = 1.2
|
||||||
|
elif g.level_moves[g.level] > self.level_par:
|
||||||
|
penality = (g.level_moves[g.level] - self.level_par) * 0.1
|
||||||
|
|
||||||
|
return (10 - penality) * multiplier
|
||||||
|
|
||||||
|
def reset_level(self):
|
||||||
|
g.lives -= 1
|
||||||
|
g.handle_points(-3.5)
|
||||||
|
if g.lives <= 0:
|
||||||
|
self.lose = True
|
||||||
|
else:
|
||||||
|
self.break_condition = False
|
||||||
|
|
||||||
|
def retry(self):
|
||||||
|
global g
|
||||||
|
g = Game()
|
||||||
|
g.initialize_level()
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
os.system('clear')
|
||||||
|
response = input('Are you sure you want to quit? [Y/N]: ')[-1]
|
||||||
|
if response.lower() == 'y':
|
||||||
|
os.system('clear')
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
for level in range(len(levels)):
|
g = Game()
|
||||||
m = Map(level + 1)
|
g.initialize_level()
|
||||||
m.generate_map_array()
|
|
||||||
while m.break_condition:
|
|
||||||
m.display()
|
|
||||||
m.wait_for_input()
|
|
||||||
m.check_win_condition()
|
|
||||||
|
|
||||||
os.system('clear')
|
os.system('clear')
|
||||||
|
|
52
maps.py
52
maps.py
|
@ -1,8 +1,4 @@
|
||||||
logo = '''
|
level_1_par = 8
|
||||||
█▀█ █▄█ █▀ █▀█ █▄▀ █▀█ █▄▄ ▄▀█ █▄░█
|
|
||||||
█▀▀ ░█░ ▄█ █▄█ █░█ █▄█ █▄█ █▀█ █░▀█
|
|
||||||
'''
|
|
||||||
|
|
||||||
level_1 = '''
|
level_1 = '''
|
||||||
#############
|
#############
|
||||||
# #
|
# #
|
||||||
|
@ -11,6 +7,7 @@ level_1 = '''
|
||||||
#############
|
#############
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
level_2_par = 18
|
||||||
level_2 = '''
|
level_2 = '''
|
||||||
#############
|
#############
|
||||||
#. #
|
#. #
|
||||||
|
@ -19,8 +16,49 @@ level_2 = '''
|
||||||
#############
|
#############
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
level_3_par = 27
|
||||||
|
level_3 = '''
|
||||||
|
#############
|
||||||
|
# #######
|
||||||
|
#@ 00 . #
|
||||||
|
# . #
|
||||||
|
###################
|
||||||
|
'''
|
||||||
|
|
||||||
levels = [
|
levels = [
|
||||||
level_1,
|
(level_1, level_1_par),
|
||||||
level_2
|
(level_2, level_2_par),
|
||||||
|
(level_3, level_3_par),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
logo = '''
|
||||||
|
█▀█ █▄█ █▀ █▀█ █▄▀ █▀█ █▄▄ ▄▀█ █▄░█
|
||||||
|
█▀▀ ░█░ ▄█ █▄█ █░█ █▄█ █▄█ █▀█ █░▀█
|
||||||
|
'''
|
||||||
|
|
||||||
|
lose = '''
|
||||||
|
█▄█ █▀█ █░█ █░░ █▀█ █▀ █▀▀
|
||||||
|
░█░ █▄█ █▄█ █▄▄ █▄█ ▄█ ██▄
|
||||||
|
'''
|
||||||
|
|
||||||
|
win = '''
|
||||||
|
█▄█ █▀█ █░█ █░█░█ █ █▄░█
|
||||||
|
░█░ █▄█ █▄█ ▀▄▀▄▀ █ █░▀█
|
||||||
|
'''
|
||||||
|
|
||||||
|
help = r'''
|
||||||
|
Welcome to PYSOKOBAN!
|
||||||
|
The object of the game is to move all of the boulders to specific storage
|
||||||
|
positions in the shortest amount of moves possible.
|
||||||
|
|
||||||
|
KEY MOVEMENT
|
||||||
|
+===========================================+
|
||||||
|
|_symbol_|_meaning_|| y k u | 7 8 9 |
|
||||||
|
| @ | you || \ | / | \ | / |
|
||||||
|
| # | wall || h- . -l | 4- . -6 |
|
||||||
|
| 0 | boulder || / | \ | / | \ |
|
||||||
|
| . | storage || b j n | 1 2 3 |
|
||||||
|
+===========================================+
|
||||||
|
|
||||||
|
If you like my stuff visit my website: https://domdit.com
|
||||||
|
'''
|
||||||
|
|
Loading…
Reference in a new issue