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.