Compare commits

..

3 Commits

18 changed files with 419 additions and 394 deletions

View File

@@ -5,13 +5,10 @@
* @param move The move that uses the short algebraic notation.
*/
ChessPieceMove::ChessPieceMove(std::string move) {
move = this->Normalize(move);
this->_move = this->Normalize(move);
if (this->IsValidShortNotation(move)) {
this->_move = move;
if (this->IsValidShortNotation()) {
this->ParseShortNotation();
} else {
throw std::invalid_argument("invalid move notation");
}
}

View File

@@ -19,39 +19,43 @@
#include "../ChessPieces/Queen.hpp"
#include "../ChessPieces/Rook.hpp"
void Chessboard::InitializeStartBoard() {
Chessboard::InitializeBoard(defaultBoard);
}
void Chessboard::SetStartingPosition() {
void Chessboard::InitializeBoard(std::set<Board_ChessPiece> board) {
for (const auto& piece : board) {
ChessPiecePosition pos = ChessPiecePosition(piece.position.first, piece.position.second);
ChessPieceColor color = (piece.color == 0) ? ChessPieceColor::Black : ChessPieceColor::White;
// black chess pieces
this->SetChessPiece(new Rook(ChessPieceColor::Black, ChessPiecePosition("A8")));
this->SetChessPiece(new Knight(ChessPieceColor::Black, ChessPiecePosition("B8")));
this->SetChessPiece(new Bishop(ChessPieceColor::Black, ChessPiecePosition("C8")));
this->SetChessPiece(new Queen(ChessPieceColor::Black, ChessPiecePosition("D8")));
this->SetChessPiece(new King(ChessPieceColor::Black, ChessPiecePosition("E8")));
this->SetChessPiece(new Bishop(ChessPieceColor::Black, ChessPiecePosition("F8")));
this->SetChessPiece(new Knight(ChessPieceColor::Black, ChessPiecePosition("G8")));
this->SetChessPiece(new Rook(ChessPieceColor::Black, ChessPiecePosition("H8")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("A7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("B7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("C7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("D7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("E7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("F7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("G7")));
this->SetChessPiece(new Pawn(ChessPieceColor::Black, ChessPiecePosition("H7")));
switch (piece.type) {
case 'R':
SetChessPiece(new Rook(color, pos));
break;
case 'N':
SetChessPiece(new Knight(color, pos));
break;
case 'B':
SetChessPiece(new Bishop(color, pos));
break;
case 'Q':
SetChessPiece(new Queen(color, pos));
break;
case 'K':
SetChessPiece(new King(color, pos));
break;
case 'P':
SetChessPiece(new Pawn(color, pos));
break;
default:
std::cout << "Invalid ChessPieceType!" << std::endl;
return;
}
}
// white chess pieces
this->SetChessPiece(new Rook(ChessPieceColor::White, ChessPiecePosition("A1")));
this->SetChessPiece(new Knight(ChessPieceColor::White, ChessPiecePosition("B1")));
this->SetChessPiece(new Bishop(ChessPieceColor::White, ChessPiecePosition("C1")));
this->SetChessPiece(new Queen(ChessPieceColor::White, ChessPiecePosition("D1")));
this->SetChessPiece(new King(ChessPieceColor::White, ChessPiecePosition("E1")));
this->SetChessPiece(new Bishop(ChessPieceColor::White, ChessPiecePosition("F1")));
this->SetChessPiece(new Knight(ChessPieceColor::White, ChessPiecePosition("G1")));
this->SetChessPiece(new Rook(ChessPieceColor::White, ChessPiecePosition("H1")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("A2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("B2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("C2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("D2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("E2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("F2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("G2")));
this->SetChessPiece(new Pawn(ChessPieceColor::White, ChessPiecePosition("H2")));
}
/**

View File

@@ -41,66 +41,11 @@ class Chessboard {
void RemoveChessPiece(ChessPiecePosition position);
public:
struct Board_ChessPiece {
int color;
char type;
std::pair<char, int> position;
Board_ChessPiece(const int& c, const char& t, std::pair<char,int> p) : color(c), type(t), position(p) {}
bool operator<(const Board_ChessPiece& other) const {
if (position != other.position) {
return position < other.position;
}
if (color != other.color) {
return color < other.color;
}
return type < other.type;
}
};
inline static const std::set<Board_ChessPiece> defaultBoard = {
{0, 'P', {'A', 7}},
{0, 'P', {'B', 7}},
{0, 'P', {'C', 7}},
{0, 'P', {'D', 7}},
{0, 'P', {'E', 7}},
{0, 'P', {'F', 7}},
{0, 'P', {'G', 7}},
{0, 'P', {'H', 7}},
{0, 'R', {'A', 8}},
{0, 'N', {'B', 8}},
{0, 'B', {'C', 8}},
{0, 'Q', {'D', 8}},
{0, 'K', {'E', 8}},
{0, 'B', {'F', 8}},
{0, 'N', {'G', 8}},
{0, 'R', {'H', 8}},
{1, 'P', {'A', 2}},
{1, 'P', {'B', 2}},
{1, 'P', {'C', 2}},
{1, 'P', {'D', 2}},
{1, 'P', {'E', 2}},
{1, 'P', {'F', 2}},
{1, 'P', {'G', 2}},
{1, 'P', {'H', 2}},
{1, 'R', {'A', 1}},
{1, 'N', {'B', 1}},
{1, 'B', {'C', 1}},
{1, 'Q', {'D', 1}},
{1, 'K', {'E', 1}},
{1, 'B', {'F', 1}},
{1, 'N', {'G', 1}},
{1, 'R', {'H', 1}}
};
~Chessboard();
std::string GetAmountOfGames();
std::vector<ChessPieceMove> GetHistoryMoves();
std::vector<std::pair<ChessPiecePosition, ChessPiecePosition>> GetHistoryPositions();
std::string GetTodaysDate(std::string format);
void InitializeStartBoard();
void InitializeBoard(std::set<Board_ChessPiece> board);
//void SetChessPiece(std::unique_ptr<ChessPiece> piece);
void SetStartingPosition();
void SetChessPiece(ChessPiece* chesspiece);
bool IsDraw();
bool IsEmptyField(ChessPiecePosition* position);

View File

@@ -5,7 +5,7 @@
#include "Visualizer/ImportVisualizer.hpp"
#include "Visualizer/PlayingViewVisualizer.hpp"
#include "Visualizer/PlaySelectVisualizer.hpp"
#include <filesystem>
#include <iostream>
#include <memory>
@@ -17,227 +17,238 @@ MenuController::~MenuController() {
// Destruktor, falls nötig
}
void MenuController::HandlePlayingNavigation(std::string choice, Chessboard& chessboard, PlayingViewVisualizer& playView, bool isGameOver) {
if (choice.empty() == false) {
if (choice.at(0) == '$') {
if (choice == "$0") {
return;
} else if (choice == "$1") {
HandleThirdOption();
} else if (choice == "$2") {
chessboard.ExportFilePGN("chessgames/save_games/");
} else if (choice == "$3") {
if (isGameOver) {
playView.SetMessage("Game is over! No moves allowed.");
} else {
chessboard.SetWinner(chessboard.GetOpponentPlayer());
}
}
} else {
if (isGameOver) {
playView.SetMessage("Game is over! No moves allowed.");
} else {
playView.SetMessage(chessboard.MoveChessPiece(choice));
}
}
}
}
void MenuController::HandleFirstOption() {
BaseVisualizer::ClearTerminal();
PlaySelectVisualizer playerSelect(3);
playerSelect.DisplayElement();
std::string input;
std::cout << "\x1B[u"; // Cursor-Positionierung
std::string choiceA;
std::string choiceB;
// ToDo: Fehlerbehandlung
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, input);
do {
playerSelect.SetLabelPlayerName("first player");
choiceA = playerSelect.ShowMenu();
std::vector<std::string> vec = split(input, '&', true);
if (choiceA.length() > 40) {
choiceA.clear();
}
} while (choiceA.empty());
do {
playerSelect.SetLabelPlayerName("second player");
choiceB = playerSelect.ShowMenu();
if (choiceB.length() > 40) {
choiceB.clear();
};
} while (choiceB.empty());
// Spieler initialisieren
Player* playerA = new Player(vec[0]);
Player* playerB = new Player(vec[1]);
Player* playerA = new Player(choiceA);
Player* playerB = new Player(choiceB);
// Schachbrett initialisieren
Chessboard chessboard;
chessboard.SetPlayers(playerA, playerB);
chessboard.InitializeStartBoard();
chessboard.SetPlayersRdm(playerA, playerB);
chessboard.SetStartingPosition();
chessboard.UpdateChessPieces();
SetChessboard(&chessboard);
// Spielansicht vorbereiten
PlayingViewVisualizer playView(&chessboard, 4, 12);
std::string choiceChessboard;
do {
while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
playView.DisplayElement();
std::string input;
std::cout << "\x1B[u"; // Cursor-Positionierung
std::cin >> input;
std::string command = ExtractAfterDollar(input);
if (!command.empty()) {
HandleCommandOptions(command);
if (command == "0") {
return;
}
} else {
std::string status = chessboard.MoveChessPiece(input);
if (status.empty() == false) {
playView.SetMessage(status);
}
}
choiceChessboard = playView.ShowMenu();
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, false);
}
std::string winner = chessboard.GetWinner();
choiceChessboard = "$0";
if (winner.empty()) {
playView.SetMessage("Game is over! - Draw");
} else {
playView.SetMessage("Game is over! - " + winner + " has won the game!");
}
} while (choiceChessboard != "$0");
while (true) {
playView.DisplayElement();
std::string input;
std::cout << "\x1B[u"; // Cursor-Positionierung
std::cin >> input;
do {
choiceChessboard = playView.ShowMenu();
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, true);
} while (choiceChessboard != "$0");
std::string command = ExtractAfterDollar(input);
if (command == "0") {
return;
}
}
// while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
// playView.DisplayElement();
// std::string input;
// std::cout << "\x1B[u"; // Cursor-Positionierung
// std::cin >> input;
// std::string command = ExtractAfterDollar(input);
// if (!command.empty()) {
// HandleCommandOptions(command);
// if (command == "0") {
// return;
// }
// } else {
// std::string status = chessboard.MoveChessPiece(input);
// if (status.empty() == false) {
// playView.SetMessage(status);
// }
// }
// }
// std::string winner = chessboard.GetWinner();
// if (winner.empty()) {
// playView.SetMessage("Game is over! - Draw");
// } else {
// playView.SetMessage("Game is over! - " + winner + " has won the game!");
// }
// while (true) {
// playView.DisplayElement();
// std::string input;
// std::cout << "\x1B[u"; // Cursor-Positionierung
// std::cin >> input;
// std::string command = ExtractAfterDollar(input);
// if (command == "0") {
// return;
// }
// }
}
void MenuController::HandleSecondOption() {
BaseVisualizer::ClearTerminal();
ImportVisualizer import;
import.DisplayElement();
ImportVisualizer importSelect;
std::string input;
std::string filePath;
std::cout << "\x1B[u";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, filePath);
if (filePath.empty()) {
return;
do {
filePath = importSelect.ShowMenu();
if (std::filesystem::exists(filePath) == false) {
filePath.clear();
}
} while (filePath.empty());
Chessboard chessboard;
chessboard.InitializeStartBoard();
chessboard.SetStartingPosition();
chessboard.UpdateChessPieces();
SetChessboard(&chessboard);
std::string status = chessboard.ImportFilePGN(filePath);
if (status.empty() == false) {
return;
}
BaseVisualizer::ClearTerminal();
PlayingViewVisualizer playView(&chessboard, 4, 12);
playView.SetMessage(status);
playView.DisplayElement();
bool isFirstDisplayed = true;
std::string choiceChessboard;
if (status.empty() == false) {
playView.SetMessage(status);
} else {
do {
while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
if (isFirstDisplayed) {
isFirstDisplayed = false;
} else {
playView.DisplayElement();
}
std::cout << "\x1B[u"; // Cursor-Positionierung
std::cin.clear();
std::getline(std::cin, input);
std::string command = ExtractAfterDollar(input);
if (!command.empty()) {
HandleCommandOptions(command);
if (command == "0") {
}
} else {
std::string status = chessboard.MoveChessPiece(input);
if (status.empty() == false) {
playView.SetMessage(status);
}
}
choiceChessboard = playView.ShowMenu();
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, false);
}
std::string winner = chessboard.GetWinner();
choiceChessboard = "$0";
if (winner.empty()) {
playView.SetMessage("Game is over! - Draw");
} else {
playView.SetMessage("Game is over! - " + winner + " has won the game!");
}
}
} while (choiceChessboard != "$0");
while (true) {
playView.DisplayElement();
std::string input;
std::cout << "\x1B[u"; // Cursor-Positionierung
std::cin >> input;
std::string command = ExtractAfterDollar(input);
if (command == "0") {
return;
}
}
do {
choiceChessboard = playView.ShowMenu();
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, true);
} while (choiceChessboard != "$0");
}
// ToDo:: Hier muss aus irgendeinem Grund immer zweimal die Eingabe abgeschickt werden. Why!?
void MenuController::HandleThirdOption() {
BaseVisualizer::ClearTerminal();
InstructionsVisualizer instructions;
instructions.DisplayElement();
std::string dummyInput;
// Eingabepuffer leeren
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "\x1B[u"; // Cursor-Positionierung
std::cin.clear();
std::getline(std::cin, dummyInput);
instructions.DrawView();
}
void MenuController::HandleCommandOptions(const std::string& command) {
if (command == "1") {
HandleThirdOption();
return;
} else if (command == "2") {
CHESSBOARD->ExportFilePGN("chessgames/save_games/");
std::cout << "Save game functionality is not implemented yet.\n";
} else if (command == "3") {
// resign
CHESSBOARD->SetWinner(CHESSBOARD->GetOpponentPlayer());
return;
} else if (command == "0") { // exit
return;
} else {
std::cout << "Invalid command. Please try again.\n";
}
}
// void MenuController::HandleCommandOptions(const std::string& command) {
// if (command == "1") {
// HandleThirdOption();
// return;
// } else if (command == "2") {
// CHESSBOARD->ExportFilePGN("chessgames/save_games/");
// std::cout << "Save game functionality is not implemented yet.\n";
// } else if (command == "3") {
// CHESSBOARD->SetWinner(CHESSBOARD->GetOpponentPlayer());
// return;
// } else if (command == "0") { // exit
// return;
// } else {
// std::cout << "Invalid command. Please try again.\n";
// }
// }
std::string MenuController::ExtractAfterDollar(const std::string& userInput) {
if (!userInput.empty() && userInput[0] == '$') {
return userInput.substr(1); // Rückgabe des Teils nach '$'
}
return ""; // Leerer String, wenn kein '$' am Anfang
}
// std::string MenuController::ExtractAfterDollar(const std::string& userInput) {
// if (!userInput.empty() && userInput[0] == '$') {
// return userInput.substr(1); // Rückgabe des Teils nach '$'
// }
// return ""; // Leerer String, wenn kein '$' am Anfang
// }
Chessboard* MenuController::GetChessboard() {
return CHESSBOARD;
}
// Chessboard* MenuController::GetChessboard() {
// return CHESSBOARD;
// }
void MenuController::SetChessboard(Chessboard* chessboard) {
CHESSBOARD = chessboard;
}
std::string MenuController::trim(const std::string& str) {
size_t start = str.find_first_not_of(" \t\n\r\f\v");
if (start == std::string::npos) return ""; // Nur Leerzeichen
size_t end = str.find_last_not_of(" \t\n\r\f\v");
return str.substr(start, end - start + 1);
}
// std::string MenuController::trim(const std::string& str) {
// size_t start = str.find_first_not_of(" \t\n\r\f\v");
// if (start == std::string::npos) return ""; // Nur Leerzeichen
// size_t end = str.find_last_not_of(" \t\n\r\f\v");
// return str.substr(start, end - start + 1);
// }
std::vector<std::string> MenuController::split(const std::string& str, char delimiter, bool trimWhitespace) {
std::vector<std::string> tokens;
std::istringstream stream(str);
std::string token;
// std::vector<std::string> MenuController::split(const std::string& str, char delimiter, bool trimWhitespace) {
// std::vector<std::string> tokens;
// std::istringstream stream(str);
// std::string token;
while (std::getline(stream, token, delimiter)) {
if (trimWhitespace) {
token = trim(token); // Trimme die Tokens, falls gewünscht
}
tokens.push_back(token);
}
// while (std::getline(stream, token, delimiter)) {
// if (trimWhitespace) {
// token = trim(token); // Trimme die Tokens, falls gewünscht
// }
// tokens.push_back(token);
// }
return tokens;
}
// return tokens;
// }

View File

@@ -2,13 +2,14 @@
#define MENU_CONTROLLER_HPP
#include "Chessboard/Chessboard.hpp"
#include "Visualizer/PlayingViewVisualizer.hpp"
#include <string>
class MenuController {
private:
std::string ExtractAfterDollar(const std::string& userInput);
void InitializeGame();
void HandlePlayingNavigation(std::string choice, Chessboard& chessboard, PlayingViewVisualizer& playView, bool isGameOver);
Chessboard* CHESSBOARD;
@@ -19,11 +20,11 @@ public:
void HandleFirstOption();
void HandleSecondOption();
void HandleThirdOption();
void HandleCommandOptions(const std::string& command);
Chessboard* GetChessboard();
// void HandleCommandOptions(const std::string& command);
// Chessboard* GetChessboard();
void SetChessboard(Chessboard* chessboard);
std::string trim(const std::string& str);
std::vector<std::string> split(const std::string& str, char delimiter, bool trimWhitespace = false);
// std::string trim(const std::string& str);
// std::vector<std::string> split(const std::string& str, char delimiter, bool trimWhitespace = false);
};
#endif // MENU_CONTROLLER_HPP

View File

@@ -11,6 +11,7 @@ void CommandMenuVisualizer::GenerateElement() {
std::string str_temp = ((CHESSBOARD->GetCurrentPlayer()->GetColor() == ChessPieceColor::White) ? "White" : "Black");
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Move [" + str_temp + "] : \x1B[s", true, PADDING);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, true);
display_vector.push_back({" "});
BaseVisualizer::display_vector.push_back({std::string(" ").append(GetMessage())});
}

View File

@@ -1,4 +1,5 @@
#include "HistorieVisualizer.hpp"
#include <algorithm>
#include "../ChessPieces/ChessPieceMove.hpp"
void HistorieVisualizer::GenerateElement() {
@@ -18,49 +19,34 @@ void HistorieVisualizer::GenerateElement() {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {playerName1, playerName2}, true);
BaseVisualizer::GenerateTableSeperator(MAX_MENU_WIDTH, true);
std::vector<ChessPieceMove> moves = this->CHESSBOARD->GetHistoryMoves();
// ToDo: History einlesen und anzeigen lassenF
if (moves.size() == 0) {
for (size_t i = 0; i < 5; i++) {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {"", ""}, true);
}
if (moves.size() % 2 == 0) {
moves = std::vector<ChessPieceMove>(moves.end() - std::min<int>(moves.size(), 10), moves.end());
} else {
moves = std::vector<ChessPieceMove>(moves.end() - std::min<int>(moves.size(), 9), moves.end());
}
if (moves.size() > 0 && moves.size() < 11) {
std::vector<std::string> rowMoves;
int rows = 0;
for (int moveIndex = moves.size(); moveIndex > 0; moveIndex =- 2) {
if (moveIndex == 1) { // Sonderfall: Letztes Element bei ungerader Anzahl
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {moves[moveIndex-1].ToString(), ""}, true);
} else {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {moves[moveIndex-2].ToString(), moves[moveIndex-1].ToString()}, true);
}
if (moveIndex % 2 == 0) {
for (int moveIndex = 0; moveIndex < moves.size(); moveIndex++) {
if (moveIndex % 2 == 0) rowMoves.clear();
rowMoves.push_back(moves[moveIndex].ToString());
if (moveIndex % 2 == 1) {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, rowMoves, true);
rows++;
} else if (moveIndex == moves.size() - 1) {
rowMoves.push_back("");
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, rowMoves, true);
rows++;
}
}
for (size_t i = 0; i < 5-rows; i++) {
for (int rowIndex = rows; rowIndex < 5; rowIndex++) {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {"", ""}, true);
}
}
if (moves.size() >= 11) {
size_t rows = 0;
for (size_t moveIndex = moves.size(); moveIndex > moves.size()-10; moveIndex -= 2) {
if (moveIndex == 1) { // Sonderfall: Letztes Element bei ungerader Anzahl
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {moves[moveIndex-1].ToString(), ""}, true);
} else {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {moves[moveIndex-2].ToString(), moves[moveIndex-1].ToString()}, true);
}
rows++;
}
for (size_t i = 1; i < 5-(rows/2); i++) {
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {"", ""}, true);
}
}
BaseVisualizer::GenerateTableTopBottom(MAX_MENU_WIDTH, false, true);
}

View File

@@ -1,13 +1,36 @@
#include "ImportVisualizer.hpp"
void ImportVisualizer::GenerateElement() {
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
for (const auto& content : menuContent) {
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
}
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "You can get a lot of PGN files from chessgames.com.", false, PADDING);
BaseVisualizer::AddEmptyLines(5, MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
// BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
// for (const auto& content : menuContent) {
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
// }
// BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "You can get a lot of PGN files from chessgames.com.", false, PADDING);
// BaseVisualizer::AddEmptyLines(5, MAX_MENU_WIDTH, false);
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
}
void ImportVisualizer::DrawView() {
BaseVisualizer::ClearTerminal();
this->display_vector.clear();
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Please enter a path to a PGN (Portable Game Notation) file:", false, PADDING);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "\x1B[s", false, PADDING);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "On https://chessgames.com/ you will find many more chess", false, PADDING);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "games in PGN format, to import into TurboSchach.", false, PADDING);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
BaseVisualizer::DisplayElement();
std::cout << "\x1B[u";
}
std::string ImportVisualizer::ShowMenu() {
this->DrawView();
std::string choice;
std::getline(std::cin, choice);
return choice;
}

View File

@@ -15,6 +15,8 @@ class ImportVisualizer : public BaseVisualizer {
ImportVisualizer() : BaseVisualizer(60, 4) {
ImportVisualizer::GenerateElement();
};
std::string ShowMenu();
void DrawView();
};
#endif //INSTRUCTIONSVISUALIZER_HPP

View File

@@ -7,7 +7,14 @@ void InstructionsVisualizer::GenerateElement() {
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
}
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Enter any key to return to menu: \x1B[s", false, PADDING);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Press enter to continue: \x1B[s", false, PADDING);
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
}
void InstructionsVisualizer::DrawView() {
BaseVisualizer::ClearTerminal();
BaseVisualizer::DisplayElement();
std::cout << "\x1B[u";
std::string choice;
std::getline(std::cin, choice);
}

View File

@@ -8,38 +8,45 @@ class InstructionsVisualizer : public BaseVisualizer {
inline static const std::vector<std::string> menuContent = {
"1. Algebraische Notation",
"",
"Um die Figuren auf dem Schachbrett zu bewegen, wird die kurze algebraische Notation nach [FIDE](https://handbook.fide.com/chapter/E012023)",
"(siehe Appendix C) unterstützt. Es werden die Schachfiguren sowohl in deutscher als auch in englischer Sprache unterstützt.",
"Um die Figuren auf dem Schachbrett zu bewegen, wird die kurze algebraische Notation",
"FIDE-Handbuch (siehe Appendix C) unterstützt. Es werden die Schachfiguren sowohl in",
"deutscher als auch in englischer Sprache unterstützt.",
"",
"| -------------------------------------- |",
"| Schachfigur | Deutsch | Englisch |",
"| ----------------- | ------- | -------- |",
"| Bauer (Pawn) | B | P |",
"| Springer (Knight) | S | N |",
"| Läufer (Bishop) | L | B |",
"| Turm (Rook) | T | R |",
"| Dame (Queen) | D | Q |",
"| König (King) | K | K |",
"| -------------------------------------- |",
"┌───────────────────┬─────────┬──────────┐",
" Schachfigur Deutsch Englisch ",
"├───────────────────┼─────────┼──────────┤",
" Bauer (Pawn) B P ",
" Springer (Knight) S N ",
" Läufer (Bishop) L B ",
" Turm (Rook) T R ",
" Dame (Queen) D Q ",
" König (King) K K ",
"└───────────────────┴─────────┴──────────┘",
"",
"Bei der kurzen Notation wird immer nur das Zielfeld eines Spielzuges genannt. Sollte der Ursprung nicht eindeutig sein kann auch die Spalte",
"oder Zeile der zu bewegenden Figur genannt werden. So gibt der Spielzug `dxe5` an dass der Bauer in der Spalte D auf das Feld E5 zieht. Das",
"`x` gibt an dass dabei eine Spielfigur des Gegeners geschlagen wird. Dies muss aber nicht zwingend angegeben werden. Der Bauer wird in den",
"Spielzügen nicht benannt. Der Spielzug `b4` ist daher der Zug eines Bauern auf das Feld B4. Alle anderen Schachfiguren werden im Zug mit",
"ihrem entsprechenden Buchstaben genannt. So gibt der Spielzug `Bc4` an dass der Läufer auf das Feld C4 gezogen wird.",
"Bei der kurzen Notation wird immer nur das Zielfeld eines Spielzuges genannt. Sollte",
"der Ursprung nicht eindeutig sein kann auch die Spalte oder Zeile der zu bewegenden Figur",
"genannt werden. So gibt der Spielzug 'dxe5' an dass der Bauer in der Spalte D auf das Feld",
"E5 zieht. Das 'x' gibt an dass dabei eine Spielfigur des Gegeners geschlagen wird. Dies muss",
"aber nicht zwingend angegeben werden. Der Bauer wird in den Spielzügen nicht benannt. Der",
"Spielzug 'b4' ist daher der Zug eines Bauern auf das Feld B4. Alle anderen Schachfiguren werden",
"im Zug mit ihrem entsprechenden Buchstaben genannt. So gibt der Spielzug 'Bc4' an dass der Läufer",
"auf das Feld C4 gezogen wird.",
"",
"Beispiele:",
" - `(=)` Angebot für ein Draw. Um das Spiel mit einem Draw zu beenden muss das Angebot direkt im nächsten Zug bestätigt werden.",
" - `b4` Der Bauer zieht auf das Feld B4.",
" - `Bc4` Der Läufer zieht auf das Feld C4.",
" - `0-0` Kleine Rochade (Rochade am Königsflügel)",
" - `0-0-0` Große Rochade (Rochade am Damenflügel)",
" - `d8Q` Umwandlung: Der Bauer zieht auf D8 und wandelt sich zur Dame.",
"",
" - (=) Angebot für ein Draw. Um das Spiel mit einem Draw zu beenden muss das Angebot direkt im",
" nächsten Zug bestätigt werden.",
" - b4 Der Bauer zieht auf das Feld B4.",
" - Bc4 Der Läufer zieht auf das Feld C4.",
" - 0-0 Kleine Rochade (Rochade am Königsflügel)",
" - 0-0-0 Große Rochade (Rochade am Damenflügel)",
" - d8Q Umwandlung: Der Bauer zieht auf D8 und wandelt sich zur Dame.",
"",
"2. PGN (Portable Game Notation)",
"TurboSchach unterstützt das Datenformat PGN, welches zur Speicherung von Schachpartien verwendet wird. Auf der Website https://www.chessgames.com/",
"werden viele Schachpartien von offiziellen Turnieren im PGN-Format zur Verfügung gestellt. Diese Dateien können in TurboSchach importiert werden.",
"Über den Menüpunkt 2 direkt nach dem Start der Anwendung ist dieser Import möglich."
"",
"TurboSchach unterstützt das Datenformat PGN, welches zur Speicherung von Schachpartien verwendet",
"wird. Auf der Website https://www.chessgames.com/ werden viele Schachpartien von offiziellen Turnieren",
"im PGN-Format zur Verfügung gestellt. Diese Dateien können in TurboSchach importiert werden."
};
void GenerateElement() override;
@@ -47,6 +54,7 @@ class InstructionsVisualizer : public BaseVisualizer {
InstructionsVisualizer() : BaseVisualizer(BaseVisualizer::FindMaxLength(menuContent), 4) {
InstructionsVisualizer::GenerateElement();
};
void DrawView();
};
#endif //INSTRUCTIONSVISUALIZER_HPP

View File

@@ -1,13 +1,13 @@
#include "PlaySelectVisualizer.hpp"
void PlaySelectVisualizer::GenerateElement() {
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
for (const auto& content : menuContent) {
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
}
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
// BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
// for (const auto& content : menuContent) {
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
// }
// BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
}
std::vector<std::pair<int, int>> PlaySelectVisualizer::GetCursorPositions() {
@@ -17,3 +17,27 @@ std::vector<std::pair<int, int>> PlaySelectVisualizer::GetCursorPositions() {
void PlaySelectVisualizer::AddToCursorPositions(const std::pair<int, int>& position) {
this->cursorPositions.push_back(position);
}
void PlaySelectVisualizer::DrawView() {
BaseVisualizer::ClearTerminal();
this->display_vector.clear();
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
if (this->labelPlayerName.empty()) {
this->labelPlayerName = "player";
}
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Please enter a name for the " + this->labelPlayerName + ":", false, PADDING);
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "\x1B[s", false, PADDING);
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
BaseVisualizer::DisplayElement();
std::cout << "\x1B[u";
}
std::string PlaySelectVisualizer::ShowMenu() {
this->DrawView();
std::string choice;
std::getline(std::cin, choice);
return choice;
}
void PlaySelectVisualizer::SetLabelPlayerName(std::string label) {
this->labelPlayerName = label;
}

View File

@@ -5,6 +5,7 @@
class PlaySelectVisualizer : public BaseVisualizer {
private:
std::string labelPlayerName;
// ToDo: Exit
inline static const std::vector<std::string> menuContent = {
"Please enter your names! Enter your names with '&' seperated.",
@@ -21,6 +22,9 @@ class PlaySelectVisualizer : public BaseVisualizer {
void GenerateElement();
void AddToCursorPositions(const std::pair<int, int>& position);
std::vector<std::pair<int, int>> GetCursorPositions();
void DrawView();
std::string ShowMenu();
void SetLabelPlayerName(std::string label);
};
#endif //PLAYSELECTVISUALIZER_HPP

View File

@@ -113,3 +113,17 @@ std::string PlayingViewVisualizer::GetMessage() {
void PlayingViewVisualizer::SetMessage(std::string message) {
this->message = message;
}
void PlayingViewVisualizer::DrawView() {
BaseVisualizer::ClearTerminal();
this->DisplayElement();
std::cout << "\x1B[u";
}
std::string PlayingViewVisualizer::ShowMenu() {
this->DrawView();
this->SetMessage("");
std::string choice;
std::getline(std::cin, choice);
return choice;
}

View File

@@ -27,6 +27,8 @@ class PlayingViewVisualizer : public BaseVisualizer {
std::string GetMove();
std::string GetMessage();
void SetMessage(std::string message);
void DrawView();
std::string ShowMenu();
};
#endif //PLAYINGVIEWVISUALIZER_HPP

View File

@@ -52,15 +52,20 @@ void StartMenuVisualizer::SetSelectedOption(int optionSelect) {
selectedOption = selectedOption;
};
void StartMenuVisualizer::DisplayElement1() {
void StartMenuVisualizer::DrawView() {
BaseVisualizer::ClearTerminal();
int temp;
for (const auto& row : display_vector) {
for (const auto& cell : row) {
std::cout << cell;
}
std::cout << std::endl;
}
BaseVisualizer::DisplayElement();
std::cout << "\x1B[u";
std::cin >> selectedOption;
}
StartMenuVisualizer::StartMenuOption StartMenuVisualizer::ShowMenu() {
this->DrawView();
std::string choice;
std::getline(std::cin, choice);
if (choice == "1") return StartMenuOption::NewGame;
if (choice == "2") return StartMenuOption::LoadGame;
if (choice == "3") return StartMenuOption::Instructions;
if (choice == "0") return StartMenuOption::Exit;
return StartMenuOption::None;
}

View File

@@ -30,10 +30,17 @@ class StartMenuVisualizer : public BaseVisualizer {
StartMenuVisualizer(size_t padding) : BaseVisualizer(BaseVisualizer::CountVisibleCharacters(StartMenuVisualizer::ACSII_ART_TURBO_SCHACH[0]), padding) {
StartMenuVisualizer::GenerateElement();
}
enum StartMenuOption {
NewGame,
LoadGame,
Instructions,
Exit,
None
};
int GetSelectedOption();
void SetSelectedOption(int selectedOption);
void DisplayElement1();
void DrawView();
StartMenuOption ShowMenu();
};
#endif //STARTMENUVISUALIZER_H

View File

@@ -13,42 +13,26 @@ int main(int argc, char* argv[]) {
SetConsoleOutputCP(CP_UTF8);
#endif
BaseVisualizer::ClearTerminal();
StartMenuVisualizer startMenu(3);
MenuController menuController; // Instanz der Klasse
MenuController menuController;
StartMenuVisualizer::StartMenuOption optionStartMenu = StartMenuVisualizer::StartMenuOption::None;
while (startMenu.GetSelectedOption() != 0) {
BaseVisualizer::ClearTerminal();
startMenu.DisplayElement1();
switch (startMenu.GetSelectedOption()) {
case 1:
do {
switch (optionStartMenu = startMenu.ShowMenu()) {
case StartMenuVisualizer::StartMenuOption::NewGame:
menuController.HandleFirstOption();
break;
case 2:
case StartMenuVisualizer::StartMenuOption::LoadGame:
menuController.HandleSecondOption();
break;
case 3:
case StartMenuVisualizer::StartMenuOption::Instructions:
menuController.HandleThirdOption();
break;
default:
std::cout << "Invalid option. Please try again.\n";
continue;
break;
}
}
} while (optionStartMenu != StartMenuVisualizer::StartMenuOption::Exit);
return 0;
}
/*
Export (Almost)
Historie
Message -> Farbe?
Sebro
Fehlermeldung durch Bewegung PlayViewVisualizer::message
*/