Author: Thomas McBurney
Date: 08:33:00 08/08/03
Go up one level in this thread
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 >You guys can figure out the rest i bet seeing this code. > >All that bitboard idiocy always. This kicks the hell out of it. > >Vincent Diepeveen, >8 august 2003 5:53 AM > >#if MSVC >__inline >#endif >void GenMovesI(RecursionBlock *rb,int sq) { > int SRsq,piece,u,xside,*s,*t,side,*v,*w; > > side = rb->side; > xside = rb->xside; > SRsq = (sq<<6); > piece = board[sq]; > if( piece == pawn ) { > v = ipiecepos[side][sq]; > w = ipawndir[side][sq]; > u = *v++; > if( row(u) != 0 && row(u) != 7 ) { > if( color[u] == neutral) { > rb->zetend->zet = (SRsq|u); > rb->zetend++; > if( (u=*v) != 128 && color[u] == neutral ) { /* indien u == sq dan false >*/ > rb->zetend->zet = (SRsq|u); > rb->zetend++; > } > } > > u = *w++; > if( color[u] == xside ) {/* ppos bevat geen 100, maar sq. */ > rb->zetend->zet = (SRsq|u|move_captures); > rb->zetend++; > } > if( (u=*w) != 128 && color[u] == xside ) { > rb->zetend->zet = (SRsq|u|move_captures); > rb->zetend++; > } > } > else { > if( color[u] == neutral) { > rb->zetend->zet = (SRsq|u|move_pqueen); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_pknight); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_prook); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_pbishop); > rb->zetend++; > } > u = *w++; > if( color[u] == xside) {/* captures */ > rb->zetend->zet = (SRsq|u|move_captures|move_pqueen); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_pknight); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_prook); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_pbishop); > rb->zetend++; > } > if( (u=*w) != 128 && color[u] == xside) { > rb->zetend->zet = (SRsq|u|move_captures|move_pqueen); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_pknight); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_prook); > rb->zetend++; > rb->zetend->zet = (SRsq|u|move_captures|move_pbishop); > rb->zetend++; > } > } > } > else { > t = cancapside[side]; > if( sweep[piece] ) { > int *vh,*wh,uh; > s = andscan[0]; > vh = ipiecepos[piece][sq]; > wh = iskippos[sq]; > uh = *vh++; > do { > int p1=snelbord[uh],sh=wh[uh]; /* local variables is faster for GCC/MSVC >*/ > vh += (s[p1]&sh); > if( color[uh] != side ) { > rb->zetend->zet = (SRsq|uh|t[p1]); > rb->zetend++; > } > } while( (uh=*vh++) != 128 ); > > /*vi = gentable[piece-3][sq]; > s = doorscan[0]; > u = vi[sq]; > do { > if( color[u] != side ) { > cappiece = snelbord[u]; > rb->zetend->zet = (SRsq|u|t[cappiece]); > rb->zetend++; > u = vi[(s[cappiece]|u)]; > } > else { > u = vi[(64|u)]; > } > } while( u != 128 );*/ > } > else { > v = ipiecepos[piece][sq]; > u = *v++; > do { > if( color[u] != side ) { > rb->zetend->zet = (SRsq|u|t[snelbord[u]]); > rb->zetend++; > } > } while( (u=*v++) != 128 ); > } > } >} > >void MoveListI(RecursionBlock *rb,struct Move *CFEP) { >/* Generate all semi-legal moves. Check is ignored. >*/ > int f,to,from,u,*psq,*pend,*w; > > to = CFEP->zet&63; > rb->zetend = rb->SemiLegals; > if( board[to] == pawn ) { /* for enpassant */ > from = (CFEP->zet>>6)&63; > if( to-from == 16 || from-to == 16 ) { > f = (to+from)>>1; > w = ipawndir[rb->xside][f]; > u = *w++; > if( color[u] == rb->side && board[u] == pawn ) { > rb->zetend->zet = ((u<<6)|f|move_captures|move_enpassant); > rb->zetend++; > } > if( (u=*w) != 128 && color[u] == rb->side && board[u] == pawn ) { > rb->zetend->zet = ((u<<6)|f|move_captures|move_enpassant); > rb->zetend++; > } > } > } > > psq = PieceList[rb->side]; > pend = PieceList[rb->side]+PieceMax[rb->side]; > if( !castld[rb->side] ) { > u = *psq; > if( castle(rb->side,u,u+2) ) { > rb->zetend->zet = ((u<<6)|(u+2)|move_castles); > rb->zetend++; > } > if( castle(rb->side,u,u-2) ) { > rb->zetend->zet = ((u<<6)|(u-2)|move_castles); > rb->zetend++; > } > } > > #if BOUNDSCHECKING > pend++; > do { > pend--; > if( *pend != 64 ) > GenMovesI(rb,*pend); > } while( pend > psq ); > #else > do { > if( *pend != 64 ) > GenMovesI(rb,*pend); > } while( --pend >= psq ); > #endif >} /* End MoveList() */
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.