|
@@ -1,4 +1,5 @@
|
|
#include "Field.h"
|
|
#include "Field.h"
|
|
|
|
+#include "Piece.h"
|
|
#include "pieces/Pawn.h"
|
|
#include "pieces/Pawn.h"
|
|
#include "pieces/King.h"
|
|
#include "pieces/King.h"
|
|
#include "pieces/Queen.h"
|
|
#include "pieces/Queen.h"
|
|
@@ -7,45 +8,73 @@
|
|
#include "pieces/Knight.h"
|
|
#include "pieces/Knight.h"
|
|
|
|
|
|
CField::CField() {
|
|
CField::CField() {
|
|
|
|
+ for(int y = 0; y < 8; y++) {
|
|
|
|
+ for(int x = 0; x < 8; x++) {
|
|
|
|
+ fields[x][y] = nullptr;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
reset();
|
|
reset();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+CField::~CField() {
|
|
|
|
+ // reset previous pieces
|
|
|
|
+ for(int y = 0; y < 8; y++) {
|
|
|
|
+ for(int x = 0; x < 8; x++) {
|
|
|
|
+ if(fields[x][y]) {
|
|
|
|
+ delete fields[x][y];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void CField::reset() {
|
|
void CField::reset() {
|
|
|
|
|
|
|
|
+ // reset previous pieces
|
|
|
|
+ for(int y = 0; y < 8; y++) {
|
|
|
|
+ for(int x = 0; x < 8; x++) {
|
|
|
|
+ if(fields[x][y]) {
|
|
|
|
+ delete fields[x][y];
|
|
|
|
+ }
|
|
|
|
+ fields[x][y] = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
// White
|
|
// White
|
|
- pieces[0][0] = new CRook(Color::WHITE);
|
|
|
|
- pieces[7][0] = new CRook(Color::WHITE);
|
|
|
|
|
|
+ fields[0][0] = new CRook(0, 0, Color::WHITE);
|
|
|
|
+ fields[7][0] = new CRook(7, 0, Color::WHITE);
|
|
|
|
|
|
- pieces[1][0] = new CKnight(Color::WHITE);
|
|
|
|
- pieces[6][0] = new CKnight(Color::WHITE);
|
|
|
|
|
|
+ fields[1][0] = new CKnight(1, 0, Color::WHITE);
|
|
|
|
+ fields[6][0] = new CKnight(6, 0, Color::WHITE);
|
|
|
|
|
|
- pieces[2][0] = new CBishop(Color::WHITE);
|
|
|
|
- pieces[5][0] = new CBishop(Color::WHITE);
|
|
|
|
|
|
+ fields[2][0] = new CBishop(2, 0, Color::WHITE);
|
|
|
|
+ fields[5][0] = new CBishop(5, 0, Color::WHITE);
|
|
|
|
|
|
- pieces[3][0] = new CQueen(Color::WHITE);
|
|
|
|
- pieces[4][0] = (m_pKingWhite = new CKing(Color::WHITE));
|
|
|
|
|
|
+ fields[3][0] = new CQueen(3, 0, Color::WHITE);
|
|
|
|
+ fields[4][0] = (m_pKingWhite = new CKing(4, 0, Color::WHITE));
|
|
for(unsigned int x = 0; x < 8; x++)
|
|
for(unsigned int x = 0; x < 8; x++)
|
|
- pieces[x][1] = new CPawn(Color::WHITE);
|
|
|
|
|
|
+ fields[x][1] = new CPawn(x, 1, Color::WHITE);
|
|
|
|
|
|
// Empty Space
|
|
// Empty Space
|
|
for(unsigned x = 0; x < 8; x++)
|
|
for(unsigned x = 0; x < 8; x++)
|
|
for(unsigned y = 2; y < 6; y++)
|
|
for(unsigned y = 2; y < 6; y++)
|
|
- pieces[x][y] = nullptr;
|
|
|
|
|
|
+ fields[x][y] = nullptr;
|
|
|
|
|
|
// Black
|
|
// Black
|
|
- pieces[0][7] = new CRook(Color::BLACK);
|
|
|
|
- pieces[7][7] = new CRook(Color::BLACK);
|
|
|
|
|
|
+ fields[0][7] = new CRook(0, 7, Color::BLACK);
|
|
|
|
+ fields[7][7] = new CRook(7, 7, Color::BLACK);
|
|
|
|
|
|
- pieces[1][7] = new CKnight(Color::BLACK);
|
|
|
|
- pieces[6][7] = new CKnight(Color::BLACK);
|
|
|
|
|
|
+ fields[1][7] = new CKnight(1, 7, Color::BLACK);
|
|
|
|
+ fields[6][7] = new CKnight(6, 7, Color::BLACK);
|
|
|
|
|
|
- pieces[2][7] = new CBishop(Color::BLACK);
|
|
|
|
- pieces[5][7] = new CBishop(Color::BLACK);
|
|
|
|
|
|
+ fields[2][7] = new CBishop(2, 7, Color::BLACK);
|
|
|
|
+ fields[5][7] = new CBishop(5, 7, Color::BLACK);
|
|
|
|
|
|
- pieces[3][7] = new CQueen(Color::BLACK);
|
|
|
|
- pieces[4][7] = (m_pKingBlack = new CKing(Color::BLACK));
|
|
|
|
|
|
+ fields[3][7] = new CQueen(3, 7, Color::BLACK);
|
|
|
|
+ fields[4][7] = (m_pKingBlack = new CKing(4, 7, Color::BLACK));
|
|
for(unsigned int x = 0; x < 8; x++)
|
|
for(unsigned int x = 0; x < 8; x++)
|
|
- pieces[x][6] = new CPawn(Color::BLACK);
|
|
|
|
|
|
+ fields[x][6] = new CPawn(x, 6, Color::BLACK);
|
|
}
|
|
}
|
|
|
|
|
|
ostream& operator<<(ostream &os, const CField &field) {
|
|
ostream& operator<<(ostream &os, const CField &field) {
|
|
@@ -58,8 +87,8 @@ ostream& operator<<(ostream &os, const CField &field) {
|
|
os << " " << y + 1;
|
|
os << " " << y + 1;
|
|
for(int x = 0; x < 8; x++) {
|
|
for(int x = 0; x < 8; x++) {
|
|
os << " ";
|
|
os << " ";
|
|
- if(field.pieces[x][y] != nullptr)
|
|
|
|
- os << *field.pieces[x][y];
|
|
|
|
|
|
+ if(field.fields[x][y] != nullptr)
|
|
|
|
+ os << *field.fields[x][y];
|
|
else
|
|
else
|
|
os << " ";
|
|
os << " ";
|
|
}
|
|
}
|
|
@@ -73,30 +102,32 @@ bool CField::checkBounds(int x, int y) {
|
|
return (x >= 0 && y >= 0 && x < 8 && y < 8);
|
|
return (x >= 0 && y >= 0 && x < 8 && y < 8);
|
|
}
|
|
}
|
|
|
|
|
|
-bool CField::isAttacked(int x, int y, int color) {
|
|
|
|
- if(!checkBounds(x, y))
|
|
|
|
|
|
+bool CField::isAttacked(int tarX, int tarY, int color) {
|
|
|
|
+ if(!checkBounds(tarX, tarY))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- // TODO: CField::isAttacked(int,int,int)
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
|
|
+ for(int x = 0; x < 8; x++) {
|
|
|
|
+ for(int y = 0; y < 8; y++) {
|
|
|
|
|
|
-void CField::swapPieces(int x0, int y0, int x1, int y1) {
|
|
|
|
- if(!checkBounds(x0, y0) || !checkBounds(x1, y1))
|
|
|
|
- return;
|
|
|
|
|
|
+ if((x != tarX || y != tarY) &&
|
|
|
|
+ fields[x][y] != nullptr &&
|
|
|
|
+ fields[x][y]->getColor() == color &&
|
|
|
|
+ fields[x][y]->canMove(this, tarX, tarY))
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- CPiece *piece0 = getPiece(x0, y0);
|
|
|
|
- CPiece *piece1 = getPiece(x1, y1);
|
|
|
|
- pieces[x0][y0] = piece1;
|
|
|
|
- pieces[x1][y1] = piece0;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool CField::move(int fromX, int fromY, int toX, int toY) {
|
|
bool CField::move(int fromX, int fromY, int toX, int toY) {
|
|
if(!checkBounds(fromX, fromY) || !checkBounds(fromX, fromY))
|
|
if(!checkBounds(fromX, fromY) || !checkBounds(fromX, fromY))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- if(fromX == toX && fromY == toY)
|
|
|
|
|
|
+ if(fromX == toX && fromY == toY) {
|
|
|
|
+ cout << "Source and Target positions are the same" << endl;
|
|
return false;
|
|
return false;
|
|
|
|
+ }
|
|
|
|
|
|
CPiece *movingPiece = getPiece(fromX, fromY);
|
|
CPiece *movingPiece = getPiece(fromX, fromY);
|
|
if(movingPiece == nullptr)
|
|
if(movingPiece == nullptr)
|
|
@@ -104,23 +135,46 @@ bool CField::move(int fromX, int fromY, int toX, int toY) {
|
|
|
|
|
|
CPiece *targetPiece = getPiece(toX, toY);
|
|
CPiece *targetPiece = getPiece(toX, toY);
|
|
if(targetPiece != nullptr) {
|
|
if(targetPiece != nullptr) {
|
|
- if(targetPiece->getType() == CPiece::Type::KING)
|
|
|
|
|
|
+ if(targetPiece->getType() == CPiece::Type::KING) {
|
|
|
|
+ cout << "You cannot attack the king" << endl;
|
|
return false;
|
|
return false;
|
|
- else if(targetPiece->getColor() == movingPiece->getColor())
|
|
|
|
|
|
+ }
|
|
|
|
+ else if(targetPiece->getColor() == movingPiece->getColor()) {
|
|
|
|
+ cout << "You cannot attack your own pieces" << endl;
|
|
return false;
|
|
return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- if(movingPiece->canMove(this, fromX, fromY, toX, toY)) {
|
|
|
|
- if(targetPiece != nullptr) {
|
|
|
|
- delete targetPiece;
|
|
|
|
- }
|
|
|
|
- pieces[toX][toY] = movingPiece;
|
|
|
|
- pieces[fromX][fromY] = nullptr;
|
|
|
|
- movingPiece->m_HasMoved = true;
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
|
|
+ if(!movingPiece->moveTo(this, toX, toY)) {
|
|
|
|
+ cout << "This piece cannot move there." << endl;
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int activeColor = movingPiece->getColor();
|
|
|
|
+ CKing *pOwnKing = (activeColor == Color::WHITE ? m_pKingWhite : m_pKingBlack);
|
|
|
|
+ if(isAttacked(pOwnKing->m_X, pOwnKing->m_Y, 1 - activeColor)) {
|
|
|
|
+ // we cannot move as our king is attacked, reset this move!
|
|
|
|
+ cout << "You king is still attacked." << endl;
|
|
|
|
+ setPiece(fromX, fromY, movingPiece);
|
|
|
|
+ setPiece(toX, toY, targetPiece);
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ movingPiece->m_HasMoved = true;
|
|
|
|
+ if(targetPiece != nullptr)
|
|
|
|
+ delete targetPiece;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CField::setPiece(int x, int y, CPiece *pPiece) {
|
|
|
|
+ if(checkBounds(x, y)) {
|
|
|
|
+ fields[x][y] = pPiece;
|
|
|
|
+ if(pPiece) {
|
|
|
|
+ pPiece->m_X = x;
|
|
|
|
+ pPiece->m_Y = y;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
int CField::normalalize(int i) {
|
|
int CField::normalalize(int i) {
|
|
@@ -152,9 +206,9 @@ bool CField::intersect(int fromX, int fromY, int toX, int toY, bool includeTarge
|
|
int y = fromY + dirY;
|
|
int y = fromY + dirY;
|
|
|
|
|
|
for(; !(x == toX && y == toY); x += dirX, y += dirY) {
|
|
for(; !(x == toX && y == toY); x += dirX, y += dirY) {
|
|
- if(pieces[x][y] != nullptr)
|
|
|
|
|
|
+ if(fields[x][y] != nullptr)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- return (includeTarget ? pieces[toX][toY] != nullptr : false);
|
|
|
|
|
|
+ return (includeTarget ? fields[toX][toY] != nullptr : false);
|
|
}
|
|
}
|