#define FORWARD extern
#define noire  0
#define rouge  1
#define verte  2  
#define jaune  3  
#define bleue  4  
#define rose  5  
#define cyane  6  
#define blanc  7  

#define fh  11    
#define fb  10    
#define fd   9   
#define fg   8    
#define del 16  
#define clr   127   
#define esc   27   

#define eCLIC 0x01
#define eCLAV 0x02

#define ecrtab(y,x)  (*(tableau+x)=y) 

#undef NULL
#define NULL ((void *)0)

#define ALLOUER(a,b)   ((a *)AllocMem(sizeof(a),b))
#define CREER(v,t,m)   (v=(struct t *)AllocMem(sizeof(struct t),m))
#define LIBERER(x,t)    FreeMem((char *)x,sizeof(struct t))
#define abs(x)         (x>=0)?x:-x

FORWARD void action();
FORWARD extern void action_bis();

extern void aficar();
extern void afilig();
extern void afiimage();
extern BOOL keypress();
extern LONG cconin();
extern void attente();
extern void lecture();
extern void efface();
extern void effecr();
extern void efffen();
extern void pass80();
extern void pass40();
extern void restore();
extern void crefen();
extern void exitMachine();
extern BOOL initMachine();
extern void trait();
extern void fencoul();
extern int random();
extern void delay();
extern char upcase();
extern void prelig();
extern void saisie();
extern void bell();
extern void musbon();
extern void musmoyen();
extern void musmauvais();
extern void musfin();
extern void musiq();
extern int  egal();
extern void commen();
extern void initJeu();
extern void exitJeu();
extern void initCharge();

extern int errno;

typedef struct Chaine
  {int len; 
   char c[256]; } CHAINE;
extern CHAINE fconcat();
extern CHAINE cconcat();
extern CHAINE fcopy();
extern int fpos();
extern void fdelete();
extern void finsert();
extern void fcinsert();
extern CHAINE atoch();
extern CHAINE ctoch();
extern BOOL idem();

#define concat(a,b,c) fconcat(a,&(b),c)
#define copy(a,b,c) fcopy(&(a),b,c)
#define pos(a,b) fpos(a,&(b))
#define delete(a,b,c) fdelete(&(a),b,c)
#define insert(a,b,c) finsert(a,&(b),c)
#define cinsert(a,b,c) fcinsert(a,&(b),c)
#define length(x) ((x).len)

#define chr(x) ((char)x)
#define ord(x) ((int)x)

extern int  a,i,j,k,touche,code,note;
extern int  mousex,mousey,amousex,amousey,deltax,deltay;

extern UBYTE *tableau ;
extern  int   variable[] ;

extern LONG adr_retour;
extern LONG adresse ;
extern LONG pointe,pointer,n,memeoire,kar;
extern int  hauteur,posx,posy, typecr,c_fond,c_forme,c_over;
extern CHAINE buflig,bufsais,reponse;
extern BOOL cadre, souli, c_deux, musicok,sortie;
extern int  numfen,nbfen,ptrfen;
extern int max,compteur,curse;
extern char ch;
extern int clicx,clicy;
extern int evenmt;
extern CHAINE vide;
         
extern LONG tabadr[];
extern int  pttab;

extern int a_base,  zone,px,py,lg,c1,memo;
extern LONG a_champ;
extern int pageLivre,maxpageLivre, a_pageLivre[11];


unsigned char  soluti[10][10],repons[10][10];
/*#define litab(x) ((int)*(tableau+x))*/
int litab(x)
LONG x;
{
return((int)*(tableau+x));
}

void filtre()
{
int i;
 for (i =1;i<=length(bufsais);i++)
 switch( bufsais.c[i] ) 
{
 case 33:
 case 34:
 case 35:
 case 36:
 case 37:
 case 38:
 case 40:
 case 41:
 case 42:
 case 43:
 case 44:
 case 46:
 case 47:
 case 58:
 case 59:
 case 60:
 case 61:
 case 62:
 case 63:
 case 64:
 case 91:
 case 92:
 case 93:
 case 94:
 case 95:
 case 96:
 case 123:
 case 124:
 case 125:
 case 126:
 case 127: bufsais.c[i] =' '; break;
 default:if (bufsais.c[i]>64 && bufsais.c[i]<91 )
         bufsais.c[i] =bufsais.c[i]+32; break;
 }
 while ( (length(bufsais)>0) && (bufsais.c[1]==' '))delete(bufsais,1,1);
 while ( (length(bufsais)>0) && (bufsais.c[length(bufsais)]==' '))
  delete(bufsais,length(bufsais),1);
 while ( pos("can't",bufsais) >0 )
  {
   i =pos("can't",bufsais);delete(bufsais,i,5);
   bufsais =cconcat(bufsais,' ');insert("cannot",bufsais,i);
  }
 while ( pos("n't",bufsais) >0 )
  {
   i =pos("n't",bufsais);delete(bufsais,i,3);
   bufsais =cconcat(bufsais,' ');insert(" not",bufsais,i);
  }
 while ( pos("  ",bufsais)>0) delete(bufsais,pos("  ",bufsais),1);
}
void afiecran(pointe)
LONG pointe;
{
int  memo,ii,nb,oct,ll;
int nombre ;
 memo =typecr;cadre =FALSE;souli =FALSE;
 switch( litab(pointe) & 63 ) {
  case 0 :  nombre =24*80;ll =80;hauteur =8;if (memo!=80 ) pass80();
                                                        else effecr();break;
  case 1 :  nombre =24*40;ll =40;hauteur =8;if (memo!=40 ) pass40(); break;
  case 2 :  nombre =16*40;ll =40;hauteur =12;if (memo!=40 ) pass40();break; 
 }
 if (typecr==40 ) effecr();
 pointe =pointe+3;posx =0;posy =0;
 nb =0;
 for (ii =1;ii<=nombre;ii++)
  {
   if (nb==0 )
    do {
     oct =litab(pointe);pointe =pointe+1;
     if (oct==1 )
      {
       c_fond =litab(pointe) % 16;
       c_forme =litab(pointe) / 16;
       pointe =pointe+1;
      }
    } while( oct==1);
   else oct =32;
   if (oct==0 ) { oct =32;nb =litab(pointe);pointe =pointe+1;}
   if (nb!=0 ) nb =nb-1;
   if (oct>127L ) { oct =oct-128;souli =TRUE;} else souli =FALSE;
   if ((oct!=32) || (souli) || (c_fond!=4) ) aficar(oct);
   else { posx =(posx+1) % ll; if (posx==0 ) posy =posy+hauteur; }
  }
 for (ii =1;ii<=litab(pointe);ii++)
  { afiimage(pointe+1);
        pointe =pointe+litab(pointe+2)*256+litab(pointe+3);}
 attente();
 if (memo!=typecr )
  if (memo==40 ) pass40(); else pass80();
 else effecr();
 adr_retour =0;
}




 void afitexteLivre()
{
int   a_image ;
int   nb,pos ;
int   l_image,h_image;
BOOL   sort ;
  c_deux =FALSE;souli =FALSE;cadre =FALSE;sort =FALSE;pos =0;hauteur =10;
  if (litab(a_pageLivre[pageLivre])==0 )
   {
    a_image =
        litab(a_pageLivre[pageLivre]+1)*256+litab(a_pageLivre[pageLivre]+2);
    pointe =a_pageLivre[pageLivre]+3;
    l_image =litab(a_image+5);h_image =litab(a_image+6);
    if (l_image<28 ) ecrtab(0,a_image+3);
    else ecrtab((40-l_image)/ 2,a_image+3);
    action(a_image);
    if (l_image<28 )
     {
      if (typecr==80 ) l_image =l_image*2;
      while ( (pos<h_image) && ! sort )
       {
        prelig(typecr-l_image-1);afilig(&(buflig.c[1]),l_image+1,pos,cyane,jaune);
        if (litab(pointe-1)==0 ) sort =TRUE;
        pos =pos+hauteur;
       }
     }
    else pos =h_image+1 ;
   }
  else pointe =a_pageLivre[pageLivre]+3;
  while ( (pos < 161) && ! sort )
   {
    prelig(typecr);afilig(&(buflig.c[1]),0,pos,cyane,jaune);
    if (litab(pointe-1)==0 ) sort =TRUE;
    pos =pos+hauteur;
   }
  trait(0,169,8*typecr-1,169,blanc);
}

 void aficommandeLivre()
 {
int toto;
  efffen(0,170,8*typecr,30);souli =FALSE;hauteur =8;
  if (pageLivre>1 )
   {
    cadre =TRUE;afilig("\006",1+(typecr-40)/ 2,177,rose,rose);
    cadre =FALSE;afilig("page pr\026c\026dente",
                           3+(typecr-40)/ 2,177,rose,rose);
   }
  if (pageLivre<maxpageLivre )
   {
    cadre =TRUE;afilig("\007",1+(typecr-40)/ 2,188,rose,rose);
    cadre =FALSE;afilig("page suivante",3+(typecr-40)/ 2,188,rose,rose);
   }
toto=litab(adresse+1);
  if (toto>0 )
   {
    cadre =TRUE;afilig("D",20+(typecr-40)/ 2,173,rose,rose);
    cadre =FALSE;
    afilig("dictionnaire",22+(typecr-40)/ 2,173,rose,rose);
    cadre =TRUE;
    afilig("F",20+(typecr-40)/ 2,182,rose,rose);
    cadre =FALSE;
    afilig("fin",22+(typecr-40)/ 2,182,rose,rose);
    cadre =TRUE;
    afilig("I",20+(typecr-40)/ 2,191,rose,rose);
    cadre =FALSE;
    afilig("impression",22+(typecr-40)/ 2,191,rose,rose);
   }
  else
   {
    cadre =TRUE;afilig("F",20+(typecr-40)/ 2,178,rose,rose);
    cadre =FALSE;afilig("fin",22+(typecr-40)/ 2,178,rose,rose);
    cadre =TRUE;afilig("I",20+(typecr-40)/ 2,188,rose,rose);
    cadre =FALSE;
    afilig("impression",22+(typecr-40)/ 2,188,rose,rose);
   }
 }

 void afipageLivre()
 {
  effecr();afitexteLivre();aficommandeLivre();
 }


 void impressionLivre()
 {
   FILE *lst;
   int i,j;
  efffen(0,170,8*typecr,30);

  if(lst=fopen("prt:","w"))
   if(ferror(lst))
   {
       afilig("Imprimante non prete...",8+(typecr-40)/ 2,180,blanc,blanc);
       attente();
   } 
   else
   {
       i=errno;
       afilig("Impression en cours...",9+(typecr-40)/ 2,180,blanc,blanc);
       for (j =1;j<=maxpageLivre;j++)
       {
         if (litab(a_pageLivre[j])==0 ) pointe =a_pageLivre[j]+3;
         else pointe =a_pageLivre[j];
         do {
              prelig(60);fprintf(lst,"%s","        ");
              for (i =1;i<=length(buflig);i++)
                  { ch =buflig.c[i];
                      if (! (ch==91||ch==93||ch==123||ch==125))
                               fprintf(lst,"%c",ch);}
              aputc('\n',lst);
            } while( litab(pointe-1)!=0);
        aputc('\n',lst);aputc('\n',lst);
    }
    aputc('\f',lst);
    close(lst);
  }
  aficommandeLivre();
}

void dictionnaireLivre(adresse)
LONG adresse;
{
 int apointe,suivant,i;
 BOOL loup,reussi ;
  loup =FALSE;
  do {
   efffen(0,170,8*typecr,30);
   afilig("Quel mot ?",0,180,blanc,blanc);
   bufsais=vide;saisie(11,180,23,TRUE);
   reussi =FALSE ;
   if (idem(bufsais,vide) || (ch==esc) ) { aficommandeLivre();loup =TRUE;}
   if (! loup )
   {
    bufsais =concat("/",bufsais,"/");
    for (i =1;i<=litab(adresse+1);i++)
     {
      pointe =1+litab(adresse+2*i)*256+litab(adresse+1+2*i);
      apointe =(int)pointe;suivant =0;
      do {
       pointe =apointe+suivant;apointe =(int)pointe;
       pointe =pointe+2;
       suivant =litab(pointe-2)*256+litab(pointe-1);
       pointe =pointe+1;
       prelig(253);buflig =concat("/",buflig,"/");
      } while(!( suivant==0 || pos(&(bufsais.c[1]),buflig)>0 ));
      if (pos(&(bufsais.c[1]),buflig)>0 )
       {
        reussi =TRUE;
        if (litab(pointe)==0 )
         {
          action(litab(pointe+1)*256+litab(pointe+2));afitexteLivre();
         }
        else
         {
          pointe =pointe+1;
          efffen(0,170,320,30);prelig(typecr);
          if (litab(pointe-1)!=0 )
           { afilig(&(buflig.c[1]),0,172,blanc,blanc);prelig(typecr);
           afilig(&(buflig.c[1]),0,182,blanc,blanc);}
          else afilig(&(buflig.c[1]),0,176,blanc,blanc);
          attente();
         }
       }
     }
    if (! reussi )
     {
      efffen(0,170,320,30);
      afilig("Comment !?!",14+(typecr-40)/ 2,180,blanc,blanc);
      attente();
     }
   }
  } while(! loup);
 }

void livre(adresse) 
LONG adresse;
{
BOOL fin ;
int  i,j;

 if (litab(adresse)==5 ) { pass40();c_fond =bleue;}
 else { pass80();c_fond =0;}
 maxpageLivre =litab(adresse+2+2*litab(adresse+1));
 a_pageLivre[1] =(int)adresse+3+2*litab(adresse+1);
 for (i =2;i<=maxpageLivre;i++)
  {
  j =1;
   if (litab(a_pageLivre[i-1])==0 ) j =j+2;
   while ( litab(a_pageLivre[i-1]+j)!=0)j =j+1;
   a_pageLivre[i] =a_pageLivre[i-1]+j+1;
  } 
 fin =FALSE;pageLivre =1;afipageLivre();
 do {
  do lecture(); while(evenmt!=eCLAV); ch =upcase(ch);
  switch( ch ) {
int toto;
   case 'D': toto=litab(adresse+1);
             if (toto>0 ) dictionnaireLivre(adresse);
                  else bell(); break;
   case 'I': impressionLivre(); CloseWorkBench(); break;
   case 'F': fin =TRUE;break;
   case fh :  pageLivre =pageLivre-1;if (pageLivre==0 ) 
                            { pageLivre =1;bell();}
                                     else afipageLivre();break;
   case fb :  pageLivre =pageLivre+1;if (pageLivre==maxpageLivre+1 )
                            { pageLivre =maxpageLivre;bell();}
                           else afipageLivre();break;
   default :bell();break;
  }
 } while(! fin);
 adr_retour =0;
}
void qcm(adresse )
LONG adresse;
{
BOOL  change,fin;
int  rep,nbrpos,maxpoint,minpoint,ligne,j;
int  sort,a_esc,apointe;
int  point[6];
 fin =FALSE;
 pass40();
 nbrpos =litab(adresse+4);
  a_esc =litab(adresse+1)*256+litab(adresse+2);
  change =TRUE;maxpoint =0;minpoint =255;
 do {
  do {
   if (change )
    {
     pointe =adresse+6;effecr();souli =FALSE;ligne =20+(4-nbrpos)*hauteur;
     do {
      prelig(typecr);afilig(&(buflig.c[1]),0,ligne,blanc,cyane);ligne =ligne+hauteur+4;
      } while( litab(pointe-1)!=0);
     ligne =ligne+6;
     for (j =1;j<=nbrpos;j ++)
      {
       cadre =TRUE;buflig =ctoch((char)(48+j));
       afilig(&(buflig.c[1]),2,ligne,rose,rose);
       cadre =FALSE;
       point[j] =litab(pointe+1)-48 ;
       if (maxpoint<point[j] ) maxpoint =point[j];
       if (minpoint>point[j] ) minpoint =point[j];
       pointe =pointe+2 ;
       do {
        prelig(typecr-4);afilig(&(buflig.c[1]),4,ligne,blanc,cyane);
        ligne =ligne+hauteur+4;
       } while( litab(pointe-1)!=0);
      }
     trait(0,159,8*typecr-1,159,blanc);
     apointe =(int)pointe;
    }
   efffen(0,160,8*typecr,40);
   afilig("Tapez votre choix ?",15+(typecr-40)/ 2,172,rose,rose);
   change =FALSE;pointe =apointe;
   do {
    do lecture(); while(evenmt!=eCLAV);ch =upcase(ch);
   } while(!( (ch==esc) || ( (ch>48) && (ch<49+nbrpos) ) )  );
   if (ch!=esc )
    {
     rep =ch-48;
     if (point[rep]==maxpoint ) musbon();
     else if (point[rep]==minpoint ) musmauvais(); else musmoyen() ;
     variable[litab(adresse+3)*2] =variable[litab(adresse+3)*2]
                                     +point[rep];
     variable[litab(adresse+3)*2+1] =variable[litab(adresse+3)*2+1]
                                       +maxpoint ;
     j =1;while ( j<rep){ pointe =pointe+litab(pointe)+1;j =j+1; }
     if (litab(pointe)==0 )
      {
       action(litab(pointe+1)*256+litab(pointe+2));
       pointe =pointe+3;change =TRUE;
      }
     else
      {
       pointe =pointe+1;efffen(0,160,8*typecr,40);prelig(typecr);
       afilig(&(buflig.c[1]),0,172,rose,rose);
       if (litab(pointe-1)!=0 )
        { prelig(typecr);afilig(&(buflig.c[1]),0,172+hauteur,rose,rose);}
       attente();
      }
     j =rep;sort =(int)pointe;
     while ( j<litab(adresse+4) )
      {
       if (litab(pointe)==0 ) sort =sort+3;
                            else sort =sort+litab(sort)+1;
       j =j+1;
      }
     sort =sort+3*(rep-1);
     change =(litab(sort+1)*256+litab(sort+2)!=0);
     if (litab(sort)==1 )
      { adr_retour =litab(sort+1)*256+litab(sort+2);fin =TRUE;}
     if (! fin ) action(litab(sort+1)*256+litab(sort+2));
    }
  } while(!( (ch==esc) || fin));
  if (! fin ) action(a_esc);change =(a_esc!=0);
 } while(! fin);
}

