The good news is I have the Visual Basic 6.0 code for a full working chess program all legal rules including the intricate ones, all written by me years ago and documented in a youtube video I made of it.

Also good news, I ported it all to C++, working and everything..

Slightly bad news is I never commented any of my code (bad programming practise .. I know ..).

However now I can put it on my to do list, 1.) To comment the code, 2.) To make it a tutorial for here 3.) to port it to Microsoft Visual C++. (From Borland C++ 6).

The bad is news is I will be doing thousands of computer science students homework for ages.. and they might not really learn how to improvise code the way I did, but they can still learn from the comments and tutorial providing I finish that. I did not program this chess player for optimized speed, but rather than passing arrays of integers or doubles I used strings to be passed and received between functions. (Strings are generally slower).

However it does the job and plays 99.x% legal moves. (The game of chess has lots of legalities to take into consideration such as 'en passant' and the 50 move rule, all of which I programmed into the programs rule deductions when a human or computer moves). I didn't however program the more intricate rules into the AI or computer past the first ply.

Programming a computer to detect legal and illegal moves even not including the en passant and other rules but just piece movements is monotonous and tedious kinda boring, however commenting it wont be as much. But there is alot of code and I'm not sure what time frame I might do it in or when I might start that.

I will put it on my todo list to A.) Port the working code from Borland to the latest Microsoft Visual C++ (Win32 console). B.) comment the code C.) Create the tutorial for those interested here.

And/or do the same for the Visual Basic 6.0 version but just commenting the code and making the tutorial.

(I had tried the automatic converter for VB6 to VB.net and it failed and even destroyed the current version of the source code I had for it and had to revert to a slightly inferior source code i had backed up for it [years ago btw]).

Also the AI/Engine needs a complete rework, the harder I worked at making it more intelligent and adding pruning the dumber and crazier it got (after a certain point).

I just posted a new tutorial for a UCI chess engine written in c++, the code is there to generate all legal moves of chess including special moves like castling, en passant, promotions and underpromotions. The version I just posted is a random mover and does not play any illegal chess moves, and as far as I can tell generates a full move list for any position or game posed to it.

It has a skeleton of the UCI protocol, enough to work as a random mover against itself or other chess engines. You can play against it by loading it in Arena chess interface (free).

To start with we will need four containers for each move, so obviously we will need an array. Since 218 is the maximum possible moves from any given position in chess we will use that as an index.

int fromSQa[218];
int fromSQb[218];
int toSQa[218];
int toSQb[218];

each move has 4 coordinates, the from square rank (fromSQa[]), the from square file (fromSQb[]), the to square rank (toSQa[]), and the to square file (toSQb[]).

When inserting a move into those 4 arrays, we will index them with z, zwill start at 0, z = 0;, each time we deposit the coordinates into the 4 arrays we will need to immediately increment z by one so it is ready to recieve the next animal/piece move. z++; which is the same as z = z + 1;.

Here we declare all the important variables we will be using to calculate the animal piece moves:

z will be the index for the 4 arrays, a will contain the coordinate of the rank of the piece we are creating moves for, b will be the file of the piece we are generating moves for, c will be the rank of the square to move to, being tested, d will be the file of the 'move to' being tested, e will be how much to add to 'a' to get the next 'c' (rank), and f will be how much to add to b to get the next d (file). So e and f control the direction of the move, in case of rooks, bishops and queens it will be repeatedly added to get further moves in the same direction as long as empty squares are being processed and still on the board.

I hope you all still follow..

Now we must search every square on the board for whites pieces,

We do that with two for loops that both count 0-7 and one is contained in the other.

The resulting pieces found at board[a][b] can now have their moves calculated depending on which piece they are and we will know they start on the square resulting from a as it's rank coordinate and b as it's file coordinate.

Knowing what file and rank numbers they start on can help us calculate what coordinates they can go to.

For now I will focus on the queen move generation.

By putting a switch statement inside the two for statements we can process each piece differently as they move differently.

It is important to use break; after each case, without that break statement it would start generating moves for the last piece found as something it isn't.

For example, without the breaks, say it found a knight and generated all the knight moves, good! then it would run over to the next case, which would be pawn moves and start generating moves for the knight as if it were a pawn, and then as if it were a king!

Well no one wants that.

Although it is sometimes useful to not use a break because you want a sequence of things done for some things and not so much the last/later thing (case/switch), I just can't think of any!

Now that the square for coordinate of a and b is found to have a white queen on it, we have to generate it's legal moves.

