package src; | |||||
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)); | |||||
} | |||||
} | |||||
} | |||||
} |
package src; | |||||
public class EscapeBot extends Bot{ | |||||
int stepCounter = 0; | |||||
int turnCount = 0; | |||||
int viewRange = 5; | |||||
int straightLength = 1; | |||||
protected EscapeBot(String[] args) { | |||||
super(args); | |||||
} | |||||
public static void main(String[] args) { | |||||
EscapeBot bot = new EscapeBot(args); | |||||
bot.run(); | |||||
} | |||||
@Override | |||||
protected char nextMove(View view) throws Exception { | |||||
if(!view.data.contains("o")){ | |||||
if(turnCount == 2){ | |||||
turnCount = 0; | |||||
straightLength++; | |||||
} | |||||
if(stepCounter < straightLength * viewRange){ | |||||
stepCounter++; | |||||
return '^'; | |||||
}else{ | |||||
stepCounter = 0; | |||||
turnCount++; | |||||
return '>'; | |||||
} | |||||
}else{ | |||||
if(view.data.substring(0,10).contains("o")){ | |||||
return '^'; | |||||
}else if(view.data.substring(10,12).contains("o")){ | |||||
return '<'; | |||||
}else if (view.data.substring(13,15).contains("o")) { | |||||
return '>'; | |||||
}else if(view.data.substring(15,25).contains("o")){ | |||||
return 'v'; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
} |
package src; | |||||
import java.util.Scanner; | |||||
public class ManualBot extends Bot{ | |||||
Scanner scanner = new Scanner(System.in); | |||||
protected ManualBot(String[] args) { | |||||
super(args); | |||||
} | |||||
public static void main(String[] args) { | |||||
ManualBot bot = new ManualBot(args); | |||||
bot.run(); | |||||
} | |||||
@Override | |||||
protected char nextMove(View view) throws Exception { | |||||
char ch = 0; | |||||
if(scanner.hasNextLine()){ | |||||
ch = scanner.nextLine().toCharArray()[0]; | |||||
} | |||||
return switch (ch) { | |||||
case 'w' -> '^'; | |||||
case 's' -> 'v'; | |||||
case 'a' -> '<'; | |||||
case 'd' -> '>'; | |||||
case 'q' -> throw new Exception(); | |||||
default -> 'l'; | |||||
}; | |||||
} | |||||
} |
package src; | |||||
public class SnakeBot extends Bot { | |||||
int stepCounter = 0; | |||||
int turnCount = 0; | |||||
int viewRange = 5; | |||||
int straightLength = 1; | |||||
boolean isOnPath = true; | |||||
protected SnakeBot(String[] args) { | |||||
super(args); | |||||
} | |||||
public static void main(String[] args) { | |||||
SnakeBot bot = new SnakeBot(args); | |||||
bot.run(); | |||||
} | |||||
@Override | |||||
protected char nextMove(View view) throws Exception { | |||||
if (!view.data.contains("@") && isOnPath) { | |||||
if (turnCount == 2) { | |||||
turnCount = 0; | |||||
straightLength++; | |||||
} | |||||
if (stepCounter < straightLength * viewRange) { | |||||
stepCounter++; | |||||
return '^'; | |||||
} else { | |||||
stepCounter = 0; | |||||
turnCount++; | |||||
return '>'; | |||||
} | |||||
} else if (!view.data.contains("@") && !isOnPath) { | |||||
} else { | |||||
isOnPath = false; | |||||
//check for minerals to the left of the rover (high prio) | |||||
for (int i = 0; i < view.data.length(); i += viewRange) { | |||||
if (view.data.substring(i, i + 2).contains("@")) { | |||||
return '<'; | |||||
} | |||||
} | |||||
//check for minerals in front of the rover (mid prio) | |||||
if (view.data.substring(0, view.data.length() / 2 - viewRange / 2).contains("@")) { | |||||
return '^'; | |||||
} | |||||
//check for minerals to the right of the rover (low prio) | |||||
for (int i = 3; i < view.data.length(); i += viewRange) { | |||||
if (view.data.substring(i, i + 2).contains("@")) { | |||||
return '>'; | |||||
} | |||||
} | |||||
// if (view.data.substring(0, 10).contains("@")) { | |||||
// return '^'; | |||||
// } else if (view.data.substring(10, 12).contains("@")) { | |||||
// return '<'; | |||||
// } else if (view.data.substring(13, 15).contains("@")) { | |||||
// return '>'; | |||||
// } else if (view.data.substring(15, 25).contains("@")) { | |||||
// return 'v'; | |||||
// } | |||||
} | |||||
return 0; | |||||
} | |||||
} |