Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated behavior for BLB and basicDroid to allow for more interesting interaction #19

Merged
merged 2 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions project-rumble/basic-bots/src/se/lth/cs/etsa02/MessageReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ of this software and associated documentation files (the "Software"), to deal
/**
* A class to help with the reading of messages.
* @author DavidPhung
* @author Teodor Ahlinder, improvements for LU Rumble (2020)
*/
public class MessageReader {

Expand Down Expand Up @@ -70,13 +71,16 @@ public Point getMyPos() {
}

/**
* Returns the value of the friendPos line if the message contains it. Otherwise returns null.
* Returns the value of the friendPos line if the message contains it. Otherwise returns an empty array.
* @return a point created from the (x,y) values in the friendPos line or null if the line is not included in the message or parsing fails.
*/
public Point getFriendPos() {
public Point[] getFriendPos() {
String[] values = getValues("friendPos");
if (values.length > 0) return parsePoint(values[0]);
return null;
Point[] p = new Point[values.length];
for (int i = 0; i < values.length; i++) {
p[i] = parsePoint(values[i]);
}
return p;
}

/**
Expand All @@ -92,6 +96,15 @@ public Point[] getEnemyPos() {
return p;
}

/**
* Returns the values of the enemyDetails lines if the message contains any. Otherwise returns an empty array.
* @return an array of strings created from values in the enemyPos lines or an empty array if no enemyPos line is included in the message.
*/
public String[] getEnemyDetails() {
String[] values = getValues("enemyDetails");
return values;
}

/**
* Returns the value of the targetEnemy line if the message contains it. Otherwise returns null.
* @return a point created from the (x,y) values in the targetEnemy line or null if the line is not included in the message.
Expand Down
30 changes: 24 additions & 6 deletions project-rumble/basic-bots/src/se/lth/cs/etsa02/MessageWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@ of this software and associated documentation files (the "Software"), to deal
package se.lth.cs.etsa02;

/**
* A class to help with composing a message.
* A class to help composing ETSA02 RoboTalk messages.
* @author DavidPhung
* @author Teodor Ahlinder, improvements for LU Rumble (2020)
*/
public class MessageWriter {

private String leaderShip;
private String teamMode;
private String myPos;
private String friendPos;
private String[] friendPos;
private int friendPosCount;
private String[] enemyPos;
private int enemyPosCount;
private String[] enemyDetails;
private int enemyDetailsCount;
private String targetEnemy;
private String targetPos;
private String moveTo;
Expand All @@ -47,7 +51,8 @@ public MessageWriter() {
leaderShip = new String();
teamMode = new String();
myPos = new String();
friendPos = new String();
friendPos = new String[10];
friendPosCount = 0;
enemyPos = new String[10];
enemyPosCount = 0;
targetEnemy = new String();
Expand Down Expand Up @@ -81,12 +86,13 @@ public void addMyPos(double x, double y) {
}

/**
* Add the friendPos line.
* Add the friendPos line. Note: we can have multiple lines of this (at most 10).
* @param x
* @param y
*/
public void addFriendPos(double x, double y) {
friendPos = "friendPos;" + x + ";" + y;
friendPos[friendPosCount] = "friendPos;" + x + ";" + y;
friendPosCount++;
}

/**
Expand All @@ -99,6 +105,13 @@ public void addEnemyPos(double x, double y) {
enemyPosCount++;
}

/**
* Add an enemyPos line. Note: we can have multiple lines of this (at most 10).
*/
public void addEnemyDetails(String name, double x, double y, double velocity, double energy, double heading, double gunHeading) {
enemyDetails[enemyDetailsCount] = "enemyDetails;" + name + ";" + x + ";" + y + ";" + velocity + ";" + energy + ";" + heading + ";" + gunHeading;
enemyDetailsCount++;
}
/**
* Add the targetEnemy line.
* @param x
Expand Down Expand Up @@ -135,10 +148,15 @@ public String composeMessage() {
addLine(sb, leaderShip);
addLine(sb, teamMode);
addLine(sb, myPos);
addLine(sb, friendPos);
for (int i = 0; i < friendPosCount; i++) {
addLine(sb, friendPos[i]);
}
for (int i = 0; i < enemyPosCount; i++) {
addLine(sb, enemyPos[i]);
}
for (int i = 0; i < enemyDetailsCount; i++) {
addLine(sb, enemyDetails[i]);
}
addLine(sb, targetEnemy);
addLine(sb, targetPos);
addLine(sb, moveTo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@ of this software and associated documentation files (the "Software"), to deal

import static robocode.util.Utils.normalRelativeAngleDegrees;

import java.io.IOException;

import robocode.BulletHitEvent;


/**
* BasicDroid - a simple droid that fires based on leader bot's orders
*
* @author Markus Borg
* @author Teodor Ahlinder, improvements for LU Rumble (2020)
*/
public class BasicDroid extends TeamRobot implements Droid {

Expand All @@ -59,10 +64,40 @@ public void onMessageReceived(MessageEvent e) {
setRadarColor(c.radarColor);
setScanColor(c.scanColor);
setBulletColor(c.bulletColor);
}else {
} else {
MessageReader reader = new MessageReader((String)e.getMessage());
if (reader.getTargetPos() != null) fireAtPoint(reader.getTargetPos());
if (reader.getMoveTo() != null) goTo(reader.getMoveTo());

// If enemy position, fire!
String[] values = reader.getEnemyDetails();
if (values.length > 0) {
String[] ss = values[0].split(";");
Point p = null;
try {
double energy = Double.parseDouble(ss[4]);
if (energy <= 0) {
return;
}
double x = Double.parseDouble(ss[1]);
double y = Double.parseDouble(ss[2]);
p = new Point(x,y);
} catch (RuntimeException err) {}
if (p != null) fireAtPoint(p);
}
}
}

/**
* onHitBullet: What to do when out bullet hits a robot
*/
private void onHitBullet(BulletHitEvent e) {
if (e.getEnergy() <= 0) {
try {
// Message allies that enemy bot is dead
MessageWriter writer = new MessageWriter();
writer.addEnemyDetails(e.getName(), 0, 0, 0, e.getEnergy(), 0, 0);
broadcastMessage(writer.composeMessage());
} catch (IOException ignored) {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,61 @@ of this software and associated documentation files (the "Software"), to deal
package se.lth.cs.etsa02.basicleaderbot;

import robocode.HitByBulletEvent;
import robocode.MessageEvent;
import robocode.ScannedRobotEvent;
import robocode.TeamRobot;
import se.lth.cs.etsa02.MessageReader;
import se.lth.cs.etsa02.MessageWriter;
import se.lth.cs.etsa02.RobotColors;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
/**
* BasicLeaderBot (BLB) - a sample team robot for ETSA02.
*
* Looks around for enemies, and orders team mates to fire.
* If hit by a bullet, it sometimes changes its motvement.
*
* @author Markus Borg
* @author Teodor Ahlinder, improvements for LU Rumble (2020)
*/
public class BasicLeaderBot extends TeamRobot {
private static final Color BODYCOLOR = Color.white;
private static final Color GUNCOLOR = Color.white;
private static final Color RADARCOLOR = Color.white;
private static final Color SCANCOLOR = Color.white;
private static final Color BULLETCOLOR = Color.white;

private ArrayList<DummyRobot> knownEnemyRobots;
private ArrayList<DummyRobot> knownAlliedRobots;

/**
* run: BLB's default behavior
* run: BLB's new behavior, improved by Teodor Ahlinder (2020)
*/
public void run() {
// Prepare RobotColors object with white colors
// ----------------------------------------------
// ------------- Starting behavior --------------
// ----------------------------------------------

// -------- Configuring list of enemies ---------
knownEnemyRobots = new ArrayList<DummyRobot>();

// ---------- Asserting leader control ----------
try {
// Declare to team that this bot is the leader
MessageWriter writer = new MessageWriter();
writer.addLeadership("followMe");
broadcastMessage(writer.composeMessage());
} catch (IOException ignored) {}

// ----------- Setting team colors --------------
RobotColors c = new RobotColors();
c.bodyColor = Color.white;
c.gunColor = Color.white;
c.radarColor = Color.white;
c.scanColor = Color.white;
c.bulletColor = Color.white;
c.bodyColor = BODYCOLOR;
c.gunColor = GUNCOLOR;
c.radarColor = RADARCOLOR;
c.scanColor = SCANCOLOR;
c.bulletColor = BULLETCOLOR;

// Set the color of BLB
setBodyColor(c.bodyColor);
Expand All @@ -62,7 +89,14 @@ public void run() {
try {
// Send RobotColors object to the entire team
broadcastMessage(c);
} catch (IOException ignored) {}
} catch (IOException ignored) {
System.out.println("Could not broadcast team colors.");
}


// ----------------------------------------------
// ------------- Running Behavior ---------------
// ----------------------------------------------

// Default behavior - BLB's standard sequence
while (true) {
Expand All @@ -73,36 +107,115 @@ public void run() {
}

/**
* onScannedRobot: BLB has detected another robot. If hostile, share position with the team.
* onScannedRobot: BLB has detected another robot. Update internal lists and transmit them to team.
*/
public void onScannedRobot(ScannedRobotEvent e) {
// No action if a teammate is detected
if (isTeammate(e.getName())) {
return;
}
// Calculate robot bearing
double robotBearing = this.getHeading() + e.getBearing();

// Calculate enemy bearing
double enemyBearing = this.getHeading() + e.getBearing();
// Calculate robot's position
double robotX = getX() + e.getDistance() * Math.sin(Math.toRadians(robotBearing));
double robotY = getY() + e.getDistance() * Math.cos(Math.toRadians(robotBearing));

// Calculate enemy's position
double enemyX = getX() + e.getDistance() * Math.sin(Math.toRadians(enemyBearing));
double enemyY = getY() + e.getDistance() * Math.cos(Math.toRadians(enemyBearing));
// Store robot in appropriate list
String scannedName = e.getName();
DummyRobot r = new DummyRobot(scannedName, robotX, robotY, e.getVelocity(), e.getEnergy(), e.getHeading(), 0);
if (isTeammate(scannedName)) {
updateList(r, knownAlliedRobots);
} else {
updateList(r, knownEnemyRobots);
}

try {
// Send enemy position to teammates
// Send positions of known allies to team
MessageWriter writer = new MessageWriter();
writer.addTargetPos(enemyX, enemyY);
writer.addMyPos(this.getX(), this.getY());
for (DummyRobot allies : knownAlliedRobots) {
writer.addFriendPos(allies.getX(), allies.getY());
}
// Send positions of known enemies to team
for (DummyRobot enemies : knownEnemyRobots) {
writer.addEnemyDetails(enemies.getName(), enemies.getX(), enemies.getY(), enemies.getVelocity(), enemies.getEnergy(), enemies.getHeading(), enemies.getGunHeading());
}
broadcastMessage(writer.composeMessage());
} catch (IOException ex) {
out.println("Unable to send order: ");
ex.printStackTrace(out);
}
}

/**
* Adds a new robot to the list, or updates the robots values if it is already in the list
* @param r robot to add or update
* @return 0 if robot was already in list, 1 if it was added as a new robot, -1 if robot energy was <=0
*/
private int updateList(DummyRobot r, ArrayList<DummyRobot> list) {
for (int i = 0; i < list.size(); i++) {
DummyRobot robot = list.get(i);
if (r.getName() == robot.getName()) {
if (r.getEnergy() <= 0) {
list.remove(i);
return -1;
}
list.get(i).update(r.getX(), r.getY(), r.getVelocity(), r.getEnergy(), r.getHeading(), r.getGunHeading());
return 0;
}
}
for (DummyRobot robot : list) {
if (r.getName() == robot.getName()) {
robot = r;
return 0;
}
}
list.add(r);
return 1;
}

/**
* onHitByBullet: BLB has been hit by a bullet. Turn perpendicular to path of the bullet.
*/
public void onHitByBullet(HitByBulletEvent e) {
turnLeft(90 - e.getBearing());
}

/**
* onDeath: Code executed when this robot dies.
*/
public void onDeath() {
try {
// Declare to team that this bot is dead and should not be followed anymore
MessageWriter writer = new MessageWriter();
writer.addLeadership("leadMe");
broadcastMessage(writer.composeMessage());
} catch (IOException ignored) {}
}

public void onMessageReceived(MessageEvent e) {
MessageReader reader = new MessageReader((String)e.getMessage());
String[] enemies = reader.getEnemyDetails();
for (String values : enemies) {
String[] v = values.split(";");
if (v.length >= 7) {
try {
double x = Double.parseDouble(v[1]);
double y = Double.parseDouble(v[2]);
double velocity = Double.parseDouble(v[3]);
double energy = Double.parseDouble(v[4]);
double heading = Double.parseDouble(v[5]);
double gunHeading = Double.parseDouble(v[6]);
DummyRobot r = new DummyRobot(v[0], x, y, velocity, energy, heading, gunHeading);
updateList(r, knownEnemyRobots);
} catch (RuntimeException err) {}
}
}
}


public ArrayList<DummyRobot> getKnownEnemyRobots() {
return knownEnemyRobots;
}

public ArrayList<DummyRobot> getKnownAlliedRobots() {
return knownAlliedRobots;
}
}
Loading