As part of intelligent systems i wrote a minimax algorithm

Here my implementation

Note* I’ve already submitted this, wouldn’t recommend you pawn it off as your own!

This report explains the implementation

import java.util.ArrayList;
import ie.ul.konane.Konane;
import ie.ul.konane.KonaneMove;
import ie.ul.konane.Player;

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

public class C0813001 extends Player
{
	private Konane currentState;

	/**
	 * Constructor
	 *
	 * @param pName ( The name Associated with the user )
	 */

	public C0813001( String pName )
	{
		super( pName );
	}

	/* (non-Javadoc)
	 * @see ie.ul.konane.Player#initialize(char)
	 */

	@Override
	public void initialize( char pColour )
	{
		this.name = "0813001";
		this.colour = pColour;
	}

	/**
	 * Instantiates the tree and gets the best move
	 *
	 * @return KonaneMove ( the next best move )
	 */

	private KonaneMove decideMyMove()
	{
		KonaneMove move = null;

		if( this.currentState.generateMoves( this.colour ).size() == 0 )
		{
			KonaneMove gameOver = new KonaneMove( 0 , 0 );
			gameOver.lostGame();
			return gameOver;
		}

		try
		{
			Tree tree = new Tree( this.currentState , this.colour );
			move = tree.getNextMove();
		}
		catch ( Exception e )
		{
			move = this.currentState.generateMoves( this.colour ).get( 0 );
			System.out.println( e.getMessage() );
			e.printStackTrace();
		}

		return move;
	}

	/* (non-Javadoc)
	 * @see ie.ul.konane.Player#makeMove(ie.ul.konane.Konane)
	 */

	@Override
	public KonaneMove makeMove( Konane game )
	{
		this.currentState = game;
		KonaneMove m = this.decideMyMove();
		return m;
	}

}

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

class Tree
{
	public static char PLAYER;
	public static char OPPONENT;
	public static int MAXDEPTH;
	public static int MAXVALUE;
	public static int MINVALUE;
	public static char heurisitic;
	private Node head;

	/**
	 * Java's version of a static constructor
	 */

	static
	{
		Tree.MAXDEPTH = 4;
		Tree.MAXVALUE = Integer.MAX_VALUE - ( Tree.MAXDEPTH * 5000 );
		Tree.MINVALUE = Integer.MIN_VALUE + ( Tree.MAXDEPTH * 5000 );
		Tree.heurisitic = 'b';
	}

	/**
	 * Constructor for the Tree
	 *
	 * @param board ( the current Konane )
	 * @param me ( the char representing my color )
	 */

	public Tree( Konane board , char me )
	{
		Tree.PLAYER = me;
		Tree.OPPONENT = ( me == 'w' ) ? 'b' : 'w';
		this.head = new Node( board );
	}

	/**
	 * After the tree has completed evaluating itself
	 * This is use to get the move that was pushed to the top
	 *
	 * @return KonaneMove ( the best move )
	 */

	public KonaneMove getNextMove()
	{
		return this.head.getBestChild().getLastMove();
	}
}

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

class Node
{
	private boolean max;

	private Konane currentBoard;
	private int currentDepth = 0;

	private ArrayList< Node > nextNodes = null;
	private ArrayList< KonaneMove > nextMoves = null;

	private KonaneMove moveThatCreatedState = null;
	private Node parentNode = null;
	private Node bestChildNode = null;

	private int heuristicValue = 0;

	/**
	 * Default constructor for the Head	 *
	 * This is the current state ( not considered a move )
	 * Begins the recursive generation of the Tree
	 *
	 * @param board ( Konane the current state )
	 */

	public Node( Konane board )
	{
		this.max = false;
		this.nextNodes = new ArrayList< Node >();
		this.currentBoard = board;
		this.currentDepth = 0;
		this.generateNextNodes( Tree.PLAYER , this.max );
	}

	/**
	 * Overloaded constructor
	 * Recursively generates next moves until MAXDEPTH is reached
	 * The base case is, if this node's heuristic value is better than its parents
	 * Then push this child Node to its parent's Node
	 *
	 * @param board ( Konane, that was generate for the next possible move )
	 * @param depth ( The depth of this Node )
	 * @param isMax ( Indicates whether its a min or max node )
	 * @param move ( The KonaneMove that generated this state )
	 * @param parent ( The parent of this state )
	 * @param whichPlayer ( The player at this depth )
	 */

	public Node( Konane board , int depth , boolean isMax , KonaneMove move , Node parent , char whichPlayer )
	{
		this.parentNode = parent;
		this.moveThatCreatedState = move;
		this.max = isMax;
		this.currentDepth = depth;
		this.nextNodes = new ArrayList< Node >();
		this.currentBoard = board;
		this.generateNextNodes( whichPlayer , this.max );

		if( parent.getBestChild() == null )
		{
			parent.setHeurisiticValue( this.heuristicValue , this );
		}
		else
		{
			if( this.max )
			{
				if( this.heuristicValue > parent.getHeurisiticValue() )
				{
					parent.setHeurisiticValue( this.heuristicValue , this );
				}
			}
			else
			{
				if( this.heuristicValue < parent.getHeurisiticValue() )
				{
					parent.setHeurisiticValue( this.heuristicValue , this );
				}
			}
		}
		this.nextMoves.clear();
		this.nextNodes.clear();
	}

	/**
	 * Gets the list of possible moves
	 * And generates the next Node states for each move
	 *
	 * @param whichPlayer ( The player at this depth )
	 * @param isMax ( is max or min )
	 */

	private void generateNextNodes( char whichPlayer , boolean isMax )
	{
		Konane newBoard;
		Node tempNode;
		KonaneMove possibleMove;

		this.nextMoves = this.currentBoard.generateMoves( whichPlayer );

		this.calculateHeuristicValue();

		if( this.currentDepth == Tree.MAXDEPTH )
		{
			return;
		}
		else
		{
			for ( int counter = 0 ; counter < this.nextMoves.size() ; counter++ )
			{
				newBoard = new Konane( this.currentBoard );
				possibleMove = new KonaneMove( this.nextMoves.get( counter ) );

				try
				{
					newBoard.makeMove( whichPlayer , possibleMove );
				}
				catch ( Exception e )
				{
					e.printStackTrace();
				}

				tempNode = new Node( newBoard , this.currentDepth + 1 , !isMax , possibleMove , this , ( whichPlayer == Tree.PLAYER ) ? Tree.OPPONENT : Tree.PLAYER );
				this.nextNodes.add( tempNode );
			}
		}
	}

	/**
	 * Calculates the heuristic value of this Node
	 */

	private void calculateHeuristicValue()
	{
		int mymoves = 1;
		int opmoves = 1;
		int heuristic = this.currentDepth;
		int mypieces = this.currentBoard.countSymbol( Tree.PLAYER );
		int oppieces = this.currentBoard.countSymbol( Tree.OPPONENT );

		if( this.currentDepth > 0 )
		{
			mymoves = ( this.max ) ? this.parentNode.getParentMoveCount() + 1 : this.nextMoves.size() + 1;
			opmoves = ( this.max ) ? this.nextMoves.size() + 1 : this.parentNode.getParentMoveCount() + 1;
		}

		if( this.currentDepth != Tree.MAXDEPTH && this.nextMoves.size() == 0 )
		{
			heuristic += ( this.max == true ) ? Tree.MAXVALUE : Tree.MINVALUE;
		}

		if( Tree.heurisitic == 'a' )
		{
			heuristic += ( int ) Math.round( mymoves - ( opmoves * 3 ) );
		}
		else if( Tree.heurisitic == 'b' )
		{
			heuristic += mymoves - opmoves;
		}
		else if( Tree.heurisitic == 'c' )
		{
			heuristic += ( int ) Math.round( mymoves / ( opmoves * 3 ) );
		}
		else if( Tree.heurisitic == 'd' )
		{
			heuristic += ( int ) Math.round( mymoves / opmoves );
		}
		else if( Tree.heurisitic == 'e' )
		{
			heuristic += ( int ) Math.round( mypieces / ( oppieces * 3 ) );
		}
		else if( Tree.heurisitic == 'f' )
		{
			heuristic += ( int ) Math.round( mypieces / oppieces );
		}
		else
		{
			heuristic += this.nextMoves.size();
		}

		this.heuristicValue = heuristic;
	}

	/**
	 * Gets a count of the moves for this Node
	 * @return ( number of possible moves )
	 */

	public int getParentMoveCount()
	{
		return this.nextMoves.size();
	}

	/**
	 * Gets the heuristic of this Node
	 *
	 * @return ( Heuristic Value )
	 */

	public int getHeurisiticValue()
	{
		return this.heuristicValue;
	}

	/**
	 * Gets the move that created this state
	 *
	 * @return ( The move )
	 */

	public KonaneMove getLastMove()
	{
		return this.moveThatCreatedState;
	}

	/**
	 * Sets the parent of a Node's, Heuristic value and besctChild
	 *
	 * @param betterHeuristicValue ( the heuristic of the child )
	 * @param betterChildNode ( the child )
	 */

	public void setHeurisiticValue( int betterHeuristicValue , Node betterChildNode )
	{
		this.heuristicValue = betterHeuristicValue;
		this.bestChildNode = betterChildNode;
	}

	/**
	 * Gets the parent of a Node
	 *
	 * @return ( the parent Node )
	 */

	public Node getParent()
	{
		return this.parentNode;
	}

	/**
	 * Gets the best child from a Node
	 * Typically used with the Head
	 *
	 * @return ( the best child )
	 */

	public Node getBestChild()
	{
		return this.bestChildNode;
	}

}