-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAbstractAnalyze.java
98 lines (77 loc) · 2.52 KB
/
AbstractAnalyze.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package net.zomis.minesweeper.analyze.factory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.zomis.minesweeper.analyze.FieldRule;
import net.zomis.minesweeper.analyze.AnalyzeFactory;
import net.zomis.minesweeper.analyze.detail.NeighborFind;
public abstract class AbstractAnalyze<F> extends AnalyzeFactory<F> implements NeighborFind<F> {
public AbstractAnalyze() {
}
protected abstract List<F> getAllPoints();
protected final void createRules(List<F> points) {
Set<F> knownNonMines = new HashSet<F>();
int remaining = getRemainingMinesCount();
if (remaining != -1) {
this.addRule(new FieldRule<F>(null, getAllUnclickedFields(), remaining));
}
for (F field : points) {
if (!fieldHasRule(field))
continue;
FieldRule<F> newRule = internalRuleFromField(field, knownNonMines);
if (newRule != null) {
this.addRule(newRule);
}
}
if (!knownNonMines.isEmpty())
this.addRule(new FieldRule<F>(null, knownNonMines, 0));
}
/**
* Determines if the specified field is/has a rule that should be added to the constraints
*
* @param field Field that is being checked
* @return True if the field has a rule that should be applied, false otherwise
*/
protected abstract boolean fieldHasRule(F field);
protected abstract int getRemainingMinesCount();
protected abstract List<F> getAllUnclickedFields();
private FieldRule<F> internalRuleFromField(F field, Set<F> knownNonMines) {
List<F> ruleParams = new ArrayList<F>();
int foundNeighbors = 0;
int fieldValue = getFieldValue(field);
for (F neighbor : getNeighbors(field)) {
if (isDiscoveredMine(neighbor))
foundNeighbors++;
else if (!isClicked(neighbor))
ruleParams.add(neighbor);
}
if (fieldValue - foundNeighbors == 0) {
if (knownNonMines != null) {
for (F mf : ruleParams) {
if (!knownNonMines.contains(mf)) {
knownNonMines.add(mf);
}
}
}
return null;
}
else return new FieldRule<F>(field, ruleParams, fieldValue - foundNeighbors);
}
protected abstract boolean isDiscoveredMine(F neighbor);
protected abstract int getFieldValue(F field);
protected abstract List<F> getNeighbors(F field);
protected abstract boolean isClicked(F neighbor);
@Override
public Collection<F> getNeighborsFor(F field) {
return getNeighbors(field);
}
@Override
public boolean isFoundAndisMine(F field) {
return isDiscoveredMine(field);
}
public void createRules() {
createRules(getAllPoints());
}
}