/*
Online Java - IDE, Code Editor, Compiler

Online Java is a quick and easy tool that helps you to build, compile, test your programs online.
*/

import java.util.Scanner;
import java.io.*;
import java.util.*;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

interface Playable
{
    public void assignChip(String playerName, Character chipValue);    
    public void selectChipPosition(String playerName, Character chipValue);
    public boolean checkAvailability(int inputColumnAsIntegerZeroIndex, int inputRowAsIntegerZeroIndex, Character chipValue, PlayerOne plOne, PlayerTwo plTwo, String name);
    public boolean checkTicTacToe(Character chipValue, String checkConnectFour);
    public void viewBoard();
}

public class Main
{
    public static void main (String[] args)
    {
        TicTacToe noughtsCrosses = new TicTacToe();
    }
}

class PlayerOne
{
    String[][] board;
    String playerOneName;
    String playerTwoName;
    PlayerTwo plTwo;
    
    enum Chips
    {
        RED('O'),
        YELLOW('X');
            
        final Character value;
        
        Chips(Character value)
        {
            this.value=value;
        }
    }
    
    public PlayerOne(TicTacToe noughtsCrosses, String playerOne, String playerTwo, PlayerTwo plTwo)
    {
        this.board=board;
        this.plTwo = plTwo;
        Chips yellow = Chips.YELLOW;
        Character yellowValue = yellow.value;
        this.playerOneName=playerOne;
        this.playerTwoName=playerTwo;
        noughtsCrosses.assignChip(playerOneName, yellowValue);    
        noughtsCrosses.selectChipPosition(playerOneName,yellowValue);
        noughtsCrosses.checkAvailability(noughtsCrosses.inputColumnAsIntegerZeroIndex, noughtsCrosses.inputRowAsIntegerZeroIndex,yellowValue, this, plTwo, (playerOneName+"(Player 1)"));
        noughtsCrosses.checkTicTacToe(yellowValue, playerOneName);
        
        plTwo = new PlayerTwo (noughtsCrosses, playerOneName, playerTwoName, this);
    }
}

class PlayerTwo
{
    String[][] board;
    PlayerOne plOne;
    String playerTwoName;
    String playerOneName;
    
    enum Chips
    {
        RED('O'),
        YELLOW('X');
            
        final Character value;
        
        Chips(Character value)
        {
            this.value=value;
        }
    }
    
    public PlayerTwo(TicTacToe noughtsCrosses, String playerOne, String playerTwo, PlayerOne plOne)
    {
        this.board=board;
        Chips red = Chips.RED;
        Character redValue = red.value;
        this.playerTwoName=playerTwo;
        this.playerOneName=playerOne;
        noughtsCrosses.assignChip(playerTwoName, redValue); 
        noughtsCrosses.selectChipPosition(playerTwoName,redValue);
        noughtsCrosses.checkAvailability(noughtsCrosses.inputColumnAsIntegerZeroIndex, noughtsCrosses.inputRowAsIntegerZeroIndex, redValue, plOne, this, (playerTwoName+"(Player 2)"));
        noughtsCrosses.checkTicTacToe(redValue, playerTwoName);
        plOne = new PlayerOne (noughtsCrosses, playerOneName,playerTwoName, this);
    }
}

class TicTacToe implements Playable
{
    int rowChipPlacedAdjusted;
    boolean hasConfigureConsecutiveSymbols;
    boolean hasConfigurePlayers;
    boolean hasConfigureBoardSize;
    int numberConsecutiveForWin;
    int numChipsPlaced;
    String regexOptions;
    Pattern patternCols;
    Pattern patternRows;
    Scanner scanner;
    String[][] board;
    Matcher matcherRows;
    Matcher matcherCols;
    Integer inputInteger;
    Character inputCharColumn;
    Character inputCharRow;
    int inputRowAsIntegerZeroIndex;
    int inputColumnAsIntegerZeroIndex;
    
    int columnChipPlacedZeroIndex;
    int rowChipPlacedZeroIndex;
    int rowChipPlaced;
    int columnChipPlaced;
    
    //This is no longer equal to 0
    //I had to swap this around with boardBaseLevelZeroIndex
    int boardHeightZeroIndex;
    
    int boardBaseLevelZeroIndex;
    int boardWidth;
    int boardWidthZeroIndex;
    int boardFirstColumnZeroIndex = 0;
    int sameColourTotal=0;
    int columnsFilled;
    boolean gridFull[] = new boolean[boardWidth];
    boolean isAvailable;
    boolean rightColour=false;
    int offset;
    int runningTotalSameColour;
    String playerOneName;
    String playerTwoName;
    String playerNameChipValue;
    int boardHeight;
    PlayerOne plOne;
    PlayerTwo plTwo;
    String lastChipName;
    Character lastChipValue;
    boolean isGameOver = false;
    
    public boolean checkAvailability(int inputCol, int inputRow, Character chipValue, PlayerOne plOne, PlayerTwo plTwo, String name)
    {
        this.plOne=plOne;
        this.plTwo=plTwo;
        System.out.println("***CHECKING AVAILABILITY****" + "\tBoard height: " +boardHeight + "\tboard Width: " + boardWidth + "\tnumber consecutive for win: " +  numberConsecutiveForWin);
        
        
        //for (int k=boardBaseLevelZeroIndex; k>=boardHeightZeroIndex; k--)
        //{
            //we now need to do this calculation first before checking the board
            rowChipPlacedZeroIndex=inputRow;      
            rowChipPlacedAdjusted=Math.abs((rowChipPlaced-boardHeight));
            
            System.out.println("********");
            System.out.println(rowChipPlacedZeroIndex);
            //System.out.println("adjust:" + rowChipPlacedAdjusted);
            
            
            if (board[rowChipPlacedAdjusted][inputCol].equals("-"))
            {
                board[rowChipPlacedAdjusted][inputCol]= String.valueOf(chipValue);
                
                System.out.println("Chip: " + chipValue + " will be placed into column: " + (columnChipPlaced) + " row: " + rowChipPlaced);
                lastChipName = name;
                lastChipValue = chipValue;
                isAvailable=true;
                numChipsPlaced=numChipsPlaced+1;
            }
            else
            {
                isAvailable=false;
                
                System.out.println("Last chip inserted " + lastChipValue + " by: " + lastChipName);
            
            
            if(numChipsPlaced<(boardWidth*boardHeight))
            {
               
            if (lastChipValue.equals('O'))
            {
                
                  plOne = new PlayerOne (this,playerOneName,playerTwoName, plTwo);
            }
            else
            {
                System.out.println(name + ", your turn again. please choose a vacant spot");
                plTwo = new PlayerTwo (this, playerOneName, playerTwoName, plOne);
            }
            }
                
                
            }
        //}
        viewBoard();
        
        return true;
    }
    
    public boolean checkTicTacToe(Character chipValue, String playerName)
    {
        System.out.println("***CHECK TIC-TAC-TOE****"); 
        
        //This was a very pivotal line of code
        //since all this time I was performing checking based on rowChipPlacedZeroIndex..
        //but we know this is not where end user placed the chip.
        //since from their perspective they were counting rows from bottom.
        //I had to change my logic so that the grids actually look like defined arrays
        //otherwise it would become absolutely nightmare to manage the logic
        System.out.println("End user inputted chip: " + rowChipPlacedAdjusted + "," + columnChipPlacedZeroIndex + "(zero index notation)");
        
        playerNameChipValue = playerName + "("+chipValue+")";
        
        System.out.println("VERTICAL CHECK => DOWNWARDS*****");
        //System.out.println("row chip placd: " + rowChipPlacedZeroIndex);
        //System.out.println("base: " + boardBaseLevelZeroIndex);
        
        
        
        //NOW, I need to change all references of rowChipPlacedZeroIndex to rowChipPlacedAdjusted
       
        if (rowChipPlacedAdjusted!=boardHeightZeroIndex)
        {
            System.out.println("INSIDE - Vertical check downwards");
            //Since I changed the boardBaseLevelZeroIndex with boardHeightZeroIndex variable values 
            //I have also got to change the direction of the expression and condition
            for (int count = rowChipPlacedAdjusted; count<=boardHeightZeroIndex; count++)
            {
                if (!board[count][columnChipPlacedZeroIndex].equals(String.valueOf(chipValue)))
                {
                    System.out.println("DOES IT BREAK");
                    sameColourTotal=0;
                    break;
                }
                
                if (board[count][columnChipPlacedZeroIndex].equals(String.valueOf(chipValue)))
                {
                    System.out.println("D");
                    sameColourTotal++;
                    
                    //I am treating rightColour similar to horizontal right, NE.....
                    //in order to consolidate variables
                    
                    if (sameColourTotal>1)
                    {
                    rightColour=true;
                    }
                    System.out.println("SAME COLOUR TOTAL: " + sameColourTotal);
                    
                    if (sameColourTotal==numberConsecutiveForWin)
                    {
                        System.out.println("***5Congratulations " + playerNameChipValue + "  Connect 4 in column: " + "N <-> S via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");
                    
                        isGameOver=true;
                    }
                }
            }
            //for similar reason kept the runningTotal
            runningTotalSameColour=sameColourTotal;
            sameColourTotal=0;
        }
        
        //I now need to implement vertical check upwards.. This was not applicable in ConnectFour
        //I need to ensure it is completed correctly since it is completed from scratch
        //it is a mirror of vertical check downwards
        System.out.println("VERTICAL CHECK => UPWARDS******");
        System.out.println(sameColourTotal);
        System.out.println(runningTotalSameColour);
        
       
        if (rowChipPlacedAdjusted!=boardBaseLevelZeroIndex)
        {
            System.out.println("INSIDE - Vertical check upwards");
            
            //Since I changed the boardBaseLevelZeroIndex with boardHeightZeroIndex variable values 
            //I have also got to change the direction of the expression and condition
            for (int count = rowChipPlacedAdjusted; count>=boardBaseLevelZeroIndex; count--)
            {
                if (!board[count][columnChipPlacedZeroIndex].equals(String.valueOf(chipValue)))
                {
                    System.out.println("DOES IT BREAK");
                    sameColourTotal=0;
                    break;
                }
                
                if (board[count][columnChipPlacedZeroIndex].equals(String.valueOf(chipValue)))
                {
                    System.out.println("U");
                    sameColourTotal++;
                    
                    if (rightColour)
                    {
                        runningTotalSameColour=runningTotalSameColour-1;
                    }
                    
                    if (sameColourTotal+runningTotalSameColour==numberConsecutiveForWin)
                    {
                        System.out.println("***5Congratulations " + playerNameChipValue + "  Connect 4 in column: " + "N <-> S via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");

                        isGameOver=true;
                        return true;
                    }
                }
            }
            //for similar reason kept the runningTotal
             offset=0;
            sameColourTotal=0;
            runningTotalSameColour=0;
            rightColour=false;
        }
        //----------------------------------------------------
        
        
        
         
        
       
        
        
        
        System.out.println("HORIZONTAL CHECK => RIGHT*****");
        
        if (columnChipPlacedZeroIndex!=boardWidthZeroIndex)
        {
	    System.out.println("INSIDE - horizontal check right");
            for (int count = columnChipPlacedZeroIndex; count<=boardWidthZeroIndex; count++)
            {
                if (!board[rowChipPlacedAdjusted][count].equals(String.valueOf(chipValue)))
                {
                    sameColourTotal=0;
                    break;
                }
                
                if (board[rowChipPlacedAdjusted][count].equals(String.valueOf(chipValue)))
                {
                    System.out.println("R");
                    sameColourTotal++;
                    if (sameColourTotal>1)
                    {
                    rightColour=true;
                    }
                    if (sameColourTotal==numberConsecutiveForWin)
                    {
                        System.out.println("***4Congratulations " + playerNameChipValue + "  Connect 4 in row: " + "W <-> E via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");;

                        isGameOver=true;
                        return true;
                    }
                }
            }
            
            runningTotalSameColour=sameColourTotal;
            sameColourTotal=0;
        }
        
        System.out.println("HORIZONTAL CHECK => LEFT*****");
        System.out.println(sameColourTotal);
        System.out.println(runningTotalSameColour);
        
        if (columnChipPlacedZeroIndex!=boardFirstColumnZeroIndex)
        {   
            System.out.println("INSIDE - horizontal check left");
            for (int count = columnChipPlacedZeroIndex; count>=boardFirstColumnZeroIndex; count--)
            {
                if (!board[rowChipPlacedAdjusted][count].equals(String.valueOf(chipValue)))
                {
                    sameColourTotal=0;
                    break;
                }
                
                if (board[rowChipPlacedAdjusted][count].equals(String.valueOf(chipValue)))
                {
                    System.out.println("L");
                    sameColourTotal++;
                    
                    if (rightColour)
                    {
                        runningTotalSameColour=runningTotalSameColour-1;
                    }
                    
                    if (sameColourTotal+runningTotalSameColour==numberConsecutiveForWin)
                    {
                        System.out.println("***5Congratulations " + playerNameChipValue + "  Connect 4 in row: " + "W <-> E via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");

                        //System.out.println("***3Congratulations " + playerNameChipValue + "  Connect 4 in row:" + rowChipPlaced);
                        isGameOver=true;
                        return true;
                    }
                }
            }
            offset=0;
            sameColourTotal=0;
            runningTotalSameColour=0;
            rightColour=false;
        }
        
        
        //Base is equal to the top  0 row
        //height is equal to last row array
        
        System.out.println("DIAGONAL CHECK 1");  
    
        if (columnChipPlacedZeroIndex!=boardWidthZeroIndex && rowChipPlacedAdjusted!=boardBaseLevelZeroIndex)
        {
            System.out.println("INSIDE D1 - Diagonal north east check");
            
            for (int count = rowChipPlacedAdjusted; count>=boardBaseLevelZeroIndex; count--)
            {
                if (columnChipPlacedZeroIndex+offset<=boardWidthZeroIndex)
                {
                    if (!board[count][columnChipPlacedZeroIndex+offset].equals(String.valueOf(chipValue)))
                    {
                        sameColourTotal=0;
                        break;
                    }
                
                    if (board[count][columnChipPlacedZeroIndex+offset].equals(String.valueOf(chipValue)))
                    {
                        System.out.println("NE");
                        
                        sameColourTotal++;
                        if (sameColourTotal>1)
                    {
                        rightColour=true;
                    }
                        offset++;
                        
                        if (sameColourTotal==numberConsecutiveForWin)
                        {
                            System.out.println("***6Congratulations " + playerNameChipValue + "  Connect 4 in diagonal: " + "NE <-> SW via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");;

                            //System.out.println("***5Congratulations " + playerNameChipValue + "  Connect 4 in diagonal");
                            isGameOver=true;
                            return true;
                        }
                    }
                }
            }
            runningTotalSameColour=sameColourTotal;
            sameColourTotal=0;
            offset=0;
        }
            
        
        System.out.println("DIAGONAL CHECK 2"); 
                                                                         
        if (columnChipPlacedZeroIndex!=boardFirstColumnZeroIndex && rowChipPlacedAdjusted!=boardHeightZeroIndex)
        {
            System.out.println("INSIDE D2 - Diagonal south west check");
            
            for (int count = rowChipPlacedAdjusted; count<=boardHeightZeroIndex; count++)
            {
                if (columnChipPlacedZeroIndex-offset>=boardFirstColumnZeroIndex)
                {
                    if (!board[count][columnChipPlacedZeroIndex-offset].equals(String.valueOf(chipValue)))
                    {
                        sameColourTotal=0;
                        break;
                    }
                    
                    if (board[count][columnChipPlacedZeroIndex-offset].equals(String.valueOf(chipValue)))
                    {
                        System.out.println("SW");
                        sameColourTotal++;
                        offset++;
                        
                        if (rightColour)
                        {
                            runningTotalSameColour=runningTotalSameColour-1;
                        }
                        
                        if (sameColourTotal+runningTotalSameColour==numberConsecutiveForWin)
                        {
                            System.out.println("***7Congratulations " + playerNameChipValue + "  Connect 4 in diagonal: " + "SW <-> NE via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");

                            //System.out.println("***6Congratulations " + playerNameChipValue + "  Connect 4 in diagonal");
                            isGameOver=true;
                            return true;
                        }
                    }
                }
            }
            runningTotalSameColour=0;
            rightColour=false;
            sameColourTotal=0;
            offset=0;
        }
        
        
        
        System.out.println("DIAGONAL CHECK 3"); 
                                      
        if (columnChipPlacedZeroIndex!=boardWidthZeroIndex && rowChipPlacedAdjusted!=boardHeightZeroIndex)
        {
            System.out.println("INSIDE D3 - Diagonal south east check");
                                                        
            for (int count = rowChipPlacedAdjusted; count<=boardHeightZeroIndex; count++)
            {
                if (columnChipPlacedZeroIndex+offset<=boardWidthZeroIndex)               
                {
                    if (!board[count][columnChipPlacedZeroIndex+offset].equals(String.valueOf(chipValue)))
                    {
                        sameColourTotal=0;
                        break;
                    }
                    
                    if (board[count][columnChipPlacedZeroIndex+offset].equals(String.valueOf(chipValue)))
                    {
                        System.out.println("SE");
                        
                        sameColourTotal++;
                        if (sameColourTotal>1)
                        {
                            rightColour=true;
                        }
                        
                        offset++;
                        
                        if (sameColourTotal==numberConsecutiveForWin)
                        {
                            System.out.println("***8Congratulations " + playerNameChipValue + "  Connect 4 in diagonal: " + "NW <-> SE via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");

                            //System.out.println("***8Congratulations " + playerNameChipValue + "  Connect 4 in diagonal");
                            isGameOver=true;
                            return true;
                        }
                    }
                    
                }
            }
            runningTotalSameColour=sameColourTotal;
            sameColourTotal=0;
            offset=0;
        }
        
        
         //Base is equal to the top  0 row
        //height is equal to last row array
    
        
        System.out.println("DIAGONAL CHECK 4"); 
        
        if (columnChipPlacedZeroIndex!=boardFirstColumnZeroIndex && rowChipPlacedAdjusted!=boardBaseLevelZeroIndex)
        {
            System.out.println("INSIDE D4 - Diagonal north west check");
                
            for (int count = rowChipPlacedAdjusted; count>=boardBaseLevelZeroIndex; count--)
            {
                if (columnChipPlacedZeroIndex-offset>=boardFirstColumnZeroIndex)
                {
                    if (!board[count][columnChipPlacedZeroIndex-offset].equals(String.valueOf(chipValue)))
                    {
                        sameColourTotal=0;
                        break;
                    }
                    
                    if (board[count][columnChipPlacedZeroIndex-offset].equals(String.valueOf(chipValue)))
                    {
                        System.out.println("NW");
                        sameColourTotal++;
                        offset++;
                        
                        if (rightColour)
                        {
                            runningTotalSameColour=runningTotalSameColour-1;
                        }
                    
                        if (sameColourTotal+runningTotalSameColour==numberConsecutiveForWin)
                        {
                            System.out.println("***9Congratulations " + playerNameChipValue + "  Connect 4 in diagonal: " + "NW <-> SE via: "+ "["+columnChipPlaced+" , " + rowChipPlaced+"]");
                            isGameOver=true;
                            return true;
                        }
                    }
                }
            }
            rightColour=false;
            runningTotalSameColour=0;
            sameColourTotal=0;
            offset=0;
        }
        
        if (numChipsPlaced==(boardWidth*boardHeight))
        {
            System.out.println("GAME OVER - NO WINNER");
            System.exit(0);
        }
        
        return false;
    }
    
    public void menu()
    {
        regexOptions="[12345]";
        
        do
        {
        
        scanner = new Scanner(System.in);
        patternRows = Pattern.compile(regexOptions, Pattern.CASE_INSENSITIVE);
        
        System.out.println("***MENU****: " + "\tPlayer One: "+ playerOneName + "\tPlayer Two: " + playerTwoName + "\t\tBoard Size (W X H):  " + boardWidth+" X " + boardHeight + "\tNumber symbols win: " + numberConsecutiveForWin);
        System.out.println("1. Configure Players");
        System.out.println("2. Configure board size");
        System.out.println("3. Configure consecutive symbols for win");
        System.out.println("4. Start game");
        System.out.println("5. Exit");
        System.out.println("Please make a choice");
        
        inputInteger = scanner.nextInt();
        matcherRows = patternRows.matcher(String.valueOf(inputInteger));
        
        }while (!matcherRows.find());
        
        System.out.println("SELECTED: " + inputInteger);
        
        switch(inputInteger)
        {
            case 1:
                configurePlayers();
                menu();
                break;
                
                case 2:
                    System.out.println("HERE");
                    configureBoardSize();
                    menu();
                    break;
                    
                    case 3:
                        if (hasConfigureBoardSize)
                        {
                            configureConsecutiveSymbols();
                        }
                        else
                        {
                            System.out.println("Please complete\t\t2.Configure board size");
                            
                        }
                        menu();
                        break;
                        
                        case 4:
                            if (hasConfigureBoardSize && hasConfigurePlayers && hasConfigureConsecutiveSymbols)
                            {
                                System.out.println("WELCOME: " + playerOneName + " , " + playerTwoName+"\n");
                                PlayerOne plOne = new PlayerOne (this, playerOneName,playerTwoName, plTwo);
                            }
                            else
                            {
                                System.out.println("Please complete 1,2,3");
                                menu();
                            }
                            
                            break;
                            
                            case 5:
                            break;
                            default:
                            System.exit(0);
        }
    }
    
    public void configureBoardSize()
    {
        do 
        {
        scanner = new Scanner(System.in);
        System.out.println("Enter width:");
        boardWidth = scanner.nextInt();
        System.out.println("Enter height:");
        boardHeight = scanner.nextInt();
        
        //I could have potentially used regex here
        //But I wanted to limt usage only during inplay experience for the players
        //otherwise it will make the code too difficult to manage in the future
        //should we wish to change the rules
        }while (((boardHeight==3 && boardWidth==1) || (boardHeight==1 && boardWidth==3))); 
        
        boardWidthZeroIndex = boardWidth-1;
        boardHeightZeroIndex=boardHeight-1;
        //need to fill board now
        board = new String[boardHeight][boardWidth];
        
        System.out.println(boardHeight);
        System.out.println(boardWidth);
        
        for (int i=0; i<boardHeight;i++)
        {
            for (int j=0; j<boardWidth;j++)
            {
                board[i][j]="-";
            }
        }
        
        /*
        //Need to move this away
        //We can define customise board sizes here as required. All other areas will fall into place
        board = new String [][]   { {"-", "-", "-", "-", "-", "-", "-"},
                                    {"-", "-", "-", "-", "-", "-", "-"},
                                    {"-", "-", "-", "-", "-", "-", "-"},
                                    {"-", "-", "-", "-", "-", "-", "-"},
                                    {"-", "-", "-", "-", "-", "-", "-"},
                                    {"-", "-", "-", "-", "-", "-", "-"}
                                };
                                
                                */
        
        boardBaseLevelZeroIndex = 0;
        boardHeight=board.length;
        
        boardWidth=board[0].length;
        hasConfigureBoardSize=true;
    }
    
