|
@@ -1,24 +1,160 @@
|
|
|
#include "Field.h"
|
|
|
-
|
|
|
#include "pieces/Pawn.h"
|
|
|
+#include "pieces/King.h"
|
|
|
+#include "pieces/Queen.h"
|
|
|
+#include "pieces/Rook.h"
|
|
|
+#include "pieces/Bishop.h"
|
|
|
+#include "pieces/Knight.h"
|
|
|
|
|
|
CField::CField() {
|
|
|
reset();
|
|
|
}
|
|
|
|
|
|
void CField::reset() {
|
|
|
- for(unsigned int x = 0; x < 8; x++) {
|
|
|
- for(unsigned int y = 0; y < 8; y++) {
|
|
|
- if(y == 1)
|
|
|
- pieces[x][y] = new CPawn(CPiece::Color::WHITE);
|
|
|
- else if(y == 2)
|
|
|
- pieces[x][y] = new CPawn(CPiece::Color::BLACK);
|
|
|
+
|
|
|
+ // White
|
|
|
+ pieces[0][0] = new CRook(Color::WHITE);
|
|
|
+ pieces[7][0] = new CRook(Color::WHITE);
|
|
|
+
|
|
|
+ pieces[1][0] = new CKnight(Color::WHITE);
|
|
|
+ pieces[6][0] = new CKnight(Color::WHITE);
|
|
|
+
|
|
|
+ pieces[2][0] = new CBishop(Color::WHITE);
|
|
|
+ pieces[5][0] = new CBishop(Color::WHITE);
|
|
|
+
|
|
|
+ pieces[3][0] = new CQueen(Color::WHITE);
|
|
|
+ pieces[4][0] = (m_pKingWhite = new CKing(Color::WHITE));
|
|
|
+ for(unsigned int x = 0; x < 8; x++)
|
|
|
+ pieces[x][1] = new CPawn(Color::WHITE);
|
|
|
+
|
|
|
+ // Empty Space
|
|
|
+ for(unsigned x = 0; x < 8; x++)
|
|
|
+ for(unsigned y = 2; y < 6; y++)
|
|
|
+ pieces[x][y] = nullptr;
|
|
|
+
|
|
|
+ // Black
|
|
|
+ pieces[0][7] = new CRook(Color::BLACK);
|
|
|
+ pieces[7][7] = new CRook(Color::BLACK);
|
|
|
+
|
|
|
+ pieces[1][7] = new CKnight(Color::BLACK);
|
|
|
+ pieces[6][7] = new CKnight(Color::BLACK);
|
|
|
+
|
|
|
+ pieces[2][7] = new CBishop(Color::BLACK);
|
|
|
+ pieces[5][7] = new CBishop(Color::BLACK);
|
|
|
+
|
|
|
+ pieces[3][7] = new CQueen(Color::BLACK);
|
|
|
+ pieces[4][7] = (m_pKingBlack = new CKing(Color::BLACK));
|
|
|
+ for(unsigned int x = 0; x < 8; x++)
|
|
|
+ pieces[x][6] = new CPawn(Color::BLACK);
|
|
|
+}
|
|
|
+
|
|
|
+ostream& operator<<(ostream &os, const CField &field) {
|
|
|
+ os << " ";
|
|
|
+ for(int x = 0; x < 8; x++)
|
|
|
+ os << " " << (char)((int)'A' + x);
|
|
|
+ os << endl;
|
|
|
+
|
|
|
+ for(int y = 7; y >= 0; y--) {
|
|
|
+ os << " " << y + 1;
|
|
|
+ for(int x = 0; x < 8; x++) {
|
|
|
+ os << " ";
|
|
|
+ if(field.pieces[x][y] != nullptr)
|
|
|
+ os << *field.pieces[x][y];
|
|
|
+ else
|
|
|
+ os << " ";
|
|
|
+ }
|
|
|
+ os << endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ return os;
|
|
|
+}
|
|
|
+
|
|
|
+bool CField::checkBounds(int x, int y) {
|
|
|
+ return (x >= 0 && y >= 0 && x < 8 && y < 8);
|
|
|
+}
|
|
|
+
|
|
|
+bool CField::isAttacked(int x, int y, int color) {
|
|
|
+ if(!checkBounds(x, y))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ // TODO: CField::isAttacked(int,int,int)
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+void CField::swapPieces(int x0, int y0, int x1, int y1) {
|
|
|
+ if(!checkBounds(x0, y0) || !checkBounds(x1, y1))
|
|
|
+ return;
|
|
|
+
|
|
|
+ CPiece *piece0 = getPiece(x0, y0);
|
|
|
+ CPiece *piece1 = getPiece(x1, y1);
|
|
|
+ pieces[x0][y0] = piece1;
|
|
|
+ pieces[x1][y1] = piece0;
|
|
|
+}
|
|
|
+
|
|
|
+bool CField::move(int fromX, int fromY, int toX, int toY) {
|
|
|
+ if(!checkBounds(fromX, fromY) || !checkBounds(fromX, fromY))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if(fromX == toX && fromY == toY)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ CPiece *movingPiece = getPiece(fromX, fromY);
|
|
|
+ if(movingPiece == nullptr)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ CPiece *targetPiece = getPiece(toX, toY);
|
|
|
+ if(targetPiece != nullptr) {
|
|
|
+ if(targetPiece->getType() == CPiece::Type::KING)
|
|
|
+ return false;
|
|
|
+ else if(targetPiece->getColor() == movingPiece->getColor())
|
|
|
+ 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 {
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int CField::normalalize(int i) {
|
|
|
+ return (i == 0 ? 0 : i / abs(i));
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+* returns false, if no intersection occurs, true otherwise
|
|
|
+*/
|
|
|
+bool CField::intersect(int fromX, int fromY, int toX, int toY, bool includeTarget) {
|
|
|
+ if(!checkBounds(fromX, fromY) || !checkBounds(fromX, fromY))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ int dirX = toX - fromX;
|
|
|
+ int dirY = toY - fromY;
|
|
|
+
|
|
|
+ // No move
|
|
|
+ if(dirX == 0 && dirY == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ // We cannot calculate intersection for this direction, e.g. dirX = 5, dirY = 3
|
|
|
+ if(dirX != 0 && dirY != 0 && abs(dirX) != abs(dirY))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ dirX = normalalize(dirX);
|
|
|
+ dirY = normalalize(dirY);
|
|
|
+
|
|
|
+ int x = fromX + dirX;
|
|
|
+ int y = fromY + dirY;
|
|
|
+
|
|
|
+ for(; !(x == toX && y == toY); x += dirX, y += dirY) {
|
|
|
+ if(pieces[x][y] != nullptr)
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
-int main(int argc, char *argv[]) {
|
|
|
- CField field;
|
|
|
- cout << field;
|
|
|
+ return (includeTarget ? pieces[toX][toY] != nullptr : false);
|
|
|
}
|