package cpsc2150.extendedConnectX.models;

/**
 * Class that represents an entire game board for the ExtendedConnectX game using an
 * array.
 * <p>This class includes methods to place tokens, check token locations,
 * and determine whether or not the game has been won or is over.</p>
 *
 * @author Owen Sullivan
 * @version 1.0
 *
 * @invariant
 *      (board[][] = ' ' OR board[][] = [ a player token ]) AND
 *      [ there are no gaps between non-space tokens ] AND
 *      MIN_ROWS {@code <=} numRows {@code <} MAX_ROWS AND
 *      MIN_COLUMNS {@code <=} numColumns {@code <} MAX_COLUMNS
 *      MIN_NUM_TO_WIN {@code <=} numToWin {@code <=} MAX_NUM_TO_WIN
 *
 * @correspondence
 *      number_of_rows = numRows AND
 *      number_of_columns = numColumns AND
 *      num_to_win = numToWin AND
 *      self = board[0...numRows-1][0...numColumns-1]
 */
public class GameBoard extends AbsGameBoard implements IGameBoard {

    private int numRows;
    private int numColumns;
    private int numToWin;
    private char[][] board;

    /**
     * Constructor for GameBoard that takes parameters for the number of rows, the number of columns, and
     * the number needed to win, and initializes all indexes of board to ' '.
     *
     * @param rows Number of rows
     * @param columns Number of columns
     * @param win Number needed to win
     *
     * @pre
     *      MIN_ROWS {@code <=} rows {@code <} MAX_ROWS AND
     *      MIN_COLUMNS {@code <=} columns {@code <} MAX_COLUMNS AND
     *      MIN_NUM_TO_WIN {@code <=} win {@code <=} MAX_NUM_TO_WIN
     *
     * @post
     *      board[][] = ' ' AND
     *      numRows = rows AND
     *      numColumns = columns AND
     *      numToWin = win AND
     *      [ size of board[] ] = numRows AND
     *      [ size of board[][] ] = numColumns
     */
    public GameBoard(int rows, int columns, int win) {

        // Update private variables
        numRows = rows;
        numColumns = columns;
        numToWin = win;

        // Initialize board
        board = new char[numRows][numColumns];

        // Loop through number of rows
        for (int i = 0; i < numRows; i++) {

            // Loop through number of columns
            for (int j = 0; j < numColumns; j++) {

                // Set the value at the current row and column to a space character
                board[i][j] = ' ';

            }

        }

    }

    public void placeToken(char p, int c) {

        // Loop through rows (starting from the bottom)
        for (int i = 0; i < numRows; i++) {

            // If the current value at current row and column indexes is a space (not a token)
            if (board[i][c] == ' ') {

                // Set the value to the parameter player token p
                board[i][c] = p;
                // Return early
                return;

            }

        }

    }

    public char whatsAtPos(BoardPosition pos) {

        // Call BoardPosition methods to get row and column, then return
        // the value at the corresponding indexes for row and column in board
        return board[pos.getRow()][pos.getColumn()];

    }

    public int getNumRows() {

        return numRows;

    }

    public int getNumColumns() {

        return numColumns;

    }

    public int getNumToWin() {

        return numToWin;

    }

}
