Author: Dann Corbit
Date: 23:31:03 08/08/03
Go up one level in this thread
On August 08, 2003 at 11:33:00, Thomas McBurney wrote:
>It's a shame I cannot understand C, otherwise this would be interesting to me.
>Maybe I should buy a book on C and learn the damn thing! Maybe even write a
>competitive chess engine! :) Anyway, my move generator (written in BASIC) uses
>pre calculated offsets for sliding pieces stored in an array. Not sure if this
>is considered fast or not, but written in BASIC its guaranteed to be about 10
>times slower than one written in C. Anyway, here's my move generator. Have
>fun!
>
>
>SUB GENMOVES (DPTH%, CLR%, PSEUDO%)
>'*********************************************************************
>' GENERATE LIST OF MOVES AND STORE THEM IN MOVELIST(DEPTH,INFO,INDEX#)
>'
>' CLR%=0 - BLACK
>' CLR%=1 - WHITE
>'
>' PSEUDO=1 - ONLY RETURN PSEUDO LEGAL MOVES (FAST)
>' PSEDUO=0 - RETURN 100% LEGAL MOVES (SLOWER)
>'*********************************************************************
>
>MOVELIST(DPTH%, 0, 0) = 0
>
>FOR Y1% = 1 TO 8
> FOR X1% = 1 TO 8
> SQ% = ((Y1% * 10) + 10) + (X1% + 1)
> IF BOARD(SQ%) < 0 AND CLR% = 0 THEN GOSUB PIECEMOVE
> IF BOARD(SQ%) > 0 AND CLR% = 1 THEN GOSUB PIECEMOVE
> NEXT
>NEXT
>
>EXIT SUB
>
>PIECEMOVE:
>
>PIECE% = ABS(BOARD(SQ%))
>IF PIECE% = 1 THEN
> GOSUB PAWNMOVE
> RETURN
>END IF
>
>STARTDIR% = RANGE(1, PIECE%)
>ENDDIR% = RANGE(2, PIECE%)
>MAXDIST% = 7
>IF PIECE% = 6 OR PIECE% = 2 THEN MAXDIST% = 1 ' king & knight only have max
>distance of 1
>
>SPECIAL% = 0
>
>FOR DIR% = STARTDIR% TO ENDDIR%
> DIST% = 0
> DO
> DIST% = DIST% + 1
> IF DIST% > MAXDIST% THEN EXIT DO
> TOSQ% = MOVEGEN(SQ%, DIR%, DIST%)
> IF TOSQ% = 0 THEN EXIT DO ' INDICATES MOVE OFF BOARD SO CHANGE DIR
> IF SGN(BOARD(TOSQ%)) = SGN(BOARD(SQ%)) THEN EXIT DO' CHANGE DIR WHEN HIT
>FRIENDLY
> GOSUB ADDMOVE
> IF BOARD(TOSQ%) <> 0 THEN EXIT DO ' CHANGE DIRECTION AFTER CAPTURE OF ENEMY
>PIECE
> LOOP
>NEXT
>
>IF PIECE% = 6 THEN GOSUB CASTLEMOVE
>
>RETURN
>
>ADDMOVE:
>
>IF PSEUDO% = 0 THEN ' verify legal move
> CALL MAKEMOVE(SQ%, TOSQ%, SPECIAL%, DPTH%)
> IF CLR% = 0 THEN ILLEGAL% = ATTACKSQ(BKING, 1)
> IF CLR% = 1 THEN ILLEGAL% = ATTACKSQ(WKING, 0)
> CALL UNMAKEMOVE(DEPTH)
> IF ILLEGAL% = 1 THEN RETURN
>END IF
>
>R% = MOVELIST(DPTH%, 0, 0) + 1
>MOVELIST(DPTH%, 1, R%) = SQ%
>MOVELIST(DPTH%, 2, R%) = TOSQ%
>MOVELIST(DPTH%, 3, R%) = SPECIAL%
>MOVELIST(DPTH%, 4, R%) = ABS(BOARD(TOSQ%))
>MOVELIST(DPTH%, 0, 0) = R%
>
>RETURN
>
>PAWNMOVE:
>
>Y% = INT((SQ% - 10) / 10) ' CALCULATE Y COORDINATE
>SPECIAL% = 0
>
>IF BOARD(SQ%) = -1 THEN ' white pawn
>
> ' MOVE ONE SQUARE FORWARD
> IF BOARD(SQ% + 10) = 0 THEN TOSQ% = SQ% + 10: GOSUB ADDPAWN
>
> 'TAKE PIECE TO THE LEFT
> IF BOARD(SQ% + 9) > 0 AND BOARD(SQ% + 9) < 100 THEN
> TOSQ% = SQ% + 9: GOSUB ADDPAWN
> END IF
>
> 'TAKE PIECE TO THE RIGHT
> IF BOARD(SQ% + 11) > 0 AND BOARD(SQ% + 11) < 100 THEN
> TOSQ% = SQ% + 11: GOSUB ADDPAWN
> END IF
>
> ' MOVE TWO SQUARES FORWARD FROM 2ND RANK
> IF Y% = 2 THEN
> IF BOARD(SQ% + 10) = 0 AND BOARD(SQ% + 20) = 0 THEN
> TOSQ% = SQ% + 20
> GOSUB ADDMOVE
> END IF
> END IF
>
> 'EN PASSANT CAPTURE
> IF SQ% + 9 = BOARD(126) OR SQ% + 11 = BOARD(126) THEN
> TOSQ% = BOARD(126)
> SPECIAL% = 7
> GOSUB ADDMOVE
> END IF
>END IF
>
>IF BOARD(SQ%) = 1 THEN ' black pawn
>
> ' MOVE ONE SQUARE FORWARD
> IF BOARD(SQ% - 10) = 0 THEN TOSQ% = SQ% - 10: GOSUB ADDPAWN
>
> 'TAKE PIECE TO THE LEFT
> IF BOARD(SQ% - 11) < 0 AND BOARD(SQ% - 11) < 100 THEN
> TOSQ% = SQ% - 11: GOSUB ADDPAWN
> END IF
>
> 'TAKE PIECE TO THE RIGHT
> IF BOARD(SQ% - 9) < 0 AND BOARD(SQ% - 9) < 100 THEN
> TOSQ% = SQ% - 9: GOSUB ADDPAWN
> END IF
>
> ' MOVE TWO SQUARES FORWARD FROM 2ND RANK
> IF Y% = 7 THEN
> IF BOARD(SQ% - 10) = 0 AND BOARD(SQ% - 20) = 0 THEN
> TOSQ% = SQ% - 20
> GOSUB ADDMOVE
> END IF
> END IF
>
> 'EN PASSANT CAPTURE
> IF SQ% - 9 = BOARD(126) OR SQ% - 11 = BOARD(126) THEN
> TOSQ% = BOARD(126)
> SPECIAL% = 7
> GOSUB ADDMOVE
> END IF
>END IF
>
>RETURN
>
>
>ADDPAWN:
>
>Y3% = INT((TOSQ% - 10) / 10)
>
>IF Y3% < 8 AND Y3% > 1 THEN
> GOSUB ADDMOVE
> RETURN
>END IF
>
>SPECIAL% = 6: GOSUB ADDMOVE ' QUEEN
>SPECIAL% = 5: GOSUB ADDMOVE ' ROOK
>SPECIAL% = 4: GOSUB ADDMOVE ' BISHOP
>SPECIAL% = 3: GOSUB ADDMOVE ' KNIGHT
>SPECIAL% = 0
>RETURN
>
>CASTLEMOVE:
>
>IF BOARD(SQ%) = -6 AND SQ% = 26 THEN
> IF BOARD(124) = 0 THEN ' HAS SHORT CASTLING RIGHTS
> IF BOARD(27) = 0 AND BOARD(28) = 0 AND BOARD(29) = -4 THEN
> IF ATTACKSQ(26, 1) = 0 AND ATTACKSQ(27, 1) = 0 AND ATTACKSQ(28, 1) = 0
>THEN
> SPECIAL% = 1
> TOSQ% = 28
> GOSUB ADDMOVE
> END IF
> END IF
> END IF
>
> IF BOARD(125) = 0 THEN ' HAS LONG CASTLING RIGHTS
> IF BOARD(25) = 0 AND BOARD(24) = 0 AND BOARD(23) = 0 AND BOARD(22) = -4 THEN
> IF ATTACKSQ(26, 1) = 0 AND ATTACKSQ(25, 1) = 0 AND ATTACKSQ(24, 1) = 0
>THEN
> SPECIAL% = 2
> TOSQ% = 24
> GOSUB ADDMOVE
> END IF
> END IF
> END IF
>END IF
>
>IF BOARD(SQ%) = 6 AND SQ% = 96 THEN
> IF BOARD(122) = 0 THEN ' HAS SHORT CASTLING RIGHTS
> IF BOARD(97) = 0 AND BOARD(98) = 0 AND BOARD(99) = 4 THEN
> IF ATTACKSQ(96, 0) = 0 AND ATTACKSQ(97, 0) = 0 AND ATTACKSQ(98, 0) = 0
>THEN
> SPECIAL% = 1
> TOSQ% = 98
> GOSUB ADDMOVE
> END IF
> END IF
> END IF
>
> IF BOARD(123) = 0 THEN ' HAS LONG CASTLING RIGHTS
> IF BOARD(95) = 0 AND BOARD(94) = 0 AND BOARD(93) = 0 AND BOARD(92) = 4 THEN
> IF ATTACKSQ(96, 0) = 0 AND ATTACKSQ(95, 0) = 0 AND ATTACKSQ(94, 0) = 0
>THEN
> SPECIAL% = 2
> TOSQ% = 94
> GOSUB ADDMOVE
> END IF
> END IF
> END IF
>END IF
>
>RETURN
>
>END SUB
// Probably something like this in C:
#include <math.h>
extern void genmoves(int dpth, int clr, int pseudo);
extern void piecemove(void);
extern void addmove(void);
extern void pawnmove(void);
extern void addpawn(void);
extern void castlemove(void);
static int attacksq[128][2];
static int board[128];
static int movelist[100][5][10]; // guessing on dimentions
static int x_1,
y_1,
sq;
static int piece;
static int startdir;
static int enddir;
static int maxdist;
static int special;
static int dir;
static int dist;
static int tosq;
static int pseudo;
static int dpth;
static int clr;
static int illegal;
static int bking;
static int wking;
static int depth;
static int r;
static int y;
static int y3;
int sgn(int a)
{
return (a < 0) ? -1 : (a > 0) ? 1 : 0;
}
void genmoves(int dpth, int clr, int pseudo)
{
// *********************************************************************
// generate list of moves and store them in movelist(depth,info,index#)
//
// clr%=0 - black
// clr%=1 - white
//
// pseudo=1 - only return pseudo legal moves (fast)
// pseduo=0 - return 100% legal moves (slower)
// *********************************************************************
movelist[dpth][0][0] = 0;
for (y_1 = 1; y_1 <= 8; y_1++) {
for (x_1 = 1; x_1 <= 8; x_1++) {
sq = ((y_1 * 10) + 10) + (x_1 + 1);
if (board[sq] < 0 && clr == 0) {
piecemove();
}
if (board[sq] > 0 && clr == 1) {
piecemove();
}
}
}
return;
}
void piecemove()
{
piece = abs(board[sq]);
if (piece == 1) {
pawnmove();
return;
}
startdir = range(1, piece);
enddir = range(2, piece);
maxdist = 7;
if (piece == 6 || piece == 2) {
maxdist = 1;
}
special = 0;
for (dir = startdir; dir <= enddir; dir++) {
dist = 0;
while (1) {
dist += 1;
if (dist > maxdist) {
break;
}
tosq = movegen(sq, dir, dist);
if (tosq == 0) {
break;
}
if (sgn(board[tosq]) == sgn(board[sq])) {
break;
}
addmove();
if (board[tosq] != 0) {
break;
}
}
}
if (piece == 6) {
castlemove();
}
}
void addmove(void)
{
if (pseudo == 0) {
makemove(sq, tosq, special, dpth);
if (clr == 0) {
illegal = attacksq[bking][1];
}
if (clr == 1) {
illegal = attacksq[wking][0];
}
unmakemove(depth);
if (illegal == 1) {
return;
}
}
r = movelist[dpth][0][0] + 1;
movelist[dpth][1][r] = sq;
movelist[dpth][2][r] = tosq;
movelist[dpth][3][r] = special;
movelist[dpth][4][r] = abs(board[tosq]);
movelist[dpth][0][0] = r;
}
void pawnmove(void)
{
y = floor((sq - 10) / 10);
special = 0;
if (board[sq] == -1) {
// move one square forward
if (board[sq + 10] == 0) {
tosq = sq + 10;
addpawn();
}
// take piece to the left
if (board[sq + 9] > 0 && board[sq + 9] < 100) {
tosq = sq + 9;
addpawn();
}
// take piece to the right
if (board[sq + 11] > 0 && board[sq + 11] < 100) {
tosq = sq + 11;
addpawn();
}
// move two squares forward from 2nd rank
if (y == 2) {
if (board[sq + 10] == 0 && board[sq + 20] == 0) {
tosq = sq + 20;
addmove();
}
}
// en passant capture
if (sq + 9 == board[126] || sq + 11 == board[126]) {
tosq = board[126];
special = 7;
addmove();
}
}
if (board[sq] == 1) {
// move one square forward
if (board[sq - 10] == 0) {
tosq = sq - 10;
addpawn();
}
// take piece to the left
if (board[sq - 11] < 0 && board[sq - 11] < 100) {
tosq = sq - 11;
addpawn();
}
// take piece to the right
if (board[sq - 9] < 0 && board[sq - 9] < 100) {
tosq = sq - 9;
addpawn();
}
// move two squares forward from 2nd rank
if (y == 7) {
if (board[sq - 10] == 0 && board[sq - 20] == 0) {
tosq = sq - 20;
addmove();
}
}
// en passant capture
if (sq - 9 == board[126] || sq - 11 == board[126]) {
tosq = board[126];
special = 7;
addmove();
}
}
}
void addpawn()
{
y3 = floor((tosq - 10) / 10);
if (y3 < 8 && y3 > 1) {
addmove();
return;
}
special = 6;
addmove();
special = 5;
addmove();
special = 4;
addmove();
special = 3;
addmove();
special = 0;
}
void castlemove()
{
if (board[sq] == -6 && sq == 26) {
if (board[124] == 0) {
if (board[27] == 0 && board[28] == 0 && board[29] == -4) {
if (attacksq[26][1] == 0 && attacksq[27][1] == 0 &&
attacksq[28][1] == 0) {
special = 1;
tosq = 28;
addmove();
}
}
}
if (board[125] == 0) {
if (board[25] == 0 && board[24] == 0 && board[23] == 0 && board[22]
== -4) {
if (attacksq[26][1] == 0 && attacksq[25][1] == 0 &&
attacksq[24][1] == 0) {
special = 2;
tosq = 24;
addmove();
}
}
}
if (board[sq] == 6 && sq == 96) {
if (board[122] == 0) {
if (board[97] == 0 && board[98] == 0 && board[99] == 4) {
if (attacksq[96][0] == 0 && attacksq[97][0] == 0 &&
attacksq[98][0] == 0) {
special = 1;
tosq = 98;
addmove();
}
}
}
if (board[123] == 0) {
if (board[95] == 0 && board[94] == 0 && board[93] == 0 &&
board[92] == 4) {
if (attacksq[96][0] == 0 && attacksq[95][0] == 0 &&
attacksq[94][0] == 0) {
special = 2;
tosq = 94;
addmove();
}
}
}
}
}
}
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.