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