false code execution depending on platform

Discuss anything and everything. Keep it clean (or else).
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

false code execution depending on platform

Post by HaWe »

hey,
for the following codes there is a big problem:

on some platforms it works (AVR, PC Windows devcpp, reported positive also for gpp C++),
for some not (Beaglebone Linux, Arduino Due ARM)

after
WHITE: d2d4

always ok, score == 30000 by default


then
BLACK: a7a6

works on AVR and PC devcpp, , score == 30000 by default
but not executed on ARM Due and/or Linux Beaglebone, score 15 == 0x0f == error !!

ANSI C for PC devcpp (works), g++ (works), Beaglebone Linux (dont)

Code: Select all

/***************************************************************************/
/*                               micro-Max,                                */
/* A chess program smaller than 2KB (of non-blank source), by H.G. Muller  */
/***************************************************************************/
/* version 4.8.j (1953 characters) features:                                 */
/* - recursive negamax search                                              */
/* - all-capture MVV/LVA quiescence search                                 */
/* - (internal) iterative deepening                                        */
/* - best-move-first 'sorting'                                             */
/* - a hash table storing score and best move                              */
/* - futility pruning                                                      */
/* - king safety through magnetic, frozen king in middle-game              */
/* - R=2 null-move pruning                                                 */
/* - keep hash and repetition-draw detection                               */
/* - better defense against passers through gradual promotion              */
/* - extend check evasions in inner nodes                                  */
/* - reduction of all non-Pawn, non-capture moves except hash move (LMR)   */
/* - full FIDE rules (expt under-promotion) and move-legality checking     */


#define K(A,B) *(int*)(T+A+(B&8)+S*(B&7))


#define HTsize (1<<8) // (1<<24)
struct HTab {
          int  K,
               V;
          int  X,
               Y,
               D;
        } HTarray[HTsize];           /* hash table, HTsize entries*/
        
        
#define MAXNODES 60000

int  K,   
     Q,
     R,
     J,
     Z;
     
long N,
     I=30000;                         /* I=80000: "infinity score" */ ;                           

int M=136,                           /* M=0x88   board system    */
    S=128,                           /* dummy square 0x80, highest valid square =127    */
    turn=16;             

char L, 
     pval[]={0,2,2,7,-1,8,12,23},                      /* relative piece values    */
     vector[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0, /* step-vector lists */
          7,-1,11,6,8,3,6},                          /* 1st dir. in vector[] per piece*/
     
     bsetup[]={6,3,5,7,4,5,3,6},                         /* initial piece setup      */
     board[129],                                        /* board: half of 16x8+dummy*/
     T[1035];                                        /* hash translation table   */

char psymbol[]= ".?+nkbrq?*?NKBRQ";

char mfrom, mto;    // current ply from - to
int  EPSQ,
     RemP;           // remove piece




/* recursive minimax search, turn=moving side, n=depth*/

int Minimax(int q, int l, int score, int EPC, int prev, int hashkey)         
                       /* (q,l)=window, score, EnPass_sqr.*/
                       /* prev=prev.dest; J,Z=hashkeys; return score*/
{
   int  j,
        r,
        m,
        v,
        d,
        h,
        i,
        F,
        G,
        V,
        P,
        f=J,
        g=Z,
        C,
        s;
   char t,
        p,
        upiece,
        x,
        y,
        X,
        Y,
        H,
        B;
   
   struct HTab *a = HTarray + (J + turn * EPC & HTsize-1);   /* lookup pos. in hash table*/
 
 
 
 
 
   q--;                                          /* adj. window: delay bonus */
   turn^=24;                                        /* change sides             */
   d=a->D;
   m=a->V;
   X=a->X;
   Y=a->Y;                  /* resume at stored depth   */
   
   if(a->K-Z|prev|                                  /* miss: other pos. or empty*/
      !(m<=q | X&8&&m>=l | X&S))                   /*   or window incompatible */
      { d=Y=0; }                                /* start iter. from scratch */
   
   X&=~M;                                        /* start at best-move hint  */
 
   while( d++ < hashkey || d<3                   /* iterative deepening loop */
     || prev&K == I
       && ( N<60000 & d<98                        /* root: deepen upto time   */
          || (K=X, L=Y&~M, d=3)
       )
     )                                          /* time's up: go do best    */
   {
      x=B=X;                                       /* start scan at prev. best */
      h=Y&S;                                       /* request try noncastl. 1st*/
      P=d<3 ? I : Minimax(-l,1-l,-score,S,0,d-3);               /* Search null move         */
      m = (-P<l | R>35) ? ( d>2 ? -I : score ) : -P;            /* Prune or stand-pat       */
      N++;                                         /* node count (for timing)  */
      do
      {
         upiece=board[x];                                   /* scan board looking for   */
         if(upiece & turn)                                  /*  own piece (inefficient!)*/
         {
            r = p = upiece&7;                               /* p = piece type (set r>0) */
            j = vector[p+16];                                 /* first step vector f.piece*/
            while(r = p>2 & r<0 ? -r : -vector[++j] )       /* loop over directions vector[] */
            {
labelA:                                        /* resume normal after best */
               y=x;                            /* (x,y)=move         */
               F=G=S;                          /* (F,G)=castl.R      */
               
               do
               {                                       /* y traverses ray, or:     */
                  H=y=h?Y^h:y+r;                           /* sneak in prev. best move */
                 
                  if(y&M)break;                            /* board edge hit           */
                 
                  m= EPC-S&board[EPC]&&y-EPC<2&EPC-y<2?I:m;      /* bad castling             */
                 
                  if(p<3&y==EPC)H^=16;                           /* shift capt.sqr. H if e.p.*/
                 
                  t=board[H];
                 
                  if(t&turn|p<3&!(y-x&7)-!t)break;            /* capt. own, bad pawn mode */
                  i=37*pval[t&7]+(t&192);                     /* value of capt. piece t   */
                  m=i<0?I:m;                                  /* K capture                */
                 
                  if(m>=l&d>1) goto labelC;                     /* abort on fail high       */
           
                  v=d-1?score:i-p;                             /* MVV/LVA scoring          */
                 
                  if(d-!t>1)                               /* remaining depth          */
                  {
                     v=p<6?board[x+8]-board[y+8]:0;                  /* center positional pts.   */
                     board[G]=board[H]=board[x]=0;board[y]=upiece|32;             /* do move, set non-virgin  */
                     if(!(G&M))board[F]=turn+6,v+=50;               /* castling: put R & score  */
                     v-=p-4|R>29?0:20;                              /* penalize mid-game K move */
                     
                     if(p<3)                                        /* pawns:                   */
                     {
                        v-=9*((x-2&M||board[x-2]-upiece)+              /* structure, undefended    */
                               (x+2&M||board[x+2]-upiece)-1            /*        squares plus bias */
                              +(board[x^16]==turn+36))                 /* kling to non-virgin King */
                              -(R>>2);                                 /* end-game Pawn-push bonus */
                         V=y+r+1&S?647-p:2*(upiece&y+16&32);           /* promotion or 6/7th bonus */
                         board[y]+=V;
                         i+=V;                                         /* change piece, add score  */
                     }
                     
                     v+= score+i;
                     V=m>q ? m : q;                           /* new eval and alpha       */
                     J+=K(y+0,board[y])-K(x+0,upiece)-K(H+0,t); 
                     Z+=K(y+8,board[y])-K(x+8,upiece)-K(H+8,t)+G -S;  /* update hash key          */
                     C=d-1-(d>5&p>2&!t&!h);
                     C=R>29|d<3|P-I?C:d;                     /* extend 1 ply if in check */
                     do {
                        s=C>2|v>V?-Minimax(-l,-V,-v,         /* recursive eval. of reply */
                                            F,0,C):v;        /* or fail low if futile    */
                     } while( s>q & ++C<d );
                   
                     v=s;
                     if(prev&&K-I&&v+I&&x==K&y==L)              /* move pending & in root:  */
                     {
                        Q=-score-i; EPSQ=F;                            /*   exit if legal & found  */
                        a->D=99;a->V=0;                        /* lock game in hash as draw*/
                        R+=i>>7;
                        return l;                            /* captured non-P material  */
                     }
                     J=f;
                     Z=g;                                    /* restore hash key         */
                     board[G]=turn+6;
                     board[F]=board[y]=0;
                     board[x]=upiece;
                     board[H]=t;                             /* undo move,G can be dummy */
                  }
                  if(v>m)                                  /* new best, update max,best*/
                  {
                     m=v,X=x,Y=y|S&F;                      /* mark double move with S  */
                  }                       
                  if(h)
                  {
                     h=0;
                     goto labelA;                           /* redo after doing old best*/
                  }                 
                  if (
                    x+r-y|upiece&32|                             /* not 1st step,moved before*/
                    p>2 & (
                      p-4|j-7||                             /* no P & no lateral K move,*/
                      board[G=x+3^r>>1&7]-turn-6            /* no virgin R in corner G, */
                      || board[G^1] | board[G^2] )          /* no 2 empty sq. next to R */
                    )
                  {
                     t+=p<5; 
                  }                                        /* fake capt. for nonsliding*/
                  else F=y;                                /* enable e.p.              */
                 
               } while(!t);                               /* if not capt. continue ray*/
         
            }
         }  // (upiece & turn)
     
      } while((x=x+9&~M)-B);                       /* next sqr. of board, wrap */
   
labelC:
      if (m>I-M|m<M-I) d=98;                       /* mate holds to any depth  */
      m= m+I|P==I ? m : 0;                         /* best loses K: (stale)mate*/
     
      if(a->D<99) {                                /* protect game history     */
         a->K=Z;
         a->V=m;
         a->D=d;                       /* always store in hash tab */
         a->X=X|8*(m>q)|S*(m<l);
         a->Y=Y;                       /* move, type (bound/exact),*/
      } 
      /* uncomment for Kibitz */
      if(!((N-S)%987)) printf("searched: %d\r",N-S);
      /*
      if(prev){
           printf("%2d ply, %9d searched, score=%6d by %c%c%c%c\n", d-1, N-S, m,
                   'a'+(X&7),'8'-(X>>4),'a'+(Y&7),'8'-(Y>>4&7));       /*    encoded in X S,8 bits   
      }   
      */
   }  // while (iterative deepening loop)                                           
 
   turn^=24;                                        /* change sides back        */
   mfrom=K; mto=L; 
   return m+= m<score;                                  /* delayed-loss bonus       */
}







