This Connect 4 game will be used for implementing game-playing AI. Sample players are supplied. One takes user input, and the other plays randomly. Right now it's set for a human player to play against a randomly playing agent, but in the future I plan to try out algorithms such as Minimax and have AI agents play against themselves.Some more features (such as notifying the players when the game is over, instead of just printing to stdout) need to be added for later work, but I'm showing this simply as a working base. I'm not so much looking for feature suggestions, since those will come later. I will be adding docstrings and comments, but for now it should be straight forward.I'm looking for tips on: program correctness, code structure, and best practices (whether specific to Python or not).(Python 3.2.3)#!/usr/bin/env pythonimport numpy as npfrom copy import copyfrom abc import ABCMeta, abstractmethodclass Connect4Game():    def __init__(self, player1, player2):        self.player1 = player1        self.player2 = player2        self.player_names = {player1 : Player1, player2 : Player2}        self.board = np.zeros((6, 7), dtype=np.int8)        self.turn = player1        self.last_move = ()        self.winner = None    def gameover(self):        if self.last_move == ():            return False        rind, cind = self.last_move        row = self.board[rind, :]        col = self.board[:, cind]        diag1 = np.diagonal(self.board, cind - rind)        diag2 = np.diagonal(np.fliplr(self.board), -(cind + rind - 6))        for line in [row, col, diag1, diag2]:            if line.shape[0] < 4:                continue            for four in [line[i:i+4] for i in range(len(line)-3)]:                if sum(four == 1) == 4:                    self.winner = self.player1                    return True                elif sum(four == 2) == 4:                    self.winner = self.player2                    return True        if sum(self.board[0] == 0) == 0:            return True        return False    def move(self, cind):        free_index = sum(self.board[:, cind] == 0) - 1        if free_index == -1:            return False        if self.turn is self.player1:            self.board[free_index, cind] = 1            self.turn = self.player2        else:            self.board[free_index, cind] = 2            self.turn = self.player1        self.last_move = (free_index, cind)        return True    def play(self):        while not self.gameover():            print(self.board)            print(self.player_names[self.turn]+'s turn.)            self.move(self.turn.get_move(copy(self.board)))        print(self.board)        if self.winner is self.player1:            print(Winner: player1)        elif self.winner is self.player2:            print(Winner: player2)        else:            print(Tie)class BasePlayer(metaclass=ABCMeta):    @abstractmethod    def __init__(self, empty, me, opponent):        pass    @abstractmethod    def get_move(self, board):        passclass HumanPlayer(BasePlayer):    def __init__(self, empty, me, opponent):        pass    def get_move(self, board):        col = input(Your move (0-6): )        return int(col)class RandomPlayer(BasePlayer):    def __init__(self, empty, me, opponent):        pass    def get_move(self, board):        free_columns = np.where(board[0] == 0)[0]        return np.random.choice(free_columns)def main():    player1 = HumanPlayer(0, 1, 2)    player2 = RandomPlayer(0, 2, 1)    game = Connect4Game(player1, player2)    game.play()if __name__ == __main__:    main()
Connect 4 game for AI agents
python;python 3.x;numpy;connect four