Stuff happened
authorSam Moore <[email protected]>
Thu, 28 Feb 2013 15:53:04 +0000 (23:53 +0800)
committerSam Moore <[email protected]>
Thu, 28 Feb 2013 15:53:04 +0000 (23:53 +0800)
- Fixed C++ agent (yay)
- Added Java agent (ew)
- Renamed some things (why?)

38 files changed:
agents/agent++/Makefile [deleted file]
agents/agent++/agent.cpp [deleted file]
agents/agent++/agent.h [deleted file]
agents/agent++/main.cpp [deleted file]
agents/agent++/qchess.cpp [deleted file]
agents/agent++/qchess.h [deleted file]
agents/c++/agent++ [new file with mode: 0755]
agents/c++/agent.cpp [new file with mode: 0644]
agents/c++/agent.h [new file with mode: 0644]
agents/c++/main.cpp [new file with mode: 0644]
agents/c++/qchess.cpp [new file with mode: 0644]
agents/c++/qchess.h [new file with mode: 0644]
agents/java/Agent.java [new file with mode: 0644]
agents/java/Board.java [new file with mode: 0644]
agents/java/Makefile [new file with mode: 0644]
agents/java/Piece.java [new file with mode: 0644]
agents/java/Reader.java [new file with mode: 0644]
agents/java/Square.java [new file with mode: 0644]
agents/java/cough [new file with mode: 0755]
agents/python/data [new symlink]
agents/python/info [new file with mode: 0644]
agents/python/qchess.py [new symlink]
agents/python/sample.py [new file with mode: 0755]
agents/sample/data [deleted symlink]
agents/sample/info [deleted file]
agents/sample/qchess.py [deleted symlink]
agents/sample/sample.py [deleted file]
qchess/build/exe.linux-x86_64-2.7.zip
qchess/build/exe.win32-2.7.zip
qchess/data/help.txt
qchess/qchess.py
run.sh
vars
web/agent.html
web/agent_python.html
web/agent_text.html
web/get.html
web/get_qchess.html [deleted file]

diff --git a/agents/agent++/Makefile b/agents/agent++/Makefile
deleted file mode 100644 (file)
index 3f9f60f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile for agent++
-
-CXX = g++ -std=gnu++0x -g -Werror -Wall -pedantic 
-LINK_OBJ = qchess.o agent.o main.o
-
-
-BIN = agent++
-
-$(BIN) : $(LINK_OBJ)
-       $(CXX) -o $(BIN) $(LINK_OBJ) 
-
-%.o : %.c
-       $(CXX) $(FLAGS) -c $<
-
-clean :
-       $(RM) $(BIN) $(OBJ) $(LINK_OBJ)
-
-clean_full: #cleans up all backup files
-       $(RM) $(BIN) $(OBJ) $(LINK_OBJ)
-       $(RM) *.*~
-       $(RM) *~
diff --git a/agents/agent++/agent.cpp b/agents/agent++/agent.cpp
deleted file mode 100644 (file)
index d24f1f0..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * agent++ : A Sample agent for UCC::Progcomp2013
- * @file agent.cpp
- * @purpose Definition of Agent class
- */
-
-#include "agent.h"
-#include <cassert> // for sanity checks
-
-using namespace std;
-
-/**
- * @constructor Agent
- * @param new_colour - colour of the Agent
- */
-Agent::Agent(const string & new_colour) : colour(new_colour), board(), selected(NULL)
-{
-       assert(colour == "white" || colour == "black");
-}
-
-/**
- * @destructor ~Agent
- */
-Agent::~Agent()
-{
-
-}
-
-/**
- * @funct Select
- * @purpose Selects a piece at random
- * @returns Square containing the selected piece
- */
-Square & Agent::Select()
-{
-       vector<Piece*> & v = board.pieces(colour); // get pieces
-       int choice = rand() % v.size(); // pick random index
-       Piece * p = v[choice]; // get piece at the index
-       assert(p->colour == colour);
-       selected = p; // update selected
-       //cerr << "Selected " << p->x << "," << p->y << " [" << p->types[0] << "," << p->types[1] << "]\n";
-       return board.square(p->x, p->y); // get Square from board
-}
-
-/**
- * @funct Move
- * @purpose Pick a square to move a selected piece into
- * @returns Square to move last selected piece into
- */
-Square & Agent::Move()
-{
-       assert(selected != NULL);
-       vector<Square*> moves; // all possible moves for selected piece
-       board.Get_moves(selected, moves); // populate possible moves
-       assert(moves.size() > 0); 
-       int choice = rand() % moves.size(); // pick random index
-       return *(moves[choice]); // return that move
-}
-
-/**
- * @funct Run
- * @purpose The "Game Loop" for the agent; read commands and call appropriate function to make responses
- * @param in - Stream to read input from (use std::cin)
- * @param out - Stream to write output to (use std::cout)
- */
-void Agent::Run(istream & in, ostream & out)
-{
-       string cmd; // buffer for tokens
-       while (in.good())
-       {
-               in >> cmd; // read first token only
-               if (cmd == "QUIT")
-               {
-                       break;
-               }
-               else if (cmd == "SELECTION?")
-               {
-                       Square & s = Select(); // get selection
-                       out << s.x << " " << s.y  << "\n"; // return response through output
-               }
-               else if (cmd == "MOVE?")
-               {
-                       Square & s = Move(); // get move
-                       out << s.x << " " << s.y << "\n"; // return response through output
-               }
-               else
-               {
-                       // There were multiple tokens...
-                       stringstream s(cmd);
-                       int x; int y;
-                       s >> x; // Convert first token (in cmd) to an int
-                       in >> y; // Read second token from in
-                       
-                       in >> cmd; // Read third token
-                       
-                       if (cmd == "->") // Token indicates a move was made
-                       {
-                               int x2; int y2; // remaining two tokens indicate destination
-                               in >> x2; in >> y2;
-                               board.Update_move(x, y, x2, y2); // update the board
-                       }
-                       else
-                       {
-                               // Tokens are for a selection
-                               int index; stringstream s2(cmd); 
-                               s2 >> index; // convert third token to an index
-                               in >> cmd; // Read fourth token - the new type of the piece
-                               board.Update_select(x, y, index, cmd); // update the board
-                       }
-                       
-               }
-       }
-}
diff --git a/agents/agent++/agent.h b/agents/agent++/agent.h
deleted file mode 100644 (file)
index bade05b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * agent++ : A Sample agent for UCC::Progcomp2013
- * @file agent.h
- * @purpose Declaration of Agent class
- */
-
-#ifndef _AGENT_H
-#define _AGENT_H
-
-#include <iostream>
-#include <sstream>
-#include "qchess.h" // Declarations of Board, Piece and Square classes; see also qchess.cpp
-
-/**
- * @class Agent
- * @purpose Class that represents an agent which will play qchess
- */
-class Agent
-{
-       public:
-               Agent(const std::string & colour); // initialise with colour
-               virtual ~Agent(); // destructor
-
-               void Run(std::istream & in, std::ostream & out); // agent run loop, specify input and output streams
-               
-               virtual Square & Select(); // select a square (default: random square containing one of my pieces)
-               virtual Square & Move(); // select a move (default: random valid move for selected piece)
-
-       
-       protected:
-               const std::string colour; // colour of the agent; do not change it
-               Board board; // board, see qchess.h
-               Piece * selected; // last piece chosen by Agent::Select, see qchess.h
-               
-};
-
-#endif //_AGENT_H
-
-//EOF
diff --git a/agents/agent++/main.cpp b/agents/agent++/main.cpp
deleted file mode 100644 (file)
index 316df26..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * agent++ : A Sample agent for UCC::Progcomp2013
- * @file main.cpp
- * @purpose The main function 
- */
-#include <cstdlib>
-#include <cstdio>
-#include <iostream>
-
-#include "agent.h" // Declarations for agent, see also agent.cpp
-
-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
-       Agent agent(colour); // create an agent using the colour
-       agent.Run(cin, cout); // run the agent (it will read from cin and output to cout)
-       
-       return 0; // Don't use exit(3), because it causes memory leaks in the C++ stdlib
-}
diff --git a/agents/agent++/qchess.cpp b/agents/agent++/qchess.cpp
deleted file mode 100644 (file)
index 57bee89..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/**
- * agent++ : A Sample agent for UCC::Progcomp2013
- * @file qchess.h
- * @purpose Definitions for game related classes; Piece, Square, Board
- */
-
-#include "qchess.h"
-#include <cassert>
-
-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
- */
-Piece::Piece(int new_x, int new_y, const string & new_colour, const string & type1, const string & type2, int index)
-       : x(new_x), y(new_y), colour(new_colour), type_index(index), types(), current_type()
-{
-       types[0] = type1; types[1] = type2;
-       if (index < 0 || index >= 2)
-       {
-               current_type = "unknown";
-       }
-       else
-       {
-               current_type = types[index];
-       }
-}
-
-/**
- * @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)
-{
-       types[0] = cpy.types[0];
-       types[1] = cpy.types[1];
-}
-
-/**
- * @constructor
- * @param choose_types - Indicates whether Board should setup the 2nd types of pieces; default false
- */
-Board::Board(bool choose_types)
-{
-
-       // initialise all the Squares
-       for (int x = 0; x < BOARD_WIDTH; ++x)
-       {
-               for (int y = 0; y < BOARD_HEIGHT; ++y)
-               {
-                       grid[x][y].x = x;
-                       grid[x][y].y = y;
-               }
-       }
-
-       // const arrays simplify below code
-       string colours[] = {"black", "white"};
-       string types[] = {"rook", "bishop", "knight", "queen", "pawn"};
-
-       // frequency of each type of piece
-       map<string, int> freq;
-       freq["rook"] = 2;
-       freq["bishop"] = 2;
-       freq["knight"] = 2;
-       freq["queen"] = 1;
-       freq["pawn"] = 8;
-       
-       // for white and black...
-       for (int i = 0; i < 2; ++i)
-       {
-               vector<Piece*> & v = pieces(colours[i]); // get vector of pieces
-               
-               
-
-               // add pawns
-               int y = (i == 0) ? 1 : BOARD_HEIGHT-2;
-               for (int x = 0; x < BOARD_WIDTH; ++x)
-               {       
-                       Piece * p = new Piece(x, y, colours[i], "pawn", "unknown");
-                       v.push_back(p);
-               }               
-
-               // add other pieces
-               y = (i == 0) ? 0 : BOARD_HEIGHT-1;
-               v.push_back(new Piece(0, y, colours[i], "rook", "unknown"));
-               v.push_back(new Piece(BOARD_WIDTH-1, y, colours[i], "rook", "unknown"));
-               v.push_back(new Piece(1, y, colours[i], "knight", "unknown"));
-               v.push_back(new Piece(BOARD_WIDTH-2, y, colours[i], "knight", "unknown"));
-               v.push_back(new Piece(2, y, colours[i], "bishop", "unknown"));
-               v.push_back(new Piece(BOARD_WIDTH-3, y, colours[i], "bishop", "unknown"));
-               v.push_back(new Piece(3, y, colours[i], "queen", "unknown"));
-
-               Piece * k = new Piece(4, y, colours[i], "king", "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<string, int> f(freq); 
-               int type2;
-               for (unsigned j = 0; j < v.size(); ++j)
-               {
-                       Piece * p = v[j];
-                       grid[p->x][p->y].piece = p;
-                       if (choose_types)
-                       {
-                               if (p->types[1] != "unknown")
-                                       continue;
-       
-                               do
-                               {
-                                       type2 = rand() % 5;
-                               } while (f[types[type2]] <= 0);
-                               f[types[type2]] -= 1;
-       
-                               p->types[1] = types[type2];                     
-                       }
-
-                       
-               }
-
-               
-
-       }
-
-}
-
-/**
- * @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
- */
-Board::Board(const Board & cpy)
-{
-       for (int x = 0; x < BOARD_WIDTH; ++x)
-       {
-               for (int y = 0; y < BOARD_HEIGHT; ++y)
-               {
-                       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);
-                       }
-               }
-       }
-}
-
-/**
- * @destructor
- */
-Board::~Board()
-{
-       white.clear();
-       black.clear();
-       for (int x = 0; x < BOARD_WIDTH; ++x)
-       {
-               for (int y = 0; y < BOARD_HEIGHT; ++y)
-               {
-                       delete grid[x][y].piece;
-               }
-       }
-
-}
-
-/**
- * @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 type - Type of the Piece
- */
-void Board::Update_select(int x, int y, int index, const string & type)
-{
-       cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << type << "\n";
-       Square & s = grid[x][y];
-       assert(s.piece != NULL);
-       assert(index >= 0 && index < 2);
-       s.piece->type_index = index;
-       s.piece->types[index] = type;
-       s.piece->current_type = type;
-}
-
-/**
- * @funct Update_move
- * @purpose Move a Piece from one square to another
- * @param x1, y1 - Coords of Square containing moving Piece
- * @param x2, y2 - Coords of Square to move into
- *     NOTE: Any Piece in the destination Square will be destroyed ("taken")
- *             and the Board's other members updated accordingly
- */
-void Board::Update_move(int x1, int y1, int x2, int y2)
-{
-       Square & s1 = grid[x1][y1];
-       Square & s2 = grid[x2][y2];
-       if (s2.piece != NULL)
-       {
-               vector<Piece*> & p = pieces(s2.piece->colour);
-               vector<Piece*>::iterator i = p.begin();
-               while (i != p.end())
-               {
-                       if (*i == s2.piece)
-                       {
-                               p.erase(i);
-                               break;
-                       }
-                       ++i;
-               }
-               Piece * k = king(s2.piece->colour);
-               if (k == s2.piece)
-               {
-                       if (k->colour == "white")
-                               white_king = NULL;
-                       else
-                               black_king = NULL;
-               }
-
-               delete s2.piece;
-       }       
-
-       s1.piece->x = s2.x;
-       s1.piece->y = s2.y;
-
-       s2.piece = s1.piece;
-       s1.piece = NULL;        
-}
-
-/**
- * @funct Get_moves
- * @purpose Get all moves for a Piece and store them
- * @param p - Piece
- * @param v - vector to store Squares in. Will *not* be cleared.
- */
-void Board::Get_moves(Piece * p, vector<Square*> & v)
-{
-       assert(p->current_type != "unknown");
-       int x = p->x; int y = p->y;
-       if (p->current_type == "king")
-       {
-               Move(p, x+1, y, v);
-               Move(p, x-1, y, v);
-               Move(p, x, y+1, v);
-               Move(p, x, y-1, v);
-               Move(p, x+1, y+1, v);
-               Move(p, x+1, y-1, v);
-               Move(p, x-1, y+1, v);
-               Move(p, x-1, y-1, v);
-       }
-       else if (p->current_type == "knight")
-       {
-               Move(p, x+2, y+1, v);
-               Move(p, x+2, y-1, v);
-               Move(p, x-2, y+1, v);
-               Move(p, x-2, y-1, v);
-               Move(p, x+1, y+2, v);
-               Move(p, x-1, y+2, v);
-               Move(p, x+1, y-2, v);
-               Move(p, x-1, y-2, v); 
-       }
-       else if (p->current_type == "pawn")
-       {
-               int y1 = (p->colour == "white") ? BOARD_HEIGHT-2 : 1;
-               int y2 = (p->colour == "white") ? y1 - 2 : y1 + 2;
-               if (p->types[0] == "pawn" && p->y == y1)
-               {
-                       
-                       Move(p, x, y2, v);
-               }
-               y2 = (p->colour == "white") ? y - 1 : y + 1;
-               Move(p, x, y2, v);
-
-               if (Valid_position(x-1, y2) && grid[x-1][y2].piece != NULL)
-                       Move(p, x-1, y2, v);
-               if (Valid_position(x+1, y2) && grid[x+1][y2].piece != NULL)
-                       Move(p, x+1, y2, v);
-       }
-       else if (p->current_type == "bishop")
-       {
-               Scan(p, 1, 1, v);
-               Scan(p, 1, -1, v);
-               Scan(p, -1, 1, v);
-               Scan(p, -1, -1, v);
-       }
-       else if (p->current_type == "rook")
-       {
-               Scan(p, 1, 0, v);
-               Scan(p, -1, 0, v);
-               Scan(p, 0, 1, v);
-               Scan(p, 0, -1, v);
-       }
-       else if (p->current_type == "queen")
-       {
-               Scan(p, 1, 1, v);
-               Scan(p, 1, -1, v);
-               Scan(p, -1, 1, v);
-               Scan(p, -1, -1, v);
-               Scan(p, 1, 0, v);
-               Scan(p, -1, 0, v);
-               Scan(p, 0, 1, v);
-               Scan(p, 0, -1, v);
-       }
-
-} 
-
-/**
- * @funct Move
- * @purpose Add a move to the vector, if it is valid
- * @param p - Piece that would move
- * @param x, y - Destination Square coords
- * @param v - vector to put the destination Square in, if the move is valid
- */
-void Board::Move(Piece * p, int x, int y, vector<Square*> & v)
-{
-       if (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
-       {
-               v.push_back(&(grid[x][y]));
-       }
-       //else
-       //      cerr << "Square " << x << "," << y << " invalid; " << grid[x][y].piece << "\n";
-}
-
-/**
- * @funct Scan
- * @purpose Add moves in a specified direction to the vector, until we get to an invalid move
- * @param p - Piece to start scanning from
- * @param vx, vy - "velocity" - change in coords each move
- * @param v - vector to store valid Squares in
- */
-void Board::Scan(Piece * p, int vx, int vy, vector<Square*> & v)
-{
-       int x = p->x + vx;
-       int y = p->y + vy;
-       while (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
-       {
-               v.push_back(&(grid[x][y]));
-               x += vx;
-               y += vy;
-       }
-}
diff --git a/agents/agent++/qchess.h b/agents/agent++/qchess.h
deleted file mode 100644 (file)
index 154e440..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * agent++ : A Sample agent for UCC::Progcomp2013
- * @file qchess.h
- * @purpose Declarations for game related classes; Piece, Square, Board
- */
-
-#ifndef _QCHESS_H
-#define _QCHESS_H
-
-
-// board height and width (don't change!)
-#define BOARD_HEIGHT 8
-#define BOARD_WIDTH 8
-
-#include <string>
-#include <vector>
-#include <map>
-#include <cstdlib>
-#include <iostream>
-
-/**
- * @class Piece
- * @purpose Represent a quantum chess piece
- */
-class Piece
-{
-       public:
-               Piece(int x, int y, const std::string & new_colour, const std::string & type1 = "unknown", const std::string & type2 = "unknown", int new_type_index = -1); // constructor
-               Piece(const Piece & cpy); // copy constructor
-               virtual ~Piece() {} // destructor
-
-               int x; int y; // position of the piece
-               std::string colour; // colour of the piece
-               int type_index; // indicates state the piece is in; 0, 1, or -1 (unknown)
-               std::string types[2]; // states of the piece
-               std::string current_type; // current state of the piece
-               
-
-};
-
-/**
- * @class Square
- * @purpose Represent a Square on the board; not necessarily occupied
- */
-class Square
-{
-       public:
-               Square() : x(-1), y(-1), piece(NULL) {} // constructor
-               Square(int new_x, int new_y, Piece * new_piece = NULL) : x(new_x), y(new_y), piece(new_piece) {} //UNUSED
-               Square(const Square & cpy) : x(cpy.x), y(cpy.y), piece(cpy.piece) {} // copy constructor (UNUSED)
-               virtual ~Square() {} //destructor
-               int x;  int y; // position of the square
-               Piece * piece; // Piece that is in the Square (NULL if unoccupied)
-};
-
-/**
- * @class Board
- * @purpose Represent a quantum chess board
- */
-class Board
-{
-       public:
-               Board(bool choose_types = false); // constructor
-               Board(const Board & cpy); // copy constructor
-               virtual ~Board(); // destructor
-
-
-               // helper; return vector of pieces given player colour
-               std::vector<Piece*> & pieces(const std::string & colour) {return ((colour == "white") ? white : black);}        
-               // helper; return king given player colour      
-               Piece * king(const std::string & colour) {return ((colour == "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
-       
-               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
-
-               // 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);}
-
-       private:
-               Square grid[BOARD_WIDTH][BOARD_HEIGHT];
-
-       
-               std::vector<Piece*> white;
-               std::vector<Piece*> black;
-               Piece * white_king;
-               Piece * black_king;
-
-               // Add a move to the vector if it is valid
-               void Move(Piece * p, int x, int y, std::vector<Square*> & v);
-
-               // Add all valid moves in a direction, stopping at the first invalid move
-               void Scan(Piece * p, int vx, int vy, std::vector<Square*> & v);
-};
-
-#endif //_QCHESS_H
-
-//EOF
diff --git a/agents/c++/agent++ b/agents/c++/agent++
new file mode 100755 (executable)
index 0000000..b4d3540
Binary files /dev/null and b/agents/c++/agent++ differ
diff --git a/agents/c++/agent.cpp b/agents/c++/agent.cpp
new file mode 100644 (file)
index 0000000..2014f55
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * agent++ : A Sample agent for UCC::Progcomp2013
+ * @file agent.cpp
+ * @purpose Definition of Agent class
+ */
+
+#include "agent.h"
+#include <cassert> // for sanity checks
+
+using namespace std;
+
+/**
+ * @constructor Agent
+ * @param new_colour - colour of the Agent
+ */
+Agent::Agent(const string & new_colour) : colour(Piece::str2colour(new_colour)), board(), selected(NULL)
+{
+
+}
+
+/**
+ * @destructor ~Agent
+ */
+Agent::~Agent()
+{
+
+}
+
+/**
+ * @funct Select
+ * @purpose Selects a piece at random
+ * @returns Square containing the selected piece
+ */
+Square & Agent::Select()
+{
+       vector<Piece*> & v = board.pieces(colour); // get pieces
+       int choice = rand() % v.size(); // pick random index
+       Piece * p = v[choice]; // get piece at the index
+       assert(p->colour == colour);
+       selected = p; // update selected
+       //cerr << "Selected " << p->x << "," << p->y << " [" << p->types[0] << "," << p->types[1] << "]\n";
+       return board.square(p->x, p->y); // get Square from board
+}
+
+/**
+ * @funct Move
+ * @purpose Pick a square to move a selected piece into
+ * @returns Square to move last selected piece into
+ */
+Square & Agent::Move()
+{
+       assert(selected != NULL);
+       vector<Square*> moves; // all possible moves for selected piece
+       board.Get_moves(selected, moves); // populate possible moves
+       assert(moves.size() > 0); 
+       int choice = rand() % moves.size(); // pick random index
+       return *(moves[choice]); // return that move
+}
+
+/**
+ * @funct Run
+ * @purpose The "Game Loop" for the agent; read commands and call appropriate function to make responses
+ * @param in - Stream to read input from (use std::cin)
+ * @param out - Stream to write output to (use std::cout)
+ */
+void Agent::Run(istream & in, ostream & out)
+{
+       string cmd; // buffer for tokens
+       while (in.good())
+       {
+               in >> cmd; // read first token only
+               if (cmd == "QUIT")
+               {
+                       break;
+               }
+               else if (cmd == "SELECTION?")
+               {
+                       Square & s = Select(); // get selection
+                       out << s.x << " " << s.y  << "\n"; // return response through output
+               }
+               else if (cmd == "MOVE?")
+               {
+                       Square & s = Move(); // get move
+                       out << s.x << " " << s.y << "\n"; // return response through output
+               }
+               else
+               {
+                       // There were multiple tokens...
+                       stringstream s(cmd);
+                       int x; int y;
+                       s >> x; // Convert first token (in cmd) to an int
+                       in >> y; // Read second token from in
+                       
+                       in >> cmd; // Read third token
+                       
+                       if (cmd == "->") // Token indicates a move was made
+                       {
+                               int x2; int y2; // remaining two tokens indicate destination
+                               in >> x2; in >> y2;
+                               board.Update_move(x, y, x2, y2); // update the board
+                       }
+                       else
+                       {
+                               // Tokens are for a selection
+                               int index; stringstream s2(cmd); 
+                               s2 >> index; // convert third token to an index
+                               in >> cmd; // Read fourth token - the new type of the piece
+                               board.Update_select(x, y, index, cmd); // update the board
+                       }
+                       
+               }
+       }
+}
diff --git a/agents/c++/agent.h b/agents/c++/agent.h
new file mode 100644 (file)
index 0000000..9c05edd
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * agent++ : A Sample agent for UCC::Progcomp2013
+ * @file agent.h
+ * @purpose Declaration of Agent class
+ */
+
+#ifndef _AGENT_H
+#define _AGENT_H
+
+#include <iostream>
+#include <sstream>
+#include "qchess.h" // Declarations of Board, Piece and Square classes; see also qchess.cpp
+
+/**
+ * @class Agent
+ * @purpose Class that represents an agent which will play qchess
+ */
+class Agent
+{
+       public:
+               Agent(const std::string & colour); // initialise with colour
+               virtual ~Agent(); // destructor
+
+               void Run(std::istream & in, std::ostream & out); // agent run loop, specify input and output streams
+               
+               virtual Square & Select(); // select a square (default: random square containing one of my pieces)
+               virtual Square & Move(); // select a move (default: random valid move for selected piece)
+
+       
+       protected:
+               const Piece::Colour colour; // colour of the agent; do not change it
+               Board board; // board, see qchess.h
+               Piece * selected; // last piece chosen by Agent::Select, see qchess.h
+               
+};
+
+#endif //_AGENT_H
+
+//EOF
diff --git a/agents/c++/main.cpp b/agents/c++/main.cpp
new file mode 100644 (file)
index 0000000..d0d7d4a
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * agent++ : A Sample agent for UCC::Progcomp2013
+ * @file main.cpp
+ * @purpose The main function 
+ */
+#include <cstdlib>
+#include <cstdio>
+#include <iostream>
+
+#include "agent.h" // Declarations for agent, see also agent.cpp
+
+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
+       {
+               Agent 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/c++/qchess.cpp b/agents/c++/qchess.cpp
new file mode 100644 (file)
index 0000000..fbca352
--- /dev/null
@@ -0,0 +1,395 @@
+/**
+ * agent++ : A Sample agent for UCC::Progcomp2013
+ * @file qchess.h
+ * @purpose Definitions for game related classes; Piece, Square, Board
+ */
+
+#include "qchess.h"
+#include <cassert>
+
+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
+ */
+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()
+{
+       types[0] = type1; types[1] = type2;
+       if (index < 0 || index >= 2)
+       {
+               current_type = Piece::UNKNOWN;
+       }
+       else
+       {
+               current_type = types[index];
+       }
+}
+
+/**
+ * @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)
+{
+       types[0] = cpy.types[0];
+       types[1] = cpy.types[1];
+}
+
+/**
+ * @constructor
+ * @param choose_types - Indicates whether Board should setup the 2nd types of pieces; default false
+ */
+Board::Board(bool choose_types)
+{
+
+       // initialise all the Squares
+       for (int x = 0; x < BOARD_WIDTH; ++x)
+       {
+               for (int y = 0; y < BOARD_HEIGHT; ++y)
+               {
+                       grid[x][y].x = x;
+                       grid[x][y].y = y;
+               }
+       }
+
+       // const arrays simplify below code
+       Piece::Colour colours[] = {Piece::BLACK, Piece::WHITE};
+       Piece::Type types[] = {Piece::PAWN, Piece::BISHOP, Piece::KNIGHT, Piece::ROOK, Piece::QUEEN};
+
+       // frequency of each type of piece
+       map<Piece::Type, int> freq;
+       freq[Piece::ROOK] = 2;
+       freq[Piece::BISHOP] = 2;
+       freq[Piece::KNIGHT] = 2;
+       freq[Piece::QUEEN] = 1;
+       freq[Piece::PAWN] = 8;
+       
+       // for white and black...
+       for (int i = 0; i < 2; ++i)
+       {
+               vector<Piece*> & v = pieces(colours[i]); // get vector of pieces
+               
+               
+
+               // add pawns
+               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);
+               }               
+
+               // 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);
+               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); 
+               int type2;
+               for (unsigned j = 0; j < v.size(); ++j)
+               {
+                       Piece * p = v[j];
+                       grid[p->x][p->y].piece = p;
+                       if (choose_types)
+                       {
+                               if (p->types[1] != Piece::UNKNOWN)
+                                       continue;
+       
+                               do
+                               {
+                                       type2 = rand() % 5;
+                               } while (f[types[type2]] <= 0);
+                               f[types[type2]] -= 1;
+       
+                               p->types[1] = types[type2];                     
+                       }
+
+                       
+               }
+
+               
+
+       }
+
+}
+
+/**
+ * @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
+ */
+Board::Board(const Board & cpy)
+{
+       for (int x = 0; x < BOARD_WIDTH; ++x)
+       {
+               for (int y = 0; y < BOARD_HEIGHT; ++y)
+               {
+                       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);
+                       }
+               }
+       }
+}
+
+/**
+ * @destructor
+ */
+Board::~Board()
+{
+       white.clear();
+       black.clear();
+       for (int x = 0; x < BOARD_WIDTH; ++x)
+       {
+               for (int y = 0; y < BOARD_HEIGHT; ++y)
+               {
+                       delete grid[x][y].piece;
+               }
+       }
+
+}
+
+/**
+ * @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 type - Type of the Piece
+ */
+void Board::Update_select(int x, int y, int index, const string & type)
+{
+       cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << type << "\n";
+       Square & s = grid[x][y];
+       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];
+}
+
+/**
+ * @funct Update_move
+ * @purpose Move a Piece from one square to another
+ * @param x1, y1 - Coords of Square containing moving Piece
+ * @param x2, y2 - Coords of Square to move into
+ *     NOTE: Any Piece in the destination Square will be destroyed ("taken")
+ *             and the Board's other members updated accordingly
+ */
+void Board::Update_move(int x1, int y1, int x2, int y2)
+{
+       Square & s1 = grid[x1][y1];
+       Square & s2 = grid[x2][y2];
+       if (s2.piece != NULL)
+       {
+               vector<Piece*> & p = pieces(s2.piece->colour);
+               vector<Piece*>::iterator i = p.begin();
+               while (i != p.end())
+               {
+                       if (*i == s2.piece)
+                       {
+                               p.erase(i);
+                               break;
+                       }
+                       ++i;
+               }
+               Piece * k = king(s2.piece->colour);
+               if (k == s2.piece)
+               {
+                       if (k->colour == Piece::WHITE)
+                               white_king = NULL;
+                       else
+                               black_king = NULL;
+               }
+
+               delete s2.piece;
+       }       
+
+       s1.piece->x = s2.x;
+       s1.piece->y = s2.y;
+
+       s2.piece = s1.piece;
+       s1.piece = NULL;        
+}
+
+/**
+ * @funct Get_moves
+ * @purpose Get all moves for a Piece and store them
+ * @param p - Piece
+ * @param v - vector to store Squares in. Will *not* be cleared.
+ */
+void Board::Get_moves(Piece * p, vector<Square*> & v)
+{
+       assert(p->current_type != Piece::UNKNOWN);
+       int x = p->x; int y = p->y;
+       if (p->current_type == Piece::KING)
+       {
+               Move(p, x+1, y, v);
+               Move(p, x-1, y, v);
+               Move(p, x, y+1, v);
+               Move(p, x, y-1, v);
+               Move(p, x+1, y+1, v);
+               Move(p, x+1, y-1, v);
+               Move(p, x-1, y+1, v);
+               Move(p, x-1, y-1, v);
+       }
+       else if (p->current_type == Piece::KNIGHT)
+       {
+               Move(p, x+2, y+1, v);
+               Move(p, x+2, y-1, v);
+               Move(p, x-2, y+1, v);
+               Move(p, x-2, y-1, v);
+               Move(p, x+1, y+2, v);
+               Move(p, x-1, y+2, v);
+               Move(p, x+1, y-2, v);
+               Move(p, x-1, y-2, v); 
+       }
+       else if (p->current_type == Piece::PAWN)
+       {
+               int y1 = (p->colour == Piece::WHITE) ? BOARD_HEIGHT-2 : 1;
+               int y2 = (p->colour == Piece::WHITE) ? y1 - 2 : y1 + 2;
+               if (p->types[0] == Piece::PAWN && p->y == y1)
+               {
+                       
+                       Move(p, x, y2, v);
+               }
+               y2 = (p->colour == Piece::WHITE) ? y - 1 : y + 1;
+               Move(p, x, y2, v);
+
+               if (Valid_position(x-1, y2) && grid[x-1][y2].piece != NULL)
+                       Move(p, x-1, y2, v);
+               if (Valid_position(x+1, y2) && grid[x+1][y2].piece != NULL)
+                       Move(p, x+1, y2, v);
+       }
+       else if (p->current_type == Piece::BISHOP)
+       {
+               Scan(p, 1, 1, v);
+               Scan(p, 1, -1, v);
+               Scan(p, -1, 1, v);
+               Scan(p, -1, -1, v);
+       }
+       else if (p->current_type == Piece::ROOK)
+       {
+               Scan(p, 1, 0, v);
+               Scan(p, -1, 0, v);
+               Scan(p, 0, 1, v);
+               Scan(p, 0, -1, v);
+       }
+       else if (p->current_type == Piece::QUEEN)
+       {
+               Scan(p, 1, 1, v);
+               Scan(p, 1, -1, v);
+               Scan(p, -1, 1, v);
+               Scan(p, -1, -1, v);
+               Scan(p, 1, 0, v);
+               Scan(p, -1, 0, v);
+               Scan(p, 0, 1, v);
+               Scan(p, 0, -1, v);
+       }
+
+} 
+
+/**
+ * @funct Move
+ * @purpose Add a move to the vector, if it is valid
+ * @param p - Piece that would move
+ * @param x, y - Destination Square coords
+ * @param v - vector to put the destination Square in, if the move is valid
+ */
+void Board::Move(Piece * p, int x, int y, vector<Square*> & v)
+{
+       if (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
+       {
+               v.push_back(&(grid[x][y]));
+       }
+       //else
+       //      cerr << "Square " << x << "," << y << " invalid; " << grid[x][y].piece << "\n";
+}
+
+/**
+ * @funct Scan
+ * @purpose Add moves in a specified direction to the vector, until we get to an invalid move
+ * @param p - Piece to start scanning from
+ * @param vx, vy - "velocity" - change in coords each move
+ * @param v - vector to store valid Squares in
+ */
+void Board::Scan(Piece * p, int vx, int vy, vector<Square*> & v)
+{
+       int x = p->x + vx;
+       int y = p->y + vy;
+       while (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
+       {
+               v.push_back(&(grid[x][y]));
+               if (grid[x][y].piece != NULL)
+                       break;
+               x += vx;
+               y += vy;
+       }
+}
+
+/**
+ * @funct str2type
+ * @purpose Convert string to Piece::Type
+ * @param str - The string
+ * @returns A Piece::Type
+ */
+Piece::Type Piece::str2type(const string & str)
+{
+       if (str == "king")
+               return Piece::KING;
+       else if (str == "queen")
+               return Piece::QUEEN;
+       else if (str == "rook")
+               return Piece::ROOK;
+       else if (str == "bishop")
+               return Piece::BISHOP;
+       else if (str == "knight")
+               return Piece::KNIGHT;
+       else if (str == "pawn")
+               return Piece::PAWN;
+       else if (str == "unknown")
+               return Piece::UNKNOWN;
+
+       throw Exception("Piece::str2type", "String \"%s\" doesn't represent a type", str.c_str());
+       return Piece::UNKNOWN;
+}
+
+/**
+ * @funct str2colour
+ * @purpose Convert string to Piece::Colour
+ * @param str - The string
+ * @returns A Piece::Colour
+ */
+Piece::Colour Piece::str2colour(const string & str)
+{
+       if (str == "white")
+               return Piece::WHITE;
+       else if (str == "black")
+               return Piece::BLACK;
+
+       throw Exception("Piece::str2colour", "string \"%s\" is not white|black", str.c_str());
+       return Piece::BLACK; // should never get here
+}
+
+
diff --git a/agents/c++/qchess.h b/agents/c++/qchess.h
new file mode 100644 (file)
index 0000000..b2b499a
--- /dev/null
@@ -0,0 +1,129 @@
+/**
+ * agent++ : A Sample agent for UCC::Progcomp2013
+ * @file qchess.h
+ * @purpose Declarations for game related classes; Piece, Square, Board
+ */
+
+#ifndef _QCHESS_H
+#define _QCHESS_H
+
+
+// board height and width (don't change!)
+#define BOARD_HEIGHT 8
+#define BOARD_WIDTH 8
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include <iostream>
+
+#include <stdarg.h>
+#include <cstdio> // for vfprintf... for the Exception
+
+/**
+ * @class Piece
+ * @purpose Represent a quantum chess piece
+ */
+class Piece
+{
+       public:
+
+               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
+               Colour colour; // colour of the piece
+               int type_index; // indicates state the piece is in; 0, 1, or -1 (unknown)
+               Type types[2]; // states of the piece
+               Type current_type; // current state of the piece
+               
+               static Type str2type(const std::string & str);
+               static Colour str2colour(const std::string & str);
+
+};
+
+/**
+ * @class Square
+ * @purpose Represent a Square on the board; not necessarily occupied
+ */
+class Square
+{
+       public:
+               Square() : x(-1), y(-1), piece(NULL) {} // constructor
+               Square(int new_x, int new_y, Piece * new_piece = NULL) : x(new_x), y(new_y), piece(new_piece) {} //UNUSED
+               Square(const Square & cpy) : x(cpy.x), y(cpy.y), piece(cpy.piece) {} // copy constructor (UNUSED)
+               virtual ~Square() {} //destructor
+               int x;  int y; // position of the square
+               Piece * piece; // Piece that is in the Square (NULL if unoccupied)
+};
+
+/**
+ * @class Board
+ * @purpose Represent a quantum chess board
+ */
+class Board
+{
+       public:
+               Board(bool choose_types = false); // constructor
+               Board(const Board & cpy); // copy constructor
+               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 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
+       
+               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
+
+               // 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);}
+
+       private:
+               Square grid[BOARD_WIDTH][BOARD_HEIGHT];
+
+       
+               std::vector<Piece*> white;
+               std::vector<Piece*> black;
+               Piece * white_king;
+               Piece * black_king;
+
+               // Add a move to the vector if it is valid
+               void Move(Piece * p, int x, int y, std::vector<Square*> & v);
+
+               // Add all valid moves in a direction, stopping at the first invalid move
+               void Scan(Piece * p, int vx, int vy, std::vector<Square*> & v);
+};
+
+/**
+ * @class Exception
+ * @purpose The only exception.
+ */
+class Exception
+{
+       public:
+               Exception(const char * funct, const char * fmt, ...)
+               {
+                       fprintf(stderr, "Exception in %s - ", funct);
+                       va_list va;
+                       va_start(va, fmt);
+                       vfprintf(stderr, fmt, va);
+                       va_end(va);
+                       fprintf(stderr, "\n");                  
+               }
+       
+};
+
+#endif //_QCHESS_H
+
+//EOF
diff --git a/agents/java/Agent.java b/agents/java/Agent.java
new file mode 100644 (file)
index 0000000..a47f770
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * @class Agent
+ * @purpose Class that represents an agent which will play qchess
+ */
+
+import java.util.Random;
+import java.util.Vector;
+
+class Agent
+{
+       public Agent(String colour) throws Exception
+       {
+               this.colour = Piece.str2colour(colour);
+
+               this.board = new Board();
+               this.selected = null;
+               this.rand = new Random();
+       }
+
+       public static void main(String [] args)
+       {
+               String colour = Reader.readLine();
+               
+               try
+               {
+                       Agent agent = new Agent(colour);
+                       agent.Run();
+               }
+               catch (Exception e)
+               {
+                       //System.err.println("EXCEPTION: agent.Run - "+e); 
+                       e.printStackTrace();
+               }
+       }
+
+       public void Run() throws Exception
+       {
+               while (true)
+               {
+                       Vector<String> v = Reader.readTokens();
+                       
+                       String cmd = v.get(0);
+                       
+                       if (cmd.compareTo("QUIT") == 0)
+                               break;
+                       else if (cmd.compareTo("SELECTION?") == 0)
+                       {
+                               Square s = select();
+                               System.out.println(Integer.toString(s.x) + " " + Integer.toString(s.y));
+                       }
+                       else if (cmd.compareTo("MOVE?") == 0)
+                       {
+                               Square s = move();
+                               System.out.println(Integer.toString(s.x) + " " + Integer.toString(s.y));
+                       }
+                       else
+                       {
+                               int x = Integer.parseInt(v.get(0));
+                               int y = Integer.parseInt(v.get(1));
+                               if (v.get(2).compareTo("->") == 0)
+                               {
+                                       int x2 = Integer.parseInt(v.get(3));
+                                       int y2 = Integer.parseInt(v.get(4));
+                                       board.Update_move(x, y, x2, y2);
+                               }
+                               else
+                               {
+                                       int index = Integer.parseInt(v.get(2));
+                                       String type = v.get(3);
+                                       board.Update_select(x, y, index, type);
+                               }
+                       }
+               }
+       }
+               
+       public Square select() throws Exception
+       {
+               Vector<Piece> p = board.pieces(colour);
+               int choice = rand.nextInt(p.size());
+               Square s = board.Get_square(p.get(choice).x, p.get(choice).y);
+               if (s.piece == null)
+                       throw new Exception("ARGH");
+               selected = s.piece;
+               return s;
+       }
+
+       public Square move()
+       {
+               Vector<Square> v = new Vector<Square>();
+               board.Get_moves(selected, v);
+               return v.get(rand.nextInt(v.size()));
+       }
+       
+       private final Piece.Colour colour; // colour of the agent; do not change it
+       private Board board;
+       private Piece selected; 
+       private Random rand;
+               
+};
diff --git a/agents/java/Board.java b/agents/java/Board.java
new file mode 100644 (file)
index 0000000..5c7d2ad
--- /dev/null
@@ -0,0 +1,224 @@
+/**
+ * @class Board
+ * @purpose Represent a quantum chess board
+ */
+
+import java.util.Vector;
+
+class Board
+{
+       public static final int WIDTH = 8;
+       public static final int HEIGHT = 8;
+       public  Board()
+       {
+       
+               this.grid = new Square[Board.WIDTH][Board.HEIGHT];
+               for (int x = 0; x < Board.WIDTH; ++x)
+               {
+                       for (int y = 0; y < Board.HEIGHT; ++y)
+                       {
+                               this.grid[x][y] = new Square(x, y, null);
+                               this.grid[x][y].x = x;
+                               this.grid[x][y].y = y;
+                       }
+               }
+               Piece.Colour[] colours = {Piece.Colour.BLACK, Piece.Colour.WHITE};
+               
+               this.white = new Vector<Piece>();
+               this.black = new Vector<Piece>();
+               for (int i = 0; i < colours.length; ++i)
+               {
+                       Vector<Piece> p = pieces(colours[i]);
+                       
+                       // add pawns
+                       int y = (i == 0) ? 1 : Board.HEIGHT-2;
+                       for (int x = 0; x < Board.WIDTH; ++x)
+                       {       
+                               p.add(new Piece(x, y, colours[i], Piece.Type.PAWN, Piece.Type.UNKNOWN));
+                       }
+
+                       // add major pieces
+                       y = (i == 0) ? 1 : Board.HEIGHT-1;
+                       
+                       p.add(new Piece(0, y, colours[i], Piece.Type.ROOK, Piece.Type.UNKNOWN));
+                       p.add(new Piece(1, y, colours[i], Piece.Type.KNIGHT, Piece.Type.UNKNOWN));
+                       p.add(new Piece(2, y, colours[i], Piece.Type.BISHOP, Piece.Type.UNKNOWN));
+                       Piece k = new Piece(3, y, colours[i], Piece.Type.KING, Piece.Type.KING);
+                       p.add(k);
+                       if (i == 0)
+                               white_king = k;
+                       else
+                               black_king = k;
+                       p.add(new Piece(4, y, colours[i], Piece.Type.QUEEN, Piece.Type.UNKNOWN));
+                       p.add(new Piece(5, y, colours[i], Piece.Type.BISHOP, Piece.Type.UNKNOWN));
+                       p.add(new Piece(6, y, colours[i], Piece.Type.KNIGHT, Piece.Type.UNKNOWN));
+                       p.add(new Piece(7, y, colours[i], Piece.Type.ROOK, Piece.Type.UNKNOWN));
+               
+                       for (int j = 0; j < p.size(); ++j)
+                       {
+                               Piece pp = p.get(j);
+                               grid[pp.x][pp.y].piece = pp;
+                       }
+                       
+               }
+               
+       }
+
+
+       public  Vector<Piece> pieces(Piece.Colour colour) 
+       {
+               return ((colour == Piece.Colour.WHITE) ? white : black);
+       }       
+       public  Piece king(Piece.Colour colour) 
+       {
+               return ((colour == Piece.Colour.WHITE) ? white_king : black_king);
+       }
+               
+       public  void Update_move(int x, int y, int x2, int y2)
+       {
+               Square s1 = grid[x][y];
+               Square s2 = grid[x2][y2];
+               if (s2.piece != null)
+               {
+                       Vector<Piece> v = pieces(s2.piece.colour);
+                       v.remove(s2.piece);
+                       
+                       if (s2.piece == king(s2.piece.colour))
+                       {
+                               if (s2.piece.colour == Piece.Colour.WHITE)
+                                       white_king = null;
+                               else
+                                       black_king = null;
+                       }
+               }
+               
+               s1.piece.x = x2;
+               s1.piece.y = y2;
+               s2.piece = s1.piece;
+               s1.piece = null;
+       }
+       public  void Update_select(int x, int y, int index, String type) throws Exception
+       {
+               Square s = grid[x][y];
+               s.piece.type_index = index;
+               s.piece.types[index] = Piece.str2type(type);
+               s.piece.current_type = s.piece.types[index];
+               
+       }
+       
+       public  Square Get_square(int x, int y) 
+       {
+               return grid[x][y]; // get square on board
+       }
+
+       public void Get_moves(Piece p, Vector<Square> v)
+       {
+               int x = p.x; 
+               int y = p.y;
+               if (p.current_type == Piece.Type.KING)
+               {
+                       Move(p, x+1, y, v);
+                       Move(p, x-1, y, v);
+                       Move(p, x, y+1, v);
+                       Move(p, x, y-1, v);
+                       Move(p, x+1, y+1, v);
+                       Move(p, x+1, y-1, v);
+                       Move(p, x-1, y+1, v);
+                       Move(p, x-1, y-1, v);
+               }
+               else if (p.current_type == Piece.Type.KNIGHT)
+               {
+                       Move(p, x+2, y+1, v);
+                       Move(p, x+2, y-1, v);
+                       Move(p, x-2, y+1, v);
+                       Move(p, x-2, y-1, v);
+                       Move(p, x+1, y+2, v);
+                       Move(p, x-1, y+2, v);
+                       Move(p, x+1, y-2, v);
+                       Move(p, x-1, y-2, v); 
+               }
+               else if (p.current_type == Piece.Type.PAWN)
+               {
+                       int y1 = (p.colour == Piece.Colour.WHITE) ? Board.HEIGHT-2 : 1;
+                       int y2 = (p.colour == Piece.Colour.WHITE) ? y1 - 2 : y1 + 2;
+                       if (p.types[0] == Piece.Type.PAWN && p.y == y1)
+                       {
+                               
+                               Move(p, x, y2, v);
+                       }
+                       y2 = (p.colour == Piece.Colour.WHITE) ? y - 1 : y + 1;
+                       Move(p, x, y2, v);
+       
+                       if (Valid_position(x-1, y2) && grid[x-1][y2].piece != null)
+                               Move(p, x-1, y2, v);
+                       if (Valid_position(x+1, y2) && grid[x+1][y2].piece != null)
+                               Move(p, x+1, y2, v);
+               }
+               else if (p.current_type == Piece.Type.BISHOP)
+               {
+                       Scan(p, 1, 1, v);
+                       Scan(p, 1, -1, v);
+                       Scan(p, -1, 1, v);
+                       Scan(p, -1, -1, v);
+               }
+               else if (p.current_type == Piece.Type.ROOK)
+               {
+                       Scan(p, 1, 0, v);
+                       Scan(p, -1, 0, v);
+                       Scan(p, 0, 1, v);
+                       Scan(p, 0, -1, v);
+               }
+               else if (p.current_type == Piece.Type.QUEEN)
+               {
+                       Scan(p, 1, 1, v);
+                       Scan(p, 1, -1, v);
+                       Scan(p, -1, 1, v);
+                       Scan(p, -1, -1, v);
+                       Scan(p, 1, 0, v);
+                       Scan(p, -1, 0, v);
+                       Scan(p, 0, 1, v);
+                       Scan(p, 0, -1, v);
+               }
+
+       }
+
+       // determine if position is on the board
+       public boolean Valid_position(int x, int y) 
+       {
+               return (x >= 0 && x <= Board.WIDTH-1 && y >= 0 && y <= Board.HEIGHT-1);
+       }
+
+       private Square[][] grid;
+
+       
+       private Vector<Piece> white;
+       private Vector<Piece> black;
+       private Piece white_king;
+       private Piece black_king;
+
+               // Add a move to the vector if it is valid
+       private void Move(Piece p, int x, int y, Vector<Square> v)
+       {
+               if (Valid_position(x, y) && (grid[x][y].piece == null || grid[x][y].piece.colour != p.colour))
+               {
+                       v.add(grid[x][y]);
+               }
+       }
+
+               // Add all valid moves in a direction, stopping at the first invalid move
+       private void Scan(Piece p, int vx, int vy, Vector<Square> v)
+       {
+               int x = p.x + vx;
+               int y = p.y + vy;
+               while (Valid_position(x, y) && (grid[x][y].piece == null || grid[x][y].piece.colour != p.colour))
+               {
+                       v.add(grid[x][y]);
+                       
+                       if (grid[x][y].piece != null)
+                               break;
+                       x += vx;
+                       y += vy;
+               }
+       }
+}
+
diff --git a/agents/java/Makefile b/agents/java/Makefile
new file mode 100644 (file)
index 0000000..50e986d
--- /dev/null
@@ -0,0 +1,18 @@
+# Q: WHY IS THERE A MAKEFILE FOR A JAVA PROGRAM???
+# A: Because Java doesn't like running programs from different directories. I have to do that.
+#      ... so I compile the Java program into an executable with gcj, and then I can run it from whatever directory I want.
+
+SRC = Agent.java Reader.java Piece.java Board.java Square.java
+MAIN = Agent
+BIN = cough
+
+$(BIN) : $(SRC)
+       gcj -o $(BIN) --main=$(MAIN) $(SRC)
+
+
+clean : 
+       rm -f $(BIN)
+       rm -f *.class
+       rm -f *~
+
+
diff --git a/agents/java/Piece.java b/agents/java/Piece.java
new file mode 100644 (file)
index 0000000..4650824
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * @file Piece.java
+ * @purpose Represent Quantum Chess Piece
+ * @author Sam Moore ([email protected])
+ */
+
+
+
+/**
+ * @class Piece
+ * @purpose Represent a quantum chess piece
+ */
+public class Piece
+{
+               public enum Type {PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, UNKNOWN};
+               public enum Colour {WHITE, BLACK};
+
+               public Piece(int new_x, int new_y, Colour new_colour, Type type1, Type type2)
+               {
+                       this.x = new_x;
+                       this.y = new_y;
+                       this.colour = new_colour;
+                       this.types = new Piece.Type[2];
+                       this.types[0] = type1;
+                       this.types[1] = type2;
+                       this.type_index = -1;
+               }
+
+               public Piece(Piece cpy)
+               {
+                       this.x = cpy.x;
+                       this.y = cpy.y;
+                       this.colour = cpy.colour;
+                       this.types[0] = cpy.types[0];
+                       this.types[1] = cpy.types[1];
+                       this.type_index = cpy.type_index;
+               }
+
+               public int x; 
+               public int y; // position of the piece
+               public Piece.Colour colour; // colour of the piece
+               public int type_index; // indicates state the piece is in; 0, 1, or -1 (unknown)
+               public Piece.Type[] types; // states of the piece
+               public Piece.Type current_type; // current state of the piece
+               
+               public static Piece.Type str2type(String str) throws Exception
+               {
+                       if (str.compareTo("king") == 0)
+                               return Piece.Type.KING;
+                       else if (str.compareTo("queen") == 0)
+                               return Piece.Type.QUEEN;
+                       else if (str.compareTo("rook") == 0)
+                               return Piece.Type.ROOK;
+                       else if (str.compareTo("bishop") == 0)
+                               return Piece.Type.BISHOP;
+                       else if (str.compareTo("knight") == 0)
+                               return Piece.Type.KNIGHT;
+                       else if (str.compareTo("pawn") == 0)
+                               return Piece.Type.PAWN;
+                       else if (str.compareTo("unknown") == 0)
+                               return Piece.Type.UNKNOWN;
+
+                       throw new Exception("Piece.str2type - string " + str + " isn't a valid type");
+                               
+               }
+               public static Piece.Colour str2colour(String str) throws Exception
+               {
+                       if (str.compareTo("white") == 0)
+                               return Piece.Colour.WHITE;
+                       else if (str.compareTo("black") == 0)
+                               return Piece.Colour.BLACK;
+                       
+
+                       throw new Exception("Piece.str2colour - string " + str + " isn't a valid colour");
+               }
+}
+
diff --git a/agents/java/Reader.java b/agents/java/Reader.java
new file mode 100644 (file)
index 0000000..58ce7bb
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Needed to do reading from stdin in Java
+ * SERIOUSLY
+ * Stupid Java
+ * @author Some website somewhere
+ */
+import java.io.*;
+import java.lang.Exception;
+import java.util.Vector;
+
+class Reader
+{
+       public static String readLine()
+       {
+               String s = "";
+               try 
+               {
+                       InputStreamReader converter = new InputStreamReader(System.in);
+                       BufferedReader in = new BufferedReader(converter);
+                       s = in.readLine();
+               } 
+               catch (Exception e) 
+               {
+                       System.err.println("EXCEPTION: Reader.readLine - "+e); 
+               }
+               return s;
+       }
+
+       public static Vector<String> readTokens()
+       {
+               String r = readLine();
+               String token = "";
+               Vector<String> result = new Vector<String>();
+               for (int ii=0; ii < r.length(); ++ii)
+               {
+                       if (r.charAt(ii) == ' ' || r.charAt(ii) == '\n')
+                       {
+                               result.add(new String(token));  
+                               //System.out.println("Token " + token);
+                               token = "";
+                       }
+                       else
+                               token += r.charAt(ii);
+               }
+               result.add(new String(token));
+               return result;
+       }
+}
diff --git a/agents/java/Square.java b/agents/java/Square.java
new file mode 100644 (file)
index 0000000..d2bd418
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * @class Square
+ * @purpose Represent a Square on the board; not necessarily occupied
+ */
+public class Square
+{
+       public Square(int new_x, int new_y, Piece new_piece)
+       {
+               this.x = new_x; 
+               this.y = new_y; 
+               this.piece = new_piece;
+       }
+       public  Square(Square cpy)
+       {
+               this.x = cpy.x;
+               this.y = cpy.y;
+               this.piece = cpy.piece;
+       }
+       public  int x;
+       public int y; // position of the square
+       public  Piece piece; // Piece that is in the Square (null if unoccupied)
+};
diff --git a/agents/java/cough b/agents/java/cough
new file mode 100755 (executable)
index 0000000..3789f4a
Binary files /dev/null and b/agents/java/cough differ
diff --git a/agents/python/data b/agents/python/data
new file mode 120000 (symlink)
index 0000000..75a080a
--- /dev/null
@@ -0,0 +1 @@
+../../qchess/data/
\ No newline at end of file
diff --git a/agents/python/info b/agents/python/info
new file mode 100644 (file)
index 0000000..77784fc
--- /dev/null
@@ -0,0 +1,4 @@
+sample.py --no-debug
+Sam Moore
+python
+Sample agent; makes random moves. Basically a copy of the internal agent that makes random moves. With comments.
diff --git a/agents/python/qchess.py b/agents/python/qchess.py
new file mode 120000 (symlink)
index 0000000..35c6d6e
--- /dev/null
@@ -0,0 +1 @@
+../../qchess/qchess.py
\ No newline at end of file
diff --git a/agents/python/sample.py b/agents/python/sample.py
new file mode 100755 (executable)
index 0000000..55572a2
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/python -u
+
+# Sample agent
+# Copy this file, change the agent as needed
+
+from qchess import * # This is normally considered bad practice in python, but good practice in UCC::Progcomp
+import random # For the example which makes random moves
+
+debug = False
+
+# The first thing to do is pick a cool name...
+class AgentSample(InternalAgent): 
+       def __init__(self, name, colour):
+               InternalAgent.__init__(self, name, colour) # The InternalAgent class gives you some useful stuff
+
+               # You can access self.board to get a qchess.Board that stores the state as recorded by the agent
+               # This board is automatically updated by the InternalAgent base class
+               # As well as a grid of pieces, qchess.Board gives you lists of pieces and other useful functions; see qchess/src/board.py
+               
+
+               #TODO: Any extra initialisation
+               
+               # You should print debug messages like this:
+               if debug:
+                       sys.stderr.write(sys.argv[0] + " : Initialised agent\n")
+               
+
+       # Must return [x,y] of selected piece
+       # Your agent will call select(), followed by get_move() and so on
+       # TODO: Implement
+       def select(self):
+               # debug message
+               if debug:
+                       sys.stderr.write(sys.argv[0] + " : Selecting piece...\n")
+               
+
+               # Here is a random choice algorithm to help you start
+               # It is a slight improvement on purely random; it will pick a piece that has at least one known possible move
+               # BUT it has a possibility to loop infinitely! You should fix that.
+
+               while True:
+                       # Randomly pick a piece
+                       # Use self.board.pieces[self.colour] to get a list of your pieces
+                       # Use self.board.pieces[opponent(self.colour)] to get opponent pieces
+                       # Use self.board.king[self.colour], vice versa, to get the king
+
+                       choices = self.board.pieces[self.colour] # All the agent's pieces
+                       choice_index = random.randint(0, len(choices)-1) # Get the index in the list of the chosen piece
+                       self.choice = choices[choice_index] # Choose the piece, and remember it
+                       
+                       # Find all known possible moves for the piece
+                       # Use self.board.possible_moves(piece) to get a list of possible moves for a piece
+                       # *BUT* Make sure the type of the piece is known (you can temporarily set it) first!
+                       # Use Piece.current_type to get/set the current type of a piece
+
+                       all_moves = [] # Will store all possible moves for the piece
+                       tmp = self.choice.current_type # Remember the chosen piece's current type
+
+                       if tmp == "unknown": # For pieces that are in a supperposition, try both types
+                               for t in self.choice.types:
+                                       if t == "unknown":
+                                               continue # Ignore unknown types
+                                       self.choice.current_type = t # Temporarily overwrite the piece's type
+                                       all_moves += self.board.possible_moves(self.choice) # Add the possible moves for that type
+                       else:
+                               all_moves = self.board.possible_moves(self.choice) # The piece is in a classical state; add possible moves
+                       self.choice.current_type = tmp # Reset the piece's current type
+                       if len(all_moves) > 0:
+                               break # If the piece had *any* possible moves, it is a good choice; leave the loop
+                       # Otherwise the loop will try again
+               # End while loop
+       
+               return [self.choice.x, self.choice.y] # Return the position of the selected piece
+
+       # Must return [x,y] of square to move the piece previously selected into
+       # Your agent will call select(), followed by get_move() and so on
+       # TODO: Implement this
+       def get_move(self):     
+               # debug message
+               if debug:
+                       sys.stderr.write(sys.argv[0] + " : Moving piece ("+str(self.choice)+")\n")
+               # As an example we will just pick a random move for the piece previously chosen in select()
+
+               # Note that whichever piece was previously selected will have collapsed into a classical state
+
+               # self.board.possible_moves(piece) will return a list of [x,y] pairs for valid moves
+
+               moves = self.board.possible_moves(self.choice) # Get all moves for the selected piece
+               move_index = random.randint(0, len(moves)-1) # Get the index in the list of the chosen move
+               return moves[move_index] # This is a randomly chosen [x,y] pair for a valid move of the piece
+
+
+# Hints:
+# select will probably have to be more complicated than get_move, because by the time get_move is called, the piece's state is known
+# If you want to see if a square is threatened/defended, you can call self.board.coverage([x,y]); see qchess/src/board.py
+# A good approach is min/max. For each move, associate a score. Then subtract the scores for moves that the opponent could make. Then pick the move with the highest score.
+# Look at qchess/src/agent_bishop.py for a more effective (but less explained) agent
+
+if __name__ == "__main__":
+
+       # Parse arguments here
+       for i in range(len(sys.argv)):
+               if sys.argv[i] == "--debug":
+                       debug = True
+               elif sys.argv[i] == "--no-debug":
+                       debug = False
+
+       colour = sys.stdin.readline().strip("\r\n")
+       agent = AgentSample(sys.argv[0], colour) # Change the class name here
+       run_agent(agent) # This is provided by qchess. It calls the functions of your agent as required during the game.
+
+# You can run this as an external agent with the qchess program
+# Just run ./qchess.py and apply common sense (or read the help file)
+
+# If you are feeling adventurous you can add it to the qchess program as an internal agent
+# This might give better performance... unless you use the --timeout switch, in which case there is absolutely no point
+# 1. Delete the lines that run the agent (the block that starts with if __name__ == "__main__")
+# 2. Copy the file to qchess/src/agent_sample.py (or whatever you want to call it)
+# 3. Edit qchess/src/Makefile so that agent_sample.py appears as one of the files in COMPONENTS
+# 4. Rebuild by running make in qchess
+# Again, run ./qchess.py and apply common sense
+
+       
+
diff --git a/agents/sample/data b/agents/sample/data
deleted file mode 120000 (symlink)
index 75a080a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../qchess/data/
\ No newline at end of file
diff --git a/agents/sample/info b/agents/sample/info
deleted file mode 100644 (file)
index 77784fc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-sample.py --no-debug
-Sam Moore
-python
-Sample agent; makes random moves. Basically a copy of the internal agent that makes random moves. With comments.
diff --git a/agents/sample/qchess.py b/agents/sample/qchess.py
deleted file mode 120000 (symlink)
index 35c6d6e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../qchess/qchess.py
\ No newline at end of file
diff --git a/agents/sample/sample.py b/agents/sample/sample.py
deleted file mode 100755 (executable)
index 55572a2..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/python -u
-
-# Sample agent
-# Copy this file, change the agent as needed
-
-from qchess import * # This is normally considered bad practice in python, but good practice in UCC::Progcomp
-import random # For the example which makes random moves
-
-debug = False
-
-# The first thing to do is pick a cool name...
-class AgentSample(InternalAgent): 
-       def __init__(self, name, colour):
-               InternalAgent.__init__(self, name, colour) # The InternalAgent class gives you some useful stuff
-
-               # You can access self.board to get a qchess.Board that stores the state as recorded by the agent
-               # This board is automatically updated by the InternalAgent base class
-               # As well as a grid of pieces, qchess.Board gives you lists of pieces and other useful functions; see qchess/src/board.py
-               
-
-               #TODO: Any extra initialisation
-               
-               # You should print debug messages like this:
-               if debug:
-                       sys.stderr.write(sys.argv[0] + " : Initialised agent\n")
-               
-
-       # Must return [x,y] of selected piece
-       # Your agent will call select(), followed by get_move() and so on
-       # TODO: Implement
-       def select(self):
-               # debug message
-               if debug:
-                       sys.stderr.write(sys.argv[0] + " : Selecting piece...\n")
-               
-
-               # Here is a random choice algorithm to help you start
-               # It is a slight improvement on purely random; it will pick a piece that has at least one known possible move
-               # BUT it has a possibility to loop infinitely! You should fix that.
-
-               while True:
-                       # Randomly pick a piece
-                       # Use self.board.pieces[self.colour] to get a list of your pieces
-                       # Use self.board.pieces[opponent(self.colour)] to get opponent pieces
-                       # Use self.board.king[self.colour], vice versa, to get the king
-
-                       choices = self.board.pieces[self.colour] # All the agent's pieces
-                       choice_index = random.randint(0, len(choices)-1) # Get the index in the list of the chosen piece
-                       self.choice = choices[choice_index] # Choose the piece, and remember it
-                       
-                       # Find all known possible moves for the piece
-                       # Use self.board.possible_moves(piece) to get a list of possible moves for a piece
-                       # *BUT* Make sure the type of the piece is known (you can temporarily set it) first!
-                       # Use Piece.current_type to get/set the current type of a piece
-
-                       all_moves = [] # Will store all possible moves for the piece
-                       tmp = self.choice.current_type # Remember the chosen piece's current type
-
-                       if tmp == "unknown": # For pieces that are in a supperposition, try both types
-                               for t in self.choice.types:
-                                       if t == "unknown":
-                                               continue # Ignore unknown types
-                                       self.choice.current_type = t # Temporarily overwrite the piece's type
-                                       all_moves += self.board.possible_moves(self.choice) # Add the possible moves for that type
-                       else:
-                               all_moves = self.board.possible_moves(self.choice) # The piece is in a classical state; add possible moves
-                       self.choice.current_type = tmp # Reset the piece's current type
-                       if len(all_moves) > 0:
-                               break # If the piece had *any* possible moves, it is a good choice; leave the loop
-                       # Otherwise the loop will try again
-               # End while loop
-       
-               return [self.choice.x, self.choice.y] # Return the position of the selected piece
-
-       # Must return [x,y] of square to move the piece previously selected into
-       # Your agent will call select(), followed by get_move() and so on
-       # TODO: Implement this
-       def get_move(self):     
-               # debug message
-               if debug:
-                       sys.stderr.write(sys.argv[0] + " : Moving piece ("+str(self.choice)+")\n")
-               # As an example we will just pick a random move for the piece previously chosen in select()
-
-               # Note that whichever piece was previously selected will have collapsed into a classical state
-
-               # self.board.possible_moves(piece) will return a list of [x,y] pairs for valid moves
-
-               moves = self.board.possible_moves(self.choice) # Get all moves for the selected piece
-               move_index = random.randint(0, len(moves)-1) # Get the index in the list of the chosen move
-               return moves[move_index] # This is a randomly chosen [x,y] pair for a valid move of the piece
-
-
-# Hints:
-# select will probably have to be more complicated than get_move, because by the time get_move is called, the piece's state is known
-# If you want to see if a square is threatened/defended, you can call self.board.coverage([x,y]); see qchess/src/board.py
-# A good approach is min/max. For each move, associate a score. Then subtract the scores for moves that the opponent could make. Then pick the move with the highest score.
-# Look at qchess/src/agent_bishop.py for a more effective (but less explained) agent
-
-if __name__ == "__main__":
-
-       # Parse arguments here
-       for i in range(len(sys.argv)):
-               if sys.argv[i] == "--debug":
-                       debug = True
-               elif sys.argv[i] == "--no-debug":
-                       debug = False
-
-       colour = sys.stdin.readline().strip("\r\n")
-       agent = AgentSample(sys.argv[0], colour) # Change the class name here
-       run_agent(agent) # This is provided by qchess. It calls the functions of your agent as required during the game.
-
-# You can run this as an external agent with the qchess program
-# Just run ./qchess.py and apply common sense (or read the help file)
-
-# If you are feeling adventurous you can add it to the qchess program as an internal agent
-# This might give better performance... unless you use the --timeout switch, in which case there is absolutely no point
-# 1. Delete the lines that run the agent (the block that starts with if __name__ == "__main__")
-# 2. Copy the file to qchess/src/agent_sample.py (or whatever you want to call it)
-# 3. Edit qchess/src/Makefile so that agent_sample.py appears as one of the files in COMPONENTS
-# 4. Rebuild by running make in qchess
-# Again, run ./qchess.py and apply common sense
-
-       
-
index b9fbb07..f9c1f25 100644 (file)
Binary files a/qchess/build/exe.linux-x86_64-2.7.zip and b/qchess/build/exe.linux-x86_64-2.7.zip differ
index 69b5d58..f795c0f 100644 (file)
Binary files a/qchess/build/exe.win32-2.7.zip and b/qchess/build/exe.win32-2.7.zip differ
index 892a7ec..4d2e5e5 100644 (file)
@@ -60,9 +60,13 @@ OPTIONS
                Print this page
        
        --graphics
                Print this page
        
        --graphics
-               Disable/Enable the GUI
+               Enable the GUI
 
                If graphics are enabled (default), then the user will be prompted to choose any of the two players not supplied as arguments.
 
                If graphics are enabled (default), then the user will be prompted to choose any of the two players not supplied as arguments.
+
+       --no-graphics
+               Disable the GUI
+               
                
        --reveal
                If graphics are enabled, the two states for pieces will always be shown, regardless of whether both states have been revealed.
                
        --reveal
                If graphics are enabled, the two states for pieces will always be shown, regardless of whether both states have been revealed.
@@ -85,6 +89,8 @@ OPTIONS
        --log[=filename]
                Log moves to a file or stdout if no filename given
 
        --log[=filename]
                Log moves to a file or stdout if no filename given
 
+               
+
        --delay[=time]
                The game pauses between moves so that it can be followed by a human observer.
                This option can be used to change the delay. If no time is given, the delay is disabled.
        --delay[=time]
                The game pauses between moves so that it can be followed by a human observer.
                This option can be used to change the delay. If no time is given, the delay is disabled.
index 327d193..427472c 100755 (executable)
@@ -1898,7 +1898,7 @@ class GraphicsThread(StoppableThread):
                #print "Test font"
                pygame.font.Font(os.path.join(os.path.curdir, "data", "DejaVuSans.ttf"), 32).render("Hello", True,(0,0,0))
 
                #print "Test font"
                pygame.font.Font(os.path.join(os.path.curdir, "data", "DejaVuSans.ttf"), 32).render("Hello", True,(0,0,0))
 
-               #load_images()
+               #create_images(grid_sz)
                create_images(grid_sz)
 
                """
                create_images(grid_sz)
 
                """
@@ -2604,4 +2604,4 @@ if __name__ == "__main__":
                sys.exit(102)
 
 # --- main.py --- #
                sys.exit(102)
 
 # --- main.py --- #
-# EOF - created from make on Thu Feb 28 18:12:37 WST 2013
+# EOF - created from make on Thu Feb 28 23:49:16 WST 2013
diff --git a/run.sh b/run.sh
index 2067aca..7a80786 100755 (executable)
--- a/run.sh
+++ b/run.sh
@@ -6,7 +6,17 @@
 
 agents=""
 
 
 agents=""
 
-
+function sanity_swarm
+{
+       # Ideally swarm shouldn't crash
+       # But I'm a shit programmer
+       # So I'll leave this in
+       kill -0 $1 2>&1 >> /dev/null
+       if [ "$?" != "0" ]; then
+               echo "Swarm $pid is no longer running! $2" 1>&2
+               exit 1
+       fi
+}
 
 # Copy messages to a log file
 if [ "$BASH_ARGV" != "_worker_" ]; then
 
 # Copy messages to a log file
 if [ "$BASH_ARGV" != "_worker_" ]; then
@@ -27,19 +37,28 @@ fi
 
 echo "Start at $(date)"
 
 
 echo "Start at $(date)"
 
-# Setup the swarm
+cd $root_dir
+# Setup the swarmF
 if [ "$swarm_hosts" != "" ]; then
 if [ "$swarm_hosts" != "" ]; then
-       swarm --daemon
+       swarm_pid=$(swarm --daemon -l daemon.log:100)
+       if [ "$?" != "0" ]; then
+               echo "Couldn't start swarm daemon!" 1>&2
+               exit 1
+       fi
+       
        for h in $swarm_hosts; do
        for h in $swarm_hosts; do
-               swarm -c "#ABSORB $h#"
+               if [ "$h" != "local" ]; then
+                       swarm -c "#ABSORB $h#"
+               fi
        done
        done
-       swarm -c "#.*# cd $root_dir; mkdir -p $results_dir/round$round"
+       sanity_swarm $swarm_pid
+       swarm -c "#.*# cd $root_dir; mkdir -p $results_dir/round$round" -l +wrapper.log:100
 fi
 
 
 
 fi
 
 
 
-cd $root_dir/$agent_dir
 count=0
 count=0
+cd $root_dir/$agent_dir
 for f in $(ls); do
        if [ -d $f ]; then
                info_file=$(ls $f | grep -w "info")
 for f in $(ls); do
        if [ -d $f ]; then
                info_file=$(ls $f | grep -w "info")
@@ -67,6 +86,8 @@ fi
 echo "Start round $round"
 
 game=0
 echo "Start round $round"
 
 game=0
+
+get_number="echo \$name | tr ':' ' ' | awk '{print \$2}'"
 for a in $agents; do
        runa="$agent_dir/$a/$(head --lines=1 $agent_dir/$a/info)"
        for b in $agents; do
 for a in $agents; do
        runa="$agent_dir/$a/$(head --lines=1 $agent_dir/$a/info)"
        for b in $agents; do
@@ -81,7 +102,9 @@ for a in $agents; do
 
                        echo "Game #$game: $a .vs. $b ($i of $games_per_pair)"
                        if [ "$swarm_hosts" != "" ]; then
 
                        echo "Game #$game: $a .vs. $b ($i of $games_per_pair)"
                        if [ "$swarm_hosts" != "" ]; then
-                               swarm -c "$qchess --no-graphics \"$runa\" \"$runb\" --log=$l --log=@web/current.log 2>$err" -o $f.result
+                               sanity_swarm $swarm_pid
+                               swarm -c "#OUTPUT $f.result#"
+                               swarm -c "$qchess --no-graphics \"$runa\" \"$runb\" --log=$l --log=@web/current\$($get_number).log 2>$err" -l +wrapper.log:100
                        else
                                $qchess --no-graphics "$runa" "$runb" --log=$l --log=@web/current.log 1> $f.result 2> $err
                                if [ "$(wc -l $err | awk '{print $1}')" == "0" ]; then rm $err; fi
                        else
                                $qchess --no-graphics "$runa" "$runb" --log=$l --log=@web/current.log 1> $f.result 2> $err
                                if [ "$(wc -l $err | awk '{print $1}')" == "0" ]; then rm $err; fi
@@ -93,6 +116,8 @@ done
 
 
 if [ "$swarm_hosts" != "" ]; then
 
 
 if [ "$swarm_hosts" != "" ]; then
+       echo "Waiting for games to finish"
+       sanity_swarm $swarm_pid
        swarm -c "#BARRIER BLOCK#" # Wait for all games to finish
 
        #Copy over log files (start before updating scores as the scp may take some time)
        swarm -c "#BARRIER BLOCK#" # Wait for all games to finish
 
        #Copy over log files (start before updating scores as the scp may take some time)
@@ -106,7 +131,8 @@ if [ "$swarm_hosts" != "" ]; then
                                fi
                        done
                fi"
                                fi
                        done
                fi"
-               swarm -c "#$h:.* \$# $cmd" # Execute once on each host
+               sanity_swarm $swarm_pid
+               swarm -c "#$h:.* &# $cmd" # Execute once on each host
        done
 fi
 
        done
 fi
 
diff --git a/vars b/vars
index 981395d..232582a 100644 (file)
--- a/vars
+++ b/vars
@@ -3,7 +3,7 @@ results_dir="web/results"
 agent_dir="agents"
 qchess="qchess/qchess.py"
 webserver=$(hostname) # Where log files need to be copied
 agent_dir="agents"
 qchess="qchess/qchess.py"
 webserver=$(hostname) # Where log files need to be copied
-swarm_hosts=""
+swarm_hosts="local"
 
 games_per_pair=1
 win_score=3
 
 games_per_pair=1
 win_score=3
index 29e0166..3b5c3ce 100644 (file)
 
 <h1> What API do I use? </h1>
 
 
 <h1> What API do I use? </h1>
 
-<p> If you are <b>not</b> using python, your agent will use the <a href="agent_text.html"/>text based API</a> </p>
 <p> If you are using python, you should use the <a href="agent_python.html"/>python API</a>. But you don't have to. </p>
 
 <p> If you are using python, you should use the <a href="agent_python.html"/>python API</a>. But you don't have to. </p>
 
+<p> If you are <b>not</b> using python , your agent will have to implement the <a href="agent_text.html"/>text based API</a>. Or you can build on the samples that already do that.</a> </p>
+
+<hr>
+
+<h2> Languages that have Samples </h3>
+
+<p> I recommend you download the <a href="http://git.ucc.asn.au/?p=progcomp2013.git"/>git repository</a>, but if you <i>really</i> want you can click on the links. </p>
+<ul>
+       <li> <a href="../agents/python"/>python</a> </li>
+       <li> <a href="../agents/c++"/>C++</a> </li>
+       <li> <a href="../agents/java"/>java</a> </li>
+</ul>
+
+<p> If you want to use a language that isn't listed, ask me nicely and I might make a sample for you. </p>
+
 <hr>
 
 <h2> I've read that, but don't know where to start </h2>
 
 <ol>
        <li> Pick a language. Python is recommended for beginners. </li>
 <hr>
 
 <h2> I've read that, but don't know where to start </h2>
 
 <ol>
        <li> Pick a language. Python is recommended for beginners. </li>
-       <li> Look at the sample agents. Here is the <a href="../agents/sample"/>sample python agent</a> </li>
+       <li> Look at the sample agents. Here is the <a href="../agents/python"/>sample python agent</a> </li>
        <li> Copy sample and rewrite amazingly awesome quantum chess algorithm of supreme domination </li>
        <li> Profit </li>
 </ol>
        <li> Copy sample and rewrite amazingly awesome quantum chess algorithm of supreme domination </li>
        <li> Profit </li>
 </ol>
@@ -27,7 +41,7 @@
 
 <h2> That was too long; I didn't read it </h2>
 
 
 <h2> That was too long; I didn't read it </h2>
 
-<p> Read the <a href="../agents/sample"/>sample python agent</a> instead. </p>
+<p> Read the <a href="../agents/c++"/>sample python agent</a> instead. </p>
 
 <hr>
 
 
 <hr>
 
@@ -42,7 +56,7 @@
 
 <hr>
 
 
 <hr>
 
-<p> Page last updated 2013-02-18 by matches </p>
+<p> Page last updated 2013-03-01 by matches </p>
 
 <p> <a href="http://www.ucc.asn.au">The UCC Website</a> </p>
 <p> <a href="http://progcomp.ucc.asn.au/2013/web">UCC::Progcomp 2013</a> </p>
 
 <p> <a href="http://www.ucc.asn.au">The UCC Website</a> </p>
 <p> <a href="http://progcomp.ucc.asn.au/2013/web">UCC::Progcomp 2013</a> </p>
index 8ef4ccd..7db07bd 100644 (file)
@@ -44,7 +44,7 @@ margin:0; padding: 0 5px; background:none; vertical-align:top;color:#000;border-
 
 <p> Be sure to read and understand <a href="http://research.cs.queensu.ca/Parallel/QuantumChess/QuantumChess.html"/>the rules</a> before reading this page. </p>
 <p> </p>
 
 <p> Be sure to read and understand <a href="http://research.cs.queensu.ca/Parallel/QuantumChess/QuantumChess.html"/>the rules</a> before reading this page. </p>
 <p> </p>
-<p> The <a href="../agents/sample"/>sample python agent</a> implements this API </p>
+<p> The <a href="../agents/python"/>sample python agent</a> implements this API </p>
 <p> You may still use the <a href="agent_text.html"/>text based API</a> if you insist. </p>
 
 
 <p> You may still use the <a href="agent_text.html"/>text based API</a> if you insist. </p>
 
 
index 6e2fe90..aff9be5 100644 (file)
@@ -12,7 +12,6 @@
 <p> Be sure to read and understand <a href="http://research.cs.queensu.ca/Parallel/QuantumChess/QuantumChess.html"/>the rules</a> before reading this page. </p>
 <p> </p>
 <p> All agents (even python ones) are stand alone programs which qchess spawns instances of to play a game. Qchess sends state updates and requests moves from players through pipes. From the agent's point of view, all it has to do is read commands from stdin and respond to stdout. </p>
 <p> Be sure to read and understand <a href="http://research.cs.queensu.ca/Parallel/QuantumChess/QuantumChess.html"/>the rules</a> before reading this page. </p>
 <p> </p>
 <p> All agents (even python ones) are stand alone programs which qchess spawns instances of to play a game. Qchess sends state updates and requests moves from players through pipes. From the agent's point of view, all it has to do is read commands from stdin and respond to stdout. </p>
-<p> <b>Note:</b> Although pipes are pretty damn awesome, they unfortunately always get buffered by default, with a stupidly large size like 4KB. This means that it is unlikely a program will work unless it is able to unbuffer its stdin/stdout streams. In some languages this is trivial. In others it is probably impossible. If you want to use a language where it is impossible, please tell the organiser. Even if I have to rewrite half of the code dealing with external agents, <i>I will make it work</i>. </p>
 
 <hr>
 
 
 <hr>
 
index 8366224..ed6a91c 100644 (file)
@@ -39,8 +39,7 @@
 
 <ul>
        <li> qchess/qchess.py - Python script version of qchess </li>
 
 <ul>
        <li> qchess/qchess.py - Python script version of qchess </li>
-       <li> agents/ - Where all the agents will go when the competition runs
-       <li> agents/sample.py - A sample agent in python </li>
+       <li> agents/ - Where all the agents will go when the competition runs. Contains sample agents. </li>
        <li> qchess/build/ - Compiled binaries of the qchess program </li>
        <li> qchess/src/ - Source python files for qchess </li>
        <li> web/ - This website </li>
        <li> qchess/build/ - Compiled binaries of the qchess program </li>
        <li> qchess/src/ - Source python files for qchess </li>
        <li> web/ - This website </li>
diff --git a/web/get_qchess.html b/web/get_qchess.html
deleted file mode 100644 (file)
index 410c03b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<html>
-
-<head>
-<title> UCC::Progcomp 2013 - Getting qchess </title>
-</head>
-
-<body bgcolor=white>
-
-<p> qchess is a python2.7 implementation of <a href="http://research.cs.queensu.ca/Parallel/QuantumChess/QuantumChess.html"/>Quantum Chess</a> </p>
-
-<h1> tl;dr </h1>
-
-<table border="1">
-
-<tr> <th>  </th> <th> Binary </th> <th> Script (requires python2.7 and pygame1.9) </th> </tr>
-<tr> <th> Windows </th> <td> <a href="http://git.ucc.asn.au/?p=progcomp2013.git;a=blob;f=qchess/build/exe.win32-2.7.zip"/>32 bit</a> </td> <td> <a href="http://git.ucc.asn.au/?p=progcomp2013.git;a=blob_plain;f=qchess/qchess.py"/>qchess.py</a></td> </tr>
-<tr> <th> Linux </th> <td> <a href="http://git.ucc.asn.au/?p=progcomp2013.git;a=blob;f=qchess/build/exe.linux-x86_64-2.7.zip"/>64 bit</a></td> <td> <a href="http://git.ucc.asn.au/?p=progcomp2013.git;a=blob_plain;f=qchess/qchess.py"/>qchess.py</a></td> </tr>
-
-
-
-
-</table>
-
-<p> <b> Warning: </b> Some things in the windows version will not work. </p>
-<p> <b> Warning: </b> The actual competition will be run on linux. If your program doesn't work on linux, you may not be able to enter. </p>
-
-
-<hr>
-
-
-<h3> Git </h3>
-<p> The best way to do things is to use <a href="http://git-scm.com/"/>git</a> and clone the repository at <a href="http://git.ucc.asn.au/?p=progcomp2013.git"/>git://git.ucc.asn.au/progcomp2013.git</a>. Run "git pull" everytime a major change is announced.  </p>
-
-
-<hr>
-
-
-<h3> Files and Directories </h3>
-
-<ul>
-       <li> qchess/qchess.py - Python script version of qchess </li>
-       <li> agents/ - Where all the agents will go when the competition runs
-       <li> agents/sample.py - A sample agent in python </li>
-       <li> qchess/build/ - Compiled binaries of the qchess program </li>
-       <li> qchess/src/ - Source python files for qchess </li>
-       <li> web/ - This website </li>
-</ul>
-
-<hr>
-
-<h3> qchess.py </h3>
-
-<ul>
-
-       <li> You will need <a href="http://www.python.org/download/releases/2.7.3"/>python 2.7.3</a> </li>
-       <ul>    <li> On Debian/Ubuntu just run `sudo apt-get install python` </li>
-               <li> On Windows, download and install the x86 (32bit) MSI, <b>not</b> the x86-64 (64bit) MSI) </li> </ul>
-       <li> You will need <a href="http://www.pygame.org/download.shtml"/>pygame 1.9.1</a> </li>
-       <ul>    <li> On Debian/Ubuntu just run `sudo apt-get install python-pygame` </li>
-               <li> On Windows, ,ake sure you get the pygame for python 2.7 MSI </li> </ul>
-
-       <li> Hopefully, if you have those, things will just work (TM) </li>
-       <ul>    <li> In linux, navigate to the qchess directory, then run with ./qchess.py </li>
-               <li> In windows, the application <i>should</i> start when you double click on it </li>
-               <li> If you want to give command line arguments, you will need to use cmd on windows </li>
-       </ul>
-</ul>
-
-<hr>
-
-<h3> Compiled Binaries </h3>
-
-<p> <b> Warning:</b> I am no longer testing the binaries. I believe the linux binary works, but the Windows binary might not. </p>
-<p> If they work for you, that is awesome, but I recommend installing python and using the python script. </p>
-<p> You'll probably want to enter in python, since the python script gives you a lot of useful functions. </p>
-
-<p> <b> On the other hand... </b>, if you have problems with an incompatable version of python, try the binaries! </p>
-
-<hr>
-
-<p> Page last updated 2012-01-30 by matches </p>
-
-<p> <a href="http://www.ucc.asn.au">The UCC Website</a> </p>
-<p> <a href="http://progcomp.ucc.asn.au/2013">UCC::Progcomp 2013</a> </p>
-
-</body>
-</html>
-

UCC git Repository :: git.ucc.asn.au