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/player/Player.java \
|
||||
src/player/malte/MalteAI.java \
|
||||
src/player/malte/Pattern.java \
|
||||
src/player/malte/Item.java \
|
||||
src/player/maurizio/MaurizioAI.java
|
||||
|
||||
OBJECTS=$($(subst $(CLASSPATH),$(BUILDS),$(CLASSES)):.java=.class)
|
||||
|
@ -26,6 +28,8 @@ BUILDFILES=$(OBJECTS) $(FXMLS_BUILD)
|
|||
|
||||
MAIN=game.Main
|
||||
|
||||
N=100
|
||||
|
||||
|
||||
all: $(CLASSES) $(FXMLS_BUILD)
|
||||
$(JAVAC) $(JAVAC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(BUILDS)
|
||||
|
@ -33,6 +37,9 @@ all: $(CLASSES) $(FXMLS_BUILD)
|
|||
run: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN)
|
||||
|
||||
simulate: $(CLASSES)
|
||||
$(JAVA) -cp $(BUILDS):$(LIBARIES) $(MAIN) $(N)
|
||||
|
||||
doc: $(CLASSES)
|
||||
$(JAVADOC) $(JAVADOC_OPTIONS) -cp $(CLASSPATH):$(LIBARIES) $(CLASSES) -d $(DOC)
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ package game;
|
|||
import java.util.Random;
|
||||
|
||||
import player.Player;
|
||||
import player.MaurizioAI;
|
||||
import player.maurizio.MaurizioAI;
|
||||
import player.malte.MalteAI;
|
||||
|
||||
/**
|
||||
* Represents a game of Connect Four.
|
||||
|
@ -13,12 +14,12 @@ public class Game {
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
private final static int GAME_ROWS = 6;
|
||||
public final static int GAME_ROWS = 6;
|
||||
|
||||
/**
|
||||
* Player One
|
||||
|
@ -69,6 +70,39 @@ public class Game {
|
|||
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.
|
||||
* @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, ...
|
||||
*/
|
||||
private int checkState(boolean output) {
|
||||
if(MaurizioAI.checkWin(this.board, p1.getID())){
|
||||
if(checkWin(this.board, p1.getID())){
|
||||
this.gameOn = false;
|
||||
if(output){
|
||||
System.out.println(p1.getP().getName() + " wins!");
|
||||
}
|
||||
return p1.getID(); // player 1 wins
|
||||
}
|
||||
if(MaurizioAI.checkWin(this.board, p2.getID())){
|
||||
if(checkWin(this.board, p2.getID())){
|
||||
this.gameOn = false;
|
||||
if(output){
|
||||
System.out.println(p2.getP().getName() + " wins!");
|
||||
|
@ -242,4 +276,83 @@ public class Game {
|
|||
}
|
||||
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;
|
||||
|
||||
import player.Player;
|
||||
import player.MaurizioAI;
|
||||
import player.MalteAI;
|
||||
import player.maurizio.MaurizioAI;
|
||||
import player.malte.MalteAI;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
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
|
||||
if (args.length == 1) {
|
||||
Game.simulate(Integer.parseInt(args[0]));
|
||||
} 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) {
|
||||
this.p = p;
|
||||
this.id = id;
|
||||
this.p.setPlayerID(id);
|
||||
}
|
||||
|
||||
public void setSymbol(String sym) {
|
||||
|
|
|
@ -4,4 +4,5 @@ public interface Player {
|
|||
|
||||
public int move(int[][] game);
|
||||
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.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Arrays;
|
||||
|
||||
import player.Player;
|
||||
|
||||
public class MalteAI implements Player{
|
||||
|
||||
private String name;
|
||||
private Random ran;
|
||||
private int id;
|
||||
|
||||
public MalteAI(String name){
|
||||
this.name = name;
|
||||
this.ran = new Random();
|
||||
}
|
||||
|
||||
public void setPlayerID(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int move(int[][] board){
|
||||
Set<Integer> options = new HashSet<>(Arrays.asList(0,1,2,3,4,5,6));
|
||||
for (Integer i: copySet(options)) {
|
||||
|
@ -22,11 +29,28 @@ public class MalteAI implements Player{
|
|||
options.remove(i);
|
||||
}
|
||||
}
|
||||
Set<Integer> instantWins = getWinningOptions(options, board);
|
||||
// Set<Integer> preventions = getPreventionOptions(options, board);
|
||||
|
||||
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) {
|
||||
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 player.Player;
|
||||
|
||||
public class MaurizioAI implements Player {
|
||||
|
||||
private String name;
|
||||
private Random ran;
|
||||
private int id;
|
||||
|
||||
public MaurizioAI(String name){
|
||||
this.name = name;
|
||||
this.ran = new Random();
|
||||
}
|
||||
|
||||
public void setPlayerID(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int move(int[][] board){
|
||||
int choice = ran.nextInt(7);
|
||||
while (board[choice][0] != 0) {
|
||||
|
@ -20,83 +27,6 @@ public class MaurizioAI implements Player {
|
|||
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(){
|
||||
return this.name;
|
||||
|
|
Loading…
Reference in a new issue