void caraword (a,b )
int a,b;
{
UBYTE i;
 buflig=ctoch(chr(repons[a][b]));
i=repons[a][b];
if (i>(UBYTE)127 ) 
  {
    buflig=ctoch(chr((int)i-128));
    buflig=concat("[",buflig,"]");
}
 afilig(&(buflig.c[1]),b,1+a*9,cyane,jaune);
 trait(b*8,a*9,b*8,8+a*9,cyane);
 trait(b*8,a*9,7+b*8,a*9,cyane);
}

void initword(taille,adresse)
int taille;
LONG adresse;
{
int i,j;
CHAINE chiffres;
chiffres=atoch("123456789");
 hauteur=8;effecr();pointe=adresse+4+taille*taille;
 j=6;
 while ( j<(taille+1)*9+5 )
  {
   prelig(38-taille);afilig(&(buflig.c[1]),taille+2,j,jaune,rouge);j=j+9;
   if (litab(pointe-1)==64 ) j=j+5;
  }
 while ( (j<193) && (litab(pointe-1)!=0) )
  {
   prelig(40);afilig(&(buflig.c[1]),0,j,jaune,rouge);j=j+9;
   if (litab(pointe-1)==64 ) j=j+5;
  }
 for(i=1;i<=taille;i++)for(j=1;j<=taille;j++)caraword(i,j);
 buflig=copy(chiffres,1,taille);
 afilig(&(buflig.c[1]),1,0,blanc,blanc);
 for(i=1;i<=taille;i++){ buflig=ctoch(chr(64+i));
                         afilig(&(buflig.c[1]),0,1+9*i,blanc,blanc)
                       ;}
 trait(8*(taille+1),9,8*(taille+1),9+9*taille,cyane);
 trait(8,9+9*taille,8*(taille+1),9+9*taille,cyane);
}

BOOL veriword(taille)
int taille;
{
int cpt,i,j;
 cpt=0;
 for(i=1;i<=taille;i++)
   for(j=1;j<=taille;j++)
  { 
    unsigned char k; 
    k=repons[i][j];
    if (k!=(UBYTE)32 && k!=(UBYTE)127 ) cpt=cpt+1;
  }
 if (cpt<30 ) bell();
 else
  for(i=1;i<=taille;i++)
   for(j=1;j<=taille;j++)
    {
    unsigned char k; 
     k=repons[i][j];
 if (k==soluti[i][j] && k!=(UBYTE)127)
     { repons[i][j]=k+(UBYTE)128;caraword(i,j);}
    }
 for(i=1;i<=taille;i++)
  for(j=1;j<=taille;j++)
   {
   unsigned char k; 
   k=repons[i][j];
  if (k<(UBYTE)127 ) return(FALSE);
   }
return(TRUE);
}

void croises(adresse)
LONG adresse;
{
int  aide,i,j,k,ligne,colonne,help,taille ;
BOOL  fin,gagne;
int  a_esc;
int cursword[8];

 cursword[0]=0;cursword[1]=124;cursword[2]=124;cursword[3]=124;
 cursword[4]=124;cursword[5]=124;cursword[6]=0;cursword[7]=0;
 taille=litab(adresse+3);a_esc=litab(adresse+1)*256+litab(adresse+2);
 pointe=adresse+4;gagne=TRUE;
 for(i=1;i<=taille;i++)
  for(j=1;j<=taille;j++)
   {
    unsigned char k;
    k=(unsigned char)litab(pointe);
    soluti[i][j]=k;repons[i][j]=k;
    if (k!=(UBYTE)127 ) repons[i][j]=(UBYTE)32;
    pointe=pointe+1;
   }
 ligne=1;colonne=1;
while ( soluti[ligne][colonne]==(UBYTE)127)colonne=colonne+1;
 help=0;fin=FALSE;initword(taille,adresse);
do 
{
 /*getword*/
 buflig=ctoch(chr(repons[ligne][colonne]));c_fond=jaune;
 afilig(&(buflig.c[1]),colonne,1+ligne*9,bleue,bleue);c_fond=bleue;
 do lecture(); while(evenmt!=eCLAV);if (ch>64 && ch<91) ch=chr(ord(ch)+32);
 caraword(ligne,colonne);

 switch (ch ) 
 {
    case 1  : 
          help=help+1;if (help>3 ) help=3;
          fin=veriword(taille);
           for( aide=1;aide<=help;aide++)
           { 
                 /* helpword*/
              BOOL sort;
              if (! fin )
              {
                sort=FALSE;
                i=random(taille)+1;j=random(taille)+1;
                do 
                {unsigned char k;
                 k=repons[i][j];
                    if (k<(UBYTE)127 && k!=soluti[i][j] )
                    { repons[i][j]=soluti[i][j]+(UBYTE)128;
                      caraword(i,j);sort=TRUE;}
                    else
                     if (j<taille ) j=j+1;
                        else { j=1;if (i<taille ) i=i+1; else i=1;}
                }
                while (! ( sort));
               }
             fin=veriword(taille);
             }
             break; 
    case 6  : gagne=FALSE;
             {int i,j; 
              for(i=1;i<=9;i++) for(j=1;j<=9;j++)repons[i][j]=soluti[i][j];}
             fin=veriword(taille);fin=TRUE; break; 
   case 20 : fin=veriword(taille); break; 
   case esc : { action(a_esc);initword(taille,adresse);} break; 
   case fg  : if (colonne!=1 ) colonne=colonne-1; else bell(); break; 
   case fd  : if (colonne!=taille ) colonne=colonne+1; else bell(); break; 
   case fh  : if (ligne!=1 ) ligne=ligne-1; else bell(); break; 
   case fb  : if (ligne!=taille ) ligne=ligne+1; else bell(); break; 
   case  28:  case 29: case 30: case 31: case 32: case 97: case  98:
   case  99:  case  100: case  101: case  102: case  103: case  104:
   case  105: case  106: case  107: case  108: case  109: case  110: 
   case  111: case  112: case  113: case  114: case  115: case  116: 
   case  117: case  118: case  119: case  120: case  121: case  122:
        if (repons[ligne][colonne]<(UBYTE)127 )
                    {
                     repons[ligne][colonne]=(UBYTE)ch;caraword(ligne,colonne);
                     if (colonne!=taille ) colonne=colonne+1; 
                     else colonne=taille-1;
                    }
         else bell(); break;
   default : bell();
  }
 }
 while (!  fin);
 if (gagne )
  {
   efffen((taille+2)*8,0,320-(taille+2)*8,200);
   efffen(0,2+(taille+1)*9,320,198-(taille+1)*9);
   buflig=atoch("BRAVO!");afilig(&(buflig.c[1]),13,80,blanc,blanc);musfin();
  }
 attente();
 adr_retour=0;
}


void prepexoPhrase(adresse)
LONG adresse;
{
 efffen(0,0,8*typecr,52);
 trait(0,0,0,51,jaune);trait(0,51,8*typecr-1,51,jaune);
 trait(8*typecr-1,51,8*typecr-1,0,jaune);
 pointe =adresse+15;
 prelig(typecr);while ( length(buflig)<typecr) buflig =concat(" ",buflig," ");
 if (length(buflig)>typecr ) buflig =copy (buflig,1,typecr);
 hauteur =12;c_fond =jaune;c_deux =TRUE;afilig(&(buflig.c[1]),0,0,bleue,bleue);
  c_fond =bleue;c_deux =FALSE;hauteur =10;
 pointe =pointe+1;prelig(typecr-2);afilig(&(buflig.c[1]),1,20,cyane,verte);
 if (litab(pointe-1)!=0 ) { prelig(typecr-2);
                              afilig(&(buflig.c[1]),1,32,cyane,verte);}
 while ( litab(pointe-1)!=0) pointe =pointe+1;
}

void afiphrase(apointe,ph)
int apointe;
int ph;
{
int i;
 pointe =apointe;
 for (i =1;i<=ph*2;i++)pointe =pointe+litab(pointe)+1;
 efffen(0,52,8*typecr,148);pointe =pointe+1;prelig(typecr);
  afilig(&(buflig.c[1]),0,58,rose,verte);
 if (litab(pointe-1)!=0 ) { prelig(typecr);
  afilig(&(buflig.c[1]),0,68,rose,verte);}
}

void phrase(adresse)
LONG adresse;
{
BOOL  memexo[128];
int  apointe,i,finboucle;
int ph,pointexo,nbrpos,chance,nbr;
BOOL loup;

 action(litab(adresse+1)*256+litab(adresse+2));loup =FALSE;
 do {
  pass40();
 for(i=0;i<=127L;i++) memexo[i] =FALSE;
  pointexo =0;nbrpos =litab(adresse+5);
  prepexoPhrase(adresse);apointe =(int)pointe;
finboucle=litab(adresse+6);
  for (nbr =1;nbr<=finboucle;nbr++)
   {
 do { ph =random(nbrpos);} while(memexo[ph]);
 memexo[ph]=TRUE;
  afiphrase(apointe,ph);chance =litab(adresse+4);
    do {
     efffen(0,86,8*typecr,114);afilig(">",0,86,cyane,cyane);
     bufsais=vide;curse =0;
     do {
      saisie(2,86,60,FALSE);
      if (ch==esc )
       {
        action(litab(adresse+1)*256+litab(adresse+2));
        prepexoPhrase(adresse);afiphrase(apointe,ph);
	buflig=atoch(">");afilig(&(buflig.c[1]),0,86,cyane,cyane);
       }
     ;} while( ch==esc);
     pointe =apointe;

{
int i;
CHAINE chaine;
 for (i =1;i<=ph*2+1;i++)pointe =pointe+litab(pointe)+1;
 pointe =pointe+1;prelig(80);
 chaine =bufsais;bufsais =buflig;filtre();buflig =bufsais;bufsais =chaine;
}
     switch( egal() ) {
      case 0 :  pointexo =pointexo+chance;chance =0;commen(0,120);break;
      case 1 : 
           commen(0,120);
           afilig("mais attention aux erreurs de frappe !!!",
                (typecr-40)/ 2,135,rose,rose);
           afilig("Il fallait r\026pondre :",
                    9+(typecr-40)/ 2,144,rose,rose);
           pointe =apointe;
           for (i =1;i<=ph*2+1;i++)pointe =pointe+litab(pointe)+1;
           pointe =pointe+1;prelig(typecr);
           afilig(&(buflig.c[1]),(typecr-length(buflig))/ 2,160,jaune,verte);
           if (litab(pointe-1)!=0 )
            { prelig(typecr);
                  afilig(&(buflig.c[1]),(typecr-length(buflig))/ 2,170,jaune,verte);}
           pointexo =pointexo+chance;chance =0;break;
      case 2 : 
           chance =chance-1;
           if (chance>0 ) commen(2,120);
           else
            {
             afilig("Il fallait r\026pondre :",
                  9+(typecr-40)/ 2,144,rose,rose);
             pointe =apointe;
             for (i =1;i<=ph*2+1;i++)pointe =pointe+litab(pointe)+1;
             pointe =pointe+1;prelig(typecr);
             afilig(&(buflig.c[1]),(typecr-length(buflig))/ 2,160,jaune,verte);
             if (litab(pointe-1)!=0 )
              { prelig(typecr);
                    afilig(&(buflig.c[1]),(typecr-length(buflig))/ 2,170,jaune,verte);
              }
             commen(1,120);break;
          }
     }
     attente();
    } while( chance!=0);
   }
  variable[litab(adresse+3)*2] =variable[litab(adresse+3)*2]+pointexo;
  variable[litab(adresse+3)*2+1] =variable[litab(adresse+3)*2+1]
                                    +litab(adresse+4)*litab(adresse+6);
  pointe =adresse+7;
  if (pointexo>=litab(pointe) ) pointe =pointe+3;
  pointe =pointe+1;
  if (litab(pointe)==1 )
   { adr_retour =litab(pointe+1)*256+litab(pointe+2);loup =TRUE;}
  else
   action(litab(pointe+1)*256+litab(pointe+2));
 } while(! loup);
}

void evaluation(adresse)
LONG adresse;
{
char  seuil,utilise  ;
int  i,j,moyenne,ligne,pr ;
CHAINE   nbre;
int   exec;
BOOL  sort ;
LONG  a_sortie[5] ;

 sort =FALSE;
 pass40();
 for (i =0;i<=4;i++)
  if (variable[2*i+1]!=0 )
   variable[2*i] =(variable[2*i]*20) / variable[2*i+1];
 moyenne =0;utilise =0;pr =50;
 for (i =1;i<=4;i++)
  if (variable[2*i+1]!=0 )
   { moyenne =moyenne+variable[2*i];utilise =utilise+1;pr =pr-10;}
 if (utilise>0 ) moyenne =moyenne / utilise;effecr();
   sprintf(&(nbre.c[1]),"%d",moyenne);
     nbre.len=strlen(&(nbre.c[1]));
 buflig =concat("Vous avez obtenu une note de ",nbre," sur 20");
 afilig(&(buflig.c[1]),(typecr-length(buflig)) / 2,pr,rose,rose) ;
 pointe =adresse+1; ligne =pr+20;
 for (i =1;i<=4;i++)
  {
   seuil =litab(pointe);pointe =pointe+8;
   if (variable[2*i]<seuil)
    {
     a_sortie[i] =pointe-4;pointe =pointe+litab(pointe-1)+1;
     while ( litab(pointe-1)!=0 )
      {
       prelig(typecr);afilig(&(buflig.c[1]),(typecr-length(buflig))/ 2,ligne,
                      cyane,cyane);
       ligne =ligne+hauteur+2;
      }
    }
   else
    {
     a_sortie[i] =pointe-7;
     while ( litab(pointe-1)!=0 )
      {
       prelig(typecr);
       afilig(&(buflig.c[1]),(typecr-length(buflig)) / 2,ligne,cyane,cyane);
       ligne =ligne+hauteur+2;
      }
     pointe =pointe+litab(pointe)+1;
    }
   ligne =ligne+4;
  }
 attente();
 for (i =0;i<=9;i++)variable[i] =0 ;
 for (i =1;i<=4;i++)
  {
   exec =litab(a_sortie[i]+1)*256+litab(a_sortie[i]+2);
   if (exec!=0 )
    {
     if (litab(a_sortie[i])==1 )
      { adr_retour =exec;sort =TRUE;i =4;}
     else action(exec);
    }
  }
  if (! sort ) adr_retour =0;
}

void lexical(adresse)
LONG adresse;
{
int a_esc,a_dico,a_mot,a_mot_s,a_note,a_titre,a_enonce,num,i,j,j1,k;
UBYTE  v_concern,nbre_essai,nbre_mot,l,h;
BOOL faux,loup ,trouve;
CHAINE  mot,
      chaine;

 pass40();loup =FALSE;
 do 
 {

  pointe =adresse+1;num =random(litab(pointe));
  a_dico =litab(pointe+num*2+1)*256+litab(pointe+num*2+2);
  pointe =pointe+litab(pointe)*2+1;
  a_esc =litab(pointe)*256+litab(pointe+1);
  v_concern =litab(pointe+2);nbre_essai =litab(pointe+3);
  nbre_mot =litab(pointe+4);a_note =(int)pointe+5;
  num =random(256);a_mot =a_dico+1;
  for (i =0;i<=num;i++)
   if (litab(a_mot)*256+litab(a_mot+1)==0 ) a_mot =a_dico+1;
   else a_mot =a_mot+litab(a_mot)*256+litab(a_mot+1);
  pointe =pointe+13;a_titre =(int)pointe;
  effecr();prelig(typecr);a_enonce =(int)(pointe+1);
  for (i= ((typecr-length(buflig)) / 2);i>=1;i--) 
                          buflig =concat(" ",buflig," ");
  c_fond =blanc;afilig(&(buflig.c[1]),0,0,bleue,bleue);c_fond =bleue;
  pointe =pointe+1;prelig(typecr);afilig(&(buflig.c[1]),0,40,rose,rose);
  for (i =1;i<=nbre_mot;i++)
   {
  efffen(0,50,320,150);
  trouve =FALSE;
  do {
   a_mot_s =a_mot+litab(a_mot)*256+litab(a_mot+1);
   if (litab(a_mot)*256+litab(a_mot+1)==0 ) a_mot_s =a_dico+1;
   pointe =a_mot+litab(a_mot+2)+4;
   if (litab(pointe)==0 ) a_mot =a_mot_s;
   else
    {
     pointe =pointe+1;prelig(255);j1 =pos("(",buflig);k =pos(":",buflig);
     if ((j1>0) && (k>0) && (j1<k) )
      {
       delete(buflig,1,k+1);
       if (length(buflig)>25 ) a_mot =a_mot_s;
       else
        { char c;
         trouve =TRUE ; c=buflig.c[length(buflig)];
         while ( ! ( ( c>14 && c<32 ) || (c<123 && c>96) ) )
            {delete(buflig,length(buflig),1); c=buflig.c[length(buflig)];}
         buflig =concat("",buflig," :");
         mot =buflig;afilig(&(buflig.c[1]),0,50+hauteur,cyane,cyane);
        }
      }
     else a_mot =a_mot_s;
    }
  } while(!( trouve));
 

    j =0;faux =TRUE;
    while ( faux && (j!=nbre_essai) )
     {
      efffen(length(mot)*8+1,50+hauteur,320-8*length(mot),hauteur);
      efffen(0,50+2*hauteur,320,200-(50+2*hauteur));
      bufsais=vide;l =length(buflig)+1;h =50+hauteur;
      do {
       saisie(l,h,40,TRUE);
       if (ch==esc ) { action(a_esc);ch =esc;}
         } while(!( ch != esc));
      pointe =a_mot+3;prelig(255);
      chaine =buflig;
      do {
       buflig =copy(chaine,1,pos("/",chaine)-1);
       delete(chaine,1,pos("/",chaine));
        } while(!( idem(chaine,vide) || egal()<2 ));
      switch( egal() ) {
       case 0 : 
            variable[2*v_concern] =variable[2*v_concern]+nbre_essai+1-j;
            commen(0,140);attente();faux =FALSE;break;
       case 1 : 
            commen(0,100);faux =FALSE;
            afilig("mais attention aux erreurs de frappe!!!",0,124,rose,rose);
            pointe =a_mot+2+litab(a_mot+2)+2+1;prelig(40);
            afilig(&(buflig.c[1]),0,136,cyane,cyane);
            if (litab(pointe-1)!=0 )
             { prelig(40);afilig(&(buflig.c[1]),0,146,cyane,cyane); }
            attente();break;
       case 2 : 
            if (j<(nbre_essai-1) ) { commen(2,140);attente(); }
            else
             {
              commen(1,100);
              afilig("Non, rappelez-vous que :",0,124,rose,rose);
              pointe =a_mot+2+litab(a_mot+2)+2+1;prelig(40);
              afilig(&(buflig.c[1]),0,136,cyane,cyane);
              if (litab(pointe-1)!=0 )
               { prelig(40);afilig(&(buflig.c[1]),0,146,cyane,cyane);}
              attente(); break;
           }
      }
      j =j+1;
     }
    a_mot =a_mot_s;
   }
  variable[v_concern*2+1] =variable[v_concern*2+1]+nbre_essai*nbre_mot;
  if (litab(a_note)<variable[2*v_concern] )
   {
    if (litab(a_note+1)!=0 )
     { adr_retour =litab(a_note+2)*256+litab(a_note+3);loup =TRUE;}
     if (! loup ) action(litab(a_note+2)*256+litab(a_note+3));
   }
  else
   {
    if (litab(a_note+4)!=0 )
     { adr_retour =litab(a_note+5)*256+litab(a_note+6);loup =TRUE;}
     if (! loup ) action(litab(a_note+5)*256+litab(a_note+6));
   }
 } while(!( loup));
}


