rendered paste body/*
* 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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*0;
int c = col + i*1;
if (r<0 || r>=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<target; i++) {
int r = row + i*rInc;
int c = col + i*cInc;
if (r<0 || r>=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();
}
}