Merge branch 'master' of https://git.informatik.uni-leipzig.de/mt85zybu/VierGewinnt
This commit is contained in:
commit
54afd84fe1
7
Makefile
7
Makefile
|
@ -18,6 +18,8 @@ src/game/GameEntry.java \
|
||||||
src/game/PlayerObject.java \
|
src/game/PlayerObject.java \
|
||||||
src/player/Player.java \
|
src/player/Player.java \
|
||||||
src/player/malte/MalteAI.java \
|
src/player/malte/MalteAI.java \
|
||||||
|
src/player/malte/Pattern.java \
|
||||||
|
src/player/malte/Item.java \
|
||||||
src/player/maurizio/MaurizioAI.java
|
src/player/maurizio/MaurizioAI.java
|
||||||
|
|
||||||
OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class)
|
OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class)
|
||||||
|
@ -26,6 +28,8 @@ BUILDFILES=$(OBJECTS) $(FXMLS_BUILD)
|
||||||
|
|
||||||
MAIN=game.Main
|
MAIN=game.Main
|
||||||
|
|
||||||
|
N=100
|
||||||
|
|
||||||
|
|
||||||
all: $(CLASSES) $(FXMLS_BUILD)
|
all: $(CLASSES) $(FXMLS_BUILD)
|
||||||
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(BUILDS)
|
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(BUILDS)
|
||||||
|
@ -33,6 +37,9 @@ all: $(CLASSES) $(FXMLS_BUILD)
|
||||||
run: $(CLASSES)
|
run: $(CLASSES)
|
||||||
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN)
|
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN)
|
||||||
|
|
||||||
|
simulate: $(CLASSES)
|
||||||
|
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) $(N)
|
||||||
|
|
||||||
doc: $(CLASSES)
|
doc: $(CLASSES)
|
||||||
$(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(DOC)
|
$(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(DOC)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ package game;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import player.Player;
|
import player.Player;
|
||||||
import player.MaurizioAI;
|
import player.maurizio.MaurizioAI;
|
||||||
|
import player.malte.MalteAI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a game of Connect Four.
|
* Represents a game of Connect Four.
|
||||||
|
@ -13,12 +14,12 @@ public class Game {
|
||||||
/**
|
/**
|
||||||
* Number of columns on the board.
|
* Number of columns on the board.
|
||||||
*/
|
*/
|
||||||
private final static int GAME_COLUMNS = 7;
|
public final static int GAME_COLUMNS = 7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of rows on the board.
|
* Number of rows on the board.
|
||||||
*/
|
*/
|
||||||
private final static int GAME_ROWS = 6;
|
public final static int GAME_ROWS = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Player One
|
* Player One
|
||||||
|
@ -69,6 +70,39 @@ public class Game {
|
||||||
this.gameOn = false;
|
this.gameOn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulates n games.
|
||||||
|
* Simulates the games and prints statistical output to stdout.
|
||||||
|
*
|
||||||
|
* @param runs The number of games to simulate.
|
||||||
|
*/
|
||||||
|
public static void simulate(int runs) {
|
||||||
|
Player p1 = new MaurizioAI("Maurizio");
|
||||||
|
Player p2 = new MalteAI("Malte");
|
||||||
|
// 0 - Draw
|
||||||
|
// 1 - p1 wins
|
||||||
|
// 2 - p2 wins
|
||||||
|
int[] statistic = new int[3];
|
||||||
|
for (int i = 0; i < runs; i++) {
|
||||||
|
int result = new Game(p1, p2).start(false, true);
|
||||||
|
// TODO: Improve IDs
|
||||||
|
statistic[result]++;
|
||||||
|
}
|
||||||
|
double[] percents = new double[3];
|
||||||
|
for (int i = 0; i < statistic.length; i++) {
|
||||||
|
percents[i] = ((double)statistic[i]) / runs * 100.0;
|
||||||
|
}
|
||||||
|
System.out.println("Draws : " + statistic[0]);
|
||||||
|
System.out.println(p1.getName() + ": " + statistic[1] + " wins");
|
||||||
|
System.out.println(p2.getName() + ": " + statistic[2] + " wins");
|
||||||
|
|
||||||
|
System.out.println("PERCENTAGE:");
|
||||||
|
System.out.println("Draws : " + percents[0] + "%");
|
||||||
|
System.out.println(p1.getName() + ": " + percents[1] + "% wins");
|
||||||
|
System.out.println(p2.getName() + ": " + percents[2] + "% wins");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a game.
|
* Start a game.
|
||||||
* @param output determines, whether game info etc. gets printed to the console
|
* @param output determines, whether game info etc. gets printed to the console
|
||||||
|
@ -168,14 +202,14 @@ public class Game {
|
||||||
* @return the state of the game, -1 = still undecided , 0 = draw, 1 = Player 1 wins, ...
|
* @return the state of the game, -1 = still undecided , 0 = draw, 1 = Player 1 wins, ...
|
||||||
*/
|
*/
|
||||||
private int checkState(boolean output) {
|
private int checkState(boolean output) {
|
||||||
if(MaurizioAI.checkWin(this.board, p1.getID())){
|
if(checkWin(this.board, p1.getID())){
|
||||||
this.gameOn = false;
|
this.gameOn = false;
|
||||||
if(output){
|
if(output){
|
||||||
System.out.println(p1.getP().getName() + " wins!");
|
System.out.println(p1.getP().getName() + " wins!");
|
||||||
}
|
}
|
||||||
return p1.getID(); // player 1 wins
|
return p1.getID(); // player 1 wins
|
||||||
}
|
}
|
||||||
if(MaurizioAI.checkWin(this.board, p2.getID())){
|
if(checkWin(this.board, p2.getID())){
|
||||||
this.gameOn = false;
|
this.gameOn = false;
|
||||||
if(output){
|
if(output){
|
||||||
System.out.println(p2.getP().getName() + " wins!");
|
System.out.println(p2.getP().getName() + " wins!");
|
||||||
|
@ -242,4 +276,83 @@ public class Game {
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkWin(int[][] board, int player){
|
||||||
|
int winLength = 4;
|
||||||
|
boolean win = false;
|
||||||
|
// check columns for win
|
||||||
|
for(int i=0;i<board.length;i++){
|
||||||
|
for(int j=0;j<(board[0].length-winLength+1);j++){
|
||||||
|
if(board[i][j] == player){
|
||||||
|
win = true;
|
||||||
|
for(int k=1;k<winLength;k++){
|
||||||
|
if(board[i][j+k] != board[i][j]){
|
||||||
|
win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(win){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check rows for win
|
||||||
|
for(int i=0;i<board[0].length;i++){
|
||||||
|
for(int j=0;j<(board.length-winLength+1);j++){
|
||||||
|
if(board[j][i] == player){
|
||||||
|
win = true;
|
||||||
|
for(int k=1;k<winLength;k++){
|
||||||
|
if(board[j+k][i] != board[j][i]){
|
||||||
|
win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(win){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check diagonals for win
|
||||||
|
//bottom-left to top-right diagonals
|
||||||
|
for(int i=0;i<(board.length-winLength+1);i++){
|
||||||
|
for(int j=(winLength-1);j<board[0].length;j++){
|
||||||
|
if(board[i][j] == player){
|
||||||
|
win = true;
|
||||||
|
for(int k=1;k<winLength;k++){
|
||||||
|
if(board[i+k][j-k] != board[i][j]){
|
||||||
|
win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(win){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//top-left to bottom-right diagonals
|
||||||
|
for(int i=0;i<(board.length-winLength+1);i++){
|
||||||
|
for(int j=0;j<(board[0].length-winLength+1);j++){
|
||||||
|
if(board[i][j] == player){
|
||||||
|
win = true;
|
||||||
|
for(int k=1;k<winLength;k++){
|
||||||
|
if(board[i+k][j+k] != board[i][j]){
|
||||||
|
win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(win){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
package game;
|
package game;
|
||||||
|
|
||||||
import player.Player;
|
import player.Player;
|
||||||
import player.MaurizioAI;
|
import player.maurizio.MaurizioAI;
|
||||||
import player.MalteAI;
|
import player.malte.MalteAI;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Player p1 = new MalteAI("Malte");
|
if (args.length == 1) {
|
||||||
Player p2 = new MaurizioAI("Maurizio");
|
Game.simulate(Integer.parseInt(args[0]));
|
||||||
new Game(p1, p2).start(true, true); //1. param = output mode, 2. param = random beginner
|
} else {
|
||||||
|
Player p1 = new MalteAI("Malte");
|
||||||
|
Player p2 = new MaurizioAI("Maurizio");
|
||||||
|
new Game(p1, p2).start(true, true); //1. param = output mode, 2. param = random beginner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class PlayerObject {
|
||||||
public PlayerObject(int id, Player p) {
|
public PlayerObject(int id, Player p) {
|
||||||
this.p = p;
|
this.p = p;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.p.setPlayerID(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSymbol(String sym) {
|
public void setSymbol(String sym) {
|
||||||
|
|
|
@ -4,4 +4,5 @@ public interface Player {
|
||||||
|
|
||||||
public int move(int[][] game);
|
public int move(int[][] game);
|
||||||
public String getName();
|
public String getName();
|
||||||
|
public void setPlayerID(int id);
|
||||||
}
|
}
|
||||||
|
|
39
src/player/malte/Item.java
Normal file
39
src/player/malte/Item.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package player.malte;
|
||||||
|
|
||||||
|
public class Item {
|
||||||
|
|
||||||
|
private int posX;
|
||||||
|
private int posY;
|
||||||
|
private int[] ids;
|
||||||
|
|
||||||
|
public Item(int posX, int posY, int id) {
|
||||||
|
this(posX, posY, new int[]{id});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item(int posX, int posY, int[] ids) {
|
||||||
|
this.posX = posX;
|
||||||
|
this.posY = posY;
|
||||||
|
this.ids = ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosX() {
|
||||||
|
return this.posX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosY() {
|
||||||
|
return this.posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getIDs() {
|
||||||
|
return this.ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasID(int id) {
|
||||||
|
for (int i: ids) {
|
||||||
|
if (i == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,27 @@
|
||||||
package player;
|
package player.malte;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import player.Player;
|
||||||
|
|
||||||
public class MalteAI implements Player{
|
public class MalteAI implements Player{
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Random ran;
|
private Random ran;
|
||||||
|
private int id;
|
||||||
|
|
||||||
public MalteAI(String name){
|
public MalteAI(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.ran = new Random();
|
this.ran = new Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayerID(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public int move(int[][] board){
|
public int move(int[][] board){
|
||||||
Set<Integer> options = new HashSet<>(Arrays.asList(0,1,2,3,4,5,6));
|
Set<Integer> options = new HashSet<>(Arrays.asList(0,1,2,3,4,5,6));
|
||||||
for (Integer i: copySet(options)) {
|
for (Integer i: copySet(options)) {
|
||||||
|
@ -22,11 +29,28 @@ public class MalteAI implements Player{
|
||||||
options.remove(i);
|
options.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Set<Integer> instantWins = getWinningOptions(options, board);
|
||||||
// Set<Integer> preventions = getPreventionOptions(options, board);
|
// Set<Integer> preventions = getPreventionOptions(options, board);
|
||||||
|
|
||||||
return takeRandom(options).intValue();
|
return takeRandom(options).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Integer> getWinningOptions(Set<Integer> options, int[][] board) {
|
||||||
|
Pattern topOfColumn = new Pattern(new Item(0, 0, 0),
|
||||||
|
new Item(0, 1, id),
|
||||||
|
new Item(0, 2, id),
|
||||||
|
new Item(0, 3, id));
|
||||||
|
Pattern leftInRow = new Pattern(new Item(0, 0, 0),
|
||||||
|
new Item(1, 0, id),
|
||||||
|
new Item(2, 0, id),
|
||||||
|
new Item(3, 0, id));
|
||||||
|
Pattern rightInRow = new Pattern(new Item(0, 0, 0),
|
||||||
|
new Item(-1, 0, id),
|
||||||
|
new Item(-2, 0, id),
|
||||||
|
new Item(-3, 0, id));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Set<Integer> copySet(Set<Integer> s) {
|
private Set<Integer> copySet(Set<Integer> s) {
|
||||||
return new HashSet<Integer>(s);
|
return new HashSet<Integer>(s);
|
||||||
}
|
}
|
||||||
|
|
10
src/player/malte/Pattern.java
Normal file
10
src/player/malte/Pattern.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package player.malte;
|
||||||
|
|
||||||
|
public class Pattern {
|
||||||
|
|
||||||
|
private Item[] parts;
|
||||||
|
|
||||||
|
public Pattern(Item... parts) {
|
||||||
|
this.parts = parts;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,24 @@
|
||||||
package player;
|
package player.maurizio;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import player.Player;
|
||||||
|
|
||||||
public class MaurizioAI implements Player {
|
public class MaurizioAI implements Player {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Random ran;
|
private Random ran;
|
||||||
|
private int id;
|
||||||
|
|
||||||
public MaurizioAI(String name){
|
public MaurizioAI(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.ran = new Random();
|
this.ran = new Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayerID(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public int move(int[][] board){
|
public int move(int[][] board){
|
||||||
int choice = ran.nextInt(7);
|
int choice = ran.nextInt(7);
|
||||||
while (board[choice][0] != 0) {
|
while (board[choice][0] != 0) {
|
||||||
|
@ -20,83 +27,6 @@ public class MaurizioAI implements Player {
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkWin(int[][] board, int player){
|
|
||||||
int winLength = 4;
|
|
||||||
boolean win = false;
|
|
||||||
// check columns for win
|
|
||||||
for(int i=0;i<board.length;i++){
|
|
||||||
for(int j=0;j<(board[0].length-winLength+1);j++){
|
|
||||||
if(board[i][j] == player){
|
|
||||||
win = true;
|
|
||||||
for(int k=1;k<winLength;k++){
|
|
||||||
if(board[i][j+k] != board[i][j]){
|
|
||||||
win = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(win){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check rows for win
|
|
||||||
for(int i=0;i<board[0].length;i++){
|
|
||||||
for(int j=0;j<(board.length-winLength+1);j++){
|
|
||||||
if(board[j][i] == player){
|
|
||||||
win = true;
|
|
||||||
for(int k=1;k<winLength;k++){
|
|
||||||
if(board[j+k][i] != board[j][i]){
|
|
||||||
win = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(win){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check diagonals for win
|
|
||||||
//bottom-left to top-right diagonals
|
|
||||||
for(int i=0;i<(board.length-winLength+1);i++){
|
|
||||||
for(int j=(winLength-1);j<board[0].length;j++){
|
|
||||||
if(board[i][j] == player){
|
|
||||||
win = true;
|
|
||||||
for(int k=1;k<winLength;k++){
|
|
||||||
if(board[i+k][j-k] != board[i][j]){
|
|
||||||
win = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(win){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//top-left to bottom-right diagonals
|
|
||||||
for(int i=0;i<(board.length-winLength+1);i++){
|
|
||||||
for(int j=0;j<(board[0].length-winLength+1);j++){
|
|
||||||
if(board[i][j] == player){
|
|
||||||
win = true;
|
|
||||||
for(int k=1;k<winLength;k++){
|
|
||||||
if(board[i+k][j+k] != board[i][j]){
|
|
||||||
win = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(win){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName(){
|
public String getName(){
|
||||||
return this.name;
|
return this.name;
|
||||||
|
|
Loading…
Reference in a new issue