Created
January 9, 2018 21:53
-
-
Save kazimuth/a3acb92d7af8329b2d25eeec51da30f5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#include <bc.h> | |
/// See bc.h at xxx for the API you have access too. | |
/// Note: the API is not thread safe; don't use pthreads. | |
/// It's not very pretty, sorry. If you want a prettier low-level language, maybe consider rust? | |
// Any method in the API may set an error. | |
// Call check_errors() to get the most recent error. | |
bool check_errors() { | |
/// Check if we have an error... | |
if (bc_has_err()) { | |
char *err; | |
/// Note: this clears the current global error. | |
int8_t code = bc_get_last_err(&err); | |
printf("Engine error code %d: %s\n", code, err); | |
bc_free_string(err); | |
return true; | |
} else { | |
return false; | |
} | |
} | |
int main() { | |
printf("Player C bot starting\n"); | |
// It's good to try and make matches deterministic. It's not required, but it | |
// makes debugging wayyy easier. | |
// Now if you use random() it will produce the same output each map. | |
srand(0); | |
// we provide some helpful helpers :) | |
bc_Direction dir = North; | |
bc_Direction opposite = bc_Direction_opposite(dir); | |
// you should basically call this after every function call. | |
check_errors(); | |
printf("Opposite direction of %d: %d\n", dir, opposite); | |
// Make sure that the world is sane! | |
assert(opposite == South); | |
printf("Connecting to manager...\n"); | |
// Most methods return pointers; methods returning integers or enums are the only exception. | |
bc_GameController *gc = new_bc_GameController(); | |
if (check_errors()) { | |
// If there was an error creating gc, just die. | |
printf("Failed, dying.\n"); | |
exit(1); | |
} | |
printf("Connected!\n"); | |
// loop through the whole game. | |
while (true) { | |
// The API is "object-oriented" - most methods take pointers to some object. | |
uint32_t round = bc_GameController_round(gc); | |
printf("Round: %d\n", round); | |
// Note that all operations perform copies out of their data structures, returning new objects. | |
// You're responsible for freeing objects. | |
bc_VecUnit *units = bc_GameController_my_units(gc); | |
// it's good to cache things like this. Calls into the API have around a 20ns overhead, plus the cost of | |
// copying the data out of the engine. not horrible, but good to avoid more than necessary. | |
int len = bc_VecUnit_len(units); | |
for (int i = 0; i < len; i++) { | |
// Get the current unit. This also copies. | |
bc_Unit *unit = bc_VecUnit_index(units, i); | |
// Calls on the controller take unit IDs for ownership reasons. | |
uint16_t id = bc_Unit_id(unit); | |
if (bc_GameController_can_move(gc, id, North) && bc_GameController_is_move_ready(gc, id)) { | |
bc_GameController_move_robot(gc, id, North); | |
check_errors(); | |
} | |
// don't want memory leaks! | |
delete_bc_Unit(unit); | |
} | |
delete_bc_VecUnit(units); | |
// this line helps the output logs make more sense by forcing output to be sent | |
// to the manager. | |
// it's not strictly necessary, but it helps. | |
fflush(stdout); | |
// pause and wait for the next turn. | |
bc_GameController_next_turn(gc); | |
} | |
// Convinced you shouldn't use C yet? | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// import the API. | |
// See xxx for the javadocs. | |
import bc.*; | |
public class Player { | |
public static void main(String[] args) { | |
// MapLocation is a data structure you'll use a lot. | |
MapLocation loc = new MapLocation(Planet.Earth, 10, 20); | |
System.out.println("loc: "+loc+", one step to the Northwest: "+loc.add(Direction.Northwest)); | |
System.out.println("loc x: "+loc.getX()); | |
// One slightly weird thing: some methods are currently static methods on a static class called bc. | |
// This will eventually be fixed :/ | |
System.out.println("Opposite of " + Direction.North + ": " + bc.bcDirectionOpposite(Direction.North)); | |
// Connect to the manager, starting the game | |
GameController gc = new GameController(); | |
// Direction is a normal java enum. | |
Direction[] directions = Direction.values(); | |
while (true) { | |
System.out.println("Current round: "+gc.round()); | |
// VecUnit is a class that you can think of as similar to ArrayList<Unit>, but immutable. | |
VecUnit units = gc.myUnits(); | |
for (int i = 0; i < units.size(); i++) { | |
Unit unit = units.get(i); | |
// Most methods on gc take unit IDs, instead of the unit objects themselves. | |
if (gc.isMoveReady(unit.id()) && gc.canMove(unit.id(), Direction.Southeast)) { | |
gc.moveRobot(unit.id(), Direction.Southeast); | |
} | |
} | |
// Submit the actions we've done, and wait for our next turn. | |
gc.nextTurn(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment