/*
 * 2006 Utah High School Programming Contest, University of Utah
 * Take-Home Problem
 *
 * BlockGroup.java
 *
 * This file contains the implementation of the BlockGroup class.
 */

/**
 * A <code>BlockGroup</code> represents a group of squares within a single
 * "sub-block" of a Sudoku <code>Board</code>.  Each square within the block
 * must have a unique value.  The primary task of a <code>BlockGroup</code> is
 * to manage that constraint.
 *
 * <p>All of the "interesting" parts of this class are implemented by the
 * <code>ConstrainedGroup</code> class.  The only things that need to be
 * implemented here involve the mapping between squares' [row, column]
 * coordinates and their indices within the group.
 *
 * @see ConstrainedGroup
 */
public class BlockGroup extends ConstrainedGroup {
    /**
     * The row number of the top-left square within this block of squares.
     */
    private final int topRow;

    /**
     * The column number of the top-left square within this block of squares.
     */
    private final int leftCol;

    /*************************************************************************/

    /**
     * Creates a new <code>BlockGroup</code>.  A block is a rectangular group
     * of squares on a Sudoku board.  The number of squares vertically is
     * <code>Board.BLOCK_HEIGHT</code>, and the number of squares horizontally
     * is <code>Board.BLOCK_WIDTH</code>.  Traditionally, the height and width
     * of a block are equal.
     *
     * <p>The group is initialized to indicate that every square value may be
     * contained in any square within the group.  In other words, nothing is
     * known about the assignment of values to squares.
     *
     * @param board    the <code>Board</code> to which this group belongs
     * @param topRow   the row number of the top-left square in the block
     * @param leftCol  the column number of the to-left square in the block
     */
    public BlockGroup(Board board, int topRow, int leftCol) {
        super(board);
        this.topRow = topRow;
        this.leftCol = leftCol;
    }

    /*
     * See comments for ConstrainedGroup#updateToIndex(Update).
     */
    protected int updateToIndex(Update u) {
        // Within a block, squares are numbered in row-major order.  For
        // example, in a 3x3 block, the square indices are as follows:
        //
        //   0 1 2
        //   3 4 5
        //   6 7 8
        //
        int rowDiff = u.row - topRow;
        int colDiff = u.col - leftCol;
        return (Board.BLOCK_WIDTH * rowDiff) + colDiff;
    }

    /*
     * See comments for ConstrainedGroup#getSquare(int).
     */
    protected Square getSquare(int index) {
        int rowInc = index / Board.BLOCK_WIDTH;
        int colInc = index % Board.BLOCK_WIDTH;

        return board.getSquare(topRow+rowInc, leftCol+colInc);
    }
}

// End of file.

