import numpy as np
import random

#This is the random player
class Player:
    def __init__(self, token):
        self.token = token
        
    def make_move(self, board):
        rows, cols = board.shape

        print("BOARD:",board)
        
        while True:
            col = random.randint(0, cols - 1)  
            if board[0, col] == ' ':
                for row in reversed(range(rows)):
                    if board[row, col] == ' ':
                        board[row, col] = self.token
                        return

#Change this class (now equal to the one obove) and add your strategy here
class Player_Student:
    def __init__(self, token):
        self.token = token
        
    def make_move(self, board):
        rows, cols = board.shape

        print("BOARD:",board)
        
        while True:
            col = random.randint(0, cols - 1) #decide the column to play with your algorithm 
            if board[0, col] == ' ':
                for row in reversed(range(rows)):
                    if board[row, col] == ' ':
                        board[row, col] = self.token
                        return
                    
class FiveWins:
    def __init__(self, rows=10, cols=10):
        self.board = np.full((rows, cols), ' ')
        self.rows = rows
        self.cols = cols
        self.winning_length = 5 #5wins

    def print_board(self):
        for row in self.board:
            print('|' + '|'.join(row) + '|')
        print(' ' + ' '.join(str(i) for i in range(self.cols)))

    def check_winner(self, token):
        # Check horizontal
        for row in range(self.rows):
            for col in range(self.cols - self.winning_length + 1):
                if np.all(self.board[row, col:col + self.winning_length] == token):
                    return True

        # Check vertical
        for col in range(self.cols):
            for row in range(self.rows - self.winning_length + 1):
                if np.all(self.board[row:row + self.winning_length, col] == token):
                    return True

        # Check / diagonal 
        for row in range(self.rows - self.winning_length + 1):
            for col in range(self.cols - self.winning_length + 1):
                if np.all([self.board[row + i, col + i] == token for i in range(self.winning_length)]):
                    return True

        # Check \ diagonal
        for row in range(self.winning_length - 1, self.rows):
            for col in range(self.cols - self.winning_length + 1):
                if np.all([self.board[row - i, col + i] == token for i in range(self.winning_length)]):
                    return True

        return False

    def is_full(self):
        return np.all(self.board[0, :] != ' ')

    def play_game(self, player1, player2):
        current_player = player1
        while True:
            current_player.make_move(self.board)
            self.print_board()

            if self.check_winner(current_player.token):
                print(f"Player {current_player.token} wins!")
                break

            if self.is_full():
                print("Draw game!")
                break

            current_player = player2 if current_player == player1 else player1

if __name__ == "__main__":
    
    player1 = Player('X') #The random player
    player2 = Player_Student('O') #your player
    game = FiveWins()
    game.play_game(player1, player2)


