Grid-based Pokitto game that challenges the player to deploy ships and then destroy the hidden ships of the computer.

Dependencies:   PokittoLib

/media/uploads/RichardAmes/naval_battle_2.png

Revision:
2:b96bb2a68c81
Parent:
1:7962cd90f0b3
--- a/main.cpp	Tue Jan 02 03:23:47 2018 +0000
+++ b/main.cpp	Tue Jan 02 18:06:00 2018 +0000
@@ -220,15 +220,18 @@
 int game_state;
 int state_ctr;
 char str1[8];
+int debug0;
 int debug1;
 int debug2;
+int debug3;
 int mx;
 int my;
 int a_num;
 int a_den;
 int arc_c;
-char pgrid[10][10];
-char cgrid[10][10];
+char pgrid[GRID_SIZE][GRID_SIZE];
+char cgrid[GRID_SIZE][GRID_SIZE];
+char heatmap[GRID_SIZE][GRID_SIZE];
 int computer_playing;
 int computer_guessing;
 int computerx;
@@ -239,9 +242,12 @@
 
 void show_debug(void)
 {
+    game.display.color = 12;
+    game.display.setCursor(60, 72);
+    sprintf(str1, "%d %d", debug0, debug1);
+    game.display.print(str1);
     game.display.setCursor(60, 80);
-    game.display.color = 12;
-    sprintf(str1, "%d %d", debug1, debug2);
+    sprintf(str1, "%d %d", debug2, debug3);
     game.display.print(str1);
 }
 
@@ -465,43 +471,110 @@
    }
 }
 
-/* Indicate if gridpoint is next to hit */
-int next_to_hit(int x, int y)
-{
-    int i;
-    int j;
-    
-    for (i = -1; i <= 1; i++)
-        for (j = -1; j <= 1; j++)
-            if ((x + i >= 0) && (x + i < GRID_SIZE) &&
-                (j + i >= 0) && (j + i < GRID_SIZE) &&
-                ((pgrid[i][j] & (GRID_SHIP | GRID_SHOT)) ==
-                 GRID_SHIP | GRID_SHOT))
-                return 1;
-    return 0;
-}
-
-/* Computer selects target.  TODO: more sophisticated logic.  Can experiment */
-/* with retries.  Sets cursx and cursy */
+/* Computer selects target.  This is where we try to beat the player. */
+/* Sets cursx and cursy */
 void target_pgrid(void)
 {
     int x;
     int y;
-    int retries;
-    
-    do
-    {
-        retries = 0;
-        do
-        {
-            x = rand() % GRID_SIZE;
-            y = rand() % GRID_SIZE;
-        }    
-        while (pgrid[x][y] & GRID_SHOT);
-    }
-    while (!next_to_hit(x, y) && (retries++ < 16));
-    cursx = x + 12;
-    cursy = y + 4;
+    int i;
+    int shipno;
+    int len;
+    int misses;
+    int hits;
+    int hottest;
+    int count;
+
+    for (x = 0; x < GRID_SIZE; x++)
+        for (y = 0; y < GRID_SIZE; y++)
+            heatmap[x][y] = 0;
+                
+    /* Update heat map */
+    /* Walk through every square, add points for every ship that would */
+    /* fit there.  Extra points if we can see a ship *is* there */
+    for (x = 0; x < GRID_SIZE; x++)
+        for (y = 0; y < GRID_SIZE; y++)
+            for (shipno = 0; shipno < sizeof(shipinfo) / sizeof(int); shipno++)
+            {
+                len = shipinfo[shipno];
+                /* Check horizontal case */
+                misses = 0;
+                for (i = 0; i < len; i++)
+                {
+                    if ((x + i >= GRID_SIZE) ||
+                        ((pgrid[x + i][y] & (GRID_SHIP | GRID_SHOT)) ==
+                          GRID_SHOT))
+                        misses++;
+                }
+                if (misses == 0)
+                {
+                    hits = 0;
+                    for (i = 0; i < len; i++)
+                    {
+                        if ((pgrid[x + i][y] & (GRID_SHIP | GRID_SHOT)) ==
+                             (GRID_SHIP | GRID_SHOT))
+                             hits++;
+                    }
+                    for (i = 0; i < len; i++)
+                        heatmap[x + i][y] += 1 + hits;
+                }
+                /* Check vertical case */
+                misses = 0;
+                for (i = 0; i < len; i++)
+                {
+                    if ((y + i >= GRID_SIZE) ||
+                        ((pgrid[x][y + i] & (GRID_SHIP | GRID_SHOT)) ==
+                          GRID_SHOT))
+                        misses++;
+                }
+                if (misses == 0)
+                {
+                    hits = 0;
+                    for (i = 0; i < len; i++)
+                    {
+                        if ((pgrid[x][y + i] & (GRID_SHIP | GRID_SHOT)) ==
+                             (GRID_SHIP | GRID_SHOT))
+                             hits++;
+                    }
+                    for (i = 0; i < len; i++)
+                        heatmap[x][y + i] += 1 + hits;
+                }
+            }
+
+    /* Find the hottest points in the heat map.  Ignore if we have already */
+    /* targeted that point */
+    hottest = 0;
+    for (x = 0; x < GRID_SIZE; x++)
+        for (y = 0; y < GRID_SIZE; y++)
+            if (!(pgrid[x][y] & GRID_SHOT))
+            {
+                if (heatmap[x][y] > hottest)
+                {
+                    count = 1;
+                    hottest = heatmap[x][y];
+                }
+                else if (heatmap[x][y] == hottest)
+                    count++;
+            }
+
+    /* Select random instance of hottest from 0..count-1 */            
+    count = rand() % count;
+    for (x = 0; x < GRID_SIZE; x++)
+        for (y = 0; y < GRID_SIZE; y++)
+            if (!(pgrid[x][y] & GRID_SHOT))
+            {
+                if (heatmap[x][y] == hottest)
+                {
+                    if (count == 0)
+                    {
+                        cursx = x + 12;
+                        cursy = y + 4;
+                        return;
+                    }
+                    else
+                        count--;
+                }
+            }
 }
 
 /* Check for winner.  Returns 0 - none, 1 - computer, 2 - player */
@@ -662,7 +735,7 @@
     }
 }
 
-/* Allow player to play ships in player grid */
+/* Allow player to place ships in player grid */
 void place_ships(void)
 {
     int i;
@@ -969,7 +1042,6 @@
     game.display.loadRGBPalette(palettePico);
     game.setFrameRate(30);
     while (game.isRunning()) {
-
 //      show_debug();
 
         if (game.update()) {