Skip to content

Commit

Permalink
Added AI for Phase 1
Browse files Browse the repository at this point in the history
  • Loading branch information
mssalkhalifah committed Jul 12, 2020
1 parent 8b547cb commit 510e3f7
Show file tree
Hide file tree
Showing 11 changed files with 536 additions and 26 deletions.
18 changes: 17 additions & 1 deletion core/src/com/groupg/game/Game.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.groupg.game;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.groupg.game.ai.Evaluation;
import com.groupg.game.ai.MiniMax;
import com.groupg.game.board.Board;
import com.groupg.game.board.PointsPosition;
import com.groupg.game.gameobject.PieceColor;
import com.groupg.game.player.Player;

Expand All @@ -10,12 +13,15 @@ public class Game {
private GameState gameState;
private Player whitePlayer;
private Player blackPlayer;
private Evaluation evaluationBoard;

public Game(MyGame myGame) {
whitePlayer = new Player(myGame.getCamera(), PieceColor.WHITE);
blackPlayer = new Player(myGame.getCamera(), PieceColor.BLACK);
gameBoard = new Board();
gameBoard.initialize();
gameState = new GameState(whitePlayer, blackPlayer, gameBoard);
evaluationBoard = new Evaluation();
}

public void update(float delta) {
Expand All @@ -24,7 +30,15 @@ public void update(float delta) {

gameBoard.update(delta, player.getMousePosition());

if (player.isPlay()) {
// If is the black player turn
if (!gameState.getCurrentTurn()) {
int bestNextPosition = MiniMax.getBestOpeningPhaseMove(gameBoard, gameState);
player.setTouchPosition(PointsPosition.getPointPosition(bestNextPosition));
player.setAction(true);
}

if (player.isPlay() || blackPlayer.isAction()) {
System.out.println("Current game board: \n" + gameBoard);
switch (gameState.getGameStates().peek()) {
case FIRST_PHASE:
gameState.firstPhase(player);
Expand All @@ -49,6 +63,8 @@ public void update(float delta) {
default:
throw new IllegalArgumentException("Unknown game state");
}
player.setAction(false);
System.out.println("Updated game board: \n" + gameBoard + "\n");
}

gameState.update(delta);
Expand Down
15 changes: 9 additions & 6 deletions core/src/com/groupg/game/GameRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.groupg.game.player.Player;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;

public class GameRule {
Expand Down Expand Up @@ -151,14 +150,18 @@ public boolean checkCaptureValid(Vector3 position, PieceColor pieceColor) {
return false;
}

public boolean checkAvailableLegalMove(PieceColor pieceColor) {
public boolean checkAvailableLegalMove(PieceColor pieceColor, GameState gameState) {
BitSet checkAvailableMoveBitBoard = board.getBitBoard(pieceColor);

if (checkAvailableMoveBitBoard.isEmpty()) return true;

if (whitePlayer.getTotalNumberOfPieces() < 3 || blackPlayer.getTotalNumberOfPieces() < 3) return false;

boolean[] availableMoves = new boolean[checkAvailableMoveBitBoard.size()];

for (int i = 0; i < checkAvailableMoveBitBoard.size(); i++) {
if (gameState.getGameStates().peek() == State.FIRST_PHASE && board.isEmptyPoint(i)) return true;

if (checkAvailableMoveBitBoard.get(i)) {
ArrayList<Integer> verticalPositionSet = pointsPosition.getVerticalSet(i);
ArrayList<Integer> horizontalPositionSet = pointsPosition.getHorizontalSet(i);
Expand Down Expand Up @@ -187,14 +190,14 @@ public boolean checkAvailableLegalMove(PieceColor pieceColor) {
horizontalMoveAvailable = board.isEmptyPoint(horizontalPositionSet.get(currentHorizontalIndex - 1));
}

availableMoves[i] = horizontalMoveAvailable || verticalMoveAvailable;
if (horizontalMoveAvailable || verticalMoveAvailable) return true;
}
}

// If one move is available then return true
for (boolean value : availableMoves) {
if (value) return true;
}
//for (boolean value : availableMoves) {
// if (value) return true;
//}

return false;
}
Expand Down
11 changes: 4 additions & 7 deletions core/src/com/groupg/game/GameState.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public boolean getCurrentTurn() {
}

public void firstPhase(Player player) {
if (gameRule.checkAvailableLegalMove(player.getPieceColor())) {
if (gameRule.checkAvailableLegalMove(player.getPieceColor(), this)) {
if (!player.maxNumberPlayed()) {
if (board.addPiece(player.getPieceColor(), player.getTouchPosition())) {
player.addPiece();
Expand All @@ -90,10 +90,7 @@ public void firstPhase(Player player) {
}

public void secondPhase(Player player) {
// If either player gotten less than 3 pieces then the game ends
if (gameRule.checkAvailableLegalMove(player.getPieceColor())
&& (whitePlayer.getCurrentNumberOfPieces() >= 3
&& blackPlayer.getCurrentNumberOfPieces() >= 3)) {
if (gameRule.checkAvailableLegalMove(player.getPieceColor(), this)) {
player.setSelectedPiece(board.getSelectPiece(player.getPieceColor(), player.getTouchPosition()));
if (player.getSelectedPiece() != null) {
gameStates.push(State.MOVE);
Expand Down Expand Up @@ -127,9 +124,9 @@ public void captureState(Player player) {
}

public void finishState() {
if (whitePlayer.getCurrentNumberOfPieces() < 3 || gameRule.checkAvailableLegalMove(whitePlayer.getPieceColor())) {
if (whitePlayer.getCurrentNumberOfPieces() < 3 || gameRule.checkAvailableLegalMove(whitePlayer.getPieceColor(), this)) {
winTexture = new Texture(Gdx.files.internal("Black_Player_Won.png"));
} else if (blackPlayer.getCurrentNumberOfPieces() < 3 || gameRule.checkAvailableLegalMove(blackPlayer.getPieceColor())) {
} else if (blackPlayer.getCurrentNumberOfPieces() < 3 || gameRule.checkAvailableLegalMove(blackPlayer.getPieceColor(), this)) {
winTexture = new Texture(Gdx.files.internal("White_Player_Won.png.png"));
}
}
Expand Down
51 changes: 51 additions & 0 deletions core/src/com/groupg/game/ai/Evaluation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.groupg.game.ai;

import com.groupg.game.board.Board;
import com.groupg.game.board.PointsPosition;
import com.groupg.game.gameobject.PieceColor;

public class Evaluation {
private int evaluation;
private int positionEvaluated;
private Board board;

public Evaluation() {
}

public Evaluation(int evaluation, Board board) {
this.evaluation = evaluation;
this.board = board;
}

public int getEvaluation() {
return evaluation;
}

public void setEvaluation(int evaluation) {
this.evaluation = evaluation;
}

public int getPositionEvaluated() {
return positionEvaluated;
}

public void setPositionEvaluated(int positionEvaluated) {
this.positionEvaluated = positionEvaluated;
}

public Board getBoard() {
return board;
}

public void setBoard(Board board) {
this.board = board;
}

public int getAddedPiece(Board board) {
for (int i = 0; i < PointsPosition.NUMBER_OF_POINTS; i++) {
if (this.board.getBitBoard(PieceColor.BLACK).get(i) != board.getBitBoard(PieceColor.BLACK).get(i)) return i;
}

return -1;
}
}
80 changes: 80 additions & 0 deletions core/src/com/groupg/game/ai/GenerateMove.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.groupg.game.ai;

import com.groupg.game.board.Board;
import com.groupg.game.board.PointsPosition;
import com.groupg.game.gameobject.PieceColor;

import java.util.ArrayList;
import java.util.BitSet;

public class GenerateMove {
public static ArrayList<Board> getMidPhasePossibleStates(Board currentBoardState, boolean isMaximizer) {
ArrayList<Board> possibleBoardStates = new ArrayList<>();

for (int i = 0; i < PointsPosition.NUMBER_OF_POINTS; i++) {
if (isMaximizer) {

}
}
return null;
}

public static ArrayList<Board> getOpeningPhasePossibleStates(Board currentBoardState, boolean isMaximizer) {
ArrayList<Board> possibleBoardStates = new ArrayList<>();

for (int i = 0; i < PointsPosition.NUMBER_OF_POINTS; i++) {
if (currentBoardState.isEmptyPoint(i)) {
Board copyCurrentBoard = currentBoardState.getCopy();

if (isMaximizer) {
copyCurrentBoard.setPositionValue(PieceColor.BLACK, i);
if (PointsPosition.checkMill(i, copyCurrentBoard.getBitBoard(PieceColor.BLACK))) {
possibleBoardStates = (getAllRemoveStates(copyCurrentBoard, possibleBoardStates, true));
} else {
possibleBoardStates.add(copyCurrentBoard);
}
} else {
copyCurrentBoard.setPositionValue(PieceColor.WHITE, i);
if (PointsPosition.checkMill(i, copyCurrentBoard.getBitBoard(PieceColor.WHITE))) {
possibleBoardStates = (getAllRemoveStates(copyCurrentBoard, possibleBoardStates, false));
} else {
possibleBoardStates.add(copyCurrentBoard);
}
}
}
}
return possibleBoardStates;
}

private static ArrayList<Board> getAllRemoveStates(Board boardCopy, ArrayList<Board> boardStates, boolean isMaximizer) {
for (int i = 0; i < PointsPosition.NUMBER_OF_POINTS; i++) {
Board newBoardCopy = boardCopy.getCopy();
if (checkCaptureValid(i, newBoardCopy, (isMaximizer) ? PieceColor.BLACK : PieceColor.WHITE)) {
boardStates.add(newBoardCopy);
}
}
return boardStates;
}

public static boolean checkCaptureValid(int capturePosition, Board boardCopy, PieceColor pieceColor) {
PieceColor capturedColor = (pieceColor == PieceColor.WHITE) ? PieceColor.BLACK : PieceColor.WHITE;
BitSet capturedBitBoard = boardCopy.getBitBoard(capturedColor);

boolean allPiecesMill = true;
for (int i = 0; i < capturedBitBoard.size(); i++) {
if (capturedBitBoard.get(i)) {
if (!PointsPosition.checkMill(i, capturedBitBoard)) {
allPiecesMill = false;
break;
}
}
}

if (capturePosition >= 0 && (allPiecesMill || !PointsPosition.checkMill(capturePosition, boardCopy.getBitBoard(capturedColor))) && capturedBitBoard.get(capturePosition)) {
capturedBitBoard.clear(capturePosition);
return true;
}

return false;
}
}
Loading

0 comments on commit 510e3f7

Please sign in to comment.