a geicko-2 based round robin ranking system designed to test c++ battleship submissions
battleship.dunkirk.sh
1#include "battleship.h"
2#include "kasbs.h"
3#include "memory.h"
4#include <string>
5
6using namespace std;
7
8// Hunter AI - uses hunt/target mode (simpler than klukas)
9inline bool onBoard(int row, int col) {
10 return row >= 0 && row < BOARDSIZE && col >= 0 && col < BOARDSIZE;
11}
12
13void initMemoryHunter(ComputerMemory &memory) {
14 memory.mode = RANDOM;
15 memory.hitRow = -1;
16 memory.hitCol = -1;
17 memory.hitShip = NONE;
18 memory.fireDir = NONE;
19 memory.fireDist = 1;
20 memory.lastResult = NONE;
21
22 for (int i = 0; i < BOARDSIZE; i++) {
23 for (int j = 0; j < BOARDSIZE; j++) {
24 memory.grid[i][j] = EMPTY_MARKER;
25 }
26 }
27}
28
29string smartMoveHunter(const ComputerMemory &memory) {
30 if (memory.mode == RANDOM) {
31 // Use checkerboard pattern for hunting
32 for (int i = 0; i < BOARDSIZE; i++) {
33 for (int j = 0; j < BOARDSIZE; j++) {
34 if ((i + j) % 2 == 0 && memory.grid[i][j] == EMPTY_MARKER) {
35 char letter = static_cast<char>('A' + i);
36 return string(1, letter) + to_string(j + 1);
37 }
38 }
39 }
40
41 // If no checkerboard cells left, use any empty cell
42 for (int i = 0; i < BOARDSIZE; i++) {
43 for (int j = 0; j < BOARDSIZE; j++) {
44 if (memory.grid[i][j] == EMPTY_MARKER) {
45 char letter = static_cast<char>('A' + i);
46 return string(1, letter) + to_string(j + 1);
47 }
48 }
49 }
50 }
51
52 // Target mode - try adjacent cells
53 int directions[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // N, E, S, W
54 int dirIdx = memory.fireDir;
55
56 if (dirIdx == NONE) dirIdx = 0;
57
58 // Try current direction
59 for (int tries = 0; tries < 4; tries++) {
60 int idx = (dirIdx + tries) % 4;
61 int dr = directions[idx][0];
62 int dc = directions[idx][1];
63 int newRow = memory.hitRow + dr;
64 int newCol = memory.hitCol + dc;
65
66 if (onBoard(newRow, newCol) && memory.grid[newRow][newCol] == EMPTY_MARKER) {
67 char letter = static_cast<char>('A' + newRow);
68 return string(1, letter) + to_string(newCol + 1);
69 }
70 }
71
72 // Fallback to random
73 for (int i = 0; i < BOARDSIZE; i++) {
74 for (int j = 0; j < BOARDSIZE; j++) {
75 if (memory.grid[i][j] == EMPTY_MARKER) {
76 char letter = static_cast<char>('A' + i);
77 return string(1, letter) + to_string(j + 1);
78 }
79 }
80 }
81
82 return "A1";
83}
84
85void updateMemoryHunter(int row, int col, int result, ComputerMemory &memory) {
86 memory.lastResult = result;
87 char marker;
88 if (isAMiss(result)) {
89 marker = MISS_MARKER;
90 } else {
91 marker = HIT_MARKER;
92 }
93 memory.grid[row][col] = marker;
94
95 if (memory.mode == RANDOM) {
96 if (!isAMiss(result)) {
97 // Got a hit, switch to target mode
98 memory.mode = SEARCH;
99 memory.hitRow = row;
100 memory.hitCol = col;
101 memory.fireDir = NORTH; // Start trying north
102 }
103 } else {
104 // In target mode
105 if (isASunk(result)) {
106 // Sunk the ship, back to hunt mode
107 memory.mode = RANDOM;
108 memory.hitRow = -1;
109 memory.hitCol = -1;
110 memory.fireDir = NONE;
111 } else if (!isAMiss(result)) {
112 // Another hit, keep current direction
113 // (fireDir stays the same)
114 } else {
115 // Miss in target mode, try next direction
116 if (memory.fireDir == NORTH) memory.fireDir = EAST;
117 else if (memory.fireDir == EAST) memory.fireDir = SOUTH;
118 else if (memory.fireDir == SOUTH) memory.fireDir = WEST;
119 else {
120 // Tried all directions, back to hunt
121 memory.mode = RANDOM;
122 memory.hitRow = -1;
123 memory.hitCol = -1;
124 memory.fireDir = NONE;
125 }
126 }
127 }
128}