main()
{
   int  score;
   char sbuf[50], sbuf2[50];
   char oboard[129];
   char oldto, oldEPSQ;
   int  *key;
   int  cstring[20];


   
   K=8;
   while(K--)
   {
      board[K]=(board[K+112]=bsetup[K]+8)+8;
      board[K+16]=18;
      board[K+96]=9;                               /* initial board setup*/
      L=8;
      while(L--)board[16*L+K+8]=(K-4)*(K-4)+(L-3.5)*(L-3.5);     /* center-pts table   */
   }                                                             /*(in unused half board[])*/
   N=1035;
   while(N-->M)T[N]=rand()>>9;
   
                                                                /* play loop          */
   while(1)                                               
   {
     N=-1;
     
     printf("\n");
     while(++N<121) {                                            /* print board */
         printf(" %c", N&8 && (N+=7) ? 10 : psymbol[board[N]&15]); 
     }
     
     if(turn==16) printf("\n>  WHITE: ");  else printf("\n>   BLACK:  ");
     
     
     
     
     
     
     
     
     
     key=cstring;     
     while( (*key++ =getchar() ) > 10 );                 /* read input line    */
     K=I;                                                /* invalid move       */
     
     if(*cstring-10) {                                   /* parse entered move */
       K= (char)cstring[0]-16*cstring[1]+799;
       L= (char)cstring[2]-16*cstring[3]+799;
     }
     
     
     printf(" DEBUG %c%c%c%c \n DEBUG K: %d  \n DEBUG L: %d \n", cstring[0],cstring[1],cstring[2],cstring[3], K, L);
    











     
     memcpy(oboard, board, sizeof(board));
     oldto=mto;
     oldEPSQ=EPSQ;
     score=Minimax(-I,I,Q,EPSQ,1,3);                              /* think or check & do*/     
     printf("\n\nscore=%d\n", score); 
    // if(score!=15) {                     
        RemP=S;   
        if(oboard[mto])   RemP=mto;
        if(mto==oldEPSQ)  RemP=oldto;
                                       
        sprintf(sbuf,"\n\nmoved: >> %c%c", 'a'+(mfrom&7),'8'-(mfrom>>4) );
       
        if(oboard[mto]) strcat(sbuf," X ");
        else strcat(sbuf,"-");
       
        sprintf(sbuf2,"%c%c ", 'a'+(mto&7),'8'-(mto>>4&7));
        strcat(sbuf, sbuf2);
        printf(sbuf);
     
        sprintf(sbuf, " (square %d to %d ) \n", mfrom, mto);
        printf("\n\nDEBUG:\n");
        sprintf(sbuf2,"  EPsq: %c%c (%d)\n  RemP: %c%c (%d)",
                         'a'+(EPSQ&7), '8'-(EPSQ>>4&7), EPSQ,
                         'a'+(RemP&7), '8'-(RemP>>4&7), RemP);
        strcat(sbuf, sbuf2);
        printf(sbuf);
        printf("\n\n");
   //  }
    // else printf("\n\nILLEGAL!\n");

   }
}


