Source code for ttt.play

from typing import Callable

from loguru import logger

from .models import Game, HumanAgent, CPUAgent
from .rewarding import rewarding


[docs]def play_game_cpu_vs_cpu(player_1: CPUAgent, player_2: CPUAgent, player_1_mode: str, player_2_mode: str, num_rounds: int, display_board: bool = True, display_text: bool = True) -> Game: """ Plays a game between two cpu players. Parameters ---------- player_1: ttt.models.CPUAgent player_2: ttt.models.CPUAgent player_1_mode: str Whether best or random. player_2_mode: str Whether best or random. num_rounds: int Number or rounds to be played. display_board: bool Whether to display the board after each move. display_text: bool Whether to display game information Returns ------- played_game: ttt.models.Game Raises ------ AssertionError: if `num_rounds` < 1 """ assert num_rounds > 0 player_1_move = player_1.get_random_move if player_1_mode == 'random' else player_1.get_best_move player_2_move = player_2.get_random_move if player_2_mode == 'random' else player_2.get_best_move player_1_victories = 0 player_2_victories = 0 start = -1 for _ in range(num_rounds): start = (start + 1) % 2 game = play_game(Game(player_1, player_2), player_1_move, player_2_move, start, display_board) if game.result == 1: player_1_victories += 1 elif game.result == 2: player_2_victories += 1 if display_text: if game.result > 0: logger.info("Player " + str(game.result) + " wins!") else: logger.info("It's a tie!") if display_text: logger.info(f"\n\nScores: CPU1 {player_1_victories} - {player_2_victories} CPU2") return game
[docs]def play_game_player_vs_comp(cpu_player: CPUAgent, cpu_player_mode: str) -> Game: """ Plays a game between a human player and a CPU agent. Parameters ---------- cpu_player: ttt.models.CPUAgent cpu_player_mode: str Whether best or random. Returns ------- played_game: ttt.models.Game """ human_player = HumanAgent() cpu_player_move = cpu_player.get_random_move if cpu_player_mode == 'random' else cpu_player.get_best_move human_player_victories = 0 cpu_player_victories = 0 start = -1 while True: start = (start + 1) % 2 game = play_game(Game(human_player, cpu_player), human_player.get_next_move, cpu_player_move, start) if game.result == 1: human_player_victories += 1 elif game.result == 2: cpu_player_victories += 1 if game.result == 1: logger.info("Player wins!") elif game.result == 2: logger.info("CPU wins!") else: logger.info("It's a tie!") next_round = -1 while next_round not in {1, 2}: logger.info("Do you want to play another round?\n\t1. Yes\n\t2. No\n") next_round = int(input()) if next_round == 2: break cpu_player = rewarding(game, 2, 0.6) logger.info(f"Scores: PLAYER {human_player_victories} - {cpu_player_victories} CPU") return game
[docs]def play_game_player_vs_player() -> None: """Plays a game between 2 human players""" player_1 = HumanAgent() player_2 = HumanAgent() player_1_victories = 0 player_2_victories = 0 start = -1 while True: start = (start + 1) % 2 game = play_game(Game(player_1, player_2), player_1.get_next_move, player_2.get_next_move, start) if game.result == 1: player_1_victories += 1 elif game.result == 2: player_2_victories += 1 if game.result == 1: logger.info("Player 1 wins!") elif game.result == 2: logger.info("Player 2 wins!") else: logger.info("It's a tie!") next_round = -1 while next_round not in {1, 2}: logger.info("Do you want to play another round?\n\t1. Yes\n\t2. No\n") next_round = int(input()) if next_round == 2: break logger.info(f"Scores: PLAYER1 {player_1_victories} - {player_2_victories} PLAYER2") return
[docs]def play_game(game: Game, player_1_move: Callable, player_2_move: Callable, start: int, display_board: bool = True) -> Game: """ Runs 1 round of a game. Parameters ---------- game: ttt.models.Game Game to be played. player_1_move: method Player's method that computes the next move. player_2_move: method Player's method that computes the next move. start: int Which player will start. display_board: bool Whether to display the board after each move or not. Returns ------- played_game: ttt.models.Game """ if start == 0: order = { 'first': {"player_id": 1, "move": player_1_move}, 'second': {"player_id": 2, "move": player_2_move} } else: order = { 'first': {"player_id": 2, "move": player_2_move}, 'second': {"player_id": 1, "move": player_1_move} } while game.result < 0: # continue till outcome of game is not decided if display_board: game.print_board() move1 = order["first"]["move"]() game.apply_move(move1, order["first"]["player_id"]) if display_board: game.print_board() if game.result >= 0: break move2 = order["second"]["move"]() game.apply_move(move2, order["second"]["player_id"]) if display_board: game.print_board() return game