a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add social tags

+93 -4
+2
README.md
··· 1 1 # Battleship Arena 2 2 3 + ![screenshot of the arena](https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png) 4 + 3 5 This is a service I made to allow students in my `cs-1210` class to benchmark their battleship programs against each other. 4 6 5 7 ## I just want to get on the leaderboard; How?
battleship-arena

This is a binary file and will not be displayed.

+1
cmd/battleship-arena/main.go
··· 139 139 r.Get("/play/{aiName}", server.HandlePlayPage) 140 140 r.Get("/api/available-ais", server.HandleAvailableAIs) 141 141 r.HandleFunc("/ws/game", game.HandleGameWebSocket) 142 + r.Get("/og-image.png", server.HandleOGImage) 142 143 r.Get("/", server.HandleLeaderboard) 143 144 144 145 log.Println("Server running at " + cfg.ExternalURL)
+18
internal/server/play.go
··· 72 72 <title>Play Battleship - Battleship Arena</title> 73 73 <meta charset="UTF-8"> 74 74 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 75 + <meta name="description" content="Challenge student-coded AI opponents in real-time Battleship battles. Test your strategy against competitive algorithms."> 76 + <meta name="keywords" content="battleship, play online, AI opponent, strategy game, multiplayer battleship"> 77 + 78 + <!-- Open Graph / Facebook --> 79 + <meta property="og:type" content="website"> 80 + <meta property="og:url" content="{{.ServerURL}}/play"> 81 + <meta property="og:title" content="Play Battleship - Challenge AI Opponents"> 82 + <meta property="og:description" content="Challenge student-coded AI opponents in real-time Battleship battles. Test your strategy against competitive algorithms."> 83 + <meta property="og:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 84 + 85 + <!-- Twitter --> 86 + <meta property="twitter:card" content="summary_large_image"> 87 + <meta property="twitter:url" content="{{.ServerURL}}/play"> 88 + <meta property="twitter:title" content="Play Battleship - Challenge AI Opponents"> 89 + <meta property="twitter:description" content="Challenge student-coded AI opponents in real-time Battleship battles. Test your strategy against competitive algorithms."> 90 + <meta property="twitter:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 91 + 75 92 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚓</text></svg>"> 93 + <link rel="canonical" href="{{.ServerURL}}/play"> 76 94 <style> 77 95 * { 78 96 margin: 0;
+47 -3
internal/server/users.go
··· 60 60 Entry *storage.LeaderboardEntry 61 61 Submissions []storage.SubmissionWithStats 62 62 PublicKeyDisplay string 63 + ServerURL string 63 64 }{ 64 65 User: user, 65 66 Entry: userEntry, 66 67 Submissions: submissions, 67 68 PublicKeyDisplay: publicKeyDisplay, 69 + ServerURL: GetServerURL(), 68 70 } 69 71 tmpl.Execute(w, data) 70 72 } ··· 76 78 return 77 79 } 78 80 81 + data := struct { 82 + Users []storage.User 83 + ServerURL string 84 + }{ 85 + Users: users, 86 + ServerURL: GetServerURL(), 87 + } 88 + 79 89 tmpl := template.Must(template.New("users").Parse(usersListHTML)) 80 - tmpl.Execute(w, users) 90 + tmpl.Execute(w, data) 81 91 } 82 92 83 93 func formatPublicKey(key string) string { ··· 104 114 <title>{{.User.Name}} (@{{.User.Username}}) - Battleship Arena</title> 105 115 <meta charset="UTF-8"> 106 116 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 117 + <meta name="description" content="Profile for {{.User.Name}} (@{{.User.Username}}) - View their Battleship AI performance, ranking, and match history."> 118 + 119 + <!-- Open Graph / Facebook --> 120 + <meta property="og:type" content="profile"> 121 + <meta property="og:url" content="{{.ServerURL}}/user/{{.User.Username}}"> 122 + <meta property="og:title" content="{{.User.Name}} (@{{.User.Username}}) - Battleship Arena"> 123 + <meta property="og:description" content="View {{.User.Name}}'s Battleship AI performance and match history."> 124 + <meta property="og:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 125 + 126 + <!-- Twitter --> 127 + <meta property="twitter:card" content="summary"> 128 + <meta property="twitter:url" content="{{.ServerURL}}/user/{{.User.Username}}"> 129 + <meta property="twitter:title" content="{{.User.Name}} (@{{.User.Username}}) - Battleship Arena"> 130 + <meta property="twitter:description" content="View {{.User.Name}}'s Battleship AI performance and match history."> 131 + <meta property="twitter:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 132 + 107 133 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚓</text></svg>"> 134 + <link rel="canonical" href="{{.ServerURL}}/user/{{.User.Username}}"> 108 135 <style> 109 136 * { 110 137 margin: 0; ··· 342 369 <title>Users - Battleship Arena</title> 343 370 <meta charset="UTF-8"> 344 371 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 372 + <meta name="description" content="Browse all registered users and participants in the Battleship Arena AI competition."> 373 + 374 + <!-- Open Graph / Facebook --> 375 + <meta property="og:type" content="website"> 376 + <meta property="og:url" content="{{.ServerURL}}/users"> 377 + <meta property="og:title" content="Users - Battleship Arena"> 378 + <meta property="og:description" content="Browse all registered users and participants in the Battleship Arena AI competition."> 379 + <meta property="og:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 380 + 381 + <!-- Twitter --> 382 + <meta property="twitter:card" content="summary"> 383 + <meta property="twitter:url" content="{{.ServerURL}}/users"> 384 + <meta property="twitter:title" content="Users - Battleship Arena"> 385 + <meta property="twitter:description" content="Browse all registered users and participants in the Battleship Arena AI competition."> 386 + <meta property="twitter:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 387 + 345 388 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚓</text></svg>"> 389 + <link rel="canonical" href="{{.ServerURL}}/users"> 346 390 <style> 347 391 * { 348 392 margin: 0; ··· 430 474 <div class="container"> 431 475 <a href="/" class="back-link">← Back to Leaderboard</a> 432 476 <h1>Players</h1> 433 - <p style="color: #94a3b8; margin-bottom: 2rem;">{{len .}} registered users</p> 477 + <p style="color: #94a3b8; margin-bottom: 2rem;">{{len .Users}} registered users</p> 434 478 435 479 <div class="users-grid"> 436 - {{range .}} 480 + {{range .Users}} 437 481 <a href="/user/{{.Username}}" class="user-card"> 438 482 <div class="user-name">{{.Name}}</div> 439 483 <div class="user-handle">@{{.Username}}</div>
+25 -1
internal/server/web.go
··· 15 15 <!DOCTYPE html> 16 16 <html lang="en"> 17 17 <head> 18 - <title>Battleship Arena</title> 18 + <title>Battleship Arena - AI Competition Leaderboard</title> 19 19 <meta charset="UTF-8"> 20 20 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 21 + <meta name="description" content="Competitive Battleship AI arena. Watch student-coded algorithms battle it out using C++ and Glicko-2 rankings."> 22 + <meta name="keywords" content="battleship, AI, competition, leaderboard, programming, C++, algorithms, game AI"> 23 + <meta name="author" content="Battleship Arena"> 24 + 25 + <!-- Open Graph / Facebook --> 26 + <meta property="og:type" content="website"> 27 + <meta property="og:url" content="{{.ServerURL}}"> 28 + <meta property="og:title" content="Battleship Arena - AI Competition Leaderboard"> 29 + <meta property="og:description" content="Competitive Battleship AI arena. Watch student-coded algorithms battle it out using C++ and Glicko-2 rankings."> 30 + <meta property="og:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 31 + 32 + <!-- Twitter --> 33 + <meta property="twitter:card" content="summary_large_image"> 34 + <meta property="twitter:url" content="{{.ServerURL}}"> 35 + <meta property="twitter:title" content="Battleship Arena - AI Competition Leaderboard"> 36 + <meta property="twitter:description" content="Competitive Battleship AI arena. Watch student-coded algorithms battle it out using C++ and Glicko-2 rankings."> 37 + <meta property="twitter:image" content="https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png"> 38 + 21 39 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚓</text></svg>"> 40 + <link rel="canonical" href="{{.ServerURL}}"> 22 41 <style> 23 42 * { 24 43 margin: 0; ··· 1064 1083 if err := tmpl.Execute(w, data); err != nil { 1065 1084 http.Error(w, fmt.Sprintf("Template error: %v", err), http.StatusInternalServerError) 1066 1085 } 1086 + } 1087 + 1088 + func HandleOGImage(w http.ResponseWriter, r *http.Request) { 1089 + // Redirect to the hosted image 1090 + http.Redirect(w, r, "https://hc-cdn.hel1.your-objectstorage.com/s/v3/d5baa2ef6d8e9f89_10379.png", http.StatusMovedPermanently) 1067 1091 } 1068 1092 1069 1093 func HandleAPILeaderboard(w http.ResponseWriter, r *http.Request) {