Réversi en C++ pour Apple ][ GS (1988)

#include "ptoc.h"



/*uses QDIntf,GSIntf,MiscTools,ConsoleIO;    */

const integer xmin = 10;
const integer ymin = 5;
const integer xmax = 314;
const integer ymax = 165;
const integer prof_niv1 = 1;
const integer prof_niv2 = 2;
const integer prof_niv3 = 3;
const integer prof_niv4 = 4;
const integer mode_agressif = 1;
const integer mode_normal = 2;
const integer mode_defensif = 4;
     const integer coef_coup = 10;

     const integer stattext = 15;

     const integer applemenu = 300;  
      const integer aboutitem = 301;

     const integer filemenu = 400;
      const integer newitem = 401;
      const integer loaditem = 402; 
      const integer saveitem = 403;
      const integer quititem = 404;

     const integer editmenu = 500;
       const integer undoitem = 505;
       const integer cutitem = 501;
       const integer copyitem = 502;
       const integer pastitem = 503;
       const integer clearitem = 504;

     const integer optionsmenu = 600;
             const integer reflexionitem = 601;
             const integer joueuritem = 602;  

enum etat {noir,blanc,rien, last_etat};
typedef matrix<0,9,0,9,etat> tableau;
struct coup_file {  
               point position;
               etat couleur;
}; 
typedef array<1,60,coup_file> partie;  

matrix<1,8,1,8,longint> val;
etat ordi,joueur;
integer prof;
array<0,2,integer> pion;
etat joueur_actif;
tableau table;
partie jeu;
integer coup;
boolean beep, redessine, demo, possible;
integer mode, njoueur;

integer mymemoryid; 
handle toolszeropage;   
boolean done; 

str255 applemenustr;   
str255 filemenustr;
str255 editmenustr;
str255 optionsmenustr;
newwindowparamblk mywind; 
windowptr mywindptr;


void startupgstools()
{
        tooltable toolrec;
        integer svtoolerrornum;
        integer btn;

   tlstartup;          
   mymemoryid = mmstartup;      
   mtstartup;          
   toolszeropage =
       newhandle(8 * 256,mymemoryid,fixedbank+pagealigned+fixedblk+locked,ptr(0));
   qdstartup(loword(toolszeropage),$80,160,mymemoryid);        
   emstartup(loword(toolszeropage)+$300,20,0,640,0,200,mymemoryid);        
   setbackcolor(0);
   setforecolor(15);
   moveto(40,40);
   drawstring("Un instant, svp...");
   toolrec.numtools = 10;
   toolrec.tools[1].tsnum = 4;      
   toolrec.tools[1].minversion = 1;
   toolrec.tools[2].tsnum = 5;      
   toolrec.tools[2].minversion = 1;
   toolrec.tools[3].tsnum = 6;      
   toolrec.tools[3].minversion = 1;
   toolrec.tools[4].tsnum = 14;    
   toolrec.tools[4].minversion = 0;
   toolrec.tools[5].tsnum = 15;    
   toolrec.tools[5].minversion = 1;
   toolrec.tools[6].tsnum = 16;    
   toolrec.tools[6].minversion = 1;
   toolrec.tools[7].tsnum = 21;    
   toolrec.tools[7].minversion = 0;
   toolrec.tools[8].tsnum = 20;    
   toolrec.tools[8].minversion = 0;
   toolrec.tools[9].tsnum = 22;    
   toolrec.tools[9].minversion = 0;
   toolrec.tools[10].tsnum = 23;    
   toolrec.tools[10].minversion  = 0;
   do {
      loadtools(toolrec);    
      svtoolerrornum = toolerrornum;
      if (svtoolerrornum != 0)  {
         btn = tlmountvolume
                   (100,40,"Erreur chargement outils","Inserer le disque systeme","Ok","Annuler");
                        if (btn != 1)  sysfailmgr(svtoolerrornum,"Unable to load tools");
      }
   } while (!(svtoolerrornum == 0));
   windstartup(mymemoryid);      
   refreshdesktop(nil);
   ctlstartup(mymemoryid,loword(toolszeropage)+$400);
   menustartup(mymemoryid,loword(toolszeropage)+$500);
   scrapstartup;
   lestartup(mymemoryid,loword(toolszeropage)+$600);
   dialogstartup(mymemoryid);
   sfstartup(mymemoryid,loword(toolszeropage)+$700);
   deskstartup;
} 

void shutdowngstools()
{
   grafoff;
   deskshutdown;
   sfshutdown;
   dialogshutdown;
   leshutdown;
   scrapshutdown;
   menushutdown;
   windshutdown;
   ctlshutdown;
   emshutdown;
   qdshutdown;
   mtshutdown;
   mmshutdown(mymemoryid);
   tlshutdown;
} 

void setupmenus()
{
        integer height;

   applemenustr = concat(">>@\\XN300\\0",
                           "==About REVERSI...\\N301\\0",
                           "==-\\N302D\\0..");
   filemenustr  =  concat(">>  File  \\N400\\0",
                        "==New Game\\N401*Nn\\0",
                        "==Load Game\\N402*Ll\\0",
                        "==Save Game\\N403*Ss\\0",
                           "==Quit\\N404*Qq\\0.");
   editmenustr  =  concat(">>  Edit  \\N500\\0",
                           "==Undo\\N505D*ZzV\\0",
                           "==Cut\\N501D*Xx\\0",
                           "==Copy\\N502D*Cc\\0",
                           "==Paste\\N503D*Vv\\0",
                           "==Clear\\N504D\\0.");
        optionsmenustr = concat (">> Options  \\N600\\0",
                                "==Reflexion\\N601*Rr\\0",
                                "==Joueur\\N602*Jj\\0.");
   setmtitlestart(10);
   /*InsertMenu(NewMenu(@OptionsMenuStr[1]),0);
   InsertMenu(NewMenu(@EditMenuStr[1]),0);  
   InsertMenu(NewMenu(@FileMenuStr[1]),0);  
   InsertMenu(NewMenu(@AppleMenuStr[1]),0);  
   FixAppleMenu(AppleMenu);      */
        height = fixmenubar;      
   drawmenubar;          
   prof =prof_niv1;
   ordi = blanc;
   joueur = noir;
        mode = mode_normal;
   demo = false;
        njoueur = 1;
}

void joueur_suivant(etat& joueur1)
{
   if (joueur1==noir)  joueur1=blanc; else joueur1=noir;
}

void init_table()
{
   integer i,j;
   longint v;
   set bord,bord_moins,milieu;   

   bord =set::of(1,8, eos);
   bord_moins =set::of(2,7, eos);   
   milieu =set::of(4,5, eos);
   for( i=0; i <= 9; i ++) for( j=0; j <= 9; j ++) table[i][j] = rien;
   table[4][4]=blanc; table[5][5]=blanc;
   table[4][5]=noir;  table[5][4]=noir;
   coup = 0;
   for( i=1; i <= 8; i ++) for( j=1; j <= 8; j ++) {
        v=1;
        if (bord.has(i))  v=v+199;  /* bords verticaux et horizontaux */
        if (bord.has(j))  v=v+199;
        if (v==399)  v=5000;            /* coins */
        if ((bord_moins.has(i)) && (bord.has(j)))  v=-100;    /* cases proches des coins */
        if ((bord_moins.has(j)) && (bord.has(i)))  v=-100;
        if ((bord_moins.has(j)) && (bord_moins.has(i)))  v=-500;
        if ((milieu.has(i)) && (milieu.has(j)))  v=5;    /* cases du milieu */
        val[i][j] = v;
   }  
   joueur_actif = noir;
   pion[1] =2;    /* pion blanc */
   pion[0] =2;  /* pion noir */
   pion[2] = 60;  /* pion restant */
   redessine = true;
}      /* Init_Table */

void enregistre (integer nombre,integer i,integer j)
{
        integer n_joueur_actif,n_autre_joueur;

        coup = coup+1;
   {
      coup_file& with = jeu[coup];  
      with.position.v=j;
      with.position.h=i;
      with.couleur = joueur_actif;
   }
    table[i][j] = joueur_actif;   
    n_joueur_actif = ord(joueur_actif);
    pion[n_joueur_actif]=pion[n_joueur_actif]+nombre+1;
    pion[2]=pion[2]-1;
    joueur_suivant(joueur_actif);
    n_autre_joueur=ord(joueur_actif);
    pion[n_autre_joueur]=pion[n_autre_joueur]-nombre;
}     /* enregistre */    

void retourne (integer i,integer j, boolean genre,longint& nombre,boolean coef)
/* genre = true : retourne le coup joue */
/* genre = false : cherche les possible */
{
   integer a,b,u,v,k,l;
   boolean flag;

        nombre=0;
        possible=false;
        if (table[i][j]==rien)  
                for( u=-1; u <= 1; u ++) for( v=-1; v <= 1; v ++) 
                   if ((table[i+u][j+v]!=rien) && (table[i+u][j+v]!=joueur_actif))  {
                switch (v) {
                           case -1 : a=j-1; break;
                           case 0  : a=8; break;
                           case 1  : a =8-j; break;
                        }     /* case u */;
                        switch (u) {
                           case -1 : b=i-1; break;
                           case 0  : b=8; break;
                           case 1  : b=8-i; break;
                        }      /* case v */                    
                        k=2;
                        flag=true;
                      while (flag && (k<=a) && (k<=b))  {
                        if (table [i+u*k][j+v*k]==joueur_actif)  { 
                                        possible=true;
                                flag =false;  
                        }
                         if (genre && ! flag)  
                            for( l=1; l <= k-1; l ++) {
                                table[i+u*l][j+v*l]=joueur_actif;
                                if (! coef)  nombre=nombre+1;
                                else nombre =nombre + val[i+u*l][j+v*l];
                            }  
                         if (table [i+u*k][j+v*k]==rien)  flag=false;
                        k=k+1;
                      }      /* while */
                   }  
}     /* retourne */              

void cherche_possible()
/* teste si le joueur actif peut jouer */
{
   integer i,j;
   longint n;

        i=1; j=1;
        do {
           retourne (i,j,false,n,false);   
           i=i+1;
           if (i==9)  {
                i=1;
                j=j+1;
           }
        } while (!((j==9) || possible));
}     

void couleur (etat etat1)
{
        void couleur_result;
        if (etat1==noir)  couleur_result="noir"; else couleur_result="blanc";
        return couleur_result;
}

/*$LongGlobals+*/
void actualise()
{
   const integer vert = 10;
   const integer noiro = 0;
        rect r;
        integer i,j;
        integer pasx, pasy;
        dialogptr dlog;
        integer itemhit;
        string message,coo,coul;

   startdrawing (mywindptr);
   setrect(r,xmin,ymin,xmax,ymax);
   pasx =(xmax-xmin) / 8;
   pasy =(ymax-ymin) / 8;
   if (redessine)  {          /* dessine plateau */
        redessine = false;
      setsolidpenpat(vert);
      paintrect(r);
      setpensize (3,2);
      setforecolor(noiro);
      setsolidpenpat(noiro);    
      for( i=0; i <= 8; i ++) {
         moveto (xmin,ymin+i*pasy);
         lineto (xmax,ymin+i*pasy);
         moveto (xmin+i*pasx,ymin);
         lineto (xmin+i*pasx,ymax);   
      }
   }     /* if */   
   setpensize(1,1);   
   for( i=1; i <= 8; i ++) for( j=1; j <= 8; j ++) { 
      if (table[i][j]!=rien)  {
         setrect (r,xmin+(i-1)*pasx+3,ymin+(j-1)*pasy+2,xmin+i*pasx,ymin+j*pasy);
         setsolidpenpat(3*ord(table[i][j]));
         paintoval(r);
      }
   }
   moveto (xmax+30,ymin+10);
   drawstring (concat("Blanc :  ",inttostring(pion[ord(blanc)]),"  "));
   moveto (xmax+30,ymin+40);
   drawstring (concat("Noir :  ",inttostring(pion[ord(noir)]),"  "));
        moveto (xmax+20,ymin+120);
        if (! (coup==0))  {
           coo = concat(chr(64+jeu[coup].position.h),inttostring(jeu[coup].position.v),"   ");
                coul = couleur (jeu[coup].couleur);  
                drawstring (concat(coul," a joue : ",coo));
   }    
   cherche_possible();
   if (! possible)  {
        joueur_suivant (joueur_actif);
        cherche_possible();
   }  
   if (possible)  {
        moveto (xmax+20,ymin+140);
           coul = couleur (joueur_actif);
           drawstring (concat (coul," joue   "));  
   }
   else {      /* fin */
        if (pion[ord(blanc)]>pion[ord(noir)])  {
           pion[ord(blanc)]=pion[ord(blanc)]+pion[ord(rien)];
           message="Les blancs gagnent";
        }    
        else if (pion[ord(blanc)]==pion[ord(noir)])  message ="Egalite";
           else {
                        pion[ord(noir)]=pion[ord(noir)]+pion[ord(rien)];
                        message="les noirs gagnent";
                }  
           moveto (xmax+30,ymin+10);
        drawstring (concat("Blanc :  ",inttostring(pion[ord(blanc)]),"  "));
           moveto (xmax+30,ymin+40);
           drawstring (concat("Noir :  ",inttostring(pion[ord(noir)]),"  "));
      setrect(r,xmax+80,ymin+130,xmax+240,ymin+170);
           dlog = newmodaldialog(r,true,0);
        setport(dlog);  
           setforecolor(0);
        setbackcolor(15);
        moveto(10,10);
      drawstring(message);
           setrect(r,40,20,90,35);
        /*NewDItem(Dlog,1,r,10,@'Ok',0,0,nil);*/
      itemhit = modaldialog(nil);
           closedialog(dlog);
           init_table();
           actualise();
        }   
}    /* actualise */
/*$LongGlobals-*/

boolean certain (str255 message)
{
        dialogptr dlog;
        rect r;
        integer item;

   boolean certain_result;
   setrect(r,xmax+30,ymin+130,xmax+310,ymin+170);
        dlog = newmodaldialog(r,true,0);
   setport(dlog);  
        setforecolor(0);
   setbackcolor(15);
   moveto(10,10);
   drawstring(message);
        setrect(r,50,20,100,35);
   /*NewDItem(Dlog,2,r,10,@'Ok',0,0,nil);*/
   setrect(r,150,20,200,35);
   /*NewDItem(Dlog,1,r,10,@'Non',0,0,nil);*/
   item = modaldialog(nil);
        closedialog(dlog);
        certain_result = (item==2);
        redessine = true;
   return certain_result;
}



void save_game()
{
        integer i;
   file<coup_file> donnees;
   coup_file donnee0;
   string fichier;
   replyrecord reponse;

        sfputfile (30,25,"Entrez le nom","Untitled.Rev",15,reponse);
        if (reponse.good)  {
                donnee0.position.v = coup;
                donnee0.position.h = 0;
                donnee0.couleur = rien;
                fichier = concat ("0/",reponse.filename);
                if ((pos(".Rev",fichier)==0) && (length(fichier)<14))  fichier =concat (fichier, ".Rev");
                rewrite (donnees,fichier);
                donnees << donnee0;
                for( i = 1; i <= coup; i ++)  donnees << jeu[i];
                close (donnees);
        }
        redessine=true;
}

void load_game()
{
        integer i;
   file<coup_file> donnees;
   coup_file donnee0;
   longint nombre;
   replyrecord reponse;
   string fichier;
   typelistrec listedetype;

        listedetype.numentries = 1;
        listedetype.filetype1 =0;
        /*SFGetFile (30,45,'Quelle partie ?',nil,@ListeDeType,reponse);*/
        if ((reponse.good) & (pos(".Rev",reponse.filename)!=0))  {
                fichier = concat("0/",reponse.filename);
                reset (donnees,fichier);
                donnees >> donnee0;
                init_table();
                for( i=1; i <= donnee0.position.v; i ++) {
                        donnees >> jeu[i];
                        retourne (jeu[i].position.h,jeu[i].position.v,true,nombre,false);
                   enregistre (nombre,jeu[i].position.h,jeu[i].position.v);
                }
                actualise();
                close (donnees);
        }
        redessine = true;            
}

void eval_coup  (integer prof,integer& iok,integer& jok)
{
        integer save_prof;
   etat joueur_save;
   tableau table_save;
   integer i,i2,j,j2;
   longint ncoup,ncoup2,n,n2,nmax;

        void eval_coup_result;
        ncoup =0;                /* sauvegarde de l'etat */
   ncoup2 =0;
   nmax = -maxlongint;
   joueur_save = joueur_actif;
   save_prof = prof;
        table_save = table;

   for( i=1; i <= 8; i ++) for( j =1; j <= 8; j ++) {
        n = 0;
      retourne (i,j,true,n,true);     /* joue si poss en (i,j) et calcul n avec coefs */
        if (possible)  {
                ncoup = ncoup+1;
                table [i][j] = joueur_actif;
                        n = n+val[i][j];
                        if (! (joueur_actif==ordi))  n=mode*n; else n=n*mode_normal;
                if (prof!=0)  {
                        joueur_suivant (joueur_actif);
                        n = n-eval_coup(prof-1,i2,j2);
              }
                if (n>nmax)  {
                   nmax =n;
                        iok = i;
                        jok = j;      
                }
                else if ((n==nmax) && (random>=0))  {
                   nmax =n;
                        iok = i;
                        jok = j;      
                }
        }  
           table = table_save;
      joueur_actif=joueur_save;
      prof = save_prof;
   }     
   if (ncoup==0)  {
                nmax =-maxlongint / 10;      /* passe son tour */
                if (! (joueur_actif==ordi))  nmax=mode*nmax; else nmax=mode_normal*nmax;
           if (! (prof==0))  {     
                        joueur_suivant(joueur_actif);
                        nmax = nmax+eval_coup(prof-1,i2,j2);
                }
        }  
   joueur_actif=joueur_save;
   eval_coup_result = nmax+coef_coup*ncoup;  
        return eval_coup_result;
}      /* eval_coup */           


void ordinateur()
{
   integer i,j;
   longint n;
   longint addr;
   struct {
                integer cursorheight;
                integer cursorwidth;
                matrix<1,8,1,3,integer> data;
                matrix<1,8,1,3,integer> mask;
                point hotspot;
   } cursor;

                           {
            /*addr := Ord4(@data);
      StuffHex(addr,     '0000FF000000');
      StuffHex(addr+6,     '0000FF000000');
      StuffHex(addr+12,  '0000FF000000');
      StuffHex(addr+18,  'FFFFFFFFFF00');
      StuffHex(addr+24,  'FFFFFFFFFF00');
      StuffHex(addr+30,  '0000FF000000');
      StuffHex(addr+36,  '0000FF000000');
      StuffHex(addr+42,  '0000FF000000');
      StuffHex(addr+48,  '000000000000');
      StuffHex(addr+54,  '000000000000');
      StuffHex(addr+60,  '000000000000');
      StuffHex(addr+66,  '000000000000');
      StuffHex(addr+72,  '000000000000');
      StuffHex(addr+78,  '000000000000');
      StuffHex(addr+84,  '000000000000');
      StuffHex(addr+90,  '000000000000');*/
            cursor.hotspot.h = 5;
            cursor.hotspot.v = 4;
            cursor.cursorheight = 8;
            cursor.cursorwidth  = 3;
            }
        /*SetCursor(@Cursor);*/
        cherche_possible();
        if (possible)  {
                n=eval_coup(prof,i,j);
                retourne (i,j,true,n,false);
                enregistre(n,i,j);
                actualise();
        }
        else {
           joueur_suivant(joueur_actif);  
           actualise();
        }
        initcursor;
        if (beep)  sysbeep;   
}

void setupwindows()
{
                  {
      param_length = sizeof_(newwindowparamblk);
      wframe     = $2020;
      wtitle     = nil;
      wrefcon     = 0;
      wzoom.top  = 0;
      wzoom.left  = 0;
      wzoom.bottom  = 0;
      wzoom.right  = 0;
      wcolor    = nil;
      wyorigin     = 0;
      wxorigin     = 0;
      wdatah     = 0;
      wdataw     = 0;
      wmaxh     = 0;
      wmaxw     = 0;
      wscrollver   = 0;
      wscrollhor   = 0;
      wpagever     = 0;
      wpagehor     = 0;
      winforefcon  = 0;
      winfoheight  = 0;
      wframedefproc= nil;
      winfodefproc = nil;
      /*wContDefProc := @actualise;*/
      wposition.top    = 20;
      wposition.left   = 95;
      wposition.bottom = 190;
      wposition.right  = 555;
      wplane     = 0;
      wstorage     = nil;
      }
   mywindptr = newwindow(mywind);
} 

void doabout()
{
        dialogptr aboutdlog;
        rect r;
        integer itemhit;

   setrect(r,112,30,542,180);
   aboutdlog = newmodaldialog(r,true,0);
   setport(aboutdlog);
   setrect(r,180,125,230,140);
   /*NewDItem(aboutDlog,1,r,10,@'Ok',0,0,nil);*/
   setforecolor(0);
   setbackcolor(15);
   moveto(10,10);
   drawstring("REVERSI v 7.0");
   moveto(10,30);
   drawstring("Ce logiciel est en Shareware, si vous decidez de le garder");
   moveto(10,40);
   drawstring("veuillez m'envoyer 100F.");
   moveto(20,55);
   drawstring("M. GUYOT Emmanuel");
   moveto(20,65);
   drawstring("547 Rue de Latingy");
   moveto(20,75);
   drawstring("45430 MARDIE");
   moveto(20,85);
   drawstring("FRANCE");
   moveto(10,100);
   drawstring("Copyright 1988 TML Systems,Inc. Certain parts of this");
   moveto(10,110);
   drawstring("software copyright by TML System,Inc.");
   showwindow (aboutdlog);
   selectwindow (aboutdlog);
   itemhit = modaldialog(nil);
   closedialog(aboutdlog);
   redessine = true;
} 

void joueurdialogue()
{
        rect r;
        dialogptr dlg;
        integer item,m;

        setrect (r,160,50,410,150);
        dlg = newmodaldialog (r,false,0);
        setrect (r,10,10,110,20);
        if (njoueur==1)  m=1; else m=0;
        /*NewDitem (dlg,3,r,RadioItem,@'Un Joueur',m,1,nil);*/
        offsetrect (r,0,20);
        if (njoueur==2)  m=1; else m=0;
        /*NewDitem (dlg,4,r,RadioItem,@'Deux Joueurs',m,1,nil);*/
        offsetrect (r,0,20);
        if (njoueur==0)  m=1; else m=0;
        /*NewDitem (dlg,5,r,RadioItem,@'Demo',m,1,nil);*/
        setrect (r,10,80,110,95);
        /*NewDitem (dlg,2,r,ButtonItem,@'Annuler',0,0,nil);*/
        setrect (r,140,10,240,20);
        /*NewDitem (dlg,99,r,StatText+ItemDisable,@'Votre couleur',0,0,nil);*/
        setrect (r,150,30,230,40);
        if (joueur==blanc)  m=1; else m=0;
        /*NewDitem (dlg,6,r,RadioItem,@'Blanc',m,2,nil);*/
        offsetrect (r,0,20);
        if (joueur==noir)  m=1; else m=0;
        /*NewDitem (dlg,7,r,RadioItem,@'Noir',m,2,nil);*/
        setrect (r,150,80,230,95);
        /*NewDitem (dlg,1,r,ButtonItem,@'Ok',0,0,nil);*/

        showwindow (dlg);
        selectwindow (dlg);
        do {
                if (getditemvalue (dlg,5)==1)  m=255; else m=0;
                hilitecontrol (m,getcontrolditem(dlg,6));
                hilitecontrol (m,getcontrolditem(dlg,7));
                item = modaldialog (nil);
                if (item>2)  setditemvalue (1,dlg,item);
        } while (!(item<=2));
        if (item==1)  {
                if (getditemvalue(dlg,3)==1)  {
                        demo = false;
                        njoueur = 1;
                        if (getditemvalue (dlg,6)==1)  {
                                ordi=noir;
                                joueur = blanc;
                        }
                        else {
                                ordi=blanc;
                                joueur=noir;
                        }
                }
                if (getditemvalue(dlg,4)==1)  {
                        demo=false;
                        njoueur=2;
                        ordi = rien;
                }
                if (getditemvalue (dlg,5)==1)  {
                        demo=true;
                        njoueur=0;
                        ordi=joueur_actif;
                }
        }
        closedialog (dlg);
        redessine=true;
}

void reflexiondialogue()
{
        rect r;
        dialogptr dlg;
        integer niv,m,item;

        setrect (r,160,50,410,170);
        dlg = newmodaldialog (r,false,0);
        setrect (r,10,10,110,20);
        if (prof==prof_niv1)  niv=1; else niv=0;
        /*NewDitem (dlg,3,r,RadioItem,@'Niveau 1',niv,1,nil);*/
        offsetrect (r,0,20);
        if (prof==prof_niv2)  niv=1; else niv=0;
/*  NewDitem (dlg,4,r,RadioItem,@'Niveau 2',niv,1,nil);*/
        offsetrect (r,0,20);
        if (prof==prof_niv3)  niv=1; else niv=0;
/*  NewDitem (dlg,5,r,RadioItem,@'Niveau 3',niv,1,nil);*/
        offsetrect (r,0,20);
        if (prof==prof_niv4)  niv=1; else niv=0;
/*  NewDitem (dlg,6,r,RadioItem,@'Niveau 4',niv,1,nil);*/
        setrect (r,10,100,110,115);
/*  NewDitem (dlg,2,r,ButtonItem,@'Annuler',0,0,nil);*/
        setrect (r,140,10,230,20);
        if (mode==mode_agressif)  m=1; else m=0;
/*  NewDItem (dlg,7,r,RadioItem,@'Agressif',m,2,nil);*/
        offsetrect (r,0,20);
        if (mode==mode_normal)  m=1; else m=0;
/*  NewDItem (dlg,8,r,RadioItem,@'Normal',m,2,nil);*/
        offsetrect (r,0,20);
        if (mode==mode_defensif)  m=1; else m=0;
/*  NewDItem (dlg,9,r,RadioItem,@'Defensif',m,2,nil);*/
        offsetrect (r,0,20);
        if (beep)  m=1; else m=0;
/*  NewDItem (dlg,10,r,CheckItem,@'Bip',m,0,nil);*/
        setrect (r,140,100,230,115);
/*  NewDitem (dlg,1,r,ButtonItem,@'Ok',0,0,nil);*/
        showwindow (dlg);
        selectwindow (dlg);
        do {
                item = modaldialog (nil);
                if (item==10)  
                        if (getditemvalue (dlg,item)==0) 
                                setditemvalue(1,dlg,item);
                        else setditemvalue (0,dlg,item);
                else
                        if (item>2) 
                                setditemvalue (1,dlg,item);  
        } while (!(item<=2));
        if (item==1)  {
                beep = (getditemvalue(dlg,10)==1);
                if (getditemvalue (dlg,3)==1)  prof=prof_niv1;
                if (getditemvalue (dlg,4)==1)  prof=prof_niv2;
                if (getditemvalue (dlg,5)==1)  prof=prof_niv3;
                if (getditemvalue (dlg,6)==1)  prof=prof_niv4;
                if (getditemvalue (dlg,7)==1)  mode=mode_agressif;
                if (getditemvalue (dlg,8)==1)  mode=mode_normal;
                if (getditemvalue (dlg,9)==1)  mode=mode_defensif;
        }
        closedialog (dlg);
        redessine = true;
}  


void processmenu(longint codeword)
{
        integer itemnum;
        longint addr;
        integer save_coup,i;
        longint nombre;

   itemnum = loword(codeword);
   switch  (itemnum)  {
        case undoitem : {
                        save_coup=coup-1;
                        init_table();
                        for( i=1; i <= save_coup; i ++) {
                                coup_file& with = jeu[i];  
                                joueur_actif = with.couleur;
                                retourne (with.position.h,with.position.v,true,nombre,false);
                                enregistre (nombre,with.position.h,with.position.v);
                                                        }
                        actualise();
                }
                break;      
      case aboutitem:
         doabout();
         break;
      case quititem:
         done = certain ("Voulez-vous vraiment quitter ?");
         break;
      case newitem : if (certain ("Voulez-vous vraiment recommencer ?"))  { 
                                init_table();
                                actualise();
                         }
                         break;
      case reflexionitem : reflexiondialogue(); break;
      case joueuritem : joueurdialogue(); break;
      case saveitem : save_game(); break;
      case loaditem : load_game(); break;      
   }  
   hilitemenu(false,hiword (codeword));
} 

void checkmenus()
{
   if (bitand(getwkind(frontwindow),$8000) != 0)  {
      enablemitem(cutitem);
      enablemitem(copyitem);
      enablemitem(pastitem);
      enablemitem(clearitem);
      redessine=true;
      }
   else {
      disablemitem(cutitem);
      disablemitem(copyitem);
      disablemitem(pastitem);
      disablemitem(clearitem);
      }
} 

void valide()
{
   integer i,j;
   longint nombre;
   point pt;

   startdrawing (mywindptr);
   getmouse (pt);
   if ((pt.v>ymin) && (pt.v<ymax) && (pt.h<xmax) && (pt.h>xmin))  {
      i=1+(pt.h-xmin) / ((xmax-xmin) / 8);
      j=1+(pt.v-ymin) / ((ymax-ymin) / 8);
      if (table[i][j]==rien)  {
         retourne (i,j,true,nombre,false);
         if (possible)  {
                enregistre(nombre,i,j);
                actualise();
        }
        else sysbeep;   
        }
        else sysbeep;      
   }   
}

void maineventloop()
{
        eventrecord event;
        integer code;

   event.taskmask = $1fff;  
   done  = false;
   do {
        if (ordi==joueur_actif)  ordinateur();
        if (demo)  {
                actualise();
                joueur_suivant (ordi);  
        }
      checkmenus();
                if (coup==0)  disablemitem(undoitem); else enablemitem (undoitem);
      code = taskmaster(-1, event);
      switch (code) {
                 case winmenubar: processmenu(event.taskdata); break;
                 case wincontent: valide(); break;  
     }
   } while (!done);
} 

int main(int argc, const char* argv[])
{
   pio_initialize(argc, argv);
   startupgstools();
   init_table();
   showcursor;
   setupmenus();
   setupwindows();
   maineventloop();
   shutdowngstools();
   return EXIT_SUCCESS;
}