Skip to content

Commit 1b2ba40

Browse files
committed
add some tests
1 parent 320d10e commit 1b2ba40

File tree

5 files changed

+128
-32
lines changed

5 files changed

+128
-32
lines changed

src/main/java/com/bernd/game/PointQueue.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ final class PointQueue {
1010
private final int capacity;
1111
private final int dim;
1212

13+
private boolean empty = true;
1314
private int write;
1415
private int read;
1516
private final int[] buffer;
@@ -24,24 +25,33 @@ private PointQueue(
2425
}
2526

2627
static PointQueue create(int dim) {
27-
// Assumption 1: All algorithms proceed from the starting point outward in a diamond shape.
28-
// Assumption 2: The circumference of the diamond shape is not greater than 2 * dim + 1.
29-
int capacity = 2 * dim + 1;
28+
// Assumption:
29+
// All algorithms proceed from the starting point outward in a diamond shape.
30+
// The diamond contains at most two points per row, see testDiamond().
31+
return byCapacity(dim, 2 * dim);
32+
}
33+
34+
// visible for testing
35+
static PointQueue byCapacity(int dim, int capacity) {
3036
return new PointQueue(capacity, dim, new int[divideUp(capacity, 2)]);
3137
}
3238

3339
void offer(int x, int y) {
40+
if (!empty && write == read) {
41+
throw new RuntimeException("buffer overflow");
42+
}
43+
empty = false;
3444
int ptId = dim * y + x;
3545
set(ptId);
3646
write = (write + 1) % capacity;
37-
if (write == read) {
38-
throw new RuntimeException("buffer overflow");
39-
}
4047
}
4148

4249
int poll() {
4350
int ptId = get();
4451
read = (read + 1) % capacity;
52+
if (read == write) {
53+
empty = true;
54+
}
4555
return ptId;
4656
}
4757

@@ -60,6 +70,10 @@ private void set(int ptId) {
6070
}
6171

6272
boolean isEmpty() {
63-
return write == read;
73+
return empty;
74+
}
75+
76+
int dim() {
77+
return dim;
6478
}
6579
}

src/main/java/com/bernd/game/PointSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ private PointSet(int dim, int[] points) {
1313
}
1414

1515
static PointSet create(int dim) {
16-
return new PointSet(dim, new int[divideUp(dim * dim, 0x11)]);
16+
return new PointSet(dim, new int[divideUp(dim * dim, 0x20)]);
1717
}
1818

1919
void add(int x, int y) {

src/test/java/com/bernd/game/CountTest.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bernd.game;
22

3+
import java.util.concurrent.ThreadLocalRandom;
34
import org.junit.jupiter.api.Test;
45

56
import static com.bernd.game.Board.B;
@@ -160,15 +161,24 @@ void testCountLargeArea() {
160161

161162
@Test
162163
void testNoBufferOverflow() {
163-
// fails if the assumption in PointQueue is incorrect
164+
// fails if the capacity assumption in PointQueue is wrong
164165
for (int dim = 1; dim < 40; dim++) {
165-
int[][] board = createEmptyBoard(dim);
166-
int result = Count.getImpliedColor(board, dim / 2, dim / 2);
167-
assertEquals(0, result);
166+
assertEquals(0, Count.getImpliedColor(
167+
createEmptyBoard(dim),
168+
dim / 2,
169+
dim / 2));
170+
assertEquals(0, Count.getImpliedColor(
171+
createEmptyBoard(dim),
172+
0,
173+
0));
174+
assertEquals(0, Count.getImpliedColor(
175+
createEmptyBoard(dim),
176+
ThreadLocalRandom.current().nextInt(dim),
177+
ThreadLocalRandom.current().nextInt(dim)));
168178
}
169179
}
170180

171-
private static int[][] createEmptyBoard(int dim) {
181+
static int[][] createEmptyBoard(int dim) {
172182
int[][] board = new int[dim][];
173183
for (int i = 0; i < board.length; i++) {
174184
board[i] = new int[dim];
Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,97 @@
11
package com.bernd.game;
22

3+
import com.bernd.util.Util;
34
import org.junit.jupiter.api.Test;
45

6+
import static com.bernd.game.CountTest.createEmptyBoard;
7+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
58
import static org.junit.jupiter.api.Assertions.assertEquals;
69
import static org.junit.jupiter.api.Assertions.assertFalse;
10+
import static org.junit.jupiter.api.Assertions.assertThrows;
711
import static org.junit.jupiter.api.Assertions.assertTrue;
812

913
class PointQueueTest {
1014

1115
@Test
12-
void testOffer() {
16+
void testOfferAndPoll() {
1317
int dim = 4;
1418
PointQueue queue = PointQueue.create(dim);
15-
assertTrue(queue.isEmpty());
1619
queue.offer(0, 1);
1720
queue.offer(1, 2);
18-
int pid = queue.poll();
19-
assertFalse(queue.isEmpty());
20-
int x = pid % dim;
21-
int y = pid / dim;
22-
assertEquals(0, x);
23-
assertEquals(1, y);
21+
poll(queue, 0, 1);
2422
queue.offer(2, 3);
25-
pid = queue.poll();
26-
assertFalse(queue.isEmpty());
27-
x = pid % dim;
28-
y = pid / dim;
29-
assertEquals(1, x);
30-
assertEquals(2, y);
31-
pid = queue.poll();
32-
x = pid % dim;
33-
y = pid / dim;
34-
assertEquals(2, x);
35-
assertEquals(3, y);
23+
poll(queue, 1, 2);
24+
poll(queue, 2, 3);
3625
assertTrue(queue.isEmpty());
3726
}
27+
28+
@Test
29+
void testFullCapacity() {
30+
PointQueue queue = PointQueue.byCapacity(2, 4);
31+
queue.offer(0, 0);
32+
queue.offer(0, 1);
33+
queue.offer(1, 0);
34+
queue.offer(1, 1);
35+
poll(queue, 0, 0);
36+
poll(queue, 0, 1);
37+
poll(queue, 1, 0);
38+
poll(queue, 1, 1);
39+
assertTrue(queue.isEmpty());
40+
}
41+
42+
@Test
43+
void testCapacityExceeded() {
44+
PointQueue queue = PointQueue.byCapacity(2, 3);
45+
queue.offer(0, 0);
46+
queue.offer(0, 1);
47+
queue.offer(1, 0);
48+
assertThrows(RuntimeException.class, () -> queue.offer(1, 1));
49+
}
50+
51+
@Test
52+
void testDiamond() {
53+
int dim = 5;
54+
int[][] board = createEmptyBoard(dim);
55+
PointQueue pointsToCheck = PointQueue.create(dim);
56+
pointsToCheck.offer(2, 2);
57+
for (int i = 0; i < 9; i++) {
58+
int ptId = pointsToCheck.poll();
59+
int y = ptId / dim;
60+
int x = ptId % dim;
61+
board[y][x] = 2;
62+
if (y > 0 && board[y - 1][x] == 0) {
63+
board[y - 1][x] = 1;
64+
pointsToCheck.offer(x, y - 1);
65+
}
66+
if (y < dim - 1 && board[y + 1][x] == 0) {
67+
board[y + 1][x] = 1;
68+
pointsToCheck.offer(x, y + 1);
69+
}
70+
if (x > 0 && board[y][x - 1] == 0) {
71+
board[y][x - 1] = 1;
72+
pointsToCheck.offer(x - 1, y);
73+
}
74+
if (x < dim - 1 && board[y][x + 1] == 0) {
75+
board[y][x + 1] = 1;
76+
pointsToCheck.offer(x + 1, y);
77+
}
78+
}
79+
// After 9 iterations, the diamond contains exactly two points per row.
80+
assertArrayEquals(new int[][]{
81+
new int[]{0, 1, 2, 1, 0},
82+
new int[]{1, 2, 2, 2, 1},
83+
new int[]{1, 2, 2, 2, 1},
84+
new int[]{0, 1, 2, 1, 0},
85+
new int[]{0, 1, 2, 1, 0},
86+
}, board, () -> Util.boardToString(board));
87+
}
88+
89+
private void poll(PointQueue queue, int expect_x, int expect_y) {
90+
assertFalse(queue.isEmpty());
91+
int ptId = queue.poll();
92+
int x = ptId % queue.dim();
93+
int y = ptId / queue.dim();
94+
assertEquals(expect_x, x);
95+
assertEquals(expect_y, y);
96+
}
3897
}

src/test/java/com/bernd/game/PointSetTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,17 @@ void testBig() {
2828
assertFalse(pointSet.has(10, 11));
2929
assertFalse(pointSet.has(11, 10));
3030
}
31+
32+
@Test
33+
void testFullCapacity() {
34+
int dim = 64;
35+
PointSet pointSet = PointSet.create(dim);
36+
for (int x = 0; x < dim; x++) {
37+
for (int y = 0; y < dim; y++) {
38+
assertFalse(pointSet.has(x, y));
39+
pointSet.add(x, y);
40+
assertTrue(pointSet.has(x, y));
41+
}
42+
}
43+
}
3144
}

0 commit comments

Comments
 (0)