@Override public String getNextAction(int[] grid, int _playerNumber) { String ret = "X"; // as fallback, make a random move playerNumber = _playerNumber; // now try to come up with something more clever long startTime = new Date().getTime(); situations = 0; IAICallback logCallBack = new IAICallback() { @Override public void callback(String message) { System.out.println(message); } }; int opponentNumber = playerNumber - 1; if (opponentNumber == 0) { opponentNumber = 2; } Situation rootSituation = new Situation(-1, opponentNumber, grid, 0, null); bestSituation = rootSituation; // may never be null! rootSituation.callback = logCallBack; rootSituation.computeNextSituations(TREE_DEPTH); long timePassed = new Date().getTime() - startTime; double seconds = (double) timePassed / 1000.0; double sps = (double) situations / seconds; System.out.println( "computed " + situations + " situation in " + timePassed + "ms: " + sps + " situations per second."); // found something! if (bestSituation._parentSituation != null && bestSituation._parentSituation._followingSituationsAreWins != 0) { ret = getNextStepToSituation(bestSituation); } else { System.out.println("Couldn't find any good moves... spamming random move."); ret = computeRandomAction(); } return ret; }
public void computeNextSituations(int maxOrder_) { if (_order >= maxOrder_) { return; } int nextPlayer = _playerNumberMadeThisMove == 1 ? 2 : 1; // check all possible actions for (int col = 0; col < AITools.GRID_COLUMNS; col++) { if (callback != null) { callback.callback("beginning col " + col); } // next free row for this column int nextFreeIndex = AITools.coordsToIndex(col, AITools.GRID_ROWS - 1); while (_grid[nextFreeIndex] != 0) { nextFreeIndex = AITools.getGridIndexOnTopOf(nextFreeIndex); if (nextFreeIndex < 0) // can't throw in this row. no possible situation { break; } } if (nextFreeIndex < 0) // can't throw in this row. no possible situation { continue; } // copy grid and apply new action int[] newGrid = _grid.clone(); newGrid[nextFreeIndex] = nextPlayer; if (_nextSituations == null) { _nextSituations = new ArrayList<Situation>(); } Situation newSituation = new Situation(col, nextPlayer, newGrid, _order + 1, this); _nextSituations.add(newSituation); newSituation._score = 0; int gameStatus = AITools.getGameStatus(newGrid); // compute follow Situations only if not a an end point if (gameStatus == -1) { newSituation.computeNextSituations(maxOrder_); } else if (gameStatus == playerNumber) { this._followingSituationsAreWins++; // check: if this situation has the order 1 (next move) and is a win, then take it! if (newSituation._order == 1) { bestSituation = newSituation; System.out.println("TAKE THE WIN: next move will finish match!"); AITools.visualizeGrid(newGrid); break; } if (bestSituation._parentSituation == null || this._followingSituationsAreWins > bestSituation._parentSituation._followingSituationsAreWins) { // safety check: up to that situation, there may be no situation where the opponent has // a winning chance! if (!thereIsASafePathToWin(newSituation)) { continue; } bestSituation = newSituation; System.out.println( "new best Situation with " + this._followingSituationsAreWins + " win chances with one piece."); AITools.visualizeGrid(newGrid); } } else if (gameStatus != 0) // not draw game -> opponent wins { this._followingSituationsAreLosses++; // System.out.println("found situation with score: " + newSituation._score); // AITools.visualizeGrid(newGrid); } } }