Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Martin Schreiber
COSC220 A2
Commits
204ac68c
Commit
204ac68c
authored
Jul 06, 2021
by
Will Billingsley
Browse files
Basic game works except for deliberately introduced bug
parent
a52252e2
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/main/java/dotsandboxes/DotsAndBoxesGrid.java
View file @
204ac68c
package
dotsandboxes
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Observer
;
import
java.util.function.Consumer
;
/**
* The state of a dots and boxes grid.
...
...
@@ -43,15 +46,60 @@ public class DotsAndBoxesGrid {
/** Which owner (if any) claimed any given box. */
private
int
[][]
boxOwners
;
public
DotsAndBoxesGrid
(
int
width
,
int
height
)
{
/** A list of functions to notify when there is an update */
private
ArrayList
<
Consumer
<
DotsAndBoxesGrid
>>
watchers
=
new
ArrayList
<>();
final
int
players
;
private
int
player
=
1
;
public
int
getPlayer
()
{
return
player
;
}
/** Moves to the next player */
private
void
nextPlayer
()
{
player
++;
if
(
player
>
players
)
{
player
=
1
;
}
}
public
DotsAndBoxesGrid
(
int
width
,
int
height
,
int
players
)
{
this
.
width
=
width
;
this
.
height
=
height
;
this
.
players
=
players
;
this
.
horizontals
=
new
boolean
[
width
-
1
][
height
];
this
.
verticals
=
new
boolean
[
width
][
height
-
1
];
this
.
boxOwners
=
new
int
[
width
-
1
][
height
-
1
];
}
private
void
notifyObservers
()
{
for
(
Consumer
<
DotsAndBoxesGrid
>
consumer
:
watchers
)
{
consumer
.
accept
(
this
);
}
}
/** Listens to this grid for changes */
public
void
addConsumer
(
Consumer
<
DotsAndBoxesGrid
>
consumer
)
{
watchers
.
add
(
consumer
);
}
/** Returns whether a horizontal line has been drawn */
public
boolean
getHorizontal
(
int
x
,
int
y
)
{
return
horizontals
[
x
][
y
];
}
/** Returns whether a vertical line has been drawn */
public
boolean
getVertical
(
int
x
,
int
y
)
{
return
verticals
[
x
][
y
];
}
/** Returns which player owns a box. By convention, 0 is unowned. */
public
int
getBoxOwner
(
int
x
,
int
y
)
{
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
...
...
@@ -59,11 +107,8 @@ public class DotsAndBoxesGrid {
* @return true if all four sides have been drawn.
*/
public
boolean
boxComplete
(
int
x
,
int
y
)
{
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
));
}
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
));
if
(
x
>=
width
-
1
||
x
<
0
||
y
>=
height
-
1
||
y
<
0
)
{
return
false
;
}
// A box is complete if the north and south horizontals and the east and west verticals have all been drawn.
...
...
@@ -71,6 +116,16 @@ public class DotsAndBoxesGrid {
return
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
;
return
true
;
}
else
{
return
false
;
}
}
/**
* "Draws" a horizontal line, from grid point (x, y) to (x + 1, y). (i.e. sets that line to true)
* @param x
...
...
@@ -88,10 +143,16 @@ public class DotsAndBoxesGrid {
// FIXME: You need to throw an exception if the line was already drawn.
this
.
horizontals
[
x
][
y
]
=
true
;
if
(
boxComplete
(
x
,
y
))
{
boxOwners
[
x
][
y
]
=
player
;
// Try to claim the north or south boxes
boolean
claimN
=
claimBox
(
x
,
y
-
1
,
player
);
boolean
claimS
=
claimBox
(
x
,
y
,
player
);
if
(
claimN
||
claimS
)
{
notifyObservers
();
return
true
;
}
else
{
nextPlayer
();
notifyObservers
();
return
false
;
}
}
...
...
@@ -113,12 +174,18 @@ public class DotsAndBoxesGrid {
// You need to throw an exception if the line was already drawn.
this
.
verticals
[
x
][
y
]
=
true
;
if
(
boxComplete
(
x
,
y
))
{
boxOwners
[
x
][
y
]
=
player
;
// Try to claim the north or south boxes
boolean
claimE
=
claimBox
(
x
,
y
,
player
);
boolean
claimW
=
claimBox
(
x
-
1
,
y
,
player
);
if
(
claimE
||
claimW
)
{
notifyObservers
();
return
true
;
}
else
{
nextPlayer
();
notifyObservers
();
return
false
;
}
}
public
boolean
gameComplete
()
{
...
...
src/main/java/dotsandboxes/DotsAndBoxesUI.java
View file @
204ac68c
package
dotsandboxes
;
import
javafx.scene.control.Label
;
import
javafx.scene.layout.AnchorPane
;
import
javafx.scene.paint.Color
;
import
javafx.scene.shape.Circle
;
import
javafx.scene.shape.Line
;
import
javafx.scene.shape.Rectangle
;
public
class
DotsAndBoxesUI
{
...
...
@@ -14,17 +16,48 @@ public class DotsAndBoxesUI {
final
DotsAndBoxesGrid
grid
;
final
AnchorPane
anchorPane
;
final
Label
label
;
public
DotsAndBoxesUI
(
DotsAndBoxesGrid
grid
)
{
/** Colours for the different players. Only goes up to 5. */
final
Color
[]
playerColours
=
{
Color
.
WHITE
,
Color
.
RED
,
Color
.
BLUE
,
Color
.
GREEN
,
Color
.
PURPLE
,
Color
.
ORANGE
};
private
void
updateLabel
()
{
label
.
setTextFill
(
playerColours
[
grid
.
getPlayer
()]);
label
.
setText
(
String
.
format
(
"Player %d's turn"
,
grid
.
getPlayer
()));
}
public
DotsAndBoxesUI
(
final
DotsAndBoxesGrid
grid
)
{
this
.
grid
=
grid
;
anchorPane
=
new
AnchorPane
();
label
=
new
Label
(
""
);
updateLabel
();
grid
.
addConsumer
((
g
)
->
updateLabel
());
// Size the anchorPane to just contain the elements
int
width
=
margin
+
dotDiameter
+
gap
+
(
grid
.
width
-
1
)
*
(
gap
+
lineLength
+
gap
+
dotDiameter
)
+
gap
+
margin
;
int
height
=
margin
+
dotDiameter
+
gap
+
(
grid
.
height
-
1
)
*
(
gap
+
lineLength
+
gap
+
dotDiameter
)
+
gap
+
margin
;
anchorPane
.
setPrefSize
(
width
,
height
);
// Lay out the boxes
for
(
int
row
=
0
;
row
<
grid
.
height
-
1
;
row
++)
{
for
(
int
col
=
0
;
col
<
grid
.
width
-
1
;
col
++)
{
final
int
x
=
col
;
final
int
y
=
row
;
Rectangle
box
=
new
Rectangle
(
gap
,
gap
,
lineLength
,
lineLength
);
box
.
setFill
(
Color
.
WHITE
);
grid
.
addConsumer
((
g
)
->
{
box
.
setFill
(
playerColours
[
g
.
getBoxOwner
(
x
,
y
)]);
});
AnchorPane
.
setLeftAnchor
(
box
,
gap
+
dotDiameter
+
col
*
(
gap
+
lineLength
+
gap
+
dotDiameter
)
+
dotDiameter
/
2.0
);
AnchorPane
.
setTopAnchor
(
box
,
gap
+
dotDiameter
+
row
*
(
gap
+
lineLength
+
gap
+
dotDiameter
)
+
dotDiameter
/
2.0
);
anchorPane
.
getChildren
().
add
(
box
);
}
}
// Lay out the horizontals
for
(
int
row
=
0
;
row
<
grid
.
height
;
row
++)
{
for
(
int
col
=
0
;
col
<
grid
.
width
-
1
;
col
++)
{
...
...
@@ -32,7 +65,21 @@ public class DotsAndBoxesUI {
line
.
setStrokeWidth
(
dotDiameter
);
line
.
setStroke
(
Color
.
DARKGREY
);
line
.
setOnMouseClicked
((
evt
)
->
line
.
setStroke
(
Color
.
RED
));
final
int
x
=
col
;
final
int
y
=
row
;
grid
.
addConsumer
((
g
)
->
{
if
(
g
.
getHorizontal
(
x
,
y
))
{
line
.
setStroke
(
Color
.
BLACK
);
}
else
{
line
.
setStroke
(
Color
.
LIGHTGRAY
);
}
});
line
.
setOnMouseClicked
((
evt
)
->
{
try
{
grid
.
drawHorizontal
(
x
,
y
,
grid
.
getPlayer
());
}
catch
(
IllegalStateException
ex
)
{
// do nothing
}});
AnchorPane
.
setLeftAnchor
(
line
,
0.0
+
gap
+
dotDiameter
+
col
*
(
gap
+
lineLength
+
gap
+
dotDiameter
));
AnchorPane
.
setTopAnchor
(
line
,
-
dotDiameter
/
2.0
+
gap
+
dotDiameter
+
row
*
(
gap
+
lineLength
+
gap
+
dotDiameter
));
...
...
@@ -47,7 +94,21 @@ public class DotsAndBoxesUI {
line
.
setStrokeWidth
(
dotDiameter
);
line
.
setStroke
(
Color
.
DARKGREY
);
line
.
setOnMouseClicked
((
evt
)
->
line
.
setStroke
(
Color
.
RED
));
final
int
x
=
col
;
final
int
y
=
row
;
grid
.
addConsumer
((
g
)
->
{
if
(
g
.
getVertical
(
x
,
y
))
{
line
.
setStroke
(
Color
.
BLACK
);
}
else
{
line
.
setStroke
(
Color
.
LIGHTGRAY
);
}
});
line
.
setOnMouseClicked
((
evt
)
->
{
try
{
grid
.
drawVertical
(
x
,
y
,
grid
.
getPlayer
());
}
catch
(
IllegalStateException
ex
)
{
// do nothing
}});
AnchorPane
.
setTopAnchor
(
line
,
0.0
+
gap
+
dotDiameter
+
row
*
(
gap
+
lineLength
+
gap
+
dotDiameter
));
AnchorPane
.
setLeftAnchor
(
line
,
-
dotDiameter
/
2.0
+
gap
+
dotDiameter
+
col
*
(
gap
+
lineLength
+
gap
+
dotDiameter
));
...
...
@@ -67,8 +128,6 @@ public class DotsAndBoxesUI {
}
}
}
...
...
src/main/java/dotsandboxes/Main.java
View file @
204ac68c
...
...
@@ -9,7 +9,7 @@ import javafx.stage.Stage;
/** Our main class that launches the app. */
public
class
Main
extends
Application
{
DotsAndBoxesGrid
grid
=
new
DotsAndBoxesGrid
(
15
,
8
);
DotsAndBoxesGrid
grid
=
new
DotsAndBoxesGrid
(
15
,
8
,
2
);
@Override
public
void
start
(
Stage
primaryStage
)
throws
Exception
{
...
...
@@ -18,11 +18,12 @@ public class Main extends Application {
Label
label
=
new
Label
(
"My label"
);
BorderPane
borderPane
=
new
BorderPane
();
borderPane
.
set
Top
(
label
);
borderPane
.
set
Bottom
(
label
);
Scene
scene
=
new
Scene
(
borderPane
,
600
,
400
);
DotsAndBoxesUI
dbUi
=
new
DotsAndBoxesUI
(
grid
);
borderPane
.
setCenter
(
dbUi
.
anchorPane
);
borderPane
.
setTop
(
dbUi
.
label
);
primaryStage
.
setScene
(
scene
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment