diff options
| -rw-r--r-- | bot/exts/evergreen/tic_tac_toe.py | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/bot/exts/evergreen/tic_tac_toe.py b/bot/exts/evergreen/tic_tac_toe.py index a9971ad2..b306e803 100644 --- a/bot/exts/evergreen/tic_tac_toe.py +++ b/bot/exts/evergreen/tic_tac_toe.py @@ -1,4 +1,5 @@ import asyncio +import random import typing as t import discord @@ -44,6 +45,52 @@ class Player: return False, list(Emojis.number_emojis.keys())[list(Emojis.number_emojis.values()).index(react.emoji)] +class AI: + """Tic Tac Toe AI class for against computer gaming.""" + + def __init__(self, symbol: str): + self.symbol = symbol + + async def check_win(self, board: t.Dict[int, str]) -> bool: + """Check does this move will result game end.""" + if ( + # Horizontal + board[1] == board[2] == board[3] + or board[4] == board[5] == board[6] + or board[7] == board[8] == board[9] + # Vertical + or board[1] == board[4] == board[7] + or board[2] == board[5] == board[8] + or board[3] == board[6] == board[9] + # Diagonal + or board[1] == board[5] == board[9] + or board[3] == board[5] == board[7] + ): + return True + return False + + async def get_move(self, board: t.Dict[int, str], _: discord.Message) -> t.Tuple[bool, int]: + """Get move from AI. AI use Minimax strategy.""" + possible_moves = [i for i, emoji in board.items() if emoji in Emojis.number_emojis] + + for symbol in (Emojis.x, Emojis.o): + for move in possible_moves: + board_copy = board.copy() + board_copy[move] = symbol + if self.check_win(board_copy): + return False, move + + open_corners = [i for i in possible_moves if i in (1, 3, 7, 9)] + if len(open_corners) > 0: + return False, random.choice(open_corners) + + if 5 in possible_moves: + return False, 5 + + open_edges = [i for i in possible_moves if i in (2, 4, 6, 8)] + return False, random.choice(open_edges) + + class Game: """Class that contains information and functions about Tic Tac Toe game.""" |