Compare commits
No commits in common. "main" and "fen" have entirely different histories.
16 changed files with 1056 additions and 3801 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -23,7 +23,8 @@
|
|||
*.debug
|
||||
*.yml
|
||||
html/
|
||||
nbproject/*
|
||||
nbproject/private/
|
||||
nbproject/Package-*.bash
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
|
|
@ -38,8 +39,4 @@ chessmcu_default/
|
|||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/mplabx
|
||||
|
||||
localTest/
|
||||
docs/
|
||||
.ca/
|
||||
*.kate-swp
|
||||
*orig
|
||||
localTest/
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "doxygen-awesome-css"]
|
||||
path = doxygen-awesome-css
|
||||
url = https://github.com/jothepro/doxygen-awesome-css.git
|
||||
289
Board.cpp
289
Board.cpp
|
|
@ -6,8 +6,7 @@
|
|||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#include "inc/Board.hpp"
|
||||
#include "inc/Piece.hpp"
|
||||
#include "Board.hpp"
|
||||
#include "inc/strFuncs.hpp"
|
||||
|
||||
/*
|
||||
|
|
@ -32,8 +31,9 @@
|
|||
|
||||
Board::Board() {
|
||||
boardGrid.resize(8);
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(int i = 0; i < 8; i++) {
|
||||
boardGrid[i].resize(8);
|
||||
}
|
||||
}
|
||||
|
||||
Board::~Board() {
|
||||
|
|
@ -41,7 +41,7 @@ Board::~Board() {
|
|||
|
||||
void Board::setupInitialPosition() {
|
||||
// set up the board grid with smart pointers
|
||||
// initialize each square with a Piece or nullptr
|
||||
// initialize each square with a Piece
|
||||
playerTurn = PL_WHITE;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
switch(i) {
|
||||
|
|
@ -89,226 +89,115 @@ void Board::setupInitialPosition() {
|
|||
}
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Sets entire board to nullptr
|
||||
*/
|
||||
void Board::clearBoard() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
for(int j = 0; j < 8; j++)
|
||||
boardGrid[i][j] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a FEN string and creates a board to that spec
|
||||
* @param strFEN A full FEN string
|
||||
* @return Returns -1 on failure, 0 on success
|
||||
*/
|
||||
|
||||
int Board::setupFromFEN(std::string strFEN) {
|
||||
int setupFromFEN(std::string strFEN) {
|
||||
std::vector<std::string> splitFEN = split(strFEN, ' ');
|
||||
if(splitFEN.size() != 6) // a valid FEN *must* contain 6 fields
|
||||
if(splitFEN.size() != 6) { // a valid FEN *must* contain 6 fields
|
||||
return -1;
|
||||
// ====== START OF FIELD 1 ======
|
||||
}
|
||||
std::vector<std::string> splitField1 = split(splitFEN[0], '/');
|
||||
int rank = 0, file = 0;
|
||||
int skip = 0;
|
||||
Square whiteKing, blackKing;
|
||||
bool wKingPlaced = false, bKingPlaced = false;
|
||||
for(auto &ranks : splitField1) {
|
||||
for(auto &sym : ranks) {
|
||||
if(skip) {
|
||||
boardGrid[rank][file] = nullptr; // remove reference
|
||||
skip--;
|
||||
file++;
|
||||
continue;
|
||||
}
|
||||
switch(sym) {
|
||||
case 'R':
|
||||
// white rook
|
||||
boardGrid[rank][file] = std::make_unique<Rook>(PIECE_WHITE);
|
||||
file++;
|
||||
break;
|
||||
case 'r':
|
||||
// black rook
|
||||
boardGrid[rank][file] = std::make_unique<Rook>(PIECE_BLACK);
|
||||
file++;
|
||||
break;
|
||||
case 'N':
|
||||
// white knight
|
||||
boardGrid[rank][file] = std::make_unique<Knight>(PIECE_WHITE);
|
||||
file++;
|
||||
break;
|
||||
case 'n':
|
||||
// black knight
|
||||
boardGrid[rank][file] = std::make_unique<Knight>(PIECE_BLACK);
|
||||
file++;
|
||||
break;
|
||||
case 'B':
|
||||
// white bishop
|
||||
boardGrid[rank][file] = std::make_unique<Bishop>(PIECE_WHITE);
|
||||
file++;
|
||||
break;
|
||||
case 'b':
|
||||
// black bishop
|
||||
boardGrid[rank][file] = std::make_unique<Bishop>(PIECE_BLACK);
|
||||
file++;
|
||||
break;
|
||||
case 'Q':
|
||||
// white queen
|
||||
boardGrid[rank][file] = std::make_unique<Queen>(PIECE_WHITE);
|
||||
file++;
|
||||
break;
|
||||
case 'q':
|
||||
// black queen;
|
||||
boardGrid[rank][file] = std::make_unique<Queen>(PIECE_BLACK);
|
||||
file++;
|
||||
break;
|
||||
case 'K':
|
||||
// white king
|
||||
if(wKingPlaced) {
|
||||
// invalid FEN, more than 1 white king
|
||||
return -1;
|
||||
} else {
|
||||
boardGrid[rank][file] = std::make_unique<King>(PIECE_WHITE);
|
||||
wKingPlaced = true;
|
||||
// store king position for later
|
||||
whiteKing.file = static_cast<File>(file);
|
||||
whiteKing.rank = static_cast<Rank>(rank);
|
||||
file++;
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
// black king
|
||||
if(bKingPlaced) {
|
||||
// invalid FEN, more than 1 black king
|
||||
return -1;
|
||||
} else {
|
||||
boardGrid[rank][file] = std::make_unique<King>(PIECE_BLACK);
|
||||
bKingPlaced = true;
|
||||
// store king position for later
|
||||
blackKing.file = static_cast<File>(file);
|
||||
blackKing.rank = static_cast<Rank>(rank);
|
||||
file++;
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
// white pawn
|
||||
boardGrid[rank][file] = std::make_unique<Pawn>(PIECE_WHITE);
|
||||
file++;
|
||||
break;
|
||||
case 'p':
|
||||
// black pawn
|
||||
boardGrid[rank][file] = std::make_unique<Pawn>(PIECE_BLACK);
|
||||
file++;
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8': {
|
||||
std::string skipStr(1, sym);
|
||||
skip = atoi(skipStr.c_str());
|
||||
//skip--; // fix off by 1 error
|
||||
while(skip--) {
|
||||
boardGrid[rank][file++] = nullptr; // remove reference
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// invalid character?
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
if(file > 7) {
|
||||
file = 0;
|
||||
case 'R':
|
||||
// white rook
|
||||
boardGrid[rank][file] = std::make_unique<Rook>(PIECE_WHITE);
|
||||
break;
|
||||
case 'r':
|
||||
// black rook
|
||||
boardGrid[rank][file] = std::make_unique<Rook>(PIECE_BLACK);
|
||||
break;
|
||||
case 'N':
|
||||
// white knight
|
||||
boardGrid[rank][file] = std::make_unique<Knight>(PIECE_WHITE);
|
||||
break;
|
||||
case 'n':
|
||||
// black knight
|
||||
boardGrid[rank][file] = std::make_unique<Knight>(PIECE_BLACK);
|
||||
break;
|
||||
case 'B':
|
||||
// white bishop
|
||||
boardGrid[rank][file] = std::make_unique<Bishop>(PIECE_WHITE);
|
||||
break;
|
||||
case 'b':
|
||||
// black bishop
|
||||
boardGrid[rank][file] = std::make_unique<Bishop>(PIECE_BLACK);
|
||||
break;
|
||||
case 'Q':
|
||||
// white queen
|
||||
boardGrid[rank][file] = std::make_unique<Queen>(PIECE_WHITE);
|
||||
break;
|
||||
case 'q':
|
||||
// black queen;
|
||||
boardGrid[rank][file] = std::make_unique<Queen>(PIECE_BLACK);
|
||||
break;
|
||||
case 'K':
|
||||
// white king
|
||||
if(wKingPlaced) {
|
||||
// invalid FEN, more than 1 white king
|
||||
return -1;
|
||||
} else {
|
||||
boardGrid[rank][file] = std::make_unique<King>(PIECE_WHITE);
|
||||
wKingPlaced = true;
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
// black king
|
||||
if(bKingPlaced) {
|
||||
// invalid FEN, more than 1 black king
|
||||
return -1;
|
||||
} else {
|
||||
boardGrid[rank][file] = std::make_unique<King>(PIECE_BLACK);
|
||||
bKingPlaced = true;
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
// white pawn
|
||||
boardGrid[rank][file] = std::make_unique<Pawn>(PIECE_WHITE);
|
||||
break;
|
||||
case 'p':
|
||||
// black pawn
|
||||
boardGrid[rank][file] = std::make_unique<Pawn>(PIECE_BLACK);
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
skip = atoi(sym);
|
||||
break;
|
||||
default:
|
||||
// invalid character?
|
||||
return -1;
|
||||
}
|
||||
file++;
|
||||
}
|
||||
rank++;
|
||||
if(rank > 7)
|
||||
break;
|
||||
}
|
||||
// ======= END OF FIELD 1 ======
|
||||
// ======= START OF FIELD 2 ======
|
||||
std::string w = "w";
|
||||
std::string b = "b";
|
||||
if(splitFEN[1] == w)
|
||||
playerTurn = PL_WHITE;
|
||||
else if(splitFEN[1] == b)
|
||||
playerTurn = PL_BLACK;
|
||||
else {
|
||||
// invalid FEN
|
||||
return -1;
|
||||
}
|
||||
// ====== END OF FIELD 2 ======
|
||||
// ====== START OF FIELD 3 ======
|
||||
std::string k = "k", K = "K", q = "q", Q = "Q";
|
||||
// yeah this is hacky af but it works... blame SO
|
||||
Piece *baseBKing = getPieceAt(blackKing);
|
||||
Piece *baseWKing = getPieceAt(whiteKing);
|
||||
King *bKing = dynamic_cast<King *>(baseBKing);
|
||||
King *wKing = dynamic_cast<King *>(baseWKing);
|
||||
if(splitFEN[2] == "-") {
|
||||
// nobody can castle, either side
|
||||
bKing->setCastleKS(false);
|
||||
bKing->setCastleQS(false);
|
||||
wKing->setCastleKS(false);
|
||||
wKing->setCastleQS(false);
|
||||
}
|
||||
if(splitFEN[2].find(k) != std::string::npos) {
|
||||
// black king can castle kingside
|
||||
bKing->setCastleKS(true);
|
||||
}
|
||||
if(splitFEN[2].find(K) != std::string::npos) {
|
||||
// white king can castle kingside
|
||||
wKing->setCastleKS(true);
|
||||
}
|
||||
if(splitFEN[2].find(q) != std::string::npos) {
|
||||
// black king can castle queenside
|
||||
bKing->setCastleQS(true);
|
||||
}
|
||||
if(splitFEN[2].find(Q) != std::string::npos) {
|
||||
// white king can castle queenside
|
||||
wKing->setCastleQS(true);
|
||||
}
|
||||
// ====== END OF FIELD 3 ======
|
||||
// ====== START OF FIELD 4 ======
|
||||
// if a pawn has just moved and can be attacked enPassant, it will be listed here
|
||||
//#ifdef DEBUG
|
||||
// for(auto &ranks : boardGrid) {
|
||||
// for(auto &files : ranks) {
|
||||
// if(files)
|
||||
// std::cout << files->getPieceName() << " ";
|
||||
// else
|
||||
// std::cout << "E ";
|
||||
// }
|
||||
// std::cout << "\n";
|
||||
// }
|
||||
//#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Board::nextTurn() {
|
||||
playerTurn = (playerTurn == PL_WHITE) ? PL_BLACK : PL_WHITE; // switch to other player's turn
|
||||
// do initial checks -- is their king in check? do they have any legal moves?
|
||||
// stalemate check - do we really need to call getLegalMoves() on every single Piece?
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should only be called after you have confirmed the move is legal!
|
||||
* This will execute the move and assume you've already checked it.
|
||||
* @param from The Square on which the Piece is departing
|
||||
* @param to The Square to which the Piece is moving to
|
||||
*/
|
||||
void Board::movePiece(Square from, Square to) {
|
||||
return;
|
||||
}
|
||||
|
||||
void Board::deserializeBoard(uint64_t incomingBoard) {
|
||||
union {
|
||||
uint8_t boardRows[8];
|
||||
uint64_t fullBoard;
|
||||
} serialBoard;
|
||||
uint8_t boardRows[8];
|
||||
for(int i = 0; i < 8; i++)
|
||||
serialBoard.boardRows[i] = static_cast<uint8_t>((incomingBoard >> (8 * i)) & 0xFF);
|
||||
boardRows[i] = (incomingBoard >> (8 * i)) & 0xFF;
|
||||
// how do we then figure out what has moved?
|
||||
return;
|
||||
}
|
||||
47
Board.hpp
Normal file
47
Board.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// © 2025 A.M. Rowsell <amr@frzn.dev>
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#ifndef BOARD_HPP
|
||||
#define BOARD_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include "Piece.hpp"
|
||||
|
||||
// why do I have to forward declare all these?!
|
||||
class Piece;
|
||||
|
||||
enum Players {
|
||||
PL_WHITE, PL_BLACK
|
||||
};
|
||||
struct Square;
|
||||
|
||||
class Board {
|
||||
private:
|
||||
friend class Piece;
|
||||
Players playerTurn;
|
||||
public:
|
||||
// this should be protected, but even when Piece is declared as a friend,
|
||||
// accessing it in Piece.cpp threw an error
|
||||
std::vector<std::vector<std::unique_ptr<Piece>>> boardGrid;
|
||||
Board();
|
||||
virtual ~Board();
|
||||
void setupInitialPosition();
|
||||
Piece *getPieceAt(Square square);
|
||||
void movePiece(Square from, Square to);
|
||||
int setupFromFEN(std::string strFEN);
|
||||
bool isInBounds(Square square) const;
|
||||
bool isEmpty(Square square) const;
|
||||
uint64_t serialBoard = 0xFFFF00000000FFFF; // opening position
|
||||
void deserializeBoard(uint64_t incomingBoard);
|
||||
|
||||
};
|
||||
|
||||
#endif // BOARD_HPP
|
||||
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#include "inc/NeoPixel.hpp"
|
||||
#include "NeoPixel.hpp"
|
||||
|
||||
uint8_t setNeoPixel(uint8_t index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
return 0;
|
||||
|
|
|
|||
228
Piece.cpp
228
Piece.cpp
|
|
@ -6,71 +6,24 @@
|
|||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#include "inc/Piece.hpp"
|
||||
#include "inc/Board.hpp"
|
||||
#include "Piece.hpp"
|
||||
|
||||
Piece::~Piece() {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Add operator overload for << to allow easy printing
|
||||
// TODO: Test getPieceAt() function to see if it works as intended
|
||||
|
||||
// because the Piece class is instantiated in another class using
|
||||
// unique_ptr, non-pure virtual functions apparently *must*
|
||||
// have definitions, or the linker freaks out
|
||||
// so this is just a stub that does nothing. it doesn't matter
|
||||
// because only the derived class versions should be called.
|
||||
|
||||
std::vector<Move> Piece::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Piece::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
return moveList;
|
||||
}
|
||||
|
||||
bool Piece::finalMoveChecks(std::vector<Move> *moveList, Board &board) {
|
||||
// This function needs to do the final checks before declaring a move legal
|
||||
// Check to see if the piece that is being moves is currently blocking check
|
||||
// Check to see if a castle is trying to go through check or out of check
|
||||
// Check if it's a piece trying to capture the King (though this shouldn't happen normally)
|
||||
return true;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
//
|
||||
// ## #
|
||||
// #
|
||||
// # ## ## # ## ## #
|
||||
// # # # # # # #
|
||||
// ## # # # # #
|
||||
// # # # # # # #
|
||||
// ## ## ##### ### ## ###
|
||||
// #
|
||||
// ###
|
||||
// *INDENT-ON*
|
||||
bool King::checkForCheck(Board &board) const {
|
||||
std::vector<std::vector<int>> kingVulnerable = {
|
||||
{-1, 0}, // Up
|
||||
{-1, -1}, // up-left
|
||||
{-1, 1}, // up-right
|
||||
{1, 0}, // Down
|
||||
{1, -1}, // down-left
|
||||
{1, 1}, // down-right
|
||||
{0, -1}, // Left
|
||||
{0, 1}, // Right
|
||||
{-1, -2}, // 1
|
||||
{-1, 2}, // 2
|
||||
{-2, -1}, // 3
|
||||
{-2, 1}, // 4
|
||||
{1, -2}, // 5
|
||||
{1, 2}, // 6
|
||||
{2, -1}, // 7
|
||||
{2, 1} // 8
|
||||
};
|
||||
// locate our King
|
||||
return inCheck;
|
||||
}
|
||||
|
||||
std::vector<Move> King::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> King::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
std::vector<std::vector<int>> directions = {
|
||||
{-1, 0}, // Up
|
||||
|
|
@ -86,10 +39,12 @@ std::vector<Move> King::getLegalMoves(const Square &from, Board &board) const {
|
|||
// establish r/f for square to check
|
||||
int r = from.rank + dir[0];
|
||||
int f = from.file + dir[1];
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
auto ra = static_cast<Rank>(r);
|
||||
auto fi = static_cast<File>(f);
|
||||
Square targetSquare = {ra, fi};
|
||||
if(targetSquare.isValid()) {
|
||||
const Piece *target = board.getPieceAt(targetSquare); // examine the target square
|
||||
if(!target) { // if square is empty (nullptr)
|
||||
const auto &target = board.boardGrid[r][f]; // examine the target square
|
||||
if(!target) { // if square is empty (NULL)
|
||||
moveList.push_back({from, targetSquare}); // then it's potentially a legal move
|
||||
} else if(target && target->getColour() != this->getColour()) { // if it's occupied with a piece of opposite colour
|
||||
moveList.push_back({from, targetSquare}); // then again it's potentially legal
|
||||
|
|
@ -134,8 +89,7 @@ std::vector<Move> King::getLegalMoves(const Square &from, Board &board) const {
|
|||
bool diagonal = (abs(dir[0]) + abs(dir[1]) == 2) ? 1 : 0; // check if diagonal
|
||||
bool knight = (abs(dir[0]) + abs(dir[1]) == 3) ? 1 : 0; // check if knight attack
|
||||
while(r >= 0 && r < 8 && f >= 0 && f < 8) {
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
const Piece *target = board.getPieceAt(targetSquare); // access the square we're examining
|
||||
auto &target = board.boardGrid[r][f]; // access the square we're examining
|
||||
if(!target) {
|
||||
// empty square, continue
|
||||
continue;
|
||||
|
|
@ -143,20 +97,18 @@ std::vector<Move> King::getLegalMoves(const Square &from, Board &board) const {
|
|||
if(target && (target->getColour() != this->getColour())) { // is it occupied & an enemy?
|
||||
if((target->getPieceType() == QUEEN || target->getPieceType() == BISHOP) && diagonal) {
|
||||
// we are being attacked diagonally on this square, so remove it
|
||||
moves.to.rank = INVALID_RANK;
|
||||
moves.to.file = INVALID_FILE;
|
||||
} else if(target->getPieceType() == KNIGHT && knight) {
|
||||
moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE;
|
||||
}
|
||||
else if(target->getPieceType() == KNIGHT && knight) {
|
||||
// we are being attacked by a knight, so remove it
|
||||
moves.to.rank = INVALID_RANK;
|
||||
moves.to.file = INVALID_FILE;
|
||||
} else if(target->getPieceType() == ROOK || target->getPieceType() == QUEEN && (!diagonal && !knight)) {
|
||||
moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE;
|
||||
}
|
||||
else if(target->getPieceType() == ROOK || target->getPieceType() == QUEEN && (!diagonal && !knight)) {
|
||||
// again, being attacked, remove it
|
||||
moves.to.rank = INVALID_RANK;
|
||||
moves.to.file = INVALID_FILE;
|
||||
moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE;
|
||||
}
|
||||
if(target->getPieceType() == PAWN && (abs(r - startSquare.rank) == 1 && abs(f - startSquare.file) == 1)) {
|
||||
moves.to.rank = INVALID_RANK;
|
||||
moves.to.file = INVALID_FILE;
|
||||
moves.to.rank = INVALID_RANK; moves.to.file = INVALID_FILE;
|
||||
}
|
||||
}
|
||||
if(target && (target->getColour() == this->getColour())) {
|
||||
|
|
@ -173,26 +125,15 @@ std::vector<Move> King::getLegalMoves(const Square &from, Board &board) const {
|
|||
}
|
||||
// will this actually work?
|
||||
moveList.erase(
|
||||
std::remove_if(moveList.begin(), moveList.end(),
|
||||
[&](const auto & x) {
|
||||
return !x.to.isValid();
|
||||
}));
|
||||
std::remove_if(moveList.begin(), moveList.end(),
|
||||
[&](const Square &x) {
|
||||
return std::find(x.begin(), x.end(), !x.isValid()) != x.end();
|
||||
}),
|
||||
moveList.end());
|
||||
return moveList;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
//
|
||||
// ##
|
||||
// #
|
||||
// # ### ## ## # ##
|
||||
// # # # # # # #
|
||||
// # # # # # ##
|
||||
// # # # # # # #
|
||||
// #### ## ## ## ##
|
||||
//
|
||||
// *INDENT-OM*
|
||||
|
||||
std::vector<Move> Rook::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Rook::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
const int directions[4][2] = {
|
||||
{-1, 0}, // Up
|
||||
|
|
@ -200,12 +141,14 @@ std::vector<Move> Rook::getLegalMoves(const Square &from, Board &board) const {
|
|||
{0, -1}, // Left
|
||||
{0, 1} // Right
|
||||
};
|
||||
for(auto &dir : directions) {
|
||||
for(auto& dir : directions) {
|
||||
int r = from.rank + dir[0];
|
||||
int f = from.file + dir[1];
|
||||
while(r >= 0 && r < 8 && f >= 0 && f < 8) {
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
const Piece *target = board.getPieceAt(targetSquare);
|
||||
const auto& target = board.boardGrid[r][f];
|
||||
auto ra = static_cast<Rank>(r);
|
||||
auto fi = static_cast<File>(f);
|
||||
Square targetSquare = {ra, fi};
|
||||
if(!target) {
|
||||
moveList.push_back({from, targetSquare});
|
||||
} else if(target && target->getColour() != this->getColour()) {
|
||||
|
|
@ -220,113 +163,22 @@ std::vector<Move> Rook::getLegalMoves(const Square &from, Board &board) const {
|
|||
return moveList;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
// ## # ## ## ## ## # ##
|
||||
// # # # # # # # # # #
|
||||
// # # # # ### ### # #
|
||||
// # # # # # # # #
|
||||
// ### ## # ### ### ### ##
|
||||
// #
|
||||
// ###
|
||||
// *INDENT-ON*
|
||||
|
||||
std::vector<Move> Queen::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Queen::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
std::vector<std::vector<int>> directions = {
|
||||
{-1, 0}, // Up
|
||||
{-1, -1}, // up-left
|
||||
{-1, 1}, // up-right
|
||||
{1, 0}, // Down
|
||||
{1, -1}, // down-left
|
||||
{1, 1}, // down-right
|
||||
{0, -1}, // Left
|
||||
{0, 1} // Right
|
||||
};
|
||||
for(auto &dir : directions) {
|
||||
// establish r/f for square to check
|
||||
int r = from.rank + dir[0];
|
||||
int f = from.file + dir[1];
|
||||
while(r >= 0 && r < 8 && f >= 0 && f < 8) {
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
const Piece *target = board.getPieceAt(targetSquare);// examine the target square
|
||||
if(!target) { // if square is empty (NULL)
|
||||
moveList.push_back({from, targetSquare}); // then it's potentially a legal move
|
||||
} else if(target && target->getColour() != this->getColour()) { // if it's occupied with a piece of opposite colour
|
||||
moveList.push_back({from, targetSquare}); // then again it's potentially legal
|
||||
break;
|
||||
} else {
|
||||
// otherwise it's one of our pieces
|
||||
break;
|
||||
}
|
||||
r += dir[0];
|
||||
f += dir[1];
|
||||
}
|
||||
}
|
||||
return moveList;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
// ## # ## #
|
||||
// # # #
|
||||
// # ## # ## ## ## # ### ####
|
||||
// # # # # # # # # # #
|
||||
// ## # # # # # # # #
|
||||
// # # # # # # # # # # #
|
||||
// ## ## ### ## ##### ### ### ## ##
|
||||
// #
|
||||
// ###
|
||||
// *INDENT-ON*
|
||||
|
||||
std::vector<Move> Knight::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Knight::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
std::vector<std::vector<int>> directions = {
|
||||
{-1, -2},
|
||||
{-1, 2},
|
||||
{-2, -1},
|
||||
{-2, 1},
|
||||
{1, -2},
|
||||
{1, 2},
|
||||
{2, -1},
|
||||
{2, 1}
|
||||
};
|
||||
return moveList;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
// ## # ##
|
||||
// # #
|
||||
// ### ## ### ### ## # ##
|
||||
// # # # # # # # # # #
|
||||
// # # # ## # # # # # #
|
||||
// # # # # # # # # # #
|
||||
// #### ##### ### ### ## ## ###
|
||||
// #
|
||||
// ###
|
||||
// *INDENT-ON*
|
||||
|
||||
std::vector<Move> Bishop::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Bishop::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
std::vector<std::vector<int>> directions = {
|
||||
{-1, -1}, // up-left
|
||||
{-1, 1}, // up-right
|
||||
{1, -1}, // down-left
|
||||
{1, 1}, // down-right
|
||||
};
|
||||
return moveList;
|
||||
}
|
||||
|
||||
// *INDENT-OFF*
|
||||
//
|
||||
// # ## ## # # ## # ##
|
||||
// # # # # # # # #
|
||||
// # # ### # # # # #
|
||||
// # # # # # # # #
|
||||
// ### ## # # # ### ##
|
||||
// #
|
||||
// ###
|
||||
// *INDENT-ON*
|
||||
|
||||
std::vector<Move> Pawn::getLegalMoves(const Square &from, Board &board) const {
|
||||
std::vector<Move> Pawn::getLegalMoves(const Square &from, const Board &board) const {
|
||||
std::vector<Move> moveList;
|
||||
const int directions[2][4][2] = {
|
||||
{
|
||||
|
|
@ -350,11 +202,13 @@ std::vector<Move> Pawn::getLegalMoves(const Square &from, Board &board) const {
|
|||
int r = from.rank + dir[0];
|
||||
int f = from.file + dir[1];
|
||||
if(r >= 0 && r < 8 && f >= 0 && f < 8) { // no need for a while loop as we only have finite moves in limited directions
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
const Piece *target = board.getPieceAt(targetSquare);
|
||||
const auto& target = board.boardGrid[r][f];
|
||||
auto ra = static_cast<Rank>(r);
|
||||
auto fi = static_cast<File>(f);
|
||||
Square targetSquare = {ra, fi};
|
||||
if(dir[0] == -2 && !this->checkIfMoved()) {
|
||||
// then 2 is potentially legal
|
||||
if(!target && board.isSquareEmpty(Square{static_cast<Rank>(r + 1), static_cast<File>(f)})) // check both squares for pieces of any colour
|
||||
if(!target && !(board.boardGrid[r + 1][f])) // check both squares for pieces of any colour
|
||||
moveList.push_back({from, targetSquare});
|
||||
else
|
||||
continue;
|
||||
|
|
@ -377,11 +231,13 @@ std::vector<Move> Pawn::getLegalMoves(const Square &from, Board &board) const {
|
|||
int r = from.rank + dir[0];
|
||||
int f = from.file + dir[1];
|
||||
if(r >= 0 && r < 8 && f >= 0 && f < 8) { // no need for a while loop as we only have finite moves in limited directions
|
||||
Square targetSquare{static_cast<Rank>(r), static_cast<File>(f)};
|
||||
const Piece *target = board.getPieceAt(targetSquare);
|
||||
const auto& target = board.boardGrid[r][f];
|
||||
auto ra = static_cast<Rank>(r);
|
||||
auto fi = static_cast<File>(f);
|
||||
Square targetSquare = {ra, fi};
|
||||
if(dir[0] == 2 && !this->checkIfMoved()) {
|
||||
// then 2 is potentially legal
|
||||
if(!target && board.isSquareEmpty(Square{static_cast<Rank>(r + 1), static_cast<File>(f)}))
|
||||
if(!target && !(board.boardGrid[r - 1][f]))
|
||||
moveList.push_back({from, targetSquare});
|
||||
else
|
||||
continue;
|
||||
|
|
|
|||
172
Piece.hpp
Normal file
172
Piece.hpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
// © 2025 A.M. Rowsell <amr@frzn.dev>
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#ifndef PIECE_HPP
|
||||
#define PIECE_HPP
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "Board.hpp"
|
||||
class Board;
|
||||
|
||||
enum PieceType {
|
||||
PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, EMPTY
|
||||
};
|
||||
|
||||
enum PieceColour {
|
||||
PIECE_WHITE, PIECE_BLACK, PIECE_EMPTY
|
||||
};
|
||||
|
||||
enum Rank {
|
||||
R1 = 0, R2 = 1, R3 = 2, R4 = 3, R5 = 4, R6 = 5, R7 = 6, R8 = 7, INVALID_RANK = 255
|
||||
};
|
||||
|
||||
enum File {
|
||||
A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, INVALID_FILE = 255
|
||||
};
|
||||
|
||||
struct Square {
|
||||
Rank rank;
|
||||
File file;
|
||||
|
||||
bool isValid() const {
|
||||
return rank >= 0 && rank < 8 && file >= 0 && file < 8;
|
||||
}
|
||||
};
|
||||
|
||||
struct Move {
|
||||
Square from;
|
||||
Square to;
|
||||
};
|
||||
|
||||
class Piece {
|
||||
private:
|
||||
friend class Board;
|
||||
protected:
|
||||
PieceColour colour;
|
||||
PieceType pieceType;
|
||||
std::string pieceName;
|
||||
char pieceSymbol;
|
||||
bool hasMoved = false;
|
||||
|
||||
public:
|
||||
|
||||
Piece(PieceColour pColour) : colour(pColour) {
|
||||
}
|
||||
virtual ~Piece();
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const;
|
||||
|
||||
PieceColour getColour() const {
|
||||
return colour;
|
||||
}
|
||||
|
||||
std::string getPieceName() const {
|
||||
return pieceName;
|
||||
}
|
||||
|
||||
char getPieceSymbol() const {
|
||||
return pieceSymbol;
|
||||
}
|
||||
|
||||
PieceType getPieceType() const {
|
||||
return pieceType;
|
||||
}
|
||||
|
||||
bool checkIfMoved() const {
|
||||
return hasMoved;
|
||||
}
|
||||
};
|
||||
|
||||
class King : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
King(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "King";
|
||||
pieceSymbol = 'K';
|
||||
pieceType = KING;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
|
||||
bool checkForCheck() const {
|
||||
return inCheck;
|
||||
}
|
||||
|
||||
bool checkForCastle() const {
|
||||
return canCastle;
|
||||
}
|
||||
protected:
|
||||
bool canCastle = true;
|
||||
bool inCheck = false;
|
||||
};
|
||||
|
||||
class Rook : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Rook(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Rook";
|
||||
pieceSymbol = 'R';
|
||||
pieceType = ROOK;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
};
|
||||
|
||||
class Queen : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Queen(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Queen";
|
||||
pieceSymbol = 'Q';
|
||||
pieceType = QUEEN;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
};
|
||||
|
||||
class Knight : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Knight(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Knight";
|
||||
pieceSymbol = 'N';
|
||||
pieceType = KNIGHT;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
};
|
||||
|
||||
class Bishop : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Bishop(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Bishop";
|
||||
pieceSymbol = 'B';
|
||||
pieceType = BISHOP;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
};
|
||||
|
||||
class Pawn : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Pawn(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Pawn";
|
||||
pieceSymbol = 'P';
|
||||
pieceType = PAWN;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, const Board &board) const override;
|
||||
};
|
||||
#endif // PIECE_HPP
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 60366c3d0423a7181e94a0cfab404f0422eca3c7
|
||||
169
inc/Board.hpp
169
inc/Board.hpp
|
|
@ -1,169 +0,0 @@
|
|||
// © 2025 A.M. Rowsell <amr@frzn.dev>
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
/** @file Board.hpp
|
||||
* @brief The header file for the Board class
|
||||
*
|
||||
* This contains the class definition for the logical representation of the chessboard
|
||||
* itself, as well as a few ancillary enums and forward declarations to make the code
|
||||
* easier to read (hopefully). Unlike the Piece.hpp header, there's no inheritance
|
||||
* or virtual functions so this "half" of the code is a bit simpler to follow.
|
||||
*/
|
||||
#ifndef BOARD_HPP
|
||||
#define BOARD_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Piece.hpp"
|
||||
class Piece;
|
||||
|
||||
/** @enum Players
|
||||
* @brief An enum for the white and black players
|
||||
*/
|
||||
enum Players { PL_WHITE, PL_BLACK };
|
||||
struct Square;
|
||||
|
||||
/** @class Board Board.hpp inc/Board.hpp
|
||||
* @brief This class abstracts the chess board itself
|
||||
*
|
||||
* The heart of the entire code is contained in the member variable boardGrid, which
|
||||
* is a representation of the board. It's a 2D vector of Pieces, which are stored using
|
||||
* smart pointers. When other functions want to view the board, they do so with the included
|
||||
* getPieceAt() getters, which return raw pointers so ownership isn't transferred.
|
||||
*
|
||||
* Outside functions/methods can also change the state of the board with setPieceAt() which
|
||||
* can allow one to move a piece (empty squares being nullptr) or add pieces to the Board when
|
||||
* required.
|
||||
*/
|
||||
class Board {
|
||||
private:
|
||||
std::vector<std::vector<std::unique_ptr<Piece>>> boardGrid; /**< This holds the game state.
|
||||
* It is a 2D vector of Piece types, or nullptr for empty squares
|
||||
* @image html boardGrid.svg "Logical diagram of boardGrid vector" */
|
||||
Players playerTurn;
|
||||
// let's get super object-oriented, baby
|
||||
// these help the getters and setters access the boardGrid
|
||||
// and also make them shorter and less duplicative
|
||||
std::unique_ptr<Piece>& at(int r, int f) {
|
||||
return boardGrid[r][f];
|
||||
}
|
||||
|
||||
const std::unique_ptr<Piece> &at(int r, int f) const {
|
||||
return boardGrid[r][f];
|
||||
}
|
||||
|
||||
std::unique_ptr<Piece> &at(const Square& sq) {
|
||||
return boardGrid[static_cast<int>(sq.rank)][static_cast<int>(sq.file)];
|
||||
}
|
||||
|
||||
const std::unique_ptr<Piece> &at(const Square& sq) const {
|
||||
return boardGrid[static_cast<int>(sq.rank)][static_cast<int>(sq.file)];
|
||||
}
|
||||
public:
|
||||
Board();
|
||||
virtual ~Board();
|
||||
|
||||
// These are to allow Piece to access Board in a controlled way
|
||||
// instead of adding a friend declaration for every subclass
|
||||
// ----- Getters -----
|
||||
Piece* getPieceAt(int r, int f) {
|
||||
return at(r, f).get();
|
||||
}
|
||||
const Piece* getPieceAt(int r, int f) const {
|
||||
return at(r, f).get();
|
||||
}
|
||||
|
||||
Piece* getPieceAt(const Square& sq) {
|
||||
return at(sq).get();
|
||||
}
|
||||
const Piece* getPieceAt(const Square& sq) const {
|
||||
return at(sq).get();
|
||||
}
|
||||
|
||||
// ----- Setters -----
|
||||
void setPieceAt(int r, int f, std::unique_ptr<Piece> piece) {
|
||||
at(r, f) = std::move(piece);
|
||||
}
|
||||
void setPieceAt(const Square& sq, std::unique_ptr<Piece> piece) {
|
||||
at(sq) = std::move(piece);
|
||||
}
|
||||
|
||||
void clearSquare(int r, int f) {
|
||||
at(r, f).reset();
|
||||
}
|
||||
void clearSquare(const Square& sq) {
|
||||
at(sq).reset();
|
||||
}
|
||||
|
||||
// ----- Utility -----
|
||||
bool isSquareEmpty(int r, int f) const {
|
||||
return at(r, f) == nullptr;
|
||||
}
|
||||
bool isSquareEmpty(const Square& sq) const {
|
||||
return at(sq) == nullptr;
|
||||
}
|
||||
|
||||
/** A function to setup the initial board
|
||||
*
|
||||
* This initializes the boardGrid with the black and white pieces
|
||||
* in their normal starting positions. All empty squares are set
|
||||
* to nullptr.
|
||||
*/
|
||||
void setupInitialPosition();
|
||||
/** This function sets the entire board to nullptr
|
||||
*
|
||||
* This should, if I understand correctly, destroy
|
||||
* all the Piece instances that existed because they will no longer
|
||||
* have any owners, and smart pointers should auto destruct.
|
||||
*/
|
||||
void clearBoard();
|
||||
/** This does the actual moving of a piece from one square to another
|
||||
*
|
||||
* Beware! This function does \e not validate if the move is legal. It
|
||||
* will simply do whatever it is told to do. So only call this once you
|
||||
* are positive the move is legal.
|
||||
* Moves to an empty square are simple, just move the Piece to that other
|
||||
* square. Captures have to also take note of the piece type captured
|
||||
* and add it to the total captured by that side. This should also destroy
|
||||
* the smart pointer automatically.
|
||||
* @param from The originating square for the Piece that is moving
|
||||
* @param to And of course, where it will end up
|
||||
*/
|
||||
void movePiece(Square from, Square to);
|
||||
void nextTurn();
|
||||
/** This function takes a standard FEN string and sets up the board.
|
||||
*
|
||||
* FEN is a standard notation that describes only an exact position and
|
||||
* other important things like whose turn it is, whether sides can castle,
|
||||
* but it does \e not include the move history of the game. This makes it
|
||||
* a simpler format for sharing particular interesting positions.
|
||||
*
|
||||
* @param strFEN A std::string that contains a valid FEN position
|
||||
* @return 0 on success, -1 if the FEN string is invalid
|
||||
*/
|
||||
int setupFromFEN(std::string strFEN);
|
||||
bool isInBounds(Square square) const;
|
||||
// serial shift register stuff
|
||||
uint64_t serialBoard = 0xFFFF00000000FFFF; // opening position
|
||||
/** This takes an incoming serial stream and detects if anything has moved.
|
||||
*
|
||||
* The input is one bit per piece, so it can only detect the presence or
|
||||
* absence of pieces on any particular square. This is the crux of our design,
|
||||
* using simpler reed switches for detection instead of RFID or any other two-way
|
||||
* communication with the pieces. This moves a lot of the complexity into software,
|
||||
* though a lot of the complexity is actually quite easy to deal with from a software
|
||||
* point of view.
|
||||
*
|
||||
* @param incomingBoard A 64-bit value, representing 1 bit per piece.
|
||||
*/
|
||||
void deserializeBoard(uint64_t incomingBoard);
|
||||
};
|
||||
|
||||
#endif // BOARD_HPP
|
||||
235
inc/Piece.hpp
235
inc/Piece.hpp
|
|
@ -1,235 +0,0 @@
|
|||
// © 2025 A.M. Rowsell <amr@frzn.dev>
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
#ifndef PIECE_HPP
|
||||
#define PIECE_HPP
|
||||
|
||||
/** @file Piece.hpp
|
||||
* @brief The header files for the Piece class.
|
||||
*
|
||||
* This file contains not only the definition of the Piece class itself, but also all
|
||||
* of the derived classes (King, Queen, Rook, etc.) I was considering having them be in
|
||||
* separate files, but each derived class does not contain that much code, so keeping them
|
||||
* all in one place seemed easier to deal with. This may change in the future!
|
||||
*
|
||||
* Also defined here are important enums that help abstract chess terms, for example the
|
||||
* PieceType, PieceColour, Rank, File, etc. These allow the code to be more readable and
|
||||
* it helps make it obvious what certain bits of code are doing.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class Board;
|
||||
|
||||
enum PieceType {
|
||||
PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, EMPTY
|
||||
};
|
||||
|
||||
enum PieceColour {
|
||||
PIECE_WHITE, PIECE_BLACK, PIECE_EMPTY
|
||||
};
|
||||
|
||||
enum Rank {
|
||||
R1 = 0, R2 = 1, R3 = 2, R4 = 3, R5 = 4, R6 = 5, R7 = 6, R8 = 7, INVALID_RANK = 255
|
||||
};
|
||||
|
||||
enum File {
|
||||
A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, INVALID_FILE = 255
|
||||
};
|
||||
|
||||
enum CastleSide {
|
||||
KINGSIDE = 1, QUEENSIDE = 2
|
||||
};
|
||||
|
||||
/** @struct Square
|
||||
* A struct that represents a square on the chess board.
|
||||
*/
|
||||
struct Square {
|
||||
Rank rank; /**< enum Rank rank represents the rank of the Square */
|
||||
File file; /**< enum File file represents the file of the Square */
|
||||
|
||||
/**
|
||||
* A function to test if the square is a valid square on the chessboard
|
||||
* @return True if the square is within the chessboard, False otherwise
|
||||
*/
|
||||
bool isValid() const {
|
||||
return rank >= 0 && rank < 8 && file >= 0 && file < 8;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* A struct representing the start and end squares of a Move.
|
||||
*/
|
||||
struct Move {
|
||||
Square from;
|
||||
Square to;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Piece Piece.hpp inc/Piece.hpp
|
||||
* @brief A class abstracting chess pieces
|
||||
*
|
||||
* This is a polymorphic base class containing the basic properties all chess pieces have.
|
||||
* It is intended to be extended by a child class for each piece Type, i.e. King, Queen, etc.
|
||||
*/
|
||||
class Piece {
|
||||
private:
|
||||
friend class Board;
|
||||
protected:
|
||||
PieceColour colour;
|
||||
PieceType pieceType;
|
||||
std::string pieceName; /**< std::string pieceName is a string showing the full name of the piece, i.e. "PAWN" */
|
||||
std::string
|
||||
pieceSymbol; /**< std::string pieceSymbol is a single character, using the standard algebraic chess notation, ie N for Knight */
|
||||
bool hasMoved = false;
|
||||
|
||||
public:
|
||||
|
||||
Piece(PieceColour pColour) : colour(pColour) {
|
||||
}
|
||||
virtual ~Piece();
|
||||
|
||||
|
||||
PieceColour getColour() const {
|
||||
return colour;
|
||||
}
|
||||
|
||||
std::string getPieceName() const {
|
||||
return pieceName;
|
||||
}
|
||||
|
||||
std::string getPieceSymbol() const {
|
||||
return pieceSymbol;
|
||||
}
|
||||
|
||||
PieceType getPieceType() const {
|
||||
return pieceType;
|
||||
}
|
||||
|
||||
bool checkIfMoved() const {
|
||||
return hasMoved;
|
||||
}
|
||||
/**
|
||||
* A virtual const function that should get all legal moves for a piece, but it may
|
||||
* include some moves that need to be pruned, like those exposing the king to check.
|
||||
* Still working out how to handle this.
|
||||
*
|
||||
* @param from the Square the Piece is currently on
|
||||
* @param board A reference to the Board we are analyzing
|
||||
* @return std::vector of Move: a list of all potentially legal moves
|
||||
*/
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const;
|
||||
|
||||
bool finalMoveChecks(std::vector<Move> *moveList, Board &board);
|
||||
|
||||
};
|
||||
|
||||
class King : public Piece {
|
||||
private:
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
King(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "King";
|
||||
pieceSymbol = "K";
|
||||
pieceType = KING;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
|
||||
bool checkForCheck(Board &board) const;
|
||||
|
||||
bool checkForCastle(enum CastleSide side) const {
|
||||
if(side == KINGSIDE)
|
||||
return canCastleKS;
|
||||
else if(side == QUEENSIDE)
|
||||
return canCastleQS;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void setCastleQS(bool canCastle) {
|
||||
canCastleQS = canCastle;
|
||||
}
|
||||
void setCastleKS(bool canCastle) {
|
||||
canCastleKS = canCastle;
|
||||
}
|
||||
protected:
|
||||
bool canCastleQS = true;
|
||||
bool canCastleKS = true;
|
||||
bool inCheck = false;
|
||||
};
|
||||
|
||||
class Rook : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Rook(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Rook";
|
||||
pieceSymbol = "R";
|
||||
pieceType = ROOK;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
};
|
||||
|
||||
class Queen : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Queen(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Queen";
|
||||
pieceSymbol = "Q";
|
||||
pieceType = QUEEN;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
};
|
||||
|
||||
class Knight : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Knight(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Knight";
|
||||
pieceSymbol = "N";
|
||||
pieceType = KNIGHT;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
};
|
||||
|
||||
class Bishop : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Bishop(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Bishop";
|
||||
pieceSymbol = "B";
|
||||
pieceType = BISHOP;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
};
|
||||
|
||||
class Pawn : public Piece {
|
||||
friend class Board;
|
||||
public:
|
||||
|
||||
Pawn(PieceColour colour) : Piece(colour) {
|
||||
pieceName = "Pawn";
|
||||
pieceSymbol = "P";
|
||||
pieceType = PAWN;
|
||||
}
|
||||
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const override;
|
||||
void promote(const Square &promotionSquare, Board &board, PieceType promoteTo);
|
||||
protected:
|
||||
bool vulnEnPassant = false;
|
||||
bool firstMove = true;
|
||||
};
|
||||
#endif // PIECE_HPP
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* File: strFuncs.hpp
|
||||
* Author: amr
|
||||
*
|
||||
|
|
|
|||
15
main.cpp
15
main.cpp
|
|
@ -49,9 +49,9 @@
|
|||
#include <sys/attribs.h> // for ISR macros
|
||||
#include <sys/kmem.h>
|
||||
|
||||
#include "inc/Board.hpp"
|
||||
#include "inc/Piece.hpp"
|
||||
#include "inc/NeoPixel.hpp"
|
||||
#include "Board.hpp"
|
||||
#include "Piece.hpp"
|
||||
#include "NeoPixel.hpp"
|
||||
|
||||
#define F_CPU 12000000UL // 12MHz
|
||||
#define F_PER 6000000UL // 6MHz
|
||||
|
|
@ -114,7 +114,7 @@ uint8_t initSystem(void) {
|
|||
SDI1R = 0b0100; // RB8
|
||||
RPA0R = 0b0001; // U1TX
|
||||
SYSKEY = 0x12345678; // lock SYSKEY
|
||||
ANSELBCLR = 0xFFFF; // port B all digital
|
||||
ANSELBCLR = 0xFFFF; // port A all digital
|
||||
SL_TRIS = 0; // RA0 as output
|
||||
SL_LAT = 1; // set high
|
||||
/* Set up SPI1 */
|
||||
|
|
@ -157,8 +157,8 @@ void initInterrupts(void) {
|
|||
INTCONbits.MVEC = 1; // Enable multi-vector interrupts
|
||||
__builtin_enable_interrupts();
|
||||
IPC10bits.DMA0IP = 3; // Priority level 3
|
||||
// IFS1CLR = _IFS1_DMA0IF_MASK; // Clear interrupt flag
|
||||
// IEC1SET = _IEC1_DMA0IE_MASK; // Enable DMA1 interrupt
|
||||
IFS1CLR = _IFS1_DMA0IF_MASK; // Clear interrupt flag
|
||||
IEC1SET = _IEC1_DMA0IE_MASK; // Enable DMA1 interrupt
|
||||
}
|
||||
|
||||
void startSPI_DMA_Transfer(void) {
|
||||
|
|
@ -179,7 +179,6 @@ extern "C" int main(void) {
|
|||
initInterrupts();
|
||||
Board gameBoard;
|
||||
NeoPixel boardLights(64);
|
||||
gameBoard.setupInitialPosition();
|
||||
while(1) {
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +191,7 @@ extern "C" void __ISR(_DMA0_VECTOR, IPL3AUTO) DMA0Handler(void) {
|
|||
DCH0INTCLR = _DCH0INT_CHBCIF_MASK; // Clear block complete flag
|
||||
// DMA RX completed — spi_rx_buffer[] now contains the data
|
||||
}
|
||||
// IFS1CLR = _IFS1_DMA0IF_MASK; // Clear global DMA0 IRQ flag
|
||||
IFS1CLR = _IFS1_DMA0IF_MASK; // Clear global DMA0 IRQ flag
|
||||
}
|
||||
|
||||
//extern "C" void __ISR(_USB1_VECTOR, IPL4AUTO) USBHandler(void) {
|
||||
|
|
|
|||
692
nbproject/configurations.xml
Normal file
692
nbproject/configurations.xml
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configurationDescriptor version="65">
|
||||
<logicalFolder name="root" displayName="root" projectFiles="true">
|
||||
<logicalFolder name="HeaderFiles"
|
||||
displayName="Header Files"
|
||||
projectFiles="true">
|
||||
<itemPath>Board.hpp</itemPath>
|
||||
<itemPath>Piece.hpp</itemPath>
|
||||
<itemPath>NeoPixel.hpp</itemPath>
|
||||
<itemPath>inc/strFuncs.hpp</itemPath>
|
||||
</logicalFolder>
|
||||
<logicalFolder name="ExternalFiles"
|
||||
displayName="Important Files"
|
||||
projectFiles="true">
|
||||
<logicalFolder name="chessmcu_default"
|
||||
displayName="chessmcu_default"
|
||||
projectFiles="true">
|
||||
<logicalFolder name="components" displayName="components" projectFiles="true">
|
||||
<itemPath>chessmcu_default/components/dfp.yml</itemPath>
|
||||
<itemPath>chessmcu_default/components/core.yml</itemPath>
|
||||
</logicalFolder>
|
||||
<itemPath>chessmcu_default/mcc-config.mc4</itemPath>
|
||||
</logicalFolder>
|
||||
<itemPath>Makefile</itemPath>
|
||||
</logicalFolder>
|
||||
<logicalFolder name="LibraryFiles"
|
||||
displayName="LibraryFiles"
|
||||
projectFiles="true">
|
||||
</logicalFolder>
|
||||
<logicalFolder name="LinkerScript"
|
||||
displayName="Linker Files"
|
||||
projectFiles="true">
|
||||
</logicalFolder>
|
||||
<logicalFolder name="SourceFiles"
|
||||
displayName="Source Files"
|
||||
projectFiles="true">
|
||||
<itemPath>main.cpp</itemPath>
|
||||
<itemPath>Board.cpp</itemPath>
|
||||
<itemPath>Piece.cpp</itemPath>
|
||||
<itemPath>NeoPixel.cpp</itemPath>
|
||||
<itemPath>graphics.cpp</itemPath>
|
||||
<itemPath>strFuncs.cpp</itemPath>
|
||||
</logicalFolder>
|
||||
</logicalFolder>
|
||||
<sourceRootList>
|
||||
<Elem>.</Elem>
|
||||
<Elem>inc</Elem>
|
||||
</sourceRootList>
|
||||
<projectmakefile>Makefile</projectmakefile>
|
||||
<confs>
|
||||
<conf name="Debug" type="2">
|
||||
<toolsSet>
|
||||
<developmentServer>localhost</developmentServer>
|
||||
<targetDevice>PIC32MX270F256B</targetDevice>
|
||||
<targetHeader></targetHeader>
|
||||
<targetPluginBoard></targetPluginBoard>
|
||||
<platformTool>noID</platformTool>
|
||||
<languageToolchain>XC32</languageToolchain>
|
||||
<languageToolchainVersion>4.60</languageToolchainVersion>
|
||||
<platform>2</platform>
|
||||
</toolsSet>
|
||||
<packs>
|
||||
<pack name="PIC32MX_DFP" vendor="Microchip" version="1.6.369"/>
|
||||
</packs>
|
||||
<ScriptingSettings>
|
||||
</ScriptingSettings>
|
||||
<compileType>
|
||||
<linkerTool>
|
||||
<linkerLibItems>
|
||||
</linkerLibItems>
|
||||
</linkerTool>
|
||||
<archiverTool>
|
||||
</archiverTool>
|
||||
<loading>
|
||||
<useAlternateLoadableFile>false</useAlternateLoadableFile>
|
||||
<parseOnProdLoad>true</parseOnProdLoad>
|
||||
<alternateLoadableFile></alternateLoadableFile>
|
||||
</loading>
|
||||
<subordinates>
|
||||
</subordinates>
|
||||
</compileType>
|
||||
<makeCustomizationType>
|
||||
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
|
||||
<makeUseCleanTarget>false</makeUseCleanTarget>
|
||||
<makeCustomizationPreStep></makeCustomizationPreStep>
|
||||
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
|
||||
<makeCustomizationPostStep></makeCustomizationPostStep>
|
||||
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
|
||||
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
|
||||
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
|
||||
</makeCustomizationType>
|
||||
<C32>
|
||||
<property key="additional-warnings" value="true"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="cast-align" value="false"/>
|
||||
<property key="code-model" value="default"/>
|
||||
<property key="const-model" value="default"/>
|
||||
<property key="data-model" value="default"/>
|
||||
<property key="disable-instruction-scheduling" value="false"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-procedural-abstraction" value="false"/>
|
||||
<property key="enable-short-double" value="false"/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exclude-floating-point" value="false"/>
|
||||
<property key="expand-pragma-config" value="false"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="false"/>
|
||||
<property key="keep-inline" value="false"/>
|
||||
<property key="make-warnings-into-errors" value="true"/>
|
||||
<property key="oXC16gcc-errata" value=""/>
|
||||
<property key="oXC16gcc-large-aggregate" value="false"/>
|
||||
<property key="oXC16gcc-mpa-lvl" value=""/>
|
||||
<property key="oXC16gcc-name-text-sec" value=""/>
|
||||
<property key="oXC16gcc-near-chars" value="false"/>
|
||||
<property key="oXC16gcc-no-isr-warn" value="false"/>
|
||||
<property key="oXC16gcc-sfr-warn" value="false"/>
|
||||
<property key="oXC16gcc-smar-io-lvl" value="1"/>
|
||||
<property key="oXC16gcc-smart-io-fmt" value=""/>
|
||||
<property key="optimization-level" value="-O0"/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="scalar-model" value="default"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="support-ansi" value="false"/>
|
||||
<property key="tentative-definitions" value="-fno-common"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
</C32>
|
||||
<C32-AR>
|
||||
<property key="additional-options-chop-files" value="false"/>
|
||||
</C32-AR>
|
||||
<C32-AS>
|
||||
<property key="assembler-symbols" value=""/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="exclude-floating-point-library" value="false"/>
|
||||
<property key="expand-macros" value="false"/>
|
||||
<property key="extra-include-directories-for-assembler" value=""/>
|
||||
<property key="extra-include-directories-for-preprocessor" value=""/>
|
||||
<property key="false-conditionals" value="false"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="keep-locals" value="false"/>
|
||||
<property key="list-assembly" value="false"/>
|
||||
<property key="list-section-info" value="true"/>
|
||||
<property key="list-source" value="false"/>
|
||||
<property key="list-symbols" value="false"/>
|
||||
<property key="oXC16asm-extra-opts" value=""/>
|
||||
<property key="oXC32asm-list-to-file" value="false"/>
|
||||
<property key="omit-debug-dirs" value="false"/>
|
||||
<property key="omit-forms" value="false"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="relax" value="false"/>
|
||||
<property key="warning-level" value=""/>
|
||||
</C32-AS>
|
||||
<C32-CO>
|
||||
<property key="coverage-enable" value=""/>
|
||||
<property key="stack-guidance" value="false"/>
|
||||
</C32-CO>
|
||||
<C32-LD>
|
||||
<property key="additional-options-use-response-files" value="false"/>
|
||||
<property key="additional-options-write-sla" value="false"/>
|
||||
<property key="allocate-dinit" value="false"/>
|
||||
<property key="code-dinit" value="false"/>
|
||||
<property key="ebase-addr" value=""/>
|
||||
<property key="enable-check-sections" value="false"/>
|
||||
<property key="enable-data-init" value="true"/>
|
||||
<property key="enable-default-isr" value="true"/>
|
||||
<property key="exclude-floating-point-library" value="false"/>
|
||||
<property key="exclude-standard-libraries" value="false"/>
|
||||
<property key="extra-lib-directories" value=""/>
|
||||
<property key="fill-flash-options-addr" value=""/>
|
||||
<property key="fill-flash-options-const" value=""/>
|
||||
<property key="fill-flash-options-how" value="0"/>
|
||||
<property key="fill-flash-options-inc-const" value="1"/>
|
||||
<property key="fill-flash-options-increment" value=""/>
|
||||
<property key="fill-flash-options-seq" value=""/>
|
||||
<property key="fill-flash-options-what" value="0"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-cross-reference-file" value="true"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="heap-size" value="1000"/>
|
||||
<property key="input-libraries" value=""/>
|
||||
<property key="kseg-length" value=""/>
|
||||
<property key="kseg-origin" value=""/>
|
||||
<property key="linker-symbols" value=""/>
|
||||
<property key="map-file" value="${DISTDIR}/${PROJECTNAME}.${IMAGE_TYPE}.map"/>
|
||||
<property key="no-device-startup-code" value="false"/>
|
||||
<property key="no-ivt" value="false"/>
|
||||
<property key="no-startup-files" value="false"/>
|
||||
<property key="oXC16ld-force-link" value="false"/>
|
||||
<property key="oXC16ld-no-smart-io" value="false"/>
|
||||
<property key="oXC16ld-stackguard" value="16"/>
|
||||
<property key="oXC32ld-extra-opts" value=""/>
|
||||
<property key="optimization-level" value="-O1"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="remove-unused-sections" value="true"/>
|
||||
<property key="report-memory-usage" value="true"/>
|
||||
<property key="serial-length" value=""/>
|
||||
<property key="serial-origin" value=""/>
|
||||
<property key="stack-size" value="100"/>
|
||||
<property key="symbol-stripping" value=""/>
|
||||
<property key="trace-symbols" value=""/>
|
||||
<property key="warn-section-align" value="false"/>
|
||||
</C32-LD>
|
||||
<C32CPP>
|
||||
<property key="additional-warnings" value="false"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="check-new" value="true"/>
|
||||
<property key="eh-specs" value="false"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exceptions" value="false"/>
|
||||
<property key="exclude-floating-point" value="false"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="false"/>
|
||||
<property key="make-warnings-into-errors" value="false"/>
|
||||
<property key="optimization-level" value=""/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="rtti" value="true"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
<appendMe value="-std=c++17"/>
|
||||
</C32CPP>
|
||||
<C32Global>
|
||||
<property key="combine-sourcefiles" value="false"/>
|
||||
<property key="common-include-directories" value=""/>
|
||||
<property key="common-macros" value=""/>
|
||||
<property key="dual-boot-partition" value="0"/>
|
||||
<property key="generic-16-bit" value="false"/>
|
||||
<property key="gp-relative-option" value=""/>
|
||||
<property key="legacy-libc" value="true"/>
|
||||
<property key="mdtcm" value=""/>
|
||||
<property key="mitcm" value=""/>
|
||||
<property key="mpreserve-all" value="false"/>
|
||||
<property key="mstacktcm" value="false"/>
|
||||
<property key="omit-pack-options" value="1"/>
|
||||
<property key="preserve-all" value="false"/>
|
||||
<property key="preserve-file" value=""/>
|
||||
<property key="relaxed-math" value="false"/>
|
||||
<property key="save-temps" value="false"/>
|
||||
<property key="stack-smashing" value=""/>
|
||||
<property key="wpo-lto" value="false"/>
|
||||
</C32Global>
|
||||
</conf>
|
||||
<conf name="Production" type="2">
|
||||
<toolsSet>
|
||||
<developmentServer>localhost</developmentServer>
|
||||
<targetDevice>PIC32MX270F256B</targetDevice>
|
||||
<targetHeader></targetHeader>
|
||||
<targetPluginBoard></targetPluginBoard>
|
||||
<platformTool>noID</platformTool>
|
||||
<languageToolchain>XC32</languageToolchain>
|
||||
<languageToolchainVersion>4.60</languageToolchainVersion>
|
||||
<platform>2</platform>
|
||||
</toolsSet>
|
||||
<packs>
|
||||
<pack name="PIC32MX_DFP" vendor="Microchip" version="1.6.369"/>
|
||||
</packs>
|
||||
<ScriptingSettings>
|
||||
</ScriptingSettings>
|
||||
<compileType>
|
||||
<linkerTool>
|
||||
<linkerLibItems>
|
||||
</linkerLibItems>
|
||||
</linkerTool>
|
||||
<archiverTool>
|
||||
</archiverTool>
|
||||
<loading>
|
||||
<useAlternateLoadableFile>false</useAlternateLoadableFile>
|
||||
<parseOnProdLoad>true</parseOnProdLoad>
|
||||
<alternateLoadableFile></alternateLoadableFile>
|
||||
</loading>
|
||||
<subordinates>
|
||||
</subordinates>
|
||||
</compileType>
|
||||
<makeCustomizationType>
|
||||
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
|
||||
<makeUseCleanTarget>false</makeUseCleanTarget>
|
||||
<makeCustomizationPreStep></makeCustomizationPreStep>
|
||||
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
|
||||
<makeCustomizationPostStep></makeCustomizationPostStep>
|
||||
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
|
||||
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
|
||||
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
|
||||
</makeCustomizationType>
|
||||
<C32>
|
||||
<property key="additional-warnings" value="false"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="cast-align" value="false"/>
|
||||
<property key="code-model" value="default"/>
|
||||
<property key="const-model" value="default"/>
|
||||
<property key="data-model" value="default"/>
|
||||
<property key="disable-instruction-scheduling" value="false"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-procedural-abstraction" value="false"/>
|
||||
<property key="enable-short-double" value="false"/>
|
||||
<property key="enable-symbols" value="false"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exclude-floating-point" value="true"/>
|
||||
<property key="expand-pragma-config" value="false"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="true"/>
|
||||
<property key="keep-inline" value="false"/>
|
||||
<property key="make-warnings-into-errors" value="false"/>
|
||||
<property key="oXC16gcc-errata" value=""/>
|
||||
<property key="oXC16gcc-large-aggregate" value="false"/>
|
||||
<property key="oXC16gcc-mpa-lvl" value=""/>
|
||||
<property key="oXC16gcc-name-text-sec" value=""/>
|
||||
<property key="oXC16gcc-near-chars" value="false"/>
|
||||
<property key="oXC16gcc-no-isr-warn" value="false"/>
|
||||
<property key="oXC16gcc-sfr-warn" value="false"/>
|
||||
<property key="oXC16gcc-smar-io-lvl" value="1"/>
|
||||
<property key="oXC16gcc-smart-io-fmt" value=""/>
|
||||
<property key="optimization-level" value="-O2"/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="scalar-model" value="default"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="support-ansi" value="false"/>
|
||||
<property key="tentative-definitions" value="-fcommon"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
</C32>
|
||||
<C32-AR>
|
||||
<property key="additional-options-chop-files" value="false"/>
|
||||
</C32-AR>
|
||||
<C32-AS>
|
||||
<property key="assembler-symbols" value=""/>
|
||||
<property key="enable-symbols" value="false"/>
|
||||
<property key="exclude-floating-point-library" value="true"/>
|
||||
<property key="expand-macros" value="false"/>
|
||||
<property key="extra-include-directories-for-assembler" value=""/>
|
||||
<property key="extra-include-directories-for-preprocessor" value=""/>
|
||||
<property key="false-conditionals" value="false"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="keep-locals" value="false"/>
|
||||
<property key="list-assembly" value="false"/>
|
||||
<property key="list-section-info" value="false"/>
|
||||
<property key="list-source" value="false"/>
|
||||
<property key="list-symbols" value="false"/>
|
||||
<property key="oXC16asm-extra-opts" value=""/>
|
||||
<property key="oXC32asm-list-to-file" value="false"/>
|
||||
<property key="omit-debug-dirs" value="false"/>
|
||||
<property key="omit-forms" value="false"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="relax" value="false"/>
|
||||
<property key="warning-level" value=""/>
|
||||
</C32-AS>
|
||||
<C32-CO>
|
||||
<property key="coverage-enable" value=""/>
|
||||
<property key="stack-guidance" value="false"/>
|
||||
</C32-CO>
|
||||
<C32-LD>
|
||||
<property key="additional-options-use-response-files" value="false"/>
|
||||
<property key="additional-options-write-sla" value="false"/>
|
||||
<property key="allocate-dinit" value="false"/>
|
||||
<property key="code-dinit" value="false"/>
|
||||
<property key="ebase-addr" value=""/>
|
||||
<property key="enable-check-sections" value="false"/>
|
||||
<property key="enable-data-init" value="true"/>
|
||||
<property key="enable-default-isr" value="true"/>
|
||||
<property key="exclude-floating-point-library" value="false"/>
|
||||
<property key="exclude-standard-libraries" value="false"/>
|
||||
<property key="extra-lib-directories" value=""/>
|
||||
<property key="fill-flash-options-addr" value=""/>
|
||||
<property key="fill-flash-options-const" value=""/>
|
||||
<property key="fill-flash-options-how" value="0"/>
|
||||
<property key="fill-flash-options-inc-const" value="1"/>
|
||||
<property key="fill-flash-options-increment" value=""/>
|
||||
<property key="fill-flash-options-seq" value=""/>
|
||||
<property key="fill-flash-options-what" value="0"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-cross-reference-file" value="true"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="heap-size" value="1000"/>
|
||||
<property key="input-libraries" value=""/>
|
||||
<property key="kseg-length" value=""/>
|
||||
<property key="kseg-origin" value=""/>
|
||||
<property key="linker-symbols" value=""/>
|
||||
<property key="map-file" value="${DISTDIR}/${PROJECTNAME}.${IMAGE_TYPE}.map"/>
|
||||
<property key="no-device-startup-code" value="false"/>
|
||||
<property key="no-ivt" value="false"/>
|
||||
<property key="no-startup-files" value="false"/>
|
||||
<property key="oXC16ld-force-link" value="false"/>
|
||||
<property key="oXC16ld-no-smart-io" value="false"/>
|
||||
<property key="oXC16ld-stackguard" value="16"/>
|
||||
<property key="oXC32ld-extra-opts" value=""/>
|
||||
<property key="optimization-level" value="-O1"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="remove-unused-sections" value="true"/>
|
||||
<property key="report-memory-usage" value="true"/>
|
||||
<property key="serial-length" value=""/>
|
||||
<property key="serial-origin" value=""/>
|
||||
<property key="stack-size" value="100"/>
|
||||
<property key="symbol-stripping" value=""/>
|
||||
<property key="trace-symbols" value=""/>
|
||||
<property key="warn-section-align" value="false"/>
|
||||
</C32-LD>
|
||||
<C32CPP>
|
||||
<property key="additional-warnings" value="false"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="check-new" value="false"/>
|
||||
<property key="eh-specs" value="true"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-symbols" value="false"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exceptions" value="true"/>
|
||||
<property key="exclude-floating-point" value="true"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="true"/>
|
||||
<property key="make-warnings-into-errors" value="false"/>
|
||||
<property key="optimization-level" value="-O2"/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="rtti" value="true"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
</C32CPP>
|
||||
<C32Global>
|
||||
<property key="combine-sourcefiles" value="false"/>
|
||||
<property key="common-include-directories" value=""/>
|
||||
<property key="common-macros" value=""/>
|
||||
<property key="dual-boot-partition" value="0"/>
|
||||
<property key="generic-16-bit" value="false"/>
|
||||
<property key="gp-relative-option" value=""/>
|
||||
<property key="legacy-libc" value="true"/>
|
||||
<property key="mdtcm" value=""/>
|
||||
<property key="mitcm" value=""/>
|
||||
<property key="mpreserve-all" value="false"/>
|
||||
<property key="mstacktcm" value="false"/>
|
||||
<property key="omit-pack-options" value="1"/>
|
||||
<property key="preserve-all" value="false"/>
|
||||
<property key="preserve-file" value=""/>
|
||||
<property key="relaxed-math" value="false"/>
|
||||
<property key="save-temps" value="false"/>
|
||||
<property key="stack-smashing" value=""/>
|
||||
<property key="wpo-lto" value="false"/>
|
||||
</C32Global>
|
||||
</conf>
|
||||
<conf name="PIC32MM" type="2">
|
||||
<toolsSet>
|
||||
<developmentServer>localhost</developmentServer>
|
||||
<targetDevice>PIC32MM0256GPM028</targetDevice>
|
||||
<targetHeader></targetHeader>
|
||||
<targetPluginBoard></targetPluginBoard>
|
||||
<platformTool>noID</platformTool>
|
||||
<languageToolchain>XC32</languageToolchain>
|
||||
<languageToolchainVersion>4.60</languageToolchainVersion>
|
||||
<platform>2</platform>
|
||||
</toolsSet>
|
||||
<packs>
|
||||
<pack name="PIC32MM-GPM-0XX_DFP" vendor="Microchip" version="1.4.156"/>
|
||||
</packs>
|
||||
<ScriptingSettings>
|
||||
</ScriptingSettings>
|
||||
<compileType>
|
||||
<linkerTool>
|
||||
<linkerLibItems>
|
||||
</linkerLibItems>
|
||||
</linkerTool>
|
||||
<archiverTool>
|
||||
</archiverTool>
|
||||
<loading>
|
||||
<useAlternateLoadableFile>false</useAlternateLoadableFile>
|
||||
<parseOnProdLoad>true</parseOnProdLoad>
|
||||
<alternateLoadableFile></alternateLoadableFile>
|
||||
</loading>
|
||||
<subordinates>
|
||||
</subordinates>
|
||||
</compileType>
|
||||
<makeCustomizationType>
|
||||
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
|
||||
<makeUseCleanTarget>false</makeUseCleanTarget>
|
||||
<makeCustomizationPreStep></makeCustomizationPreStep>
|
||||
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
|
||||
<makeCustomizationPostStep></makeCustomizationPostStep>
|
||||
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
|
||||
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
|
||||
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
|
||||
</makeCustomizationType>
|
||||
<C32>
|
||||
<property key="additional-warnings" value="false"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="cast-align" value="false"/>
|
||||
<property key="code-model" value="default"/>
|
||||
<property key="const-model" value="default"/>
|
||||
<property key="data-model" value="default"/>
|
||||
<property key="disable-instruction-scheduling" value="false"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-procedural-abstraction" value="false"/>
|
||||
<property key="enable-short-double" value="false"/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exclude-floating-point" value="true"/>
|
||||
<property key="expand-pragma-config" value="false"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="false"/>
|
||||
<property key="keep-inline" value="false"/>
|
||||
<property key="make-warnings-into-errors" value="false"/>
|
||||
<property key="oXC16gcc-errata" value=""/>
|
||||
<property key="oXC16gcc-large-aggregate" value="false"/>
|
||||
<property key="oXC16gcc-mpa-lvl" value=""/>
|
||||
<property key="oXC16gcc-name-text-sec" value=""/>
|
||||
<property key="oXC16gcc-near-chars" value="false"/>
|
||||
<property key="oXC16gcc-no-isr-warn" value="false"/>
|
||||
<property key="oXC16gcc-sfr-warn" value="false"/>
|
||||
<property key="oXC16gcc-smar-io-lvl" value="1"/>
|
||||
<property key="oXC16gcc-smart-io-fmt" value=""/>
|
||||
<property key="optimization-level" value="-O0"/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="scalar-model" value="default"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="support-ansi" value="false"/>
|
||||
<property key="tentative-definitions" value="-fno-common"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
</C32>
|
||||
<C32-AR>
|
||||
<property key="additional-options-chop-files" value="false"/>
|
||||
</C32-AR>
|
||||
<C32-AS>
|
||||
<property key="assembler-symbols" value=""/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="exclude-floating-point-library" value="true"/>
|
||||
<property key="expand-macros" value="false"/>
|
||||
<property key="extra-include-directories-for-assembler" value=""/>
|
||||
<property key="extra-include-directories-for-preprocessor" value=""/>
|
||||
<property key="false-conditionals" value="false"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="keep-locals" value="false"/>
|
||||
<property key="list-assembly" value="false"/>
|
||||
<property key="list-section-info" value="false"/>
|
||||
<property key="list-source" value="false"/>
|
||||
<property key="list-symbols" value="false"/>
|
||||
<property key="oXC16asm-extra-opts" value=""/>
|
||||
<property key="oXC32asm-list-to-file" value="false"/>
|
||||
<property key="omit-debug-dirs" value="false"/>
|
||||
<property key="omit-forms" value="false"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="relax" value="false"/>
|
||||
<property key="warning-level" value=""/>
|
||||
</C32-AS>
|
||||
<C32-CO>
|
||||
<property key="coverage-enable" value=""/>
|
||||
<property key="stack-guidance" value="false"/>
|
||||
</C32-CO>
|
||||
<C32-LD>
|
||||
<property key="additional-options-use-response-files" value="false"/>
|
||||
<property key="additional-options-write-sla" value="false"/>
|
||||
<property key="allocate-dinit" value="false"/>
|
||||
<property key="code-dinit" value="false"/>
|
||||
<property key="ebase-addr" value=""/>
|
||||
<property key="enable-check-sections" value="false"/>
|
||||
<property key="enable-data-init" value="true"/>
|
||||
<property key="enable-default-isr" value="true"/>
|
||||
<property key="exclude-floating-point-library" value="false"/>
|
||||
<property key="exclude-standard-libraries" value="false"/>
|
||||
<property key="extra-lib-directories" value=""/>
|
||||
<property key="fill-flash-options-addr" value=""/>
|
||||
<property key="fill-flash-options-const" value=""/>
|
||||
<property key="fill-flash-options-how" value="0"/>
|
||||
<property key="fill-flash-options-inc-const" value="1"/>
|
||||
<property key="fill-flash-options-increment" value=""/>
|
||||
<property key="fill-flash-options-seq" value=""/>
|
||||
<property key="fill-flash-options-what" value="0"/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-cross-reference-file" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="heap-size" value="768"/>
|
||||
<property key="input-libraries" value=""/>
|
||||
<property key="kseg-length" value=""/>
|
||||
<property key="kseg-origin" value=""/>
|
||||
<property key="linker-symbols" value=""/>
|
||||
<property key="map-file" value="${DISTDIR}/${PROJECTNAME}.${IMAGE_TYPE}.map"/>
|
||||
<property key="no-device-startup-code" value="false"/>
|
||||
<property key="no-ivt" value="false"/>
|
||||
<property key="no-startup-files" value="false"/>
|
||||
<property key="oXC16ld-force-link" value="false"/>
|
||||
<property key="oXC16ld-no-smart-io" value="false"/>
|
||||
<property key="oXC16ld-stackguard" value="16"/>
|
||||
<property key="oXC32ld-extra-opts" value=""/>
|
||||
<property key="optimization-level" value="-O1"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="remove-unused-sections" value="true"/>
|
||||
<property key="report-memory-usage" value="true"/>
|
||||
<property key="serial-length" value=""/>
|
||||
<property key="serial-origin" value=""/>
|
||||
<property key="stack-size" value="100"/>
|
||||
<property key="symbol-stripping" value=""/>
|
||||
<property key="trace-symbols" value=""/>
|
||||
<property key="warn-section-align" value="false"/>
|
||||
</C32-LD>
|
||||
<C32CPP>
|
||||
<property key="additional-warnings" value="false"/>
|
||||
<property key="addresss-attribute-use" value="false"/>
|
||||
<property key="check-new" value="false"/>
|
||||
<property key="eh-specs" value="true"/>
|
||||
<property key="enable-app-io" value="false"/>
|
||||
<property key="enable-omit-frame-pointer" value="false"/>
|
||||
<property key="enable-symbols" value="true"/>
|
||||
<property key="enable-unroll-loops" value="false"/>
|
||||
<property key="exceptions" value="true"/>
|
||||
<property key="exclude-floating-point" value="true"/>
|
||||
<property key="extra-include-directories" value=""/>
|
||||
<property key="generate-16-bit-code" value="false"/>
|
||||
<property key="generate-micro-compressed-code" value="false"/>
|
||||
<property key="isolate-each-function" value="false"/>
|
||||
<property key="make-warnings-into-errors" value="false"/>
|
||||
<property key="optimization-level" value=""/>
|
||||
<property key="place-data-into-section" value="true"/>
|
||||
<property key="post-instruction-scheduling" value="default"/>
|
||||
<property key="pre-instruction-scheduling" value="default"/>
|
||||
<property key="preprocessor-macros" value=""/>
|
||||
<property key="rtti" value="true"/>
|
||||
<property key="strict-ansi" value="false"/>
|
||||
<property key="toplevel-reordering" value=""/>
|
||||
<property key="unaligned-access" value=""/>
|
||||
<property key="use-cci" value="false"/>
|
||||
<property key="use-iar" value="false"/>
|
||||
<property key="use-indirect-calls" value="false"/>
|
||||
</C32CPP>
|
||||
<C32Global>
|
||||
<property key="combine-sourcefiles" value="false"/>
|
||||
<property key="common-include-directories" value=""/>
|
||||
<property key="common-macros" value=""/>
|
||||
<property key="dual-boot-partition" value="0"/>
|
||||
<property key="generic-16-bit" value="false"/>
|
||||
<property key="gp-relative-option" value=""/>
|
||||
<property key="legacy-libc" value="true"/>
|
||||
<property key="mdtcm" value=""/>
|
||||
<property key="mitcm" value=""/>
|
||||
<property key="mpreserve-all" value="false"/>
|
||||
<property key="mstacktcm" value="false"/>
|
||||
<property key="omit-pack-options" value="1"/>
|
||||
<property key="preserve-all" value="false"/>
|
||||
<property key="preserve-file" value=""/>
|
||||
<property key="relaxed-math" value="false"/>
|
||||
<property key="save-temps" value="false"/>
|
||||
<property key="stack-smashing" value=""/>
|
||||
<property key="wpo-lto" value="false"/>
|
||||
</C32Global>
|
||||
</conf>
|
||||
</confs>
|
||||
</configurationDescriptor>
|
||||
|
|
@ -4,8 +4,9 @@ template <typename Out>
|
|||
void split(const std::string &s, char delim, Out result) {
|
||||
std::istringstream iss(s);
|
||||
std::string item;
|
||||
while(std::getline(iss, item, delim))
|
||||
while (std::getline(iss, item, delim)) {
|
||||
*result++ = item;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string &s, char delim) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue