Dans cette série, je partagerai mes progrès avec le défi de programmation que je me suis imposé : construire un Battlesnake dans autant de langages de programmation différents que possible.
Consultez le premier message pour une courte introduction à cette série.
Vous pouvez également suivre mes progrès sur GitHub.
Java est le langage des entreprises, la logique métier de nombreux grands systèmes de back-office y est écrite.
J'ai écrit beaucoup de code Java dans le passé, mais Python et JavaScript ont pris place dans mes activités de programmation contemporaines.
Étant donné que Java peut être utilisé pour écrire des logiciels très lisibles et robustes (les IDE Java ont tendance à offrir un excellent support de refactorisation), je pense toujours que c'est le bon langage pour certains systèmes.
Par rapport à ses prédécesseurs, Java a apporté aux développeurs de nombreuses améliorations (selon vos goûts, bien sûr) : gestion automatique de la mémoire, types de collections intégrés et une bibliothèque standard étendue. Cependant, le langage a maintenant plus de 30 ans, et il y a des signes évidents des temps, comme l'absence de support JSON dans la bibliothèque standard (mais il a un support XML ?).
Java, tel qu'il est prêt à l'emploi aujourd'hui, peut-il encore être utilisé pour créer une implémentation Battlesnake propre et concise ? Continuez à lire pour le découvrir.
Voici à quoi ressemble Snake.java :
public class Snake { public static void main(String args[]) { System.out.println("Hello world!"); } }
Voici à quoi ressemble le Dockerfile :
FROM eclipse-temurin:17-jdk RUN mkdir /app WORKDIR /app COPY Snake.java . RUN javac Snake.java CMD ["java", "Snake"]
Et voici la configuration de développement en action :
Pour être honnête, j'ai dû rechercher sur Google la disponibilité d'un serveur Web de base dans la bibliothèque standard Java. Il s'avère qu'il existe un serveur HTTP (d'après le nom du package) dans ce qui est probablement l'une des parties les plus anciennes de la bibliothèque standard : com.sun.net.httpserver.HttpServer.
L'utilisation de l'implémentation du serveur est en fait assez simple, voici mon code initial pour gérer la demande de métadonnées Battlesnake :
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)); } }
Une partie importante du code logique du jeu est là pour analyser les données JSON entrantes. La bibliothèque Java standard ne contient pas d'analyseur JSON et une bibliothèque d'analyseurs typique contient des milliers de lignes de code.
Avec beaucoup de hacks, j'ai pu analyser le Battlesnake JSON, et seulement ce JSON
Vous trouverez ci-dessous quatre des fonctions du code liées à l'analyse JSON (ces fonctions analysent les champs, les objets et les tableaux) :
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, '[', ']'); }
Le reste de la logique du jeu est assez simple, j'ai utilisé une classe Coordonnée de base pour une meilleure lisibilité et concision :
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); }
Je suis sûr que la logique du jeu peut être améliorée, pourquoi ne pas essayer ? ?
Et voici le code complet en action :
Le code complet du C Battlesnake peut être trouvé ici sur GitHub.
J'espère que vous aimerez lire mes aventures de codage.
Dites-moi dans les commentaires ci-dessous ce que vous pensez du code ci-dessus ou quels langages de programmation vous attendez avec impatience dans cette série.
Jusqu'à la prochaine langue !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!