240 lines
8 KiB
Python
240 lines
8 KiB
Python
import os
|
|
import pickle
|
|
import sys
|
|
import time
|
|
|
|
from pynput.keyboard import Key, Listener, KeyCode
|
|
|
|
from assets.help import PAGE_ONE, PAGE_TWO, PAGE_THREE, PAGE_FOUR, PAGE_FIVE, PAGE_SIX, PAGE_SEVEN
|
|
from deck import Deck
|
|
|
|
|
|
class Game:
|
|
def __init__(self, username='Wayne Skyler'):
|
|
self.username = username
|
|
|
|
self.deck = Deck()
|
|
self.current_room_cards = []
|
|
self.selected_card = 0
|
|
self.graveyard = []
|
|
|
|
self.paused = False
|
|
|
|
self.room = 1
|
|
self.block_skip = False
|
|
|
|
self.weapon = None
|
|
self.defeated = []
|
|
|
|
self.max_health = 20
|
|
self.health = 20
|
|
|
|
self.history = []
|
|
|
|
self.help_screens = [PAGE_ONE, PAGE_TWO, PAGE_THREE, PAGE_FOUR, PAGE_FIVE, PAGE_SIX, PAGE_SEVEN]
|
|
self.current_help_screen = 0
|
|
self.on_help_screen = False
|
|
self.from_screen = None
|
|
|
|
|
|
self.score = len(self.deck.deck) * -1
|
|
self.save_file = 'save.pickle'
|
|
|
|
@property
|
|
def current_card(self):
|
|
return self.current_room_cards[self.selected_card]
|
|
|
|
def initialize(self):
|
|
self.deck = Deck()
|
|
self.deck.generate_deck()
|
|
self.deck.shuffle()
|
|
|
|
while len(self.current_room_cards) < 4 and len(self.deck.deck) > 0:
|
|
self.current_room_cards.append(self.deck.draw())
|
|
|
|
self.current_room_cards[0].selected = True
|
|
|
|
def display(self):
|
|
os.system('clear')
|
|
print(f"Current Room: {self.room} | Health: {self.health}/{self.max_health} | ? for Rules & Controls")
|
|
print('\t'.join([str(x) for x in self.current_room_cards]))
|
|
print('\n')
|
|
print('\n')
|
|
print(f"Weapon: {self.weapon if self.weapon else 'None'} {'[{}]'.format(' '.join([str(x) for x in self.defeated]) if self.graveyard else None)}")
|
|
print(f"{self.current_card.help_text(self.weapon)} [Enter]")
|
|
|
|
def flash_message(self, msg):
|
|
for i in reversed(range(3)):
|
|
os.system('clear')
|
|
print(msg)
|
|
print(f'\n\tWait {str(i+1)} Seconds...')
|
|
time.sleep(1)
|
|
|
|
def toggle_pause(self):
|
|
self.paused = True if not self.paused else False
|
|
|
|
def input(self):
|
|
|
|
def on_press(key):
|
|
self.history.append(key)
|
|
|
|
if self.paused and key != KeyCode.from_char('p'):
|
|
return False
|
|
|
|
if key == Key.right:
|
|
self.change_selected_card()
|
|
elif key == Key.left:
|
|
self.change_selected_card(False)
|
|
elif key == Key.enter:
|
|
if self.current_card.suit in [0, 2]: # Interact with selected card
|
|
self.attack()
|
|
elif self.current_card.suit == 1:
|
|
self.health_potion()
|
|
elif self.current_card.suit == 3:
|
|
self.equip_weapon()
|
|
elif key == KeyCode.from_char('s'): # Skip Room
|
|
self.skip_room()
|
|
elif key == KeyCode.from_char('b'): # Attack Barehanded
|
|
weapon_copy = self.weapon
|
|
self.weapon = None
|
|
self.attack()
|
|
self.weapon = weapon_copy
|
|
elif key == KeyCode.from_char('p'):
|
|
self.toggle_pause()
|
|
elif key == Key.esc: # Quit The Game
|
|
self.store_high_score()
|
|
sys.exit()
|
|
if key == KeyCode.from_char('?'):
|
|
self.on_help_screen = True if not self.on_help_screen else False
|
|
|
|
if key == Key.up:
|
|
if self.current_help_screen != 0:
|
|
self.current_help_screen -= 1
|
|
self.help_screen()
|
|
if key == Key.down:
|
|
if self.current_help_screen < len(self.help_screens) - 1:
|
|
self.current_help_screen += 1
|
|
self.help_screen()
|
|
|
|
return False
|
|
|
|
with Listener(on_press=on_press) as listener:
|
|
listener.join()
|
|
|
|
def help_screen(self):
|
|
os.system('clear')
|
|
print(self.help_screens[self.current_help_screen])
|
|
|
|
def change_selected_card(self, right=True):
|
|
self.current_card.selected = False
|
|
if right:
|
|
if self.selected_card != len(self.current_room_cards) - 1:
|
|
self.selected_card += 1
|
|
else:
|
|
if self.selected_card > 0:
|
|
self.selected_card -= 1
|
|
self.current_card.selected = True
|
|
|
|
def attack(self):
|
|
if self.current_card.suit not in [0, 2]:
|
|
self.flash_message('\n\n\n\tSelected card is not an enemy!')
|
|
return
|
|
|
|
if not self.weapon:
|
|
self.health -= self.current_card.value
|
|
|
|
if self.health > 0:
|
|
self.send_selected_to_grave()
|
|
else:
|
|
if self.defeated and self.defeated[-1].value < self.current_card.value:
|
|
self.health -= self.current_card.value
|
|
self.flash_message('\n\n\n\tYou should not have done that! \n\tYour weapon was not strong enough; causing you to take all of the damage!' )
|
|
self.send_selected_to_grave()
|
|
return
|
|
if self.weapon.value < self.current_card.value:
|
|
damage = self.current_card.value - self.weapon.value
|
|
self.health -= damage
|
|
if self.health <= 0:
|
|
pass
|
|
self.defeated.append(self.current_card)
|
|
self.send_selected_to_grave()
|
|
|
|
def send_selected_to_grave(self):
|
|
self.graveyard.append(self.current_room_cards.pop(self.selected_card))
|
|
self.check_win()
|
|
self.selected_card = 0
|
|
if len(self.current_room_cards) == 1:
|
|
self.advance_room()
|
|
if len(self.current_room_cards) > 0:
|
|
self.current_card.selected = True
|
|
self.deselect_defeated()
|
|
|
|
def health_potion(self):
|
|
self.health += self.current_card.value
|
|
if self.health > 20:
|
|
self.health = 20
|
|
self.send_selected_to_grave()
|
|
|
|
def equip_weapon(self):
|
|
self.defeated = []
|
|
self.weapon = self.current_card
|
|
self.current_card.selected = False
|
|
self.send_selected_to_grave()
|
|
|
|
def deselect_defeated(self):
|
|
for i in self.defeated:
|
|
i.selected = False
|
|
|
|
def advance_room(self):
|
|
self.block_skip = False
|
|
self.room += 1
|
|
|
|
# TODO: This can be simplified with initialize room func
|
|
while len(self.current_room_cards) < 4:
|
|
self.current_room_cards.append(self.deck.draw())
|
|
self.current_room_cards[0].selected = True
|
|
|
|
def skip_room(self):
|
|
if self.block_skip:
|
|
self.flash_message('\n\n\n\tYou cannot run away!')
|
|
else:
|
|
for card in self.current_room_cards:
|
|
card.selected = False
|
|
self.deck.deck.append(card)
|
|
self.current_room_cards = []
|
|
self.advance_room()
|
|
self.block_skip = True
|
|
self.flash_message('\n\n\n\tRun Away, Coward!! 🤡')
|
|
|
|
def cleanup(self):
|
|
self.current_room_cards = [x for x in self.current_room_cards if x is not None]
|
|
|
|
def store_high_score(self):
|
|
self.calculate_score()
|
|
with open(self.save_file, 'rb') as f:
|
|
save_data = pickle.load(f)
|
|
save_data['high_scores'].append((self.username, self.score))
|
|
sorted_high_scores = sorted(save_data['high_scores'], key=lambda x: x[1], reverse=True)[:9]
|
|
save_data['high_scores'] = sorted_high_scores
|
|
|
|
with open(self.save_file, 'wb') as f:
|
|
pickle.dump(save_data, f)
|
|
|
|
def calculate_score(self):
|
|
self.score = 0
|
|
for card in self.current_room_cards + list(self.deck.deck):
|
|
if card.suit in [0, 2]:
|
|
self.score -= card.value
|
|
|
|
if self.score == 0:
|
|
self.score += self.health
|
|
for card in self.current_room_cards + list(self.deck.deck):
|
|
if card.suit == 1:
|
|
self.score += card.value
|
|
|
|
def check_win(self):
|
|
if len(self.deck.deck) <= 0 and len(self.current_room_cards) <= 0:
|
|
self.calculate_score()
|
|
self.store_high_score()
|
|
return True
|
|
|