ajout doc modele
This commit is contained in:
parent
18e84de927
commit
47fe1a7d47
@ -7,30 +7,62 @@ import java.util.HashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GameModel} is a class that represents the state of the game.
|
||||||
|
*
|
||||||
|
* @autor Alexeï Kadir, Lyanis Souidi, Hugo Dimitrijevic
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
public class GameModel {
|
public class GameModel {
|
||||||
|
/**
|
||||||
|
* The {@code Map} of {@code Cell}s to the {@code Set} of {@code Line}s that
|
||||||
|
* intersect them.
|
||||||
|
*/
|
||||||
private final Map<Cell, Set<Line>> cells;
|
private final Map<Cell, Set<Line>> cells;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code Set} of {@code Line}s that have been drawn.
|
||||||
|
*/
|
||||||
private final Set<Line> lines;
|
private final Set<Line> lines;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the initial cross.
|
||||||
|
*/
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the game is in hard mode. In hard mode, {@code Line}s cannot extend
|
||||||
|
* each other.
|
||||||
|
*/
|
||||||
private boolean hardMode;
|
private boolean hardMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of unique valid {@code Line}s that can be drawn.
|
||||||
|
*/
|
||||||
private int validLineCount;
|
private int validLineCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start of the {@code Line} being drawn. If this is {@code null}, no
|
||||||
|
* {@code Line} is
|
||||||
|
* being drawn.
|
||||||
|
*/
|
||||||
private Cell inputLineStart;
|
private Cell inputLineStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The end of the {@code Line} being drawn. If this is {@code null}, no
|
||||||
|
* {@code Line} is
|
||||||
|
* being drawn.
|
||||||
|
*/
|
||||||
private Cell inputLineEnd;
|
private Cell inputLineEnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code GameModel} with the specified size, and whether the
|
||||||
|
* game is in
|
||||||
|
* hard mode.
|
||||||
|
*
|
||||||
|
* @param size The size of the initial cross.
|
||||||
|
* @param hardMode Whether the game is in hard mode.
|
||||||
|
*/
|
||||||
public GameModel(int size, boolean hardMode) {
|
public GameModel(int size, boolean hardMode) {
|
||||||
this.cells = new HashMap<Cell, Set<Line>>();
|
this.cells = new HashMap<Cell, Set<Line>>();
|
||||||
this.lines = new HashSet<Line>();
|
this.lines = new HashSet<Line>();
|
||||||
@ -40,7 +72,14 @@ public class GameModel {
|
|||||||
this.hardMode = hardMode;
|
this.hardMode = hardMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the grid, and initializes a new game with a cross of the specified
|
||||||
|
* size. This call does not recount the number of valid {@code Line}s that can
|
||||||
|
* be
|
||||||
|
* drawn.
|
||||||
|
*
|
||||||
|
* @param size The size of the initial cross.
|
||||||
|
*/
|
||||||
private void resetGrid(int size) {
|
private void resetGrid(int size) {
|
||||||
if ((size + 2) % 3 != 0)
|
if ((size + 2) % 3 != 0)
|
||||||
throw new IllegalArgumentException("Invalid size.");
|
throw new IllegalArgumentException("Invalid size.");
|
||||||
@ -66,7 +105,14 @@ public class GameModel {
|
|||||||
this.fillCells(side * 2 - 2, side * 2 - 2, 1, side);
|
this.fillCells(side * 2 - 2, side * 2 - 2, 1, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recounts the number of valid {@code Line}s that can be drawn. This call
|
||||||
|
* iterates over all
|
||||||
|
* {@code Cell}s in the grid, and finds all unique valid {@code Line}s that
|
||||||
|
* intersect them. This call is expensive, and should be used sparingly. The
|
||||||
|
* line count is updated when lines are added by the user, so this call is only
|
||||||
|
* necessary when the grid is reset.
|
||||||
|
*/
|
||||||
private void recountValidLines() {
|
private void recountValidLines() {
|
||||||
this.validLineCount = 0;
|
this.validLineCount = 0;
|
||||||
|
|
||||||
@ -78,29 +124,55 @@ public class GameModel {
|
|||||||
this.validLineCount = validLines.size();
|
this.validLineCount = validLines.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of unique valid {@code Line}s that can be drawn.
|
||||||
|
*
|
||||||
|
* @return The number of unique valid {@code Line}s that can be drawn.
|
||||||
|
*/
|
||||||
public int getValidLineCount() {
|
public int getValidLineCount() {
|
||||||
return this.validLineCount;
|
return this.validLineCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the game is finished. The game is finished when all valid
|
||||||
|
* {@code Line}s have been drawn.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the game is finished, {@code false} otherwise.
|
||||||
|
*/
|
||||||
public boolean isGameFinished() {
|
public boolean isGameFinished() {
|
||||||
return this.validLineCount == 0;
|
return this.validLineCount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the score of the game. The score is the number of {@code Line}s that
|
||||||
|
* have been drawn.
|
||||||
|
*
|
||||||
|
* @return The score of the game.
|
||||||
|
*/
|
||||||
public int getScore() {
|
public int getScore() {
|
||||||
return this.lines.size();
|
return this.lines.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the grid, and initializes a new game with a cross of the specified
|
||||||
|
* size.
|
||||||
|
*
|
||||||
|
* @param size The size of the initial cross.
|
||||||
|
*/
|
||||||
public void reset(int size) {
|
public void reset(int size) {
|
||||||
this.resetGrid(size);
|
this.resetGrid(size);
|
||||||
|
|
||||||
this.recountValidLines();
|
this.recountValidLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the grid, and initializes a new game with a cross of the specified
|
||||||
|
* size, and the specified set of {@code Line}s. These {@code Line}s are added
|
||||||
|
* without checking for validity.
|
||||||
|
*
|
||||||
|
* @param size The size of the initial cross.
|
||||||
|
* @param lines The set of {@code Line}s to add to the grid.
|
||||||
|
*/
|
||||||
public void reset(int size, Set<Line> lines) {
|
public void reset(int size, Set<Line> lines) {
|
||||||
this.resetGrid(size);
|
this.resetGrid(size);
|
||||||
|
|
||||||
@ -119,12 +191,20 @@ public class GameModel {
|
|||||||
this.recountValidLines();
|
this.recountValidLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the cross.
|
||||||
|
*
|
||||||
|
* @return The size of the cross.
|
||||||
|
*/
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return this.size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of the {@code Set} of {@code Cell}s in the grid.
|
||||||
|
*
|
||||||
|
* @return A copy of the {@code Set} of {@code Cell}s in the grid.
|
||||||
|
*/
|
||||||
public Set<Cell> getCells() {
|
public Set<Cell> getCells() {
|
||||||
Set<Cell> cells = new HashSet<Cell>();
|
Set<Cell> cells = new HashSet<Cell>();
|
||||||
|
|
||||||
@ -134,7 +214,11 @@ public class GameModel {
|
|||||||
return cells;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of the {@code Set} of {@code Line}s that have been drawn.
|
||||||
|
*
|
||||||
|
* @return A copy of the {@code Set} of {@code Line}s that have been drawn.
|
||||||
|
*/
|
||||||
public Set<Line> getLines() {
|
public Set<Line> getLines() {
|
||||||
Set<Line> lines = new HashSet<Line>();
|
Set<Line> lines = new HashSet<Line>();
|
||||||
|
|
||||||
@ -144,13 +228,23 @@ public class GameModel {
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts drawing a {@code Line} at the specified {@code Cell}.
|
||||||
|
*
|
||||||
|
* @param start The {@code Cell} where the {@code Line} starts.
|
||||||
|
*/
|
||||||
public void startInputLine(Cell start) {
|
public void startInputLine(Cell start) {
|
||||||
this.inputLineStart = new Cell(start);
|
this.inputLineStart = new Cell(start);
|
||||||
this.inputLineEnd = new Cell(start);
|
this.inputLineEnd = new Cell(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the end of the {@code Line} being drawn to the specified {@code Cell}.
|
||||||
|
*
|
||||||
|
* @param end The {@code Cell} where the {@code Line} ends.
|
||||||
|
* @return {@code true} if the end of the {@code Line} was moved, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
public boolean moveInputLineEnd(Cell end) {
|
public boolean moveInputLineEnd(Cell end) {
|
||||||
if (this.inputLineStart == null)
|
if (this.inputLineStart == null)
|
||||||
return false;
|
return false;
|
||||||
@ -162,7 +256,15 @@ public class GameModel {
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends drawing a {@code Line} at the specified {@code Cell}. If the
|
||||||
|
* {@code Line}
|
||||||
|
* is valid, it is added to the grid, and the {@code Cell}s it intersects are
|
||||||
|
* updated. If the {@code Line} is not valid, it is discarded. The number of
|
||||||
|
* unique valid {@code Line}s that can be drawn is updated as well.
|
||||||
|
*
|
||||||
|
* @param end The {@code Cell} where the {@code Line} ends.
|
||||||
|
*/
|
||||||
public void endInputLine(Cell end) {
|
public void endInputLine(Cell end) {
|
||||||
if (this.inputLineStart == null)
|
if (this.inputLineStart == null)
|
||||||
return;
|
return;
|
||||||
@ -205,27 +307,54 @@ public class GameModel {
|
|||||||
this.inputLineEnd = null;
|
this.inputLineEnd = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a {@code Line} is being drawn.
|
||||||
|
*
|
||||||
|
* @return {@code true} if a {@code Line} is being drawn, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
public boolean hasInputLine() {
|
public boolean hasInputLine() {
|
||||||
return this.inputLineStart != null;
|
return this.inputLineStart != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the {@code Line} being drawn is valid.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the {@code Line} being drawn is valid, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
public boolean isInputLineValid() {
|
public boolean isInputLineValid() {
|
||||||
return this.isLineValid(this.inputLineStart, this.inputLineEnd);
|
return this.isLineValid(this.inputLineStart, this.inputLineEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code Cell} where the {@code Line} being drawn starts.
|
||||||
|
*
|
||||||
|
* @return The {@code Cell} where the {@code Line} being drawn starts.
|
||||||
|
*/
|
||||||
public Cell getInputLineStart() {
|
public Cell getInputLineStart() {
|
||||||
return new Cell(this.inputLineStart);
|
return new Cell(this.inputLineStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code Cell} where the {@code Line} being drawn ends.
|
||||||
|
*
|
||||||
|
* @return The {@code Cell} where the {@code Line} being drawn ends.
|
||||||
|
*/
|
||||||
public Cell getInputLineEnd() {
|
public Cell getInputLineEnd() {
|
||||||
return new Cell(this.inputLineEnd);
|
return new Cell(this.inputLineEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the {@code Line} between the specified {@code Cell}s is
|
||||||
|
* valid. A {@code Line} is valid if it is horizontal, vertical, or diagonal,
|
||||||
|
* and intersects exactly four {@code Cell}s. In hard mode, {@code Line}s
|
||||||
|
* cannot extend each other.
|
||||||
|
*
|
||||||
|
* @param start The {@code Cell} where the {@code Line} starts.
|
||||||
|
* @param end The {@code Cell} where the {@code Line} ends.
|
||||||
|
* @return {@code true} if the {@code Line} is valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
public boolean isLineValid(Cell start, Cell end) {
|
public boolean isLineValid(Cell start, Cell end) {
|
||||||
if (!Line.isValid(start, end))
|
if (!Line.isValid(start, end))
|
||||||
return false;
|
return false;
|
||||||
@ -266,7 +395,14 @@ public class GameModel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all unique valid {@code Line}s that intersect the specified
|
||||||
|
* {@code Cell},
|
||||||
|
* and adds them to the specified {@code Set}.
|
||||||
|
*
|
||||||
|
* @param cell The {@code Cell} to check for intersections.
|
||||||
|
* @param lines The {@code Set} to add the valid {@code Line}s to.
|
||||||
|
*/
|
||||||
private void findValidLines(Cell cell, Set<Line> lines) {
|
private void findValidLines(Cell cell, Set<Line> lines) {
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
Cell start = new Cell(cell.x - 4 + i, cell.y);
|
Cell start = new Cell(cell.x - 4 + i, cell.y);
|
||||||
@ -295,19 +431,35 @@ public class GameModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the specified rectangle of {@code Cell}s.
|
||||||
|
*
|
||||||
|
* @param x The x-coordinate of the top-left corner of the rectangle.
|
||||||
|
* @param y The y-coordinate of the top-left corner of the rectangle.
|
||||||
|
* @param w The width of the rectangle.
|
||||||
|
* @param h The height of the rectangle.
|
||||||
|
*/
|
||||||
private void fillCells(int x, int y, int w, int h) {
|
private void fillCells(int x, int y, int w, int h) {
|
||||||
for (int dx = 0; dx < w; dx++)
|
for (int dx = 0; dx < w; dx++)
|
||||||
for (int dy = 0; dy < h; dy++)
|
for (int dy = 0; dy < h; dy++)
|
||||||
this.placeCell(x + dx, y + dy);
|
this.placeCell(x + dx, y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places a {@code Cell} in the grid.
|
||||||
|
*
|
||||||
|
* @param x The x-coordinate of the {@code Cell}.
|
||||||
|
* @param y The y-coordinate of the {@code Cell}.
|
||||||
|
*/
|
||||||
private void placeCell(int x, int y) {
|
private void placeCell(int x, int y) {
|
||||||
this.placeCell(new Cell(x, y));
|
this.placeCell(new Cell(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places a {@code Cell} in the grid.
|
||||||
|
*
|
||||||
|
* @param cell The {@code Cell} to place.
|
||||||
|
*/
|
||||||
private void placeCell(Cell cell) {
|
private void placeCell(Cell cell) {
|
||||||
if (this.cells.containsKey(cell))
|
if (this.cells.containsKey(cell))
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user