To castle, or not to castle, that is the question, picoEngine….

will_castle

As you can see from the above screenshot, one of the engines possible moves is e8g8, which is for the black king to castle on the king’s side. This is great news. Previously, I had given the engine the ability to accept the input for castling, but it could not choose to do so on it’s own. But not anymore! Now it can decide to castle if it thinks that is the best thing to do!

Of course, you can read through the entire commit on my GitLab, but here is the focal point:

if (theBoard[60] == ‘k’) {
cout << “The king is on square 60” << endl;
if (theBoard[59] == ‘-‘ && theBoard[58] == ‘-‘ &&
theBoard[57] == ‘-‘ && theBoard[56] == ‘r’ && m_qcastle == true) {
cout << “Path is clear to castle queenside.” << endl;
if (isKingSafe(theBoard, turn)) {
//The king is not in check, so…
theBoard[59] = ‘k’;
theBoard[60] = ‘-‘;
if (isKingSafe(theBoard, turn)) {
//The king is safe in between, so…
theseMoves.push_back(58);
//Then the move will get checked if king is safe at destination.
}
theBoard[60] = ‘k’;
theBoard[59] = ‘-‘;}
} //queenside

This portion covers the black king’s queen’s side castle options. It is more or less a convoluted set of if/then statements. If the king is on the normal king starting square, and the “hallway” is empty between it and the rook, and the rook and king have never moved (m_qcastle == true) THEN check if the king is in check, and if he will be safe every step of the way. If he is safe, then suggest that as a move to consider.

While it is not the cleanest code, and will cause problems for “non-classical” variants of chess, such as chess960, this gets the job done for traditional chess use.

Linux – keep it simple.

Advertisements

Castle, picoEngine?

castleinput

After about an hour of accomplishing nothing, I finally gave up on what I was doing and fixed the UCI input for “movpos” when castling. So now, if given the move for castling, it moves the rook as well as the king!

You can check out the whole commit on my GitLab, but here is the only important part:

if (m_theBoard[first] == ‘k’ || m_theBoard[first] == ‘K’){
cout << “King Move” << endl;
if (first == 4 && second == 6) {
// White Castles King Side
m_theBoard[7] = ‘-‘;
m_theBoard[5] = ‘R’;cout << “castleWKS” << endl;
} else if (first == 4 && second == 2) {
// White Castles Queen Side
m_theBoard[0] = ‘-‘;
m_theBoard[3] = ‘R’;cout << “castleWQS” << endl;
} else if (first == 60 && second == 62) {
// Black Castles King Side
m_theBoard[63] = ‘-‘;
m_theBoard[61] = ‘r’;cout << “castleBKS” << endl;
} else if (first == 60 && second == 58) {
// Black Castles Queen Side
m_theBoard[56] = ‘-‘;
m_theBoard[59] = ‘r’;cout << “castleBQS” << endl;
}
} // Not a king move…..

As you can see, I just have the engine check if the input move was a king (k for black king, K for white king, which is standard computer notation). If it was a king that moved, it checks to see if it is one of the four possible castle moves, and then, if it is, the engine moves the rook as well. Nothing fancy, but it gets the job done!

Linux – keep it simple.

Promotion time picoEngine!

picoEnginePawns

It’s really important to note that if a pawn gets promoted, it becomes the new piece, whatever that piece is. Either a knight, bishop, rook, or queen. While this was happening in the interface, it was not being recognized by picoEngine. Since picoEngine didn’t know it was promoted, it would “assume” a pawn was sitting there. This caused a lot of trouble with king safety calculations, as I’m sure you could understand.

if (sepVect[k].size() == 5) {
char newPiece = ‘-‘;
if (!m_whitesTurn) {
newPiece = tolower(sepVect[k].at(4);
} else {
newPiece = toupper(sepVect[k].at(4));
}
m_theBoard[second] = newPiece;
}

Fortunately the fix was pretty simple. I initiated a check, if there were 5 digits, then the fifth digit is the promotion piece! All I had to do was consider if it should be upper or lower case for my board, which was simply solved by inputting whose turn it was.

Linux – keep it simple.

picoEngine?! Where is the king?!

picoengineKingStuck

What good is king safety if the king refuses to capture it’s attacker? I guess I had programmed a cowardly lion… er… uh… king. Actually the real problem was that of where the king “was” on the board, per my code.

  // For checking if the king is safe.

int z;

if (whoseTurn){

for (int i = 0; i < 64; i++) {

switch (boardPositions[i]) {

–  case ‘K’: z = boardPositions[i];break;

+  case ‘K’: z = i;break;

}

}

So rather than the king being where he was supposed to be, the engine believed the king to be off the board at square “75” (it is the integer equivalent of the character ‘k’). So, above, you can see the minus of “case ‘K’: z = boardPositions[i];break;” and the plus replacing it with “case ‘K’: z = i;break;”. We needed it’s integer position on the board, not the integer equivalent of the character ‘k’…. Sometimes I marvel at my own foolishness.

Linux – keep it simple.

Pawns, one step at a time, picoEngine….

picoEnginePawns

Okay, it’s time to work on moves for the last piece: the pawn. Believe it or not, the pawn is the most difficult piece for me to program. It has so many small idiosyncrasies. If you are on the home row, you can go two spaces, but not any other time. If you were just passed by a pawn from it’s home row doing a two step, you can en passant. Oh, and you attack diagonally, but only move directly forward. I think you get the idea.

Just the basic one step, two step, and attack diagonally moves took 50 lines of code for me to write! You can check out the full commit on my GitLab, but here is the important part:

string Moves::pawnMoves(string boardPositions, int i) {
string list = “”;
vector <int> theseMoves;
string moveSquare;
string theBoard = boardPositions;
bool turn = true;
int rowNum = i/8;
int colNum = i%8;
int k = i + 16;
cout << rowNum << endl;
if (rowNum == 1) {
// The standard catch for moving two spaces forward.
if (theBoard[i+8] == ‘-‘ && theBoard[i+16] == ‘-‘) {
theseMoves.push_back(k);
}
}

// The standard catch for moving one space forward.
k = i + 8;
if (theBoard[k] == ‘-‘) {
theseMoves.push_back(k);
}
k = i + 7;// Attacking to the left and up.
if (colNum > 0 && islower(theBoard[k])) {
theseMoves.push_back(k);
}
k = i + 9;// Attacking to the right and up.
if (colNum < 7 && islower(theBoard[k])) {
theseMoves.push_back(k);
}
// End boring pawn moves.

// Need en passant moves //

for(int l=0; (unsigned)l<theseMoves.size();l++) {
int k = theseMoves[l];
if (islower(theBoard[k]) || theBoard[k] == ‘-‘) {
moveSquare = theBoard[k];
theBoard[k] = ‘P’;
theBoard[i] = ‘-‘;
if (isKingSafe(theBoard, turn)) {
char F = (char)(‘a’ + colNum);
char G = (char)(‘1’ + rowNum);
int rowNumK = k/8;
int colNumK = k%8;
char T = (char)(‘a’ + colNumK);
char U = (char)(‘1’ + rowNumK);
list = list + F + G + T + U + “,”;
}
theBoard[k] = moveSquare[0];
theBoard[i] = ‘P’;
}
}
return list;
} // End white pawn moves.

Now I just have to work on en passant, and work on the king’s castle moves. Almost done with moves so I can actually focus on building the “thinking” part of the engine!

Linux – keep it simple.

This is not checkers, picoEngine….

picoEngineKing

Then why does he say “king me?!” Today I worked on the king moves for picoEngine. Note that I did not include castling moves yet. Without the castle moves, the king is actually one of the easiest pieces to program, as you can see:

string Moves::kingMoves(string boardPositions, int i) {
string list = “”;
vector <int> theseMoves;
string moveSquare;
string theBoard = boardPositions;
bool turn = true;
int rowNum = i/8;
int colNum = i%8;
if (rowNum > 0) {
if (theBoard[i-8] == ‘-‘ || islower(theBoard[i-8])) {
theseMoves.push_back(i-8);}
if (colNum > 0) {
if (theBoard[i-9] == ‘-‘ || islower(theBoard[i-9])) {
theseMoves.push_back(i-9);}}
if (colNum < 7) {
if (theBoard[i-7] == ‘-‘ || islower(theBoard[i-7])) {
theseMoves.push_back(i-7);}}}
if (rowNum < 7) {
if (theBoard[i+8] == ‘-‘ || islower(theBoard[i+8])) {
theseMoves.push_back(i+8);}
if (colNum < 7) {
if (theBoard[i+9] == ‘-‘ || islower(theBoard[i+9])) {
theseMoves.push_back(i+9);}}
if (colNum > 0) {
if (theBoard[i+7] == ‘-‘ || islower(theBoard[i+7])) {
theseMoves.push_back(i+7);}}}
if (colNum < 7) {
if (theBoard[i+1] == ‘-‘ || islower(theBoard[i+1])) {
theseMoves.push_back(i+1);}}
if (colNum > 0) {
if (theBoard[i-1] == ‘-‘ || islower(theBoard[i-1])) {
theseMoves.push_back(i-1);}}

// Need castle moves //

for(int l=0; (unsigned)l<theseMoves.size();l++) {
int k = theseMoves[l];
if (islower(theBoard[k]) || theBoard[k] == ‘-‘) {
moveSquare = theBoard[k];
theBoard[k] = ‘K’;
theBoard[i] = ‘-‘;
if (isKingSafe(theBoard, turn)) {
char F = (char)(‘a’ + colNum);
char G = (char)(‘1’ + rowNum);
int rowNumK = k/8;
int colNumK = k%8;
char T = (char)(‘a’ + colNumK);
char U = (char)(‘1’ + rowNumK);
list = list + F + G + T + U + “,”;
}
theBoard[k] = moveSquare[0];
theBoard[i] = ‘K’;
}
}
return list;
} // End white king moves.

The key part being checking each direction to see if the space is open or occupied by the opposing team. This generates a list that is then checked to see if each move is “safe” or not. Which reminds me, I still need to finish fixing the king safety check…..

Either way, you can check out the full commit on my GitLab.

Linux – keep it simple.

Queen, picoEngine?

picoEngineQueen

In my most recent commit, which you can check out in full at my GitLab, I added the ability for the queen to move to the picoEngine. This completes all of the major/minor pieces of motion, and only leaves the king and pawns to complete (believe it or not, these are the hardest to do, as they have many conditional clauses).

I actually was able to hammer this out in about 15 minutes, since it really is just a combination of the rook and bishop moves with a “q” instead of the respective letters. Since it is identical to those, I wont post much of the code here. If you are wondering, however, how I add them to the header files, it looks like this in Moves.h:

#pragma once
#include <cmath>
#include <string>
using namespace std;

class Moves {

private:
char m_theBoard[64] = {‘R’,’N’,’B’,’Q’,’K’,’B’,’N’,’R’,’P’,’P’,’P’,’P’,’P’,
‘P’,’P’,’P’,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,
‘-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,’-‘,
‘-‘,’p’,’p’,’p’,’p’,’p’,’p’,’p’,’p’,’r’,’n’,’b’,’q’,’k’,’b’,’n’,’r’};

bool m_whitesTurn = true;
bool m_Kcastle = true;
bool m_Qcastle = true;
bool m_kcastle = true;
bool m_qcastle = true;
bool m_enPassant = false;
string m_enPasPawn = “”;
int m_moveSince = 0;
int m_turnCount = 0;
// Public prototypes go here
public:

// All available moves.
string available(string boardPositions, bool whoseTurn);

// Best move.
string bestMove(string boardPositions, bool whoseTurn, bool styleRandom);

// Is the king safe?
bool isKingSafe(string boardPositions, bool whoseTurn);

// Black night moves:
string nightMovesB(string boardPositions, int i);
// white night moves:
string nightMoves(string boardPositions, int i);
// Black rook moves:
string rookMovesB(string boardPositions, int i);
// white rook moves:
string rookMoves(string boardPositions, int i);
// Black bishop moves:
string bishopMovesB(string boardPositions, int i);
// white bishop moves:
string bishopMoves(string boardPositions, int i);
// Black queen moves:
string queenMovesB(string boardPositions, int i);
// white queen moves:
string queenMoves(string boardPositions, int i);

};

After adding the command option to the header file, then I can actually create it in the Moves.cpp file:

string Moves::queenMoves(string boardPositions, int i) {
————– Abridged, see commit for details. ——————-
} // End white queen moves.

Object oriented programming (oop) is a really fun way to program. The top 2 programming languages used for video games today are Java and C++, which are both oop types of programming. Since Android devices now make up more percentage of the worlds operating system than any other operating system, and most Android games are written in oop like Java and C++, that makes sense. But even most desktop games are made with these languages as well.

Linux – keep it simple.

Bishops aren’t Bums…

picoengineBishop

Believe it or not, the bishops can now move! 3 of the 6 piece types now have the complete freedom of movement that they should have on the regular board! Things seem to be making steady progress, although I still see some issues with kingSafety, so I’ll have to work on that!

There is also an issue with odd positions. If you start a new game as normal. All is well for picoEngine, and it can track moves as usual. However, if you use the interface to adjust the piece positions, picoEngine will only track the first move, subsequent moves cause an illegal exception. So that needs to be looked into. Also, picoEngine does not like Chess960!

As always, the full commit is available on GitHub, if you’d like to see how the bishops get their move on. It is very similar to the rook motion, but diagonally placed.

Linux – keep it simple.

Uh, picoEngine? I thought you said the king was safe?

kingsafe

Except he’s not. That’s right. I big technical oversight on my part allowed the king to not be safe at all!

while (boardPositions[k] == ‘*’ && notI) {

Needed to be changed to:

while (boardPositions[k] == ‘-‘ && notI) {

That’s right! A – is what my board uses for empty spaces. But the Java board I wrote for JustChessEngine used an * instead. I guess I got confused when looking at the code and put it in the wrong way! Too much copy and paste from my Java work I suppose. Either way, the king is safer now!

Linux – keep it simple.

picoEngine is such a rook-ie!

picoEngineRook

Now the rooks can move too!

While it is only a small improvement, the rooks can now also be moved by picoEngine, which is a great step forward. Overall, that leaves 2 of 6 pieces complete for motion, or about 33% complete. Technically, when that is done, the engine will be completely playable, however, much work will be needed to make it “intelligent”.

While there are probably better ways to do this, I followed a pretty simple pattern for making the rook moves:

// Up moves
bool notI = true;
int j = 1;
int vert = 8;
int k = i;
if (i < 56) {
k = i + (vert * j);
}
while (theBoard[k] == ‘-‘ && notI) {
theseMoves.push_back(k);
vert += 8;
if (k < 56) {
k = i + (vert * j);
} else {
notI = false;
}
} // While it’s empty.
if (isupper(theBoard[k])) {
theseMoves.push_back(k);
} // When there is an enemy.

// Down moves
notI = true;
j = -1;
vert = 8;
k = i;
if (i > 7) {
k = i + (vert * j);
}
while (theBoard[k] == ‘-‘ && notI) {
theseMoves.push_back(k);
vert += 8;
if (k >7) {
k = i + (vert * j);
} else {
notI = false;
}
} // While it’s empty.
if (isupper(theBoard[k])) {
theseMoves.push_back(k);
} // When there is an enemy.

That is for “up” moves, and the pattern repeats for down, left, and right. As always, you can check out the full commit on my GitLab.

Linux – keep it simple.