Enhancement + added #8 multipleRounds to Main

This commit is contained in:
MaurizioBruetsch 2017-10-15 20:59:03 +02:00
parent 574cb1df34
commit b9e24a89b2
3 changed files with 123 additions and 188 deletions

View file

@ -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++){

View file

@ -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");
}
}

View file

@ -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;
}