Skip to content

Commit

Permalink
Added IO_COMPASS and documenting some IO commands (#84)
Browse files Browse the repository at this point in the history
Implemented IO_MARK and IO_MARK_READ.
Added documentation for some IO commands.
Added IO_COMPASS for finding local orientation.
Changed IO_BATTERY to push a normalized value.
Changed IO_MARK stack order offset pushed first.
Added IO_LASER and IO_RECEIVE aliases.
  • Loading branch information
krisives authored Oct 24, 2016
1 parent cc4d129 commit 81af09d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 7 deletions.
79 changes: 77 additions & 2 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,92 @@ The maximum CPU speed is 100, setting any number higher is the same as setting
to 100. The game operates at 10 frames per second meaning a fully overclocked
CPU will execute 1000 instructions per second, 100 per frame.

### Battery Check

A robot can know how much battery it has:

```
push8 #IO_BATTERY
io
popf batteryLevel
```

The float on the stack will be between `0.0` and `1.0` describing how much
battery is remaining.

### Laser

*Not yet implemented*
Robots get a laser beam which can damage some obstacles and other robots in
combat. Currently a laser can break rocks which may be blocking doors. Having
the laser on costs up to `256` battery per game frame, less if the laser is
not fully powered or hits something early.

Will deal battery damage to other bots.
```
; Full power laser
pushf 1.0
push8 #IO_LASER
io
; Laser off
pushf 0.0
push8 #IO_LASER
io
```

### Accelerometer

The accelerometer allows a robot to detect relative changes in it's position.
Each time you use the IO_ACCELEROMETER command the last position is saved and
the difference is pushed on the stack as two floats.

```
push8 #IO_ACCELEROMETER
io
popf relY
popf relX
```

### Compass

The compass allows a robot to determine which direction they are facing.

```
push8 #IO_COMPASS
io
popf facing
```

### World Marking

Robots can "mark" the world which is kind of like how animals can pee and sniff
the pee. A robot uses `IO_MARK` to write bytes to the current tile and can
use `IO_MARK_READ` to read data of the current tile. Each tile has 8 bytes
of storage.

```
push8 #00 ; Offset
push8 #42 ; Value to save
push8 #IO_MARK
io
```

You can read the same data back using:

```
push8 #00 ; Offset
push8 #IO_MARK_READ
io
pop8 tileData
```

Note that other robots (if in a shared world) also may read or write data to
the same tile.

### Radio

*Note the radio isn't implemented entirely yet*

The radio allows robots to send and receive messages with one another. Robots
"tune" their radio using the `IO_RADIO` command setting a frequency and
transmit power. The `IO_SEND` and `IO_RECV` to send and receive messages.

30 changes: 28 additions & 2 deletions src/asmcup/runtime/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ public float getY() {
return y;
}

public int getColumn() {
return (int)(x / World.TILE_SIZE);
}

public int getRow() {
return (int)(y / World.TILE_SIZE);
}

public int getCellX() {
return getColumn() / World.TILES_PER_CELL;
}

public int getCellY() {
return getRow() / World.TILES_PER_CELL;
}

public int getCellKey() {
return getCellX() | (getCellY() << 16);
}

public float getFacing() {
return facing;
}
Expand Down Expand Up @@ -303,11 +323,11 @@ protected void handleIO(World world) {
lazer = popFloatSafe(0.0f, 1.0f);
break;
case IO_BATTERY:
vm.pushFloat(battery);
vm.pushFloat((float)battery / BATTERY_MAX);
break;
case IO_MARK:
offset = vm.pop8();
value = vm.pop8();
offset = vm.pop8();
world.mark(this, offset, value);
break;
case IO_MARK_READ:
Expand All @@ -330,6 +350,9 @@ protected void handleIO(World world) {
case IO_RECV:
vm.push8(world.recv(this, frequency));
break;
case IO_COMPASS:
vm.pushFloat(facing);
break;
default:
lastInvalidIO = world.getFrame();
return;
Expand Down Expand Up @@ -414,14 +437,17 @@ protected static float clampSafe(float f, float min, float max) {
public static final int IO_STEER = 2;
public static final int IO_OVERCLOCK = 3;
public static final int IO_LAZER = 4;
public static final int IO_LASER = 4;
public static final int IO_BATTERY = 5;
public static final int IO_MARK = 6;
public static final int IO_MARK_READ = 7;
public static final int IO_ACCELEROMETER = 8;
public static final int IO_RADIO = 9;
public static final int IO_SEND = 10;
public static final int IO_RECV = 11;
public static final int IO_RECEIVE = 11;
public static final int IO_SENSOR_CONFIG = 12;
public static final int IO_COMPASS = 13;

public static final float SPEED_MAX = 8;
public static final float STEER_RATE = (float)(Math.PI * 0.1);
Expand Down
18 changes: 15 additions & 3 deletions src/asmcup/runtime/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
public class World {
protected final ArrayList<Robot> robots;
protected final HashMap<Integer, Cell> cells;
protected final HashMap<Integer, byte[]> tileData;
protected final int seed;
protected int frame;

Expand All @@ -15,6 +16,7 @@ public World() {
public World(int seed) {
this.robots = new ArrayList<>();
this.cells = new HashMap<>();
this.tileData = new HashMap<>();
this.seed = seed;
this.frame = 0;
}
Expand Down Expand Up @@ -157,12 +159,21 @@ protected void tickItems(Robot robot) {
}

public void mark(Robot robot, int offset, int value) {
// TODO read data from tile
int key = robot.getColumn() | (robot.getRow() << 16);
byte[] data = tileData.get(key);

if (data == null) {
data = new byte[8];
tileData.put(key, data);
}

data[offset & 0b11] = (byte)(value & 0xFF);
}

public int markRead(Robot robot, int offset) {
// TODO write data to tile
return 0;
int key = robot.getColumn() | (robot.getRow() << 16);
byte[] data = tileData.get(key);
return (data == null) ? 0 : data[offset & 0b11];
}

public void send(Robot robot, float frequency, int data) {
Expand All @@ -180,4 +191,5 @@ public int recv(Robot robot, float frequency) {
public static final int CELL_SIZE = TILES_PER_CELL * TILE_SIZE;
public static final int CELL_COUNT = 0xFF;
public static final int SIZE = TILE_SIZE * TILES_PER_CELL * CELL_COUNT;
public static final int CENTER = SIZE / 2;
}

0 comments on commit 81af09d

Please sign in to comment.