diff --git a/src/game/Game.java b/src/game/Game.java index a9ad413..55a3666 100644 --- a/src/game/Game.java +++ b/src/game/Game.java @@ -3,6 +3,7 @@ package game; import java.util.Random; import player.Player; +import player.Player2; /** * Represents a game of Connect Four. @@ -69,30 +70,43 @@ public class Game { } /** - * Starts the game. + * Start a game. + * @param output determines, whether game info etc. gets printed to the console + * @param rand determines whether the starting player gets selected randomly + * @return the winner of the game (0=draw) */ - public void start() { - // Set random starting player. - Random ran = new Random(); - if (ran.nextBoolean()) { + public int start(boolean output, boolean rand) { + // Set starting player. + if(rand){ + Random ran = new Random(); + if (ran.nextBoolean()) { + currentP = this.p1; + } else { + currentP = this.p2; + } + } else{ currentP = this.p1; - } else { - currentP = this.p2; } + // Start the game this.gameOn = true; while(gameOn) { - makeMove(); + makeMove(output); currentP = other(currentP); - if(gameOn) { + if(output){ logGame(); - checkState(); - } else { - System.out.println("*******************"); - System.out.println("Thanks for Playing!"); - System.out.println("*******************"); + } + int state = checkState(output); + if(state != (-1)){ + if(output){ + System.out.println("*******************"); + System.out.println("Thanks for Playing!"); + System.out.println("*******************"); + } + return state; // the result of the game } } + return checkState(false); // it is impossible to reach this, but it makes the compiler happy ;) } /** @@ -112,14 +126,17 @@ public class Game { /** * Calls a players functions to make a move. */ - private void makeMove() { + private void makeMove(boolean output) { // Get a choice from the player, while only giving him a copy of the game. int choice = currentP.getP().move(copyBoard()); // Check his choice against the current board. if (choice < 0 || choice > GAME_COLUMNS || this.board[choice][0] != 0) { // If a player makes a false move, the game punishes him. this.gameOn = false; - log(currentP.getP().getName() + " made an illegal move and lost!"); + //TODO the game gets stopped, but checkState doesn't know what that means!? + if(output){ + log(currentP.getP().getName() + " made an illegal move and lost!"); + } return; } // Find the lowest empty field in the board in the choosen column. @@ -130,9 +147,17 @@ public class Game { // Change the board accordingly. this.board[choice][pos] = currentP.getID(); this.hist.add(new GameEntry(currentP, choice, pos)); - log(currentP.getP().getName() + " made a move!"); + if(output){ + log(currentP.getP().getName() + " made a move!"); + } } + /** + * Resets the board and the history of the game. + */ + public void reset(){ + this.board = new int[GAME_COLUMNS][GAME_ROWS]; + } /** * Checks the board for game-ending conditions. * The game is won, if one of the players manages to get four @@ -140,186 +165,39 @@ public class Game { * The game is drawn when the board is full, that is, when every * one of the 42 pieces are played. * The function changes variables accordingly. + * @return the state of the game, -1 = still undecided , 0 = draw, 1 = Player 1 wins, ... */ - private void checkState() { - // --- CHECK WIN --- - // Check rows - outer:for (int i = 0; i < GAME_COLUMNS; i++) { - // Player One's counter - int count1 = 0; - // Player Two's counter - int count2 = 0; - for (int j = 0; j < GAME_ROWS; j++) { - if (this.board[i][j] == p1.getID()) { - count1++; - count2 = 0; - } else if (this.board[i][j] == p2.getID()) { - count1 = 0; - count2++; - } else { - count1 = 0; - count2 = 0; - } - if (count1 >= 4) { - log(p1.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - if (count2 >= 4) { - log(p2.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } + private int checkState(boolean output) { + if(Player2.checkWin(this.board, p1.getID())){ + this.gameOn = false; + if(output){ + System.out.println(p1.getP().getName() + " wins!"); } + return p1.getID(); // player 1 wins } - // Check columns - outer:for (int j = 0; j < GAME_ROWS; j++) { - // Player One's counter - int count1 = 0; - // Player Two's counter - int count2 = 0; - for (int i = 0; i < GAME_COLUMNS; i++) { - if (this.board[i][j] == p1.getID()) { - count1++; - count2 = 0; - } else if (this.board[i][j] == p2.getID()) { - count1 = 0; - count2++; - } else { - count1 = 0; - count2 = 0; - } - if (count1 >= 4) { - log(p1.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - if (count2 >= 4) { - log(p2.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } + if(Player2.checkWin(this.board, p2.getID())){ + this.gameOn = false; + if(output){ + System.out.println(p2.getP().getName() + " wins!"); } + return p2.getID(); // player 2 wins } - // Check diagonals from lower left to upper right. - boolean reverse = false; - int count1 = 0; - int count2 = 0; - int posX = 1, posY = -1; - int addX = -1, addY = 1; - outer:while (posX != GAME_COLUMNS -1 || posY != GAME_ROWS - 1) { - posX += addX; - posY += addY; - if (posX > GAME_COLUMNS - 1) { - posY += 2; - posX = GAME_COLUMNS - 1; - reverse = true; - } else if (posY > GAME_ROWS - 1) { - posX += 2; - posY = GAME_ROWS - 1; - reverse = true; - } else if (posX < 0) { - posX = 0; - reverse = true; - } else if (posY < 0) { - posY = 0; - reverse = true; - } - if (reverse) { - addX *= -1; - addY *= -1; - count1 = 0; - count2 = 0; - reverse = false; - } - if (this.board[posX][posY] == p1.getID()) { - count1++; - count2 = 0; - } else if (this.board[posX][posY] == p2.getID()) { - count1 = 0; - count2++; - } else { - count1 = 0; - count2 = 0; - } - if (count1 >= 4) { - log(p1.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - if (count2 >= 4) { - log(p2.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - } - // Check diagonals from lower right to upper left. - reverse = false; - count1 = 0; - count2 = 0; - posX = GAME_COLUMNS; - posY = 1; - addX = -1; - addY = -1; - outer:while (posX != 0 || posY != GAME_ROWS - 1) { - posX += addX; - posY += addY; - if (posX < 0) { - posY += 2; - posX = 0; - reverse = true; - } else if (posY > GAME_ROWS - 1) { - posX -= 2; - posY = GAME_ROWS - 1; - reverse = true; - } else if (posX > GAME_COLUMNS - 1) { - posX = GAME_COLUMNS - 1; - reverse = true; - } else if (posY < 0) { - posY = 0; - reverse = true; - } - if (reverse) { - addX *= -1; - addY *= -1; - count1 = 0; - count2 = 0; - reverse = false; - } - if (this.board[posX][posY] == p1.getID()) { - count1++; - count2 = 0; - } else if (this.board[posX][posY] == p2.getID()) { - count1 = 0; - count2++; - } else { - count1 = 0; - count2 = 0; - } - if (count1 >= 4) { - log(p1.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - if (count2 >= 4) { - log(p2.getP().getName() + " won!"); - this.gameOn = false; - break outer; - } - } - // --- CHECK DRAW --- + boolean draw = true; - outer:for (int i = 0; i < GAME_COLUMNS; i++) { - for (int j = 0; j < GAME_ROWS; j++) { - if (this.board[i][j] == 0) { - draw = false; - break outer; - } + for (int i = 0; i < GAME_COLUMNS; i++) { + if(this.board[i][0] == 0) { + draw = false; + break; } } if (draw) { this.gameOn = false; + if(output){ + System.out.println("Draw!"); + } + return 0; // draw } + return -1; // game still undecided } /** @@ -346,7 +224,6 @@ public class Game { /** * Prints the current board to stdout. - * The Player that started the game gets 'X' the other one 'O'. */ private void logGame() { for(int i = 0; i < board[0].length; i++){ diff --git a/src/player/MaurizioAI.java b/src/player/MaurizioAI.java index 2d782a2..a517d10 100644 --- a/src/player/MaurizioAI.java +++ b/src/player/MaurizioAI.java @@ -20,6 +20,84 @@ 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