在本系列中,我将分享我在自我施加的编程挑战方面取得的进展:用尽可能多的不同编程语言构建 Battlesnake。
查看第一篇文章,了解本系列的简短介绍。
您也可以在 GitHub 上关注我的进度。
Java是企业的语言,很多大型后台系统的业务逻辑都是用它编写的。
我过去编写过很多 Java 代码,但 Python 和 JavaScript 已经在我当代的编程活动中占据了一席之地。
因为 Java 可以用来编写非常可读和健壮的软件(Java IDE 往往有很好的重构支持),所以我仍然认为它是适合某些系统的语言。
与它的前辈相比,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"]
这是正在运行的开发设置:
说实话,我不得不在 Google 上搜索 Java 标准库中基本 Web 服务器的可用性。事实证明,(根据包名称)有一个 HTTP 服务器,它可能是标准库中最古老的部分之一:com.sun.net.httpserver.HttpServer。
使用服务器实现实际上非常简单,这是我处理 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 解析相关的四个函数(这些函数解析字段、对象和数组):
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中文网其他相关文章!