Advertisement
Guest User

Untitled

a guest
May 19th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.58 KB | None | 0 0
  1. package ee.taltech.iti0202.gomoku.strategy;
  2.  
  3. import ee.taltech.iti0202.gomoku.game.Location;
  4. import ee.taltech.iti0202.gomoku.game.SimpleBoard;
  5. import ee.taltech.iti0202.gomoku.opponent.ComputerStrategy;
  6.  
  7. import java.util.ArrayList;
  8. import java.util.Arrays;
  9. import java.util.Random;
  10.  
  11. /**
  12. * Important!
  13. * This is an example strategy class.
  14. * You should not overwrite this.
  15. * Instead make your own class, for example:
  16. * public class AgoStrategy implements ComputerStrategy
  17. * <p>
  18. * and add all the logic there. The created strategy
  19. * should be visible under player selection automatically.
  20. * <p>
  21. * This file here might be overwritten in future versions.
  22. */
  23. public class StudentStrategyMihail implements ComputerStrategy {
  24. private BetterBoard lastBoard;
  25. private int friendlyAI;
  26. private int enemyAI;
  27. private int[][] map;
  28. private int height;
  29. private int width;
  30. private static final long[] scoresV2 = {1, 50, 2500, 125000, 6250000, 312500000};
  31. private static int maxDepth = 2;
  32. private int[] friendlyThreats;
  33. private int[] enemyThreats;
  34.  
  35. @Override
  36. public Location getMove(SimpleBoard board, int player) {
  37. // let's operate on 2-d array
  38. map = new int[board.getHeight()][board.getWidth()];
  39. friendlyAI = player;
  40. enemyAI = player * -1;
  41. height = width = board.getHeight();
  42. lastBoard = new BetterBoard(board.getBoard());
  43.  
  44. Random randomGenerator = new Random();
  45. randomGenerator.ints(0, board.getWidth());
  46.  
  47.  
  48. minMax(lastBoard, 0, friendlyAI, new Location(0, 0));
  49. Location bestMove = getBestMove();
  50. System.out.println("BEST MOVE" + bestMove);
  51.  
  52. return new Location(bestMove.getRow(), bestMove.getColumn());
  53. }
  54.  
  55. private int minMax(BetterBoard board, int depth, int player, Location curMove) {
  56.  
  57. int status = getMoveScore(board, curMove);
  58. if (depth == maxDepth) {
  59. return status;
  60. } else if (status == Integer.MAX_VALUE || status == Integer.MIN_VALUE) {
  61. return status;
  62. }
  63.  
  64. int[][] localMap = new int[height][width];
  65. for (int i = 0; i < height; i++) {
  66. for (int j = 0; j < width; j++) {
  67. if (board.getBoard()[i][j] == SimpleBoard.EMPTY) {
  68. BetterBoard newBoard = getBoardCopy(board);
  69. newBoard.getBoard()[i][j] = player;
  70. localMap[i][j] = minMax(newBoard, depth + 1, player * -1, new Location(i, j));
  71.  
  72. } else {
  73. if (player == friendlyAI) {
  74. localMap[i][j] = Integer.MIN_VALUE;
  75. } else {
  76. localMap[i][j] = Integer.MAX_VALUE;
  77. }
  78. }
  79. }
  80. }
  81. map = localMap;
  82. if (player == friendlyAI) {
  83. return maxFrom2dArr(localMap);
  84. } else {
  85. return minFrom2dArr(localMap);
  86. }
  87. }
  88.  
  89. private void print2dArr(int[][] arr) {
  90. System.out.println("PRINTING 2D ARRAY");
  91. for (int[] ints : arr) {
  92. for (int anInt : ints) {
  93. if (anInt == Integer.MIN_VALUE) {
  94. System.out.print(String.format("%11s", "[-]"));
  95.  
  96. } else {
  97. System.out.print(String.format("%11d", anInt));
  98. }
  99. }
  100. System.out.print("\n");
  101. }
  102. }
  103.  
  104. private BetterBoard getBoardCopy(BetterBoard board) {
  105. int[][] newIntArrBoard = new int[board.getHeight()][board.getHeight()];
  106. for (int k = 0; k < board.getHeight(); k++) {
  107. for (int l = 0; l < board.getWidth(); l++) {
  108. newIntArrBoard[k][l] = board.getLocation(k, l);
  109. }
  110. }
  111. return new BetterBoard(newIntArrBoard);
  112. }
  113.  
  114. private Location getBestMove() {
  115. int curMax = Integer.MIN_VALUE;
  116. int curMaxRow = 0;
  117. int curMaxColumn = 0;
  118.  
  119. for (int i = 0; i < map.length; i++) {
  120. for (int j = 0; j < map[i].length; j++) {
  121. if (map[i][j] >= curMax) {
  122. if (lastBoard.getLocation(i, j) == SimpleBoard.EMPTY) {
  123. curMax = map[i][j];
  124. curMaxRow = i;
  125. curMaxColumn = j;
  126. }
  127. }
  128. }
  129. }
  130. return new Location(curMaxRow, curMaxColumn);
  131. }
  132.  
  133.  
  134. private int minFrom2dArr(int[][] arr) {
  135. int curMin = Integer.MAX_VALUE;
  136. for (int[] ints : arr) {
  137. for (int anInt : ints) {
  138. curMin = Math.min(curMin, anInt);
  139. }
  140. }
  141. return curMin;
  142. }
  143.  
  144. private int maxFrom2dArr(int[][] arr) {
  145. int curMax = Integer.MIN_VALUE;
  146. for (int[] ints : arr) {
  147. for (int anInt : ints) {
  148. curMax = Math.max(curMax, anInt);
  149. }
  150. }
  151. return curMax;
  152. }
  153.  
  154.  
  155. @Override
  156. public String getName() {
  157. return "Mihail Smirnov ja Aleksei Born-to-Kill";
  158. }
  159.  
  160.  
  161. private int getProperSide(int player, int value) {
  162. if (player == enemyAI && value == Integer.MAX_VALUE) {
  163. return Integer.MIN_VALUE;
  164. } else {
  165. return value;
  166. }
  167. }
  168.  
  169.  
  170. /**
  171. * 1 You won
  172. * -1 Opponent won
  173. * 0 OpenGame
  174. */
  175. private int getMoveScore(BetterBoard board, Location curTurn) {
  176. friendlyThreats = new int[6];
  177. enemyThreats = new int[6];
  178. int curColor = board.getFromLocation(curTurn);
  179. if (curColor == SimpleBoard.EMPTY) {
  180. return 0;
  181. }
  182.  
  183. // check a vertical direction:
  184. checkVerticals(board);
  185.  
  186. // check a horizontal direction:
  187. checkHorizontal(board);
  188.  
  189. // diagonal upper-right to down-left:
  190. checkDiagonal7H(board);
  191.  
  192. // diagonal upper-left to down-right
  193. checkDiagonal4H(board);
  194.  
  195. int totalScore = 0;
  196.  
  197. for (int i = 5; i > 0; i--) {
  198. int delimiter = enemyThreats[i - 1] / 2;
  199. enemyThreats[i] += delimiter;
  200. enemyThreats[i - 1] -= delimiter * 2;
  201.  
  202. int delimiterFriendly = friendlyThreats[i - 1] / 2;
  203. if (friendlyThreats[i] - delimiterFriendly > enemyThreats[i]){
  204. friendlyThreats[i] += delimiterFriendly;
  205. friendlyThreats[i - 1] -= delimiterFriendly * 2;
  206. }
  207.  
  208. }
  209. for (int i = 5; i >= 0; i--) {
  210. totalScore -= enemyThreats[i] * scoresV2[i];
  211. totalScore += friendlyThreats[i] * scoresV2[i];
  212. }
  213.  
  214.  
  215. return getProperSide(curColor, totalScore);
  216. }
  217.  
  218. private void checkLine(int[] line) {
  219. if (line.length < 5) {
  220. return;
  221. }
  222.  
  223. int startIndex = 0;
  224. int counter = 0;
  225. int lastPoint = -2;
  226. int beforeStart = -2;
  227.  
  228. for (int i = 0; i < line.length; i++) {
  229.  
  230. // first player on the line
  231. // n in the row
  232. if (line[startIndex] == line[i] && counter != 0) {
  233. counter++;
  234. } else if (line[i] != 0 && counter == 0) {
  235. beforeStart = lastPoint;
  236. startIndex = i;
  237. counter = 1;
  238. }
  239.  
  240. // player change
  241. if (counter != 0 && (line[i] == line[startIndex] * -1 || (line[i] == 0) || i == line.length - 1)) {
  242. if (has5inRow(line, startIndex)) {
  243. if (line[startIndex] == friendlyAI) {
  244. addThreats(beforeStart, line[i], counter, line[startIndex]);
  245. } else if (line[startIndex] == enemyAI) {
  246. addThreats(beforeStart, line[i], counter, line[startIndex]);
  247. }
  248. }
  249.  
  250. if (line[i] != 0) {
  251. beforeStart = lastPoint;
  252. startIndex = i;
  253. counter = 1;
  254. } else {
  255. beforeStart = 0;
  256. counter = 0;
  257. }
  258. }
  259.  
  260. lastPoint = line[i];
  261. }
  262. }
  263.  
  264. private boolean has5inRow(int[] line, int start) {
  265. // TODO make in count only right way
  266. int player = line[start];
  267. int counter = 0;
  268. for (int i = start; i < line.length; i++) {
  269. if (line[i] != player * -1) {
  270. counter++;
  271. } else {
  272. break;
  273. }
  274. }
  275. for (int i = start - 1; i >= 0; i--) {
  276. if (line[i] != player * -1) {
  277. counter++;
  278. } else {
  279. break;
  280. }
  281. }
  282. return counter >= 5;
  283. }
  284.  
  285. private void addThreats(int start, int end, int counter, int player) {
  286. int threat = 0;
  287. int openSides = countOpenSides(start, end);
  288.  
  289. if (counter == 1 && openSides == 2){
  290. threat = 1;
  291. }
  292.  
  293. if (counter == 2 && openSides == 2) {
  294. threat = 2;
  295. } else if (counter == 2) {
  296. threat = 1;
  297. }
  298.  
  299. if (counter == 3 && openSides == 2) {
  300. threat = 3;
  301. } else if (counter == 3) {
  302. threat = 2;
  303. }
  304.  
  305. if (counter == 4 && openSides == 2) {
  306. threat = 4;
  307. } else if (counter == 4) {
  308. threat = 3;
  309. }
  310.  
  311. if (counter == 5) {
  312. threat = 5;
  313. }
  314.  
  315. if (player == friendlyAI) {
  316. friendlyThreats[threat]++;
  317. } else if (player == enemyAI) {
  318. enemyThreats[threat]++;
  319. }
  320. }
  321.  
  322. private int countOpenSides(int start, int end) {
  323. int result = 0;
  324. if (start == 0) {
  325. result += 1;
  326. }
  327. if (end == 0) {
  328. result += 1;
  329. }
  330. return result;
  331. }
  332.  
  333. private void checkVerticals(BetterBoard board) {
  334. for (int i = 0; i < height; i++) {
  335. int[] curLine = new int[height];
  336. for (int j = 0; j < width; j++) {
  337. curLine[j] = board.getBoard()[j][i];
  338. }
  339. checkLine(curLine);
  340. }
  341. }
  342.  
  343. // int[] curLine = new int[10];
  344. // curLine[j] = board.getBoard()[j][i];
  345. // checkLine(curLine);
  346.  
  347. private void checkHorizontal(BetterBoard board) {
  348. for (int i = 0; i < height; i++) {
  349. int[] curLine = new int[height];
  350. for (int j = 0; j < width; j++) {
  351. curLine[j] = board.getBoard()[i][j];
  352. }
  353. checkLine(curLine);
  354. }
  355. }
  356.  
  357. private void checkDiagonal4H(BetterBoard board) {
  358. for (int i = 0; i < height; i++) {
  359. ArrayList<Integer> curLine = new ArrayList<>();
  360. for (int j = 0; j < width; j++) {
  361. if (i + j < height) {
  362. curLine.add(board.getBoard()[i + j][j]);
  363. } else {
  364. break;
  365. }
  366. }
  367.  
  368. int[] primitive = curLine.stream()
  369. .mapToInt(Integer::intValue)
  370. .toArray();
  371. checkLine(primitive);
  372.  
  373. }
  374.  
  375. for (int i = 1; i < height; i++) {
  376. ArrayList<Integer> curLine = new ArrayList<>();
  377. for (int j = 0; j < width; j++) {
  378. if (i + j < height) {
  379. curLine.add(board.getBoard()[j][j + i]);
  380. } else {
  381. break;
  382. }
  383. }
  384. int[] primitive = curLine.stream()
  385. .mapToInt(Integer::intValue)
  386. .toArray();
  387. checkLine(primitive);
  388. }
  389. }
  390.  
  391. private void checkDiagonal7H(BetterBoard board) {
  392. for (int i = 0; i < height; i++) {
  393. ArrayList<Integer> curLine = new ArrayList<>();
  394. for (int j = 0; j < width; j++) {
  395. if (i - j >= 0) {
  396. curLine.add(board.getBoard()[i - j][j]);
  397. } else {
  398. break;
  399. }
  400. }
  401. int[] primitive = curLine.stream()
  402. .mapToInt(Integer::intValue)
  403. .toArray();
  404. checkLine(primitive);
  405. }
  406.  
  407.  
  408. for (int i = 0; i < height - 1; i++) {
  409. ArrayList<Integer> curLine = new ArrayList<>();
  410. for (int j = 1; j < height; j++) {
  411. if (i + j <= height - 1) {
  412. curLine.add(board.getBoard()[height - j][i + j]);
  413. } else {
  414. break;
  415. }
  416. }
  417.  
  418. int[] primitive = curLine.stream()
  419. .mapToInt(Integer::intValue)
  420. .toArray();
  421. checkLine(primitive);
  422. }
  423. }
  424. }
  425.  
  426.  
  427. class BetterBoard extends SimpleBoard {
  428.  
  429. /**
  430. * Constructor to instantiate the board.
  431. *
  432. * @param simpleBoard 2-dimensional
  433. * array for the board.
  434. */
  435. BetterBoard(int[][] simpleBoard) {
  436. super(simpleBoard);
  437. }
  438.  
  439. int getFromLocation(Location location) {
  440. return this.getBoard()[location.getRow()][location.getColumn()];
  441. }
  442.  
  443. @Override
  444. public String toString() {
  445. StringBuilder toReturn = new StringBuilder();
  446. toReturn.append("Board State:\n");
  447. for (int i = 0; i < getWidth(); i++) {
  448. for (int j = 0; j < getHeight(); j++) {
  449. toReturn.append("[").append(getBoard()[i][j]).append("]");
  450. }
  451. toReturn.append("\n");
  452. }
  453. return String.valueOf(toReturn);
  454. }
  455. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement