All pastes #993139 Raw Edit

Untitled

public text v1 · immutable
#993139 ·published 2008-04-22 12:07 UTC
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();
    }

}