Sketch C for AVR (works), ARM Due (don't)

Code: Select all

/***************************************************************************/
/*                               micro-Max,                                */
/* A chess program smaller than 2KB (of non-blank source), by H.G. Muller  */
/***************************************************************************/
/* version 4.8.i Sketch (1953 characters) features:                                 */
/* - recursive negamax search                                              */
/* - all-capture MVV/LVA quiescence search                                 */
/* - (internal) iterative deepening                                        */
/* - best-move-first 'sorting'                                             */
/* - a hash table storing score and best move                              */
/* - futility pruning                                                      */
/* - king safety through magnetic, frozen king in middle-game              */
/* - R=2 null-move pruning                                                 */
/* - keep hash and repetition-draw detection                               */
/* - better defense against passers through gradual promotion              */
/* - extend check evasions in inner nodes                                  */
/* - reduction of all non-Pawn, non-capture moves except hash move (LMR)   */
/* - full FIDE rules (expt under-promotion) and move-legality checking     */


#define K(A,B) *(int*)(T+A+(B&8)+S*(B&7))


#define HTsize (1<<8) // (1<<24)
struct HTab {
          int  K,
               V;
          int  X,
               Y,
               D;
        } HTarray[HTsize];           /* hash table, HTsize entries*/
        
        
#define MAXNODES 60000

int  K,   
     Q,
     R,
     J,
     Z;
     
long N,
     I=30000;                         /* I=80000: "infinity score" */ ;                           

int 
    M=136,                           /* M=0x88   board system    */
    S=128,                           /* dummy square 0x80, highest valid square =127    */
    turn=16;             

char L,
     pval[]={0,2,2,7,-1,8,12,23},                      /* relative piece values    */
     vector[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0, /* step-vector lists */
          7,-1,11,6,8,3,6},                          /* 1st dir. in vector[] per piece*/
     
     bsetup[]={6,3,5,7,4,5,3,6},                         /* initial piece setup      */
     board[129],                                        /* board: half of 16x8+dummy*/
     T[1035];                                        /* hash translation table   */

char psymbol[]= ".?+nkbrq?*?NKBRQ";

char mfrom, mto;    // current ply from - to
int  EPSQ,
     RemP;           // remove piece




/* recursive minimax search, turn=moving side, n=depth*/

int  Minimax(int  q, int  l, int  score, int  EPC, int  prev, int  hashkey)         
                       /* (q,l)=window, score, EnPass_sqr.*/
                       /* prev=prev.dest; J,Z=hashkeys; return score*/
{
   int  j,
        r,
        m,
        v,
        d,
        h,
        i,
        F,
        G,
        V,
        P,
        f=J,
        g=Z,
        C,
        s;
   char t,
        p,
        upiece,
        x,
        y,
        X,
        Y,
        H,
        B;
   
   struct HTab *a = HTarray + (J + turn * EPC & HTsize-1);   /* lookup pos. in hash table*/
 
   char sbuf[50];
 
 
 
   q--;                                          /* adj. window: delay bonus */
   turn^=24;                                        /* change sides             */
   d=a->D;
   m=a->V;
   X=a->X;
   Y=a->Y;                  /* resume at stored depth   */
   
   if(a->K-Z|prev|                                  /* miss: other pos. or empty*/
      !(m<=q | X&8&&m>=l | X&S))                   /*   or window incompatible */
      { d=Y=0; }                                /* start iter. from scratch */
   
   X&=~M;                                        /* start at best-move hint  */
 
   while( d++ < hashkey || d<3                   /* iterative deepening loop */
     || prev&K == I
       && ( N<60000 & d<98                        /* root: deepen upto time   */
          || (K=X, L=Y&~M, d=3)
       )
     )                                          /* time's up: go do best    */
   {
      x=B=X;                                       /* start scan at prev. best */
      h=Y&S;                                       /* request try noncastl. 1st*/
      P=d<3 ? I : Minimax(-l,1-l,-score,S,0,d-3);               /* Search null move         */
      m = (-P<l | R>35) ? ( d>2 ? -I : score ) : -P;            /* Prune or stand-pat       */
      N++;                                         /* node count (for timing)  */
      do
      {
         upiece=board[x];                                   /* scan board looking for   */
         if(upiece & turn)                                  /*  own piece (inefficient!)*/
         {
            r = p = upiece&7;                               /* p = piece type (set r>0) */
            j = vector[p+16];                                 /* first step vector f.piece*/
            while(r = p>2 & r<0 ? -r : -vector[++j] )       /* loop over directions vector[] */
            {
labelA:                                        /* resume normal after best */
               y=x;                            /* (x,y)=move         */
               F=G=S;                          /* (F,G)=castl.R      */
               
               do
               {                                       /* y traverses ray, or:     */
                  H=y=h?Y^h:y+r;                           /* sneak in prev. best move */
                 
                  if(y&M)break;                            /* board edge hit           */
                 
                  m= EPC-S&board[EPC]&&y-EPC<2&EPC-y<2?I:m;      /* bad castling             */
                 
                  if(p<3&y==EPC)H^=16;                           /* shift capt.sqr. H if e.p.*/
                 
                  t=board[H];
                 
                  if(t&turn|p<3&!(y-x&7)-!t)break;            /* capt. own, bad pawn mode */
                  i=37*pval[t&7]+(t&192);                     /* value of capt. piece t   */
                  m=i<0?I:m;                                  /* K capture                */
                 
                  if(m>=l&d>1) goto labelC;                     /* abort on fail high       */
           
                  v=d-1?score:i-p;                             /* MVV/LVA scoring          */
                 
                  if(d-!t>1)                               /* remaining depth          */
                  {
                     v=p<6?board[x+8]-board[y+8]:0;                  /* center positional pts.   */
                     board[G]=board[H]=board[x]=0;board[y]=upiece|32;             /* do move, set non-virgin  */
                     if(!(G&M))board[F]=turn+6,v+=50;               /* castling: put R & score  */
                     v-=p-4|R>29?0:20;                              /* penalize mid-game K move */
                     
                     if(p<3)                                        /* pawns:                   */
                     {
                        v-=9*((x-2&M||board[x-2]-upiece)+              /* structure, undefended    */
                               (x+2&M||board[x+2]-upiece)-1            /*        squares plus bias */
                              +(board[x^16]==turn+36))                 /* kling to non-virgin King */
                              -(R>>2);                                 /* end-game Pawn-push bonus */
                         V=y+r+1&S?647-p:2*(upiece&y+16&32);           /* promotion or 6/7th bonus */
                         board[y]+=V;
                         i+=V;                                         /* change piece, add score  */
                     }
                     
                     v+= score+i;
                     V=m>q ? m : q;                           /* new eval and alpha       */
                     J+=K(y+0,board[y])-K(x+0,upiece)-K(H+0,t); 
                     Z+=K(y+8,board[y])-K(x+8,upiece)-K(H+8,t)+G -S;  /* update hash key          */
                     C=d-1-(d>5&p>2&!t&!h);
                     C=R>29|d<3|P-I?C:d;                     /* extend 1 ply if in check */
                     do {
                        s=C>2|v>V?-Minimax(-l,-V,-v,         /* recursive eval. of reply */
                                            F,0,C):v;        /* or fail low if futile    */
                     } while( s>q & ++C<d );
                   
                     v=s;
                     if(prev&&K-I&&v+I&&x==K&y==L)              /* move pending & in root:  */
                     {
                        Q=-score-i; EPSQ=F;                            /*   exit if legal & found  */
                        a->D=99;a->V=0;                        /* lock game in hash as draw*/
                        R+=i>>7;
                        return l;                            /* captured non-P material  */
                     }
                     J=f;
                     Z=g;                                    /* restore hash key         */
                     board[G]=turn+6;
                     board[F]=board[y]=0;
                     board[x]=upiece;
                     board[H]=t;                             /* undo move,G can be dummy */
                  }
                  if(v>m)                                  /* new best, update max,best*/
                  {
                     m=v,X=x,Y=y|S&F;                      /* mark double move with S  */
                  }                       
                  if(h)
                  {
                     h=0;
                     goto labelA;                           /* redo after doing old best*/
                  }                 
                  if (
                    x+r-y|upiece&32|                             /* not 1st step,moved before*/
                    p>2 & (
                      p-4|j-7||                             /* no P & no lateral K move,*/
                      board[G=x+3^r>>1&7]-turn-6            /* no virgin R in corner G, */
                      || board[G^1] | board[G^2] )          /* no 2 empty sq. next to R */
                    )
                  {
                     t+=p<5; 
                  }                                        /* fake capt. for nonsliding*/
                  else F=y;                                /* enable e.p.              */
                 
               } while(!t);                               /* if not capt. continue ray*/
         
            }
         }  // (upiece & turn)
     
      } while((x=x+9&~M)-B);                       /* next sqr. of board, wrap */
   
labelC:
      if (m>I-M|m<M-I) d=98;                       /* mate holds to any depth  */
      m= m+I|P==I ? m : 0;                         /* best loses K: (stale)mate*/
     
      if(a->D<99) {                                /* protect game history     */
         a->K=Z;
         a->V=m;
         a->D=d;                       /* always store in hash tab */
         a->X=X|8*(m>q)|S*(m<l);
         a->Y=Y;                       /* move, type (bound/exact),*/
      } 
      /* uncomment for Kibitz */
      if(!((N-S)%987)) {        
        sprintf(sbuf, "searched: %d\n",N-S);
        Serial.print(sbuf);
      }
      
   }  // while (iterative deepening loop)                                           
 
   turn^=24;                                        /* change sides back        */
   mfrom=K; mto=L; 
   return m+= m<score;                                  /* delayed-loss bonus       */
}





void chess()
{
   int  score, i;
   char sbuf[50], sbuf2[50];
   char oboard[129];
   char oldto, oldEPSQ;
   char cstring[20];
   
   K=8;
   while(K--)
   {
      board[K]=(board[K+112]=bsetup[K]+8)+8;
      board[K+16]=18;
      board[K+96]=9;                               /* initial board setup*/
      L=8;
      while(L--)board[16*L+K+8]=(K-4)*(K-4)+(L-3.5)*(L-3.5);     /* center-pts table   */
   }                                                             /*(in unused half board[])*/
   N=1035;
   while(N-->M)T[N]=rand()>>9;
   
                                                                /* play loop          */
   while(1)                                               
   {
     N=-1;
     
     Serial.print("\n");
     while(++N<121) {                                            /* print board */
         sprintf(sbuf," %c", N&8 && (N+=7) ? 10 : psymbol[board[N]&15]); 
         Serial.print(sbuf);
     }
     
     if(turn==16) sprintf(sbuf,"\n>  WHITE: ");  else sprintf(sbuf,"\n>   BLACK:  ");  
     Serial.print(sbuf);
     
     i = 0;        
     strcpy(cstring,"");
     do   {
       while (Serial.available()==0);       
       cstring[i] = Serial.read();     
       if(cstring[i]==13) {
         cstring[i]=0;
         break;
       }
       else i++;
     } while(i < 10);
     
     K=I;
     
     if(cstring[0]!=0) {                                   /* parse entered move */
       K= cstring[0]-16*cstring[1]+799;
       L= cstring[2]-16*cstring[3]+799;
     }    
     
     Serial.print("\n DEBUG cstring : "); Serial.println(cstring);
     sprintf(sbuf,"\n DEBUG K: %d  \n DEBUG L: %d \n",  K, L);
     Serial.print(sbuf);
     
     Serial.println();  Serial.println(cstring);  Serial.println();
     
     memcpy(oboard, board, sizeof(board));
     oldto=mto;
     oldEPSQ=EPSQ;
     
     score=Minimax(-I, I, Q, EPSQ, 1, 3);                              /* think or check & do*/     
     Serial.print("\nscore=");  Serial.println(score);  Serial.println();
    
    // if(ack!=15) {                     
        RemP=S;   
        if(oboard[mto])   RemP=mto;
        if(mto==oldEPSQ)  RemP=oldto;
                                       
        sprintf(sbuf,"\n\nmoved: >> %c%c", 'a'+(mfrom&7),'8'-(mfrom>>4) );
       
        if(oboard[mto]) strcat(sbuf," X ");
        else strcat(sbuf,"-");
       
        sprintf(sbuf2,"%c%c ", 'a'+(mto&7),'8'-(mto>>4&7));
        strcat(sbuf, sbuf2);
        Serial.print(sbuf);
     
        sprintf(sbuf, " (square %d to %d ) \n", mfrom, mto);
        Serial.print("\n\nDEBUG:\n");
        sprintf(sbuf2,"  EPsq: %c%c (%d)\n  RemP: %c%c (%d)",
                         'a'+(EPSQ&7), '8'-(EPSQ>>4&7), EPSQ,
                         'a'+(RemP&7), '8'-(RemP>>4&7), RemP);
        strcat(sbuf, sbuf2);
        Serial.print(sbuf);
        Serial.print("\n\n");
    //  }
    // else printf("\n\nILLEGAL!\n");

   }
}




void setup() {
   Serial.begin(9600);    
}



void loop() {    
   chess();
   
   while(1);  
}

what the F*** is happening here?

edit:
meanwhile even tried by changing

Code: Select all

#define K(A,B) *(int*)(T+A+(B&8)+S*(B&7))
to

Code: Select all

#define K(A,B) (int)(T+A+( B&8 )+S*( B&7 )) 
- exactly the same results as before
Last edited by HaWe on 16 Nov 2014, 13:05, edited 1 time in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

this is the program output for 3 platforms:

Arduino Mega AVR (works)

Code: Select all

Mega:
======


 r n b q k b n r 
 + + + + + + + + 
 . . . . . . . . 
 . . . . . . . . 
 . . . . . . . . 
 . . . . . . . . 
 * * * * * * * * 
 R N B Q K B N R 

>  WHITE: DEBUG cstring : d2d4

 DEBUG K: 99  
 DEBUG L: 67 

d2d4


score=30000



moved: >> d2-d4 

DEBUG:
 (square 99 to 67 ) 
  EPsq: d3 (83)
  RemP: a8 (128)


 r n b q k b n r 
 + + + + + + + + 
 . . . . . . . . 
 . . . . . . . . 
 . . . * . . . . 
 . . . . . . . . 
 * * * . * * * * 
 R N B Q K B N R 

>   BLACK:  DEBUG cstring : a7a6

 DEBUG K: 16  
 DEBUG L: 32 

a7a6


score=30000



moved: >> a7-a6 

DEBUG:
 (square 16 to 32 ) 
  EPsq: a8 (128)
  RemP: a8 (128)


 r n b q k b n r 
 . + + + + + + + 
 + . . . . . . . 
 . . . . . . . . 
 . . . * . . . . 
 . . . . . . . . 
 * * * . * * * * 
 R N B Q K B N R 

>  WHITE: //<<<<<<<<<<<<<<<<<< executed correctly, turn on white!


Arduino Due ARM (not)

Code: Select all


Due:
====


 r n b q k b n r 
 + + + + + + + + 
 . . . . . . . . 
 . . . . . . . . 
 . . . . . . . . 
 . . . . . . . . 
 * * * * * * * * 
 R N B Q K B N R 

>  WHITE: DEBUG cstring : d2d4

 DEBUG K: 99  
 DEBUG L: 67 

d2d4


score=30000



moved: >> d2-d4 

DEBUG:
 (square 99 to 67 ) 
  EPsq: d3 (83)
  RemP: a8 (128)


 r n b q k b n r 
 + + + + + + + + 
 . . . . . . . . 
 . . . . . . . . 
 . . . * . . . . 
 . . . . . . . . 
 * * * . * * * * 
 R N B Q K B N R 

>   BLACK:  DEBUG cstring : a7a6

 DEBUG K: 16  
 DEBUG L: 32 

a7a6


score=15



moved: >> a7-a6 

DEBUG:
 (square 16 to 32 ) 
  EPsq: d3 (83)
  RemP: a8 (128)


 r n b q k b n r 
 + + + + + + + + 
 . . . . . . . . 
 . . . . . . . . 
 . . . * . . . . 
 . . . . . . . . 
 * * * . * * * * 
 R N B Q K B N R 

>   BLACK:  //<<<<<<<<<<<<<<<<<< not executed , hangs on black's turn !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



PC devcpp (works):

Code: Select all

devcpp:
=======


 r n b q k b n r
 + + + + + + + +
 . . . . . . . .
 . . . . . . . .
 . . . . . . . .
 . . . . . . . .
 * * * * * * * *
 R N B Q K B N R

>  WHITE: d2d4
d2d4
 DEBUG K: 99
 DEBUG L: 67


score=30000


moved: >> d2-d4

DEBUG:
 (square 99 to 67 )
  EPsq: d3 (83)
  RemP: a8 (128)


 r n b q k b n r
 + + + + + + + +
 . . . . . . . .
 . . . . . . . .
 . . . * . . . .
 . . . . . . . .
 * * * . * * * *
 R N B Q K B N R

>   BLACK:  a7a6
a7a6
 DEBUG K: 16
 DEBUG L: 32


score=30000


moved: >> a7-a6

DEBUG:
 (square 16 to 32 )
  EPsq: a8 (128)
  RemP: a8 (128)


 r n b q k b n r
 . + + + + + + +
 + . . . . . . .
 . . . . . . . .
 . . . * . . . .
 . . . . . . . .
 * * * . * * * *
 R N B Q K B N R

>  WHITE:  //<<<<<<<<<<<<<<<<<< executed correctly, turn on white!
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: false code execution depending on platform

Post by mightor »

It could be related to compiler optimizations. Try to compile with -O0 (that's an "oh" followed by a "zero").

= Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

thank you,
I'm personally working just with my PC and with Arduino Sketch for Mega and Due -

but as the problem is just about the Due:

where can I change the compiler options in Sketch?

Recently I've been using Sketch releases 1.5.6 and 1.5.8 by same odd results compiling identical source codes:
OK for Mega,
faulty for Due.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

update:

just observed: for the Due also the legality check for auto move is faulty, it generates patially completely illegal moves.

On the other hand, for the AVR Mega all moves are correct: So there must be a mess in the ARM compiler, no?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

update2:

using both gpp and Clang on a Beaglebone platform (2 completely different compilers !!) another user observed identical faulty moves, optimization was switched off.
So code optimization actually can't be the reason why.

!!>>> IIRC, Beaglebone is ARM based just as Arduino Due <<<!!

On his Windows PC the code compiled and run without issues, just like for me.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

for a comparatively very much simplified chess engine version (1.6 vs. 4.8: no hash tables used here) it's already the same issue:

works for Mega (AVR),
don't work for Due (ARM-Cortex):

Code: Select all

/***************************************************************************/
/*                               micro-Max,                                */
/* A chess program smaller than 2KB (of non-blank source), by H.G. Muller  */
/***************************************************************************/
/* version 1.6 Sketch (1433 non-blank characters) features:                       */
/* - recursive negamax search                                              */
/* - quiescence search with recaptures                                     */
/* - recapture extensions                                                  */
/* - (internal) iterative deepening                                        */
/* - best-move-first 'sorting'                                             */
/* - full FIDE rules and move-legality checking                            */

/* accepts under-promotions: type 1,2,3 (=R,B,N) after input move          */
/* (input buffer c[] & *P made global, K and N encoding swapped for this)  */


#define W while

int M=136,
    S=128,
    I=8e3,
    C=799,
    Q,
    O,
    K,
    N;   

char L,
     *P,
     w[]={0,1,1,-1,3,3,5,9},                      
     o[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0,
          7,-1,6,11,8,3,6,                          
          6,4,5,7,3,5,4,6},                         
     b[129],

     n[]=".?+knbrq?*?KNBRQ",

     c[9];

int D(int k, int q, int l, int e, int E, int z, int n)    
{                       
 int j,r,m,v,d,h,i,F,G,s;
 char t,p,u,x,y,X,Y,H,B;

 q--;                                          
 d=X=Y=0;                                      

 W(d++<n||                                     
   z==8&K==I&&(N<1e6&d<98||                    
   (K=X,L=Y&~M,d=2)))                          
 {x=B=X;                                       
  h=Y&S;                                   
  m=d>1?-I:e;                                  
  N++;                                         
  do{u=b[x];                                   
   if(u&k)                                     
   {r=p=u&7;                                   
    j=o[p+16];                                 
    W(r=p>2&r<0?-r:-o[++j])                    
    {A:                                        
     y=x;F=G=S;                                
     do{                                       
      H=y=h?Y^h:y+r;                        
      if(y&M)break;                            
      m=E-S&&b[E]&&y-E<2&E-y<2?I:m;    /* castling-on-Pawn-check bug fixed */
      if(p<3&y==E)H^=16;                       
      t=b[H];if(t&k|p<3&!(y-x&7)-!t)break;       
      i=99*w[t&7];                             
      m=i<0?I:m;                       /* castling-on-Pawn-check bug fixed */
      if(m>=l)goto C;                          

      if(s=d-(y!=z))                           
      {v=p<6?b[x+8]-b[y+8]:0;
       b[G]=b[H]=b[x]=0;b[y]=u|32;             
       if(!(G&M))b[F]=k+6,v+=30;               
       if(p<3)                                 
       {v-=9*((x-2&M||b[x-2]-u)+               
              (x+2&M||b[x+2]-u)-1);            
        if(y+r+1&S)b[y]|=7,i+=C;               
       }
       v=-D(24-k,-l,m>q?-m:-q,-e-v-i,F,y,s);   
       if(K-I)                                 
       {if(v+I&&x==K&y==L&z==8)                
        {Q=-e-i; O=F;
         if(b[y]-u&7&&P-c>5)b[y]-=c[4]&3;        /* under-promotions */
         return l;
        }v=m;                                   
       }                                       
       b[G]=k+6;b[F]=b[y]=0;b[x]=u;b[H]=t;     
       if(v>m)                         
        m=v,X=x,Y=y|S&F;                       
       if(h){h=0;goto A;}                            
      }
      if(x+r-y|u&32|                           
         p>2&(p-3|j-7||                        
         b[G=x+3^r>>1&7]-k-6                   
         ||b[G^1]|b[G^2])                      
        )t+=p<5;                               
      else F=y;                                
     }W(!t);                                   
  }}}W((x=x+9&~M)-B);                          
C:if(m>I-M|m<M-I)d=98;                         
  m=m+I?m:-D(24-k,-I,I,0,S,S,1);    
 }                                             
 return m+=m<e;                                
}







void chess()
{
   int  k=8;
   int  score, i;
   char sbuf[50], sbuf2[50];
   char oboard[129];
   char oldto, oldEPSQ;
   char cstring[20];

 K=8;
 W(K--)
 {
   b[K]=(b[K+112]=o[K+24]+8)+8;
   b[K+16]=18;b[K+96]=9;
   L=8;
   W(L--) b[16*L+K+8]=(K-4)*(K-4)+(L-3.5)*(L-3.5); 
 }                                                   

 W(1)                                                
 {
   N=-1;
   W(++N<121) {                      // print board
     sprintf(sbuf, " %c",N&8&&(N+=7)?10:n[b[N]&15]);          
     Serial.print(sbuf);
   }   
   
                                     // read input line    
  i = 0;       
  strcpy(cstring,"");
  do   {
       while (Serial.available()==0);       
       cstring[i] = Serial.read();     
       if(cstring[i]==13) {
         cstring[i]=0;
         break;
       }
       else i++;
  } while(i < 10);
  
   
   
   
   K=I;      
   
   if(cstring[0]!=0) {                                   /* parse entered move */
       K= cstring[0]-16*cstring[1]+C;
       L= cstring[2]-16*cstring[3]+C;
   }   
 
   Serial.print("\n DEBUG cstring : "); Serial.println(cstring);
   sprintf(sbuf,"\n DEBUG K: %d  \n DEBUG L: %d \n",  K, L);
   Serial.print(sbuf);
   
   k^= D(k,-I,I,Q,O,8,2)-I ? 0 : 24;
 }
}
 
 
 
 
 
 


void setup() {
   Serial.begin(9600);   
}



void loop() {   
   chess();
   
   while(1); 
}

HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

some tests by a German user:
http://www.roboternetz.de/community/thr ... post608206
Mxt wrote:So, ich bins wieder. 8-)

Die Sache hat mir keine Ruhe gelassen. Ich habe also auch noch meinen Due gesucht und jetzt mit vier Programmen getestet.

Folgende Erkenntnisse:

1) Die im ersten Posting genannten Züge White d2d4 und Black a7a6 akzeptiert nur die PC-Version. Bei Due und beiden Beaglebone Programmen kommt bei a7a6 ein Score 15.

