     VMR PROGRAMMING CONTEST - RandomVectors

    A hacker should be able to read code as well as write it.

    Examine the following function and describe in moderate detail
    what it does.  Give also a description of the probable nature
    of the rest of the program.  The most accurate analysis of
    accurate analysis of acceptable detail will win a floppy disk,
    a copy of the beta version of the complete program, and a free
    subscription to !~Frequency One~!

    This contest does not apply to people who have already seen the
    rest of the code, or it's compiled result.




lstruct randomvectors(lstruct l)
{
   /*  Note:  I don't know really how this function works
              exactly.  It was given to me in a dream by the
              Goddess Eris, She of the Obscure and Unreadable
              Code (among other things).
   */
   int p[80][4]; //points[x, {x,y,lifetime,dir}]
   int np, flag;  //activepoints, num arrows.
   int i,j,k,r,s,x, nxp, nyp, cxp, cyp, nokay, factor;
   int d[9][2];  //dirs
   int ds[4];
   int okay[4], sokay[4];

   ds[0]=UP; ds[1]=LEFT; ds[2]=DOWN; ds[3]=RIGHT;
   d[DOWN][0]=0; d[DOWN][1]=1; d[LEFT][0]=-1; d[LEFT][1]=0;
   d[UP][0]=0; d[UP][1]=-1; d[RIGHT][0]=1; d[RIGHT][1]=0;
   for (i=0; i<33; i++) for (j=0; j<21; j++) l.arrows[i][j]=0;
   for (i=0; i<80; i++) p[i][2]=0;
   np=1;
   p[0][0]=3; p[0][1]=10; p[0][2]=1; p[0][3]=3;
   flag=1;

   while (np>0 && flag){
      flag=0;
      for (i=0; i<np; i++) if (p[i][2]) {
            flag=-11;  s=0;
            nxp=p[i][0]+d[ds[p[i][3]]][0];
            nyp=p[i][1]+d[ds[p[i][3]]][1];
            if (l.arrows[nxp][nyp] || nxp<1 || nyp<1 || nxp>30
           || nyp>18 || (!(rand()%3) && p[i][2]>3) ) {
               for (j=0; j<4; j++) {
                  okay[j]=1; sokay[j]=0;
                  if (j==(p[i][3]+2)%4 || (p[i][0]+d[ds[j]][0]>30
                 && d[ds[j]][0]) || (p[i][0]+d[ds[j]][0]<2 && d[ds[j]][0])
                 || (p[i][1]+d[ds[j]][1]>18 && d[ds[j]][1])
                 || (p[i][1]+d[ds[j]][1]<2  && d[ds[j]][1]))
                     okay[j]=0;
                  else {
                     cxp=p[i][0]+d[ds[j]][0]; cyp=p[i][1]+d[ds[j]][1];
                     while (cxp+1>0 && cyp+1>0 && cxp<33 && cyp<21) {
                        if (l.arrows[cxp][cyp]) {okay[j]=0; break;}
                        cxp+=d[ds[j]][0]; cyp+=d[ds[j]][1];
                     }
                     if (!okay[j] && (( ((j+2)%4) & l.arrows[cxp][cyp])
                    || (((j+2)%4)*16) & l.arrows[cxp][cyp] )) {
                        if (rand()%25) {
                           for (k=0; k<4; k++) okay[k]=0;
                           s=6; if (l.arrows[nxp][nyp] || nxp<1 ||
                          nyp<1 || nxp>30 || nyp>18) s=5;
                           break;
                        } else okay[j]=1;
                     }
                  }
               } //checked all the directions now for branching.
               nokay=0;
               for (j=0; j<4; j++) if (okay[j]) nokay++;
               k=0;
               for (j=0; j<4; j++) {
                  if (okay[j]) { sokay[k]=j; k++; }
               }
               for (j=0; j<4; j++) okay[j]=0;
               if (nokay==1 && sokay[0]==p[i][3]){ s=6; nokay=0; }
               if (!nokay) {
                if (s<6){
                  l.arrows[p[i][0]][p[i][1]]=0;
                  p[i][2]=0;
                  np--;
                  setcolor(15);
                  circle(p[i][0]*20,p[i][1]*20,6);
                }
               } else {
                l.arrows[p[i][0]][p[i][1]]=ds[(p[i][3]+2)%4]*16;
                                                  //_DIR=DIR * 16
                  do k=rand()%nokay; while (sokay[k]==p[i][3]);
                  okay[k]=-1;    //indicates we've picked it already.
                  s=k;
                  for (x=0; x<nokay-1; x++) if (rand()%(4-x)) {
                     while (okay[k]) k=rand()%nokay;
                     okay[k]=-1;
                            r=0;
                      //next we do a 'newpoint()' put it inline.r=0;
                     while (r<80 && p[r][2]) r++;
                     if (!p[r][2]) {
                        p[r][0]=p[i][0]+d[ds[sokay[k]]][0];
                        p[r][1]=p[i][1]+d[ds[sokay[k]]][1];
                        p[r][2]=1;
                        p[r][3]=sokay[k];
                        np++;
                     }
                     l.arrows[p[i][0]][p[i][1]]+=ds[sokay[k]];
                  }
                  k=s;
                  p[i][3]=sokay[k];   //new dir for this point.
                  p[i][2]=1;
                  l.arrows[p[i][0]][p[i][1]]+=ds[sokay[k]];
                  p[i][0]=p[i][0]+d[ds[p[i][3]]][0];
                  p[i][1]=p[i][1]+d[ds[p[i][3]]][1];
               }
            } else {
               p[i][2]+=1;
               p[i][0]+=d[ds[p[i][3]]][0];
               p[i][1]+=d[ds[p[i][3]]][1];
               setcolor(i%16);
               circle(p[i][0]*20,p[i][1]*20,3);
               circle(p[i][0]*20,p[i][1]*20,2);
               circle(p[i][0]*20,p[i][1]*20,4);
            }
         if (j==6) i--;     //if we want to keep going and can.
      }
      delay(DTIME/2);
   }
   i=1;
   while (!l.arrows[i][10]) {
      while (!l.arrows[i][10]) i++;
      if (l.arrows[i][10] & LEFT) l.arrows[i][10]=0;
   }  //get rid of starting obstacles.
   delay(50);
   return(l);
}
