Ajout du modèle
This commit is contained in:
parent
9859945768
commit
18e84de927
317
app/src/main/java/fr/iutfbleau/sae/GameModel.java
Normal file
317
app/src/main/java/fr/iutfbleau/sae/GameModel.java
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
package fr.iutfbleau.sae;
|
||||||
|
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
public class GameModel {
|
||||||
|
|
||||||
|
private final Map<Cell, Set<Line>> cells;
|
||||||
|
|
||||||
|
|
||||||
|
private final Set<Line> lines;
|
||||||
|
|
||||||
|
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
|
||||||
|
private boolean hardMode;
|
||||||
|
|
||||||
|
|
||||||
|
private int validLineCount;
|
||||||
|
|
||||||
|
|
||||||
|
private Cell inputLineStart;
|
||||||
|
|
||||||
|
|
||||||
|
private Cell inputLineEnd;
|
||||||
|
|
||||||
|
|
||||||
|
public GameModel(int size, boolean hardMode) {
|
||||||
|
this.cells = new HashMap<Cell, Set<Line>>();
|
||||||
|
this.lines = new HashSet<Line>();
|
||||||
|
|
||||||
|
this.reset(size);
|
||||||
|
|
||||||
|
this.hardMode = hardMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void resetGrid(int size) {
|
||||||
|
if ((size + 2) % 3 != 0)
|
||||||
|
throw new IllegalArgumentException("Invalid size.");
|
||||||
|
|
||||||
|
this.size = size;
|
||||||
|
|
||||||
|
this.cells.clear();
|
||||||
|
this.lines.clear();
|
||||||
|
|
||||||
|
int side = (this.size + 2) / 3;
|
||||||
|
|
||||||
|
this.fillCells(0, side - 1, side, 1);
|
||||||
|
this.fillCells(0, side - 1, 1, side);
|
||||||
|
this.fillCells(side - 1, 0, side, 1);
|
||||||
|
this.fillCells(side - 1, 0, 1, side);
|
||||||
|
this.fillCells(side * 2 - 2, 0, 1, side);
|
||||||
|
this.fillCells(side * 2 - 2, side - 1, side, 1);
|
||||||
|
this.fillCells(0, side * 2 - 2, side, 1);
|
||||||
|
this.fillCells(side * 3 - 3, side - 1, 1, side);
|
||||||
|
this.fillCells(side - 1, side * 3 - 3, side, 1);
|
||||||
|
this.fillCells(side - 1, side * 2 - 2, 1, side);
|
||||||
|
this.fillCells(side * 2 - 2, side * 2 - 2, side, 1);
|
||||||
|
this.fillCells(side * 2 - 2, side * 2 - 2, 1, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void recountValidLines() {
|
||||||
|
this.validLineCount = 0;
|
||||||
|
|
||||||
|
Set<Line> validLines = new HashSet<Line>();
|
||||||
|
|
||||||
|
for (Cell cell : this.cells.keySet())
|
||||||
|
this.findValidLines(cell, validLines);
|
||||||
|
|
||||||
|
this.validLineCount = validLines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getValidLineCount() {
|
||||||
|
return this.validLineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isGameFinished() {
|
||||||
|
return this.validLineCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getScore() {
|
||||||
|
return this.lines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void reset(int size) {
|
||||||
|
this.resetGrid(size);
|
||||||
|
|
||||||
|
this.recountValidLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void reset(int size, Set<Line> lines) {
|
||||||
|
this.resetGrid(size);
|
||||||
|
|
||||||
|
for (Line line : lines) {
|
||||||
|
for (Cell cell : line) {
|
||||||
|
this.placeCell(cell);
|
||||||
|
|
||||||
|
Set<Line> hits = this.cells.get(cell);
|
||||||
|
if (hits != null)
|
||||||
|
hits.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lines.add(new Line(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.recountValidLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<Cell> getCells() {
|
||||||
|
Set<Cell> cells = new HashSet<Cell>();
|
||||||
|
|
||||||
|
for (Cell cell : this.cells.keySet())
|
||||||
|
cells.add(new Cell(cell));
|
||||||
|
|
||||||
|
return cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<Line> getLines() {
|
||||||
|
Set<Line> lines = new HashSet<Line>();
|
||||||
|
|
||||||
|
for (Line line : this.lines)
|
||||||
|
lines.add(new Line(line));
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void startInputLine(Cell start) {
|
||||||
|
this.inputLineStart = new Cell(start);
|
||||||
|
this.inputLineEnd = new Cell(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean moveInputLineEnd(Cell end) {
|
||||||
|
if (this.inputLineStart == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean changed = !this.inputLineEnd.equals(end);
|
||||||
|
|
||||||
|
this.inputLineEnd = new Cell(end);
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void endInputLine(Cell end) {
|
||||||
|
if (this.inputLineStart == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.inputLineEnd = new Cell(end);
|
||||||
|
|
||||||
|
if (!this.isLineValid(this.inputLineStart, this.inputLineEnd)) {
|
||||||
|
this.inputLineStart = null;
|
||||||
|
this.inputLineEnd = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Line line = new Line(this.inputLineStart, this.inputLineEnd);
|
||||||
|
|
||||||
|
Set<Line> validLines = new HashSet<Line>();
|
||||||
|
for (Cell cell : line)
|
||||||
|
this.findValidLines(cell, validLines);
|
||||||
|
|
||||||
|
int startValidLineCount = validLines.size();
|
||||||
|
|
||||||
|
for (Cell cell : line) {
|
||||||
|
this.placeCell(cell);
|
||||||
|
|
||||||
|
Set<Line> hits = this.cells.get(cell);
|
||||||
|
if (hits != null)
|
||||||
|
hits.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lines.add(line);
|
||||||
|
|
||||||
|
validLines.clear();
|
||||||
|
for (Cell cell : line)
|
||||||
|
this.findValidLines(cell, validLines);
|
||||||
|
|
||||||
|
int endValidLineCount = validLines.size();
|
||||||
|
|
||||||
|
this.validLineCount += endValidLineCount - startValidLineCount;
|
||||||
|
|
||||||
|
this.inputLineStart = null;
|
||||||
|
this.inputLineEnd = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean hasInputLine() {
|
||||||
|
return this.inputLineStart != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isInputLineValid() {
|
||||||
|
return this.isLineValid(this.inputLineStart, this.inputLineEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Cell getInputLineStart() {
|
||||||
|
return new Cell(this.inputLineStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Cell getInputLineEnd() {
|
||||||
|
return new Cell(this.inputLineEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isLineValid(Cell start, Cell end) {
|
||||||
|
if (!Line.isValid(start, end))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Line line = new Line(start, end);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (Cell cell : line)
|
||||||
|
if (this.cells.containsKey(cell))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Set<Line> intersections = new HashSet<Line>();
|
||||||
|
|
||||||
|
for (Cell cell : line) {
|
||||||
|
Set<Line> lines = this.cells.get(cell);
|
||||||
|
|
||||||
|
if (lines == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (Line hit : lines)
|
||||||
|
if (intersections.contains(hit))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
intersections.addAll(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hardMode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (Line intersection : intersections)
|
||||||
|
if (intersection.extendsLine(line))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void findValidLines(Cell cell, Set<Line> lines) {
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
Cell start = new Cell(cell.x - 4 + i, cell.y);
|
||||||
|
Cell end = new Cell(cell.x + i, cell.y);
|
||||||
|
|
||||||
|
if (this.isLineValid(start, end))
|
||||||
|
lines.add(new Line(start, end));
|
||||||
|
|
||||||
|
start = new Cell(cell.x - 4 + i, cell.y - 4 + i);
|
||||||
|
end = new Cell(cell.x + i, cell.y + i);
|
||||||
|
|
||||||
|
if (this.isLineValid(start, end))
|
||||||
|
lines.add(new Line(start, end));
|
||||||
|
|
||||||
|
start = new Cell(cell.x - 4 + i, cell.y + 4 - i);
|
||||||
|
end = new Cell(cell.x + i, cell.y - i);
|
||||||
|
|
||||||
|
if (this.isLineValid(start, end))
|
||||||
|
lines.add(new Line(start, end));
|
||||||
|
|
||||||
|
start = new Cell(cell.x, cell.y - 4 + i);
|
||||||
|
end = new Cell(cell.x, cell.y + i);
|
||||||
|
|
||||||
|
if (this.isLineValid(start, end))
|
||||||
|
lines.add(new Line(start, end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void fillCells(int x, int y, int w, int h) {
|
||||||
|
for (int dx = 0; dx < w; dx++)
|
||||||
|
for (int dy = 0; dy < h; dy++)
|
||||||
|
this.placeCell(x + dx, y + dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void placeCell(int x, int y) {
|
||||||
|
this.placeCell(new Cell(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void placeCell(Cell cell) {
|
||||||
|
if (this.cells.containsKey(cell))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.cells.put(cell, new HashSet<Line>());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user