import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.InetSocketAddress; public abstract class Bot { // Ein Bot ist ein Programm, das sich mit einem Server verbindet und // mit diesem kommuniziert. Der Server sendet dem Bot eine Zeichenkette, // die das Spielfeld repräsentiert. Der Bot sendet dem Server ein Zeichen, // das die nächste Bewegung des Bots repräsentiert. private final String host; // Hostname oder IP-Adresse des Servers private final int port; // Port des Servers protected Bot(String[] args) { host = args.length > 0 ? args[0] : "localhost"; port = args.length > 1 ? Integer.parseInt(args[1]) : 63187; } // Diese Methode stellt die Verbindung zum Server her und startet die // Kommunikation mit dem Server. Die Methode wird von der main-Methode // aufgerufen. protected void run() { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port)); OutputStream out = socket.getOutputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); View view = new View(); while (true) { view.read(in); view.print(); try { char ch = nextMove(view); out.write(ch); } catch (Exception e) { break; } } socket.close(); } catch (IOException e) { System.err.println("Error: " + e.getMessage()); } } // Diese Methode ermittelt den nächsten Zug des Bots. Sie wird von der // run-Methode aufgerufen, nachdem der Server das Spielfeld gesendet hat. // Subklassen müssen diese Methode implementieren. abstract protected char nextMove(View view) throws Exception; // Diese Klasse repräsentiert das Spielfeld. Sie wird von der run-Methode // verwendet, um das Spielfeld zu lesen und auszugeben. // Subklassen können diese Klasse verwenden, um das Spielfeld zu analysieren. public static class View { protected String data; protected int width; // Diese Methode liest das Spielfeld vom Server. private void read(BufferedReader in) throws IOException { StringBuilder sb = new StringBuilder(); data = in.readLine(); if (data == null) { return; } sb.append(data); width = data.length(); for (int i = 1; i < width; ++i) { sb.append(in.readLine()); } data = sb.toString(); } // Diese Methode gibt das Spielfeld aus. protected void print() { if (data == null || width < 1) { return; } for (int i = 0, len = data.length(); i < len; i += width) { System.out.println(data.substring(i, i + width)); } } } }