a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
at main 4.0 kB view raw
1#include <iostream> 2#include <vector> 3#include <algorithm> 4#include <numeric> 5#include <cstdlib> 6#include <ctime> 7 8using namespace std; 9 10const int BOARDSIZE = 10; 11 12// Simple coordinate parsing 13pair<int, int> parseMove(const string& move) { 14 int row = move[0] - 'A'; 15 int col = stoi(move.substr(1)) - 1; 16 return {row, col}; 17} 18 19int runSingleGame() { 20 char board[BOARDSIZE][BOARDSIZE]; 21 22 // Initialize board 23 for (int i = 0; i < BOARDSIZE; i++) { 24 for (int j = 0; j < BOARDSIZE; j++) { 25 board[i][j] = '.'; 26 } 27 } 28 29 // Place ships randomly 30 int shipSizes[] = {5, 4, 3, 3, 2}; 31 for (int s = 0; s < 5; s++) { 32 bool placed = false; 33 while (!placed) { 34 int row = rand() % BOARDSIZE; 35 int col = rand() % BOARDSIZE; 36 int orient = rand() % 2; 37 38 bool canPlace = true; 39 for (int i = 0; i < shipSizes[s]; i++) { 40 int r = row + (orient == 1 ? i : 0); 41 int c = col + (orient == 0 ? i : 0); 42 if (r >= BOARDSIZE || c >= BOARDSIZE || board[r][c] == 'S') { 43 canPlace = false; 44 break; 45 } 46 } 47 48 if (canPlace) { 49 for (int i = 0; i < shipSizes[s]; i++) { 50 int r = row + (orient == 1 ? i : 0); 51 int c = col + (orient == 0 ? i : 0); 52 board[r][c] = 'S'; 53 } 54 placed = true; 55 } 56 } 57 } 58 59 // Random shooting 60 vector<pair<int,int>> allCells; 61 for (int i = 0; i < BOARDSIZE; i++) { 62 for (int j = 0; j < BOARDSIZE; j++) { 63 allCells.push_back({i, j}); 64 } 65 } 66 67 // Shuffle cells 68 for (int i = allCells.size() - 1; i > 0; i--) { 69 int j = rand() % (i + 1); 70 swap(allCells[i], allCells[j]); 71 } 72 73 // Shoot until all ships found 74 int moves = 0; 75 int shipsRemaining = 17; // 5+4+3+3+2 76 77 for (size_t i = 0; i < allCells.size(); i++) { 78 int row = allCells[i].first; 79 int col = allCells[i].second; 80 moves++; 81 if (board[row][col] == 'S') { 82 shipsRemaining--; 83 if (shipsRemaining == 0) break; 84 } 85 } 86 87 return moves; 88} 89 90int main() { 91 const int numGames = 1000; 92 vector<int> moveCounts; 93 94 srand(time(NULL)); 95 96 cout << "Running " << numGames << " games with random AI..." << endl; 97 98 for (int i = 0; i < numGames; i++) { 99 int moves = runSingleGame(); 100 moveCounts.push_back(moves); 101 if ((i + 1) % 100 == 0) { 102 cout << "Completed " << (i + 1) << " games..." << endl; 103 } 104 } 105 106 // Calculate statistics 107 sort(moveCounts.begin(), moveCounts.end()); 108 int minMoves = moveCounts.front(); 109 int maxMoves = moveCounts.back(); 110 double avg = accumulate(moveCounts.begin(), moveCounts.end(), 0.0) / moveCounts.size(); 111 int median = moveCounts[moveCounts.size() / 2]; 112 int p25 = moveCounts[moveCounts.size() / 4]; 113 int p75 = moveCounts[3 * moveCounts.size() / 4]; 114 115 cout << "\n=== Random AI Statistics (1000 games) ===" << endl; 116 cout << "Min moves: " << minMoves << endl; 117 cout << "25th percentile: " << p25 << endl; 118 cout << "Median moves: " << median << endl; 119 cout << "Average moves: " << avg << endl; 120 cout << "75th percentile: " << p75 << endl; 121 cout << "Max moves: " << maxMoves << endl; 122 123 cout << "\n=== Suggested Stage Thresholds ===" << endl; 124 cout << "Stage 1 (Beginner): >" << p75 << " avg moves (worse than random)" << endl; 125 cout << "Stage 2 (Intermediate): " << static_cast<int>(avg) << "-" << p75 << " avg moves (around random average)" << endl; 126 cout << "Stage 3 (Advanced): " << p25 << "-" << static_cast<int>(avg) << " avg moves (better than random)" << endl; 127 cout << "Stage 4 (Expert): <" << p25 << " avg moves (much better than random)" << endl; 128 129 return 0; 130}