diff --git a/manager/controller.cpp b/manager/controller.cpp
index de46f02fe6712e7598dfafc3dc74eb63a602c280..7325ec75a15b950acac605f37feea264a3d68db5 100644
--- a/manager/controller.cpp
+++ b/manager/controller.cpp
@@ -174,9 +174,9 @@ MovementResult Controller::MakeMove(string & buffer)
 		
 	}
 
-	//if (!Board::LegalResult(moveResult))
-	//	return MovementResult::OK; //HACK - Legal results returned!
-	//else
+	if (!Board::LegalResult(moveResult))
+		return MovementResult::OK; //HACK - Legal results returned!
+	else
 		return moveResult; 	
 
 }
diff --git a/samples/dummy/Makefile b/samples/dummy/Makefile
index 96cb9695f65e3c62a9da22692bd04a137c6e20b5..9762ad1e152763b33bbcef8d6ae3187374bbb350 100644
--- a/samples/dummy/Makefile
+++ b/samples/dummy/Makefile
@@ -8,12 +8,8 @@ dummy : dummy.o
 
 
 clean :
-	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
-
-clean_full: #cleans up all backup files
-	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
-	$(RM) *.*~
-	$(RM) *~
+	rm -f dummy.o
+	rm -f dummy
 
 
 
diff --git a/samples/dummy/dummy.cpp b/samples/dummy/dummy.cpp
index a4a68ce22fc872b69d5002501edb4d5dc2e12f23..4e39b7488e3ced435afe6703332894d304630439 100644
--- a/samples/dummy/dummy.cpp
+++ b/samples/dummy/dummy.cpp
@@ -18,7 +18,8 @@ int main(int argc, char ** argv)
 {
 	setbuf(stdout, NULL);
 	setbuf(stdin, NULL);
-	
+
+	srand(time(NULL));	
 
 	//Read in the colour, and choose a layout
 	
diff --git a/samples/forfax/forfax.cpp b/samples/forfax/forfax.cpp
index 729e2f962445a68a06e678743d1111baf40a9cb5..ede3156b851bd991ca03c742e5eed1a26c58a37a 100644
--- a/samples/forfax/forfax.cpp
+++ b/samples/forfax/forfax.cpp
@@ -17,6 +17,8 @@
 #include <list>
 #include <cmath>
 
+//#define DEBUG
+
 using namespace std;
 
 
@@ -48,7 +50,7 @@ int Forfax::remainingUnits[][15] = {{0,0,1,1,8,5,4,4,4,3,2,1,1,6,0},{0,0,1,1,8,5
  * @param newColour - colour
  */
 Piece::Piece(int newX, int newY,const Colour & newColour)
-	: x(newX), y(newY), colour(newColour), minRank(Piece::FLAG), maxRank(Piece::BOMB), lastMove(0)
+	: x(newX), y(newY), colour(newColour), minRank(Piece::FLAG), maxRank(Piece::BOMB), lastMove(0), lastx(newX), lasty(newY)
 {
 
 }
@@ -61,7 +63,7 @@ Piece::Piece(int newX, int newY,const Colour & newColour)
  * @param fixedRank - rank of the new piece
  */
 Piece::Piece(int newX, int newY,const Colour & newColour, const Type & fixedRank)
-	: x(newX), y(newY), colour(newColour), minRank(fixedRank), maxRank(fixedRank), lastMove(0)
+	: x(newX), y(newY), colour(newColour), minRank(fixedRank), maxRank(fixedRank), lastMove(0),  lastx(newX), lasty(newY)
 {
 	
 	
@@ -265,6 +267,19 @@ Board::Direction Board::DirectionBetween(int x1, int y1, int x2, int y2)
 	
 
 	
+}
+
+/**
+ * HELPER - Returns the number of moves between two points
+ * @param x1 x coordinate of the first point
+ * @param y1 y coordinate of the first point
+ * @param x2 x coordinate of the second point
+ * @param y2 y coordinate of the second point
+ * @returns The number of moves taken to progress from (x1, y1) to (x2, y2), assuming no obstacles
+ */
+int Board::NumberOfMoves(int x1, int y1, int x2, int y2)
+{
+	return (abs(x2 - x1) + abs(y2 - y1)); //Pieces can't move diagonally, so this is pretty straight forward
 }
 
 /**
@@ -279,7 +294,8 @@ bool Board::ForgetPiece(Piece * forget)
 		return false;
 	
 	vector<Piece*> & in = GetPieces(forget->colour); bool result = false;
-	for (vector<Piece*>::iterator i=in.begin(); i != in.end(); ++i)
+	vector<Piece*>::iterator i=in.begin(); 
+	while (i != in.end())
 	{
 		
 		if ((*i) == forget)
@@ -289,12 +305,61 @@ bool Board::ForgetPiece(Piece * forget)
 			
 			continue;
 		}
-		
+		++i;
 		
 	}
 
 	
 	return result;
+}
+
+/**
+ * Gets the closest Piece of a specified colour to a point
+ * @param x The x coordinate of the point
+ * @param y The y coordinate of the point
+ * @param colour The colour that the piece must match (may be Piece::BOTH to match either colour)
+ * @returns Piece* pointing to the closest piece of a matching colour, NULL if no piece found
+ */
+Piece * Board::GetClosest(int x, int y, const Piece::Colour & colour) const
+{
+	if (x < 0 || y < 0 || x >= width || y >= height)
+		return NULL;
+
+	for (int dist = 0; dist < max<int>(width, height); ++dist)
+	{
+		
+		for (int yy = y-dist; yy <= y+dist; ++yy)
+		{
+			Piece * get = Get(x+dist, y);
+			if ((get != NULL) && (get->colour == colour || colour == Piece::BOTH))
+				return get;
+		}
+		for (int yy = y-dist; yy <= y+dist; ++yy)
+		{
+			Piece * get = Get(x-dist, y);
+			if ((get != NULL) && (get->colour == colour || colour == Piece::BOTH))
+				return get;
+		}
+		for (int xx = x-dist; xx <= x+dist; ++xx)
+		{
+			Piece * get = Get(xx, y+dist);
+			if ((get != NULL) && (get->colour == colour || colour == Piece::BOTH))
+				return get;
+		}
+		for (int xx = x-dist; xx <= y+dist; ++xx)
+		{
+			Piece * get = Get(xx, y-dist);
+			if ((get != NULL) && (get->colour == colour || colour == Piece::BOTH))
+				return get;
+		}
+
+	}
+	
+	return NULL;
+	
+	
+	
+	
 }
 
 /**
@@ -303,6 +368,7 @@ bool Board::ForgetPiece(Piece * forget)
 Forfax::Forfax() : board(NULL), colour(Piece::NONE), strColour("NONE"), turnNumber(0)
 {
 	//By default, Forfax knows nothing; the main function in main.cpp calls Forfax's initialisation functions
+	srand(time(NULL));
 }
 
 /**
@@ -366,32 +432,51 @@ double Forfax::MovementScore(Piece * piece, const Board::Direction & dir) const
 	if (!board->ValidPosition(x2, y2) || !piece->Mobile())
 	{
 		
-		basevalue = 0;
+		basevalue = 0; //No point attempting to move immobile units, or moving off the edges of the board
 	}
 	else if (board->Get(x2, y2) == NULL)
 	{
-		basevalue = 0.5*IntrinsicWorth(x2, y2);
+		//If the position is empty...
+		Piece * closestEnemy = board->GetClosest(x2, y2, Piece::Opposite(piece->colour));
+		if (closestEnemy == NULL)
+		{
+			basevalue = 0.05*IntrinsicWorth(x2, y2); //Should never get this unless there are no enemies left
+		}
+		else
+		{
+			//Allocate score based on score of Combat with nearest enemy to the target square, decrease with distance between target square and the enemy
+			basevalue = 0.95*CombatScore(closestEnemy->x, closestEnemy->y, piece) - 0.2*(double)((double)(Board::NumberOfMoves(closestEnemy->x, closestEnemy->y, x2, y2))/(double)((max<int>(board->Width(), board->Height()))));
+		}
+		
 		
 	}
 	else if (board->Get(x2, y2)->colour != Piece::Opposite(piece->colour))
 	{
-		basevalue = 0;
+		basevalue = 0; //The position is occupied by an ally, and so its pointless to try and move there
 	}
 	else 
 	{
-		Piece * defender = board->Get(x2, y2);
-		double combatSuccess = CombatSuccessChance(piece, defender);
-		basevalue = IntrinsicWorth(x2, y2)*combatSuccess*VictoryScore(piece, defender) + (1.0 - combatSuccess)*DefeatScore(piece, defender);
+		basevalue = CombatScore(x2, y2, piece); //The position is occupied by an enemy; compute combat score
 	}
 
 	if (basevalue > 0)
 	{
+		//Hack which decreases score for units that moved recently
+		//Does not decrease below a threshold (so that at the start of the game units will actually move!)
 		double oldValue = basevalue;
 		basevalue -= (double)(1.0/((double)(1.0 + (turnNumber - piece->lastMove))));
-		if (basevalue < oldValue/8.0)
-			basevalue = oldValue/8.0;
+		if (basevalue < oldValue/1000.0)
+			basevalue = oldValue/1000.0;
 	}
 	
+
+	if (x2 == piece->lastx && y2 == piece->lasty) //Hack which decreases score for backtracking moves
+		basevalue = basevalue/1.5;
+
+	if (rand() % 10 == 0) //Hack which introduces some randomness by boosting one in every 10 scores
+		basevalue *= 4;
+	if (basevalue > 1)
+		basevalue = 1;
 	return basevalue;
 }
 
@@ -475,7 +560,7 @@ Forfax::Status Forfax::MakeMove()
 		if (interpret != OK) {return interpret;}
 
 		//Forfax ignores the board state; he only uses the move result lines
-		
+		#ifndef DEBUG
 		for (int y=0; y < board->Height(); ++y)
 		{
 			for (int x = 0; x < board->Width(); ++x)
@@ -483,6 +568,7 @@ Forfax::Status Forfax::MakeMove()
 			if (cin.get() != '\n')
 				return NO_NEWLINE;
 		}
+		#endif //DEBUG
 		
 	}
 	
@@ -589,13 +675,13 @@ Forfax::Status Forfax::InterpretMove()
 	//If ranks were supplied, update the known ranks of the involved pieces
 	if (attackerRank != Piece::NOTHING && attacker != NULL)
 	{
-		assert(attacker->minRank <= attackerRank && attacker->maxRank >= attackerRank);
+		//assert(attacker->minRank <= attackerRank && attacker->maxRank >= attackerRank);
 		attacker->minRank = attackerRank;
 		attacker->maxRank = attackerRank;
 	}
 	if (defenderRank != Piece::NOTHING && defender != NULL)
 	{
-		assert(defender->minRank <= defenderRank && defender->maxRank >= defenderRank);
+		//assert(defender->minRank <= defenderRank && defender->maxRank >= defenderRank);
 		defender->minRank = defenderRank;
 		defender->maxRank = defenderRank;
 
@@ -635,6 +721,8 @@ Forfax::Status Forfax::InterpretMove()
 		//Update board and piece
 		board->Set(x2, y2, attacker);
 		board->Set(x, y, NULL);
+		attacker->lastx = attacker->x;
+		attacker->lasty = attacker->y;
 		attacker->x = x2;
 		attacker->y = y2;
 	}
@@ -648,6 +736,8 @@ Forfax::Status Forfax::InterpretMove()
 
 		board->Set(x2, y2, attacker);
 		board->Set(x, y, NULL);
+		attacker->lastx = attacker->x;
+		attacker->lasty = attacker->y;
 		attacker->x = x2;
 		attacker->y = y2;
 
@@ -810,6 +900,8 @@ double Forfax::IntrinsicWorth(int x, int y) const
  */
 double Forfax::VictoryScore(Piece * attacker, Piece * defender) const
 {
+
+	//If defender's rank is known, flags or bombs are worth more than usual
 	if (defender->minRank == defender->maxRank)
 	{
 		if (defender->minRank == Piece::FLAG)
@@ -817,6 +909,7 @@ double Forfax::VictoryScore(Piece * attacker, Piece * defender) const
 		else if (defender->minRank == Piece::BOMB)
 			return 0.9;
 	}
+	//Return average of normalised defender ranks
 	return max<double>(((defender->maxRank / Piece::BOMB) + (defender->minRank / Piece::BOMB))/2, 0.6);
 }
 
@@ -828,30 +921,78 @@ double Forfax::VictoryScore(Piece * attacker, Piece * defender) const
  */
 double Forfax::DefeatScore(Piece * attacker, Piece * defender) const
 {
-	if (attacker->minRank == Piece::SPY)
-		return 0.05;
-
-	if (defender->minRank == defender->maxRank)
+	
+	double result = 0;
+	if (defender->minRank == defender->maxRank) //If the defender's rank is known for certain...
 	{
-		if (defender->minRank == Piece::BOMB)
-			return 1 - (double)((double)(attacker->minRank) / (double)(Piece::BOMB));
+		if (defender->minRank == Piece::BOMB) //Committing suicide to destroy bombs has a value that decreases with the attacker's rank
+			result = 1 - 0.5*(double)((double)(attacker->minRank) / (double)(Piece::BOMB));
+		else if (defender->minRank == Piece::FLAG)
+			result = 1; //Its impossible to lose to the flag anyway...
 		else
-			return 0.5;
-	}
+		{
+			//This is committing suicide on a higher ranked non-bomb enemy piece.
+			//Basically pointless, but the greater the attacker's rank the more pointless!
+			double temp = (double)((double)(attacker->minRank) / (double)(Piece::BOMB));
+			result = 0.01*(1 - temp)*(1 - temp);
 
-	double possibleRanks = 0; double totalRanks = 0;
-	for (Piece::Type rank = Piece::NOTHING; rank <= Piece::BOMB; rank = Piece::Type((int)(rank) + 1))
+			
+		}
+	}	
+	else //The defender's rank is not known
 	{
-		totalRanks += remainingUnits[(int)(defender->colour)][(int)(rank)];
-		if (rank >= defender->minRank && rank <= defender->maxRank)
-			possibleRanks += remainingUnits[(int)(defender->colour)][(int)(rank)];
+
+		//Score is allocated based on how much knowledge is gained by attacking defender
+		//The more possible ranks for the defender, the greater the score
+		//The score decreases as the rank of the attacker is increased.
+
+		double possibleRanks = 0; double totalRanks = 0; double bonus = 0; 
+		for (Piece::Type rank = Piece::NOTHING; rank <= Piece::BOMB; rank = Piece::Type((int)(rank) + 1))
+		{
+			totalRanks += remainingUnits[(int)(defender->colour)][(int)(rank)];
+
+			if (rank >= defender->minRank && rank <= defender->maxRank)
+			{
+				possibleRanks += remainingUnits[(int)(defender->colour)][(int)(rank)];
+				if (rank == Piece::BOMB)
+					bonus += remainingUnits[(int)(defender->colour)][(int)(rank)];
+				if (rank == Piece::FLAG)
+					bonus += 2*remainingUnits[(int)(defender->colour)][(int)(rank)];
+			}
+			
+		}
+
+
+		if (totalRanks > 0)
+			result = (possibleRanks/totalRanks) - 0.8*(double)((double)(attacker->minRank) / (double)(Piece::BOMB));
+
+		result += bonus / totalRanks;
 		
+		if (result > 1)
+			result = 1;
 	}
 
-	if (totalRanks > 0)
-		return (possibleRanks/totalRanks) - (double)((double)(attacker->minRank) / (double)(Piece::BOMB));
-	return 0;
-}		
+	if (attacker->minRank == Piece::SPY) //Spies are slightly more valuable than usual since they kill the Marshal
+		result = result / 1.5;
+	return result;
+
+}
+
+/**
+ * Calculates a score indicating the worth of invoking combat in a square
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param attacker The piece invoking the combat
+ * @returns A value between 0 in 1, with 0 indicating worthless (or no combat) and 1 indicating highest value
+ */
+double Forfax::CombatScore(int x, int y, Piece * attacker) const
+{
+	Piece * defender = board->Get(x, y);
+	if (defender == NULL)
+		return 0;
+	double combatSuccess = CombatSuccessChance(attacker, defender);
+	return IntrinsicWorth(x, y)*combatSuccess*VictoryScore(attacker, defender) + (1.0 - combatSuccess)*DefeatScore(attacker, defender);		
+}
 
 /**
  * DEBUG - Print the board seen by Forfax to a stream
diff --git a/samples/forfax/forfax.h b/samples/forfax/forfax.h
index 4bd747816cb069f89bc0ce4f17b333fb5b33247d..054854bb270d1cd1a05a0bdd277b5314727c9df1 100644
--- a/samples/forfax/forfax.h
+++ b/samples/forfax/forfax.h
@@ -54,6 +54,7 @@ class Piece
 		Type minRank; //The minimum possible rank of the piece
 		Type maxRank; //The maximum possible rank of the piece
 		int lastMove;
+		int lastx; int lasty;
 		
 		
 
@@ -72,6 +73,7 @@ class Board
 		std::vector<Piece*> & GetPieces(const Piece::Colour & colour) {return colour == Piece::RED ? red : blue;} //retrieve array of pieces
 		
 		Piece * Get(int x, int y) const; //Retrieve single piece
+		Piece * GetClosest(int x, int y, const Piece::Colour & search = Piece::BOTH) const; //Retrieve closest piece of specified colour to the point
 		Piece *  Set(int x, int y, Piece * newPiece); //Add piece to board
 
 		bool ValidPosition(int x, int y) const {return (x > 0 && x < width && y > 0 && y < height);}
@@ -85,7 +87,7 @@ class Board
 
 		static void MoveInDirection(int & x, int & y, const Direction & dir, int multiplier = 1);
 		static Direction DirectionBetween(int x1, int y1, int x2, int y2);
-
+		static int NumberOfMoves(int x1, int y1, int x2, int y2);
 		
 
 		static int redUnits[];
@@ -125,6 +127,7 @@ class Forfax
 		//Move score functions
 		double MovementScore(Piece * move, const Board::Direction & dir) const; //Calculate total score
 		double CombatSuccessChance(Piece * attacker, Piece * defender) const; //Calculate chance of success in combat
+		double CombatScore(int x, int y, Piece * attacker) const; //Calculate total worth of combat at a point
 		double IntrinsicWorth(int x, int y) const; //How much a given point on the board is worth
 		double VictoryScore(Piece * attacker, Piece * defender) const; //How much killing the defender is worth
 		double DefeatScore(Piece * attacker, Piece * defender) const; //How much losing is worth
@@ -176,6 +179,7 @@ class MovementChoice
 };
 
 
+
 #endif //FORFAX_H
 
 //EOF