In dieser Serie werde ich meine Fortschritte bei meiner selbst auferlegten Programmierherausforderung teilen: einen Battlesnake in so vielen verschiedenen Programmiersprachen wie möglich erstellen.
Im ersten Beitrag finden Sie eine kurze Einführung in diese Serie.
Sie können meine Fortschritte auch auf GitHub verfolgen.
Java ist die Sprache der Unternehmen, die Geschäftslogik vieler großer Back-Office-Systeme ist darin geschrieben.
Ich habe in der Vergangenheit viel Java-Code geschrieben, aber Python und JavaScript haben in meinen heutigen Programmieraktivitäten ihren Platz eingenommen.
Da Java zum Schreiben sehr gut lesbarer und robuster Software verwendet werden kann (Java-IDEs verfügen in der Regel über eine hervorragende Refactoring-Unterstützung), bin ich immer noch der Meinung, dass es für einige Systeme die richtige Sprache ist.
Im Vergleich zu seinen Vorgängern brachte Java den Entwicklern viele Verbesserungen (je nach Geschmack natürlich): automatische Speicherverwaltung, integrierte Sammlungstypen und eine umfangreiche Standardbibliothek. Allerdings ist die Sprache mittlerweile über 30 Jahre alt und es gibt einige deutliche Zeichen der Zeit, wie zum Beispiel keine JSON-Unterstützung in der Standardbibliothek (aber XML-Unterstützung?).
Kann Java, wie es heute standardmäßig verfügbar ist, immer noch verwendet werden, um eine saubere und prägnante Battlesnake-Implementierung zu erstellen? Lesen Sie weiter, um es herauszufinden.
So sieht Snake.java aus:
public class Snake { public static void main(String args[]) { System.out.println("Hello world!"); } }
So sieht die Docker-Datei aus:
FROM eclipse-temurin:17-jdk RUN mkdir /app WORKDIR /app COPY Snake.java . RUN javac Snake.java CMD ["java", "Snake"]
Und hier ist das Entwicklungssetup in Aktion:
Um ehrlich zu sein, musste ich nach der Verfügbarkeit eines einfachen Webservers in der Java-Standardbibliothek suchen. Es stellt sich heraus, dass es (basierend auf dem Paketnamen) einen HTTP-Server in einem der wahrscheinlich ältesten Teile der Standardbibliothek gibt: com.sun.net.httpserver.HttpServer.
Die Verwendung der Serverimplementierung ist eigentlich ganz einfach. Hier ist mein erster Code zur Verarbeitung der Battlesnake-Metadatenanfrage:
import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpExchange; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; public class Snake { static class BattleSnakeHandler implements HttpHandler { public void handle(HttpExchange exchange) throws IOException { String response = "{\"apiversion\": \"1\", " + "\"author\": \"'robvanderleek\", \"version\": \"1.0\", " + "\"color\": \"#b07219\", \"head\": \"safe\", " + "\"tail\": \"sharp\"}"; exchange.sendResponseHeaders(200, response.length()); OutputStream os = exchange.getResponseBody(); os.write(response.getBytes()); os.close(); } } public static void main(String args[]) throws IOException { int port = Integer.parseInt( System.getenv().getOrDefault("PORT", "3000")); HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); server.createContext("/", new BattleSnakeHandler()); server.setExecutor(null); server.start(); System.out.println( String.format("Starting Battlesnake server on port: %d", port)); } }
Ein wesentlicher Teil des Spiellogikcodes dient dazu, die eingehenden JSON-Daten zu analysieren. Die Standard-Java-Bibliothek enthält keinen JSON-Parser und eine typische Parser-Bibliothek enthält Tausende von Codezeilen.
Mit vielen Hacks konnte ich den Battlesnake-JSON analysieren, und nur diesen JSON
Im Folgenden sind vier der Funktionen im Code aufgeführt, die sich auf die JSON-Analyse beziehen (diese Funktionen analysieren Felder, Objekte und Arrays):
private String getField(String json, String name) { String needle = '"' + name + '"'; return json.substring(json.indexOf(needle) + needle.length() + 1); } private String getBalanced(String json, String name, char open, char close) { String start = getField(json, name); int idx = 0, indent = 0; do { if (start.charAt(idx) == open) { indent++; } else if (start.charAt(idx) == close) { indent--; } idx++; } while (indent > 0); return start.substring(0, idx); } private String getObject(String json, String name) { return getBalanced(json, name, '{', '}'); } private String getArray(String json, String name) { return getBalanced(json, name, '[', ']'); }
Der Rest der Spiellogik ist recht einfach. Zur besseren Lesbarkeit und Prägnanz habe ich eine einfache Koordinatenklasse verwendet:
private Coordinate nearestFood(String board, Coordinate head) { String foodJson = getArray(board, "food"); Set<Coordinate> food = getCoordinates(foodJson); double distance = Double.MAX_VALUE; int x = 255, y = 255; for (Coordinate f: food) { double d = Math.sqrt(Math.pow(head.x - f.x, 2) + Math.pow(head.y - f.y, 2)); if (d < distance) { distance = d; x = f.x; y = f.y; } } return new Coordinate(x, y); }
Ich bin sicher, dass die Spiellogik verbessert werden kann. Warum probieren Sie es nicht einmal aus? ?
Und das ist der vollständige Code in Aktion:
Den vollständigen Code für C Battlesnake finden Sie hier auf GitHub.
Ich hoffe, dass Ihnen die Lektüre meiner Programmierabenteuer gefällt.
Lassen Sie mich in den Kommentaren unten wissen, was Sie über den obigen Code denken oder auf welche Programmiersprachen Sie sich in dieser Serie freuen.
Bis zur nächsten Sprache!
Das obige ist der detaillierte Inhalt vonBattlesnake Challenge # Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!