Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ee.taltech.iti0202.gomoku.strategy;
- import ee.taltech.iti0202.gomoku.game.Location;
- import ee.taltech.iti0202.gomoku.game.SimpleBoard;
- import ee.taltech.iti0202.gomoku.opponent.ComputerStrategy;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Random;
- /**
- * Important!
- * This is an example strategy class.
- * You should not overwrite this.
- * Instead make your own class, for example:
- * public class AgoStrategy implements ComputerStrategy
- * <p>
- * and add all the logic there. The created strategy
- * should be visible under player selection automatically.
- * <p>
- * This file here might be overwritten in future versions.
- */
- public class StudentStrategyMihail implements ComputerStrategy {
- private BetterBoard lastBoard;
- private int friendlyAI;
- private int enemyAI;
- private int[][] map;
- private int height;
- private int width;
- private static final long[] scoresV2 = {1, 50, 2500, 125000, 6250000, 312500000};
- private static int maxDepth = 2;
- private int[] friendlyThreats;
- private int[] enemyThreats;
- @Override
- public Location getMove(SimpleBoard board, int player) {
- // let's operate on 2-d array
- map = new int[board.getHeight()][board.getWidth()];
- friendlyAI = player;
- enemyAI = player * -1;
- height = width = board.getHeight();
- lastBoard = new BetterBoard(board.getBoard());
- Random randomGenerator = new Random();
- randomGenerator.ints(0, board.getWidth());
- minMax(lastBoard, 0, friendlyAI, new Location(0, 0));
- Location bestMove = getBestMove();
- System.out.println("BEST MOVE" + bestMove);
- return new Location(bestMove.getRow(), bestMove.getColumn());
- }
- private int minMax(BetterBoard board, int depth, int player, Location curMove) {
- int status = getMoveScore(board, curMove);
- if (depth == maxDepth) {
- return status;
- } else if (status == Integer.MAX_VALUE || status == Integer.MIN_VALUE) {
- return status;
- }
- int[][] localMap = new int[height][width];
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- if (board.getBoard()[i][j] == SimpleBoard.EMPTY) {
- BetterBoard newBoard = getBoardCopy(board);
- newBoard.getBoard()[i][j] = player;
- localMap[i][j] = minMax(newBoard, depth + 1, player * -1, new Location(i, j));
- } else {
- if (player == friendlyAI) {
- localMap[i][j] = Integer.MIN_VALUE;
- } else {
- localMap[i][j] = Integer.MAX_VALUE;
- }
- }
- }
- }
- map = localMap;
- if (player == friendlyAI) {
- return maxFrom2dArr(localMap);
- } else {
- return minFrom2dArr(localMap);
- }
- }
- private void print2dArr(int[][] arr) {
- System.out.println("PRINTING 2D ARRAY");
- for (int[] ints : arr) {
- for (int anInt : ints) {
- if (anInt == Integer.MIN_VALUE) {
- System.out.print(String.format("%11s", "[-]"));
- } else {
- System.out.print(String.format("%11d", anInt));
- }
- }
- System.out.print("\n");
- }
- }
- private BetterBoard getBoardCopy(BetterBoard board) {
- int[][] newIntArrBoard = new int[board.getHeight()][board.getHeight()];
- for (int k = 0; k < board.getHeight(); k++) {
- for (int l = 0; l < board.getWidth(); l++) {
- newIntArrBoard[k][l] = board.getLocation(k, l);
- }
- }
- return new BetterBoard(newIntArrBoard);
- }
- private Location getBestMove() {
- int curMax = Integer.MIN_VALUE;
- int curMaxRow = 0;
- int curMaxColumn = 0;
- for (int i = 0; i < map.length; i++) {
- for (int j = 0; j < map[i].length; j++) {
- if (map[i][j] >= curMax) {
- if (lastBoard.getLocation(i, j) == SimpleBoard.EMPTY) {
- curMax = map[i][j];
- curMaxRow = i;
- curMaxColumn = j;
- }
- }
- }
- }
- return new Location(curMaxRow, curMaxColumn);
- }
- private int minFrom2dArr(int[][] arr) {
- int curMin = Integer.MAX_VALUE;
- for (int[] ints : arr) {
- for (int anInt : ints) {
- curMin = Math.min(curMin, anInt);
- }
- }
- return curMin;
- }
- private int maxFrom2dArr(int[][] arr) {
- int curMax = Integer.MIN_VALUE;
- for (int[] ints : arr) {
- for (int anInt : ints) {
- curMax = Math.max(curMax, anInt);
- }
- }
- return curMax;
- }
- @Override
- public String getName() {
- return "Mihail Smirnov ja Aleksei Born-to-Kill";
- }
- private int getProperSide(int player, int value) {
- if (player == enemyAI && value == Integer.MAX_VALUE) {
- return Integer.MIN_VALUE;
- } else {
- return value;
- }
- }
- /**
- * 1 You won
- * -1 Opponent won
- * 0 OpenGame
- */
- private int getMoveScore(BetterBoard board, Location curTurn) {
- friendlyThreats = new int[6];
- enemyThreats = new int[6];
- int curColor = board.getFromLocation(curTurn);
- if (curColor == SimpleBoard.EMPTY) {
- return 0;
- }
- // check a vertical direction:
- checkVerticals(board);
- // check a horizontal direction:
- checkHorizontal(board);
- // diagonal upper-right to down-left:
- checkDiagonal7H(board);
- // diagonal upper-left to down-right
- checkDiagonal4H(board);
- int totalScore = 0;
- for (int i = 5; i > 0; i--) {
- int delimiter = enemyThreats[i - 1] / 2;
- enemyThreats[i] += delimiter;
- enemyThreats[i - 1] -= delimiter * 2;
- int delimiterFriendly = friendlyThreats[i - 1] / 2;
- if (friendlyThreats[i] - delimiterFriendly > enemyThreats[i]){
- friendlyThreats[i] += delimiterFriendly;
- friendlyThreats[i - 1] -= delimiterFriendly * 2;
- }
- }
- for (int i = 5; i >= 0; i--) {
- totalScore -= enemyThreats[i] * scoresV2[i];
- totalScore += friendlyThreats[i] * scoresV2[i];
- }
- return getProperSide(curColor, totalScore);
- }
- private void checkLine(int[] line) {
- if (line.length < 5) {
- return;
- }
- int startIndex = 0;
- int counter = 0;
- int lastPoint = -2;
- int beforeStart = -2;
- for (int i = 0; i < line.length; i++) {
- // first player on the line
- // n in the row
- if (line[startIndex] == line[i] && counter != 0) {
- counter++;
- } else if (line[i] != 0 && counter == 0) {
- beforeStart = lastPoint;
- startIndex = i;
- counter = 1;
- }
- // player change
- if (counter != 0 && (line[i] == line[startIndex] * -1 || (line[i] == 0) || i == line.length - 1)) {
- if (has5inRow(line, startIndex)) {
- if (line[startIndex] == friendlyAI) {
- addThreats(beforeStart, line[i], counter, line[startIndex]);
- } else if (line[startIndex] == enemyAI) {
- addThreats(beforeStart, line[i], counter, line[startIndex]);
- }
- }
- if (line[i] != 0) {
- beforeStart = lastPoint;
- startIndex = i;
- counter = 1;
- } else {
- beforeStart = 0;
- counter = 0;
- }
- }
- lastPoint = line[i];
- }
- }
- private boolean has5inRow(int[] line, int start) {
- // TODO make in count only right way
- int player = line[start];
- int counter = 0;
- for (int i = start; i < line.length; i++) {
- if (line[i] != player * -1) {
- counter++;
- } else {
- break;
- }
- }
- for (int i = start - 1; i >= 0; i--) {
- if (line[i] != player * -1) {
- counter++;
- } else {
- break;
- }
- }
- return counter >= 5;
- }
- private void addThreats(int start, int end, int counter, int player) {
- int threat = 0;
- int openSides = countOpenSides(start, end);
- if (counter == 1 && openSides == 2){
- threat = 1;
- }
- if (counter == 2 && openSides == 2) {
- threat = 2;
- } else if (counter == 2) {
- threat = 1;
- }
- if (counter == 3 && openSides == 2) {
- threat = 3;
- } else if (counter == 3) {
- threat = 2;
- }
- if (counter == 4 && openSides == 2) {
- threat = 4;
- } else if (counter == 4) {
- threat = 3;
- }
- if (counter == 5) {
- threat = 5;
- }
- if (player == friendlyAI) {
- friendlyThreats[threat]++;
- } else if (player == enemyAI) {
- enemyThreats[threat]++;
- }
- }
- private int countOpenSides(int start, int end) {
- int result = 0;
- if (start == 0) {
- result += 1;
- }
- if (end == 0) {
- result += 1;
- }
- return result;
- }
- private void checkVerticals(BetterBoard board) {
- for (int i = 0; i < height; i++) {
- int[] curLine = new int[height];
- for (int j = 0; j < width; j++) {
- curLine[j] = board.getBoard()[j][i];
- }
- checkLine(curLine);
- }
- }
- // int[] curLine = new int[10];
- // curLine[j] = board.getBoard()[j][i];
- // checkLine(curLine);
- private void checkHorizontal(BetterBoard board) {
- for (int i = 0; i < height; i++) {
- int[] curLine = new int[height];
- for (int j = 0; j < width; j++) {
- curLine[j] = board.getBoard()[i][j];
- }
- checkLine(curLine);
- }
- }
- private void checkDiagonal4H(BetterBoard board) {
- for (int i = 0; i < height; i++) {
- ArrayList<Integer> curLine = new ArrayList<>();
- for (int j = 0; j < width; j++) {
- if (i + j < height) {
- curLine.add(board.getBoard()[i + j][j]);
- } else {
- break;
- }
- }
- int[] primitive = curLine.stream()
- .mapToInt(Integer::intValue)
- .toArray();
- checkLine(primitive);
- }
- for (int i = 1; i < height; i++) {
- ArrayList<Integer> curLine = new ArrayList<>();
- for (int j = 0; j < width; j++) {
- if (i + j < height) {
- curLine.add(board.getBoard()[j][j + i]);
- } else {
- break;
- }
- }
- int[] primitive = curLine.stream()
- .mapToInt(Integer::intValue)
- .toArray();
- checkLine(primitive);
- }
- }
- private void checkDiagonal7H(BetterBoard board) {
- for (int i = 0; i < height; i++) {
- ArrayList<Integer> curLine = new ArrayList<>();
- for (int j = 0; j < width; j++) {
- if (i - j >= 0) {
- curLine.add(board.getBoard()[i - j][j]);
- } else {
- break;
- }
- }
- int[] primitive = curLine.stream()
- .mapToInt(Integer::intValue)
- .toArray();
- checkLine(primitive);
- }
- for (int i = 0; i < height - 1; i++) {
- ArrayList<Integer> curLine = new ArrayList<>();
- for (int j = 1; j < height; j++) {
- if (i + j <= height - 1) {
- curLine.add(board.getBoard()[height - j][i + j]);
- } else {
- break;
- }
- }
- int[] primitive = curLine.stream()
- .mapToInt(Integer::intValue)
- .toArray();
- checkLine(primitive);
- }
- }
- }
- class BetterBoard extends SimpleBoard {
- /**
- * Constructor to instantiate the board.
- *
- * @param simpleBoard 2-dimensional
- * array for the board.
- */
- BetterBoard(int[][] simpleBoard) {
- super(simpleBoard);
- }
- int getFromLocation(Location location) {
- return this.getBoard()[location.getRow()][location.getColumn()];
- }
- @Override
- public String toString() {
- StringBuilder toReturn = new StringBuilder();
- toReturn.append("Board State:\n");
- for (int i = 0; i < getWidth(); i++) {
- for (int j = 0; j < getHeight(); j++) {
- toReturn.append("[").append(getBoard()[i][j]).append("]");
- }
- toReturn.append("\n");
- }
- return String.valueOf(toReturn);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement