Implemented sequences
This commit is contained in:
parent
0c3623a45e
commit
8f984e653f
|
@ -74,11 +74,14 @@ public class MalteAI implements Player{
|
|||
}
|
||||
|
||||
public double calculateWeight(int[][] board, int column) {
|
||||
double W_START = 1.0;
|
||||
double W_ILLEGAL = -1.0;
|
||||
double W_INSTANT_WIN = 2;
|
||||
double W_PREVENT_INSTANT_WIN = 1.9;
|
||||
double weight = W_START;
|
||||
double W_START = 1.0;
|
||||
double W_ILLEGAL = -1.0;
|
||||
double W_WIN = 1.5;
|
||||
double W_INSTANT_WIN = 5.0;
|
||||
double W_PREVENT_WIN = 1.4;
|
||||
double W_PREVENT_INSTANT_WIN= 2.0;
|
||||
double W_DONT = 0.01;
|
||||
double weight = W_START;
|
||||
// Prever a place in the center;
|
||||
weight *= 1.0 - Math.abs(3.0 - column) / (3.0 * 100.0);
|
||||
// Relative positions like (-1, -1), (0, -1), etc.
|
||||
|
@ -92,65 +95,54 @@ public class MalteAI implements Player{
|
|||
}
|
||||
// Setup Sequences
|
||||
Sequence[] sequences = new Sequence[8];
|
||||
Sequence[] sequencesAbove = new Sequence[8];
|
||||
for (int i = 0; i < sequences.length; i++) {
|
||||
sequences[i] = Sequence.readSequenceFromBoard(board, thisPos, relAround[i]);
|
||||
sequences[i] = Sequence.readSequenceFromBoard(board,
|
||||
thisPos.add(relAround[i]),
|
||||
relAround[i]);
|
||||
sequences[i].setPlayerID(this.id);
|
||||
sequences[i].setEnemyID(this.enemyID);
|
||||
sequencesAbove[i] = Sequence.readSequenceFromBoard(board,
|
||||
thisPos.add(relAround[0]).add(relAround[i]),
|
||||
relAround[i]);
|
||||
sequencesAbove[i].setPlayerID(this.id);
|
||||
sequencesAbove[i].setEnemyID(this.enemyID);
|
||||
}
|
||||
|
||||
// Collect information about our surroundings.
|
||||
for (int i = 0; i < nrs.length; i++) {
|
||||
// The postion around us we're collecting information from.
|
||||
Position curPos = thisPos.add(relAround[i]);
|
||||
// Check whether this position is on the board at all.
|
||||
if (isPosOnBoard(curPos)) {
|
||||
// Get the ID in this position.
|
||||
ids[i] = getIDFromBoard(board, curPos);
|
||||
// Get the number of IDs in this direction.
|
||||
nrs[i] = countIDsInDir(board, ids[i], curPos, relAround[i]);
|
||||
} else {
|
||||
// If not on board, -1 is the way to go.
|
||||
ids[i] = -1;
|
||||
nrs[i] = -1;
|
||||
}
|
||||
}
|
||||
// Look for problems/options in one direction at a time.
|
||||
for (int i = 0; i < nrs.length; i++) {
|
||||
if (nrs[i] == 3) {
|
||||
if (ids[i] == this.id) {
|
||||
// We can win like this!
|
||||
for (int i = 0; i < sequences.length; i++) {
|
||||
Sequence x = sequences[i];
|
||||
if (x.matches("MMM")) {
|
||||
weight *= W_INSTANT_WIN;
|
||||
} else if (x.matches("EEE")) {
|
||||
weight *= W_PREVENT_INSTANT_WIN;
|
||||
} else if (x.matches("EE ")) {
|
||||
weight *= W_PREVENT_WIN;
|
||||
} else if (x.matches("MM ")) {
|
||||
weight *= W_WIN;
|
||||
} else if (i < 4) {
|
||||
Sequence y = sequences[i + 4];
|
||||
if ((x.matches("MM") &&
|
||||
y.matches("M")) ||
|
||||
(x.matches("M") &&
|
||||
y.matches("MM"))) {
|
||||
weight *= W_INSTANT_WIN;
|
||||
} else if (ids[i] == this.enemyID) {
|
||||
// We can at least prevent him from winning.
|
||||
} else if ((x.matches("EE") &&
|
||||
y.matches("E")) ||
|
||||
(x.matches("E") &&
|
||||
y.matches("EE"))) {
|
||||
weight *= W_PREVENT_INSTANT_WIN;
|
||||
} else if ((x.matches("MM ") &&
|
||||
y.matches(" ")) ||
|
||||
(x.matches(" ") &&
|
||||
y.matches("MM "))) {
|
||||
weight *= W_WIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look for problems/options in two directions at a time.
|
||||
for (int i = 0; i < nrs.length / 2; i++) {
|
||||
// Same ID on opposite sides.
|
||||
if (ids[i] == ids[i + 4]) {
|
||||
// Almost a finished row.
|
||||
if (nrs[i] + nrs[i + 4] > 3) {
|
||||
if (ids[i] == this.id) {
|
||||
// Its our ID.
|
||||
weight *= W_INSTANT_WIN;
|
||||
} else if (ids[i] == this.enemyID) {
|
||||
// Its the enemy's ID.
|
||||
weight *= W_PREVENT_INSTANT_WIN;
|
||||
}
|
||||
}
|
||||
// Prevent choosing a bad spot
|
||||
Sequence xA = sequencesAbove[i];
|
||||
if (sequencesAbove[i].matches("EEE")) {
|
||||
weight *= W_DONT;
|
||||
}
|
||||
}
|
||||
// Maybe we get lucky TODO: Expand this.
|
||||
double extraWeight = 0.0;
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
if (ids[i] == this.id) {
|
||||
extraWeight += Math.pow(nrs[i], 2) * 2;
|
||||
} else if (ids[i] == this.enemyID) {
|
||||
extraWeight += Math.pow(nrs[i], 2);
|
||||
}
|
||||
}
|
||||
extraWeight /= 10 * 126;
|
||||
weight *= extraWeight + 1.0;
|
||||
return weight;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class Position {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%d, %d)", posX, posY);
|
||||
return String.format("(%+d, %+d)", posX, posY);
|
||||
}
|
||||
|
||||
public static Position[] getRelCirclePositions() {
|
||||
|
|
|
@ -10,19 +10,48 @@ public class Sequence {
|
|||
private Position startingPos;
|
||||
private Position direction;
|
||||
private List<Integer> ids;
|
||||
private int playerID;
|
||||
private int enemyID;
|
||||
|
||||
public Sequence(List<Integer> ids) {
|
||||
public Sequence(Position startingPos, Position direction, List<Integer> ids) {
|
||||
this.ids = new ArrayList<Integer>(ids);
|
||||
this.startingPos = startingPos;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public void setPlayerID(int playerID) {
|
||||
this.playerID = playerID;
|
||||
}
|
||||
|
||||
public void setEnemyID(int enemyID) {
|
||||
this.enemyID = enemyID;
|
||||
}
|
||||
|
||||
public boolean matches(String s) {
|
||||
String idStr = idString().toLowerCase();
|
||||
s = s.toLowerCase();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (i >= idStr.length()) {
|
||||
return false;
|
||||
}
|
||||
if (s.charAt(i) == 'p' &&
|
||||
idStr.charAt(i) == ' ') {
|
||||
return false;
|
||||
} else if (s.charAt(i) != idStr.charAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Sequence readSequenceFromBoard(int[][] board, Position pos, Position dir) {
|
||||
Position cur = pos;
|
||||
List<Integer> ids = new ArrayList<Integer>();
|
||||
while (isPosOnBoard(cur)) {
|
||||
cur = cur.add(dir);
|
||||
ids.add(getIDFromBoard(board, cur));
|
||||
cur = cur.add(dir);
|
||||
}
|
||||
return new Sequence(ids);
|
||||
return new Sequence(pos, dir, ids);
|
||||
}
|
||||
|
||||
private static boolean isPosOnBoard(Position pos) {
|
||||
|
@ -38,8 +67,22 @@ public class Sequence {
|
|||
return new Integer(board[pos.getPosX()][pos.getPosY()]);
|
||||
}
|
||||
|
||||
public String idString() {
|
||||
String s = "";
|
||||
for (Integer x: ids) {
|
||||
if (x.intValue() == this.playerID) {
|
||||
s += "M";
|
||||
} else if (x.intValue() == this.enemyID) {
|
||||
s += "E";
|
||||
} else {
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("START: %s, DIR: %s, %s", startingPos, direction, ids);
|
||||
return String.format("START: %s, DIR: %s, \"%s\"", startingPos, direction, idString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue