#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAX_GRID 8
#define DURATION 4

int movenpick(int turn, int x1, int y1);
void print_map(int x, int y);

void print_map(int x, int y)
{
 int i, j;
 printf("\nFind the Hidden Submarine: Written by Prof. Joseph Ng\nOcean Map\n\n ");
 for (i = 0; i < MAX_GRID; i++) printf(" %d", i); printf("\n");
 for (i = 0; i < MAX_GRID; i++){
     printf("%d", i);
     for (j = 0; j < MAX_GRID; j++){
         if ((i == y) && (j == x)) printf(" D"); else printf(" .");
     }
     printf("\n");
 }
 printf("\n\n\nMessage:\n");
}

int movenpick(int turn, int x1, int y1)
{
 static int x0, y0;
 int deltax1, deltax2, deltay1, deltay2;
 int sqdistance, deltaxsq, deltaysq;
 int move_dir;

 if (turn == 0){ /* generate a submarine on the 8X8 Grid */
    do{
       x0 = rand()%MAX_GRID;
       y0 = rand()%MAX_GRID;
    }while ((x1 == x0) && (y1 == y0));
 }

 printf("DEBUG>Submarine at X = %d   Y = %d\n", x0, y0);

 if ((x0 == x1) && (y0 == y1)) return 0; /* hit */

 if (turn % DURATION == 0){ /* submarine move */
    move_dir = rand()%9+1;
    printf("DEBUG>Submarine move at direction %d\n", move_dir);
    switch (move_dir){
      case 7: x0 = (x0 + MAX_GRID - 1) % MAX_GRID;
      case 8: y0 = (y0 + MAX_GRID - 1) % MAX_GRID; break;
      case 9: y0 = (y0 + MAX_GRID - 1) % MAX_GRID;
      case 6: x0 = (x0 + MAX_GRID + 1) % MAX_GRID; break;
      case 3: x0 = (x0 + MAX_GRID + 1) % MAX_GRID;
      case 2: y0 = (y0 + MAX_GRID + 1) % MAX_GRID; break;
      case 1: y0 = (y0 + MAX_GRID + 1) % MAX_GRID;
      case 4: x0 = (x0 + MAX_GRID - 1) % MAX_GRID; break;
      case 5: break;
     default: printf("Illegal movement: %d\n", move_dir); break;
    }
    printf("DEBUG>Submarine now at X = %d   Y = %d\n", x0, y0);
 }else printf("\n\n");

 if (x0 > x1){ deltax1 = x0 - x1; deltax2 = x1 + MAX_GRID - x0; }
    else{ deltax1 = x1 - x0; deltax2 = x0 + MAX_GRID - x1; }
 if (deltax1 > deltax2) deltaxsq = deltax2 * deltax2;
    else deltaxsq = deltax1 * deltax1;

 if (y0 > y1){ deltay1 = y0 - y1; deltay2 = y1 + MAX_GRID - y0; }
    else{ deltay1 = y1 - y0; deltay2 = y0 + MAX_GRID - y1; }
 if (deltay1 > deltay2) deltaysq = deltay2 * deltay2;
    else deltaysq = deltay1 * deltay1;

 sqdistance = deltaxsq + deltaysq;
 if (sqdistance <= 2) return 1; /* red alert */
 if (sqdistance <= 8) return 2; /* yellow alert */
    else return 3; /* green alert */
}

int main(int argc, char* argv[])
{
 int x, y;
 int done = 0;
 int turn = -1;
 int c, dummy, alert;

 srand(37);

 x = rand()%MAX_GRID;
 y = rand()%MAX_GRID;

 print_map(x, y);
 printf("Destroyer Start Position: X = %d   Y = %d\n", x, y);
 printf("\n\n\n\n\n\n\n");

 while (!done){
       printf("Enter Command> ");
       c = getchar(); dummy = getchar();
       switch (c){
         case 'x': printf("Exit on command. Bye!\n"); exit(0);
	 case '7': x = (x + MAX_GRID - 1) % MAX_GRID;
	 case '8': y = (y + MAX_GRID - 1) % MAX_GRID; turn++; break;
	 case '9': y = (y + MAX_GRID - 1) % MAX_GRID;
	 case '6': x = (x + MAX_GRID + 1) % MAX_GRID; turn++; break;
	 case '3': x = (x + MAX_GRID + 1) % MAX_GRID;
	 case '2': y = (y + MAX_GRID + 1) % MAX_GRID; turn++; break;
	 case '1': y = (y + MAX_GRID + 1) % MAX_GRID;
	 case '4': x = (x + MAX_GRID - 1) % MAX_GRID; turn++; break;
	 case '5': turn++; break;
	 default : printf("Illegal movement: %c\n", c); break;
       }

       print_map(x, y);
       printf("Turn:%3d Dir:%c X = %d   Y = %d\n", turn, c, x, y);

       alert = movenpick(turn, x, y);
       switch(alert){
         case 0: printf("Hit! Congratulation! End game.\n"); done = 1; break;
         case 1: printf("Red Alert!!!\n"); break;
         case 2: printf("Yellow Alert!!\n"); break;
         case 3: printf("Green Alert!\n"); break;
        default: break;
       }
       printf("\n\n\n");
 }

 return 0;
}