2) Wenn ich die Windows Version mit Leeren Eingaben füttere und die dort berechneten Züge in die drei ARM Programme eingebe, dann funktionieren die. Auch auf dem Due. Ich habe aber keine ganze Partie gespielt, nur ein Dutzend Züge.

3) Alle Programme scheinen immer die selben Züge zu wählen, wenn man sie neu startet und nur leere Eingaben macht. Aber jede Version andere. Der PC beginnt immer mit d2-d4, der Due ( Arduino 1.5.8 ) immer mit f2-f3, BBB g++ mit e2-e3 und BBB Clang mit b1-c3.

Schlussfolgerung: Hier ist "undefined behavior" im Spiel, zumindest bei den drei ARM-Versionen. Da werden irgendwo Sprachkonstrukte verwendet, die nicht wirklich erlaubt sind und wahrscheinlich auf dem PC und er 8-Bit Plattform zufällig funktionieren.

Danach zu suchen macht sicher Arbeit, da wäre ein guter Debugger hilfreich.

I already tried to contact Harm Geert Muller but unfortunately can't find a valid email contact address... :(
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

as all reported runtime execution errors occur repeatedly just on ARM-Cortex-MCUs by either compiler (CLang, gpp, Sketch),
and nowhere else
(no Windows XP 32bit PC, no Windows 7 64bit PC, no 8 bit AVR),
and additionally there are no compiler errors or warnings for Windows and/or AVR:
My guess is: it's probably a ARM-Cortex-Hardware-construction-/ design-error !


Is anyone able to test the code on ARM 9 EV3 by gpp?
and possibly on ARM 7 NXT by nxtOSEK or by NxOS?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: false code execution depending on platform

Post by HaWe »

testing char vs. endianess:

Code: Select all

void setup() {
Serial.begin(9600);
}

void loop() {
char i, sbuf[20];

i=-10;
sprintf(sbuf, "\n%d\n", i);
Serial.println(sbuf);

sprintf(sbuf, "\n%d\n", *(int *)"abcd");
Serial.println(sbuf);

while(1);
}
Mega:
-10 // unsigned char !! changing: no effects
25185 // << what is this ?

Due:
246 // signed char !! changing: no effects
1684234849 // << what is this ?
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests