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 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 = {
|
||||
'lives': 3,
|
||||
'points': 0,
|
||||
'total_moves': 0,
|
||||
'level_moves': {}
|
||||
}
|
||||
class Game:
|
||||
def __init__(self):
|
||||
self.map_instance = None
|
||||
self.level = 0
|
||||
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:
|
||||
def __init__(self, level=1):
|
||||
self.level = level
|
||||
self.level_map = levels[self.level - 1]
|
||||
def __init__(self):
|
||||
self.level = g.level
|
||||
self.level_map = levels[self.level][0]
|
||||
self.level_par = levels[self.level][1]
|
||||
self.map_array = []
|
||||
self.storage_locations = []
|
||||
|
||||
|
@ -33,10 +48,14 @@ class Map:
|
|||
self.previous_element = ' '
|
||||
|
||||
self.win = False
|
||||
self.lose = False
|
||||
self.break_condition = True
|
||||
|
||||
self.total_win = g.level + 1 == len(levels)
|
||||
self.final_points_given = False
|
||||
|
||||
def generate_map_array(self):
|
||||
STATS['level_moves'][self.level] = 0
|
||||
g.level_moves[self.level] = 0
|
||||
|
||||
level_array = self.level_map.split('\n')
|
||||
|
||||
|
@ -58,60 +77,82 @@ class Map:
|
|||
self.map_array.append(row_elements)
|
||||
|
||||
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')
|
||||
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!')
|
||||
print(f'lvl: {g.level} | mvs: {g.level_moves[self.level]} | pts: {g.points} | lives: {g.lives}')
|
||||
|
||||
if self.lose:
|
||||
print(lose)
|
||||
elif self.total_win and self.win:
|
||||
print(win)
|
||||
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):
|
||||
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
|
||||
if key.char == 'q':
|
||||
self.quit()
|
||||
if key.char == '?':
|
||||
os.system('clear')
|
||||
print(help)
|
||||
response = input('Back to the game? Press any key to contiue: ')
|
||||
os.system('clear')
|
||||
|
||||
if (self.total_win and self.win) or self.lose:
|
||||
if key.char == 'r':
|
||||
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
|
||||
|
||||
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()
|
||||
|
||||
def move(self, direction):
|
||||
STATS['level_moves'][self.level] += 1
|
||||
STATS['total_moves'] += 1
|
||||
g.level_moves[self.level] += 1
|
||||
g.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
|
||||
tmp_player_x, tmp_player_y = self.calculate_future_position(self.player_x, self.player_y, direction)
|
||||
|
||||
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_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):
|
||||
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
|
||||
tmp_boulder_x, tmp_boulder_y = self.calculate_future_position(tmp_player_x, tmp_player_y, direction)
|
||||
|
||||
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:
|
||||
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__':
|
||||
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()
|
||||
|
||||
g = Game()
|
||||
g.initialize_level()
|
||||
os.system('clear')
|
||||
|
|
52
maps.py
52
maps.py
|
@ -1,8 +1,4 @@
|
|||
logo = '''
|
||||
█▀█ █▄█ █▀ █▀█ █▄▀ █▀█ █▄▄ ▄▀█ █▄░█
|
||||
█▀▀ ░█░ ▄█ █▄█ █░█ █▄█ █▄█ █▀█ █░▀█
|
||||
'''
|
||||
|
||||
level_1_par = 8
|
||||
level_1 = '''
|
||||
#############
|
||||
# #
|
||||
|
@ -11,6 +7,7 @@ level_1 = '''
|
|||
#############
|
||||
'''
|
||||
|
||||
level_2_par = 18
|
||||
level_2 = '''
|
||||
#############
|
||||
#. #
|
||||
|
@ -19,8 +16,49 @@ level_2 = '''
|
|||
#############
|
||||
'''
|
||||
|
||||
level_3_par = 27
|
||||
level_3 = '''
|
||||
#############
|
||||
# #######
|
||||
#@ 00 . #
|
||||
# . #
|
||||
###################
|
||||
'''
|
||||
|
||||
levels = [
|
||||
level_1,
|
||||
level_2
|
||||
(level_1, level_1_par),
|
||||
(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