// C Source File
// Created 02/02/01; 17:20:08

#define OPTIMIZE_ROM_CALLS      // Use ROM Call Optimization

#define SAVE_SCREEN             // Save/Restore LCD Contents
#include <stdlib.h>
#include <stdio.h>
#include <kbd.h>
#include <graph.h>
#include <sprites.h>

short _ti89;                    // Produce .89Z File
short _ti92plus;                // Produce .9XZ File


// prototype des fonctions :
void affiche_case(int x, int y, char *carre,int cond, ...);

// variables globales
  char buff[8];
  char tab[7][15];
  char tab_ant[7][15];

// Main Function
void _main(void)
{
  int i,j,k,l,x_ant,y_ant;
  int c;        // code de la touche
  int fin_partie = 0;
  int debut_partie = 1;
  int nb_mines=0;
  int score=0;
  static unsigned char char_g[5] = {0x37,0x38,0x7E,0x81,0x7E};  //char gauche
  static unsigned char char_d[5] = {0xEC,0x1C,0x7E,0x81,0x7E};  //char droit
  static unsigned char logo[53] =
  {0x22,0x36,0x2A,0x22,0x22,0x00,
   0x3E,0x08,0x08,0x08,0x3E,0x00,
   0x22,0x32,0x2A,0x26,0x22,0x00,
   0x3E,0x20,0x3C,0x20,0x3E,0x00,
   0x22,0x22,0x3E,0x22,0x22,0x00,
   0x22,0x22,0x22,0x22,0x1C,0x00,
   0x22,0x32,0x2A,0x26,0x22,0x00,
   0x3E,0x08,0x08,0x08,0x08,0x08,0x00,
   0x00,0x00,0x3E,0x7F};        // logo vertical MINEHUNT
  static unsigned char c_demine[8] = {0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF};
  static unsigned char c_mine[8] = {0xFF,0x81,0x99,0xBD,0xBD,0x99,0x81,0xFF};
  static unsigned char c_dest[8] = {0xFF,0xD5,0xAB,0xD5,0xAB,0xD5,0xAB,0xFF};
  static unsigned char c_perdu[8] = {0xFF,0xC3,0xA5,0x99,0x99,0xA5,0xC3,0xFF};
  static unsigned char c_gagne[8] = {0xFF,0x81,0xA5,0x81,0xA5,0x99,0x81,0xFF};
  ////////////////////////
  //AFFICHAGE DU PLATEAU//
  ////////////////////////
  clrscr();                                             // on efface l'écran
  FontSetSys (F_4x6);                                   // petite police
  Sprite8 (1, 1, 5, char_g, LCD_MEM, SPRT_XOR);         // char en haut à gauche
  Sprite8 (10+7*16, 1, 5, char_d, LCD_MEM, SPRT_XOR);   // char en haut à droite
  Sprite8 (0, 11, 53, logo, LCD_MEM, SPRT_XOR);         // logo MINEHUNT à gauche
  Sprite8 (10+7*16, 11, 53, logo, LCD_MEM, SPRT_XOR);   // logo MINEHUNT à droite
  DrawStr (17, 0, "NEAR",A_NORMAL);                     // en-tête
  DrawStr (83, 0, "SCORE:",A_NORMAL);                   // en-tête
  for (i=0;i<9;i++)                                     // affichage des lignes horizontales
        DrawLine (9, 7+7*i, 9+16*7, 7+7*i, A_NORMAL);
  for (i=0;i<17;i++)                                    // affichage des lignes verticales
        DrawLine (9+7*i, 7, 9+7*i, 7+7*8, A_NORMAL);
  affiche_case (15, 7, c_dest, FALSE);                  // on affiche la case de destination    
  /////////////////////////////
  //INITIALISATION DU PLATEAU//
  /////////////////////////////
  for (j=0;j<8;j++)
        for(i=0;i<16;i++)
                tab_ant[j][i] = tab[j][i] = 0;
  // placement des bombes //
  randomize();
  while (nb_mines<20) {                                 // nb_mines a été initialisé au début à 0
        k = random(8);
        l = random(16);
        if ( ((k+l)!=0)&&((k+l)!=22) )                  // pas de bombe en haut à gauche ni en bas à droite
                if (!tab[k][l]) {
                        tab[k][l] = 1;
                        nb_mines++;
                }
  }
  //  fin de placement  //
  i = j = 0;                                            // initialisation de la position actuelle
  ////////////////////////////
  //BOUCLE DE JEU PRINCIPALE//
  ////////////////////////////
  while (!fin_partie) {                                 // fin_partie a été initialisé à 'FALSE' au début
        x_ant = i;                                      // on mémorise la position précédente
        y_ant = j;                                      //              ""
        while ((x_ant==i)&&(y_ant==j)&&(!fin_partie)) { // on attend l'appui d'une touche
                if (debut_partie==TRUE) {               // Au début, on joue automatiquement à la case en haut à gauche
                        debut_partie=FALSE;
                        break;
                }
                c = ngetchx ();
                switch( c ) {
                        case '4':
                                i--;
                                break;
                        case '6':
                                i++;
                                break;
                        case '2':
                                j++;
                                break;
                        case '8':
                                j--;
                                break;
                        case '7':
                                i--;
                                j--;
                                break;
                        case '9':
                                i++;
                                j--;
                                break;
                        case '3':
                                i++;
                                j++;
                                break;
                        case '1':
                                i--;
                                j++;
                                break;
                        case KEY_ESC:                   // touche 'Esc'
                                fin_partie = TRUE;
                                break;
                        case KEY_F5:
                                DrawStr (0, 68, "MINEHUNT adapted from the HP48G(X) by JCOP",A_XOR);
                }// fin du switch
                if ((i<0)||(i>15)||(j<0)||(j>7)) {
                        i = x_ant;
                        j = y_ant;
                }
        }//fin du while

        if ( (i==15) && (j==7) ) {                      // partie gagnée!!
                score++;
                sprintf( buff, "%d\0", score);
                DrawStr (109, 0, buff, A_REPLACE);      // en-tête
                affiche_case( i, j, c_gagne, TRUE, x_ant, y_ant);
                DrawStr( 18, 0, "YOU MADE IT!! ", A_REPLACE);
                for ( k=0; k<8; k++ )
                        for ( l=0; l<16; l++ )
                                if ( tab[k][l] )
                                        affiche_case( l, k, c_mine, FALSE);
                fin_partie = TRUE;
                ngetchx ();                             // wait for a keypress
        }
        else if ( !tab[j][i] ) {                        // rien
                affiche_case( i, j, c_demine, TRUE, x_ant, y_ant);
                if (!tab_ant[j][i]) {                   // si cette case n'était pas encore déminée
                        tab_ant[j][i]=1;
                        score++;                        // alors on incrémente le score
                }
                nb_mines = 0;
                for ( k=max(0,j-1); k<=min(7,j+1); k++ )
                        for (l=max(0,i-1); l<=min(15,i+1); l++ )
                                if ( tab[k][l] )        // s'il y a une mine
                                        nb_mines++;
                sprintf( buff, "%d MINE%s", nb_mines, (nb_mines==1)? "  ": "S");
                DrawStr(38, 0, buff, A_REPLACE);        // en-tête
                sprintf( buff, "%d\0", score);
                DrawStr (109, 0, buff, A_REPLACE);      // en-tête                      
        }
        else {  // il y a une mine :(
                affiche_case( i, j, c_perdu, TRUE, x_ant, y_ant);
                DrawStr(17, 0, "YOU BLEW UP!! ", A_REPLACE);
                for ( k=0; k<8; k++ )
                        for ( l=0; l<16; l++ )
                                if ( tab[k][l] )
                                        if ( (k!=j)||(l!=i) )
                                                affiche_case( l, k, c_mine, FALSE);
                fin_partie = TRUE;
                ngetchx ();                             // wait for a keypress
        }
  }// fin du while
}

///////////////////////////////// affiche_case /////////////////////////////////
void affiche_case(int x, int y, char *carre, int cond, ...)
{
        static unsigned char c_vide[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        static unsigned char  c_rempli[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
        x = 9 + 7*x;
        y = 7 + 7*y;
        if (cond==1)
                Sprite8 (*(&cond+1)*7+9, *(&cond+2)*7+7, 8, c_rempli, LCD_MEM, SPRT_OR);
        Sprite8 (x, y, 8, c_vide, LCD_MEM, SPRT_AND);
        Sprite8 (x, y, 8, carre, LCD_MEM, SPRT_XOR);
}

                                /*      END     */