This below program will be further enhanced for TicTacToe game with Human and Computer as players.Currently this program is written for choosing best move for a given grid position.package project2.tictactoe;enum TicTacToe{    X, O, NULL;    @Override    public String toString(){        switch(this){        case X:            return X;        case O:            return O;        default:            return NULL;        }    }}public class TicTacToeGame{    TicTacToe[][] twoDimArray = new TicTacToe[3][3];    TicTacToeGame(){        for(int i = 0; i < 3; i++){            for(int j = 0; j < 3; j++){                this.twoDimArray[i][j] = TicTacToe.NULL;            }        }    }    private static final Boolean HUMAN_TURN = false;    private static final Boolean COMPUTER_TURN = true;    private static String bestMove = null;    boolean gameDone(){        for(int i = 0; i < 3; i++){            if(this.twoDimArray[i][0] != TicTacToe.NULL){                if(this.twoDimArray[i][0] == this.twoDimArray[i][1]){                    if(this.twoDimArray[i][1] == this.twoDimArray[i][2]){                        return true;                    }                }            }            if(this.twoDimArray[0][i] != TicTacToe.NULL){                if(this.twoDimArray[0][i] == this.twoDimArray[1][i]){                    if(this.twoDimArray[1][i] == this.twoDimArray[2][i]){                        return true;                    }                }            }            if(i == 1){                /* Diagnol check */                if(this.twoDimArray[i-1][0] != TicTacToe.NULL){                    if(this.twoDimArray[i-1][0] == this.twoDimArray[i][i]){                        if(this.twoDimArray[i][i] == this.twoDimArray[i+1][i+1]){                            return true;                        }                    }                }                if(this.twoDimArray[i+1][0] != TicTacToe.NULL){                    if(this.twoDimArray[i+1][0] == this.twoDimArray[i][i]){                        if(this.twoDimArray[i][i] == this.twoDimArray[i-1][i+1]){                            return true;                        }                    }                }            }        } /* end for-loop*/        return false;    }    byte chooseBestMove(boolean side){        byte bestScore;        if(this.gameDone()){            if( side == HUMAN_TURN){                return +1; //actually computer side won here, so +1            }else{                return -1; //actually human side won here, so -1.            }        }else{            if(side == COMPUTER_TURN){                bestScore = -2; // this is little mathematics to maintain best score            }else{                bestScore = +2;            }            for(int i=0; i<9; ++i)                    if(this.twoDimArray[i/3][i%3] == TicTacToe.NULL)                    {                        /*Make a new possible move and modify the array on heap*/                        if(side == TicTacToeGame.COMPUTER_TURN){                            this.twoDimArray[i/3][i%3] = TicTacToe.O;                        }else{                            this.twoDimArray[i/3][i%3] = TicTacToe.X;                        }                        byte score = chooseBestMove(!side);                        if(side == TicTacToeGame.COMPUTER_TURN){                            if(score > bestScore){                                bestScore = score;                                bestMove = Place \ + TicTacToe.O + \ at position [ + i/3 + ][ + i%3 + ];                            }                        }                        if(side == TicTacToeGame.HUMAN_TURN){                            if(score < bestScore){                                bestScore = score;                                bestMove = Place \ + TicTacToe.X + \ at position [ + i/3 + ][ + i%3 + ];                            }                        }                        /* Undo the possible move */                        if(side == TicTacToeGame.COMPUTER_TURN){                            this.twoDimArray[i/3][i%3] = TicTacToe.NULL;                        }else{                            this.twoDimArray[i/3][i%3] = TicTacToe.NULL;                        }                    }        }        return bestScore;     }    void printElements(){        for(int i = 0; i < 3; i++){            System.out.println(  + twoDimArray[i][0] +  |  + twoDimArray[i][1] +  |  + twoDimArray[i][2]);            if(i != 2)                System.out.println(------------------);        }    }    public static void main(String[] args){        TicTacToeGame objRef = new TicTacToeGame();        boolean side = true; //first move is computer move        /* For any Grid scenario set below*/        objRef.twoDimArray[0][0] = TicTacToe.NULL;        objRef.twoDimArray[0][1] = TicTacToe.NULL;        objRef.twoDimArray[0][2] = TicTacToe.NULL;        objRef.twoDimArray[1][0] = TicTacToe.NULL;        objRef.twoDimArray[1][1] = TicTacToe.NULL;        objRef.twoDimArray[1][2] = TicTacToe.NULL;        objRef.twoDimArray[2][0] = TicTacToe.NULL;        objRef.twoDimArray[2][1] = TicTacToe.NULL;        objRef.twoDimArray[2][2] = TicTacToe.NULL;        /* Choose best move */        byte score = objRef.chooseBestMove(side);        System.out.println(TicTacToeGame.bestMove);    }}Does this program follow the elements of OOPs paradigm, abstraction and encapsulation?I would require comments to refine this programming style to fit into OOP paradigm.
Does this Tic-Tac-Toe game follow abstraction and encapsulation?
java;object oriented;tic tac toe;ai