このシリーズでは、私が自ら課したプログラミングの課題、つまりできるだけ多くの異なるプログラミング言語で Battlesnake を構築することの進捗状況を共有します。
このシリーズの短い紹介については、最初の投稿を確認してください。
GitHub で私の進捗状況を確認することもできます。
Java は企業向けの言語であり、多くの大規模なバックオフィス システムのビジネス ロジックは Java で書かれています。
私はこれまでに多くの Java コードを書いてきましたが、現在のプログラミング活動では Python と JavaScript がその役割を果たしています。
Java は非常に読みやすく堅牢なソフトウェアを作成するために使用できるため (Java IDE は優れたリファクタリング サポートを備えている傾向があります)、一部のシステムには Java が適切な言語であると今でも感じています。
Java は、以前のバージョンと比較して、自動メモリ管理、組み込みのコレクション型、広範な標準ライブラリなど、開発者に多くの改善をもたらしました (もちろん好みにもよりますが)。ただし、この言語は現在 30 年以上前のものであり、標準ライブラリで JSON がサポートされていない (ただし、XML はサポートされている?) など、明らかな時代の兆候がいくつかあります。
Java は、現在すぐに使える状態でも、クリーンで簡潔な Battlesnake 実装を構築するために使用できますか?詳細については、読み進めてください。
Snake.java は次のようになります:
public class Snake { public static void main(String args[]) { System.out.println("Hello world!"); } }
Dockerfile は次のようになります:
FROM eclipse-temurin:17-jdk RUN mkdir /app WORKDIR /app COPY Snake.java . RUN javac Snake.java CMD ["java", "Snake"]
そして、実際の開発セットアップは次のとおりです:
正直に言うと、Java 標準ライブラリの基本的な Web サーバーが利用できるかどうかを Google で調べなければなりませんでした。 (パッケージ名に基づくと) おそらく標準ライブラリの最も古い部分の 1 つである com.sun.net.httpserver.HttpServer.
に HTTP サーバーがあることがわかりました。
サーバー実装の使用は実際には非常に簡単です。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)); } }
ゲーム ロジック コードの重要な部分は、受信した JSON データを解析するためにあります。標準の Java ライブラリには JSON パーサーは含まれておらず、一般的なパーサー ライブラリには数千行のコードが含まれています。
多くのハッキングにより、Battlesnake の JSON、その JSON のみ
以下は、JSON 解析に関連するコード内の 4 つの関数です (これらの関数はフィールド、オブジェクト、配列を解析します)。
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, '[', ']'); }
ゲーム ロジックの残りの部分は非常に簡単です。読みやすさと簡潔さを高めるために、基本的な座標クラスを使用しました。
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); }
ゲームロジックは改善できると思いますので、試してみてはいかがでしょうか? ?
これが動作中の完全なコードです:
C Battlesnake の完全なコードは、GitHub にあります。
私のコーディングの冒険と合わせて読んでいただければ幸いです。
上記のコードについてどう思うか、このシリーズでどのプログラミング言語を楽しみにしているか、下のコメントで教えてください。
次の言語まで!
以上がバトルスネークチャレンジ # Javaの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。