Compare commits
51 commits
malte-alte
...
master
Author | SHA1 | Date | |
---|---|---|---|
937ba9663d | |||
b60a9b4d06 | |||
f2fd55ec47 | |||
87725b969b | |||
afddc1ba6e | |||
352f991005 | |||
f2359321cc | |||
Malte Tammena | 4cb2eecac4 | ||
74320a091a | |||
b717ba4e24 | |||
37d9f8da73 | |||
5605076dbf | |||
21f73d6694 | |||
Malte Tammena | 5496b0d40b | ||
047ec9b728 | |||
b543da5964 | |||
d9d4f50e74 | |||
281b7ce321 | |||
fa8ce856f1 | |||
ea340e5cda | |||
466c41737e | |||
ff624e3bff | |||
101ef5bd89 | |||
dd68bbf6c7 | |||
8bc4af7d8a | |||
d52b8c60a9 | |||
1cb455100d | |||
b6214bd9e1 | |||
eef311480f | |||
96758d864d | |||
6a93dd4a05 | |||
a3d7f190d0 | |||
f7576ebfe6 | |||
479cd7f975 | |||
6f55dde659 | |||
62f6466370 | |||
a4110b96a2 | |||
dc1e45fe0c | |||
1d87754f53 | |||
2e9347cfb3 | |||
9769fc0c6d | |||
b0ed66a786 | |||
318792c9b0 | |||
499859fd53 | |||
51a783eb4b | |||
dee946cb5a | |||
54afd84fe1 | |||
158b5735f2 | |||
b5dc4406fa | |||
cff6eb441e | |||
367edd393b |
9
Makefile
9
Makefile
|
@ -9,7 +9,7 @@ JAVADOC_OPTIONS=-Xdoclint:all -private -encoding UTF-8 -charset UTF-8 -docencodi
|
|||
BUILDS=builds
|
||||
DOC=doc
|
||||
CLASSPATH=src
|
||||
LIBARIES=\
|
||||
LIBRARIES=\
|
||||
lib/jansi-1.16.jar
|
||||
CLASSES=\
|
||||
src/game/Main.java \
|
||||
|
@ -22,6 +22,7 @@ src/player/Human.java \
|
|||
src/player/malte/MalteAI.java \
|
||||
src/player/malte/Position.java \
|
||||
src/player/malte/Sequence.java \
|
||||
src/player/malte/Item.java \
|
||||
src/player/maurizio/MaurizioAI.java
|
||||
|
||||
OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class)
|
||||
|
@ -36,13 +37,13 @@ P2=
|
|||
|
||||
|
||||
all: $(CLASSES) $(FXMLS_BUILD)
|
||||
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(BUILDS)
|
||||
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBRARIES) $(CLASSES) -d $(BUILDS)
|
||||
|
||||
run: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) $(P1) $(P2)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBRARIES) $(MAIN) $(P1) $(P2)
|
||||
|
||||
simulate: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) $(N)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBRARIES) $(MAIN) $(N)
|
||||
|
||||
doc: $(CLASSES)
|
||||
$(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(DOC)
|
||||
|
|
55
makeWindows
Normal file
55
makeWindows
Normal file
|
@ -0,0 +1,55 @@
|
|||
JAVA=java
|
||||
JAVAC=javac
|
||||
JAVADOC=javadoc
|
||||
JAR=jar
|
||||
|
||||
JAVAC_OPTIONS=-Xlint:all
|
||||
JAVADOC_OPTIONS=-Xdoclint:all -private -encoding UTF-8 -charset UTF-8 -docencoding UTF-8
|
||||
|
||||
BUILDS=builds
|
||||
DOC=doc
|
||||
CLASSPATH=src
|
||||
LIBRARIES=\
|
||||
lib/jansi-1.16.jar
|
||||
CLASSES=\
|
||||
src/game/Main.java \
|
||||
src/game/Game.java \
|
||||
src/game/GameHistory.java \
|
||||
src/game/GameEntry.java \
|
||||
src/game/PlayerObject.java \
|
||||
src/player/Player.java \
|
||||
src/player/Human.java \
|
||||
src/player/malte/MalteAI.java \
|
||||
src/player/malte/Position.java \
|
||||
src/player/malte/Sequence.java \
|
||||
src/player/malte/Item.java \
|
||||
src/player/maurizio/MaurizioAI.java
|
||||
|
||||
OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class)
|
||||
|
||||
BUILDFILES=$(OBJECTS) $(FXMLS_BUILD)
|
||||
|
||||
MAIN=game.Main
|
||||
|
||||
N=100
|
||||
P1=
|
||||
P2=
|
||||
|
||||
|
||||
all: $(CLASSES) $(FXMLS_BUILD)
|
||||
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH);$(LIBRARIES) $(CLASSES) -d $(BUILDS)
|
||||
|
||||
run: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS);$(LIBRARIES) $(MAIN) $(P1) $(P2)
|
||||
|
||||
simulate: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS);$(LIBRARIES) $(MAIN) $(N)
|
||||
|
||||
doc: $(CLASSES)
|
||||
$(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH);$(LIBARIES) $(CLASSES) -d $(DOC)
|
||||
|
||||
jar: all
|
||||
$(JAR) -cfe VierGewinnt.jar $(MAIN) -C $(BUILDS) .
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDS)\* $(DOC)\* VierGewinnt.jar
|
|
@ -154,13 +154,13 @@ public class Game {
|
|||
if(output){
|
||||
System.out.println(other(currentP).getP().getName() + " wins.");
|
||||
}
|
||||
return other(currentP).getID(); // TODO this only works if the players hav IDs 1 and 2
|
||||
return other(currentP).getID(); // TODO only works if the players have IDs 1 and 2
|
||||
}
|
||||
}
|
||||
// Uninstall Jansi
|
||||
AnsiConsole.systemUninstall();
|
||||
System.out.println("BUG!");
|
||||
return checkState(false); // this is impossible to reach this, but it makes the compiler happy ;)
|
||||
return checkState(false); // can't be reached
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ public class MalteAI implements Player{
|
|||
@Override
|
||||
public void setPlayerID(int id) {
|
||||
this.id = id;
|
||||
this.enemyID = id == 1 ? 2: 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,6 +65,7 @@ public class MalteAI implements Player{
|
|||
for (double d: weights) {
|
||||
max = max > d ? max: d;
|
||||
}
|
||||
System.out.println(Arrays.toString(weights));
|
||||
for (int i = 0; i < weights.length; i++) {
|
||||
if (Math.abs(max - weights[i]) < 0.000001) {
|
||||
return i;
|
||||
|
|
|
@ -2,6 +2,8 @@ package player.maurizio;
|
|||
|
||||
import java.util.Random;
|
||||
import game.Game;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import player.Player;
|
||||
|
||||
|
@ -27,28 +29,110 @@ public class MaurizioAI implements Player {
|
|||
|
||||
public int move(int[][] board){
|
||||
// check for one move wins
|
||||
int m1 = winningMove(board, id);
|
||||
if(m1 != -1){
|
||||
return m1;
|
||||
}
|
||||
|
||||
// create a list of all legal moves
|
||||
LinkedList<Integer> moves1 = new LinkedList<Integer>();
|
||||
for(int i=0;i<Game.GAME_COLUMNS;i++){
|
||||
if(board[i][0] == 0){
|
||||
moves1.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
// filter out loosing moves
|
||||
for(int i=0;i<Game.GAME_COLUMNS;i++){
|
||||
if(board[i][0] == 0){
|
||||
int[][] boardNew = makeMove(board, i, id);
|
||||
int m2 = winningMove(boardNew, enemyID);
|
||||
if(m2 != -1){
|
||||
moves1.remove((Object) i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//move randomly if instant defeat is inevitable
|
||||
if(moves1.isEmpty()){
|
||||
return moveRandom(board);
|
||||
}
|
||||
|
||||
//forced move
|
||||
if(moves1.size() == 1){
|
||||
return moves1.peek();
|
||||
}
|
||||
|
||||
//look for two move wins among the non-loosing moves
|
||||
int m2 = winningMove2(board, id, moves1);
|
||||
if(m2 != -1){
|
||||
return m2;
|
||||
}
|
||||
|
||||
//copy moves
|
||||
LinkedList<Integer> moves2 = new LinkedList<Integer>();
|
||||
for(int i : moves1){
|
||||
moves2.add(i);
|
||||
}
|
||||
// avoid 2-move losses
|
||||
for(int i : moves1){ // I make a move
|
||||
int[][] board1 = makeMove(board, i, id);
|
||||
int m3 = winningMove2(board1, enemyID, allMoves());
|
||||
if(m3 != -1){
|
||||
moves2.remove((Object) i);
|
||||
}
|
||||
}
|
||||
|
||||
if(!moves2.isEmpty()){
|
||||
return moveCentral(board, moves2);
|
||||
} else {
|
||||
if(!moves1.isEmpty()){
|
||||
return moveCentral(board, moves1);
|
||||
}
|
||||
}
|
||||
|
||||
return moveCentral(board); // can't be reached
|
||||
}
|
||||
|
||||
private int winningMove(int [][] board, int id){
|
||||
for(int i=0;i<Game.GAME_COLUMNS;i++){
|
||||
if(board[i][0] == 0 && checkWin(board, i, id)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//if no wins were found try avoiding losing on the next move
|
||||
// for(int i=0;i<Game.GAME_COLUMNS;i++){
|
||||
// boolean loser = false;
|
||||
// if(board[i][0] == 0){
|
||||
// int[][] boardNew = makeMove(board, i, id);
|
||||
// for(int j=0;j<Game.GAME_COLUMNS;j++){
|
||||
// if(boardNew[j][0] != 0 && checkWin(boardNew, j, 1)){
|
||||
// loser = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(!loser){
|
||||
// return i;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return moveRandom(board);
|
||||
return -1;// signals that no winning move exists
|
||||
}
|
||||
|
||||
private LinkedList<Integer> allMoves(){
|
||||
LinkedList<Integer> ret = new LinkedList<Integer>();
|
||||
for(int i=0;i<Game.GAME_COLUMNS;i++){
|
||||
ret.add(i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int winningMove2(int[][] board, int id, LinkedList<Integer> moves){
|
||||
for(int i : moves){
|
||||
if(board[i][0] != 0){
|
||||
continue;
|
||||
}
|
||||
int[][] boardNew = makeMove(board, i, id);
|
||||
boolean winner1 = true;
|
||||
for(int j=0;j<Game.GAME_COLUMNS;j++){
|
||||
if(boardNew[j][0] == 0){
|
||||
int[][] boardNewNew = makeMove(boardNew, j, enemyID);
|
||||
int m3 = winningMove(boardNewNew, id);
|
||||
if(m3 == -1){
|
||||
winner1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(winner1){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1; // no move found that wins in 2 moves
|
||||
}
|
||||
|
||||
private int moveRandom(int[][] board){
|
||||
|
@ -59,6 +143,60 @@ public class MaurizioAI implements Player {
|
|||
return choice;
|
||||
}
|
||||
|
||||
private int moveCentral(int[][] board){
|
||||
if(board[3][0] == 0){
|
||||
return 3;
|
||||
}
|
||||
if(board[2][0] == 0){
|
||||
return 2;
|
||||
}
|
||||
if(board[4][0] == 0){
|
||||
return 4;
|
||||
}
|
||||
if(board[1][0] == 0){
|
||||
return 1;
|
||||
}
|
||||
if(board[5][0] == 0){
|
||||
return 5;
|
||||
}
|
||||
if(board[0][0] == 0){
|
||||
return 0;
|
||||
}
|
||||
if(board[6][0] == 0){
|
||||
return 6;
|
||||
}
|
||||
return -1; // board is full
|
||||
}
|
||||
|
||||
private int moveCentral(int[][] board, LinkedList<Integer> moves){
|
||||
if (moves.isEmpty()) {
|
||||
return -1; // empty list
|
||||
}
|
||||
if(moves.contains(3) && board[3][0] == 0){
|
||||
return 3;
|
||||
}
|
||||
if(moves.contains(2) && board[2][0] == 0){
|
||||
return 2;
|
||||
}
|
||||
if(moves.contains(4) && board[4][0] == 0){
|
||||
return 4;
|
||||
}
|
||||
if(moves.contains(1) && board[1][0] == 0){
|
||||
return 1;
|
||||
}
|
||||
if(moves.contains(5) && board[5][0] == 0){
|
||||
return 5;
|
||||
}
|
||||
if(moves.contains(0) && board[0][0] == 0){
|
||||
return 0;
|
||||
}
|
||||
if(moves.contains(6) && board[6][0] == 0){
|
||||
return 6;
|
||||
}
|
||||
|
||||
return -1; // Can' t happen
|
||||
}
|
||||
|
||||
private int[][] makeMove(int[][] board, int choice, int id) {
|
||||
// Check his choice against the current board.
|
||||
if (choice < 0 || choice > Game.GAME_COLUMNS || board[choice][0] != 0) {
|
||||
|
@ -70,7 +208,7 @@ public class MaurizioAI implements Player {
|
|||
while (pos < (board[0].length - 1) && board[choice][pos + 1] == 0) {
|
||||
pos++;
|
||||
}
|
||||
// Change the board accordingl
|
||||
// Change the board accordingly
|
||||
int[][] boardNew = copyBoard(board);
|
||||
boardNew[choice][pos] = id;
|
||||
return boardNew;
|
||||
|
@ -89,10 +227,11 @@ public class MaurizioAI implements Player {
|
|||
private boolean withinBoard(int x, int y){
|
||||
return ((x>=0 && x < Game.GAME_COLUMNS) && (y>=0 && y < Game.GAME_ROWS));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether the last Move closed any lines on the board
|
||||
* checks whether the last move closed any lines on the board
|
||||
*/
|
||||
private boolean checkWin(int[][] board, int col, int id){
|
||||
private boolean checkWin(int[][] board, int col, int iD){
|
||||
// find row of last move -- assuming the move was legal
|
||||
int row = 0;
|
||||
while(row < Game.GAME_ROWS-1 && board[col][row+1] == 0){
|
||||
|
@ -106,7 +245,7 @@ public class MaurizioAI implements Player {
|
|||
win = false;
|
||||
break;
|
||||
}
|
||||
if(j != -i && board[col+i+j][row] != id){
|
||||
if(j != -i && board[col+i+j][row] != iD){
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
|
@ -122,7 +261,7 @@ public class MaurizioAI implements Player {
|
|||
win = false;
|
||||
break;
|
||||
}
|
||||
if(j != -i && board[col][row+i+j] != id){
|
||||
if(j != -i && board[col][row+i+j] != iD){
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
|
@ -138,7 +277,7 @@ public class MaurizioAI implements Player {
|
|||
win = false;
|
||||
break;
|
||||
}
|
||||
if(j != -i && board[col+i+j][row-i-j] != id){
|
||||
if(j != -i && board[col+i+j][row-i-j] != iD){
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
|
@ -154,7 +293,7 @@ public class MaurizioAI implements Player {
|
|||
win = false;
|
||||
break;
|
||||
}
|
||||
if(j != -i && board[col+i+j][row+i+j] != id){
|
||||
if(j != -i && board[col+i+j][row+i+j] != iD){
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue