Commit 7a6c3dd9 authored by Sam Moore's avatar Sam Moore

Did something, apparently

parent 6632f343
No preview for this file type
......@@ -19,8 +19,8 @@ using namespace std;
* @param new_piece_index - Index for piece in a vector
*/
Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2,
int new_type_index, int new_piece_index)
: x(new_x), y(new_y), colour(new_colour), type_index(new_type_index), types(), current_type(), piece_index(new_piece_index)
int new_type_index)
: x(new_x), y(new_y), colour(new_colour), type_index(new_type_index), types(), current_type()
{
types[0] = type1; types[1] = type2;
if (type_index < 0 || type_index >= 2)
......@@ -37,7 +37,7 @@ Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece
* @constructor
* @param cpy - Piece to copy construct from
*/
Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index), piece_index(cpy.piece_index)
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];
......@@ -49,7 +49,7 @@ Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_i
*/
Board::Board(bool choose_types)
: white(), black(), white_unknown(), black_unknown(), white_nUnknown(0), black_nUnknown(0),
white_king(NULL), black_king(NULL), parent(NULL)
white_king(NULL), black_king(NULL)
{
// initialise all the Squares
......@@ -150,7 +150,7 @@ Board::Board(bool choose_types)
Board::Board(Board & cpy)
: white(cpy.white), black(cpy.black), white_unknown(cpy.white_unknown), black_unknown(cpy.black_unknown),
white_nUnknown(cpy.white_nUnknown), black_nUnknown(cpy.black_nUnknown),
white_king(cpy.white_king), black_king(cpy.black_king), parent(&cpy)
white_king(cpy.white_king), black_king(cpy.black_king)
{
for (int x = 0; x < BOARD_WIDTH; ++x)
{
......@@ -158,7 +158,11 @@ Board::Board(Board & cpy)
{
grid[x][y].x = x;
grid[x][y].y = y;
grid[x][y].piece = cpy.grid[x][y].piece;
if (cpy.grid[x][y].piece != NULL)
{
vector<Piece*> & v = pieces(cpy.grid[x][y].piece->colour);
Piece::AddPiece(v, *(cpy.grid[x][y].piece));
}
}
}
}
......@@ -204,7 +208,7 @@ void Board::Update_select(int x, int y, int index, const Piece::Type & t)
cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << t << "\n";
Square & s = grid[x][y];
Clone_copy(s);
assert(s.piece != NULL);
assert(index >= 0 && index < 2);
......@@ -237,7 +241,6 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
Square & s1 = grid[x1][y1];
Square & s2 = grid[x2][y2];
Clone_copy(s1);
......@@ -255,11 +258,7 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
}
++i;
}
while (i != p.end())
{
(*i)->piece_index -= 1;
++i;
}
Piece * k = king(s2.piece->colour);
if (k == s2.piece)
{
......@@ -268,10 +267,8 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
else
black_king = NULL;
}
if ((IsClone() && s2.piece == parent->grid[x2][y2].piece) == false)
{
delete s2.piece;
}
delete s2.piece;
}
s1.piece->x = s2.x;
......@@ -290,6 +287,7 @@ void Board::Update_move(int x1, int y1, int x2, int y2)
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)
{
......@@ -480,24 +478,21 @@ Piece::Colour Piece::str2colour(const string & str)
Piece * Piece::AddPiece(vector<Piece*> & v, int x, int y, const Piece::Colour & colour, const Piece::Type & t1, const Piece::Type & t2,
int type_index)
{
Piece * p = new Piece(x,y,colour,t1, t2,type_index, v.size());
Piece * p = new Piece(x,y,colour,t1, t2,type_index);
v.push_back(p);
return p;
}
/**
* @funct Clone_copy
* @purpose If necessary, copy the piece in the square
* @param s - The square
* @funct AddPiece
* @purpose Copy a Piece and add it to a vector
* @param v - The vector
* @param cpy - Piece to copy
* @returns Pointer to the new Piece
*/
void Board::Clone_copy(Square & s)
Piece * Piece::AddPiece(vector<Piece*> & v, const Piece & cpy)
{
if (s.piece == NULL || !IsClone()) return;
if (parent->grid[s.x][s.y].piece == s.piece)
{
s.piece = new Piece(*(s.piece));
vector<Piece*> & v = pieces(s.piece->colour);
v[s.piece->piece_index] = s.piece;
}
Piece * p = new Piece(cpy);
v.push_back(p);
return p;
}
\ No newline at end of file
......@@ -45,14 +45,14 @@ class Piece
static const char * type2str(const Type & t);
static Piece * AddPiece(std::vector<Piece*> & v, int x, int y, const Colour & colour, const Type & type1, const Type & type2, int type_index=-1);
static Piece * AddPiece(std::vector<Piece*> & v, const Piece & cpy);
private:
friend class Board;
Piece(int x, int y, const Colour & colour, const Type & type1, const Type & type2
, int type_index, int new_piece_index); // constructor
, int type_index); // constructor
Piece(const Piece & cpy); // copy constructor
int piece_index; // index of the piece in Board's pieces vector
};
......@@ -111,8 +111,7 @@ class Board
// determine if position is on the board
bool Valid_position(int x, int y) {return (x >= 0 && x <= BOARD_WIDTH-1 && y >= 0 && y <= BOARD_HEIGHT-1);}
bool IsClone() const {return parent != NULL;}
void Clone_copy(Square & s);
private:
Square grid[BOARD_WIDTH][BOARD_HEIGHT];
......@@ -128,7 +127,7 @@ class Board
Piece * white_king;
Piece * black_king;
Board * parent;
// Add a move to the vector if it is valid
void Move(Piece * p, int x, int y, std::vector<Square*> & v);
......
......@@ -11,7 +11,7 @@ BIN = silver
$(BIN) : $(LINKOBJ)
$(CXX) -o $(BIN) $(LINKOBJ)
$(CXX) -o $(BIN) $(LINKOBJ) $(LIB)
%.o : %.cpp
$(CXX) -c $<
......
../c++/agent.cpp
\ No newline at end of file
/**
* 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
}
}
}
}
../c++/agent.h
\ No newline at end of file
/**
* 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
......@@ -9,6 +9,7 @@
#include "silverfish.h"
using namespace std;
/**
......@@ -20,6 +21,8 @@ using namespace std;
int main(int argc, char ** argv)
{
srand(time(NULL)); // seed random number generator
string colour; cin >> colour; // first read the colour of the agent
......
../c++/qchess.cpp
\ No newline at end of file
/**
* 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;
Piece::Type Piece::AllTypes[] = {PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, UNKNOWN};
Piece::Colour Piece::AllColours[] = {WHITE, BLACK};
/**
* @constructor
* @param new_x, new_y - Position of piece
* @param new_colour - Colour of piece
* @param type1, type2 - Types of piece
* @param new_type_index - Index for initial type of piece
* @param new_piece_index - Index for piece in a vector
*/
Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2,
int new_type_index)
: x(new_x), y(new_y), colour(new_colour), type_index(new_type_index), types(), current_type()
{
types[0] = type1; types[1] = type2;
if (type_index < 0 || type_index >= 2)
{
current_type = Piece::UNKNOWN;
}
else
{
current_type = types[type_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)
: white(), black(), white_unknown(), black_unknown(), white_nUnknown(0), black_nUnknown(0),
white_king(NULL), black_king(NULL)
{
// 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
// 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;
if (!choose_types)
{
white_unknown = freq;
black_unknown = freq;
white_nUnknown = 15;
black_nUnknown = 15;
}
// for white and black...
for (int i = 0; i < 2; ++i)
{
vector<Piece*> & v = pieces(Piece::AllColours[i]); // get vector of pieces
// add pawns
int y = (i == 0) ? 1 : BOARD_HEIGHT-2;
for (int x = 0; x < BOARD_WIDTH; ++x)
{
Piece::AddPiece(v, x, y, Piece::AllColours[i], Piece::PAWN, Piece::UNKNOWN);
}
// add other pieces
y = (i == 0) ? 0 : BOARD_HEIGHT-1;
Piece::AddPiece(v, 0, y, Piece::AllColours[i], Piece::ROOK, Piece::UNKNOWN);
Piece::AddPiece(v, BOARD_WIDTH-1, y, Piece::AllColours[i], Piece::ROOK, Piece::UNKNOWN);
Piece::AddPiece(v, 1, y, Piece::AllColours[i], Piece::KNIGHT, Piece::UNKNOWN);
Piece::AddPiece(v, BOARD_WIDTH-2, y, Piece::AllColours[i], Piece::KNIGHT, Piece::UNKNOWN);
Piece::AddPiece(v, 2, y, Piece::AllColours[i], Piece::BISHOP, Piece::UNKNOWN);
Piece::AddPiece(v, BOARD_WIDTH-3, y, Piece::AllColours[i], Piece::BISHOP, Piece::UNKNOWN);
Piece::AddPiece(v, 3, y, Piece::AllColours[i], Piece::QUEEN, Piece::UNKNOWN);
Piece * k = Piece::AddPiece(v, 4, y, Piece::AllColours[i], Piece::KING, Piece::KING, 1);
if (i == 0)
white_king = k;
else
black_king = 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[Piece::AllTypes[type2]] <= 0);
f[Piece::AllTypes[type2]] -= 1;
p->types[1] = Piece::AllTypes[type2];
}
}
}
}
/**
* @constructor
* @param cpy - Board to clone
*/
Board::Board(Board & cpy)
: white(cpy.white), black(cpy.black), white_unknown(cpy.white_unknown), black_unknown(cpy.black_unknown),
white_nUnknown(cpy.white_nUnknown), black_nUnknown(cpy.black_nUnknown),
white_king(cpy.white_king), black_king(cpy.black_king)
{
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)
{
vector<Piece*> & v = pieces(cpy.grid[x][y].piece->colour);
Piece::AddPiece(v, *(cpy.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 as a string
*/
void Board::Update_select(int x, int y, int index, const string & type)
{
Board::Update_select(x, y, index, Piece::str2type(type));
}
/**
* @funct Update_select
* @purpose Update Piece that has been selected
* @param x, y - Position of Piece to update
* @param index - 0 or 1 - State the Piece "collapsed" into
* @param t - Type of the Piece
*/
void Board::Update_select(int x, int y, int index, const Piece::Type & t)
{
cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << t << "\n";
Square & s = grid[x][y];
assert(s.piece != NULL);
assert(index >= 0 && index < 2);
s.piece->type_index = index;
if (s.piece->types[index] == Piece::UNKNOWN)
{
map<Piece::Type, int> & m = unknown_types(s.piece->colour);
int n = (m[t]--);
if (n < 0)
throw Exception("Board::Update_select", "Too many pieces of type %s found", Piece::type2str(t));
nUnknown(s.piece->colour)--;
}
s.piece->types[index] = t;
s.piece->current_type = t;
for (int x = 0; x < BOARD_WIDTH; ++x)
{
for (int y = 0; y < BOARD_HEIGHT; ++y)
{
grid[x][y].Update_coverage(*this);
}
}
}
/**
* @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)