void action(adresse)
LONG  adresse;
{
 sortie=FALSE;
 if (adresse!=0 )
  {
   adr_retour=adresse;
   do 
   {
int toto;
toto=litab(adr_retour);
    if (toto>127L ) { afiecran(adr_retour);sortie=TRUE;}
    if (toto>63L ) { afiimage(adr_retour);sortie=TRUE;}
    adresse=adr_retour;
    if (! sortie )
    switch (litab(adresse) ) 
    {
      case 2: case 3: case 4  :  break; 
      case 5: case 6   : livre(adresse) ; break; 
      case 7: case 8   : qcm(adresse); break; 
      case 9: case 10  : phrase(adresse); break; 
      case 15    : lexical(adresse); break; 
      case 19: case 20 : evaluation(adresse); break; 
      case 21: case 22 : croises(adresse); break; 
      default:adr_retour=0; break; 
    }
   }
   while (! ( adr_retour==0 || sortie));
  }
}

void executeur()
{
int i ;
LONG    ptr ;
 nbfen=0;pass40();
 effecr();
 for(i=0;i<=255;i++)variable[i]=0 ;
 if (litab(2)*256+litab(3)!=0 )
  {int lili;
   ptr=litab(2)*256+litab(3);
   lili=litab(ptr);
   for(i=1;i<=lili;i++)
    if (litab(ptr+1)!=255 )
     { action(litab(ptr+1)*256+litab(ptr+2));
     ptr=ptr+2;}
    else
    switch (litab(ptr+2) ) {
     case  1 : {
           crefen(litab(ptr+3),litab(ptr+4),litab(ptr+5),
           litab(ptr+6));ptr=ptr+6;
          } break; 
      case 2 : { restore();ptr=ptr+2;} break; 
      case 3 : {
           if (litab(ptr+3)==0 ) { kar=cconin();ch=chr(kar); }
           else delay(litab(ptr+3)*10);
           ptr=ptr+3;
          } break; 
      case 4 : { efface(litab(ptr+3));ptr=ptr+3;} break; 
      case 5 : {
           variable[litab(ptr+3)*2]=litab(ptr+4);
           variable[litab(ptr+3)*2+1]=litab(ptr+4);
           ptr=ptr+4;
          } break; 
     }
  }
 pass40();buflig=atoch("AU REVOIR !!");
 effecr();
 afilig(&(buflig.c[1]),(40-length(buflig))/ 2,96,blanc,blanc);
 musfin();attente();sortie=FALSE;
}

char  choix()
{
int i, l, h;
 pass40();sortie=FALSE;
 souli=FALSE;cadre=FALSE;hauteur=8;
 trait(3,0,133,0,1);trait(4,1,132,1,1);trait(5,2,131,2,1);trait(6,3,130,3,1);
 trait(8,5,128,5,1);trait(9,6,127,6,1);trait(10,7,126,7,1);
 trait(12,9,124,9,1);trait(13,10,123,10,1);
 trait(15,12,121,12,1);
posx=2; posy=16; c_forme=blanc; if(c_deux) c_forme=blanc;
aficar('\0');
 afilig("\001\002\003\004\005 \012\013\014\013\015\016",3,16,blanc,blanc); buflig=vide;for(i=0;i<=5;i++)buflig=cconcat(buflig,chr(i));
 buflig=atoch("ENIGME A OXFORD");
 l=length(buflig);h=(40-l) / 2;
 afilig(&(buflig.c[1]),h,56,blanc,blanc);
 trait((h*8-8),48,((h+l)*8+8),48,1);
 trait(((h+l)*8+8),48,((h+l)*8+8),72,1);
 trait(((h+l)*8+8),72,(h*8-8),72,1);trait((h*8-8),72,(h*8-8),48,1);
 buflig=atoch("Auteur : B\026atrice FRANZI ");
 afilig(&(buflig.c[1]),15,104,verte,verte);
 trait(0,123,319,123,1);
 buflig=atoch("Quel \026pisode voulez-vous \026tudier ?");
 afilig(&(buflig.c[1]),0,144,blanc,blanc);
 buflig=atoch("Tapez votre choix \0501 \030 4\051 : ");
 afilig(&(buflig.c[1]),7,160,rouge,rouge);
 do {
  do lecture(); while(evenmt!=eCLAV); if (ch==esc )  sortie=TRUE;
 }
 while (! ( (ch>48 && ch<53) || sortie));
 return(ch);
}



