Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • abhatta5/ab-2
1 result
Select Git revision
Show changes
Commits on Source (3)
package dotsandboxes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Consumer;
......@@ -25,11 +24,13 @@ import java.util.function.Consumer;
* - for each column, there are as many horizontals as there are corner dots.
* - for each column, there is one less box than the number of corner dots
*
* For example, in this (4, 3) grid, there are (3, 3) horizontal lines, and (4, 2) vertical lines, and (3, 2) boxes.
* For example, in this (4, 3) grid, there are (3, 3) horizontal lines, and (4,
* 2) vertical lines, and (3, 2) boxes.
*
* We number all lines and boxes by their top-left coordinate.
*
* In Java 14+, we might use a Record class for this, but we're using 11+ as an LTS version, so we don't have that yet.
* In Java 14+, we might use a Record class for this, but we're using 11+ as an
* LTS version, so we don't have that yet.
*/
public class DotsAndBoxesGrid {
......@@ -50,6 +51,7 @@ public class DotsAndBoxesGrid {
final int players;
private int player = 1;
public int getPlayer() {
return player;
}
......@@ -98,9 +100,9 @@ public class DotsAndBoxesGrid {
return boxOwners[x][y];
}
/**
* Checks whether a box has been fully drawn (all four sides)
*
* @param x coordinate of the left side of the box
* @param y coordinate of the top of the box
* @return true if all four sides have been drawn.
......@@ -110,12 +112,19 @@ public class DotsAndBoxesGrid {
return false;
}
// A box is complete if the north and south horizontals and the east and west verticals have all been drawn.
// FIXME: You'll need to fix this code (after writing a test first).
// A box is complete if the north and south horizontals and the east and west
// verticals have all been drawn.
if (horizontals[x][y] && horizontals[x + 1][y] && verticals[x][y] && verticals[x][y + 1])
return true;
return false;
}
/** Tries to claim a box for a player. If the box is complete, sets the ownership and returns true. */
/**
* Tries to claim a box for a player. If the box is complete, sets the ownership
* and returns true.
*/
private boolean claimBox(int x, int y, int p) {
if (boxComplete(x, y)) {
boxOwners[x][y] = player;
......@@ -126,20 +135,27 @@ public class DotsAndBoxesGrid {
}
/**
* "Draws" a horizontal line, from grid point (x, y) to (x + 1, y). (i.e. sets that line to true)
* "Draws" a horizontal line, from grid point (x, y) to (x + 1, y). (i.e. sets
* that line to true)
*
* @param x
* @param y
* @return true if it completes a box
*/
public boolean drawHorizontal(int x, int y, int player) {
if (x >= width - 1 || x < 0) {
throw new IndexOutOfBoundsException(String.format("x was %d, which is out of range. Range is 0 to %d", x, width - 1));
throw new IndexOutOfBoundsException(
String.format("x was %d, which is out of range. Range is 0 to %d", x, width - 1));
}
if (y >= height || y < 0) {
throw new IndexOutOfBoundsException(String.format("y was %d, which is out of range. Range is 0 to %d", y, height));
throw new IndexOutOfBoundsException(
String.format("y was %d, which is out of range. Range is 0 to %d", y, height));
}
// FIXME: You need to throw an exception if the line was already drawn.
if (horizontals[x][y] == true) {
throw new IllegalStateException(
String.format("x was at %d and y was %d, Horizontal line already drawn", x, y));
}
this.horizontals[x][y] = true;
......@@ -157,20 +173,27 @@ public class DotsAndBoxesGrid {
}
/**
* "Draws" a vertical line, from grid point (x, y) to (x, y + 1). (i.e. sets that line to true)
* "Draws" a vertical line, from grid point (x, y) to (x, y + 1). (i.e. sets
* that line to true)
*
* @param x
* @param y
* @return true if it completes a box
*/
public boolean drawVertical(int x, int y, int player) {
if (x >= width || x < 0) {
throw new IndexOutOfBoundsException(String.format("x was %d, which is out of range. Range is 0 to %d", x, width));
throw new IndexOutOfBoundsException(
String.format("x was %d, which is out of range. Range is 0 to %d", x, width));
}
if (y >= height - 1 || y < 0) {
throw new IndexOutOfBoundsException(String.format("y was %d, which is out of range. Range is 0 to %d", y, height - 1));
throw new IndexOutOfBoundsException(
String.format("y was %d, which is out of range. Range is 0 to %d", y, height - 1));
}
// You need to throw an exception if the line was already drawn.
if (verticals[x][y] == true) {
throw new IllegalStateException(
String.format("x was at %d and y was %d, Vertical line already drawn", x, y));
}
this.verticals[x][y] = true;
// Try to claim the north or south boxes
......@@ -188,10 +211,11 @@ public class DotsAndBoxesGrid {
}
public boolean gameComplete() {
// Students who took COSC250 might recognise this style of code. This is Java's version of higher order functions.
// The grid is complete if "for all rows, all the boxes in that row have a non-zero owner"
// Students who took COSC250 might recognise this style of code. This is Java's
// version of higher order functions.
// The grid is complete if "for all rows, all the boxes in that row have a
// non-zero owner"
return Arrays.stream(boxOwners).allMatch((row) -> Arrays.stream(row).allMatch((owner) -> owner > 0));
}
}
......@@ -9,14 +9,17 @@ import org.apache.logging.log4j.Logger;
public class DotsAndBoxesGridTest {
/*
* Because Test classes are classes, they can have fields, and can have static fields.
* This field is a logger. Loggers are like a more advanced println, for writing messages out to the console or a log file.
* Because Test classes are classes, they can have fields, and can have static
* fields.
* This field is a logger. Loggers are like a more advanced println, for writing
* messages out to the console or a log file.
*/
private static final Logger logger = LogManager.getLogger(DotsAndBoxesGridTest.class);
/*
* Tests are functions that have an @Test annotation before them.
* The typical format of a test is that it contains some code that does something, and then one
* The typical format of a test is that it contains some code that does
* something, and then one
* or more assertions to check that a condition holds.
*
* This is a dummy test just to show that the test suite itself runs
......@@ -27,5 +30,44 @@ public class DotsAndBoxesGridTest {
assertTrue(true);
}
// FIXME: You need to write tests for the two known bugs in the code.
@Test
public void testBoxIsIncomplete() {
DotsAndBoxesGrid grid = new DotsAndBoxesGrid(4, 4, 2);
int x = 0, y = 0, player = 1;
grid.drawHorizontal(x, y, player);
grid.drawHorizontal(x + 1, y, player);
grid.drawVertical(x, y, player);
assertFalse(grid.boxComplete(x, y), "Box not fully drawn!");
}
@Test
public void testForAlreadyDrawnHorizontalLine() {
DotsAndBoxesGrid grid = new DotsAndBoxesGrid(4, 5, 2);
int x = 0, y = 0, player = 1;
grid.drawHorizontal(x, y, player);
grid.drawHorizontal(x + 1, y, player);
grid.drawVertical(x, y, player);
assertThrows(IllegalStateException.class, () -> {
grid.drawHorizontal(x, y, player);
});
}
@Test
public void testForAlreadyDrawnVerticalLine() {
DotsAndBoxesGrid grid = new DotsAndBoxesGrid(4, 5, 2);
int x = 0, y = 0, player = 1;
grid.drawHorizontal(x, y, player);
grid.drawHorizontal(x + 1, y, player);
grid.drawVertical(x, y, player);
assertThrows(IllegalStateException.class, () -> {
grid.drawVertical(x, y, player);
});
}
}
\ No newline at end of file