//
// Created by hamac on 18.12.2024.
//

#include "Chessboard.h"
#include "Chesspiece.cpp"
#include "ChessUtils.cpp"
#include <iostream>
#include <fstream>

std::string Chessboard::getChessIcon(char identifier) {
    switch (identifier) {
    case 'x': return blackSquare;
    case 'r': return blackRook;
    case 'n': return blackKnight;
    case 'b': return blackBischop;
    case 'q': return blackQueen;
    case 'k': return blackKing;
    case 'p': return blackPawn;
    case 'w': return whiteSquare;
    case 'R': return whiteRook;
    case 'N': return whiteKnight;
    case 'B': return whiteBischop;
    case 'Q': return whiteQueen;
    case 'K': return whiteKing;
    case 'P': return whitePawn;
    default: return "";
    }
}

void Chessboard::generateTopLine() {
    this->display += " " + horizontal + " " + topLeft;
    for (int col = 0; col < boardSize; ++col) {
        this->display += horizontal + horizontal + horizontal;
        if (col < boardSize - 1) this->display += topIntersection;
    }
    this->display += topRight + "\n";
}

void Chessboard::generatePlayingField(const std::vector<std::vector<char>>& chessboard) {
    char desc = 56;
    for (int row = 0; row < boardSize; ++row) {
        this->display += " ";
        this->display += desc--;
        this->display += " " + vertical;
        for (int col = 0; col < boardSize; ++col) {
            this->display += " " + Chessboard::getChessIcon(chessboard[row][col]) + " " + vertical;
        }
        this->display += "\n";

        // Horizontale Trennlinie (außer nach der letzten Zeile)
        if (row < boardSize - 1) {
            this->display += " " + horizontal + " " + vertical;
            for (int col = 0; col < boardSize; ++col) {
                this->display += horizontal + horizontal + horizontal;
                if (col < boardSize - 1) this->display += middleIntersection;
            }
            this->display += vertical + "\n";
        }
    }
}

void Chessboard::generateBottomLine() {
    char desc = 65;
    this->display += " " + horizontal + " " + bottomLeft;
    for (int col = 0; col < boardSize; ++col) {
        this->display += horizontal + horizontal + horizontal;
        if (col < boardSize - 1) this->display += bottomIntersection;
    }
    this->display += bottomRight + "\n";
    this->display += "   " + vertical;
    for (int col = 0; col < boardSize; ++col) {
        this->display += " ";
        this->display += (desc++);
        this->display +=  " " + vertical;
    }
    this->display += "\n\n";
}

/* methods */
bool Chessboard::getTurnOrder() { return this->turnOrder; }
void Chessboard::setTurnOrder(bool turnOrder) { this->turnOrder = turnOrder; }

std::vector<std::vector<char>> Chessboard::getBoard() { return this->currentBoard; }
void Chessboard::setBoard(std::vector<std::vector<char>> board) { this->currentBoard = board; }

std::vector<std::vector<char>> Chessboard::getStartBoard() { return this->startBoard; }

std::vector<std::vector<char>> Chessboard::getEmptyBoard() { return this->emptyBoard; }

void Chessboard::draw () {
  //Chessboard::draw(getStartBoard());
  Chessboard::draw(this->currentBoard);
}

void Chessboard::draw (const std::vector<std::vector<char>>& chessboard) {
    this->display = "";
    // Obere Rahmenlinie
    Chessboard::generateTopLine();
    std::cout << std::endl;

    // Schachbrett mit vertikalen Linien
    Chessboard::generatePlayingField(chessboard);

    // Untere Rahmenlinie
    Chessboard::generateBottomLine();

    Chessboard::setBoard(chessboard);

    std::cout << this->display << std::endl;
    std::cout << std::endl;
}

void Chessboard::init() {
    Chessboard::initPieces();
}

