diff --git a/cmd_interface.py b/cmd_interface.py index 2483d3f..3f9c90e 100644 --- a/cmd_interface.py +++ b/cmd_interface.py @@ -1,4 +1,4 @@ - +__author__ = "7987847, Werner, 7347119, Fajst, 7735965, Melikidze" from os import get_terminal_size, name, system from sys import stdout @@ -24,14 +24,14 @@ class Terminal: class Matrix: def __init__(self): self.columns, self.lines = Terminal.get_size() - self.clear(self) + self.clear() def clear(self): self.matrix = [] def refresh(self): self.columns, self.lines = Terminal.get_size() - self.clear(self) + self.clear() for i in range(self.lines): self.matrix.append([]) for j in range(self.columns): @@ -40,51 +40,51 @@ class Matrix: def set_frame(self, x, y, dx, dy, rounded=True, double=False, title=None, alligncenter=True): if double: - self.set(self, x, y, "╔") - self.set(self, x + dx, y, "╗") - self.set(self, x, y + dy, "╚") - self.set(self, x + dx, y + dy, "╝") + self.set( x, y, "╔") + self.set(x + dx, y, "╗") + self.set(x, y + dy, "╚") + self.set(x + dx, y + dy, "╝") for i in range(1, dx): - self.set(self, x + i, y, "═") - self.set(self, x + i, y + dy, "═") + self.set(x + i, y, "═") + self.set(x + i, y + dy, "═") for i in range(1, dy): - self.set(self, x, y + i, "║") - self.set(self, x + dx, y + i, "║") + self.set(x, y + i, "║") + self.set(x + dx, y + i, "║") else: if rounded: - self.set(self, x, y, "╭") - self.set(self, x + dx, y, "╮") - self.set(self, x, y + dy, "╰") - self.set(self, x + dx, y + dy, "╯") + self.set(x, y, "╭") + self.set(x + dx, y, "╮") + self.set(x, y + dy, "╰") + self.set(x + dx, y + dy, "╯") else: - self.set(self, x, y, "┌") - self.set(self, x + dx, y, "┐") - self.set(self, x, y + dy, "└") - self.set(self, x + dx, y + dy, "┘") + self.set(x, y, "┌") + self.set(x + dx, y, "┐") + self.set(x, y + dy, "└") + self.set(x + dx, y + dy, "┘") for i in range(1, dx): - self.set(self, x + i, y, "─") - self.set(self, x + i, y + dy, "─") + self.set(x + i, y, "─") + self.set(x + i, y + dy, "─") for i in range(1, dy): - self.set(self, x, y + i, "│") - self.set(self, x + dx, y + i, "│") + self.set(x, y + i, "│") + self.set(x + dx, y + i, "│") if title is not None: if alligncenter: - self.set(self, x + int(dx / 2) - int(len(title) / 2) - 1, y, + self.set(x + int(dx / 2) - int(len(title) / 2) - 1, y, "┤" if not double else "╡") - self.set(self, x + int(dx / 2) + int(len(title) / 2), y, "├" if + self.set(x + int(dx / 2) + int(len(title) / 2), y, "├" if not double else "╞") - self.set_string(self, x + int(dx / 2) - int(len(title) / 2), + self.set_string(x + int(dx / 2) - int(len(title) / 2), y, title) else: - self.set(self, x + 1, y, "┤" if not double else "╡") - self.set(self, x + len(title) + 2, y, "├" if not double else + self.set(x + 1, y, "┤" if not double else "╡") + self.set( x + len(title) + 2, y, "├" if not double else "╞") - self.set_string(self, x + 2, y, title) + self.set_string(x + 2, y, title) def set_square(self, x, y, dx, dy, char): for i in range(dx): for j in range(dy): - self.set(self, x + i, y + j, char) + self.set(x + i, y + j, char) def set(self, x, y, value): try: @@ -103,10 +103,10 @@ class Matrix: def set_string(self, x, y, chars): for i in range(len(chars)): - self.set(self, x + i, y, chars[i]) + self.set(x + i, y, chars[i]) def set_string_center(self, y, chars): - self.set_string(self, int(Terminal.get_columns() / 2 - len(chars) / 2), + self.set_string(int(Terminal.get_columns() / 2 - len(chars) / 2), y, chars) def get_matrix(self): diff --git a/game.py b/game.py index bbcaee9..f29aa64 100644 --- a/game.py +++ b/game.py @@ -63,8 +63,8 @@ def compare_cards(cards_to_compare:list): return winner +if __name__ == '__main__': + card_deck = create_cards() + print(card_deck) -card_deck = create_cards() -print(card_deck) - -print(deal_cards(card_deck, 5, 5)) + print(deal_cards(card_deck, 5, 5)) \ No newline at end of file diff --git a/game_bot.py b/game_bot.py index a68e240..1ffa5d6 100644 --- a/game_bot.py +++ b/game_bot.py @@ -1,30 +1,22 @@ __author__ = "7987847, Werner, 7347119, Fajst, 7735965, Melikidze" class BOT: - def __init__(self, name, cards): + def __init__(self, name, bot_number, cards): self.name = name self.cards = cards self.points = 0 self.trumpf = False self.trumpf_color = None + self.bot_number = bot_number - def play_card(self, played_cards): + def play_card(self): ''' Plays a card - input: - - played_cards: list - list of cards that have been played already output: - card: dict card to play ''' - if len(played_cards) == 0: - return self.cards.pop(0) - else: - for card in self.cards: - if card['suit'] == played_cards[0]['suit']: - return self.cards.pop(self.cards.index(card)) - return self.cards.pop(0) + return self.cards.pop(0) def add_points(self, points): ''' @@ -114,6 +106,24 @@ class BOT: ''' return self.trumpf + def is_bot(self): + ''' + Returns if the player is a bot + output: + - is_bot: bool + if the player is a bot + ''' + return True + + def get_bot_number(self): + ''' + Returns the bot number + output: + - bot_number: int + bot number + ''' + return self.bot_number + # Setter def set_trumpf(self, trumpf): diff --git a/game_player.py b/game_player.py new file mode 100644 index 0000000..a8adb6a --- /dev/null +++ b/game_player.py @@ -0,0 +1,72 @@ +__author__ = "7987847, Werner, 7347119, Fajst, 7735965, Melikidze" + +class PLAYER: + def __init__(self, name, cards): + self.name = name + self.cards = cards + self.points = 0 + self.trumpf = False + self.trumpf_color = None + + def get_name(self): + ''' + Returns the name of the player + output: + - name: str + name of the player + ''' + return self.name + + def is_bot(self): + ''' + Returns if the player is a bot + output: + - is_bot: bool + if the player is a bot + ''' + return False + + def get_cards(self): + ''' + Returns the cards of the player + output: + - cards: list + list of cards of the player + ''' + return self.cards + + def pop_card(self, card:int): + ''' + Removes a card from the players cards + input: + - card: int + index of the card + ''' + return self.cards.pop(card) + + def get_cards(self): + ''' + Returns the cards of the player + output: + - cards: list + list of cards of the player + ''' + return self.cards + + def add_points(self, points): + ''' + Adds points to the player + input: + - points: int + points to add + ''' + self.points += points + + def get_points(self): + ''' + Returns the points of the player + output: + - points: int + points of the player + ''' + return self.points \ No newline at end of file diff --git a/main.py b/main.py index 919e6d9..152d8fb 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,104 @@ -__author__ = "7987847, Werner, 7347119, Fajst, 1234567, dalimeli" +__author__ = "7987847, Werner, 7347119, Fajst, 7735965, Melikidze" + +from cmd_interface import Matrix, Terminal +from time import sleep + +import screen_handler +import game +from game_bot import BOT +from game_player import PLAYER + +screen = Matrix() + +NO = ["n", 'N', 'no', 'No', 'NO', 'nO',''] +YES = ["y", 'Y', 'yes', 'Yes', 'YES', 'yES','yEs','YeS','yES', ''] + +previous_config = None +def main(first_time:bool=True, previous_config = None): + if first_time: + screen.refresh() + screen.set_frame(int(Terminal.get_columns() / 2 - 25), int(Terminal.get_lines() / 2 - 10), 50, 20, rounded=True, title="Welcome to the game") + screen.set_string_center(int(Terminal.get_lines() /2 - 7), "Follow these instructions") + screen.set_string_center(int(Terminal.get_lines() /2 - 6), "for an enhanced gaming experience:") + screen.set_string_center(int(Terminal.get_lines() /2 - 4), "1. Make sure your terminal is") + screen.set_string_center(int(Terminal.get_lines() /2 - 3), " fullscreen or at least 80x24") + screen.set_string_center(int(Terminal.get_lines() /2), "2. Make sure to not resize your") + screen.set_string_center(int(Terminal.get_lines() /2 + 1), " terminal during gameplay") + screen.set_string_center(int(Terminal.get_lines() /2 + 4), "Your terminal currently has the size:") + screen.set_string_center(int(Terminal.get_lines() /2 + 5), f"{Terminal.get_columns()}x{Terminal.get_lines()}") + screen.set_string_center(int(Terminal.get_lines() /2 + 7), "If your terminal is not fullscreen or") + screen.set_string_center(int(Terminal.get_lines() /2 + 8), "at least 80x24, the game will pause") + screen.set_string_center(int(Terminal.get_lines() /2 + 9), "and display an error message until resolved") + if screen_handler.console_input("Would you like to check out the rules of the game?", "[Y/n]", screen) in YES: + # TODO: Show rules + screen_handler.game_rules(screen) + screen.refresh() + if previous_config is not None and screen_handler.console_input("Would you like to reuse the configuration from the last game?", "[Y/n]", screen) in YES: + pass + else: + previous_config = screen_handler.config_sequence(screen) + + screen.refresh() + screen.print() + + + card_deck = game.create_cards() + dealt_cards = game.deal_cards(card_deck, int(previous_config[1]) + int(previous_config[2]), int(previous_config[3])) + + players = [] + for i in range(0, int(previous_config[1])): + players.append(PLAYER(screen_handler.console_input(f'Name for Player {i + 1}', '', screen=screen), dealt_cards[i])) + for i in range(0, int(previous_config[2])): + players.append(BOT(f'Bot {i + 1}', i + 1, dealt_cards[len(previous_config[1]) + i])) + + screen.refresh() + + screen_handler.starting_screen(screen, players) + + sleep(5) + + screen.refresh() + + round_no = 0 + + while players[0].get_cards() != []: + round_no += 1 + cards = [] + for player in players: + if player.is_bot(): + cards.append(screen_handler.bot_interface(screen, player, round_no)) + sleep(0.5) + else: + cards.append(screen_handler.player_interface(screen, player, round_no)) + players[game.compare_cards(cards)].add_points(1) + + # determine winner + winner = players[0] + for player in players: + if player.get_points() > winner.get_points(): + winner = player + screen_handler.winner_screen(screen, winner, players) + + + + + + + + return previous_config + + + +if __name__ == "__main__": + try: + previous_config = main() + while screen_handler.console_input("Would you like to play again?", "[Y/n]", screen) in YES: + screen.refresh() + previous_config = main(first_time=False, previous_config=previous_config) + except KeyboardInterrupt: + pass + + Terminal.clear() + print("Thank you for playing!") \ No newline at end of file diff --git a/screen_handler.py b/screen_handler.py new file mode 100644 index 0000000..0e39d8b --- /dev/null +++ b/screen_handler.py @@ -0,0 +1,201 @@ +__author__ = "7987847, Werner, 7347119, Fajst, 7735965, Melikidze" + +from time import sleep +from cmd_interface import Matrix, Terminal +from game_player import PLAYER +from game_bot import BOT + + +def console_input(text:str, input_str:str, screen:Matrix, fullscreen=False): + screen.set_string(2, Terminal.get_lines() - 2, text) + screen.set(0, Terminal.get_lines() - 2, "│") + screen.set_string(0, Terminal.get_lines() - 3, "╭─────────────────────────── ── ── ─ ─ ─") + if fullscreen: + screen.set_string(0, Terminal.get_lines() - 3, "├─────────────────────────── ── ── ─ ─ ─") + screen.set_string(0, Terminal.get_lines() - 1, " ─ ─ ─ ── ── ") + screen.print() + return input("╰→ " + input_str + " ") + +def draw_card(card:dict, screen:Matrix, x:int, y:int): + pass + + +def game_rules(screen:Matrix): + screen.refresh() + screen.set_frame(0, 0, Terminal.get_columns() - 1, Terminal.get_lines() - 1, rounded=True, title="Game Rules") + screen.set_string(2, int(Terminal.get_lines() /2 - 6), "How to play:") + screen.set_string(2, int(Terminal.get_lines() /2 - 4), "1. The player with the lowest trumpf card starts the game") + screen.set_string(2, int(Terminal.get_lines() /2 - 3), "2. The player has to play a card of the same suit as the first card") + screen.set_string(2, int(Terminal.get_lines() /2 - 2), "3. If the player does not have a card of the same suit, he can play any card") + screen.set_string(2, int(Terminal.get_lines() /2 - 1), "4. The player with the highest card of the same suit wins the round") + screen.set_string(2, int(Terminal.get_lines() /2), "5. The player with the most points wins the game") + screen.set_string(2, int(Terminal.get_lines() /2 + 1), "6. The player with the most points wins the game") + screen.set_string(2, int(Terminal.get_lines() /2 + 3), "Press ENTER key to continue...") + screen.print() + input() + + +def config_sequence(screen:Matrix): + screen.refresh() + screen.set_frame(int(Terminal.get_columns() / 2 - 25), int(Terminal.get_lines() / 2 - 10), 50, 20, rounded=True, title="Game Configuration") + screen.set_string_center(int(Terminal.get_lines() /2 - 6), "Please answer the questions below:") + config = ['', '1', '1','1'] + question_possible_asnwers = ['1 - 5', '', ''] + previous_question = "" + question_no = 0 + for i in ['How many players are playing?','How many bots should be playing?', 'How many cards should be drawn per player?']: + input = "" + screen.set_string(int(Terminal.get_columns() / 2 - 24),int(Terminal.get_lines() /2 - 4 + question_no), " ") + screen.set_string(int(Terminal.get_columns() / 2 - 24),int(Terminal.get_lines() /2 - 2 + question_no), " ") + screen.set_string_center(int(Terminal.get_lines() /2 - 4 + question_no), previous_question + " " + config[question_no]) + screen.set_string_center(int(Terminal.get_lines() /2 - 2 + question_no), i) + screen.set_frame(int(Terminal.get_columns() / 2 - 24), int(Terminal.get_lines() / 2 - 3 + question_no), 48, 2,double=True) + config[question_no + 1] = console_input(i, "[" + question_possible_asnwers[question_no] + "]", screen) + previous_question = i + question_no += 1 + question_possible_asnwers[1] = f"{'0' if config[1] == '5' else '1'} - {5 - int(config[1])}" + question_possible_asnwers[2] = f"1 - {str(int(52 / (int(config[1]) + int(config[2]))))}" + return config + + +def starting_screen(screen:Matrix, players:list): + screen.refresh() + screen.set_frame(int(Terminal.get_columns() / 2 - 25), int(Terminal.get_lines() / 2 - 10), 50, 20, rounded=True, title="Preparing...") + screen.set_string_center(int(Terminal.get_lines() /2 - 6), "The game is starting...") + screen.set_string_center(int(Terminal.get_lines() /2 - 4), "Here are the players:") + # screen.set_string_center(int(Terminal.get_lines() /2 - 3), players[0].get_name()) + # screen.set_string_center(int(Terminal.get_lines() /2 - 2), players[1].get_name()) + # screen.set_string_center(int(Terminal.get_lines() /2 - 1), players[2].get_name()) + # screen.set_string_center(int(Terminal.get_lines() /2), players[3].get_name()) + # screen.set_string_center(int(Terminal.get_lines() /2 + 1), players[4].get_name()) + + for i in range(len(players)): + screen.set_string_center(int(Terminal.get_lines() /2 - 3 + i), players[i].get_name()) + + screen.print() + + +def add_bot_font(screen:Matrix, bot:int): + line_1 = "$$$$$$$\ $$\ " + line_2 = "$$ __$$\ $$ | " + line_3 = "$$ | $$ | $$$$$$\ $$$$$$\ " + line_4 = "$$$$$$$\ |$$ __$$\\_$$ _| " + line_5 = "$$ __$$\ $$ / $$ | $$ | " + line_6 = "$$ | $$ |$$ | $$ | $$ |$$\ " + line_7 = "$$$$$$$ |\$$$$$$ | \$$$$ | " + line_8 = "\_______/ \______/ \____/ " + + if bot == 1: + screen.set_string_center(4, line_1 + " $$\ ") + screen.set_string_center(5, line_2 + " $$$$ | ") + screen.set_string_center(6, line_3 + " \_$$ | ") + screen.set_string_center(7, line_4 + " $$ | ") + screen.set_string_center(8, line_5 + " $$ | ") + screen.set_string_center(9, line_6 + " $$ | ") + screen.set_string_center(10, line_7 + " $$$$$$\ ") + screen.set_string_center(11, line_8 + " \______|") + + elif bot == 2: + screen.set_string_center(4, line_1 + " $$$$$$\ ") + screen.set_string_center(5, line_2 + "$$ __$$\ ") + screen.set_string_center(6, line_3 + "\__/ $$ |") + screen.set_string_center(7, line_4 + " $$$$$$ |") + screen.set_string_center(8, line_5 + "$$ ____/ ") + screen.set_string_center(9, line_6 + "$$ | ") + screen.set_string_center(10, line_7 + "$$$$$$$$\ ") + screen.set_string_center(11, line_8 + "\________|") + + elif bot == 3: + screen.set_string_center(4, line_1 + " $$$$$$\ ") + screen.set_string_center(5, line_2 + "$$ ___$$\ ") + screen.set_string_center(6, line_3 + "\_/ $$ |") + screen.set_string_center(7, line_4 + " $$$$$ / ") + screen.set_string_center(8, line_5 + " \___$$\ ") + screen.set_string_center(9, line_6 + "$$\ $$ |") + screen.set_string_center(10, line_7 + "\$$$$$$ |") + screen.set_string_center(11, line_8 + " \______/ ") + + elif bot == 4: + screen.set_string_center(4, line_1 + "$$\ $$\ ") + screen.set_string_center(5, line_2 + "$$ | $$ |") + screen.set_string_center(6, line_3 + "$$ | $$ |") + screen.set_string_center(7, line_4 + " $$$$$$$$ |") + screen.set_string_center(8, line_5 + "\_____$$ |") + screen.set_string_center(9, line_6 + " $$ |") + screen.set_string_center(10, line_7 + " $$ |") + screen.set_string_center(11, line_8 + " \__|") + + + screen.print() + + +def draw_player_cards(screen:Matrix, cards:list): + card1 = "╔═══╗" + card2 = "║ X ║" + card3 = "║ X ║" + card4 = "╚═══╝" + + SUITS = ["♠", "♥", "♦", "♣"] + RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] + + y = 5 + x = 0 + + for i in range(len(cards)): + card = cards[i] + if Terminal.get_columns() < x + 10: + y += 7 + x = 0 + if card.get("suit") == "Spades": + card2 = "║ ♠ ║" + elif card.get("suit") == "Hearts": + card2 = "║ ♥ ║" + elif card.get("suit") == "Diamonds": + card2 = "║ ♦ ║" + elif card.get("suit") == "Clubs": + card2 = "║ ♣ ║" + + if card.get("rank") == "Ace": + card3 = "║ A ║" + elif card.get("rank") == "Jack": + card3 = "║ J ║" + elif card.get("rank") == "Queen": + card3 = "║ Q ║" + elif card.get("rank") == "King": + card3 = "║ K ║" + elif card.get("rank") == "10": + card3 = "║10 ║" + else: + card3 = f"║ {card.get('rank')} ║" + + screen.set_string(3 + x, y - 1, " " + str(i)) + screen.set_string(3 + x, y, card1) + screen.set_string(3 + x, y + 1, card2) + screen.set_string(3 + x, y + 2, card3) + screen.set_string(3 + x, y + 3, card4) + + x += 6 + + + +def player_interface(screen:Matrix, player:PLAYER, round_no:int): + screen.refresh() + screen.set_frame(0, 0, Terminal.get_columns() - 1, Terminal.get_lines() - 1, rounded=True, title=f"Player '{player.get_name()}' is playing in round NO. {round_no}") + draw_player_cards(screen, player.get_cards()) + screen.print() + chosen_card = console_input("Choose a card by its number", str(len(player.get_cards())), screen, fullscreen=True) + return player.pop_card(int(chosen_card)) + +def bot_interface(screen:Matrix, bot:BOT, round_no:int): + screen.refresh() + screen.set_frame(0, 0, Terminal.get_columns() - 1, Terminal.get_lines() - 1, rounded=True, title=f"Bot {bot.get_name()} is playing in round NO. {round_no}") + add_bot_font(screen, bot.get_bot_number()) + screen.print() + return bot.play_card() + +def winner_screen(screen, winner, players:list): + screen.refresh() + screen.set_frame(int(Terminal.get_columns() / 2 - 25), int(Terminal.get_lines() / 2 - 10), 50, 20, rounded=True, title=f"Player '{winner.get_name()}' won the game!") + screen.set_string_center(4, "Congratulations!") + screen.set_string_center(5, f"Player '{winner.get_name()}' won the game!") + screen.print()