Enhancement + added #8 multipleRounds to Main
This commit is contained in:
parent
574cb1df34
commit
b9e24a89b2
|
@ -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,182 +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++) {
|
||||
int count1 = 0;
|
||||
int count2 = 0;
|
||||
for (int j = 0; j < GAME_ROWS; j++) {
|
||||
if (this.board[i][j] == 1) {
|
||||
count1++;
|
||||
count2 = 0;
|
||||
} else if (this.board[i][j] == 2) {
|
||||
count1 = 0;
|
||||
count2++;
|
||||
} else {
|
||||
count1 = 0;
|
||||
count2 = 0;
|
||||
}
|
||||
if (count1 >= 4) {
|
||||
log("Player 1 won!");
|
||||
this.gameOn = false;
|
||||
break outer;
|
||||
}
|
||||
if (count2 >= 4) {
|
||||
log("Player 2 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++) {
|
||||
int count1 = 0;
|
||||
int count2 = 0;
|
||||
for (int i = 0; i < GAME_COLUMNS; i++) {
|
||||
if (this.board[i][j] == 1) {
|
||||
count1++;
|
||||
count2 = 0;
|
||||
} else if (this.board[i][j] == 2) {
|
||||
count1 = 0;
|
||||
count2++;
|
||||
} else {
|
||||
count1 = 0;
|
||||
count2 = 0;
|
||||
}
|
||||
if (count1 >= 4) {
|
||||
log("Player 1 won!");
|
||||
this.gameOn = false;
|
||||
break outer;
|
||||
}
|
||||
if (count2 >= 4) {
|
||||
log("Player 2 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] == 1) {
|
||||
count1++;
|
||||
count2 = 0;
|
||||
} else if (this.board[posX][posY] == 2) {
|
||||
count1 = 0;
|
||||
count2++;
|
||||
} else {
|
||||
count1 = 0;
|
||||
count2 = 0;
|
||||
}
|
||||
if (count1 >= 4) {
|
||||
log("Player 1 won!");
|
||||
this.gameOn = false;
|
||||
break outer;
|
||||
}
|
||||
if (count2 >= 4) {
|
||||
log("Player 2 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] == 1) {
|
||||
count1++;
|
||||
count2 = 0;
|
||||
} else if (this.board[posX][posY] == 2) {
|
||||
count1 = 0;
|
||||
count2++;
|
||||
} else {
|
||||
count1 = 0;
|
||||
count2 = 0;
|
||||
}
|
||||
if (count1 >= 4) {
|
||||
log("Player 1 won!");
|
||||
this.gameOn = false;
|
||||
break outer;
|
||||
}
|
||||
if (count2 >= 4) {
|
||||
log("Player 2 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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -342,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++){
|
||||
|
|
|
@ -3,12 +3,33 @@ package game;
|
|||
import player.Player;
|
||||
import player.Player1;
|
||||
import player.Player2;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Player p1 = new Player1("Malte");
|
||||
Player p2 = new Player2("Maurizio");
|
||||
new Game(p1, p2).start();
|
||||
|
||||
// Analysis of how often the starting player wins, when both player make completely
|
||||
// random moves.
|
||||
Game game = new Game(p1, p2);
|
||||
int count1 = 0; // number of times Player1 aka Malte wins
|
||||
int count2 = 0; // number of times Player2 aka Mauri wins
|
||||
Scanner scan = new Scanner(System.in);
|
||||
System.out.print("Bitte geben sie die Anzahl der Partien ein: ");
|
||||
int rounds = scan.nextInt();
|
||||
for(int i=1;i<=rounds;i++){
|
||||
int res = game.start(false, false);
|
||||
if(res == 1){
|
||||
count1++;
|
||||
}
|
||||
if(res == 2){
|
||||
count2++;
|
||||
}
|
||||
game.reset();
|
||||
}
|
||||
System.out.println(rounds + " rounds with " + count1 + " wins for Player1 " +
|
||||
count2 + " wins for Player2 and " + (rounds-count1-count2) + " draws");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public class Player2 implements Player{
|
|||
boolean win = false;
|
||||
// check columns for win
|
||||
for(int i=0;i<board.length;i++){
|
||||
for(int j=0;j<=(board[0].length-winLength);j++){
|
||||
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++){
|
||||
|
@ -43,11 +43,11 @@ public class Player2 implements Player{
|
|||
|
||||
// check rows for win
|
||||
for(int i=0;i<board[0].length;i++){
|
||||
for(int j=0;j<=(board.length-winLength);j++){
|
||||
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[i][j+k] != board[i][j]){
|
||||
if(board[j+k][i] != board[j][i]){
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
|
@ -60,8 +60,41 @@ public class Player2 implements Player{
|
|||
}
|
||||
|
||||
// check diagonals for win
|
||||
//TODO
|
||||
//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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue