Ajout du modèle

This commit is contained in:
Lyanis SOUIDI 2024-04-03 16:49:11 +02:00
parent 9859945768
commit 18e84de927

View 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>());
}
}