/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package no.uia.is207.c4.player; import no.uia.is207.c4.game.Colour; import no.uia.is207.c4.game.ComputerPlayer; import no.uia.is207.c4.game.Game; import no.uia.is207.c4.game.GameOverException; import no.uia.is207.c4.game.GameState; import no.uia.is207.c4.game.IllegalMoveException; import no.uia.is207.c4.game.Player; /** * * @author arnea06 */ public class NegamaxPlayer extends ComputerPlayer { private Game game; private Colour[][] board; private Colour[][] used; public NegamaxPlayer() { super("NegamaxPlayer", "NegamaxPlayer"); } @Override protected int findMove(Game game) { this.game = game; System.out.println("starter negamax"); return negamax(8); } private int negamax(int depth) { if(game.gameOver() || depth == 0) { System.out.println("starter evaluering"); return eval(); } int[] cols = new int[game.NCOLS]; for(int col = 0; col < game.NCOLS; col++) { cols[col] = col; } int value = Integer.MIN_VALUE; int colIndex = 3; for(int col : cols) { if(game.legalMove(col)) { try { if(game.getState() == GameState.BLACK_TURN) { GameState state = game.doMove(Colour.BLACK, col); } else if(game.getState() == GameState.RED_TURN) { GameState state = game.doMove(Colour.RED, col); } } catch (GameOverException e) { return eval(); } catch (IllegalMoveException e) { continue; } int tmp = -negamax(depth-1); if(tmp > value) { value = tmp; colIndex = col; } game.undoMove(); } } return cols[colIndex]; } private int eval() { System.out.println("starter å tegne brettet"); board = new Colour[game.NROWS][game.NCOLS]; for(int row = 0; row < game.NROWS; row++) { for(int col = 0; col < game.NCOLS; col++) { board[row][col] = game.getField(row, col); } } System.out.println("ferdig med å tegne brettet"); System.out.println("Sjekker om det finnes 4 på rad"); if(getColour() == Colour.BLACK) { if(hasWon(Colour.BLACK)) { System.out.println("svart har vunnet"); return Integer.MAX_VALUE; } else if(hasWon(Colour.RED)) { System.out.println("rød har vunnet"); return Integer.MIN_VALUE; } } else if(getColour() == Colour.RED) { if(hasWon(Colour.RED)) { System.out.println("rød har vunnet"); return Integer.MAX_VALUE; } else if(hasWon(Colour.BLACK)) { System.out.println("svart har vunnet"); return Integer.MIN_VALUE; } } System.out.println("ferdig å sjekke om det var 4 på rad"); used = null; used = new Colour[game.NROWS][game.NCOLS]; int red3InARow = threeInARow(Colour.RED); int red2InARow = twoInARow(Colour.RED); int red1InARow = oneInARow(Colour.RED); System.out.println("rød har: 3pårad = " + red3InARow + ":: 2pårad = " + red2InARow + ":: 1pårad = " + red1InARow); used = null; used = new Colour[game.NROWS][game.NCOLS]; int black3InARow = threeInARow(Colour.BLACK); int black2InARow = twoInARow(Colour.BLACK); int black1InARow = oneInARow(Colour.BLACK); System.out.println("svart har: 3pårad = " + black3InARow + ":: 2pårad = " + black2InARow + ":: 1pårad = " + black1InARow); int red = (red3InARow*32) + (red2InARow*4) + red1InARow; int black = (black3InARow*32) + (black2InARow*4) + black1InARow; if(getColour() == Colour.BLACK) { System.out.println("returnerer styrken til svart: " + (black - red)); return black - red; } else if(getColour() == Colour.RED) { System.out.println("returnerer styrken til rød: " + (red - black)); return red - black; } else { System.out.println("returnerer default 0"); return 0; } } /** Check whether the last player has won */ private boolean hasWon(Colour p) { System.out.println("kommet inn i haswon metoden"); int col = game.getLastMove(); System.out.println("hentet lastmove: " + col); int row = game.getHeight(col) == 0 ? 0 : game.getHeight(col) -1; System.out.println("hentet høyden = " + row); int target = 4; System.out.println("starter med å sjekke om " + p + " har vunnet"); if (check(p, row, col, 0, 1, target)) { System.out.println("returnerer at: " + p + " har vunnet horisontalt"); return true; // horizontal } else if (check(p, row, col, 1, 1, target)) { System.out.println("returnerer at: " + p + " har vunnet diag1"); return true; // diag1 } else if (check(p, row, col, 1, 0, target)) { System.out.println("returnerer at: " + p + " har vunnet vertikalt"); return true; // vertical } else if (check(p, row, col, 1, -1, target)) { System.out.println("returnerer at: " + p + " har vunnet diag2"); return true; // diag2 } else { System.out.println("returnerer at: " + p + " ikke har vunnet"); return false; } } private int threeInARow(Colour p) { int target = 3; int inARow = 0; for(int row = 0; row < game.NROWS; row++) { for(int col = 0; col < game.NCOLS; col++) { if(game.getField(row, col) != p) continue; if(used[row][col] == p) continue; if(check(p, row, col, 0, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 0, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, -1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } } } return inARow; } private int twoInARow(Colour p) { int target = 2; int inARow = 0; for(int row = 0; row < game.NROWS; row++) { for(int col = 0; col < game.NCOLS; col++) { if(game.getField(row, col) != p) continue; if(used[row][col] == p) continue; if(check(p, row, col, 0, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 0, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, -1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } } } return inARow; } private int oneInARow(Colour p) { int target = 1; int inARow = 0; for(int row = 0; row < game.NROWS; row++) { for(int col = 0; col < game.NCOLS; col++) { if(game.getField(row, col) != p) continue; if(used[row][col] == p) continue; if(check(p, row, col, 0, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, 0, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } if(check(p, row, col, 1, -1, target)) { inARow++; for(int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) continue; else if (board[r][c] == p) used[r][c] = p; } } } } return inARow; } private boolean check(Colour p, int row, int col, int rInc, int cInc, int target) { System.out.println("startet check metoden"); if (rInc == 0 && cInc == 0) { return false; } int count = 0; for (int i=-target+1; i=game.NROWS || c<0 || c>=game.NCOLS) { count = 0; // off edge of board, reset } else if (board[row + i*rInc][col + i*cInc] == p) { count++; // found one our own, increase count if (count == target) { return true; } } else { count = 0; // not ours, reset } } return false; } public Player copy() { return new NegamaxPlayer(); } }