├── .gitignore ├── LICENSE ├── README.md ├── RELEASE.md ├── backend ├── Dockerfile ├── README.md ├── __init__.py ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20190811_1452.py │ │ ├── 0003_auto_20191024_0426.py │ │ ├── 0004_auto_20191103_1312.py │ │ ├── 0005_auto_20191103_1344.py │ │ ├── 0006_auto_20191109_1644.py │ │ ├── 0007_league_game_released.py │ │ ├── 0008_auto_20191110_0252.py │ │ ├── 0009_auto_20191215_2044.py │ │ ├── 0010_team_score.py │ │ ├── 0011_auto_20200110_0821.py │ │ ├── 0012_scrimmage_tournament_id.py │ │ ├── 0013_auto_20200118_2249.py │ │ ├── 0014_auto_20200119_0609.py │ │ ├── 0015_auto_20200122_0135.py │ │ ├── 0016_auto_20200122_0201.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── pub.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── dev_settings.py ├── manage.py ├── requirements.txt ├── resumes │ ├── download.py │ ├── notes.txt │ └── sql.txt ├── settings.py ├── templates │ ├── base.html │ ├── email │ │ ├── password_reset.html │ │ └── verification.html │ └── view.html ├── tests.py ├── tournament.sql ├── urls.py ├── uwsgi-dev.ini ├── uwsgi.ini └── wsgi.py ├── build.gradle ├── client ├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── bc20 │ ├── bundle.js │ ├── tiled_1-3eMNULX.jpg │ ├── tree_bullets-1wQTwL-.png │ ├── tree_robots-3eqYfGf.png │ └── yellow_star-1n2ECJB.png ├── package-lock.json ├── package.json ├── playback │ ├── README.md │ ├── out │ │ ├── game.d.ts │ │ ├── game.js │ │ ├── gameworld.d.ts │ │ ├── gameworld.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── match.d.ts │ │ ├── match.js │ │ ├── metadata.d.ts │ │ ├── metadata.js │ │ ├── simulator.d.ts │ │ ├── simulator.js │ │ ├── soa.d.ts │ │ └── soa.js │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── game.ts │ │ ├── gameworld.ts │ │ ├── gen │ │ ├── create.ts │ │ └── tsconfig.json │ │ ├── index.ts │ │ ├── legacy │ │ ├── bench │ │ │ ├── run.ts │ │ │ └── runTimeline.ts │ │ ├── simulator.ts │ │ └── test │ │ │ ├── game.ts │ │ │ └── soa.ts │ │ ├── match.ts │ │ ├── metadata.ts │ │ ├── soa.ts │ │ └── tsconfig.json └── visualizer │ ├── README.md │ ├── build │ └── icon.png │ ├── electron-main.js │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app.ts │ ├── config.ts │ ├── constants.ts │ ├── electron-modules.ts │ ├── game │ │ ├── fps.ts │ │ ├── gamearea │ │ │ ├── gamearea.ts │ │ │ └── renderer.ts │ │ ├── index.ts │ │ ├── nextstep.ts │ │ └── sidebar │ │ │ ├── console.ts │ │ │ ├── mapfilter.ts │ │ │ ├── matchqueue.ts │ │ │ ├── matchrunner.ts │ │ │ ├── profiler.ts │ │ │ └── stats.ts │ ├── imageloader.ts │ ├── main │ │ ├── controls.ts │ │ ├── sidebar.ts │ │ └── splash.ts │ ├── mapeditor │ │ ├── action │ │ │ ├── generator.ts │ │ │ ├── renderer.ts │ │ │ └── validator.ts │ │ ├── form.ts │ │ ├── forms │ │ │ ├── archon.ts │ │ │ ├── header.ts │ │ │ ├── robots.ts │ │ │ ├── symmetry.ts │ │ │ ├── tree.ts │ │ │ └── unit.ts │ │ ├── index.ts │ │ └── mapeditor.ts │ ├── profiler.ts │ ├── scaffold.ts │ ├── static │ │ ├── css │ │ │ ├── style.css │ │ │ └── tournament.css │ │ └── img │ │ │ ├── bullets │ │ │ ├── bullet_fast.png │ │ │ ├── bullet_medium.png │ │ │ └── bullet_slow.png │ │ │ ├── controls │ │ │ ├── Legacy │ │ │ │ ├── go-next.png │ │ │ │ ├── go-previous.png │ │ │ │ ├── playback-pause.png │ │ │ │ ├── playback-start.png │ │ │ │ ├── playback-stop.png │ │ │ │ ├── seek-backward.png │ │ │ │ ├── seek-forward.png │ │ │ │ ├── skip-backward.png │ │ │ │ ├── skip-forward.png │ │ │ │ └── upload.png │ │ │ ├── go-next.png │ │ │ ├── go-previous.png │ │ │ ├── green-next.png │ │ │ ├── green-previous.png │ │ │ ├── playback-pause.png │ │ │ ├── playback-start.png │ │ │ ├── playback-stop.png │ │ │ ├── reverse.png │ │ │ ├── skip-backward.png │ │ │ ├── skip-forward.png │ │ │ └── upload.png │ │ │ ├── map │ │ │ ├── full_health_tree.png │ │ │ ├── low_health_tree.png │ │ │ ├── sapling.png │ │ │ ├── tiled_1.jpg │ │ │ ├── tree_bullets.png │ │ │ └── tree_robots.png │ │ │ ├── soup.png │ │ │ ├── sprites │ │ │ ├── Cow.png │ │ │ ├── Drone_blue.png │ │ │ ├── Drone_blue_carry.png │ │ │ ├── Drone_red.png │ │ │ ├── Drone_red_carry.png │ │ │ ├── Fulfillment_blue.png │ │ │ ├── Fulfillment_red.png │ │ │ ├── HQ_blue.png │ │ │ ├── HQ_red.png │ │ │ ├── Landscaper_blue.png │ │ │ ├── Landscaper_red.png │ │ │ ├── Miner_blue.png │ │ │ ├── Miner_red.png │ │ │ ├── Net_gun_blue.png │ │ │ ├── Net_gun_red.png │ │ │ ├── Refinery_blue.png │ │ │ ├── Refinery_red.png │ │ │ ├── SOUPER_blue.png │ │ │ ├── SOUPER_red.png │ │ │ ├── Vaporator_blue.png │ │ │ ├── Vaporator_red.png │ │ │ ├── archon_blue.png │ │ │ ├── archon_neutral.png │ │ │ ├── archon_red.png │ │ │ ├── bullet_tree_blue.png │ │ │ ├── bullet_tree_neutral.png │ │ │ ├── bullet_tree_red.png │ │ │ ├── gardener_blue.png │ │ │ ├── gardener_neutral.png │ │ │ ├── gardener_red.png │ │ │ ├── lumberjack_blue.png │ │ │ ├── lumberjack_neutral.png │ │ │ ├── lumberjack_red.png │ │ │ ├── recruit_blue.png │ │ │ ├── recruit_neutral.png │ │ │ ├── recruit_red.png │ │ │ ├── scout_blue.png │ │ │ ├── scout_neutral.png │ │ │ ├── scout_red.png │ │ │ ├── soldier_blue.png │ │ │ ├── soldier_neutral.png │ │ │ ├── soldier_red.png │ │ │ ├── tank_blue.png │ │ │ ├── tank_neutral.png │ │ │ ├── tank_red.png │ │ │ └── unknown.png │ │ │ └── yellow_star.png │ ├── tournament.ts │ └── websocket.ts │ ├── tsconfig.json │ └── webpack.config.js ├── docker-compose-b.yml ├── docker-compose.yml ├── engine ├── .gitignore ├── AUTHORS ├── COPYING ├── README.md ├── build.gradle ├── circle.yml ├── settings.gradle └── src │ ├── main │ └── battlecode │ │ ├── common │ │ ├── BodyInfo.java │ │ ├── Clock.java │ │ ├── Direction.java │ │ ├── GameActionException.java │ │ ├── GameActionExceptionType.java │ │ ├── GameConstants.java │ │ ├── MapLocation.java │ │ ├── RobotController.java │ │ ├── RobotInfo.java │ │ ├── RobotType.java │ │ ├── Team.java │ │ └── Transaction.java │ │ ├── doc │ │ ├── CostlyMethodTaglet.java │ │ └── RobotTypeTaglet.java │ │ ├── instrumenter │ │ ├── InstrumentationException.java │ │ ├── RobotDeathException.java │ │ ├── SandboxedRobotPlayer.java │ │ ├── TeamClassLoaderFactory.java │ │ ├── Verifier.java │ │ ├── bytecode │ │ │ ├── ClassReferenceUtil.java │ │ │ ├── InstrumentingClassVisitor.java │ │ │ ├── InstrumentingMethodVisitor.java │ │ │ ├── InterfaceReader.java │ │ │ ├── MethodCostUtil.java │ │ │ └── resources │ │ │ │ ├── AllowedPackages.txt │ │ │ │ ├── DisallowedClasses.txt │ │ │ │ └── MethodCosts.txt │ │ ├── inject │ │ │ ├── AtomicInteger.java │ │ │ ├── AtomicLong.java │ │ │ ├── AtomicReference.java │ │ │ ├── ConcurrentHashMap.java │ │ │ ├── InstrumentableFunctions.java │ │ │ ├── InstrumentedString.java │ │ │ ├── ObjectMethods.java │ │ │ ├── RobotMonitor.java │ │ │ ├── System.java │ │ │ ├── Thread.java │ │ │ └── Unsafe.java │ │ ├── profiler │ │ │ ├── Profiler.java │ │ │ ├── ProfilerCollection.java │ │ │ ├── ProfilerEvent.java │ │ │ └── ProfilerEventType.java │ │ └── stream │ │ │ ├── EOFInputStream.java │ │ │ ├── LimitedPrintStream.java │ │ │ ├── PrintStreamWrapper.java │ │ │ ├── RoboPrintStream.java │ │ │ └── SilencedPrintStream.java │ │ ├── schema │ │ ├── Action.java │ │ ├── BodyType.java │ │ ├── BodyTypeMetadata.java │ │ ├── Event.java │ │ ├── EventWrapper.java │ │ ├── GameFooter.java │ │ ├── GameHeader.java │ │ ├── GameMap.java │ │ ├── GameWrapper.java │ │ ├── LocalPollutionTable.java │ │ ├── MatchFooter.java │ │ ├── MatchHeader.java │ │ ├── PollutionEffect.java │ │ ├── ProfilerEvent.java │ │ ├── ProfilerFile.java │ │ ├── ProfilerProfile.java │ │ ├── RGBTable.java │ │ ├── Round.java │ │ ├── SpawnedBodyTable.java │ │ ├── TeamData.java │ │ ├── Vec.java │ │ └── VecTable.java │ │ ├── server │ │ ├── Config.java │ │ ├── ErrorReporter.java │ │ ├── GameInfo.java │ │ ├── GameMaker.java │ │ ├── GameState.java │ │ ├── Main.java │ │ ├── NetServer.java │ │ ├── PlayerFinder.java │ │ ├── Server.java │ │ ├── ServerState.java │ │ └── Version.java │ │ ├── util │ │ ├── FlatHelpers.java │ │ ├── SquareArray.java │ │ └── TeamMapping.java │ │ └── world │ │ ├── BuildMaps.java │ │ ├── DominationFactor.java │ │ ├── GameMapIO.java │ │ ├── GameStats.java │ │ ├── GameWorld.java │ │ ├── IDGenerator.java │ │ ├── InternalRobot.java │ │ ├── LiveMap.java │ │ ├── MapBuilder.java │ │ ├── ObjectInfo.java │ │ ├── RobotControllerImpl.java │ │ ├── TeamInfo.java │ │ ├── TestMapBuilder.java │ │ ├── control │ │ ├── CowControlProvider.java │ │ ├── NullControlProvider.java │ │ ├── PlayerControlProvider.java │ │ ├── RobotControlProvider.java │ │ └── TeamControlProvider.java │ │ ├── maps │ │ ├── ALandDivided.java │ │ ├── AMaze.java │ │ ├── BeachFrontProperty.java │ │ ├── CentralLake.java │ │ ├── CentralSoup.java │ │ ├── ChristmasInJuly.java │ │ ├── ClearlyTwelveHorsesInASalad.java │ │ ├── Climb.java │ │ ├── Constriction.java │ │ ├── CosmicBackgroundRadiation.java │ │ ├── CowFarm.java │ │ ├── DidAMonkeyMakeThis.java │ │ ├── DisproportionatelySmallGap.java │ │ ├── DoesNotExist.java │ │ ├── Egg.java │ │ ├── Europe.java │ │ ├── FourLakeLand.java │ │ ├── GSF.java │ │ ├── Hills.java │ │ ├── Hourglass.java │ │ ├── IceCream.java │ │ ├── InADitch.java │ │ ├── IsThisProcedural.java │ │ ├── Islands.java │ │ ├── Islands2.java │ │ ├── MapTestSmall.java │ │ ├── Maze.java │ │ ├── MoreCowbell.java │ │ ├── MtDoom.java │ │ ├── NoU.java │ │ ├── OmgThisIsProcedural.java │ │ ├── Prison.java │ │ ├── ProceduralConfirmed.java │ │ ├── RandomSoup1.java │ │ ├── RandomSoup2.java │ │ ├── RealArt.java │ │ ├── Sheet4.java │ │ ├── Showerhead.java │ │ ├── Soup.java │ │ ├── SoupOnTheSide.java │ │ ├── Spiral.java │ │ ├── Squares.java │ │ ├── Swirl.java │ │ ├── TheHighGround.java │ │ ├── Toothpaste.java │ │ ├── TwoForOneAndTwoForAll.java │ │ ├── TwoLakeLand.java │ │ ├── Volcano.java │ │ ├── WaterBot.java │ │ ├── WateredDown.java │ │ └── WhyDidntTheyUseEagles.java │ │ └── resources │ │ ├── ALandDivided.map20 │ │ ├── AMaze.map20 │ │ ├── BeachFrontProperty.map20 │ │ ├── CentralLake.map20 │ │ ├── CentralSoup.map20 │ │ ├── ChristmasInJuly.map20 │ │ ├── ClearlyTwelveHorsesInASalad.map20 │ │ ├── Climb.map20 │ │ ├── Constriction.map20 │ │ ├── CosmicBackgroundRadiation.map20 │ │ ├── CowFarm.map20 │ │ ├── DidAMonkeyMakeThis.map20 │ │ ├── DisproportionatelySmallGap.map20 │ │ ├── DoesNotExist.map20 │ │ ├── Egg.map20 │ │ ├── Europe.map20 │ │ ├── FourLakeLand.map20 │ │ ├── GSF.map20 │ │ ├── Hills.map20 │ │ ├── Hourglass.map20 │ │ ├── IceCream.map20 │ │ ├── InADitch.map20 │ │ ├── Infinity.map20 │ │ ├── IsThisProcedural.map20 │ │ ├── Islands.map20 │ │ ├── Islands2.map20 │ │ ├── Maze.map20 │ │ ├── MoreCowbell.map20 │ │ ├── MtDoom.map20 │ │ ├── NoU.map20 │ │ ├── OmgThisIsProcedural.map20 │ │ ├── Prison.map20 │ │ ├── ProceduralConfirmed.map20 │ │ ├── RandomSoup1.map20 │ │ ├── RandomSoup2.map20 │ │ ├── RealArt.map20 │ │ ├── Sheet4.map20 │ │ ├── Showerhead.map20 │ │ ├── Soup.map20 │ │ ├── SoupOnTheSide.map20 │ │ ├── Spiral.map20 │ │ ├── Squares.map20 │ │ ├── Swirl.map20 │ │ ├── TheHighGround.map20 │ │ ├── Toothpaste.map20 │ │ ├── TwoForOneAndTwoForAll.map20 │ │ ├── TwoLakeLand.map20 │ │ ├── Volcano.map20 │ │ ├── WaterBot.map20 │ │ ├── WateredDown.map20 │ │ ├── WhyDidntTheyUseEagles.map20 │ │ └── maptestsmall.map20 │ └── test │ └── battlecode │ ├── common │ ├── DirectionTest.java │ └── MapLocationTest.java │ ├── instrumenter │ ├── LoaderTest.java │ ├── README.weirdtests │ ├── SandboxedRobotPlayerTest.java │ ├── URLUtils.java │ ├── VerifierTest.java │ ├── resources │ │ ├── ValueA.class │ │ ├── ValueB.class │ │ └── java.lang.Double.class │ └── sample │ │ ├── instrumentertest │ │ ├── CallsIllegalMethods.java │ │ ├── CallsMathRandom.java │ │ ├── DoesntOverrideHashCode.java │ │ ├── DoesntOverrideToString.java │ │ ├── IllegalMethodReference.java │ │ ├── LegalMethodReference.java │ │ ├── Nothing.java │ │ ├── Outer.java │ │ ├── OverridesHashCode.java │ │ ├── OverridesToString.java │ │ ├── Reflection.java │ │ ├── StringFormat.java │ │ ├── UsesEnumMap.java │ │ ├── UsesLambda.java │ │ └── UsesThrowable.java │ │ ├── shared │ │ └── SharedUtility.java │ │ ├── testplayeractions │ │ └── RobotPlayer.java │ │ ├── testplayerarray │ │ └── RobotPlayer.java │ │ ├── testplayerarraybytecode │ │ └── RobotPlayer.java │ │ ├── testplayerbytecode │ │ └── RobotPlayer.java │ │ ├── testplayerbytecodekotlin │ │ └── RobotPlayer.kt │ │ ├── testplayerbytecodekotlinintrinsics │ │ └── RobotPlayer.kt │ │ ├── testplayerclock │ │ └── RobotPlayer.java │ │ ├── testplayerdebug │ │ └── RobotPlayer.java │ │ ├── testplayerempty │ │ └── RobotPlayer.java │ │ ├── testplayerloopforever │ │ └── RobotPlayer.java │ │ ├── testplayermultiarraybytecode │ │ └── RobotPlayer.java │ │ ├── testplayernodebug │ │ └── RobotPlayer.java │ │ ├── testplayerstatic │ │ └── RobotPlayer.java │ │ ├── testplayersystem │ │ └── RobotPlayer.java │ │ ├── testplayersystemout │ │ └── RobotPlayer.java │ │ └── testplayerusesshared │ │ └── RobotPlayer.java │ ├── server │ └── GameMakerTest.java │ ├── util │ └── SquareArrayTest.java │ └── world │ ├── GameMapIOTest.java │ ├── GenerateMaps.java │ ├── IDGeneratorTest.java │ ├── RobotControllerTest.java │ ├── TestGame.java │ ├── TestMapBuilder.java │ └── resources │ └── clearMap.map20 ├── example-bots ├── .gitignore ├── README.md ├── build.gradle ├── settings.gradle └── src │ ├── main │ └── examplefuncsplayer │ │ └── RobotPlayer.java │ └── test │ └── nothingbot │ └── Sanity.java ├── frontend ├── .env.development ├── .env.production ├── .eslintrc.js ├── Dockerfile.dev ├── README.md ├── deploy.sh ├── package-lock.json ├── package.json ├── public │ ├── assets │ │ ├── css │ │ │ ├── bc_styles.css │ │ │ ├── bootstrap.min.css │ │ │ ├── light-bootstrap-dashboard.css │ │ │ ├── pe-icon-7-helper.css │ │ │ └── pe-icon-7-stroke.css │ │ ├── fonts │ │ │ ├── Pe-icon-7-stroke.eot │ │ │ ├── Pe-icon-7-stroke.svg │ │ │ ├── Pe-icon-7-stroke.ttf │ │ │ └── Pe-icon-7-stroke.woff │ │ ├── img │ │ │ ├── castle.png │ │ │ ├── church.png │ │ │ ├── crusader.png │ │ │ ├── pilgrim.png │ │ │ ├── preacher.png │ │ │ ├── prophet.png │ │ │ ├── s_castle.png │ │ │ ├── s_church.png │ │ │ ├── s_crusader.png │ │ │ ├── s_pilgrim.png │ │ │ ├── s_preacher.png │ │ │ ├── s_prophet.png │ │ │ └── voyager_vision.png │ │ └── js │ │ │ ├── bootstrap.min.js │ │ │ ├── chartist.min.js │ │ │ ├── jquery-1.10.2.js │ │ │ └── light-bootstrap-dashboard.js │ ├── bc20 │ │ ├── app.js │ │ ├── app.js.map │ │ ├── bundle.js │ │ ├── bundle.js.map │ │ ├── profiler.js │ │ ├── profiler.js.map │ │ ├── speedscope │ │ │ ├── demangle-cpp.6caf93ee.js │ │ │ ├── favicon-16x16.d02bd490.png │ │ │ ├── favicon-32x32.c68a0a43.png │ │ │ ├── file-format-schema.json │ │ │ ├── import.0a51feeb.js │ │ │ ├── index.html │ │ │ ├── perf-vertx-stacks-01-collapsed-all.1841aedb.txt │ │ │ ├── release.txt │ │ │ ├── reset.7ae984ff.css │ │ │ └── speedscope.f741b731.js │ │ ├── tiled_1-3eMNULX.jpg │ │ └── yellow_star-1n2ECJB.png │ ├── favicon.png │ ├── index.html │ ├── javadoc │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── battlecode │ │ │ └── common │ │ │ │ ├── BodyInfo.html │ │ │ │ ├── Clock.html │ │ │ │ ├── Direction.html │ │ │ │ ├── GameActionException.html │ │ │ │ ├── GameActionExceptionType.html │ │ │ │ ├── GameConstants.html │ │ │ │ ├── MapLocation.html │ │ │ │ ├── RobotController.html │ │ │ │ ├── RobotInfo.html │ │ │ │ ├── RobotType.html │ │ │ │ ├── Team.html │ │ │ │ ├── Transaction.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ └── package-tree.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── specs.html │ ├── version.txt │ └── visualizer.html ├── screenshot.png └── src │ ├── api.js │ ├── components │ ├── avatar.js │ ├── paginationControl.js │ ├── perfCard.js │ ├── rankingTeamList.js │ ├── scrimmageRequestor.js │ ├── teamCard.js │ ├── teamList.js │ ├── updateCard.js │ ├── userCard.js │ └── userList.js │ ├── footer.js │ ├── index.js │ ├── navbar.js │ ├── sidebar.js │ └── views │ ├── VerifyUser.jsx │ ├── account.js │ ├── codeofconduct.js │ ├── countdown.css │ ├── countdown.js │ ├── debugging.js │ ├── docs.js │ ├── getting-started.js │ ├── home.js │ ├── ide.js │ ├── issues.js │ ├── login.js │ ├── not_found.js │ ├── passwordChange.jsx │ ├── passwordForgot.jsx │ ├── rankings.js │ ├── register.js │ ├── replay.js │ ├── resources.js │ ├── scrimmaging.js │ ├── search.js │ ├── staff.js │ ├── submissions.js │ ├── team.js │ ├── teamInfo.js │ ├── tournaments.js │ ├── updates.js │ └── visualizer.js ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── infrastructure ├── .gitignore ├── Makefile ├── README.md ├── compile.Dockerfile ├── env.Dockerfile ├── game.Dockerfile ├── matcher │ ├── bracketlib.py │ ├── config.py │ ├── scrimmage.py │ ├── tournament_server.py │ └── util.py ├── passed_students.sql ├── pub.py ├── scrimmage.Dockerfile ├── tournament-util │ ├── .gitignore │ ├── bracketlib.py │ ├── config.py │ ├── csv_to_files.py │ ├── data │ │ └── 0-example │ │ │ ├── maps.json │ │ │ ├── team_names │ │ │ └── team_pk │ ├── finals_seeds.py │ ├── match_list.py │ ├── pull_seeding.py │ ├── scrim_ranks.sql │ ├── scrim_ranks_verified.sql │ └── util.py ├── tournament.Dockerfile ├── worker.Dockerfile └── worker │ ├── app │ ├── compile_server.py │ ├── config.py │ ├── game_server.py │ ├── subscription.py │ └── util.py │ └── box │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── settings.gradle │ ├── src │ └── Helloworld.java │ └── version.txt ├── install_all.sh ├── post_release.py ├── pre_release.py ├── schema ├── .gitignore ├── LICENSE ├── README.md ├── battlecode.fbs ├── java │ └── battlecode │ │ └── schema │ │ ├── Action.java │ │ ├── BodyType.java │ │ ├── BodyTypeMetadata.java │ │ ├── Event.java │ │ ├── EventWrapper.java │ │ ├── GameFooter.java │ │ ├── GameHeader.java │ │ ├── GameMap.java │ │ ├── GameWrapper.java │ │ ├── LocalPollutionTable.java │ │ ├── MatchFooter.java │ │ ├── MatchHeader.java │ │ ├── ProfilerEvent.java │ │ ├── ProfilerFile.java │ │ ├── ProfilerProfile.java │ │ ├── RGBTable.java │ │ ├── Round.java │ │ ├── SpawnedBodyTable.java │ │ ├── TeamData.java │ │ ├── Vec.java │ │ └── VecTable.java ├── js │ └── battlecode_generated.js ├── package-lock.json ├── package.json └── ts │ ├── battlecode_generated.ts │ └── index.ts ├── settings.gradle └── specs ├── README.md ├── css ├── bootstrap.min.css ├── dashboard.css └── ie10-viewport-bug-workaround.css ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── js ├── bootstrap.min.js ├── ie10-viewport-bug-workaround.js └── jquery.min.js ├── specs.html ├── specs.md └── template.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *__pycache__* 4 | *.pyc 5 | .vscode/ 6 | venv/ 7 | docker-compose.prod.yml 8 | 9 | .idea 10 | 11 | access.txt 12 | 13 | ## Frontend 14 | frontend/build 15 | 16 | ## Backend 17 | backend/resumes/files/ 18 | 19 | ### Gradle ### 20 | .gradle 21 | /build/ 22 | 23 | ### Matches should be ignored 24 | /matches/ 25 | 26 | ### Java 27 | *.classpath 28 | *.project 29 | *.settings 30 | bin/ 31 | 32 | ### Client 33 | client/bc20 34 | client/visualizer/bc20 35 | 36 | ### Vim 37 | # Swap 38 | [._]*.s[a-v][a-z] 39 | !*.svg # comment out if you don't need vector files 40 | [._]*.sw[a-p] 41 | [._]s[a-rt-v][a-z] 42 | [._]ss[a-gi-z] 43 | [._]sw[a-p] 44 | # Session 45 | Session.vim 46 | Sessionx.vim 47 | # Temporary 48 | .netrwhist 49 | *~ 50 | # Auto-generated tag files 51 | tags 52 | # Persistent undo 53 | [._]*.un~ 54 | 55 | ### Distribution 56 | temp-dist 57 | 58 | ### Javadoc 59 | battlecode-javadoc-* 60 | 61 | ### test bots 62 | battlecode20-internal-test-bots 63 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | # Start with a Python image. 2 | FROM python@sha256:6eaf19442c358afc24834a6b17a3728a45c129de7703d8583392a138ecbdb092 3 | 4 | # Some stuff that everyone has been copy-pasting 5 | # since the dawn of time. 6 | ENV PYTHONUNBUFFERED 1 7 | 8 | # Install some necessary things. 9 | RUN apt-get update 10 | RUN apt-get install -y swig libssl-dev dpkg-dev netcat 11 | 12 | # Copy all our files into the image. 13 | RUN mkdir /code 14 | WORKDIR /code 15 | COPY requirements.txt /code/ 16 | 17 | # Install our requirements. 18 | RUN pip install -r requirements.txt 19 | 20 | COPY . /code/ 21 | 22 | CMD ["uwsgi", "--ini", "uwsgi.ini"] 23 | -------------------------------------------------------------------------------- /backend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/backend/__init__.py -------------------------------------------------------------------------------- /backend/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/backend/api/__init__.py -------------------------------------------------------------------------------- /backend/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class APIConfig(AppConfig): 5 | name = 'api' 6 | label = 'api' 7 | -------------------------------------------------------------------------------- /backend/api/migrations/0002_auto_20190811_1452.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.4 on 2019-08-11 14:52 2 | 3 | from django.db import migrations 4 | import datetime 5 | 6 | def add_0_league(apps, schema_editor): 7 | # We can't import the Person model directly as it may be a newer 8 | # version than this migration expects. We use the historical version. 9 | League = apps.get_model('api', 'League') 10 | l0 = League(id=0,name='bc20',start_date=datetime.datetime(year=2019, month=6, day=1),end_date=datetime.datetime(year=2020,month=6,day=1),active=True,submissions_enabled=True) 11 | l0.save() 12 | 13 | class Migration(migrations.Migration): 14 | 15 | dependencies = [ 16 | ('api', '0001_initial'), 17 | ] 18 | 19 | operations = [ 20 | migrations.RunPython(add_0_league), 21 | ] 22 | -------------------------------------------------------------------------------- /backend/api/migrations/0007_league_game_released.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.4 on 2019-11-09 23:27 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0006_auto_20191109_1644'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='league', 15 | name='game_released', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /backend/api/migrations/0008_auto_20191110_0252.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.4 on 2019-11-10 02:52 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0007_league_game_released'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='scrimmage', 15 | name='blue_mu', 16 | field=models.IntegerField(null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='scrimmage', 20 | name='red_mu', 21 | field=models.IntegerField(null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /backend/api/migrations/0009_auto_20191215_2044.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.4 on 2019-12-15 20:44 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0008_auto_20191110_0252'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='team', 15 | name='code', 16 | ), 17 | migrations.AddField( 18 | model_name='team', 19 | name='staff_team', 20 | field=models.BooleanField(default=False), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /backend/api/migrations/0010_team_score.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-10 07:52 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0009_auto_20191215_2044'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='team', 15 | name='score', 16 | field=models.FloatField(default=0.001), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /backend/api/migrations/0011_auto_20200110_0821.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-10 08:21 2 | 3 | from django.db import migrations 4 | 5 | def calculate_score(apps, schema_editor): 6 | Team = apps.get_model('api', 'Team') 7 | for team in Team.objects.all(): 8 | team.score = team.mu - 3*team.sigma 9 | team.save() 10 | 11 | class Migration(migrations.Migration): 12 | 13 | dependencies = [ 14 | ('api', '0010_team_score'), 15 | ] 16 | 17 | operations = [ 18 | migrations.RunPython(calculate_score), 19 | ] 20 | -------------------------------------------------------------------------------- /backend/api/migrations/0012_scrimmage_tournament_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-12 19:36 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0011_auto_20200110_0821'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='scrimmage', 15 | name='tournament_id', 16 | field=models.IntegerField(null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /backend/api/migrations/0013_auto_20200118_2249.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-18 22:49 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0012_scrimmage_tournament_id'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='team', 15 | name='high_school', 16 | field=models.BooleanField(default=False), 17 | ), 18 | migrations.AddField( 19 | model_name='team', 20 | name='international', 21 | field=models.BooleanField(default=False), 22 | ), 23 | migrations.AddField( 24 | model_name='team', 25 | name='mit', 26 | field=models.BooleanField(default=False), 27 | ), 28 | migrations.AddField( 29 | model_name='team', 30 | name='student', 31 | field=models.BooleanField(default=False), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /backend/api/migrations/0014_auto_20200119_0609.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-19 06:09 2 | 3 | from django.db import migrations 4 | from django.conf import settings 5 | 6 | def convert_to_elo(apps, schema_editor): 7 | # we want to set the elo of every team with a submission to ELO_START 8 | # and to ELO_NULL if no submission 9 | Team = apps.get_model('api', 'Team') 10 | TeamSubmission = apps.get_model('api', 'TeamSubmission') 11 | for team in Team.objects.all(): 12 | try: 13 | team_sub = TeamSubmission.objects.all().get(team=team) 14 | if team_sub.last_1_id is not None: 15 | team.score = settings.ELO_START 16 | else: 17 | team.score = settings.ELO_NULL 18 | team.save() 19 | except: 20 | team.score = settings.ELO_NULL 21 | team.save() 22 | 23 | class Migration(migrations.Migration): 24 | 25 | dependencies = [ 26 | ('api', '0013_auto_20200118_2249'), 27 | ] 28 | 29 | operations = [ 30 | migrations.RunPython(convert_to_elo), 31 | ] 32 | -------------------------------------------------------------------------------- /backend/api/migrations/0015_auto_20200122_0135.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-22 01:35 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('api', '0014_auto_20200119_0609'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tournament', 15 | name='blurb', 16 | field=models.TextField(blank=True), 17 | ), 18 | migrations.AddField( 19 | model_name='tournament', 20 | name='bracket_link', 21 | field=models.TextField(blank=True), 22 | ), 23 | migrations.AddField( 24 | model_name='tournament', 25 | name='teamsubmission_column_name', 26 | field=models.TextField(default='tour_sprint_id'), 27 | ), 28 | migrations.AlterField( 29 | model_name='team', 30 | name='score', 31 | field=models.FloatField(default=-1000000), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /backend/api/migrations/0016_auto_20200122_0201.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.8 on 2020-01-22 02:01 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('api', '0015_auto_20200122_0135'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='teamsubmission', 16 | name='tour_hs', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tour_hs', to='api.Submission'), 18 | ), 19 | migrations.AddField( 20 | model_name='teamsubmission', 21 | name='tour_intl_qual', 22 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tour_intl_qual', to='api.Submission'), 23 | ), 24 | migrations.AddField( 25 | model_name='teamsubmission', 26 | name='tour_newbie', 27 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tour_newbie', to='api.Submission'), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /backend/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/backend/api/migrations/__init__.py -------------------------------------------------------------------------------- /backend/api/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | Public endpoints. 3 | """ 4 | 5 | from django.urls import path 6 | from rest_framework.routers import DefaultRouter 7 | 8 | from . import views 9 | 10 | router = DefaultRouter() 11 | router.register('user/profile', views.UserProfileViewSet, base_name='userprofile') 12 | router.register('user', views.UserViewSet, base_name='user') 13 | router.register('verify', views.VerifyUserViewSet, base_name='verify') 14 | router.register('league', views.LeagueViewSet, base_name='league') 15 | router.register('(?P[^\/.]+)/team', views.TeamViewSet, base_name='team') 16 | router.register('(?P[^\/.]+)/submission', views.SubmissionViewSet, base_name='submission') 17 | router.register('(?P[^\/.]+)/teamsubmission', views.TeamSubmissionViewSet, base_name='teamsubmission') 18 | router.register('(?P[^\/.]+)/scrimmage', views.ScrimmageViewSet, base_name='scrimmage') 19 | router.register('(?P[^\/.]+)/tournament', views.TournamentViewSet, base_name='tournament') 20 | router.register('userteam/(?P[^\/]+)', views.UserTeamViewSet, base_name='userteam') 21 | router.register('match', views.MatchmakingViewSet, base_name='match') 22 | 23 | urlpatterns = router.urls 24 | -------------------------------------------------------------------------------- /backend/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- 1 | coreapi==2.3.3 2 | coreschema==0.0.4 3 | coverage==4.5.4 4 | Django==2.2.13 5 | django-cors-headers==3.0.2 6 | django-debug-toolbar==2.0 7 | django-nose==1.4.6 8 | django-rest-passwordreset==1.0.0 9 | django-webpack-loader==0.6.0 10 | djangorestframework==3.9.4 11 | djangorestframework-simplejwt==4.3.0 12 | itypes==1.1.0 13 | Jinja2==2.10.1 14 | MarkupSafe==1.1.1 15 | nose==1.3.7 16 | psycopg2==2.8.3 17 | PyJWT==1.7.1 18 | six==1.12.0 19 | sqlparse==0.3.0 20 | uritemplate==3.0.0 21 | uWSGI==2.0.18 22 | cachetools==3.1.1 23 | certifi==2019.9.11 24 | chardet==3.0.4 25 | google-api-core==1.14.3 26 | google-auth==1.6.3 27 | google-cloud-core==1.0.3 28 | google-cloud-storage==1.20.0 29 | google-cloud-pubsub==1.1.0 30 | google-resumable-media==0.4.1 31 | googleapis-common-protos==1.6.0 32 | idna==2.8 33 | protobuf==3.10.0 34 | pyasn1==0.4.7 35 | pyasn1-modules==0.2.7 36 | pytz==2019.3 37 | requests==2.22.0 38 | rsa==4.0 39 | urllib3==1.25.6 40 | trueskill==0.4.5 41 | sendgrid==6.1.0 42 | -------------------------------------------------------------------------------- /backend/resumes/notes.txt: -------------------------------------------------------------------------------- 1 | (see sql.txt for some scripts) 2 | 3 | download a list of all verified ids 4 | 5 | pull all resumes (for all verified ones), preserve user ids 6 | for each group of users (hs us, hs intl, college us, college intl, others that aren't devs): 7 | in ascending scrim rank, find associated resume 8 | rename to "#elo FirstLastResume" 9 | Also for users in users_all not in users_teams find resume as "FirstLastResume" 10 | 11 | 12 | -------------------------------------------------------------------------------- /backend/resumes/sql.txt: -------------------------------------------------------------------------------- 1 | Downloading all users with resumes: 2 | SELECT api_user.id, api_user.first_name, api_user.last_name FROM api_user 3 | WHERE api_user.verified=True 4 | ORDER BY api_user.id 5 | 6 | ----- 7 | 8 | Downloading all competitive resume users _on teams_ and team info: 9 | SELECT api_user.id, api_user.first_name, api_user.last_name, api_team_users.team_id, api_team.score, api_team.high_school, api_team.international, api_team.student 10 | FROM api_user 11 | LEFT JOIN api_team_users on api_user.id=api_team_users.user_id 12 | LEFT JOIN api_team on api_team_users.team_id=api_team.id 13 | WHERE api_user.verified=True and api_team.staff_team=False 14 | ORDER BY api_user.id -------------------------------------------------------------------------------- /backend/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% block main %}{% endblock %} 10 | 11 | -------------------------------------------------------------------------------- /backend/templates/email/password_reset.html: -------------------------------------------------------------------------------- 1 |

Hello, {{ username|safe }}!

2 | 3 |

4 | Click here to reset your password. Link 5 | expires in 24 hours. 6 |

7 | -------------------------------------------------------------------------------- /backend/templates/email/verification.html: -------------------------------------------------------------------------------- 1 |

Hello, {{ username|safe }}!

2 | 3 |

Your password verification key is {{ verification_key }}.

4 |

You can click here to verify your email.

5 | -------------------------------------------------------------------------------- /backend/templates/view.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load render_bundle from webpack_loader %} 3 | 4 | {% block main %} 5 |
6 | {% render_bundle 'vendors' %} 7 | {% render_bundle 'App' %} 8 | 20 | 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /backend/tournament.sql: -------------------------------------------------------------------------------- 1 | -- MAKE A BACKUP ON GCLOUD BEFORE RUNNING THIS 2 | -- Also run this in steps not as a file 3 | 4 | -- 1: Set submissions_enabled to False in api_league 5 | update api_league set submissions_enabled=FALSE; 6 | 7 | -- 2: Change `tour_seed_id` to the current tournament 8 | update api_teamsubmission set tour_seed_id = last_1_id; 9 | 10 | -- 3: Add the tournament to the tournaments table 11 | insert into api_tournament (id, "name", style, date_time, divisions, stream_link, hidden, league_id) 12 | values (2, 'Seeding', 'doubleelim', CURRENTDATE, '{college}', STREAMLINK, True, 0); 13 | 14 | 15 | 16 | -- Get the emails of winning teams 17 | SELECT email from api_user left join api_team_users on api_team_users.user_id = api_user.id 18 | left join api_team on api_team_users.team_id = api_team.id 19 | WHERE api_team."name" in ('wining', 'team', 'names'); 20 | 21 | -- Lock in submissions for more advanced tournaments 22 | UPDATE api_teamsubmission SET tour_intl_qual_id=last_1_id FROM api_team WHERE api_team.id=api_teamsubmission.team_id AND api_team.international AND api_team.student; -------------------------------------------------------------------------------- /backend/uwsgi-dev.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | module=wsgi:application 3 | master=True 4 | home=venv 5 | vacuum=True 6 | max-requests=5000 7 | http-socket=:80 8 | processes=3 9 | harakiri=20 10 | -------------------------------------------------------------------------------- /backend/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | module=wsgi:application 3 | chdir=/code 4 | master=True 5 | pidfile=/tmp/project-master.pid 6 | vacuum=True 7 | max-requests=5000 8 | http-socket=:80 9 | processes=3 10 | harakiri=20 11 | -------------------------------------------------------------------------------- /backend/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for api project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | # Configuring editor styles - https://editorconfig.org/ 2 | 3 | # Basically keeping the legacy settings 4 | 5 | # this is top-most .editorconfig file 6 | root = true 7 | 8 | # Default config 9 | # 2 space indent 10 | # Unix style endline 11 | # UTF-8 encoding 12 | # final newline 13 | [*] 14 | indent_style = space 15 | indent_size = 2 16 | end_of_line = lf 17 | charset = utf-8 18 | insert_final_newline = true 19 | 20 | # For .js or .ts files 21 | [*.{js,ts}] 22 | trim_trailing_whitespace = true 23 | 24 | # For *.json files (packages.json, tsconfig.json, webpack.json, ...) 25 | [*.json] 26 | trim_trailing_whitespace = false 27 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore file for visualizer and playback 2 | # feel free to add additional local paths with brief explanation 3 | 4 | # installed npm modules 5 | */node_modules/ 6 | 7 | # bundled visualizer 8 | visualizer/bc20/ 9 | # built client 10 | dist/ 11 | 12 | # Generated test bc20 files 13 | examples/ 14 | 15 | # any battlecode files 16 | *.bc20 17 | 18 | # for mac users? 19 | **/.DS_Store -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # Battlecode Client 🌱 2 | 3 | ## Overview 4 | Trivial wrapping folder for `playback` and `visualizer`. It handles universal configurations or scripts. 5 | 6 | * `.editorconfig` 7 | * `LICENSE` 8 | * `.gitignore` 9 | * `package.json` 10 | 11 | ### NPM config 12 | Look at `package.json`. 13 | 14 | This NPM module does not have any dependencies or meaningful output, but it is for wrapping scripts of `playback` and `visualizer` in one place. 15 | 16 | * `npm run install-all`: Installs npm packages in `playback` and `visualizer`. **Execute this when you start** 17 | * `npm run build`, `npm run build_playback` 18 | * `npm run electron`: Run the client in electron. You might want to run this most of the time. 19 | * `npm run watch`: Watch for the changes of `visualizer`. Note that it *does not watch* `playback`. 20 | * `npm run prod-electron`, `npm run prod-electron-no-sign`, `npm run prod-test` 21 | * `npm run clean`: Cleans `dist/`. (output folder of `prod`) 22 | -------------------------------------------------------------------------------- /client/bc20/tiled_1-3eMNULX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/bc20/tiled_1-3eMNULX.jpg -------------------------------------------------------------------------------- /client/bc20/tree_bullets-1wQTwL-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/bc20/tree_bullets-1wQTwL-.png -------------------------------------------------------------------------------- /client/bc20/tree_robots-3eqYfGf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/bc20/tree_robots-3eqYfGf.png -------------------------------------------------------------------------------- /client/bc20/yellow_star-1n2ECJB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/bc20/yellow_star-1n2ECJB.png -------------------------------------------------------------------------------- /client/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bc20-client", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bc20-client", 3 | "version": "1.0.0", 4 | "description": "Client wrapper of visualizer and playback", 5 | "main": "visualizer/electron-main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "install_all": "(cd playback && npm install) & (cd visualizer && npm install)", 9 | "clean": "rm -rf dist/", 10 | "build": "(cd playback && npm run build) & (cd visualizer && npm run build)", 11 | "build_playback": "(cd playback && npm run build)", 12 | "electron": "npm run build_playback & (cd visualizer && npm run electron)", 13 | "watch": "npm run build_playback & (cd visualizer && npm run watch)", 14 | "prod-electron": "npm run build_playback & (cd visualizer && npm run prod-electron)", 15 | "prod-electron-no-sign": "npm run build_playback & (cd visualizer && npm run prod-electron-no-sign)", 16 | "prod-test": "npm run build_playback & (cd visualizer && npm run prod-test)" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/battlecode/battlecode20.git" 21 | }, 22 | "author": "Teh Devs", 23 | "license": "GPL-3.0", 24 | "bugs": { 25 | "url": "https://github.com/battlecode/battlecode20/issues" 26 | }, 27 | "homepage": "https://github.com/battlecode/battlecode20#readme" 28 | } 29 | -------------------------------------------------------------------------------- /client/playback/out/game.d.ts: -------------------------------------------------------------------------------- 1 | import Metadata from './metadata'; 2 | import { schema } from 'battlecode-schema'; 3 | import Match from './match'; 4 | /** 5 | * Represents an entire game. 6 | * Contains a Match for every match in a game. 7 | */ 8 | export default class Game { 9 | /** 10 | * Whether the game has finished loading. 11 | */ 12 | readonly finished: boolean; 13 | /** 14 | * The ID the of winner of the overall game. 15 | */ 16 | readonly winner: number; 17 | private _winner; 18 | /** 19 | * Every match that's happened so far. 20 | */ 21 | private readonly _matches; 22 | /** 23 | * Match count. 24 | */ 25 | readonly matchCount: number; 26 | /** 27 | * The metadata of the game. 28 | */ 29 | readonly meta: Metadata; 30 | private _meta; 31 | /** 32 | * Create a Game with nothing inside. 33 | */ 34 | constructor(); 35 | /** 36 | * Get a particular match. 37 | */ 38 | getMatch(index: number): Match; 39 | /** 40 | * Apply an event to the game. 41 | */ 42 | applyEvent(event: schema.EventWrapper): void; 43 | /** 44 | * Apply an event from a NON-GZIPPED ArrayBuffer containing an EventWrapper. 45 | * 46 | * It is expected to be non-gzipped because it was sent over a websocket; if 47 | * you're reading from a file, use loadFullGameRaw. 48 | * 49 | * Do not mutate `data` after calling this function! 50 | */ 51 | applyEventRaw(data: ArrayBuffer): void; 52 | /** 53 | * Load a game all at once. 54 | */ 55 | loadFullGame(wrapper: schema.GameWrapper): void; 56 | /** 57 | * Load a full game from a gzipped ArrayBuffer containing a GameWrapper. 58 | * 59 | * Do not mutate `data` after calling this function! 60 | */ 61 | loadFullGameRaw(data: ArrayBuffer): void; 62 | } 63 | -------------------------------------------------------------------------------- /client/playback/out/index.d.ts: -------------------------------------------------------------------------------- 1 | import GameWorld from './gameworld'; 2 | import * as gameworld from './gameworld'; 3 | import Metadata from './metadata'; 4 | import * as metadata from './metadata'; 5 | import StructOfArrays from './soa'; 6 | import * as soa from './soa'; 7 | import Match from './match'; 8 | import { Log, Block, Transaction } from './match'; 9 | import Game from './game'; 10 | import { flatbuffers, schema } from 'battlecode-schema'; 11 | export { Game, Log, Block, Transaction, Match, GameWorld, gameworld, Metadata, metadata, StructOfArrays, soa, flatbuffers, schema }; 12 | -------------------------------------------------------------------------------- /client/playback/out/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const gameworld_1 = require("./gameworld"); 4 | exports.GameWorld = gameworld_1.default; 5 | const gameworld = require("./gameworld"); 6 | exports.gameworld = gameworld; 7 | const metadata_1 = require("./metadata"); 8 | exports.Metadata = metadata_1.default; 9 | const metadata = require("./metadata"); 10 | exports.metadata = metadata; 11 | const soa_1 = require("./soa"); 12 | exports.StructOfArrays = soa_1.default; 13 | const soa = require("./soa"); 14 | exports.soa = soa; 15 | const match_1 = require("./match"); 16 | exports.Match = match_1.default; 17 | const game_1 = require("./game"); 18 | exports.Game = game_1.default; 19 | const battlecode_schema_1 = require("battlecode-schema"); 20 | exports.flatbuffers = battlecode_schema_1.flatbuffers; 21 | exports.schema = battlecode_schema_1.schema; 22 | // TODO provide ergonomic main export 23 | -------------------------------------------------------------------------------- /client/playback/out/simulator.d.ts: -------------------------------------------------------------------------------- 1 | import GameWorld from './gameworld'; 2 | import { schema } from 'battlecode-schema'; 3 | /** 4 | * A function that runs through a GameWrapper containing a single match, and 5 | * returns the state of the world at the end of the game. 6 | * 7 | * Intended for testing. 8 | */ 9 | export declare function crunch(game: schema.GameWrapper): GameWorld; 10 | -------------------------------------------------------------------------------- /client/playback/out/simulator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const metadata_1 = require("./metadata"); 4 | const gameworld_1 = require("./gameworld"); 5 | const battlecode_schema_1 = require("battlecode-schema"); 6 | /** 7 | * A function that runs through a GameWrapper containing a single match, and 8 | * returns the state of the world at the end of the game. 9 | * 10 | * Intended for testing. 11 | */ 12 | function crunch(game) { 13 | const gameHeader = game.events(0).e(new battlecode_schema_1.schema.GameHeader()); 14 | const metadata = new metadata_1.default().parse(gameHeader); 15 | const world = new gameworld_1.default(metadata); 16 | const matchHeader = game.events(1).e(new battlecode_schema_1.schema.MatchHeader()); 17 | world.loadFromMatchHeader(matchHeader); 18 | for (let i = 2;; i++) { 19 | const event = game.events(i); 20 | if (event.eType() === battlecode_schema_1.schema.Event.MatchFooter) { 21 | return world; 22 | } 23 | // must be a Round 24 | world.processDelta(event.e(new battlecode_schema_1.schema.Round())); 25 | } 26 | } 27 | exports.crunch = crunch; 28 | -------------------------------------------------------------------------------- /client/playback/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "battlecode-playback", 3 | "version": "2019.0.0", 4 | "description": "Play back and analyze battlecode match files.", 5 | "author": "Teh Devs", 6 | "license": "GPL-3.0", 7 | "private": true, 8 | "main": "out/index.js", 9 | "typings": "out/index.d.ts", 10 | "scripts": { 11 | "clean": "rm -rf out", 12 | "build": "tsc -p src", 13 | "lint": "tslint 'src/**/*.ts'", 14 | "gen": "mkdir -p ../examples/ && ts-node src/gen/create.ts", 15 | "watch": "tsc -w -p src", 16 | "test": "npm run gen && blue-tape \"out/gen/test/**/*.js\" | tap-dot" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "github.com/battlecode/battlecode20" 21 | }, 22 | "dependencies": { 23 | "battlecode-schema": "file:../../schema", 24 | "core-js": "^3.3.6", 25 | "deepcopy": "^2.0.0", 26 | "pako": "^1.0.10", 27 | "victor": "^1.1.0" 28 | }, 29 | "devDependencies": { 30 | "@types/blue-tape": "^0.1.33", 31 | "@types/core-js": "^2.5.2", 32 | "@types/node": "^12.12.5", 33 | "@types/pako": "^1.0.1", 34 | "@types/victor": "^1.1.0", 35 | "blue-tape": "^1.0.0", 36 | "npm-force-resolutions": "0.0.3", 37 | "stream": "0.0.2", 38 | "tap-dot": "^2.0.0", 39 | "ts-node": "^8.4.1", 40 | "tslint": "^5.20.0", 41 | "typescript": "^3.6.4" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /client/playback/src/gen/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "outDir": "../../out", 6 | "target": "es6", 7 | "typeRoots": [ 8 | "../../node_modules/@types" 9 | ], 10 | "lib": [ "es2016", "dom" ], 11 | }, 12 | "include": [ 13 | "**/*.ts", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /client/playback/src/index.ts: -------------------------------------------------------------------------------- 1 | import GameWorld from './gameworld'; 2 | import * as gameworld from './gameworld'; 3 | import Metadata from './metadata'; 4 | import * as metadata from './metadata'; 5 | import StructOfArrays from './soa'; 6 | import * as soa from './soa'; 7 | import Match from './match'; 8 | import {Log,Block,Transaction} from './match'; 9 | import Game from './game'; 10 | import { flatbuffers, schema } from 'battlecode-schema'; 11 | 12 | export {Game, Log, Block, Transaction, Match, GameWorld, gameworld, Metadata, metadata, StructOfArrays, soa, flatbuffers, schema}; 13 | 14 | // TODO provide ergonomic main export 15 | -------------------------------------------------------------------------------- /client/playback/src/legacy/bench/run.ts: -------------------------------------------------------------------------------- 1 | import {readFileSync} from 'fs'; 2 | import {crunch} from '../simulator'; 3 | import {schema, flatbuffers} from 'battlecode-schema'; 4 | 5 | const wrapper = schema.GameWrapper.getRootAsGameWrapper( 6 | new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc20'))) 7 | ); 8 | 9 | crunch(wrapper); 10 | -------------------------------------------------------------------------------- /client/playback/src/legacy/bench/runTimeline.ts: -------------------------------------------------------------------------------- 1 | import {readFileSync} from 'fs'; 2 | import {crunch} from '../simulator'; 3 | import {schema, flatbuffers} from 'battlecode-schema'; 4 | import Game from '../../game'; 5 | 6 | const wrapper = schema.GameWrapper.getRootAsGameWrapper( 7 | new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc20'))) 8 | ); 9 | 10 | const game = new Game(); 11 | game.loadFullGame(wrapper); 12 | 13 | for (let i = 0; i < game.matchCount; i++) { 14 | console.log(`running game ${i}`); 15 | game.getMatch(i).compute(0); 16 | } 17 | -------------------------------------------------------------------------------- /client/playback/src/legacy/simulator.ts: -------------------------------------------------------------------------------- 1 | import Metadata from '../metadata'; 2 | import GameWorld from '../gameworld'; 3 | import {schema} from 'battlecode-schema'; 4 | 5 | /** 6 | * A function that runs through a GameWrapper containing a single match, and 7 | * returns the state of the world at the end of the game. 8 | * 9 | * Intended for testing. 10 | */ 11 | export function crunch(game: schema.GameWrapper): GameWorld { 12 | const gameHeader = game.events(0).e(new schema.GameHeader()) as schema.GameHeader; 13 | const metadata = new Metadata().parse(gameHeader); 14 | const world = new GameWorld(metadata); 15 | const matchHeader = game.events(1).e(new schema.MatchHeader()) as schema.MatchHeader; 16 | world.loadFromMatchHeader(matchHeader); 17 | 18 | for (let i = 2;; i++) { 19 | const event = game.events(i); 20 | if (event.eType() === schema.Event.MatchFooter) { 21 | return world; 22 | } 23 | // must be a Round 24 | world.processDelta(event.e(new schema.Round()) as schema.Round); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /client/playback/src/legacy/test/game.ts: -------------------------------------------------------------------------------- 1 | import {schema, flatbuffers} from 'battlecode-schema'; 2 | import {createGameHeader, createEventWrapper} from '../../gen/create'; 3 | 4 | function createMatch(matches: number, turnsPerMatch: number): flatbuffers.Offset { 5 | let builder = new flatbuffers.Builder(); 6 | const header = createGameHeader(builder); 7 | let events: flatbuffers.Offset[] = []; 8 | 9 | events.push(createEventWrapper(builder, createGameHeader(builder), schema.Event.GameHeader)); 10 | 11 | for (let i = 0; i < matches; i++) { 12 | schema.GameMap.startGameMap(builder); 13 | schema.GameMap.addMinCorner(builder, schema.Vec.createVec(builder, -1000, -1000)); 14 | schema.GameMap.addMaxCorner(builder, schema.Vec.createVec(builder, 100000, 100000)); 15 | const map = schema.GameMap.endGameMap(builder); 16 | 17 | schema.MatchHeader.startMatchHeader(builder); 18 | schema.MatchHeader.addMaxRounds(builder, turnsPerMatch); 19 | schema.MatchHeader.addMap(builder, map); 20 | events.push(createEventWrapper(builder, schema.MatchHeader.endMatchHeader(builder), schema.Event.MatchHeader)); 21 | 22 | 23 | 24 | } 25 | 26 | return -1; 27 | } 28 | -------------------------------------------------------------------------------- /client/playback/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "outDir": "../out", 6 | "target": "es6", 7 | "declaration": true, 8 | "typeRoots": [ 9 | "../../node_modules/@types" 10 | ], 11 | "lib": [ "es2016", "dom" ], 12 | }, 13 | "include": [ 14 | "*.ts", 15 | ], 16 | "exclude": [ 17 | "legacy/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /client/visualizer/build/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/build/icon.png -------------------------------------------------------------------------------- /client/visualizer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Battlecode Client 5 | 6 | 7 | 8 |
9 | 10 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /client/visualizer/src/electron-modules.ts: -------------------------------------------------------------------------------- 1 | // This file is a dirty hack that is necessary because nobody expected anyone 2 | // to make an app that runs both in the browser and electron. 3 | 4 | // To add another electron-exclusive module, add it to this file, 5 | // and add it to 'externals' for non-webpack in webpack.config.js 6 | 7 | // if we're on the web, we define these objects to be null 8 | // they will ERROR AT RUNTIME if used 9 | // only use them if you've made sure that process.env.ELECTRON === true 10 | 11 | // ambient webpack function: creates modules 12 | declare function define(...args: any[]); 13 | 14 | // only define if non-browser 15 | if (!process.env.ELECTRON) { 16 | define('electron', [], () => null); 17 | define('os', [], () => null); 18 | define('fs', [], () => null); 19 | define('path', [], () => null); 20 | define('child_process', [], () => null); 21 | define('http', [], () => null); 22 | } 23 | 24 | // in electron, actually imports 25 | // in browser, imports null 26 | import * as _electron from 'electron'; 27 | import * as _os from 'os'; 28 | import * as _fs from 'fs'; 29 | import * as _path from 'path'; 30 | import * as _child_process from 'child_process'; 31 | import * as _http from 'http'; 32 | 33 | export var electron = _electron; 34 | export var os = _os; 35 | export var fs = _fs; 36 | export var path = _path; 37 | export var child_process = _child_process; 38 | export var http = _http; 39 | 40 | export default { 41 | electron: _electron, 42 | os: _os, 43 | fs: _fs, 44 | path: _path, 45 | child_process: _child_process, 46 | http: _http 47 | } 48 | -------------------------------------------------------------------------------- /client/visualizer/src/game/fps.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * FPS Counter math. 3 | */ 4 | export default class TickCounter { 5 | private smoothing: number; 6 | private updateEvery: number; 7 | private lastUpdate: number; 8 | private ticksSinceUpdate: number; 9 | 10 | /** 11 | * Ticks per second. 12 | */ 13 | tps: number; 14 | 15 | /** 16 | * @param smoothing 17 | * @param updateEvery how frequently to update the FPS counter, in ms 18 | */ 19 | constructor(smoothing: number, updateEvery: number) { 20 | this.smoothing = smoothing; 21 | this.updateEvery = updateEvery; 22 | this.lastUpdate = 0; 23 | this.ticksSinceUpdate = 0; 24 | this.tps = 0; 25 | } 26 | 27 | /** 28 | * @param time the system time in ms 29 | * @param ticks the ticks since the last update 30 | */ 31 | update(time: number, ticks: number) { 32 | this.ticksSinceUpdate += ticks; 33 | 34 | if (time > this.lastUpdate + this.updateEvery) { 35 | this.lastUpdate = time; 36 | this.tps = this.smoothing * (this.ticksSinceUpdate / (this.updateEvery / 1000)) + 37 | (1 - this.smoothing) * this.tps; 38 | this.ticksSinceUpdate = 0; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /client/visualizer/src/game/index.ts: -------------------------------------------------------------------------------- 1 | import GameArea from './gamearea/gamearea'; 2 | import Renderer from './gamearea/renderer'; 3 | 4 | import Console from './sidebar/console'; 5 | import MapFilter from './sidebar/mapfilter'; 6 | import {MapSchema} from './sidebar/mapfilter'; 7 | import {MapType} from '../constants'; 8 | import MatchQueue from './sidebar/matchqueue'; 9 | import MatchRunner from './sidebar/matchrunner'; 10 | import Stats from './sidebar/stats'; 11 | import Profiler from './sidebar/profiler'; 12 | 13 | import TickCounter from './fps'; 14 | import {NextStepSchema} from './nextstep'; 15 | import NextStep from './nextstep'; 16 | 17 | export {GameArea, Renderer}; 18 | export {Console, MapType, MapSchema, MapFilter, MatchQueue, MatchRunner, Stats, Profiler}; 19 | export {TickCounter, NextStepSchema, NextStep}; 20 | -------------------------------------------------------------------------------- /client/visualizer/src/game/nextstep.ts: -------------------------------------------------------------------------------- 1 | import {StructOfArrays, Metadata, GameWorld, schema} from 'battlecode-playback'; 2 | 3 | export type NextStepSchema = { 4 | id: Int32Array, 5 | x: Int32Array, 6 | y: Int32Array 7 | } 8 | 9 | /** 10 | * For interpolated rendering. 11 | */ 12 | export default class NextStep { 13 | /** 14 | * { 15 | * id: Int32Array, 16 | * x: Int32Array, 17 | * y: Int32Array 18 | * } 19 | */ 20 | bodies: StructOfArrays; 21 | 22 | // Cache fields 23 | private _vecTableSlot: schema.VecTable; 24 | 25 | constructor() { 26 | this.bodies = new StructOfArrays({ 27 | id: new Int32Array(0), 28 | x: new Int32Array(0), 29 | y: new Int32Array(0) 30 | }, 'id'); 31 | this._vecTableSlot = new schema.VecTable(); 32 | } 33 | 34 | /** 35 | * Load where robots will be in the next time step, 36 | * so that we can smoothly transition between steps. 37 | */ 38 | loadNextStep(world: GameWorld, delta: schema.Round) { 39 | this.bodies.copyFrom(world.bodies); 40 | if (delta.roundID() != world.turn + 1) { 41 | throw new Error(`Bad Round [lerp]: world.turn = ${world.turn}, round.roundID() = ${delta.roundID()}`); 42 | } 43 | 44 | const movedLocs = delta.movedLocs(this._vecTableSlot); 45 | if(delta!==null && movedLocs!==null){ 46 | this.bodies.alterBulk({ 47 | id: delta.movedIDsArray(), 48 | x: movedLocs.xsArray(), 49 | y: movedLocs.ysArray() 50 | }); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /client/visualizer/src/mapeditor/index.ts: -------------------------------------------------------------------------------- 1 | import MapGenerator from './action/generator'; 2 | import {MapUnit, Symmetry} from './action/renderer'; 3 | import MapRenderer from './action/renderer'; 4 | import MapValidator from './action/validator'; 5 | 6 | import {UnitForm} from './forms/unit'; 7 | // import ArchonForm from './forms/archon'; 8 | import HeaderForm from './forms/header'; 9 | import RobotForm from './forms/robots'; 10 | import SymmetryForm from './forms/symmetry'; 11 | // import TreeForm from './forms/tree'; 12 | 13 | import {GameMap} from './form'; 14 | import MapEditorForm from './form'; 15 | import MapEditor from './mapeditor'; 16 | 17 | export {MapGenerator, MapUnit, Symmetry, MapRenderer, MapValidator} 18 | export {UnitForm, HeaderForm, RobotForm, SymmetryForm} 19 | export {GameMap, MapEditorForm, MapEditor}; -------------------------------------------------------------------------------- /client/visualizer/src/static/css/tournament.css: -------------------------------------------------------------------------------- 1 | .blackout { 2 | width: 100vw; 3 | height: 100vh; 4 | position: fixed; 5 | top: 0px; 6 | left: 0px; 7 | 8 | background-color: black; 9 | color: white; 10 | font-size: 50px; 11 | text-align: center; 12 | z-index: 5; 13 | } 14 | 15 | .blackout-container { 16 | margin-top: 10vh; 17 | margin-left: 16vw; 18 | margin-right: 16vw; 19 | } 20 | 21 | .tournament-header { 22 | font-size: 72px; 23 | } 24 | .tournament-subheader { 25 | font-size: 18px; 26 | } 27 | .tournament-extra { 28 | color: gray; 29 | } 30 | 31 | .column-left { 32 | float: left; 33 | width: 47%; 34 | } 35 | 36 | .column-center { 37 | display: inline-block; 38 | width: 6%; 39 | line-height: 20vw; 40 | } 41 | 42 | .column-right { 43 | float: right; 44 | width: 47%; 45 | } 46 | 47 | .avatar { 48 | width: 20vw; 49 | height: 20vw; 50 | margin-bottom: 32px; 51 | } 52 | 53 | .big-avatar { 54 | width: 25vw; 55 | height: 25vw; 56 | margin-bottom: 32px; 57 | } 58 | 59 | .scorecard { 60 | margin-top: 3px; 61 | font-size: 40px; 62 | margin-bottom: 32px; 63 | } 64 | -------------------------------------------------------------------------------- /client/visualizer/src/static/img/bullets/bullet_fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/bullets/bullet_fast.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/bullets/bullet_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/bullets/bullet_medium.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/bullets/bullet_slow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/bullets/bullet_slow.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/go-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/go-next.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/go-previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/go-previous.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/playback-pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/playback-pause.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/playback-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/playback-start.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/playback-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/playback-stop.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/seek-backward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/seek-backward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/seek-forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/seek-forward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/skip-backward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/skip-backward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/skip-forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/skip-forward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/Legacy/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/Legacy/upload.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/go-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/go-next.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/go-previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/go-previous.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/green-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/green-next.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/green-previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/green-previous.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/playback-pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/playback-pause.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/playback-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/playback-start.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/playback-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/playback-stop.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/reverse.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/skip-backward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/skip-backward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/skip-forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/skip-forward.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/controls/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/controls/upload.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/full_health_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/full_health_tree.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/low_health_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/low_health_tree.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/sapling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/sapling.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/tiled_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/tiled_1.jpg -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/tree_bullets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/tree_bullets.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/map/tree_robots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/map/tree_robots.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/soup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/soup.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Cow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Cow.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Drone_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Drone_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Drone_blue_carry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Drone_blue_carry.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Drone_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Drone_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Drone_red_carry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Drone_red_carry.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Fulfillment_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Fulfillment_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Fulfillment_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Fulfillment_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/HQ_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/HQ_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/HQ_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/HQ_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Landscaper_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Landscaper_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Landscaper_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Landscaper_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Miner_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Miner_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Miner_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Miner_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Net_gun_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Net_gun_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Net_gun_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Net_gun_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Refinery_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Refinery_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Refinery_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Refinery_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/SOUPER_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/SOUPER_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/SOUPER_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/SOUPER_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Vaporator_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Vaporator_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/Vaporator_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/Vaporator_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/archon_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/archon_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/archon_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/archon_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/archon_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/archon_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/bullet_tree_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/bullet_tree_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/bullet_tree_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/bullet_tree_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/bullet_tree_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/bullet_tree_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/gardener_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/gardener_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/gardener_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/gardener_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/gardener_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/gardener_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/lumberjack_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/lumberjack_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/lumberjack_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/lumberjack_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/lumberjack_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/lumberjack_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/recruit_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/recruit_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/recruit_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/recruit_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/recruit_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/recruit_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/scout_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/scout_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/scout_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/scout_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/scout_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/scout_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/soldier_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/soldier_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/soldier_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/soldier_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/soldier_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/soldier_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/tank_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/tank_blue.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/tank_neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/tank_neutral.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/tank_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/tank_red.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/sprites/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/sprites/unknown.png -------------------------------------------------------------------------------- /client/visualizer/src/static/img/yellow_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/client/visualizer/src/static/img/yellow_star.png -------------------------------------------------------------------------------- /client/visualizer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // TODO: is it really a good idea to have es5 as target and es2016 in the lib section?? 4 | "target": "es5", 5 | "strictNullChecks": true, 6 | "sourceMap": true, 7 | "lib": ["es2016", "dom"], 8 | "types": ["node"] 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /docker-compose-b.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | 5 | # frontend: 6 | # build: 7 | # context: ./frontend 8 | # dockerfile: Dockerfile.dev 9 | # volumes: 10 | # - ./frontend:/code 11 | # ports: 12 | # - 3000:3000 13 | # # environment: 14 | # # - NODE_PATH=/install/node_modules 15 | 16 | backend: 17 | build: 18 | context: ./backend 19 | dockerfile: Dockerfile 20 | volumes: 21 | - ./backend:/code 22 | ports: 23 | - 8000:80 24 | environment: 25 | - DJANGO_SETTINGS_MODULE=dev_settings 26 | - DB_HOST_BC_DEV=db 27 | # command: bash -c 'while !GameActionException to be thrown. 6 | *

7 | * Each GameActionException has a type that roughly identifies what 8 | * caused the exception. 9 | *

10 | * In addition to GameActionException, 11 | * some robot functions can throw the unchecked exceptions 12 | * {@link IllegalStateException} and {@link IllegalArgumentException}. 13 | * An IllegalStateException is thrown if this robot can 14 | * never successfully call the function. 15 | * An IllegalArgumentException is thrown if this type of 16 | * robot can never successfully call the function with the given arguments. 17 | * A GameActionException is thrown in all other circumstances. 18 | */ 19 | public class GameActionException extends Exception { 20 | 21 | static final long serialVersionUID = 0x5def11da; 22 | private final GameActionExceptionType type; 23 | 24 | /** 25 | * Creates a GameActionException with the given type and message. 26 | * @param type the type of the GameActionException 27 | * @param message the error message 28 | */ 29 | public GameActionException(GameActionExceptionType type, String message) { 30 | super(message); 31 | this.type = type; 32 | } 33 | 34 | /** 35 | * Gives the type of gameworld interaction that caused this GameActionException, which 36 | * was specified when this instance was constructed. 37 | * 38 | * @return this GameActionException's type. 39 | */ 40 | public GameActionExceptionType getType() { 41 | return type; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/common/GameActionExceptionType.java: -------------------------------------------------------------------------------- 1 | package battlecode.common; 2 | 3 | /** 4 | * Enumerates the possible errors in GameWorld interactions that cause a GameActionException to be thrown. 5 | */ 6 | public enum GameActionExceptionType { 7 | 8 | /** 9 | * Internal error in the GameWorld engine. This is bad. 10 | */ 11 | INTERNAL_ERROR, 12 | /** 13 | * Indicates when a robot tries to perform an action for which it does not have enough resources. 14 | */ 15 | NOT_ENOUGH_RESOURCE, 16 | /** 17 | * Indicates when a robot tries to move into a non-empty location. 18 | */ 19 | CANT_MOVE_THERE, 20 | /** 21 | * Indicates when a robot tries to execute an action, but is not currently idle. 22 | */ 23 | IS_NOT_READY, 24 | /** 25 | * Indicates when a robot tries to sense a robot that no longer exists or is no longer 26 | * in this robot's sensor range. 27 | */ 28 | CANT_SENSE_THAT, 29 | /** 30 | * Indicates when a robot tries to perform an action on a location that is outside 31 | * its range. 32 | */ 33 | OUT_OF_RANGE, 34 | /** 35 | * Indicates when a robot tries to perform an action it can't. 36 | */ 37 | CANT_DO_THAT, 38 | /** 39 | * Indicates when a robot tries to pick up a unit but can't. 40 | */ 41 | CANT_PICK_UP_UNIT, 42 | /** 43 | * Indicates when a robot tries to perform an action on another robot, but there is 44 | * no suitable robot there. 45 | */ 46 | NO_ROBOT_THERE, 47 | /** 48 | * Indicates when a robot tries to messages of an incorrect size to the blockchain. 49 | */ 50 | INCORRECT_BLOCKCHAIN_TRANSACTION_LENGTH, 51 | /** 52 | * Indicates when round number is out of range. 53 | */ 54 | ROUND_OUT_OF_RANGE 55 | } 56 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/common/Team.java: -------------------------------------------------------------------------------- 1 | package battlecode.common; 2 | 3 | /** 4 | * This enum represents the team of a robot. A robot is on exactly one team. 5 | * Player robots are on either team A or team B. 6 | *

7 | * Since Team is a Java 1.5 enum, you can use it in switch 8 | * statements, it has all the standard enum methods (valueOf, 9 | * values, etc.), and you can safely use == for 10 | * equality tests. 11 | */ 12 | public enum Team { 13 | /** 14 | * Team A. 15 | */ 16 | A, 17 | /** 18 | * Team B. 19 | */ 20 | B, 21 | /** 22 | * Neutral robots. 23 | */ 24 | NEUTRAL; 25 | 26 | /** 27 | * Determines the team that is the opponent of this team. 28 | * 29 | * @return the opponent of this team. 30 | * 31 | * @battlecode.doc.costlymethod 32 | */ 33 | public Team opponent() { 34 | switch (this) { 35 | case A: 36 | return B; 37 | case B: 38 | return A; 39 | default: 40 | return NEUTRAL; 41 | } 42 | } 43 | 44 | /** 45 | * Returns whether a robot of this team is a player-controlled entity 46 | * (team A or team B). 47 | * 48 | * @return true a robot of this team is player-controlled; false otherwise. 49 | * 50 | * @battlecode.doc.costlymethod 51 | */ 52 | public boolean isPlayer() { 53 | return this == A || this == B; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/InstrumentationException.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter; 2 | 3 | /** 4 | * An exception used to indicate that there was a problem instrumenting a player (e.g., the player references a 5 | * disallowed class, or one if its classes can't be found). This must be an unchecked Exception, because it 6 | * has to be thrown in overriden methods. 7 | * 8 | * @author adamd 9 | */ 10 | public class InstrumentationException extends RuntimeException { 11 | 12 | public enum Type { 13 | ILLEGAL, 14 | MISSING 15 | } 16 | 17 | public final Type type; 18 | 19 | public InstrumentationException(Type type, String message) { 20 | super(message); 21 | this.type = type; 22 | } 23 | 24 | public InstrumentationException(Type type, String message, Throwable cause) { 25 | super(message, cause); 26 | this.type = type; 27 | } 28 | 29 | @Override 30 | public String getMessage() { 31 | return type + " " + super.getMessage(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/RobotDeathException.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter; 2 | 3 | /** 4 | * An exception used to kill robot threads when their robot dies in the game. In other words, when a robot 5 | * dies, a RobotDeathException is thrown in the robot's thread, and it propagates all the way up to RobotRunnable, 6 | * ending the robot's thread. This must be an unchecked exception, since it could be thrown anywhere in the player's code. 7 | * 8 | * @author adamd 9 | */ 10 | public class RobotDeathException extends VirtualMachineError { 11 | 12 | public RobotDeathException() { 13 | super(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/bytecode/resources/AllowedPackages.txt: -------------------------------------------------------------------------------- 1 | java/io 2 | java/lang 3 | java/lang/invoke 4 | java/math 5 | java/util 6 | java/util/function 7 | java/util/regex 8 | java/util/stream 9 | java/text 10 | battlecode/common 11 | scala 12 | scala/collection 13 | scala/collection/generic 14 | scala/collection/immutable 15 | scala/collection/interfaces 16 | scala/collection/mutable 17 | scala/collection/script 18 | scala/math 19 | scala/runtime 20 | scala/util 21 | scala/util/automata 22 | scala/util/continuations 23 | scala/util/control 24 | scala/util/grammar 25 | scala/util/logging 26 | scala/util/regexp 27 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/bytecode/resources/DisallowedClasses.txt: -------------------------------------------------------------------------------- 1 | java/io/File 2 | java/io/FileDescriptor 3 | java/io/FileInputStream 4 | java/io/FileOutputStream 5 | java/io/FilePermission 6 | java/io/FileReader 7 | java/io/FileWriter 8 | java/io/RandomAccessFile 9 | java/io/SerializablePermission 10 | java/lang/ClassLoader 11 | java/lang/Compiler 12 | java/lang/InheritableThreadLocal 13 | java/lang/Package 14 | java/lang/Process 15 | java/lang/ProcessBuilder 16 | java/lang/Runtime 17 | java/lang/RuntimePermission 18 | java/lang/SecurityManager 19 | java/lang/Thread 20 | java/lang/ThreadGroup 21 | java/lang/ThreadLocal 22 | java/lang/invoke/SwitchPoint 23 | java/lang/invoke/MethodHandleProxies 24 | java/util/Calendar 25 | java/util/Currency 26 | java/util/Date 27 | java/util/EventListener 28 | java/util/EventListenerProxy 29 | java/util/EventObject 30 | java/util/FormattableFlags 31 | java/util/Formatter 32 | java/util/GregorianCalendar 33 | java/util/ListResourceBundle 34 | java/util/Locale 35 | java/util/MissingResourceException 36 | java/util/Properties 37 | java/util/PropertyPermission 38 | java/util/PropertyResourceBundle 39 | java/util/ResourceBundle 40 | java/util/SimpleTimeZone 41 | java/util/TimeZone 42 | java/util/Timer 43 | java/util/TimerTask 44 | java/util/UUID 45 | java/util/WeakHashMap 46 | scala/Symbol 47 | scala/Symbol$ 48 | scala/runtime/MethodCache 49 | scala/util/DynamicVariable 50 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/AtomicInteger.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | @SuppressWarnings("unused") 4 | public class AtomicInteger { 5 | 6 | private int l; 7 | 8 | public AtomicInteger() { 9 | } 10 | 11 | public AtomicInteger(int x) { 12 | l = x; 13 | } 14 | 15 | public int get() { 16 | return l; 17 | } 18 | 19 | public void set(int x) { 20 | l = x; 21 | } 22 | 23 | public boolean compareAndSet(int expect, int update) { 24 | boolean b = (l == expect); 25 | if (b) l = update; 26 | return b; 27 | } 28 | 29 | public int incrementAndGet() { 30 | return ++l; 31 | } 32 | 33 | public int decrementAndGet() { 34 | return --l; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/AtomicLong.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | // Fake AtomicLong class, needed by java.util.Random. 4 | @SuppressWarnings("unused") 5 | public class AtomicLong { 6 | 7 | private long l; 8 | 9 | public AtomicLong() { 10 | } 11 | 12 | public AtomicLong(long x) { 13 | l = x; 14 | } 15 | 16 | public long get() { 17 | return l; 18 | } 19 | 20 | public void set(long x) { 21 | l = x; 22 | } 23 | 24 | public boolean compareAndSet(long expect, long update) { 25 | boolean b = (l == expect); 26 | if (b) l = update; 27 | return b; 28 | } 29 | 30 | public long incrementAndGet() { 31 | return ++l; 32 | } 33 | 34 | public long getAndIncrement() { 35 | return l++; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/AtomicReference.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | @SuppressWarnings("unused") 4 | public class AtomicReference { 5 | 6 | private V v; 7 | 8 | public AtomicReference() { 9 | } 10 | 11 | public AtomicReference(V w) { 12 | v = w; 13 | } 14 | 15 | public boolean compareAndSet(V e, V u) { 16 | if (v == e) { 17 | v = u; 18 | return true; 19 | } else 20 | return false; 21 | } 22 | 23 | public V get() { 24 | return v; 25 | } 26 | 27 | public V getAndSet(V w) { 28 | V vold = v; 29 | v = w; 30 | return vold; 31 | } 32 | 33 | public void lazySet(V w) { 34 | v = w; 35 | } 36 | 37 | public void set(V w) { 38 | v = w; 39 | } 40 | 41 | public String toString() { 42 | if (v == null) 43 | return "null"; 44 | else 45 | return v.toString(); 46 | } 47 | 48 | public boolean weakCompareAndSet(V e, V u) { 49 | return compareAndSet(e, u); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/ConcurrentHashMap.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | import java.util.Hashtable; 4 | import java.util.concurrent.ConcurrentMap; 5 | 6 | /** 7 | * ConcurrentMap implementation that isn't really concurrent. 8 | * Needed to instrument Clojure. 9 | */ 10 | @SuppressWarnings("unused") 11 | public class ConcurrentHashMap extends Hashtable implements ConcurrentMap { 12 | 13 | public V putIfAbsent(K key, V value) { 14 | if (!containsKey(key)) 15 | return put(key, value); 16 | else 17 | return get(key); 18 | } 19 | 20 | public boolean remove(Object key, Object value) { 21 | if (containsKey(key) && get(key).equals(value)) { 22 | remove(key); 23 | return true; 24 | } else return false; 25 | } 26 | 27 | public boolean replace(K key, V oldValue, V newValue) { 28 | if (containsKey(key) && get(key).equals(oldValue)) { 29 | put(key, newValue); 30 | return true; 31 | } else return false; 32 | } 33 | 34 | public V replace(K key, V value) { 35 | if (containsKey(key)) { 36 | return put(key, value); 37 | } else return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/Thread.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | import battlecode.instrumenter.InstrumentationException; 4 | 5 | import static battlecode.instrumenter.InstrumentationException.Type.ILLEGAL; 6 | 7 | @SuppressWarnings("unused") 8 | public class Thread extends java.lang.Thread { 9 | 10 | private static Thread INSTANCE = new Thread(false); 11 | 12 | private Thread(boolean b) { 13 | } 14 | 15 | public Thread() { 16 | throw new InstrumentationException(ILLEGAL, "You can't start threads; try using multiple robots."); 17 | } 18 | 19 | public Thread(Runnable r) { 20 | throw new InstrumentationException(ILLEGAL, "You can't start threads; try using multiple robots."); 21 | } 22 | 23 | public static Thread currentThread() { 24 | return INSTANCE; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/inject/Unsafe.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.inject; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Do-nothing replacement for sun.misc.Unsafe. Used by Random. 7 | */ 8 | @SuppressWarnings("unused") 9 | public class Unsafe { 10 | 11 | private Unsafe() { 12 | } 13 | 14 | private static Unsafe instance = new Unsafe(); 15 | 16 | public static Unsafe getUnsafe() { 17 | return instance; 18 | } 19 | 20 | public long objectFieldOffset(Field f) { 21 | return 0; 22 | } 23 | 24 | public void putObjectVolatile(Object o, long offset, Object x) { 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/profiler/ProfilerCollection.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.profiler; 2 | 3 | import battlecode.common.RobotType; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * A ProfilerCollection is a collection of all Profiler instances for a team for a match. 12 | */ 13 | public class ProfilerCollection { 14 | private List profilers = new ArrayList<>(); 15 | 16 | private List frames = new ArrayList<>(); 17 | private Map frameIds = new HashMap<>(); 18 | 19 | public Profiler createProfiler(int robotId, RobotType robotType) { 20 | // The name has to be display-friendly 21 | String name = String.format("#%s (%s)", robotId, robotType.toString()); 22 | 23 | Profiler profiler = new Profiler(name, this::getFrameId); 24 | profilers.add(profiler); 25 | return profiler; 26 | } 27 | 28 | public List getFrames() { 29 | return frames; 30 | } 31 | 32 | public List getProfilers() { 33 | return profilers; 34 | } 35 | 36 | private int getFrameId(String methodName) { 37 | if (!frameIds.containsKey(methodName)) { 38 | frames.add(methodName); 39 | frameIds.put(methodName, frames.size() - 1); 40 | } 41 | 42 | return frameIds.get(methodName); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/profiler/ProfilerEvent.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.profiler; 2 | 3 | public class ProfilerEvent { 4 | private ProfilerEventType type; 5 | private int at; 6 | private int frameId; 7 | 8 | public ProfilerEvent(ProfilerEventType type, int at, int frameId) { 9 | this.type = type; 10 | this.at = at; 11 | this.frameId = frameId; 12 | } 13 | 14 | public ProfilerEventType getType() { 15 | return type; 16 | } 17 | 18 | public int getAt() { 19 | return at; 20 | } 21 | 22 | public int getFrameId() { 23 | return frameId; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/profiler/ProfilerEventType.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.profiler; 2 | 3 | public enum ProfilerEventType { 4 | OPEN("O"), CLOSE("C"); 5 | 6 | private final String value; 7 | 8 | ProfilerEventType(String value) { 9 | this.value = value; 10 | } 11 | 12 | public String getValue() { 13 | return value; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/instrumenter/stream/EOFInputStream.java: -------------------------------------------------------------------------------- 1 | package battlecode.instrumenter.stream; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * Boring input stream. 8 | */ 9 | public class EOFInputStream extends InputStream { 10 | @Override 11 | public int read() throws IOException { 12 | throw new java.io.EOFException(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/schema/Event.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | /** 6 | * An Event is a single step that needs to be processed. 7 | * A saved game simply consists of a long list of Events. 8 | * Events can be divided by either being sent separately (e.g. as separate 9 | * websocket messages), or by being wrapped with a GameWrapper. 10 | * A game consists of a series of matches; a match consists of a series of 11 | * rounds, and is played on a single map. Each round is a single simulation 12 | * step. 13 | */ 14 | public final class Event { 15 | private Event() { } 16 | public static final byte NONE = 0; 17 | /** 18 | * There should only be one GameHeader, at the start of the stream. 19 | */ 20 | public static final byte GameHeader = 1; 21 | /** 22 | * There should be one MatchHeader at the start of each match. 23 | */ 24 | public static final byte MatchHeader = 2; 25 | /** 26 | * A single simulation step. A round may be skipped if 27 | * nothing happens during its time. 28 | */ 29 | public static final byte Round = 3; 30 | /** 31 | * There should be one MatchFooter at the end of each simulation step. 32 | */ 33 | public static final byte MatchFooter = 4; 34 | /** 35 | * There should only be one GameFooter, at the end of the stream. 36 | */ 37 | public static final byte GameFooter = 5; 38 | 39 | public static final String[] names = { "NONE", "GameHeader", "MatchHeader", "Round", "MatchFooter", "GameFooter", }; 40 | 41 | public static String name(int e) { return names[e]; } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/schema/EventWrapper.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * Necessary due to flatbuffers requiring unions to be wrapped in tables. 13 | */ 14 | public final class EventWrapper extends Table { 15 | public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb) { return getRootAsEventWrapper(_bb, new EventWrapper()); } 16 | public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb, EventWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } 17 | public EventWrapper __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 18 | 19 | public byte eType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } 20 | public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; } 21 | 22 | public static int createEventWrapper(FlatBufferBuilder builder, 23 | byte e_type, 24 | int eOffset) { 25 | builder.startObject(2); 26 | EventWrapper.addE(builder, eOffset); 27 | EventWrapper.addEType(builder, e_type); 28 | return EventWrapper.endEventWrapper(builder); 29 | } 30 | 31 | public static void startEventWrapper(FlatBufferBuilder builder) { builder.startObject(2); } 32 | public static void addEType(FlatBufferBuilder builder, byte eType) { builder.addByte(0, eType, 0); } 33 | public static void addE(FlatBufferBuilder builder, int eOffset) { builder.addOffset(1, eOffset, 0); } 34 | public static int endEventWrapper(FlatBufferBuilder builder) { 35 | int o = builder.endObject(); 36 | return o; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/schema/GameFooter.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * The final event sent in the game. 13 | */ 14 | public final class GameFooter extends Table { 15 | public static GameFooter getRootAsGameFooter(ByteBuffer _bb) { return getRootAsGameFooter(_bb, new GameFooter()); } 16 | public static GameFooter getRootAsGameFooter(ByteBuffer _bb, GameFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } 17 | public GameFooter __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 18 | 19 | /** 20 | * The ID of the winning team of the game. 21 | */ 22 | public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } 23 | 24 | public static int createGameFooter(FlatBufferBuilder builder, 25 | byte winner) { 26 | builder.startObject(1); 27 | GameFooter.addWinner(builder, winner); 28 | return GameFooter.endGameFooter(builder); 29 | } 30 | 31 | public static void startGameFooter(FlatBufferBuilder builder) { builder.startObject(1); } 32 | public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } 33 | public static int endGameFooter(FlatBufferBuilder builder) { 34 | int o = builder.endObject(); 35 | return o; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/schema/Vec.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * A vector in two-dimensional space. Discrete space, of course. 13 | * Defaults to the 0 vector. 14 | */ 15 | public final class Vec extends Struct { 16 | public Vec __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 17 | 18 | public int x() { return bb.getInt(bb_pos + 0); } 19 | public int y() { return bb.getInt(bb_pos + 4); } 20 | 21 | public static int createVec(FlatBufferBuilder builder, int x, int y) { 22 | builder.prep(4, 8); 23 | builder.putInt(y); 24 | builder.putInt(x); 25 | return builder.offset(); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/server/GameState.java: -------------------------------------------------------------------------------- 1 | package battlecode.server; 2 | 3 | public enum GameState { 4 | RUNNING, 5 | DONE 6 | } 7 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/server/ServerState.java: -------------------------------------------------------------------------------- 1 | package battlecode.server; 2 | 3 | /** 4 | * Represents the state of a match in a running server. 5 | */ 6 | public enum ServerState { 7 | 8 | /** 9 | * The match is not ready for running yet. 10 | */ 11 | NOT_READY, 12 | 13 | /** 14 | * The match is ready to start running. 15 | */ 16 | READY, 17 | 18 | /** 19 | * The match is running. 20 | */ 21 | RUNNING, 22 | 23 | /** 24 | * The match is paused. 25 | */ 26 | PAUSED, 27 | 28 | /** 29 | * The match has finished running. 30 | */ 31 | FINISHED, 32 | 33 | /** 34 | * The match could not be run because the server experienced an error. 35 | */ 36 | ERROR 37 | } 38 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/server/Version.java: -------------------------------------------------------------------------------- 1 | package battlecode.server; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | 6 | /** 7 | * Utility class for determining the java version. 8 | * 9 | * @author james 10 | */ 11 | public class Version { 12 | /** 13 | * The version of battlecode. 14 | */ 15 | public final static String version; 16 | 17 | static { 18 | String readVersion; 19 | try (final BufferedReader r = new BufferedReader(new InputStreamReader( 20 | Version.class.getClassLoader().getResourceAsStream("battlecode-version")))) { 21 | readVersion = r.readLine(); 22 | } catch (Exception e) { 23 | System.err.println("Can't open version"); 24 | e.printStackTrace(); 25 | readVersion = "UNKNOWN"; 26 | } 27 | version = readVersion; 28 | } 29 | 30 | /** 31 | * @param args unused 32 | */ 33 | public static void main(String[] args) { 34 | System.out.println(version); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/util/TeamMapping.java: -------------------------------------------------------------------------------- 1 | package battlecode.util; 2 | 3 | import battlecode.common.Team; 4 | 5 | import java.util.EnumMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * Utility 10 | * 11 | * @author james 12 | */ 13 | public final class TeamMapping { 14 | private static final Map teamsToIds = new EnumMap<>(Team.class); 15 | static { 16 | teamsToIds.put(Team.NEUTRAL, (byte)0); 17 | teamsToIds.put(Team.A, (byte)1); 18 | teamsToIds.put(Team.B, (byte)2); 19 | } 20 | private static final Team[] idsToTeams = {Team.NEUTRAL, Team.A, Team.B}; 21 | 22 | /** 23 | * Get the team for a team ID 24 | */ 25 | public static Team team(byte id) { 26 | return idsToTeams[id]; 27 | } 28 | 29 | /** 30 | * Get the ID for a team 31 | */ 32 | public static byte id(Team team) { 33 | return teamsToIds.get(team); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/DominationFactor.java: -------------------------------------------------------------------------------- 1 | package battlecode.world; 2 | 3 | /** 4 | * Determines roughly by how much the winning team won. 5 | */ 6 | public enum DominationFactor { 7 | /** 8 | * Win by coin flip (tiebreak 5). 9 | */ 10 | WON_BY_DUBIOUS_REASONS, 11 | /** 12 | * Win by highest robot ID (tiebreak 4). 13 | */ 14 | HIGHBORN, 15 | /** 16 | * Win by more successful broadcasts (tiebreak 3). 17 | */ 18 | GOSSIP_GIRL, 19 | /** 20 | * Win by having higher net worth: soup + soup costs of robots (tiebreak 2). 21 | */ 22 | QUALITY_OVER_QUANTITY, 23 | /** 24 | * Win by having more robots (tiebreak 1). 25 | */ 26 | QUANTITY_OVER_QUALITY, 27 | /** 28 | * Win by enemy HQ being destroyed. 29 | */ 30 | HQ_DESTROYED 31 | } 32 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/GameStats.java: -------------------------------------------------------------------------------- 1 | package battlecode.world; 2 | 3 | import battlecode.common.Team; 4 | 5 | /** 6 | * Class to hold any game stats desired for a specific match 7 | * such as winner and domination factor 8 | */ 9 | public class GameStats { 10 | 11 | private Team winner; 12 | private DominationFactor dominationFactor; 13 | 14 | public GameStats() { 15 | this.winner = null; 16 | this.dominationFactor = null; 17 | } 18 | 19 | public void setWinner(Team t) { 20 | winner = t; 21 | } 22 | 23 | public void setDominationFactor(DominationFactor d) { 24 | dominationFactor = d; 25 | } 26 | 27 | public Team getWinner() { 28 | return winner; 29 | } 30 | 31 | public DominationFactor getDominationFactor() { 32 | return dominationFactor; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/control/NullControlProvider.java: -------------------------------------------------------------------------------- 1 | package battlecode.world.control; 2 | 3 | import battlecode.world.GameWorld; 4 | import battlecode.world.InternalRobot; 5 | 6 | /** 7 | * RobotControlProvider that does nothing. 8 | * 9 | * @author james 10 | */ 11 | public class NullControlProvider implements RobotControlProvider { 12 | @Override 13 | public void matchStarted(GameWorld world) {} 14 | 15 | @Override 16 | public void matchEnded() {} 17 | 18 | @Override 19 | public void robotSpawned(InternalRobot robot) {} 20 | 21 | @Override 22 | public void robotKilled(InternalRobot robot) {} 23 | 24 | @Override 25 | public void roundStarted() {} 26 | 27 | @Override 28 | public void runRobot(InternalRobot robot) {} 29 | 30 | @Override 31 | public void roundEnded() {} 32 | 33 | @Override 34 | public int getBytecodesUsed(InternalRobot robot) { 35 | return 0; 36 | } 37 | 38 | @Override 39 | public boolean getTerminated(InternalRobot robot) { 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/ALandDivided.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/ALandDivided.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/AMaze.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/AMaze.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/BeachFrontProperty.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/BeachFrontProperty.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/CentralLake.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/CentralLake.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/CentralSoup.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/CentralSoup.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/ChristmasInJuly.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/ChristmasInJuly.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/ClearlyTwelveHorsesInASalad.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/ClearlyTwelveHorsesInASalad.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Climb.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Climb.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Constriction.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Constriction.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/CosmicBackgroundRadiation.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/CosmicBackgroundRadiation.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/CowFarm.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/CowFarm.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/DidAMonkeyMakeThis.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/DidAMonkeyMakeThis.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/DisproportionatelySmallGap.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/DisproportionatelySmallGap.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/DoesNotExist.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/DoesNotExist.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Egg.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Egg.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Europe.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Europe.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/FourLakeLand.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/FourLakeLand.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/GSF.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/GSF.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Hills.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Hills.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Hourglass.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Hourglass.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/IceCream.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/IceCream.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/InADitch.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/InADitch.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Infinity.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Infinity.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/IsThisProcedural.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/IsThisProcedural.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Islands.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Islands.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Islands2.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Islands2.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Maze.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Maze.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/MoreCowbell.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/MoreCowbell.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/MtDoom.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/MtDoom.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/NoU.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/NoU.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/OmgThisIsProcedural.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/OmgThisIsProcedural.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Prison.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Prison.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/ProceduralConfirmed.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/ProceduralConfirmed.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/RandomSoup1.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/RandomSoup1.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/RandomSoup2.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/RandomSoup2.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/RealArt.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/RealArt.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Sheet4.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Sheet4.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Showerhead.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Showerhead.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Soup.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Soup.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/SoupOnTheSide.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/SoupOnTheSide.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Spiral.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Spiral.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Squares.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Squares.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Swirl.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Swirl.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/TheHighGround.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/TheHighGround.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Toothpaste.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Toothpaste.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/TwoForOneAndTwoForAll.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/TwoForOneAndTwoForAll.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/TwoLakeLand.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/TwoLakeLand.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/Volcano.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/Volcano.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/WaterBot.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/WaterBot.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/WateredDown.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/WateredDown.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/WhyDidntTheyUseEagles.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/WhyDidntTheyUseEagles.map20 -------------------------------------------------------------------------------- /engine/src/main/battlecode/world/resources/maptestsmall.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/main/battlecode/world/resources/maptestsmall.map20 -------------------------------------------------------------------------------- /engine/src/test/battlecode/common/DirectionTest.java: -------------------------------------------------------------------------------- 1 | package battlecode.common; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class DirectionTest { 8 | 9 | // TODO: write a bunch more of these 10 | 11 | // @Test 12 | // public void testBasic() { 13 | // final Direction north = new Direction(0, 1); 14 | // assertEquals(north.getDeltaX(0), 0, .00000001); 15 | // assertEquals(north.getDeltaY(1), 1, .00000001); 16 | // } 17 | } 18 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/common/MapLocationTest.java: -------------------------------------------------------------------------------- 1 | package battlecode.common; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class MapLocationTest { 8 | 9 | // TODO: write a bunch more of these 10 | 11 | @Test 12 | public void testConstructor() { 13 | MapLocation loc = new MapLocation(10123, -401823); 14 | assertEquals(loc.x, 10123); 15 | assertEquals(loc.y, -401823); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/resources/ValueA.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/test/battlecode/instrumenter/resources/ValueA.class -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/resources/ValueB.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/test/battlecode/instrumenter/resources/ValueB.class -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/resources/java.lang.Double.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/test/battlecode/instrumenter/resources/java.lang.Double.class -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/CallsIllegalMethods.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | import java.io.PrintStream; 4 | 5 | @SuppressWarnings("unused") 6 | public class CallsIllegalMethods { 7 | public static class CallsWait { 8 | static { 9 | try { 10 | new Object().wait(); 11 | } catch (Exception e) { 12 | throw new RuntimeException(e); 13 | } 14 | } 15 | } 16 | 17 | public static class CallsClassForName { 18 | static { 19 | try { 20 | Class.forName("???"); 21 | } catch (Exception e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | } 26 | 27 | public static class CallsStringIntern { 28 | static { 29 | try { 30 | "???".intern(); 31 | } catch (Exception e) { 32 | throw new RuntimeException(e); 33 | } 34 | } 35 | } 36 | 37 | public static class CallsSystemNanoTime { 38 | static { 39 | try { 40 | System.nanoTime(); 41 | } catch (Exception e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | } 46 | 47 | public static class CreatesFilePrintStream { 48 | static { 49 | try { 50 | new PrintStream("???"); 51 | } catch (Exception e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/CallsMathRandom.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | @SuppressWarnings("unused") 7 | public class CallsMathRandom { 8 | private static final double d = Math.random(); 9 | } 10 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/DoesntOverrideHashCode.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * Used to test hashCode instrumentation. 5 | * 6 | * @author james 7 | */ 8 | @SuppressWarnings("unused") 9 | public class DoesntOverrideHashCode { 10 | // We need to be able to make sure that calls to hashcode are instrumented correctly. 11 | public int getHashCode() { 12 | return this.hashCode(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/DoesntOverrideToString.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | @SuppressWarnings("unused") 4 | public class DoesntOverrideToString { 5 | public String getToString() { 6 | return this.toString(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/IllegalMethodReference.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | import java.util.Random; 4 | import java.util.function.Supplier; 5 | 6 | /** 7 | * @author james 8 | */ 9 | @SuppressWarnings("unused") 10 | public class IllegalMethodReference { 11 | // This is not allowed, since we can't currently implement it. 12 | Supplier randomSupplier = Random::new; 13 | } 14 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/LegalMethodReference.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | import java.util.Random; 4 | import java.util.function.Supplier; 5 | 6 | /** 7 | * @author james 8 | */ 9 | @SuppressWarnings("all") 10 | public class LegalMethodReference { 11 | // This is allowed, and hopefully won't be replaced with a method reference. 12 | private static final Supplier legalRandomSupplier = () -> new Random(); 13 | } 14 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/Nothing.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | public class Nothing {} 7 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/Outer.java: -------------------------------------------------------------------------------- 1 | // Javac will move this into the correct package in the build output 2 | package instrumentertest; 3 | 4 | /** 5 | * Test loading of inner classes. 6 | * @author james 7 | */ 8 | @SuppressWarnings("unused") 9 | public class Outer { 10 | public static class Inner {} 11 | } 12 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/OverridesHashCode.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | @SuppressWarnings("unused") 7 | public class OverridesHashCode { 8 | public int getHashCode() { 9 | return this.hashCode(); 10 | } 11 | @Override 12 | public int hashCode() { 13 | return 57; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/OverridesToString.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | @SuppressWarnings("unused") 4 | public class OverridesToString { 5 | public String getToString() { 6 | return this.toString(); 7 | } 8 | @Override 9 | public String toString() { 10 | return "foo"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/Reflection.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | @SuppressWarnings("unused") 7 | public class Reflection { 8 | static { 9 | Reflection.class.getClassLoader(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/StringFormat.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | @SuppressWarnings("unused") 7 | public class StringFormat { 8 | public static void run() { 9 | String s = String.format("Test %d", 1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/UsesEnumMap.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | import battlecode.common.Team; 4 | 5 | import java.util.EnumMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author james 10 | */ 11 | @SuppressWarnings("unused") 12 | public class UsesEnumMap { 13 | // This is allowed, even though using a Class for anything else isn't. 14 | public static final Map enumMap = new EnumMap<>(Team.class); 15 | } 16 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/UsesLambda.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | import java.util.BitSet; 4 | import java.util.Comparator; 5 | import java.util.Scanner; 6 | import java.util.function.Predicate; 7 | 8 | /** 9 | * @author james 10 | */ 11 | @SuppressWarnings("unused") 12 | public class UsesLambda { 13 | public static void run() { 14 | Predicate isNullObjectPredicate = o -> o == null; 15 | 16 | isNullObjectPredicate.test("Hi!"); 17 | isNullObjectPredicate.test(null); 18 | 19 | Comparator alwaysTheSame = (a, b) -> 0; 20 | 21 | alwaysTheSame.compare("Hi", 12345); 22 | alwaysTheSame.compare(null, null); 23 | 24 | // Classes that use lambdas internally 25 | BitSet s = new BitSet(27); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/instrumentertest/UsesThrowable.java: -------------------------------------------------------------------------------- 1 | package instrumentertest; 2 | 3 | /** 4 | * @author james 5 | */ 6 | @SuppressWarnings("unused") 7 | public class UsesThrowable { 8 | public static void run() { 9 | Throwable t = new Exception(); 10 | t.printStackTrace(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/shared/SharedUtility.java: -------------------------------------------------------------------------------- 1 | package shared; 2 | 3 | /** 4 | * @author james 5 | */ 6 | public class SharedUtility { 7 | public static int theNumberSeven() { 8 | return 7; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayeractions; 2 | 3 | import battlecode.common.*; 4 | 5 | /** 6 | * A RobotPlayer for testing that uses all of the methods in RobotController. 7 | * 8 | * @author james 9 | */ 10 | @SuppressWarnings("unused") 11 | public class RobotPlayer { 12 | public static void run(RobotController rc) throws GameActionException { 13 | rc.resign(); 14 | rc.senseNearbyRobots(); 15 | 16 | System.out.println("I shouldn't overflow!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerarray/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerarray; 2 | 3 | import battlecode.common.GameActionException; 4 | import battlecode.common.RobotController; 5 | 6 | /** 7 | * @author pear0 (William Gulian) 8 | */ 9 | public class RobotPlayer { 10 | public static void run(RobotController rc) throws GameActionException { 11 | 12 | RobotPlayer[] objects = new RobotPlayer[2]; 13 | for (RobotPlayer o : objects) { 14 | } 15 | 16 | while (true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerarraybytecode/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerarraybytecode; 2 | 3 | import battlecode.common.RobotController; 4 | import battlecode.common.Clock; 5 | 6 | /** 7 | * @author jamie 8 | */ 9 | public class RobotPlayer { 10 | @SuppressWarnings("unused") 11 | public static void run(RobotController rc) { 12 | int arrayLength = 2; 13 | while (arrayLength <= 16) { 14 | Clock.yield(); 15 | byte[] b = new byte[arrayLength]; 16 | Clock.yield(); 17 | arrayLength *= 2; 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerbytecode/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerbytecode; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | /** 6 | * @author james 7 | */ 8 | public class RobotPlayer { 9 | @SuppressWarnings("unused") 10 | public static void run(RobotController rc) { 11 | byte[] b = new byte[1000]; 12 | System.arraycopy(b, 0, b, 0, 1000); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerbytecodekotlin/RobotPlayer.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("RobotPlayer") 2 | @file:Suppress("PackageDirectoryMismatch") 3 | 4 | package testplayerbytecodekotlin 5 | 6 | import battlecode.common.RobotController 7 | 8 | fun run(@Suppress("UNUSED_PARAMETER") rc: RobotController) { 9 | 10 | (1..1000).toList() 11 | 12 | } -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerclock/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerclock; 2 | 3 | import battlecode.common.Clock; 4 | import battlecode.common.Direction; 5 | import battlecode.common.GameActionException; 6 | import battlecode.common.RobotController; 7 | 8 | /** 9 | * @author james 10 | */ 11 | public class RobotPlayer { 12 | public static void run(RobotController rc) throws GameActionException { 13 | Clock.yield(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerdebug/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerdebug; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | /** 6 | * @author james 7 | */ 8 | public class RobotPlayer { 9 | public static void run(RobotController rc) { 10 | debug_recurse(); 11 | } 12 | 13 | public static void debug_recurse() { 14 | debug_useLotsOfBytecode(); 15 | } 16 | 17 | public static void debug_useLotsOfBytecode() { 18 | int[] i = new int[1000]; 19 | System.arraycopy(i, 0, i, 0, 1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerempty/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | // Javac will move this into the correct package in the build output 2 | package testplayerempty; 3 | 4 | import battlecode.common.RobotController; 5 | 6 | /** 7 | * A RobotPlayer for testing that does nothing. 8 | * 9 | * @author james 10 | */ 11 | @SuppressWarnings("unused") 12 | public class RobotPlayer { 13 | public static void run(RobotController r) throws Exception {} 14 | } 15 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerloopforever/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerloopforever; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | /** 6 | * @author james 7 | */ 8 | public class RobotPlayer { 9 | public static void run(RobotController rc) { 10 | while (true) {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayermultiarraybytecode/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayermultiarraybytecode; 2 | 3 | import battlecode.common.RobotController; 4 | import battlecode.common.Clock; 5 | 6 | /** 7 | * @author jamie 8 | */ 9 | public class RobotPlayer { 10 | @SuppressWarnings("unused") 11 | public static void run(RobotController rc) { 12 | int x = 2; 13 | int y = 3; 14 | int z = 4; 15 | while (x <= 16) { 16 | Clock.yield(); 17 | byte[][][][] b = new byte[x][y][z][0]; 18 | Clock.yield(); 19 | x *= 2; 20 | y *= 3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayernodebug/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayernodebug; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | /** 6 | * @author james 7 | */ 8 | public class RobotPlayer { 9 | @SuppressWarnings("unused") 10 | public static void run(RobotController rc) { 11 | boolean[] debugContainsTrue = {false}; 12 | 13 | System.out.println(debugContainsTrue); 14 | System.out.println(debugContainsTrue[0]); 15 | 16 | debug_setTrue(debugContainsTrue); 17 | 18 | System.out.println(debugContainsTrue); 19 | System.out.println(debugContainsTrue[0]); 20 | 21 | if (debugContainsTrue[0]) { 22 | // loop forever 23 | while (true); 24 | } 25 | } 26 | 27 | public static void debug_setTrue(boolean[] param) { 28 | param[0] = true; 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerstatic/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerstatic; 2 | 3 | import battlecode.common.Clock; 4 | import battlecode.common.RobotController; 5 | 6 | /** 7 | * @author james 8 | */ 9 | public class RobotPlayer { 10 | static { 11 | Clock.yield(); 12 | } 13 | 14 | @SuppressWarnings("unused") 15 | public static void run(RobotController rc) { 16 | // Immediately return 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayersystem/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayersystem; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | /** 6 | * @author james 7 | */ 8 | public class RobotPlayer { 9 | @SuppressWarnings("unused") 10 | public static void run(RobotController rc) { 11 | 12 | String shouldTerminate = System.getProperty("bc.testing.should.terminate"); 13 | if (shouldTerminate == null || !shouldTerminate.equals("true")) { 14 | // loop forever 15 | while (true); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayersystemout/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayersystemout; 2 | 3 | import battlecode.common.RobotController; 4 | 5 | import java.io.PrintStream; 6 | 7 | /** 8 | * @author james 9 | */ 10 | public class RobotPlayer { 11 | public static void run(RobotController rc) { 12 | Class k = System.class; 13 | PrintStream s = System.out; 14 | System.out.println("I LOVE MEMES"); 15 | System.out.println("this shouldn't have a header"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/instrumenter/sample/testplayerusesshared/RobotPlayer.java: -------------------------------------------------------------------------------- 1 | package testplayerusesshared; 2 | 3 | import battlecode.common.GameActionException; 4 | import battlecode.common.RobotController; 5 | import shared.SharedUtility; 6 | 7 | /** 8 | * @author james 9 | */ 10 | public class RobotPlayer { 11 | @SuppressWarnings("unused") 12 | public static void run(RobotController rc) throws GameActionException { 13 | // rc.broadcast(0, SharedUtility.theNumberSeven()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/util/SquareArrayTest.java: -------------------------------------------------------------------------------- 1 | package battlecode.util; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * @author james 9 | */ 10 | public class SquareArrayTest { 11 | @Test 12 | public void testDouble() { 13 | SquareArray.Double arr = new SquareArray.Double(10, 7); 14 | assertEquals(10, arr.width); 15 | assertEquals(7, arr.height); 16 | for (int x = 0; x < arr.width; x++) { 17 | for (int y = 0; y < arr.height; y++) { 18 | arr.set(x, y, x * 1000 + y); 19 | assertEquals(x * 1000 + y, arr.get(x, y), 1e-9); 20 | } 21 | } 22 | } 23 | 24 | @Test 25 | public void testBoolean() { 26 | SquareArray.Boolean arr = new SquareArray.Boolean(10, 7); 27 | assertEquals(10, arr.width); 28 | assertEquals(7, arr.height); 29 | for (int x = 0; x < arr.width; x++) { 30 | for (int y = 0; y < arr.height; y++) { 31 | arr.set(x, y, (x+y) % 2 == 5); 32 | assertEquals((x+y) % 2 == 5, arr.get(x, y)); 33 | } 34 | } 35 | } 36 | 37 | @Test 38 | public void testObject() { 39 | SquareArray.Of arr = new SquareArray.Of<>(10, 7); 40 | 41 | assertEquals(10, arr.width); 42 | assertEquals(7, arr.height); 43 | 44 | for (int x = 0; x < arr.width; x++) { 45 | for (int y = 0; y < arr.height; y++) { 46 | Object o = new Object(); 47 | arr.set(x, y, o); 48 | assertEquals(o, arr.get(x, y)); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/world/GameMapIOTest.java: -------------------------------------------------------------------------------- 1 | package battlecode.world; 2 | 3 | import battlecode.common.*; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | public class GameMapIOTest { 13 | 14 | final static ClassLoader loader = GameMapIOTest.class.getClassLoader(); 15 | 16 | @Test 17 | public void testFindsDefaultMap() throws IOException { 18 | // will throw exception if default map can't be loaded 19 | GameMapIO.loadMap("maptestsmall", null); 20 | } 21 | 22 | @Test 23 | public void testFindsPackageMap() throws IOException { 24 | LiveMap readMap = GameMapIO.loadMapAsResource(loader, 25 | "battlecode/world/resources", "clearMap"); 26 | assertEquals(readMap.getMapName(), "clearMap"); 27 | assertEquals(readMap.getHeight(), 50.0, 0); 28 | assertEquals(readMap.getWidth(), 50.0, 0); 29 | assertEquals(readMap.getSeed(), 128); 30 | assertEquals(readMap.getOrigin().x, 0.0, 0); 31 | assertEquals(readMap.getOrigin().y, 0.0, 0); 32 | } 33 | 34 | 35 | @Test 36 | public void testRoundTrip() throws IOException { 37 | LiveMap inputMap = new TestMapBuilder("simple", 55, 3, 58, 50, 1337, 50, 0) 38 | .addRobot(0, Team.A, RobotType.HQ, new MapLocation(0, 0)) 39 | .addRobot(1, Team.B, RobotType.HQ, new MapLocation(25, 25)) 40 | .setSoup() 41 | .setWater() 42 | .setPollution() 43 | .setDirt() 44 | .build(); 45 | 46 | LiveMap outputMap = GameMapIO.Serial.deserialize(GameMapIO.Serial.serialize(inputMap)); 47 | 48 | assertEquals("Round trip failed", inputMap, outputMap); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/world/GenerateMaps.java: -------------------------------------------------------------------------------- 1 | package battlecode.world; 2 | 3 | import battlecode.common.MapLocation; 4 | import battlecode.common.RobotType; 5 | import battlecode.common.Team; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | 12 | /** 13 | * @author james 14 | * 15 | * so uh 16 | * 17 | * this exists 18 | */ 19 | @Ignore 20 | public class GenerateMaps { 21 | @Test 22 | public void makeSimple() throws IOException { 23 | LiveMap map = new TestMapBuilder("maptest", 0, 0, 100, 100, 30, 3000, 0) 24 | .addRobot( 25 | 0, 26 | Team.A, 27 | RobotType.HQ, 28 | new MapLocation( 29 | 1, 30 | 1 31 | ) 32 | ) 33 | .addRobot( 34 | 1, 35 | Team.B, 36 | RobotType.HQ, 37 | new MapLocation( 38 | 99, 39 | 99 40 | ) 41 | ) 42 | .setSoup() 43 | .setWater() 44 | .setPollution() 45 | .build(); 46 | GameMapIO.writeMap(map, new File("/Users/ezou/dev/battlecode20/engine/src/main/battlecode/world/maptest")); 47 | LiveMap test = GameMapIO.loadMap("maptest", new File("/Users/ezou/dev/battlecode20/engine/src/main/battlecode/world/resources")); 48 | // System.out.println(test.toString()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/world/IDGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package battlecode.world; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.BitSet; 6 | 7 | import static org.junit.Assert.assertFalse; 8 | 9 | /** 10 | * @author james 11 | */ 12 | public class IDGeneratorTest { 13 | @Test 14 | public void testIDGeneratorNoDuplicates() { 15 | BitSet seen = new BitSet(IDGenerator.ID_BLOCK_SIZE * 2); 16 | IDGenerator gen = new IDGenerator(0); 17 | 18 | for (int i = 0; i < IDGenerator.ID_BLOCK_SIZE * 2; i++) { 19 | int nextID = gen.nextID(); 20 | 21 | assertFalse(seen.get(nextID)); 22 | 23 | seen.set(nextID, true); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /engine/src/test/battlecode/world/resources/clearMap.map20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/engine/src/test/battlecode/world/resources/clearMap.map20 -------------------------------------------------------------------------------- /example-bots/.gitignore: -------------------------------------------------------------------------------- 1 | /lib 2 | /build 3 | /battlecode-player.jar 4 | .DS_Store 5 | /proguard 6 | *~ 7 | .gradle 8 | -------------------------------------------------------------------------------- /example-bots/README.md: -------------------------------------------------------------------------------- 1 | # Example Bots 2 | 3 | These bots are example bots for testing the game implementation. There should be lots of bots for different edge cases here. 4 | 5 | Note that this is NOT where we will do internal playtesting — anything in here will be open for all competitors to see, and we don't want them to see our really good internal test bots. 6 | -------------------------------------------------------------------------------- /example-bots/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'scala' 3 | 4 | // You can specify players to release here, or on the command line, 5 | // with the setting here taking priority. Note that leaving this 6 | // blank (i.e., an empty string) results in the release of all players. 7 | // To release no players, set this to 'NONE'. 8 | // WE DONT SUPPORT THIS ANYMORE 9 | project.ext.release_players='NONE' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven {url "https://oss.sonatype.org/content/repositories/snapshots/"} 14 | jcenter() 15 | } 16 | 17 | sourceSets { 18 | main { 19 | scala.srcDirs = ["src/main"] 20 | 21 | // output.classesDir = "$buildDir/classes" 22 | java.outputDir = file("$buildDir/classes") 23 | scala.outputDir = file("$buildDir/classes") 24 | } 25 | test { 26 | scala.srcDirs = ["src/test"] 27 | 28 | // output.classesDir = "$buildDir/tests" 29 | java.outputDir = file("$buildDir/tests") 30 | scala.outputDir = file("$buildDir/tests") 31 | } 32 | // main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | dependencies { 36 | compile project(':engine') 37 | 38 | // scala 39 | compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.1' 40 | 41 | 42 | 43 | // Testing dependencies 44 | testCompile 'junit:junit:4.12' 45 | } 46 | 47 | jar { 48 | if (project.hasProperty('release_players')) 49 | for (String player : project.property('release_players').split(',')) 50 | include "**/" + player + "/*.class" 51 | 52 | includeEmptyDirs = false 53 | } 54 | -------------------------------------------------------------------------------- /example-bots/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example-bots' 2 | -------------------------------------------------------------------------------- /example-bots/src/test/nothingbot/Sanity.java: -------------------------------------------------------------------------------- 1 | package nothingbot; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * Test that the testing infrastructure works. 9 | * 10 | * Hooraaay. 11 | * 12 | * @author james 13 | */ 14 | public class Sanity { 15 | @Test 16 | public void testSanity() { 17 | assertEquals(1, 1); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/.env.development: -------------------------------------------------------------------------------- 1 | REACT_APP_BACKEND_URL=http://localhost:8000 2 | REACT_APP_REPLAY_URL=https://2020.battlecode.org -------------------------------------------------------------------------------- /frontend/.env.production: -------------------------------------------------------------------------------- 1 | REACT_APP_BACKEND_URL=https://2020.battlecode.org 2 | REACT_APP_REPLAY_URL=https://2020.battlecode.org -------------------------------------------------------------------------------- /frontend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "airbnb", 3 | parser: "babel-eslint", 4 | 5 | env: { 6 | browser: true 7 | }, 8 | rules: { 9 | "react/jsx-filename-extension": [1, { extensions: [".js", ".jsx"] }] 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /frontend/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | 2 | FROM node:10.16-alpine 3 | 4 | # RUN mkdir /install 5 | # COPY package.json /install 6 | # RUN cd /install && npm install 7 | 8 | RUN mkdir /frontend 9 | WORKDIR /frontend 10 | 11 | # start the app 12 | EXPOSE 3000 13 | # CMD ["npm", "run", "startx"] 14 | # the reason we're doing npm install here is because we then can use 15 | # the mounted node_modules and keep package_lock nicely in version control 16 | CMD npm install && npm run startx 17 | -------------------------------------------------------------------------------- /frontend/deploy.sh: -------------------------------------------------------------------------------- 1 | if [ "$1" == "deploy" ] 2 | then 3 | echo "WARNING: Do you really want to deploy with the game? This SHOULD NEVER BE DONE before the game is released to the world, since this means that the game specs and the visualizer become public." 4 | select yn in "Yes" "No"; do 5 | case $yn in 6 | Yes ) break;; 7 | No ) exit;; 8 | esac 9 | done 10 | echo "WARNING: Do you have an up-to-date version of frontend/public/access.txt? If not, make sure to obtain it from someone who has it." 11 | select yn in "Yes" "No"; do 12 | case $yn in 13 | Yes ) break;; 14 | No ) exit;; 15 | esac 16 | done 17 | echo "Proceding with deploy!" 18 | npm install 19 | npm run build 20 | cd build 21 | gsutil -m rm gs://battlecode20-frontend/** 22 | gsutil -m cp -r * gs://battlecode20-frontend 23 | cd .. 24 | elif [ "$1" == "clean" ] 25 | then 26 | gsutil -m rm gs://battlecode20-frontend/** 27 | # DISABLED AFTER RELEASE 28 | # elif [ "$1" == "deploynogame" ] 29 | # then 30 | # echo "WARNING: DON'T " 31 | # npm install 32 | # npm run buildnogame 33 | # cd build 34 | # gsutil -m rm gs://battlecode20-frontend/** 35 | # gsutil -m cp -r * gs://battlecode20-frontend 36 | # cd .. 37 | else 38 | echo "Unsupported instruction" 39 | fi 40 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "battlecode-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "https://2020.battlecode.org", 6 | "devDependencies": { 7 | "react-scripts": "^3.3.0" 8 | }, 9 | "dependencies": { 10 | "ace-builds": "^1.3.3", 11 | "jquery": "^3.4.1", 12 | "js-cookie": "^2.2.0", 13 | "moment": "^2.24.0", 14 | "pixi.js": "^4.8.4", 15 | "rc-slider": "^8.6.4", 16 | "react": "^16.4.0", 17 | "react-dom": "^16.12.0", 18 | "react-dropzone": "^8.0.3", 19 | "react-floater": "^0.7.2", 20 | "react-pixi-fiber": "^0.7.0", 21 | "react-popout": "^1.0.1", 22 | "react-router": "^4.3.1", 23 | "react-router-dom": "^4.3.1", 24 | "styled-components": "^4.1.3", 25 | "superagent": "^4.1.0", 26 | "vm2": "^3.6.3" 27 | }, 28 | "scripts": { 29 | "startx": "BROWSER=none react-scripts start", 30 | "start": "react-scripts start", 31 | "build": "rm -rf build && react-scripts build", 32 | "buildnogame": "rm -rf build && rm -rf public/bc20 && rm -rf public/javadoc && rm -rf public/specs.html && react-scripts build", 33 | "test": "react-scripts test --env=jsdom", 34 | "eject": "react-scripts eject" 35 | }, 36 | "browserslist": [ 37 | ">0.2%", 38 | "not dead", 39 | "not ie <= 11", 40 | "not op_mini all" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /frontend/public/assets/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /frontend/public/assets/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /frontend/public/assets/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /frontend/public/assets/img/castle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/castle.png -------------------------------------------------------------------------------- /frontend/public/assets/img/church.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/church.png -------------------------------------------------------------------------------- /frontend/public/assets/img/crusader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/crusader.png -------------------------------------------------------------------------------- /frontend/public/assets/img/pilgrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/pilgrim.png -------------------------------------------------------------------------------- /frontend/public/assets/img/preacher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/preacher.png -------------------------------------------------------------------------------- /frontend/public/assets/img/prophet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/prophet.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_castle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_castle.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_church.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_church.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_crusader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_crusader.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_pilgrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_pilgrim.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_preacher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_preacher.png -------------------------------------------------------------------------------- /frontend/public/assets/img/s_prophet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/s_prophet.png -------------------------------------------------------------------------------- /frontend/public/assets/img/voyager_vision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/assets/img/voyager_vision.png -------------------------------------------------------------------------------- /frontend/public/bc20/speedscope/favicon-16x16.d02bd490.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/bc20/speedscope/favicon-16x16.d02bd490.png -------------------------------------------------------------------------------- /frontend/public/bc20/speedscope/favicon-32x32.c68a0a43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/bc20/speedscope/favicon-32x32.c68a0a43.png -------------------------------------------------------------------------------- /frontend/public/bc20/speedscope/index.html: -------------------------------------------------------------------------------- 1 | speedscope -------------------------------------------------------------------------------- /frontend/public/bc20/speedscope/release.txt: -------------------------------------------------------------------------------- 1 | speedscope@1.5.2 2 | Thu Oct 10 18:34:24 PDT 2019 3 | c3074b73436eddc789b96d0142c6ee56b34ff399 4 | -------------------------------------------------------------------------------- /frontend/public/bc20/speedscope/reset.7ae984ff.css: -------------------------------------------------------------------------------- 1 | a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}html{overflow:hidden}body,html{height:100%}body{overflow:auto} -------------------------------------------------------------------------------- /frontend/public/bc20/tiled_1-3eMNULX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/bc20/tiled_1-3eMNULX.jpg -------------------------------------------------------------------------------- /frontend/public/bc20/yellow_star-1n2ECJB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/bc20/yellow_star-1n2ECJB.png -------------------------------------------------------------------------------- /frontend/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/public/favicon.png -------------------------------------------------------------------------------- /frontend/public/javadoc/package-list: -------------------------------------------------------------------------------- 1 | battlecode.common 2 | -------------------------------------------------------------------------------- /frontend/public/javadoc/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /frontend/public/version.txt: -------------------------------------------------------------------------------- 1 | 2020.2.0.3 -------------------------------------------------------------------------------- /frontend/public/visualizer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Battlecode Online Match Viewer 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 34 | 35 | 39 | 40 | 41 |
42 |

Loading Battlecode client...

43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /frontend/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/frontend/screenshot.png -------------------------------------------------------------------------------- /frontend/src/components/paginationControl.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class PaginationControl extends Component { 4 | render() { 5 | const { props } = this; 6 | 7 | if (!props.pageLimit || props.pageLimit<= 1) { 8 | return null; 9 | }; 10 | 11 | const items = []; 12 | const isFirst = props.page === 1; 13 | const isLast = props.page === props.pageLimit; 14 | 15 | items.push( 16 |
  • 17 | props.onPageClick(props.page - 1)}>Previous 18 |
  • 19 | ); 20 | 21 | 22 | for (let i = 1; i <= props.pageLimit; i++) { 23 | items.push( 24 |
  • 25 | props.onPageClick(i)}>{i} 26 |
  • 27 | ) 28 | } 29 | 30 | items.push( 31 |
  • 32 | props.onPageClick(props.page + 1)}>Next 33 |
  • 34 | ); 35 | 36 | return ( 37 |
      38 | {items} 39 |
    40 | ) 41 | } 42 | } 43 | 44 | export default PaginationControl; -------------------------------------------------------------------------------- /frontend/src/components/updateCard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class UpdateCard extends Component { 4 | /* 5 | a card that displays the time when its content was last updated 6 | default is to just show "time when it loaded" which is not automatically 7 | updated/so not really ideal 8 | */ 9 | 10 | constructor(props) { 11 | super(props); 12 | this.state = {'update_date': new Date()}; 13 | } 14 | 15 | timeSince() { 16 | var seconds = Math.floor((new Date() - this.state.update_date) / 1000); 17 | 18 | var interval = Math.floor(seconds / 86400); 19 | if (interval > 1) return "Updated " + interval + " days ago."; 20 | interval = Math.floor(seconds / 3600); 21 | if (interval > 1) return "Updated " + interval + " hours ago."; 22 | interval = Math.floor(seconds / 60); 23 | if (interval > 1) return "Updated " + interval + " minutes ago."; 24 | //if (seconds <= 15) return "Just updated." 25 | return "Updated " + Math.floor(seconds) + " seconds ago."; 26 | } 27 | 28 | getFooter() { 29 | return( 30 |
    31 |
    32 |
    33 | { this.timeSince() } 34 |
    35 |
    36 | ) 37 | } 38 | } 39 | 40 | export default UpdateCard -------------------------------------------------------------------------------- /frontend/src/components/userCard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Avatar from '../components/avatar'; 3 | 4 | 5 | class UserCard extends Component { 6 | render () { 7 | const user = this.props.user 8 | const staff_msg = user.is_staff ? ( | ) : null 9 | return ( 10 |
    11 |
    12 |
    13 |
    14 |
    15 | 16 |

    {user.first_name + " " + user.last_name}
    {user.username} { staff_msg }

    17 |
    18 |
    19 |

    {user.bio}

    20 |
    21 |
    22 | ) 23 | } 24 | } 25 | 26 | export default UserCard 27 | 28 | 29 | -------------------------------------------------------------------------------- /frontend/src/footer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { NavLink } from 'react-router-dom'; 3 | 4 | class Footer extends Component { 5 | render() { 6 | return ( 7 |
    8 |
    9 | 23 |

    24 | © {new Date().getFullYear()} MIT Battlecode. 25 |

    26 |
    27 |
    28 | ); 29 | } 30 | } 31 | 32 | export default Footer; 33 | -------------------------------------------------------------------------------- /frontend/src/views/VerifyUser.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import Api from '../api'; 4 | 5 | class VerifyUser extends Component { 6 | state = { 7 | message: '', 8 | success: false, 9 | } 10 | 11 | componentDidMount() { 12 | Api.verifyAccount('', this.callback); 13 | } 14 | 15 | callback = (data, success) => { 16 | if (success) { 17 | this.setState({ success, message: 'Your email is now verified' }); 18 | } else { 19 | this.setState({ message: data.status }); 20 | } 21 | } 22 | 23 | render() { 24 | const { message, success } = this.state; 25 | return ( 26 |
    27 | {message} 28 |
    29 | ); 30 | } 31 | } 32 | 33 | 34 | export default VerifyUser; 35 | -------------------------------------------------------------------------------- /frontend/src/views/countdown.css: -------------------------------------------------------------------------------- 1 | .Countdown{ 2 | margin: 10px auto; 3 | padding-bottom: 20px; 4 | } 5 | 6 | .Countdown-col{ 7 | display: inline-block; 8 | } 9 | 10 | .Countdown-col-element{ 11 | display: inline-block; 12 | margin: 0 20px; 13 | display: flex; 14 | flex-direction: column; 15 | } 16 | 17 | .Countdown-col-element strong{ 18 | font-size: 2em; 19 | } 20 | 21 | .countdown-container { 22 | text-align: center; 23 | } -------------------------------------------------------------------------------- /frontend/src/views/not_found.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class NotFound extends Component { 4 | constructor(props) { 5 | super() 6 | this.state = { 7 | soup: '' 8 | } 9 | } 10 | 11 | render() { 12 | const soupStyle = { 13 | paddingBottom: "0", 14 | fontSize: "100px", 15 | marginBottom: "-30px", 16 | } 17 | 18 | // display one of three random soup emojis :) 19 | if (!this.state.soup) { 20 | const rand = Math.floor(Math.random() * 3) 21 | let soup_emoji = "" 22 | switch (rand) { 23 | case 0: 24 | soup_emoji = "🍲" 25 | break 26 | case 1: 27 | soup_emoji = "🥘" 28 | break 29 | default: 30 | soup_emoji = "🍜" 31 | 32 | } 33 | 34 | this.setState({soup: soup_emoji}) 35 | } 36 | 37 | 38 | return ( 39 |
    40 |

    {this.state.soup}

    41 |

    404 error

    42 |
    Sorry, we couldn't find the page you were looking for!
    43 |
    44 | ); 45 | } 46 | } 47 | 48 | export default NotFound; -------------------------------------------------------------------------------- /frontend/src/views/staff.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class AddCard extends Component { 4 | render() { 5 | return ( 6 |
    7 |
    8 |

    i am a card

    9 |
    10 |
    11 | ) 12 | } 13 | } 14 | 15 | class Staff extends Component { 16 | render() { 17 | return ( 18 |
    19 |
    20 | 21 |
    22 |

    Under construction!

    23 |
    24 | 25 |
    26 |
    27 | ) 28 | // return ( 29 | //
    30 | //
    31 | 32 | //
    33 | //
    34 | //
    35 | //
    36 | // 37 | //
    38 | //
    39 | //
    40 | //
    41 | //
    42 | //
    43 | // 44 | //
    45 | //
    46 | //
    47 | //
    48 | 49 | //
    50 | //

    rankings go here

    51 | //
    52 | 53 | //
    54 | //
    55 | // ) 56 | } 57 | } 58 | 59 | export default Staff -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # modify this file to change project properties 2 | teamA=examplefuncsplayer 3 | teamB=examplefuncsplayer 4 | maps=maptestsmall 5 | profilerEnabled=false 6 | source=src 7 | mapLocation=maps 8 | release_version=2020.2.0.3 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Dec 07 21:59:50 EST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip 7 | -------------------------------------------------------------------------------- /infrastructure/.gitignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | .vscode/* 3 | build/* 4 | matches/* -------------------------------------------------------------------------------- /infrastructure/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: env worker compile game scrimmage tournament images push clean 2 | 3 | # Basic environment variables for docker images 4 | env: 5 | docker build - < env.Dockerfile -t bc20-env 6 | 7 | # Worker servers: compilation server and game runner server 8 | worker: env 9 | docker build -f worker.Dockerfile -t bc20-worker worker 10 | compile: worker 11 | docker build -f compile.Dockerfile -t bc20-compile worker 12 | game: worker 13 | docker build -f game.Dockerfile -t bc20-game worker 14 | 15 | # Matchmaking servers: scrimmage matchmaking and tournament running 16 | scrimmage: env 17 | docker build -f scrimmage.Dockerfile -t bc20-scrimmage matcher 18 | tournament: env 19 | docker build -f tournament.Dockerfile -t bc20-tournament matcher 20 | 21 | images: compile game scrimmage tournament 22 | 23 | # Push to google container registry 24 | push: images 25 | docker tag bc20-compile gcr.io/battlecode18/bc20-compile 26 | docker tag bc20-game gcr.io/battlecode18/bc20-game 27 | docker tag bc20-scrimmage gcr.io/battlecode18/bc20-scrimmage 28 | docker tag bc20-tournament gcr.io/battlecode18/bc20-tournament 29 | docker push gcr.io/battlecode18/bc20-compile 30 | docker push gcr.io/battlecode18/bc20-game 31 | docker push gcr.io/battlecode18/bc20-scrimmage 32 | docker push gcr.io/battlecode18/bc20-tournament 33 | 34 | clean: 35 | docker rmi -f bc20-env bc20-worker bc20-compile bc20-game bc20-scrimmage bc20-tournament 36 | docker rmi -f gcr.io/battlecode18/bc20-compile gcr.io/battlecode18/bc20-game gcr.io/battlecode18/bc20-scrimmage gcr.io/battlecode18/bc20-tournament 37 | -------------------------------------------------------------------------------- /infrastructure/compile.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bc20-worker 2 | 3 | COPY app/compile_server.py app/ 4 | CMD /app/compile_server.py 5 | -------------------------------------------------------------------------------- /infrastructure/env.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8.1-alpine3.11 2 | 3 | ENV BC20_DB_USERNAME database_admin 4 | ENV BC20_DB_PASSWORD ??? 5 | -------------------------------------------------------------------------------- /infrastructure/game.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bc20-worker 2 | 3 | COPY app/game_server.py app/ 4 | COPY maps box/maps/ 5 | CMD /app/game_server.py 6 | -------------------------------------------------------------------------------- /infrastructure/matcher/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | # Configure logging format 5 | 6 | logging.basicConfig(format='%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s') 7 | logging.getLogger().setLevel(logging.INFO) 8 | 9 | 10 | # Constants, parameters and configurations 11 | 12 | API_AUTHENTICATE = 'https://2020.battlecode.org/auth/token/' 13 | API_USERNAME = os.getenv('BC20_DB_USERNAME') 14 | API_PASSWORD = os.getenv('BC20_DB_PASSWORD') 15 | 16 | API_SCRIM_LIST = 'https://2020.battlecode.org/api/match/scrimmage_list/' 17 | API_ENQUEUE = 'https://2020.battlecode.org/api/match/enqueue/' 18 | 19 | NUM_WORKER_THREADS = 10 20 | 21 | TOURNAMENT_WORKER_TIMEOUT = 15 22 | 23 | def api_match_status(gameid): 24 | """ 25 | Returns the API link for obtaining the status of a scrimmage 26 | gameid: the ID of the game 27 | """ 28 | return 'https://2020.battlecode.org/api/0/scrimmage/{}/'.format(gameid) 29 | -------------------------------------------------------------------------------- /infrastructure/matcher/scrimmage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import util 4 | from config import * 5 | 6 | import threading, requests 7 | from apscheduler.schedulers.blocking import BlockingScheduler 8 | from queue import Queue 9 | 10 | sched = BlockingScheduler() 11 | scrim_queue = Queue() 12 | 13 | def worker(): 14 | while True: 15 | scrim = scrim_queue.get() 16 | logging.info('Enqueueing scrimmage: {}'.format(scrim)) 17 | result = util.enqueue({ 18 | 'type': 'scrimmage', 19 | 'player1': scrim['player1'], 20 | 'player2': scrim['player2'] 21 | }) 22 | if result == None: 23 | scrim_queue.put(scrim) 24 | 25 | @sched.scheduled_job('cron', minute=0) 26 | def matchmake(): 27 | try: 28 | logging.info('Obtaining scrimmage list') 29 | auth_token = util.get_api_auth_token() 30 | response = requests.get(url=API_SCRIM_LIST, headers={ 31 | 'Authorization': 'Bearer {}'.format(auth_token) 32 | }) 33 | response.raise_for_status() 34 | scrim_list = response.json()["matches"] 35 | for scrim in scrim_list: 36 | scrim_queue.put(scrim) 37 | except Exception as e: 38 | logging.critical('Could not get scrimmage list', exc_info=e) 39 | 40 | if __name__ == '__main__': 41 | threads = [threading.Thread(target=worker) for i in range(NUM_WORKER_THREADS)] 42 | for thread in threads: 43 | thread.start() 44 | sched.start() 45 | -------------------------------------------------------------------------------- /infrastructure/matcher/util.py: -------------------------------------------------------------------------------- 1 | from config import * 2 | 3 | import requests 4 | 5 | def get_api_auth_token(): 6 | """Retrieves an API token for sending authenticated requests to the backend server""" 7 | try: 8 | response = requests.post(url=API_AUTHENTICATE, data={ 9 | 'username': API_USERNAME, 10 | 'password': API_PASSWORD 11 | }) 12 | response.raise_for_status() 13 | return response.json()['access'] 14 | except: 15 | logging.error('Could not obtain API authentication token') 16 | 17 | def enqueue(match_params): 18 | """Enqueues a match, returning the match id on success""" 19 | try: 20 | auth_token = get_api_auth_token() 21 | response = requests.post(url=API_ENQUEUE, data=match_params, headers={ 22 | 'Authorization': 'Bearer {}'.format(auth_token) 23 | }) 24 | response.raise_for_status() 25 | return response.json()["message"] 26 | except: 27 | logging.error('Could not enqueue match: {}'.format(match_params)) 28 | -------------------------------------------------------------------------------- /infrastructure/scrimmage.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bc20-env 2 | 3 | # Install software dependencies 4 | RUN pip3 install --upgrade \ 5 | apscheduler \ 6 | requests 7 | 8 | COPY config.py util.py scrimmage.py app/ 9 | CMD /app/scrimmage.py 10 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/.gitignore: -------------------------------------------------------------------------------- 1 | /data/* 2 | !/data/0-example 3 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/bracketlib.py: -------------------------------------------------------------------------------- 1 | ../matcher/bracketlib.py -------------------------------------------------------------------------------- /infrastructure/tournament-util/config.py: -------------------------------------------------------------------------------- 1 | ../matcher/config.py -------------------------------------------------------------------------------- /infrastructure/tournament-util/csv_to_files.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # USAGE: csv_to_files.py CSV_FILE 3 | 4 | import sys, json 5 | 6 | filename = sys.argv[1] 7 | 8 | with open(filename, 'r') as f: 9 | with open('team_pk', 'w') as g: 10 | with open('team_names', 'w') as h: 11 | f.readline() # Skip the title row 12 | for line in f.readlines(): 13 | team_id, team_name, team_score = line.split(',') 14 | team_name = team_name[1:-1] # Remove quotation marks 15 | g.write(team_id+'\n') 16 | h.write(team_name+'\n') 17 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/data/0-example/maps.json: -------------------------------------------------------------------------------- 1 | { 2 | "Round 1 (Winners)": [ 3 | "Egg", 4 | "Climb", 5 | "DoesNotExist" 6 | ], 7 | "Round 1 (Losers)": [ 8 | "Waves", 9 | "Toothpaste", 10 | "Hourglass" 11 | ], 12 | "Round 2 (Winners)": [ 13 | "NoU", 14 | "Pokeball", 15 | "Canyon" 16 | ], 17 | "Round 2 (Losers A)": [ 18 | "Swirl", 19 | "Spiral", 20 | "Constriction" 21 | ], 22 | "Round 3": [ 23 | "Hypnosis", 24 | "ALandDivided", 25 | "CentralLake" 26 | ], 27 | "Round 4 (if needed)": [ 28 | "CPU", 29 | "Diagonals", 30 | "Maze" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/data/0-example/team_names: -------------------------------------------------------------------------------- 1 | 914 2 | 917 3 | 919 4 | 920 5 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/data/0-example/team_pk: -------------------------------------------------------------------------------- 1 | arvid 2 | 2:40 AM 3 | teh devs 4 | database_team 5 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/finals_seeds.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Usage: finals_seeds.py CSV_FILE 3 | 4 | import sys, os, requests 5 | 6 | KEY = os.getenv('BC20_CHALLONGE_KEY') 7 | 8 | response = requests.get(url='https://api.challonge.com/v1/tournaments/bc20_seeding/participants.json?api_key={}'.format(KEY)) 9 | response.raise_for_status() 10 | 11 | seeded = {} 12 | for team in response.json(): 13 | seeded[team['participant']['name']] = team['participant']['final_rank'] 14 | 15 | def calculate_value(seed, score, winner_bracket): 16 | return score + 500 * winner_bracket - 10 * seed 17 | 18 | teams = [] 19 | with open(sys.argv[1], 'r') as f: 20 | f.readline() # Skip the title row 21 | for line in f.readlines(): 22 | team_id, team_name, team_score, team_winner_bracket = line.split(',') 23 | team_score, team_winner_bracket = float(team_score), int(team_winner_bracket) 24 | team_name = team_name[1:-1] # Remove quotation marks 25 | team_seed = seeded[team_name] 26 | team_value = calculate_value(team_seed, team_score, team_winner_bracket) 27 | teams.append((team_value, team_id, team_name, team_seed, team_score, team_winner_bracket)) 28 | teams.sort(key=lambda x: -x[0]) 29 | 30 | with open('team_pk', 'w') as g: 31 | with open('team_names', 'w') as h: 32 | for team in teams: 33 | team_value, team_id, team_name, team_seed, team_score, team_winner_bracket = team 34 | print (team) 35 | g.write(team_id+'\n') 36 | h.write(team_name+'\n') 37 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/match_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys, json, requests 4 | 5 | with open(sys.argv[1], 'r') as f: 6 | replays = json.loads(f.read()) 7 | 8 | for match in replays: 9 | if match is not None: 10 | for game in match: 11 | if game[3] == 1: 12 | winner = 'redwon' 13 | elif game[3] == 2: 14 | winner = 'bluewon' 15 | else: 16 | raise ValueError('Invalid winner: {}'.format(game[3])) 17 | print ('{} -vs- {} | {} {} replay {}'.format( 18 | game[0].rjust(40), # Red team 19 | game[1].ljust(40), # Blue team 20 | game[2].ljust(30), # Map name 21 | winner.ljust(8), # Winner status 22 | game[4])) # Replay id 23 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/pull_seeding.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Usage: pull_seeding.py CSV_FILE 3 | 4 | import sys, os, requests 5 | 6 | KEY = os.getenv('BC20_CHALLONGE_KEY') 7 | 8 | response = requests.get(url='https://api.challonge.com/v1/tournaments/bc20_seeding/participants.json?api_key={}'.format(KEY)) 9 | response.raise_for_status() 10 | 11 | seeded = {} 12 | for team in response.json(): 13 | seeded[team['participant']['name']] = team['participant']['final_rank'] 14 | 15 | scrim_ranks = [] 16 | with open(sys.argv[1], 'r') as f: 17 | f.readline() # Skip the title row 18 | for line in f.readlines(): 19 | team_id, team_name, team_score = line.split(',') 20 | team_name = team_name[1:-1] # Remove quotation marks 21 | scrim_ranks.append((team_id, team_name, team_score)) 22 | 23 | teams = [] 24 | for rank, team_data in enumerate(scrim_ranks): 25 | team_id, team_name, team_score = team_data 26 | if team_name in seeded: 27 | teams.append((seeded[team_name], rank+1, team_id, team_name)) 28 | else: 29 | teams.append((1000000, rank+1, team_id, team_name)) 30 | teams.sort() 31 | 32 | with open('team_pk', 'w') as g: 33 | with open('team_names', 'w') as h: 34 | for team in teams: 35 | team_seed, team_scrim, team_id, team_name = team 36 | print (team) 37 | g.write(team_id+'\n') 38 | h.write(team_name+'\n') 39 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/scrim_ranks.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Gets the list of teams with at least one submission, in order of scrimmage rank. 3 | Useful for seeding tournaments such as Sprint. 4 | */ 5 | 6 | SELECT 7 | api_team.id, api_team.name, api_team.score 8 | FROM 9 | api_team 10 | INNER JOIN 11 | api_teamsubmission 12 | ON 13 | api_team.id = api_teamsubmission.team_id 14 | WHERE 15 | api_teamsubmission.last_1_id IS NOT NULL 16 | AND NOT api_team.staff_team 17 | AND NOT api_team.deleted 18 | ORDER BY 19 | score DESC; 20 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/scrim_ranks_verified.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Gets the list of teams consisting of only verified students, 3 | with at least one submission, in order of scrimmage rank. 4 | Useful for seeding tournaments which require only verified students. 5 | */ 6 | 7 | SELECT 8 | api_team.id, api_team.name, api_team.score 9 | FROM 10 | api_team 11 | INNER JOIN 12 | api_teamsubmission 13 | ON 14 | api_team.id = api_teamsubmission.team_id 15 | INNER JOIN 16 | api_team_users 17 | ON 18 | api_team.id = api_team_users.team_id 19 | INNER JOIN 20 | api_user 21 | ON 22 | api_team_users.user_id = api_user.id 23 | WHERE 24 | api_teamsubmission.last_1_id IS NOT NULL 25 | AND NOT api_team.staff_team 26 | AND NOT api_team.deleted 27 | GROUP BY 28 | api_team.id 29 | HAVING 30 | COUNT(api_user.id) = COUNT(CASE WHEN api_user.verified THEN 1 END) 31 | ORDER BY 32 | api_team.score DESC; 33 | -------------------------------------------------------------------------------- /infrastructure/tournament-util/util.py: -------------------------------------------------------------------------------- 1 | ../matcher/util.py -------------------------------------------------------------------------------- /infrastructure/tournament.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bc20-env 2 | 3 | # Install software dependencies 4 | RUN pip3 install --upgrade \ 5 | requests 6 | 7 | COPY config.py util.py bracketlib.py team_pk team_names maps.json tournament_server.py app/ 8 | 9 | WORKDIR app 10 | CMD ./tournament_server.py 7 team_pk team_names maps.json 11 | -------------------------------------------------------------------------------- /infrastructure/worker.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bc20-env 2 | 3 | # Private key for gcloud authentication 4 | ENV GOOGLE_APPLICATION_CREDENTIALS /app/gcloud-key.json 5 | 6 | # Install software dependencies 7 | # Need g++ for pip to successfully install google cloud dependencies 8 | RUN apk --update --no-cache add \ 9 | g++ \ 10 | openjdk8 \ 11 | zip 12 | RUN pip3 install --upgrade \ 13 | google-cloud-pubsub \ 14 | google-cloud-storage \ 15 | requests 16 | 17 | # Initialise box and gradle 18 | COPY box box/ 19 | RUN cd box && ./gradlew --no-daemon build && rm -rf build src 20 | 21 | COPY app/config.py app/subscription.py app/util.py app/gcloud-key.json app/ 22 | -------------------------------------------------------------------------------- /infrastructure/worker/box/gradle.properties: -------------------------------------------------------------------------------- 1 | # modify this file to change project properties 2 | teamA=examplefuncsplayer 3 | teamB=examplefuncsplayer 4 | packageNameA=examplefuncsplayer 5 | packageNameB=examplefuncsplayer 6 | maps=maptestsmall 7 | source=src 8 | version=2020.0.1.2 9 | gpr.user=battlecodedownloadpackage 10 | -------------------------------------------------------------------------------- /infrastructure/worker/box/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/infrastructure/worker/box/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /infrastructure/worker/box/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Dec 07 21:59:50 EST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /infrastructure/worker/box/settings.gradle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/infrastructure/worker/box/settings.gradle -------------------------------------------------------------------------------- /infrastructure/worker/box/src/Helloworld.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This hello world program is compiled when the docker image is built, to 3 | * force gradle to download all of its dependencies; this way, users have a 4 | * shorter wait time because they don't have to wait for this very slow 5 | * download 6 | */ 7 | 8 | public class Helloworld { 9 | public static void main(String[] args) { 10 | System.out.println("Hello world!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /infrastructure/worker/box/version.txt: -------------------------------------------------------------------------------- 1 | 2020.1.0.0 -------------------------------------------------------------------------------- /install_all.sh: -------------------------------------------------------------------------------- 1 | cd schema && npm install && cd .. 2 | cd client && npm run install_all && cd .. 3 | cd frontend && npm install && cd .. 4 | -------------------------------------------------------------------------------- /post_release.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Here's what this script does: 5 | * Converts `specs.md` into a fancy specs html document (`frontend/public/specs.html`). 6 | * Puts the javadoc in `frontend/public/javadoc/`. 7 | * Builds the web client and copies it to `frontend/public/bc20`. 8 | 9 | Only use this as part of following the `RELEASE.md` document. Crucially, `./gradlew publish` needs to run before this. 10 | """ 11 | 12 | import argparse 13 | import subprocess 14 | import os 15 | 16 | def main(): 17 | fancy_specs() 18 | 19 | javadoc() 20 | 21 | client() 22 | 23 | def fancy_specs(): 24 | os.chdir('specs') 25 | subprocess.call('pandoc specs.md --self-contained --template template.html --toc -o specs.html --metadata pagetitle="Battlecode 2020 Specs"', shell=True) 26 | os.chdir('..') 27 | subprocess.call('cp specs/specs.html frontend/public/specs.html', shell=True) 28 | 29 | def javadoc(): 30 | """ 31 | Copy javadoc 32 | """ 33 | subprocess.call("cp -r engine/build/docs/javadoc frontend/public", shell=True) 34 | 35 | def client(): 36 | """ 37 | Build client for web. 38 | """ 39 | os.chdir("client/visualizer") 40 | subprocess.call("npm run prod", shell=True) 41 | subprocess.call("cp -r bc20 ../../frontend/public", shell=True) 42 | os.chdir("../../frontend") 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /schema/.gitignore: -------------------------------------------------------------------------------- 1 | typings 2 | .idea 3 | *.iml -------------------------------------------------------------------------------- /schema/java/battlecode/schema/Event.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | /** 6 | * An Event is a single step that needs to be processed. 7 | * A saved game simply consists of a long list of Events. 8 | * Events can be divided by either being sent separately (e.g. as separate 9 | * websocket messages), or by being wrapped with a GameWrapper. 10 | * A game consists of a series of matches; a match consists of a series of 11 | * rounds, and is played on a single map. Each round is a single simulation 12 | * step. 13 | */ 14 | public final class Event { 15 | private Event() { } 16 | public static final byte NONE = 0; 17 | /** 18 | * There should only be one GameHeader, at the start of the stream. 19 | */ 20 | public static final byte GameHeader = 1; 21 | /** 22 | * There should be one MatchHeader at the start of each match. 23 | */ 24 | public static final byte MatchHeader = 2; 25 | /** 26 | * A single simulation step. A round may be skipped if 27 | * nothing happens during its time. 28 | */ 29 | public static final byte Round = 3; 30 | /** 31 | * There should be one MatchFooter at the end of each simulation step. 32 | */ 33 | public static final byte MatchFooter = 4; 34 | /** 35 | * There should only be one GameFooter, at the end of the stream. 36 | */ 37 | public static final byte GameFooter = 5; 38 | 39 | public static final String[] names = { "NONE", "GameHeader", "MatchHeader", "Round", "MatchFooter", "GameFooter", }; 40 | 41 | public static String name(int e) { return names[e]; } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /schema/java/battlecode/schema/EventWrapper.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * Necessary due to flatbuffers requiring unions to be wrapped in tables. 13 | */ 14 | public final class EventWrapper extends Table { 15 | public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb) { return getRootAsEventWrapper(_bb, new EventWrapper()); } 16 | public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb, EventWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } 17 | public EventWrapper __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 18 | 19 | public byte eType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } 20 | public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; } 21 | 22 | public static int createEventWrapper(FlatBufferBuilder builder, 23 | byte e_type, 24 | int eOffset) { 25 | builder.startObject(2); 26 | EventWrapper.addE(builder, eOffset); 27 | EventWrapper.addEType(builder, e_type); 28 | return EventWrapper.endEventWrapper(builder); 29 | } 30 | 31 | public static void startEventWrapper(FlatBufferBuilder builder) { builder.startObject(2); } 32 | public static void addEType(FlatBufferBuilder builder, byte eType) { builder.addByte(0, eType, 0); } 33 | public static void addE(FlatBufferBuilder builder, int eOffset) { builder.addOffset(1, eOffset, 0); } 34 | public static int endEventWrapper(FlatBufferBuilder builder) { 35 | int o = builder.endObject(); 36 | return o; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /schema/java/battlecode/schema/GameFooter.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * The final event sent in the game. 13 | */ 14 | public final class GameFooter extends Table { 15 | public static GameFooter getRootAsGameFooter(ByteBuffer _bb) { return getRootAsGameFooter(_bb, new GameFooter()); } 16 | public static GameFooter getRootAsGameFooter(ByteBuffer _bb, GameFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } 17 | public GameFooter __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 18 | 19 | /** 20 | * The ID of the winning team of the game. 21 | */ 22 | public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } 23 | 24 | public static int createGameFooter(FlatBufferBuilder builder, 25 | byte winner) { 26 | builder.startObject(1); 27 | GameFooter.addWinner(builder, winner); 28 | return GameFooter.endGameFooter(builder); 29 | } 30 | 31 | public static void startGameFooter(FlatBufferBuilder builder) { builder.startObject(1); } 32 | public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } 33 | public static int endGameFooter(FlatBufferBuilder builder) { 34 | int o = builder.endObject(); 35 | return o; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /schema/java/battlecode/schema/Vec.java: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | package battlecode.schema; 4 | 5 | import java.nio.*; 6 | import java.lang.*; 7 | import java.util.*; 8 | import com.google.flatbuffers.*; 9 | 10 | @SuppressWarnings("unused") 11 | /** 12 | * A vector in two-dimensional space. Discrete space, of course. 13 | * Defaults to the 0 vector. 14 | */ 15 | public final class Vec extends Struct { 16 | public Vec __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; } 17 | 18 | public int x() { return bb.getInt(bb_pos + 0); } 19 | public int y() { return bb.getInt(bb_pos + 4); } 20 | 21 | public static int createVec(FlatBufferBuilder builder, int x, int y) { 22 | builder.prep(4, 8); 23 | builder.putInt(y); 24 | builder.putInt(x); 25 | return builder.offset(); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /schema/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "battlecode-schema", 3 | "version": "2017.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/flatbuffers": { 8 | "version": "1.9.1", 9 | "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.9.1.tgz", 10 | "integrity": "sha512-TC3X0Nkj5wgvuY217VkodBtjbD3Yr0JNApDY1GW9IU5Mzm5ie1IJErqe4vRm+wy08IRz3bemaDATrdEw1CJlVQ==", 11 | "dev": true 12 | }, 13 | "flatbuffers": { 14 | "version": "1.11.0", 15 | "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.11.0.tgz", 16 | "integrity": "sha512-0PqFKtXI4MjxomI7jO4g5XfLPm/15g2R+5WGCHBGYGh0ihQiypnHlJ6bMmkkrAe0GzZ4d7PDAfCONKIPUxNF+A==" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /schema/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "battlecode-schema", 3 | "version": "2017.0.0", 4 | "private": "true", 5 | "description": "flatbuffers parser for battlecode match files", 6 | "main": "ts/index.ts", 7 | "scripts": { 8 | "test": "true", 9 | "build": "flatc --ts -o ts battlecode.fbs && flatc --java -o java battlecode.fbs" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/battlecode/battlecode-schema.git" 14 | }, 15 | "keywords": [ 16 | "battlecode" 17 | ], 18 | "author": "Teh Devs", 19 | "license": "GPL-3.0", 20 | "bugs": { 21 | "url": "https://github.com/battlecode/battlecode-schema/issues" 22 | }, 23 | "homepage": "https://github.com/battlecode/battlecode-schema#readme", 24 | "dependencies": { 25 | "flatbuffers": "^1.11.0" 26 | }, 27 | "devDependencies": { 28 | "@types/flatbuffers": "^1.9.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /schema/ts/index.ts: -------------------------------------------------------------------------------- 1 | import { battlecode as bc } from "./battlecode_generated"; 2 | import schema = bc.schema; 3 | export { schema }; 4 | 5 | export { flatbuffers } from 'flatbuffers'; 6 | 7 | // export { battlecode.schema as schema } from './battlecode_generated'; 8 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'battlecode-release' 2 | 3 | include 'engine', 'example-bots' 4 | include ":internal-test-bots" 5 | project(":internal-test-bots").projectDir = file("battlecode20-internal-test-bots") 6 | -------------------------------------------------------------------------------- /specs/README.md: -------------------------------------------------------------------------------- 1 | # Specs 2 | 3 | Game specs are in `specs.md`, which is the source of truth. 4 | 5 | We're using `pandoc` to generate a pretty HTML version of the specs: 6 | 7 | ``` 8 | pandoc specs.md --self-contained --template template.html --toc -o specs.html --metadata pagetitle="Battlecode 2020 Specs" 9 | ``` 10 | 11 | You can install `pandoc` using your favorite package manager. 12 | -------------------------------------------------------------------------------- /specs/css/ie10-viewport-bug-workaround.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | /* 8 | * See the Getting Started docs for more information: 9 | * http://getbootstrap.com/getting-started/#support-ie10-width 10 | */ 11 | @-webkit-viewport { width: device-width; } 12 | @-moz-viewport { width: device-width; } 13 | @-ms-viewport { width: device-width; } 14 | @-o-viewport { width: device-width; } 15 | @viewport { width: device-width; } 16 | -------------------------------------------------------------------------------- /specs/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/specs/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /specs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/specs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /specs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/specs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /specs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlecode/battlecode20/7618f6be7d12da39f2e6e25801e578f1fecfbd86/specs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /specs/js/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // See the Getting Started docs for more information: 8 | // http://getbootstrap.com/getting-started/#support-ie10-width 9 | 10 | (function () { 11 | 'use strict'; 12 | 13 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 14 | var msViewportStyle = document.createElement('style') 15 | msViewportStyle.appendChild( 16 | document.createTextNode( 17 | '@-ms-viewport{width:auto!important}' 18 | ) 19 | ) 20 | document.querySelector('head').appendChild(msViewportStyle) 21 | } 22 | 23 | })(); 24 | --------------------------------------------------------------------------------