    public void configureConsecutiveSymbols()
    {
        scanner = new Scanner(System.in);
        
        do
        {
            System.out.println("Number consecutive symbols in row/diagonal constituing a win (greater than 2):");
            System.out.println("Should be less than equal to Width (" +boardWidth+") and Height (" + boardHeight+")");
            numberConsecutiveForWin = scanner.nextInt();
            //System.out.println("board width: " + boardWidth);
            System.out.println("numberConsecutiveForWin: " + numberConsecutiveForWin);
            
        }while (numberConsecutiveForWin<=2 || (numberConsecutiveForWin>boardWidth && numberConsecutiveForWin>boardHeight));
        
        hasConfigureConsecutiveSymbols = true;
    }
    
    public void configurePlayers()
    {
        scanner = new Scanner(System.in);
        System.out.println("Enter name for Player 1:");
        playerOneName = scanner.next();
        System.out.println("Enter name for Player 2:");
        playerTwoName = scanner.next();
        
        hasConfigurePlayers=true;
    }
    
    public void assignChip(String playerName, Character chip)
    {
        System.out.println("***ASSIGN CHIP****");
        System.out.println(playerName + " has been assigned: " + chip + " chip");
    }
    
    public void selectChipPosition(String playerName, Character chip)
    {
        System.out.println("***SELECT CHIP POSITION****");
        scanner = new Scanner(System.in);
        
        viewBoard();
        
        do
        {
            System.out.println(playerName + "("+chip+")" +  ",  Which column would you like to insert the chip?");
            inputCharColumn = scanner.next().charAt(0);
            
            System.out.println(playerName + "("+chip+")" +  ",  Which row would you like to insert the chip?");
            inputCharRow = scanner.next().charAt(0);
            
            //need to adjust this
            
            StringBuilder regex=new StringBuilder();
            int numColumnRegex=1;
            
            regex.append("[");
            do
            {
                regex.append(Integer.toString(numColumnRegex));
                numColumnRegex++;
                
            }while (numColumnRegex<=boardWidth);
            
            regex.append("]");
            regexOptions=regex.toString();
            //System.out.println("AVAILABLE COLUMNS: " + regexOptions);
            
            patternCols = Pattern.compile(regexOptions, Pattern.CASE_INSENSITIVE);
            matcherCols = patternCols.matcher(Character.toString(inputCharColumn));
            
            regex=new StringBuilder();
            int numRowRegex=1;
            
            
            regex.append("[");
            
            
            do
            {
                regex.append(Integer.toString(numRowRegex));
                numRowRegex++;
                
            }while (numRowRegex<=boardHeight);
            
            regex.append("]");
            regexOptions=regex.toString();
            System.out.println("AVAILABLE COLUMNS: " + regexOptions);
            
            patternRows = Pattern.compile(regexOptions, Pattern.CASE_INSENSITIVE);
            matcherRows = patternRows.matcher(Character.toString(inputCharColumn));
            
        
        }while (!matcherRows.find() && !matcherCols.find());
        
        
        
        inputColumnAsIntegerZeroIndex = Character.getNumericValue(inputCharColumn-1);
        columnChipPlacedZeroIndex = Character.getNumericValue(inputCharColumn-1);
        
        columnChipPlaced = Character.getNumericValue(inputCharColumn);
        
        
        inputRowAsIntegerZeroIndex = Character.getNumericValue(inputCharRow-1);
        rowChipPlacedZeroIndex = Character.getNumericValue(inputCharRow-1);
        rowChipPlaced = Character.getNumericValue(inputCharRow);
        
    }
    