void Chessboard::initPieces() {
    /*playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,0)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,1)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,2)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,3)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,4)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,5)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,6)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,7)));
    playingPieces['w'].push_back(std::make_unique<Rook>('w', std::make_pair(7,0)));
    playingPieces['w'].push_back(std::make_unique<Knight>('w', std::make_pair(7,1)));
    playingPieces['w'].push_back(std::make_unique<Bischop>('w', std::make_pair(7,2)));
    playingPieces['w'].push_back(std::make_unique<Queen>('w', std::make_pair(7,3)));
    playingPieces['w'].push_back(std::make_unique<King>('w', std::make_pair(7,4)));
    playingPieces['w'].push_back(std::make_unique<Bischop>('w', std::make_pair(7,5)));
    playingPieces['w'].push_back(std::make_unique<Knight>('w', std::make_pair(7,6)));
    playingPieces['w'].push_back(std::make_unique<Rooke>('w', std::make_pair(7,7)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(1,0)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,1)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,2)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,3)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,4)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,5)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,6)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,7)));
    playingPieces['b'].push_back(std::make_unique<Rook>('b', std::make_pair(0,0)));
    playingPieces['b'].push_back(std::make_unique<Knight>('b', std::make_pair(0,1)));
    playingPieces['b'].push_back(std::make_unique<Bischop>('b', std::make_pair(0,2)));
    playingPieces['b'].push_back(std::make_unique<Queen>('b', std::make_pair(0,3)));
    playingPieces['b'].push_back(std::make_unique<King>('b', std::make_pair(0,4)));
    playingPieces['b'].push_back(std::make_unique<Bischop>('b', std::make_pair(0,5)));
    playingPieces['b'].push_back(std::make_unique<Knight>('b', std::make_pair(0,6)));
    playingPieces['b'].push_back(std::make_unique<Rook>('b', std::make_pair(0,7)));*/
    /* playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,0)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,1)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,2)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,3)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,4)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,5)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,6)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(6,7)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,0)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,1)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,2)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,3)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,4)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,5)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,6)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(7,7)));
    playingPieces['w'].push_back(std::make_unique<Pawn>('w', std::make_pair(1,0)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,1)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,2)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,3)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,4)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,5)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,6)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(1,7)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,0)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,1)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,2)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,3)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,4)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,5)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,6)));
    playingPieces['b'].push_back(std::make_unique<Pawn>('b', std::make_pair(0,7))); */
}

void Chessboard::move() {

}

char Chessboard::getCorrectPiece(char pieceIdentifier) {
    bool isWhite = Chessboard::getTurnOrder();
    if (!isWhite) return pieceIdentifier + 32;
    return pieceIdentifier;
}

//
void Chessboard::move(std::string move) {
    std::vector<std::string> splitMove;

    if (move.find('#') != std::string::npos) {
        // Schachmate
        // Finish game
    } else if (move.rfind("0-0", 0) == 0) { // Kleine Rochade
      // Check for Rochade
    } else if (move.rfind("0-0-0", 0) == 0) {
        // Große Rochade
    }

    // Standard move
    if (move.find('-')) {
        splitMove = ChessUtils::split(move, '-');
    } else if (move.find('x')) {
        splitMove = ChessUtils::split(move, 'x');
    }

    std::pair oldCoords = ChessUtils::convertPosition(splitMove[0]);
    std::pair newCoords = ChessUtils::convertPosition(splitMove[1]);

    std::vector<std::vector<char>> board = getBoard();

    // Oben: Schwarz
    // Unten: Weiß

    // Eine Bewegung ist einfach nur die Spielfigur welche aus der alten Position in die neue Position verschoben wird.
    // Die alte Position ist damit immer leer (außer bei speziellen Spielzügen).
    // Sonderfall: Auf der neuen Position steht bereits eine Figur. Diese Figur ist dann weg!
    char figur = board[oldCoords.first][oldCoords.second];
    int fromFigurInt = (int) figur;
    int toFigurInt = (int) board[newCoords.first][newCoords.second];

    bool wrongPlayer = false;

    if (this->getTurnOrder() && (fromFigurInt >= 97 && fromFigurInt <= 118)) {
      wrongPlayer = true;
    } else if (this->getTurnOrder() == false && (fromFigurInt >= 65 && fromFigurInt <= 87)) {
      wrongPlayer = true;
    } else {
      wrongPlayer = false;
    }

    bool moveOK = false;

    std::cout << "From: " << board[oldCoords.first][oldCoords.second] << std::endl;
    std::cout << "To: " << board[newCoords.first][newCoords.second] << std::endl;

    switch(figur) {
      case 'P':
      case 'p':
        //Bauer
        if (fromFigurInt >= 97 && fromFigurInt <= 118) { // Schwarze Figur
          if (oldCoords.first + 2 == newCoords.first && oldCoords.second == newCoords.second) { // 2 Schritte nach vorne! Aber nur beim ersten Zug.
            if (fromFigurInt >= 97 && fromFigurInt <= 118 && oldCoords.first == 1) {
              if (board[newCoords.first][newCoords.second] == 'w' || board[newCoords.first][newCoords.second] == 'x') {
                moveOK = true;
              } else {
                moveOK = false;
              }
            }
          } else if (oldCoords.first + 1 == newCoords.first && oldCoords.second == newCoords.second) { // 1 Schritt nach vorne!
            if (board[newCoords.first][newCoords.second] == 'w' || board[newCoords.first][newCoords.second] == 'x') {
              moveOK = true;
            } else {
              moveOK = false;
            }
          } else if (oldCoords.first + 1 == newCoords.first && (oldCoords.second + 1 == newCoords.second || oldCoords.second - 1 == newCoords.second)) { // Quer schlagen
            if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
              // Eigene Figur
              moveOK = false;
            } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
              // Eigene Figur
              moveOK = false;
            } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
              // Gegnerfigur
              moveOK = true;
            } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
              // Gegnerfigur
              moveOK = true;
            } else {
              // Leeres Feld
              moveOK = false;
            }
          } else { //Falscher Zug
            moveOK = false;
          }
        } else if (fromFigurInt >= 65 && fromFigurInt <= 87) { // Weiße Figur
          if (oldCoords.first - 2 == newCoords.first && oldCoords.second == newCoords.second) { // 2 Schritte nach vorne! Aber nur beim ersten Zug.
            if (fromFigurInt >= 65 && fromFigurInt <= 87 && oldCoords.first == 6) {
              if (board[newCoords.first][newCoords.second] == 'w' || board[newCoords.first][newCoords.second] == 'x') {
                moveOK = true;
              } else {
                moveOK = false;
              }
            }
          } else if (oldCoords.first - 1 == newCoords.first && oldCoords.second == newCoords.second) { // 1 Schritt nach vorne!
            if (board[newCoords.first][newCoords.second] == 'w' || board[newCoords.first][newCoords.second] == 'x') {
              moveOK = true;
            } else {
              moveOK = false;
            }
          } else if (oldCoords.first - 1 == newCoords.first && (oldCoords.second + 1 == newCoords.second || oldCoords.second - 1 == newCoords.second)) { // Quer schlagen
            if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
              // Eigene Figur
              moveOK = false;
            } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
              // Eigene Figur
              moveOK = false;
            } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
              // Gegnerfigur
              moveOK = true;
            } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
              // Gegnerfigur
              moveOK = true;
            } else {
              // Leeres Feld
              moveOK = false;
            }
          } else { //Falscher Zug
            moveOK = false;
          }
        }
        break;
      case 'R': // Turm
      case 'r':
        // Der Turm darf wie die Dame ziehen, aber nicht diagonal.


        moveOK = false;

        // Der Turm wird Feld für Feld verschoben und dabei die Regel überprüft.
        // Es darf nur auf der Endposition zu einer Kollision kommen.
        // Dort muss dann überprüft werden ob eine gegnerische Figur dort steht oder eine eigene Figur.
        // Gegnerische Figur wird geschlagen. Die eigene Figur wäre hier ungültig.
        // Wenn das Feld leer ist, kann die Figur dort platziert werden.
        if (oldCoords.first > newCoords.first && oldCoords.second == newCoords.second) { // Turm zieht nach oben!
          for (int mV = oldCoords.first-1; mV >= newCoords.first; mV--) {
            if (mV == newCoords.first) { // Ziel erreicht!
              int toFigur = (int) board[mV][oldCoords.second];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[mV][oldCoords.second] == 'w' || board[mV][oldCoords.second] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.first < newCoords.first && oldCoords.second == newCoords.second) { // Turm zieht nach unten!
          for (int mV = oldCoords.first+1; mV <= newCoords.first; mV++) {
            if (mV == newCoords.first) { // Ziel erreicht!
              int toFigur = (int) board[mV][oldCoords.second];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[mV][oldCoords.second] == 'w' || board[mV][oldCoords.second] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.second > newCoords.second && oldCoords.first == newCoords.first) { // Turm zieht nach links!
          for (int mH = oldCoords.second-1; mH >= newCoords.second; mH--) {
            if (mH == newCoords.second) { // Ziel erreicht!
              int toFigur = (int) board[oldCoords.first][mH];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[oldCoords.first][mH] == 'w' || board[oldCoords.first][mH] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.second < newCoords.second && oldCoords.first == newCoords.first) { // Turm zieht nach rechts!
          for (int mH = oldCoords.second+1; mH <= newCoords.second; mH++) {
            if (mH == newCoords.second) { // Ziel erreicht!
              int toFigur = (int) board[oldCoords.first][mH];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[oldCoords.first][mH] == 'w' || board[oldCoords.first][mH] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        }
        break;
      case 'N'://Pferd
      case 'n':
        // Das Pferd zieht zwei Felder vorwärts und einen Schritt seitwärts.
        if ((oldCoords.first + 2 == newCoords.first || oldCoords.first - 2 == newCoords.first) && (oldCoords.second + 1 == newCoords.second || oldCoords.second - 1 == newCoords.second)) {
          int toFigur = (int) board[newCoords.first][newCoords.second];
          if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
            // Gegnerfigur
            moveOK = true;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
            // Gegnerfigur
            moveOK = true;
          } else {
            // Leeres Feld
            moveOK = true;
          }
        }
        break;
      case 'B': //Läufer
      case 'b':
        // Der Läufer darf wie die Dame ziehen, aber nicht horizontal oder vertikal.
        //Der Läufer wechselt auch nicht die Farbe auf dem Brett.


        for (int i = 1; i < 7; i++) {
          if (oldCoords.first < newCoords.first && oldCoords.second < newCoords.second) { // Bewegung nach rechts unten
            char currentFigur = board[oldCoords.first+i][oldCoords.second+i];

            if (newCoords.first == oldCoords.first+i && newCoords.second == oldCoords.second+i) { // Ziel erreicht.
              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
              break;
            } else { // Auf dem Weg
              if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                continue;
              } else { // Figur ist auf dem Weg
                moveOK = false;
              }
            }
          } else if (oldCoords.first > newCoords.first && oldCoords.second > newCoords.second) { // Bewegung nach links oben
            char currentFigur = board[oldCoords.first-i][oldCoords.second-i];

            if (newCoords.first == oldCoords.first-i && newCoords.second == oldCoords.second-i) { // Ziel erreicht.
              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
              break;
            } else { // Auf dem Weg
              if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                continue;
              } else { // Figur ist auf dem Weg
                moveOK = false;
              }
            }
          } else if (oldCoords.first < newCoords.first && oldCoords.second > newCoords.second) { // Bewegung nach links unten
            char currentFigur = board[oldCoords.first+i][oldCoords.second-i];

            if (newCoords.first == oldCoords.first+i && newCoords.second == oldCoords.second-i) { // Ziel erreicht.
              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
              break;
            } else { // Auf dem Weg
              if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                continue;
              } else { // Figur ist auf dem Weg
                moveOK = false;
              }
            }
          } else if (oldCoords.first > newCoords.first && oldCoords.second < newCoords.second) { // Bewegung nach rechts oben
            char currentFigur = board[oldCoords.first-i][oldCoords.second+i];

            if (newCoords.first == oldCoords.first-i && newCoords.second == oldCoords.second+i) { // Ziel erreicht.
              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
              break;
            } else { // Auf dem Weg
              if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                continue;
              } else { // Figur ist auf dem Weg
                moveOK = false;
              }
            }
          } else { // Fehlerhafte Bewegung
            moveOK = false;
          }
        }
        break;
      case 'Q': //Dame
      case 'q':
        // Die Königin kann in alle Richtungen beliebig viele Schritte ziehen. Figuren dürfen nicht übersprungen werden.
        // Vor eigenen Figuren muss angehalten werden. Gegnerische Figuren dürfen geschlagen werden und die Königin verbleibt auf diesem Feld.

        // Movement Diagonal (exakt gleich zu Läufer)
        // und dann Movement Horizontal / Vertikal (exakt gleich zu Turm)
        if (oldCoords.first > newCoords.first && oldCoords.second == newCoords.second) { // Turm zieht nach oben!
          for (int mV = oldCoords.first-1; mV >= newCoords.first; mV--) {
            if (mV == newCoords.first) { // Ziel erreicht!
              int toFigur = (int) board[mV][oldCoords.second];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[mV][oldCoords.second] == 'w' || board[mV][oldCoords.second] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.first < newCoords.first && oldCoords.second == newCoords.second) { // Turm zieht nach unten!
          for (int mV = oldCoords.first+1; mV <= newCoords.first; mV++) {
            if (mV == newCoords.first) { // Ziel erreicht!
              int toFigur = (int) board[mV][oldCoords.second];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[mV][oldCoords.second] == 'w' || board[mV][oldCoords.second] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.second > newCoords.second && oldCoords.first == newCoords.first) { // Turm zieht nach links!
          for (int mH = oldCoords.second-1; mH >= newCoords.second; mH--) {
            if (mH == newCoords.second) { // Ziel erreicht!
              int toFigur = (int) board[oldCoords.first][mH];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[oldCoords.first][mH] == 'w' || board[oldCoords.first][mH] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else if (oldCoords.second < newCoords.second && oldCoords.first == newCoords.first) { // Turm zieht nach rechts!
          for (int mH = oldCoords.second+1; mH <= newCoords.second; mH++) {
            if (mH == newCoords.second) { // Ziel erreicht!
              int toFigur = (int) board[oldCoords.first][mH];

              if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 97 && toFigur <= 118) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 65 && toFigur <= 87) {
                // Eigene Figur
                moveOK = false;
              } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigur >= 65 && toFigur <= 87) {
                // Gegnerfigur
                moveOK = true;
              } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigur >= 97 && toFigur <= 118) {
                // Gegnerfigur
                moveOK = true;
              } else {
                // Leeres Feld
                moveOK = true;
              }
            } else { // Auf dem Weg
              if (board[oldCoords.first][mH] == 'w' || board[oldCoords.first][mH] == 'x') { // OK - Weiter
                continue;
              } else { // Fehler - Da steht eine Figur - Spielzug ungültig!
                moveOK = false;
              }
            }
          }
        } else { // muss vertikal sein

          // exakt gleich zum Läufer
          for (int i = 1; i < 7; i++) {
            if (oldCoords.first < newCoords.first && oldCoords.second < newCoords.second) { // Bewegung nach rechts unten
              char currentFigur = board[oldCoords.first+i][oldCoords.second+i];

              if (newCoords.first == oldCoords.first+i && newCoords.second == oldCoords.second+i) { // Ziel erreicht.
                if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Gegnerfigur
                  moveOK = true;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Gegnerfigur
                  moveOK = true;
                } else {
                  // Leeres Feld
                  moveOK = true;
                }
                break;
              } else { // Auf dem Weg
                if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                  continue;
                } else { // Figur ist auf dem Weg
                  moveOK = false;
                }
              }
            } else if (oldCoords.first > newCoords.first && oldCoords.second > newCoords.second) { // Bewegung nach links oben
              char currentFigur = board[oldCoords.first-i][oldCoords.second-i];

              if (newCoords.first == oldCoords.first-i && newCoords.second == oldCoords.second-i) { // Ziel erreicht.
                if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Gegnerfigur
                  moveOK = true;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Gegnerfigur
                  moveOK = true;
                } else {
                  // Leeres Feld
                  moveOK = true;
                }
                break;
              } else { // Auf dem Weg
                if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                  continue;
                } else { // Figur ist auf dem Weg
                  moveOK = false;
                }
              }
            } else if (oldCoords.first < newCoords.first && oldCoords.second > newCoords.second) { // Bewegung nach links unten
              char currentFigur = board[oldCoords.first+i][oldCoords.second-i];

              if (newCoords.first == oldCoords.first+i && newCoords.second == oldCoords.second-i) { // Ziel erreicht.
                if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Gegnerfigur
                  moveOK = true;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Gegnerfigur
                  moveOK = true;
                } else {
                  // Leeres Feld
                  moveOK = true;
                }
                break;
              } else { // Auf dem Weg
                if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                  continue;
                } else { // Figur ist auf dem Weg
                  moveOK = false;
                }
              }
            } else if (oldCoords.first > newCoords.first && oldCoords.second < newCoords.second) { // Bewegung nach rechts oben
              char currentFigur = board[oldCoords.first-i][oldCoords.second+i];

              if (newCoords.first == oldCoords.first-i && newCoords.second == oldCoords.second+i) { // Ziel erreicht.
                if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Eigene Figur
                  moveOK = false;
                } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
                  // Gegnerfigur
                  moveOK = true;
                } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
                  // Gegnerfigur
                  moveOK = true;
                } else {
                  // Leeres Feld
                  moveOK = true;
                }
                break;
              } else { // Auf dem Weg
                if (currentFigur == 'w' || currentFigur == 'x') { // OK weiter
                  continue;
                } else { // Figur ist auf dem Weg
                  moveOK = false;
                }
              }
            } else { // Fehlerhafte Bewegung
              moveOK = false;
            }
          }
        }
        break;
      case 'K'://König
      case 'k':
        // Der König kann in alle Richtungen einen Schritt ziehen. Darf sich dabei aber nicht gefährden.
        if ((oldCoords.first + 1 == newCoords.first || oldCoords.first - 1 == newCoords.first) && (oldCoords.second == newCoords.second)) {
          // 1 Schritt nach vorne oder hinten!
          if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Gegnerfigur
            moveOK = true;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Gegnerfigur
            moveOK = true;
          } else {
            // Leeres Feld
            moveOK = true;
          }
        }
        if ((oldCoords.second + 1 == newCoords.second || oldCoords.second - 1 == newCoords.second) && (oldCoords.first == newCoords.first)) {
          // 1 Schritt nach links oder rechts!
          if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Gegnerfigur
            moveOK = true;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Gegnerfigur
            moveOK = true;
          } else {
            // Leeres Feld
            moveOK = true;
          }
        }
        if (oldCoords.first + 1 == newCoords.first && (oldCoords.second - 1 == newCoords.second || oldCoords.second + 1 == newCoords.second)) {
          // 1 Schritt quer nach vorne!
          if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Gegnerfigur
            moveOK = true;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Gegnerfigur
            moveOK = true;
          } else {
            // Leeres Feld
            moveOK = true;
          }
        }
        if (oldCoords.first - 1 == newCoords.first && (oldCoords.second - 1 == newCoords.second || oldCoords.second + 1 == newCoords.second)) {
          // 1 Schritt quer nach hinten!
          if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Eigene Figur
            moveOK = false;
          } else if (fromFigurInt >= 97 && fromFigurInt <= 118 && toFigurInt >= 65 && toFigurInt <= 87) {
            // Gegnerfigur
            moveOK = true;
          } else if (fromFigurInt >= 65 && fromFigurInt <= 87 && toFigurInt >= 97 && toFigurInt <= 118) {
            // Gegnerfigur
            moveOK = true;
          } else {
            // Leeres Feld
            moveOK = true;
          }
        }
        break;
      default:
        //Ungültig
        break;
    }

    if (!wrongPlayer) {
      if (moveOK) {
        board[newCoords.first][newCoords.second] = board[oldCoords.first][oldCoords.second];
        board[oldCoords.first][oldCoords.second] = 'x';
        this->queue.push(move);
        this->turnOrder = !this->turnOrder;
      } else {
        std::cout << "Wrong Movement!" << std::endl;
      }
    } else {
      std::cout << "Wrong Player!" << std::endl;
    }

    //board[oldCoords.first][oldCoords.second] = getEmptyBoard()[oldCoords.first][oldCoords.second];
    //board[newCoords.first][newCoords.second] = getCorrectPiece(splitMove[0][0]);

    //e4-e5

    Chessboard::draw(board);

    // Notation
    // Start with current position - dash - new position
    // eg.: b1-c3
    // Letter first than number
    // eg.: a5
    // Pawn: e4 or p e4 (pawn)
    // R for rook
    // N for Knight
    // K for King
    // B for Bischop
    // Q for Queen
    // Special:
    // 0-0 short castle
    // 0-0-0 long castle
    // en passant: write square where pawn lands
    // Umwandlung: g8=R,Q,N,B (Wo gehst du hin = Was wirst du)

    // capture: x
    // check: +
    // checkmate: #
    // draw/stalemate: 1/2-1/2

}

// This method saves the current board state
void Chessboard::saveBoard() {
  std::ofstream savefile;
  savefile.open("test.txt");
  for (int i = 0; i < this->currentBoard.size(); i++) {
    for (int j = 0; j < this->currentBoard[i].size(); j++) {
      savefile << this->currentBoard[i][j];
    }
    savefile << std::endl;
  }
  savefile.close();
  //TODO Zeile 9 - Spieler am Zug
  //TODO Zeile 10... Spielzüge?
}

// This method loads a save state
void Chessboard::loadBoard(std::string filepath) {
  std::ifstream savefile;
  savefile.open(filepath);
  std::string line;
  std::vector<std::vector<char>> board;
  int rownumber = 0;

  while (std::getline(savefile, line)) {
    std::istringstream iss(line);

    if (rownumber < 8) {
      std::vector<char> row;

      for (int c = 0; c < line.length(); c++) {
        row.push_back(line[c]);
      }
      board.push_back(row);
    } else if (rownumber == 8) {
      std::cout << "Spieler: " << line;
    }
    rownumber++;
  }

  this->currentBoard = board;
}