/** Returns value > 0 if lift is reachable. */ public static int liftReachable(Board board, int liftx, int lifty) { Cell up = board.get(liftx, lifty + 1); Cell down = board.get(liftx, lifty - 1); Cell left = board.get(liftx - 1, lifty); Cell right = board.get(liftx + 1, lifty); return cell2int(up) + cell2int(down) + cell2int(left) + cell2int(right); }
private void startGame() { int turn = 0; gameOver = false; board = new Board(BOARD_SIZE, BOARD_SIZE); // TODO clean up this logic while (!gameOver) { try { PlayerHandler currentPlayer = players.get(turn % MAX_PLAYERS); PlayerHandler otherPlayer = players.get((turn + 1) % MAX_PLAYERS); System.out.println("Notifying player " + currentPlayer.piece + " to make move"); currentPlayer.output.writeObject(true); System.out.println("Waiting for player " + currentPlayer.piece + " to make move"); GamePacket packet = (GamePacket) currentPlayer.input.readObject(); if (packet.getGamePiece() == currentPlayer.piece) { if (isValidMove(packet)) { currentPlayer.output.writeObject(false); currentPlayer.output.writeObject(packet); otherPlayer.output.writeObject(packet); System.out.println("Valid move"); if (board.isWinner(packet.getGamePiece())) { System.out.println("Player " + currentPlayer.piece + " wins!"); currentPlayer.output.writeObject("You Win Player " + currentPlayer.piece); otherPlayer.output.writeObject("You lose Player " + otherPlayer.piece); endGame(); } board.display(); turn++; if (turn == (BOARD_SIZE * BOARD_SIZE)) { for (PlayerHandler p : players) { p.output.writeObject("Tie Game!"); } endGame(); } } else { System.out.println("Invalid move"); } } else { System.out.println("Expected a move from " + currentPlayer.piece); } } catch (IOException ioex) { System.err.println("Error writing to player socket"); } catch (ClassNotFoundException cnfex) { System.err.println("Invalid object type found"); } } }
private boolean isValidMove(GamePacket packet) { char piece = packet.getGamePiece(); int x = packet.getxPos(); int y = packet.getyPos(); return board.insertPos(x, y, piece); }
public boolean step(Position to) { if (to.isNull()) { return false; } int tmpRow = super.position.getRow() - to.getRow(); int tmpColumn = super.position.getColumn() - to.getColumn(); boolean flag = (tmpRow == 0 || tmpColumn == 0); if (!Board.isEmpty(to)) { return flag && (Board.getColour(to) != super.getColour()); } return flag; }
@Override public Piece givePiece(Board board, Piece[] pieces) { List<Piece> nonWinning = new ArrayList<>(Arrays.asList(pieces)); Streak[] streaks = board.findStreaks(); for (Streak streak : streaks) { if (streak.getLength() == 3) { Piece streakPiece = new Piece(streak.getType()); // Remove matching from nonWinning list LinkedList<Piece> winning = new LinkedList<>(); for (Piece p : nonWinning) { if (Piece.getSimilarities(p, streakPiece) != 0) { winning.add(p); } } nonWinning.removeAll(winning); } } if (nonWinning.isEmpty()) { // System.out.println("Must give a winning piece"); return super.givePiece(board, pieces); } else { // System.out.println("Non winning piece"); return nonWinning.get(0); } }
/* * Creates a tree of moves to take with their evaluated scores */ public void createSearchSpace(int level, State state, Board board, boolean myTurn) { int[] openColumns = board.getOpenColumns(); state.nextMoves = new State[openColumns.length]; for (int i = 0; i < openColumns.length; i++) { int move = openColumns[i]; board.handleMove(myTurn, move); int score = heuristic.getScore(board); state.nextMoves[i] = new State(move, board, score); if (level != depth && board.hasWinner() == false) createSearchSpace(level + 1, state.nextMoves[i], board, !myTurn); board.undoMove(move); board.setHasWinner(false); } }
@Override public Board yourMove(Piece givenPiece, Board board, Piece[] piecesAvailable) { Streak[] streaks = board.findStreaks(); for (Streak streak : streaks) { if (streak.getLength() == 3 && Piece.getSimilarities(givenPiece, new Piece(streak.getType())) != 0) { // Place piece // Find free places int[] placeFree = new int[] {0, 1, 2, 3}; for (int i = 0; i < 4; i++) { Piece p = null; switch (streak.getOrientation()) { case HORIZONTAL: p = board.getPiece(streak.getNo(), i); break; case VERTICAL: p = board.getPiece(i, streak.getNo()); break; case DIAGONAL: if (streak.getNo() == 0) { p = board.getPiece(i, i); } else { p = board.getPiece(3 - i, i); } } if (p != null) { placeFree[i] = -1; } } for (int place : placeFree) { if (place >= 0) { if (streak.getOrientation() == Streak.Orientation.HORIZONTAL) { board.setPiece(streak.getNo(), place, givenPiece); } else if (streak.getOrientation() == Streak.Orientation.VERTICAL) { board.setPiece(place, streak.getNo(), givenPiece); } else { if (streak.getNo() == 0) { board.setPiece(place, place, givenPiece); } else { board.setPiece(3 - place, place, givenPiece); } } } } return board; } } return super.yourMove(givenPiece, board, piecesAvailable); }
private int controlBorders(int hv) { int heurVal = hv; for (int row = 2; row < Board.SIZE - 3; row++) { if (board.getField()[row][0] == myTile) { heurVal += 5; } if (board.getField()[row][Board.SIZE - 1] == myTile) { heurVal += 5; } } for (int col = 2; col < Board.SIZE - 3; col++) { if (board.getField()[0][col] == myTile) { heurVal += 5; } if (board.getField()[Board.SIZE - 1][col] == myTile) { heurVal += 5; } } return heurVal; }
private int getHeuristicalValue(int row, int col) { Tile tile = board.getTile(row, col); switch (tile) { case PLAYER1: return -1 * HEURISTICAL_VALUES[row][col]; case PLAYER2: return HEURISTICAL_VALUES[row][col]; default: return 0; } }
public int extraHV() { int heurVal = board.getPossiblePositions(myTile).size() * 3; if (heurVal == 0 && board.getPossiblePositions(myTile.getOpposite()).isEmpty()) { int myCount = 0, otherCount = 0; for (int row = 0; row < Board.SIZE; row++) { for (int col = 0; col < Board.SIZE; col++) { if (board.getField()[row][col] == myTile) { myCount++; } else if (board.getField()[row][col] == myTile.getOpposite()) { otherCount++; } } if (myCount - otherCount < 0) { return -10000; } else if (myCount - otherCount > 0) { return 10000; } } } heurVal += controlCorners(heurVal) + controlBorders(heurVal); return heurVal; }
public void setChilds() { int myRow, myCol; for (int row = 0; row < Board.SIZE; row++) { for (int col = 0; col < Board.SIZE; col++) { if (board.getTile(row, col) == myTile.getOpposite()) { for (Direction dir : Direction.values()) { myRow = row + dir.getRow(); myCol = col + dir.getCol(); if (!(myRow < 0 || myCol < 0 || myRow >= Board.SIZE || myCol >= Board.SIZE) && board.getTile(myRow, myCol) == Tile.EMPTY) { if (board.possibleChange(myRow, myCol, myTile, dir.getOpposite())) { childs.add( getNewChild( board.putTile(myRow, myCol, myTile.getOpposite()), new Position(myRow, myCol), myTile.getOpposite())); } } } } } } }
/* * Sets the white Pieces on the board */ private static void placeWhitePieces(PlayerSet whiteSet, Board board) { Space currentSpace = board.getSpace(Rank.One, File.A); Iterator<Piece> it = whiteSet.iterator(); // set the "first" row (Rank 1) of white pieces left to right currentSpace.changePiece(it.next()); for (int i = 0; i < 7; i++) { currentSpace = currentSpace.getSpaceRight(); currentSpace.changePiece(it.next()); } currentSpace = currentSpace.getSpaceForward(); // set the "second" row ("Rank 2) of white pieces from right to left for (int i = 0; i < 8; i++) { currentSpace.changePiece(it.next()); currentSpace = currentSpace.getSpaceLeft(); } }
/* * Sets the black pieces on the board */ private static void placeBlackPieces(PlayerSet blackSet, Board board) { Space currentSpace = board.getSpace(Rank.Eight, File.A); Iterator<Piece> it = blackSet.iterator(); // set the "first" row(Rank 8) of black pieces from left to right currentSpace.changePiece(it.next()); for (int i = 0; i < 7; i++) { currentSpace = currentSpace.getSpaceRight(); currentSpace.changePiece(it.next()); } currentSpace = currentSpace.getSpaceBackward(); // set the "second" row(Rank 7) of black pieces from right to left for (int i = 0; i < 8; i++) { currentSpace.changePiece(it.next()); currentSpace = currentSpace.getSpaceLeft(); } }
public void alphabetaTT(char[][] map, int d, double a, double b, boolean isHome, Move[] stack) { double ev_tem = 0; ev_tem = ev2(map, isHome); if (d == MAX_DEPTH || Math.abs(ev_tem) == MAX_SCORE) { stack[d].score = ev_tem; return; } Board board = new Board(map, isHome, "alphabetatt"); TTEntry tte = tt.getEntry(board.getHashKey()); if (tte != null && tte.getDepth() <= d) { if (tte.getType() == TTEntry.NT.EXACT) { stack[d].score = tte.getScore(); return; } if (tte.getType() == TTEntry.NT.LOWERBOUND && tte.getScore() > a) a = tte.getScore(); else if (tte.getType() == TTEntry.NT.UPPERBOUNT && tte.getScore() < b) b = tte.getScore(); if (a >= b) { stack[d].score = tte.getScore(); return; } } if (board.getSize() == 0) System.out.println(isHome + "\t" + d); Move move; if (isHome) { double v = Double.NEGATIVE_INFINITY; while (board.hasNext()) { if (FIRST_LAYER_DEBUG == 1 && d == 0) System.out.println("Home: 0 Total: " + board.getSize()); move = board.next(); map[move.row1][move.col1] = homeSym; map[move.row2][move.col2] = homeSym; if (d + 1 == MAX_DEPTH) { stack[d + 1].set(move.row1, move.col1, move.row2, move.col2); } alphabetaTT(map, d + 1, a, b, false, stack); if (stack[d + 1].score > v) { v = stack[d + 1].score; stack[d].set(move.row1, move.col1, move.row2, move.col2, v); } map[move.row1][move.col1] = emptySym; map[move.row2][move.col2] = emptySym; a = Math.max(a, stack[d].score); if (stack[d].score >= b || stack[d].score == MAX_SCORE) return; } if (stack[d].score < a) tt.store(new TTEntry(board.getHashKey(), stack[d].score, TTEntry.NT.LOWERBOUND, d)); else if (stack[d].score > b) tt.store(new TTEntry(board.getHashKey(), stack[d].score, TTEntry.NT.UPPERBOUNT, d)); return; } else { double v = Double.POSITIVE_INFINITY; while (board.hasNext()) { if (FIRST_LAYER_DEBUG == 1 && d == 0) System.out.println("Away: 0 Total: " + board.getSize()); move = board.next(); map[move.row1][move.col1] = awaySym; map[move.row2][move.col2] = awaySym; if (d + 1 == MAX_DEPTH) { stack[d + 1].set(move.row1, move.col1, move.row2, move.col2); } alphabetaTT(map, d + 1, a, b, true, stack); if (stack[d + 1].score < v) { v = stack[d + 1].score; stack[d].set(move.row1, move.col1, move.row2, move.col2, v); } map[move.row1][move.col1] = emptySym; map[move.row2][move.col2] = emptySym; b = Math.min(b, stack[d].score); if (stack[d].score <= a || stack[d].score == -MAX_SCORE) return; } if (stack[d].score < a) tt.store(new TTEntry(board.getHashKey(), stack[d].score, TTEntry.NT.LOWERBOUND, d)); else if (stack[d].score > b) tt.store(new TTEntry(board.getHashKey(), stack[d].score, TTEntry.NT.UPPERBOUNT, d)); return; } }
@Override public void run() { killermove = new int[Board.SIZE][2]; tt = new Transposition[TT_SIZE]; // Decay the history values for (int i = 0; i < 2; i++) { for (int j = 0; j < Board.SIZE; j++) { history[i][j] /= 2; bfboard[i][j] /= 2; } } // // endTime = 15000; // for testing // long lastItStartTime = 0, lastItTime = 0; int val = 0, alpha = N_INF, beta = P_INF; boolean wonlost = false; // int approxMovesMade = (Board.REAL_SIZE - initBoard.freeSquares) / 2; endTime = Math.max((initBoard.timeLeft() / (25 + approxMovesMade)), BASE_TIME); System.out.println(":: End time-span: " + endTime); // No need to search deep the first few moves if (initBoard.freeSquares >= 60) MAX_DEPTH = 8; else MAX_DEPTH = P_INF; // endTime += System.currentTimeMillis(); while (maxDepth < MAX_DEPTH && !forceHalt && !interupted) { maxDepth += 1; System.out.println(":: Max depth: " + maxDepth); prevBestMove = bestMove; lastItStartTime = System.currentTimeMillis(); // val = alphaBeta(initBoard, maxDepth, alpha, beta, myPlayer, -1, false); if (aspiration) { if (val >= beta) { System.out.println(":: Re-search required, val(" + val + ") >= beta."); researches++; alpha = val; beta = P_INF; val = alphaBeta(initBoard, maxDepth, alpha, beta, myPlayer, -1, false); } else if (val <= alpha) { researches++; System.out.println(":: Re-search required, val(" + val + ") <= alpha."); alpha = N_INF; beta = val; val = alphaBeta(initBoard, maxDepth, alpha, beta, myPlayer, -1, false); } DELTA = Math.max(Math.abs(val / 2) - 1, DEFAULT_DELTA); // alpha = val - DELTA; beta = val + DELTA; } // System.out.println(" - Best value so far: " + val); System.out.println(" - Best move so far: " + bestMove); System.out.println(" - Nodes visited: " + decForm.format(nodes)); // We win/lose if (Math.abs(val) > FW1_VAL) { wonlost = true; break; } // lastItTime = System.currentTimeMillis() - lastItStartTime; // // We don't have enough time for the next iteration.... // if (endTime - System.currentTimeMillis() < lastItTime * 3) // break; } // We can still use the current val if the result is better in vase of forced halt if (forceHalt || interupted) { bestMove = prevBestMove; maxDepth--; } // if (!wonlost) { numMoves++; totalNodes += nodes; totalDepth += maxDepth; } // System.out.println(":: Forced halt: " + forceHalt); System.out.println(":: TT Lookups: " + decForm.format(tt_lookups)); System.out.println(":: Collisions: " + decForm.format(collisions)); System.out.println(":: Nodes visited: " + decForm.format(nodes)); System.out.println("--------------------------------"); // Free the transposition table for the gc. tt = null; if (!interupted && parallel) callback.makeMove(bestMove); }
private int alphaBeta( Board board, int depth, int alpha, int beta, int player, int move, boolean nullMove) { if (forceHalt || interupted) return 0; // if (timeCheck == 0) { // // Check if still time left. // if (System.currentTimeMillis() >= endTime) { // forceHalt = true; // return 0; // } // timeCheck = TIME_CHECK_INT; // } // timeCheck--; nodes++; // For win/loss depth int inv_depth = maxDepth - depth, value = N_INF, bestValue = N_INF; int capsw, capsb, olda = alpha, oldb = beta; int plyBestMove = -1, hashPos = 0, color = (player == myPlayer) ? 1 : -1; boolean valuefound = false, collision = false; int[] currentMoves; // Transposition tp = null; if (transpositions) { hashPos = getHashPos(board.zobristHash); tp = tt[hashPos]; // Check if present in transposition table if (tp != null) { tt_lookups++; // Position was evaluated previously // Check for a collision if (tp.hash != board.zobristHash) { collisions++; collision = true; } else if (depth <= tp.depth) { if (tp.flag == Transposition.REAL) return tp.value; if (tp.flag == Transposition.L_BOUND && tp.value > alpha) alpha = tp.value; else if (tp.flag == Transposition.U_BOUND && tp.value < beta) beta = tp.value; if (alpha >= beta) return tp.value; } } } // Check if position is terminal. if (move != -1) { int winstate = board.checkWin(board.board[move]); if (winstate != Board.NONE_WIN) { if (winstate == player) { // Prefer shallow wins! bestValue = (WIN_VAL - (D_DECR * inv_depth)); valuefound = true; } else if (winstate == Board.DRAW) { return 0; } else { // Deeper losses are "less worse" :) than shallow losses bestValue = -(WIN_VAL - (D_DECR * inv_depth)); return bestValue; } } } // Leaf-node, evaluate the node if (depth == 0 && !valuefound) { bestValue = color * evaluate(board, inv_depth); valuefound = true; } else if (!valuefound) { // Don't do null moves at the first move, it messes up the swap rule if (nullmoves && !nullMove && depth < maxDepth && depth > R && !board.firstMove) { board.pass(); // Check for a null-move cut-off value = -alphaBeta(board, depth - 1 - R, -beta, -alpha, getOpponent(player), -1, true); board.undoPass(); if (value >= beta) { return beta; } } // if (tp == null || collision) { currentMoves = board.getAvailableMoves(killermove[inv_depth]); } else { currentMoves = board.getAvailableMoves( killermove[inv_depth][0], killermove[inv_depth][1], tp.bestMove); } int startindex = board.startindex, currentmove; double maxHistVal = 1.; for (int i = 0; i < currentMoves.length; i++) { // Try the killer and transposition moves first, then try the hh moves if (i >= startindex && maxHistVal > 0. && historyHeuristic) { board.getNextMove(history[player - 1], bfboard[player - 1], currentMoves, i); // If the previous max history value was 0, we can just follow the indexed list maxHistVal = board.maxHistVal; } currentmove = currentMoves[i]; if (board.doMove(currentmove, player)) { // Returns false if suicide if (board.capturePieces(currentmove)) { // capsw = board.playerCaps[0]; capsb = board.playerCaps[1]; // Keep track of the captured pieces. captures[0] += capsw; captures[1] += capsb; // value = -alphaBeta( board, depth - 1, -beta, -alpha, getOpponent(player), currentmove, nullMove); // if (value > bestValue) { // for detemining the move to return if (depth == maxDepth && value > bestValue) { bestMove = currentmove; } // bestValue = value; plyBestMove = currentmove; } // alpha = Math.max(alpha, bestValue); // Substract the captures from this move captures[0] -= capsw; captures[1] -= capsb; board.undoMove(); // Update the butterfly board for the relative history heuristic bfboard[player - 1][currentmove]++; if (alpha >= beta) { if (killermoves && currentmove != killermove[inv_depth][0]) { killermove[inv_depth][1] = killermove[inv_depth][0]; killermove[inv_depth][0] = currentmove; } break; } } } else { System.err.println("error making move!"); } } } // Update the history heuristics for move-ordering if (plyBestMove > -1) history[player - 1][plyBestMove]++; // Replace if deeper or doesn't exist if (transpositions && (tp == null || (collision && depth > tp.depth))) { tp = new Transposition(); tt[hashPos] = tp; tp.bestMove = plyBestMove; tp.depth = depth; tp.hash = board.zobristHash; // if (bestValue <= olda) { tp.flag = Transposition.U_BOUND; } else if (bestValue >= oldb) { tp.flag = Transposition.L_BOUND; } else { tp.flag = Transposition.REAL; } tp.value = bestValue; } return bestValue; }
/* * Constructor */ public MinimaxAgent(Board board, int numToWin) { this.board = board; heuristic = new Heuristic(numToWin); if (board.getHeight() > 10 && board.getWidth() > 10) depth = 4; }
@Test public void test() { Board test_board; // Spielbrett test_board = new Board(7, 6); // Test 1 : Spieler X gewinnt in einer Spalte test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.X, 0); assertTrue("Patt: findWinner() gibt Player.X", test_board.findWinner() == Player.X); // Test 2 : Spieler O gewinnt in einer Spalte test_board = new Board(7, 6); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); assertTrue("Patt: findWinner() gibt Player.=O", test_board.findWinner() == Player.O); // Test 3 : Spieler X gewinnt in einer Zeile test_board = new Board(7, 6); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 4); assertTrue("Patt: findWinner() gibt Player.X", test_board.findWinner() == Player.X); // Test 4 : Spieler O gewinnt in einer Zeile test_board = new Board(7, 6); test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.O, 4); assertTrue("Patt: findWinner() gibt Player.=O", test_board.findWinner() == Player.O); // Test 5 : Spieler X gewinnt diagonal test_board = new Board(7, 6); test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.X, 3); assertTrue("Patt: findWinner() gibt Player.=X", test_board.findWinner() == Player.X); // Test 6 : Spieler O gewinnt diagonal test_board = new Board(7, 6); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.O, 3); assertTrue("Patt: findWinner() gibt Player.=X", test_board.findWinner() == Player.O); // Test 7 Spielsituation: erste Möglichkeit Patt test_board = new Board(7, 6); // Spalte 1 füllen test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); // Spalte 2 füllen test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.X, 1); // Spalte3 füllen test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.O, 2); // Spalte 4 füllen test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 3); // Spalte 5 füllen test_board.makeDrop(Player.X, 4); test_board.makeDrop(Player.O, 4); test_board.makeDrop(Player.O, 4); test_board.makeDrop(Player.X, 4); test_board.makeDrop(Player.O, 4); test_board.makeDrop(Player.O, 4); // Spalte 6 füllen test_board.makeDrop(Player.O, 5); test_board.makeDrop(Player.X, 5); test_board.makeDrop(Player.X, 5); test_board.makeDrop(Player.O, 5); test_board.makeDrop(Player.X, 5); test_board.makeDrop(Player.X, 5); // Spalte 7 füllen test_board.makeDrop(Player.X, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.X, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); // kontrolliert, ob das gewünschte Ergebnis in diesem Testfall eintritt assertTrue("Patt: findWinner() soll null zurückgeben", test_board.findWinner() == null); assertTrue("Patt: isFull() gibt true zurück", test_board.isFull()); assertTrue("Patt: isGameDraw() gibt true zurück", test_board.isGameDraw()); assertFalse("Patt: hasWinner() gibt false zurück", test_board.hasWinner()); assertTrue("Patt: isEndSituation() gibt true zurück", test_board.isEndSituation()); // Test 7 Spielsituation: zweite Möglichkeit für einen Patt test_board = new Board(7, 6); // Spalte 1 füllen test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.X, 0); test_board.makeDrop(Player.O, 0); test_board.makeDrop(Player.X, 0); // Spalte 2 füllen test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.X, 1); test_board.makeDrop(Player.O, 1); test_board.makeDrop(Player.X, 1); // Spalte3 füllen test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.X, 2); test_board.makeDrop(Player.O, 2); test_board.makeDrop(Player.X, 2); // Spalte 4 füllen test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.O, 3); test_board.makeDrop(Player.X, 3); test_board.makeDrop(Player.O, 3); // Spalte 5 füllen test_board.makeDrop(Player.X, 4); test_board.makeDrop(Player.O, 4); test_board.makeDrop(Player.O, 4); test_board.makeDrop(Player.X, 4); test_board.makeDrop(Player.X, 4); test_board.makeDrop(Player.O, 4); // Spalte 6 füllen test_board.makeDrop(Player.O, 5); test_board.makeDrop(Player.X, 5); test_board.makeDrop(Player.O, 5); test_board.makeDrop(Player.X, 5); test_board.makeDrop(Player.O, 5); test_board.makeDrop(Player.X, 5); // Spalte 7 füllen test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.X, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.X, 6); // kontrolliert, ob das gewünschte Ergebnis in diesem Testfall eintritt assertTrue("Patt: findWinner() soll null zurückgeben", test_board.findWinner() == null); assertTrue("Patt: isFull() gibt true zurück", test_board.isFull() == true); assertTrue("Patt: isGameDraw() gibt true zurück", test_board.isGameDraw() == true); // Test 9 : Spieler wirft in eine volle Spalte test_board = new Board(7, 6); test_board.makeDrop(Player.X, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.X, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); test_board.makeDrop(Player.O, 6); assertTrue( "Spalte ist voll: findFirstEmptyField gibt null zurück", test_board.findFirstEmtpyFieldInColumn(6) == null); // Test 10 : Spieler wirft in eine falsche Spalte (7) test_board = new Board(7, 6); test_board.makeDrop(Player.X, 7); assertTrue( "falsche Spalte: findFirstEmptyField gibt null zurück", test_board.findFirstEmtpyFieldInColumn(7) == null); }
private int controlCorners(int hv) { int heurVal = hv; if (board.getField()[0][0] == Tile.EMPTY) { if (board.getField()[0][1] == myTile) { heurVal -= 10; } if (board.getField()[1][1] == myTile) { heurVal -= 10; } if (board.getField()[1][0] == myTile) { heurVal -= 10; } } else if (board.getField()[0][0] == myTile) { heurVal += 50; } if (board.getField()[Board.SIZE - 1][0] == Tile.EMPTY) { if (board.getField()[Board.SIZE - 1][1] == myTile) { heurVal -= 10; } if (board.getField()[Board.SIZE - 2][1] == myTile) { heurVal -= 10; } if (board.getField()[Board.SIZE - 2][0] == myTile) { heurVal -= 10; } } else if (board.getField()[Board.SIZE - 1][0] == myTile) { heurVal += 50; } if (board.getField()[0][Board.SIZE - 1] == Tile.EMPTY) { if (board.getField()[1][Board.SIZE - 1] == myTile) { heurVal -= 10; } if (board.getField()[0][Board.SIZE - 2] == myTile) { heurVal -= 10; } if (board.getField()[1][Board.SIZE - 2] == myTile) { heurVal -= 10; } } else if (board.getField()[0][Board.SIZE - 1] == myTile) { heurVal += 50; } if (board.getField()[Board.SIZE - 1][Board.SIZE - 1] == Tile.EMPTY) { if (board.getField()[Board.SIZE - 2][Board.SIZE - 1] == myTile) { heurVal -= 10; } if (board.getField()[Board.SIZE - 1][Board.SIZE - 2] == myTile) { heurVal -= 10; } if (board.getField()[Board.SIZE - 2][Board.SIZE - 2] == myTile) { heurVal -= 10; } } else if (board.getField()[Board.SIZE - 1][Board.SIZE - 1] == myTile) { heurVal += 50; } return heurVal; }