diff --git a/agents/c++/Makefile b/agents/c++/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..760d975e204a5c3fdc2bddcac7ef13a1dfdd48eb
--- /dev/null
+++ b/agents/c++/Makefile
@@ -0,0 +1,33 @@
+#Makefile for C++ agent
+CXX = g++ -std=gnu++0x -Wall -Werror -pedantic -g
+OBJ = qchess.o agent.o main.o
+LIB = 
+
+LINKOBJ = $(OBJ)
+
+RM = rm -f
+BIN = agent++
+
+
+
+$(BIN) : $(LINKOBJ)
+	$(CXX) -o $(BIN) $(LINKOBJ)
+
+%.o : %.cpp
+	$(CXX) -c $<
+
+no_main : $(OBJ)
+
+main.o : main.cpp
+	$(CXX) -c main.cpp
+
+clean :
+	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
+
+clean_full: #cleans up all backup files
+	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
+	$(RM) *.*~
+	$(RM) *~
+
+
+	
\ No newline at end of file
diff --git a/agents/c++/agent++ b/agents/c++/agent++
index b4d35404d6799cb77da349a6161042f02a91db1e..956a6442da3ad3d0089ef2e7d162995f94ab4466 100755
Binary files a/agents/c++/agent++ and b/agents/c++/agent++ differ
diff --git a/agents/c++/qchess.cpp b/agents/c++/qchess.cpp
index fbca35262f0231db6139ea308305feb681f8ad85..f908756ffaed72c56f75ae8ec7b32f2fdd43cf86 100644
--- a/agents/c++/qchess.cpp
+++ b/agents/c++/qchess.cpp
@@ -9,24 +9,27 @@
 
 using namespace std;
 
+
 /**
  * @constructor
  * @param new_x, new_y - Position of piece
  * @param new_colour - Colour of piece
  * @param type1, type2 - Types of piece
- * @param index - Index for initial type of piece
+ * @param new_type_index - Index for initial type of piece
+ * @param new_piece_index - Index for piece in a vector
  */
-Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2, int index)
-	: x(new_x), y(new_y), colour(new_colour), type_index(index), types(), current_type()
+Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2, 
+	     int new_type_index, int new_piece_index)
+	: x(new_x), y(new_y), colour(new_colour), type_index(new_type_index), types(), current_type(), piece_index(new_piece_index)
 {
 	types[0] = type1; types[1] = type2;
-	if (index < 0 || index >= 2)
+	if (type_index < 0 || type_index >= 2)
 	{
 		current_type = Piece::UNKNOWN;
 	}
 	else
 	{
-		current_type = types[index];
+		current_type = types[type_index];
 	}
 }
 
@@ -34,7 +37,7 @@ Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece
  * @constructor
  * @param cpy - Piece to copy construct from
  */
-Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index)
+Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index), piece_index(cpy.piece_index)
 {
 	types[0] = cpy.types[0];
 	types[1] = cpy.types[1];
@@ -44,7 +47,9 @@ Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_i
  * @constructor
  * @param choose_types - Indicates whether Board should setup the 2nd types of pieces; default false
  */
-Board::Board(bool choose_types)
+Board::Board(bool choose_types) 
+	: white(), black(), white_unknown(), black_unknown(), white_nUnknown(0), black_nUnknown(0),
+	white_king(NULL), black_king(NULL),  parent(NULL)
 {
 
 	// initialise all the Squares
@@ -69,6 +74,14 @@ Board::Board(bool choose_types)
 	freq[Piece::QUEEN] = 1;
 	freq[Piece::PAWN] = 8;
 	
+	if (!choose_types)
+	{
+		white_unknown = freq;
+		black_unknown = freq;
+		white_nUnknown = 15;
+		black_nUnknown = 15;
+	}
+	
 	// for white and black...
 	for (int i = 0; i < 2; ++i)
 	{
@@ -80,26 +93,25 @@ Board::Board(bool choose_types)
 		int y = (i == 0) ? 1 : BOARD_HEIGHT-2;
 		for (int x = 0; x < BOARD_WIDTH; ++x)
 		{	
-			Piece * p = new Piece(x, y, colours[i], Piece::PAWN, Piece::UNKNOWN);
-			v.push_back(p);
+			Piece::AddPiece(v, x, y, colours[i], Piece::PAWN, Piece::UNKNOWN);
 		}		
 
 		// add other pieces
 		y = (i == 0) ? 0 : BOARD_HEIGHT-1;
-		v.push_back(new Piece(0, y, colours[i], Piece::ROOK, Piece::UNKNOWN));
-		v.push_back(new Piece(BOARD_WIDTH-1, y, colours[i], Piece::ROOK, Piece::UNKNOWN));
-		v.push_back(new Piece(1, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN));
-		v.push_back(new Piece(BOARD_WIDTH-2, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN));
-		v.push_back(new Piece(2, y, colours[i], Piece::BISHOP, Piece::UNKNOWN));
-		v.push_back(new Piece(BOARD_WIDTH-3, y, colours[i], Piece::BISHOP, Piece::UNKNOWN));
-		v.push_back(new Piece(3, y, colours[i], Piece::QUEEN, Piece::UNKNOWN));
-
-		Piece * k = new Piece(4, y, colours[i], Piece::KING, Piece::KING, 1);
+		Piece::AddPiece(v, 0, y, colours[i], Piece::ROOK, Piece::UNKNOWN);
+		Piece::AddPiece(v, BOARD_WIDTH-1, y, colours[i], Piece::ROOK, Piece::UNKNOWN);
+		Piece::AddPiece(v, 1, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN);
+		Piece::AddPiece(v, BOARD_WIDTH-2, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN);
+		Piece::AddPiece(v, 2, y, colours[i], Piece::BISHOP, Piece::UNKNOWN);
+		Piece::AddPiece(v, BOARD_WIDTH-3, y, colours[i], Piece::BISHOP, Piece::UNKNOWN);
+		Piece::AddPiece(v, 3, y, colours[i], Piece::QUEEN, Piece::UNKNOWN);
+
+		Piece * k = Piece::AddPiece(v, 4, y, colours[i], Piece::KING, Piece::KING, 1);
 		if (i == 0)
 			white_king = k;
 		else
 			black_king = k;
-		v.push_back(k);
+		
 		
 		// add to board and choose second types if required
 		map<Piece::Type, int> f(freq); 
@@ -133,10 +145,12 @@ Board::Board(bool choose_types)
 
 /**
  * @constructor
- * @param cpy - Board to copy construct from; each Piece in the copy will be *copied*
- *		The Piece's in the copied Board may be altered without affecting the original
+ * @param cpy - Board to clone
  */
-Board::Board(const Board & cpy)
+Board::Board(Board & cpy) 
+: white(cpy.white), black(cpy.black), white_unknown(cpy.white_unknown), black_unknown(cpy.black_unknown), 
+  white_nUnknown(cpy.white_nUnknown), black_nUnknown(cpy.black_nUnknown), 
+  white_king(cpy.white_king), black_king(cpy.black_king), parent(&cpy)
 {
 	for (int x = 0; x < BOARD_WIDTH; ++x)
 	{
@@ -144,12 +158,7 @@ Board::Board(const Board & cpy)
 		{
 			grid[x][y].x = x;
 			grid[x][y].y = y;
-
-			if (cpy.grid[x][y].piece != NULL)
-			{
-				grid[x][y].piece = new Piece(*(cpy.grid[x][y].piece));
-				pieces(grid[x][y].piece->colour).push_back(grid[x][y].piece);
-			}
+			grid[x][y].piece = cpy.grid[x][y].piece;
 		}
 	}
 }
@@ -176,17 +185,43 @@ Board::~Board()
  * @purpose Update Piece that has been selected
  * @param x, y - Position of Piece to update
  * @param index - 0 or 1 - State the Piece "collapsed" into
- * @param type - Type of the Piece
+ * @param type - Type of the Piece as a string
  */
 void Board::Update_select(int x, int y, int index, const string & type)
 {
-	cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << type << "\n";
+	Board::Update_select(x, y, index, Piece::str2type(type));
+}
+
+/**
+ * @funct Update_select
+ * @purpose Update Piece that has been selected
+ * @param x, y - Position of Piece to update
+ * @param index - 0 or 1 - State the Piece "collapsed" into
+ * @param t - Type of the Piece
+ */
+void Board::Update_select(int x, int y, int index, const Piece::Type & t)
+{
+	cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << t << "\n";
 	Square & s = grid[x][y];
+	
+	Clone_copy(s);
+	
 	assert(s.piece != NULL);
 	assert(index >= 0 && index < 2);
 	s.piece->type_index = index;
-	s.piece->types[index] = Piece::str2type(type);
-	s.piece->current_type = s.piece->types[index];
+	
+	if (s.piece->types[index] == Piece::UNKNOWN)
+	{
+		map<Piece::Type, int> & m = unknown_types(s.piece->colour);
+		int n = (m[t]--);
+		if (n < 0)
+			throw Exception("Board::Update_select", "Too many pieces of type %s found", Piece::type2str(t));
+		
+		nUnknown(s.piece->colour)--;
+		
+	}
+	s.piece->types[index] = t;
+	s.piece->current_type = t;
 }
 
 /**
@@ -201,6 +236,12 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
 {
 	Square & s1 = grid[x1][y1];
 	Square & s2 = grid[x2][y2];
+	
+	Clone_copy(s1);
+	
+
+	
+
 	if (s2.piece != NULL)
 	{
 		vector<Piece*> & p = pieces(s2.piece->colour);
@@ -214,6 +255,11 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
 			}
 			++i;
 		}
+		while (i != p.end())
+		{
+			(*i)->piece_index -= 1;
+			++i;
+		}
 		Piece * k = king(s2.piece->colour);
 		if (k == s2.piece)
 		{
@@ -222,8 +268,10 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
 			else
 				black_king = NULL;
 		}
-
-		delete s2.piece;
+		if ((IsClone() && s2.piece == parent->grid[x2][y2].piece) == false)
+		{
+			delete s2.piece;
+		}
 	}	
 
 	s1.piece->x = s2.x;
@@ -375,6 +423,36 @@ Piece::Type Piece::str2type(const string & str)
 	return Piece::UNKNOWN;
 }
 
+/**
+ * @funct type2str
+ * @purpose Convert Piece::Type to string
+ * @param t - The Types
+ * @returns a const char*
+ */
+const char * Piece::type2str(const Piece::Type & t)
+{
+	switch (t)
+	{
+		case PAWN:
+			return "pawn";
+		case BISHOP:
+			return "bishop";
+		case KNIGHT:
+			return "knight";
+		case ROOK:
+			return "rook";
+		case QUEEN:
+			return "queen";
+		case UNKNOWN:
+			return "unknown";
+		case KING:
+			return "king";
+		default:
+			throw Exception("Piece::type2str", "Unknown type %d", (int)t);
+			return "";
+	}
+}
+
 /**
  * @funct str2colour
  * @purpose Convert string to Piece::Colour
@@ -392,4 +470,34 @@ Piece::Colour Piece::str2colour(const string & str)
 	return Piece::BLACK; // should never get here
 }
 
+/**
+ * @funct AddPiece
+ * @purpose Creates a new Piece and adds it to a vector
+ * @param v - The vector
+ * @params - All remaining parameters passed to Piece::Piece
+ * @returns Pointer to the new Piece
+ */
+Piece * Piece::AddPiece(vector<Piece*> & v, int x, int y, const Piece::Colour & colour, const Piece::Type & t1, const Piece::Type & t2,
+			int type_index)
+{
+	Piece * p = new Piece(x,y,colour,t1, t2,type_index, v.size());
+	v.push_back(p);
+	return p;
+}
 
+/**
+ * @funct Clone_copy
+ * @purpose If necessary, copy the piece in the square
+ * @param s - The square
+ */
+void Board::Clone_copy(Square & s)
+{
+	if (s.piece == NULL || !IsClone()) return;
+	if (parent->grid[s.x][s.y].piece == s.piece)
+	{
+		s.piece = new Piece(*(s.piece));
+		vector<Piece*> & v = pieces(s.piece->colour);
+		v[s.piece->piece_index] = s.piece;
+	}
+	
+}
\ No newline at end of file
diff --git a/agents/c++/qchess.h b/agents/c++/qchess.h
index b2b499ad012a62e125dff267add5b62d6f123d42..40b09f182b098ca00842e573051d1add2cceefab 100644
--- a/agents/c++/qchess.h
+++ b/agents/c++/qchess.h
@@ -32,8 +32,6 @@ class Piece
 		typedef enum {PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, UNKNOWN} Type;
 		typedef enum {WHITE=0, BLACK=1} Colour;
 
-		Piece(int x, int y, const Colour & colour, const Type & type1, const Type & type2=UNKNOWN, int type_index = -1); // constructor
-		Piece(const Piece & cpy); // copy constructor
 		virtual ~Piece() {} // destructor
 
 		int x; int y; // position of the piece
@@ -44,6 +42,18 @@ class Piece
 		
 		static Type str2type(const std::string & str);
 		static Colour str2colour(const std::string & str);
+		static const char * type2str(const Type & t);
+		
+		static Piece * AddPiece(std::vector<Piece*> & v, int x, int y, const Colour & colour, const Type & type1, const Type & type2, int type_index=-1);
+		
+	private:
+		friend class Board;
+		Piece(int x, int y, const Colour & colour, const Type & type1, const Type & type2
+			, int type_index, int new_piece_index); // constructor
+		Piece(const Piece & cpy); // copy constructor
+		
+		int piece_index; // index of the piece in Board's pieces vector
+		
 
 };
 
@@ -70,33 +80,55 @@ class Board
 {
 	public:
 		Board(bool choose_types = false); // constructor
-		Board(const Board & cpy); // copy constructor
+		Board(Board & parent); // clones a board, copy on write
 		virtual ~Board(); // destructor
 
 
 		// helper; return vector of pieces given player colour
 		std::vector<Piece*> & pieces(const Piece::Colour & colour) {return ((colour == Piece::WHITE) ? white : black);}	
+		// helper; return map of unidentified 2nd types for given colour
+		std::map<Piece::Type, int> & unknown_types(const Piece::Colour & colour)
+		{
+			return ((colour == Piece::WHITE) ? white_unknown : black_unknown);
+		}
+		
+		int & nUnknown(const Piece::Colour & colour)
+		{
+			return ((colour == Piece::WHITE) ? white_nUnknown : black_nUnknown);
+		}
+		
 		// helper; return king given player colour	
 		Piece * king(const Piece::Colour & colour) {return ((colour == Piece::WHITE) ? white_king : black_king);}
 		
 		void Update_move(int x, int y, int x2, int y2); // move a piece
 		void Update_select(int x, int y, int index, const std::string & type); // update a selected piece
+		void Update_select(int x, int y, int index, const Piece::Type & t);
 	
 		Square & square(int x, int y) {return grid[x][y];} // get square on board
 
-		void Get_moves(Piece * p, std::vector<Square*> & v); // get allowed moves for piece
+		void Get_moves(Piece * p, std::vector<Square*> & v); // get allowed moves for piece of known type
 
 		// determine if position is on the board
 		bool Valid_position(int x, int y) {return (x >= 0 && x <= BOARD_WIDTH-1 && y >= 0 && y <= BOARD_HEIGHT-1);}
+		
+		bool IsClone() const {return parent != NULL;}
+		void Clone_copy(Square & s);
 
 	private:
 		Square grid[BOARD_WIDTH][BOARD_HEIGHT];
 
-	
+		// All pieces for each player
 		std::vector<Piece*> white;
 		std::vector<Piece*> black;
+		// The number of pieces with each 2nd type that are still unidentified
+		std::map<Piece::Type, int> white_unknown; 
+		std::map<Piece::Type, int> black_unknown;
+		int white_nUnknown;
+		int black_nUnknown;
 		Piece * white_king;
 		Piece * black_king;
+		
+		Board * parent;
 
 		// Add a move to the vector if it is valid
 		void Move(Piece * p, int x, int y, std::vector<Square*> & v);
diff --git a/agents/silverfish/Makefile b/agents/silverfish/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e2c4927146a01b673ac7a0532d21cb9f36ed43c5
--- /dev/null
+++ b/agents/silverfish/Makefile
@@ -0,0 +1,33 @@
+#Makefile for SilverFish agent
+CXX = g++ -std=gnu++0x -Wall -Werror -pedantic -g
+OBJ = qchess.o agent.o silverfish.o main.o
+LIB = 
+
+LINKOBJ = $(OBJ)
+
+RM = rm -f
+BIN = silver
+
+
+
+$(BIN) : $(LINKOBJ)
+	$(CXX) -o $(BIN) $(LINKOBJ)
+
+%.o : %.cpp
+	$(CXX) -c $<
+
+no_main : $(OBJ)
+
+main.o : main.cpp
+	$(CXX) -c main.cpp
+
+clean :
+	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
+
+clean_full: #cleans up all backup files
+	$(RM) $(BIN) $(OBJ) $(LINKOBJ)
+	$(RM) *.*~
+	$(RM) *~
+
+
+	
\ No newline at end of file
diff --git a/agents/silverfish/agent.cpp b/agents/silverfish/agent.cpp
new file mode 120000
index 0000000000000000000000000000000000000000..9851ddc036b7d68f195916b0a887bdf24d827642
--- /dev/null
+++ b/agents/silverfish/agent.cpp
@@ -0,0 +1 @@
+../c++/agent.cpp
\ No newline at end of file
diff --git a/agents/silverfish/agent.h b/agents/silverfish/agent.h
new file mode 120000
index 0000000000000000000000000000000000000000..8fbe3b61b17ff5914be4f1e82c3e86be08838e75
--- /dev/null
+++ b/agents/silverfish/agent.h
@@ -0,0 +1 @@
+../c++/agent.h
\ No newline at end of file
diff --git a/agents/silverfish/main.cpp b/agents/silverfish/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d24493fcac61c2791e9f77c5286d62ab7966a86
--- /dev/null
+++ b/agents/silverfish/main.cpp
@@ -0,0 +1,38 @@
+/**
+ * silverfish : A Sample agent for UCC::Progcomp2013
+ * @file main.cpp
+ * @purpose The main function 
+ */
+#include <cstdlib>
+#include <cstdio>
+#include <iostream>
+
+#include "silverfish.h"
+
+using namespace std;
+
+/**
+ * @funct main
+ * @purpose The main function; starts the agent
+ * @param argc - Number of arguments, unused
+ * @param argv - Argument string array, unused
+ */
+int main(int argc, char ** argv)
+{
+	srand(time(NULL)); // seed random number generator
+
+	string colour; cin >> colour; // first read the colour of the agent
+
+	try
+	{
+		Silver agent(colour); // create an agent using the colour
+		agent.Run(cin, cout); // run the agent (it will read from cin and output to cout)
+	}
+	catch (const Exception & e)
+	{
+		return 1;
+	}
+	
+	
+	return 0; // Don't use exit(3), because it causes memory leaks in the C++ stdlib
+}
diff --git a/agents/silverfish/qchess.cpp b/agents/silverfish/qchess.cpp
new file mode 120000
index 0000000000000000000000000000000000000000..a7709725099b1b680b6106f972059ca43bf88723
--- /dev/null
+++ b/agents/silverfish/qchess.cpp
@@ -0,0 +1 @@
+../c++/qchess.cpp
\ No newline at end of file
diff --git a/agents/silverfish/qchess.h b/agents/silverfish/qchess.h
new file mode 120000
index 0000000000000000000000000000000000000000..c020ad2673d4ffb5011e013374f1320508a74c4e
--- /dev/null
+++ b/agents/silverfish/qchess.h
@@ -0,0 +1 @@
+../c++/qchess.h
\ No newline at end of file
diff --git a/agents/silverfish/silver b/agents/silverfish/silver
new file mode 100755
index 0000000000000000000000000000000000000000..88d49e340b261c004514c633107b5537ffbcc2cd
Binary files /dev/null and b/agents/silverfish/silver differ
diff --git a/agents/silverfish/silverfish.cpp b/agents/silverfish/silverfish.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20eb9e930f30a3d608f016e233c7ddd822974c56
--- /dev/null
+++ b/agents/silverfish/silverfish.cpp
@@ -0,0 +1,30 @@
+#include "silverfish.h"
+
+using namespace std;
+
+Silver::Silver(const string & colour) : Agent(colour), values()
+{
+	values[Piece::PAWN] = 1;
+	values[Piece::BISHOP] = 3;
+	values[Piece::KNIGHT] = 3;
+	values[Piece::ROOK] = 5;
+	values[Piece::QUEEN] = 9;
+	values[Piece::KING] = 100;
+	values[Piece::UNKNOWN] = 1.5;
+}
+
+Silver::Silver(const string & colour, const map<Piece::Type, double> & new_values) : Agent(colour), values(new_values)
+{
+	//TODO: Assert map is valid
+}
+
+Square & Silver::Select()
+{
+	
+	return Agent::Select();
+}
+
+Square & Silver::Move()
+{
+	return Agent::Move();
+}
\ No newline at end of file
diff --git a/agents/silverfish/silverfish.h b/agents/silverfish/silverfish.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc5b26a532b2344c66637fd9b7a581fb428fe3dc
--- /dev/null
+++ b/agents/silverfish/silverfish.h
@@ -0,0 +1,20 @@
+#ifndef _SILVERFISH_H
+#define _SILVERFISH_H
+
+#include "agent.h"
+
+class Silver : public Agent
+{
+	public:
+		Silver(const std::string & colour);
+		Silver(const std::string & colour, const std::map<Piece::Type, double> & new_values);
+		virtual ~Silver() {}
+		
+		virtual Square & Select();
+		virtual Square & Move();
+
+		std::map<Piece::Type, double> values;
+};
+
+
+#endif //_SILVERFISH_H
\ No newline at end of file