for (e = -1; e <= 1; e++) {
for (f = -1; f <= 1; f++) {

The above code will give us the directions a queen move, all cominations of -1, 0 and one for both e and f. Starting at -1, -1, and ending at +1, +1. For example, suppose our white queen is on h8 (7, 7), when we add -1, and -1 we get the coordinates for the g7 square (6, 6). as you can see we are moving diagonally down the board one square, and if we add it again we get f6 (5, 5), so repeatedly adding these values we keep going diagonally down the board, which is how a bishop or queen can move. Now for the next f and e values we have 0, -1, if we add these repeating as we did before we get the queen moving like a rook across the back rank, ie h8, to g8, to f8, to e8, to d8, to c8 and so on till it goes off the board. The only two values we don't need to add are 0, 0, because it would stay on it's square and not generate any moves. So we add some logic to leave out doing anything except getting the next direction in e and f. Below:

if (!(f == 0 && e == 0)) { // process the following code provided f and e are not both 0

Now that we have excluded the direction 0, 0, all the remaining directions are either the way a bishop or a rook moves diagonally (4 directions), and up down left and right.

Now assuming the white queen is on h8, then a, b, are 7, 7, starting with c = a + e;,d = b + f;, well we know e and f both start at -1, so lets do the math c = a + e; well a is 7 e is -1 therefore c = 7 + (-1), so c == -6, and d = 7 + (-1), next if (!(f == 0 && e == 0)) { checks that f and e are not both == 0, since the condition returns true we continue inside the if statement here, inside the if statement we have a do-while loopdo { well nothing happens here because the while condition for this do-while loop is at the bottom in while (!(bounds(c, d) == false));, now say g7 square is unoccupied, well if (bounds(c, d)) {, well we know c == 6 and d == 6 so both of these on on the board (between 0 - 7, more than 7 is off the board or less than 0 is off the board also, so bounds returns true, and we continue inside this if statement also, now if board[c][d] (board[6][6]) is unoccupied, it will be equal to 0, so this statement if (board[c][d] == 0) { will return true and we continue inside this if statement too.

So the above code saves the two from square coordinates and the two to square coordinates as integers, lets assume z ==0, our index for this move is zero, after saving the movce coordinates we increment z for the next move to be saved in our parallel arrays (same as above).

The next statement we encounter is if (board[c][d] < 0) {, since board[c][d] == 0 we can skip over what's inside this if statement, next up is if (board[c][d] > 0) break; , since this returns false also we can skip over break;.

Now,

c = c + e;
d = d + f;

we take c + e and get 6 + (-1) and put that into c, so c now equals 5. And the same with d except with d = d + f; d = 6 + (-1); d = 5, now we are at the end of the top if statement with the bounds() check in it }.

}while (!(bounds(c, d) == false));

since c and d are 5 and 5 the square is on the board so the statement in while(...) is true, and we continue at the top of the do-while loop, if (bounds(c, d)) { will return true, let's look at where that starts and ends:

Now c and d are the coordinates for f6 on the chess board (or 5, 5), now assume that square contains a black piece, all black pieces have a value less than zero or a negative integer value. Well if (board[c][d] == 0) { will not return true, so we won't process till the next '}', now if (board[c][d] < 0) { will be tru inside the brackets so we continue with:

this saves the move coordinates in our 4 parallel arrays and increments the array index by 1. But instead this time we have a break statement after saving the move, the break takes us out of the do-while loop which takes us back to:

Now c is set to a + e, we know e equals -1 still and a = 7, so c = 7 + (-1), c = 6, and d = 7 + 0, so d = 7, now we are moving down like a rook, decrementing the rank but keeping on the same file, lets assume h7 contains a white piece, the next statement will be if (!(f == 0 && e == 0)) {, since e = -1, '(f == 0 && e == 0) will return false, so we have that break down to if (!false) {, and the opposite of false is tryue so we will continue inside the if statement open brace ('}').

The next statement is if (bounds(c, d)) {, since c and d are in the bounds of 0-7 we will continue inside this if statement as well. Next if (board[c][d] == 0) {, in this situation since c, d coordinates on the board contain a positive value piece we don't continue inside this if statement. Next if (board[c][d] < 0) { again won't be true either, so next is if (board[c][d] > 0) break; which will return true in the brackets of the if statement, since it's detected a friendly piece a move will not be saved nor will z be incremented (otherwise we'd be saving a move that captures a friendly piece), but we do go to break; which takes us back to the for statement for f to increment to 1, since we can't continue processing in that direction as we'd be generating queen moves in that direction through a friendly piece thus we terminate that direction with the break statement, and it continues on saving all moves that continue on empty squares saving them as moves until we hit a non empty square, or go off the board and capturing opposite polarity of pieces only.

If you follow so far you can work this out in your head from here.

That covers at least queen moves so far and the rook move generator and bishop moves are almost identical except for this line if (!(f == 0 && e == 0)) {.

The knight and king moves are much simpler as they are not repeating in the directions the move and attack.