// DoxBoard.java // exported methods: // // DoxBoard constructor // String toString() overrides Object.toString() // int[] validMoves() returns a List of valid moves (empty spots) // DoxBoard applyMove(move, whoseTurn) returns updated board (does not update this) // String getBoxOwner(r, c) returns "A" or "B" or " " // int numBoxRows() returns number of rows // int numBoxCols() returns number of columns // boolean gameIsOver() returns true if all squares are owned // int numBoxesOwnedBy(player) returns the count import java.util.*; class DoxBoard { private Box[][] boxes; int boxRows, boxCols; // rows and cols of boxes, not dots public boolean anotherMove; DoxBoard(int dotRows, int dotCols, String lines, String boxOwners) { boxRows = dotRows - 1; boxCols = dotCols - 1; anotherMove = false; // turns true when a box is surrounded boxes = new Box[boxRows][boxCols]; // the first q-1 chars in lines specify horizontal lines; // vertical lines are specified by chars starting at q int q = dotRows * (dotCols - 1); for (int r = 0; r " + // (q + c * boxRows + r)); boolean l = lines.charAt(q + c * boxRows + r) == 'X'; boolean ri = lines.charAt(q + (c+1) * boxRows + r) == 'X'; char owner = boxOwners.charAt(r * boxCols + c); String ownedBy = " "; if (owner == 'A') ownedBy = "A"; else if (owner == 'B') ownedBy = "B"; boxes[r][c] = new Box(t, ri, b, l, ownedBy); } } } // constructor for internal use only - does a deep clone private DoxBoard(DoxBoard b1) { boxRows = b1.boxRows; boxCols = b1.boxCols; anotherMove = false; boxes = new Box[boxRows][boxCols]; for (int r = 0; r validMoves() { ArrayList list = new ArrayList(); for (int r = 0; r= q - boxCols) // on the bottom row { row = boxRows - 1; if (newBoard.boxes[row][col].bottom) System.err.println("**Error 2 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].bottom = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } } else // on a middle row, update two boxes { row = (move - col) / boxCols; if (newBoard.boxes[row][col].top) System.err.println("**Error 3 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].top = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } row = row - 1; if (newBoard.boxes[row][col].bottom) System.err.println("**Error 4 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].bottom = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } } } else // vertical line { int col; int row = (move - q) % boxRows; // integer division, truncates if (move - q < boxRows) // on the left column { col = 0; if (newBoard.boxes[row][col].left) System.err.println("**Error 5 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].left = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } } else if (move >= q + (boxRows * boxCols)) // on the right column { col = boxCols - 1; if (newBoard.boxes[row][col].right) System.err.println("**Error 6 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].right = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } } else // on a middle column, update two boxes { col = (move - q - row) / boxRows; if (newBoard.boxes[row][col].left) System.err.println("**Error 7 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].left = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } col = col - 1; if (newBoard.boxes[row][col].right) System.err.println("**Error 8 in applyMove, " +move+ " is not empty."); else { newBoard.boxes[row][col].right = true; if (newBoard.surrounded(row, col)) { newBoard.boxes[row][col].ownedBy = whoseTurn; newBoard.anotherMove = true; } } } } return newBoard; } // return true if the four walls of the specified box are all filled in private boolean surrounded(int r, int c) { return boxes[r][c].top && boxes[r][c].right && boxes[r][c].bottom && boxes[r][c].left; } public boolean gameIsOver() { for (int r = 0; r