    public void viewBoard()
    {
        int j=0;
        int rowOnBoard=0;
        
        if (isGameOver)
        {
            System.out.println("\n****CURRENT BOARD****: " + "***Congratulations " + playerNameChipValue);
            
            //since I am not exiting my code when player win, I need to set this otherwise
            //it will congratulate the opposing player on next turn even without reaching goal
            isGameOver=false;
        }
        else
        {
            System.out.println("\n****CURRENT BOARD****");
        }
        
        StringBuilder [] sb  = new StringBuilder[((board.length*2)+1)];
        
        for (int i=0; i<sb.length;i++)
        {
            if (i%2==0)
            {
                for (int f=0; f<board[0].length;f++)
                {
                    if (f==0)
                    {
                        sb[i+j]=new StringBuilder("|---|");
                    }
                    else
                    {
                        sb[i+j].append("---|");
                    }
                }
            }
            else
            {
                sb[i]=new StringBuilder("");
                
                if (rowOnBoard!=board.length)
                {
                    for (int m=0; m<board[0].length;m++)
                    {
                        if (m==0)
                        {
                            sb[i].append("|"+" " +board[rowOnBoard][m]+ " |");
                        }
                        else
                        {
                            sb[i].append(""+" "+board[rowOnBoard][m]+ " |");
                        }
                    }
                    rowOnBoard++;
                }
            }
        }
        for (StringBuilder gg: sb)
        {
            System.out.println(gg.toString());
        }
    }
    
    public TicTacToe() 
    {
        System.out.println("Welcome to Online IDE!! Happy Coding :)");
        System.out.println("*********Welcome to TIC-TAC-TOE**************");
        System.out.println("NOTE: Code will not terminate on a win, see onscreen messages");
        
        
        menu();
        
        if (hasConfigureBoardSize)
        {
            viewBoard();
        }
    }
}