From 35b9fa595b13523e14dcdaba85388c1bcf4a095a Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 9 Oct 2021 12:36:42 -0400 Subject: [PATCH 001/413] added a draft schema --- draft_schema.fbs | 304 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 draft_schema.fbs diff --git a/draft_schema.fbs b/draft_schema.fbs new file mode 100644 index 00000000..24698fcd --- /dev/null +++ b/draft_schema.fbs @@ -0,0 +1,304 @@ +namespace battlecode.schema; + +/// A vector in two-dimensional space. Discrete space, of course. +/// Defaults to the 0 vector. +struct Vec { + x: int = 0; + y: int = 0; +} + +/// A table of vectors. +table VecTable { + xs: [int]; + ys: [int]; +} + + +/// A table of RGB values. +table RGBTable { + red: [int]; + green: [int]; + blue: [int]; +} + +/// The possible types of things that can exist. +/// Note that bullets are not treated as bodies. +enum BodyType : byte { + + // Core unit types + MINER, + ARCHON, + BUILDER, + LABORATORY, + + // Combat units + GUARD, + GUARD_TURRET, + ARCHER, + ARCHER_TURRET, + WIZARD, + WIZARD_TURRET +} + +/// A list of new bodies to be placed on the map. +table SpawnedBodyTable { + /// The numeric ID of the new bodies. + /// Will never be negative. + /// There will only be one body with a particular ID at a time. + /// So, there will never be two robots with the same ID, or a robot and + /// a building with the same ID. + robotIDs: [int]; + /// The teams of the new bodies. + teamIDs: [byte]; + /// The types of the new bodies. + types: [BodyType]; + /// The locations of the bodies. + locs: VecTable; + /// the amount of influence paid to create these bodies + /// for initial Enlightenment Centers, this is the amount of influence + /// needed to take over + influences: [int]; +} + +/// The map a round is played on. +table GameMap { + /// The name of a map. + name: string; + /// The bottom corner of the map. + minCorner: Vec; + /// The top corner of the map. + maxCorner: Vec; + /// The bodies on the map. + bodies: SpawnedBodyTable; + /// The random seed of the map. + randomSeed: int; + /// The factor to divide cooldowns by + passability: [double]; +} + +/// Actions that can be performed. +/// Purely aesthetic; have no actual effect on simulation. +/// (Although the simulation may want to track the 'parents' of +/// particular robots.) +/// Actions may have 'targets', which are the units on which +/// the actions were performed. +enum Action : byte { + ATTACK, // combat unit types + DAZZLE, // wizard + SPAWN_UNIT, //archon + UPGRADE, //buldings + MINE, // miner + BUILD, // builder + CONVERT_GOLD, // for alchemist laboratory +} + +// Metadata + +/// Metadata about all bodies of a particular type. +table BodyTypeMetadata { + type: BodyType; + spawnSource: BodyType; + actionCooldown: float; + actionRadiusSquared: int; + visionRadiusSquared: int; + moveCooldown: float; + bytecodeLimit: int; + level: int; + dps: int; + hp: int; +} + +/// Data relevant to a particular team. +table TeamData { + /// The name of the team. + name: string; + /// The java package the team uses. + packageName: string; + /// The ID of the team this data pertains to. + teamID: byte; +} + +// Profiler tables + +/// These tables are set-up so that they match closely with speedscope's file format documented at +/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. +/// The client uses speedscope to show the recorded data in an interactive interface. + +/// A single event in a profile. Represents either an open event (meaning a +/// method has been entered) or a close event (meaning the method was exited). +table ProfilerEvent { + /// Whether this is an open event (true) or a close event (false). + isOpen: bool; + /// The bytecode counter at the time the event occurred. + at: int; + /// The index of the method name in the ProfilerFile.frames array. + frame: int; +} + +/// A profile contains all events and is labeled with a name. +table ProfilerProfile { + /// The display-friendly name of the profile. + name: string; + /// The events that occurred in the profile. + events: [ProfilerEvent]; +} + +/// A profiler file is a collection of profiles. +/// When profiling is enabled there is one of these per team per match. +table ProfilerFile { + /// The method names that are referred to in the events. + frames: [string]; + /// The recorded profiles, one per robot. + profiles: [ProfilerProfile]; +} + +/// Events + +/// An Event is a single step that needs to be processed. +/// A saved game simply consists of a long list of Events. +/// Events can be divided by either being sent separately (e.g. as separate +/// websocket messages), or by being wrapped with a GameWrapper. +/// A game consists of a series of matches; a match consists of a series of +/// rounds, and is played on a single map. Each round is a single simulation +/// step. +union Event { + /// There should only be one GameHeader, at the start of the stream. + GameHeader, + /// There should be one MatchHeader at the start of each match. + MatchHeader, + /// A single simulation step. A round may be skipped if + /// nothing happens during its time. + Round, + /// There should be one MatchFooter at the end of each simulation step. + MatchFooter, + /// There should only be one GameFooter, at the end of the stream. + GameFooter +} + +/// The first event sent in the game. Contains all metadata about the game. +table GameHeader { + /// The version of the spec this game complies with. + specVersion: string; + /// The teams participating in the game. + teams: [TeamData]; + /// Information about all body types in the game. + bodyTypeMetadata: [BodyTypeMetadata]; +} + +/// The final event sent in the game. +table GameFooter { + /// The ID of the winning team of the game. + winner: byte; +} + +/// Sent to start a match. +table MatchHeader { + /// The map the match was played on. + map: GameMap; + /// The maximum number of rounds in this match. + maxRounds: int; +} + +/// Sent to end a match. +table MatchFooter { + /// The ID of the winning team. + winner: byte; + /// The number of rounds played. + totalRounds: int; + /// Profiler data for team A and B if profiling is enabled. + profilerFiles: [ProfilerFile]; +} + +/// A single time-step in a Game. +/// The bulk of the data in the file is stored in tables like this. +/// Note that a struct-of-arrays format is more space efficient than an array- +/// of-structs. +table Round { + /// The IDs of teams in the Game. + teamIDs: [int]; + + /// The IDs of bodies that moved. + movedIDs: [int]; + /// The new locations of bodies that have moved. + movedLocs: VecTable; + + /// New bodies. + spawnedBodies: SpawnedBodyTable; + + /// The IDs of bodies that died. + diedIDs: [int]; + + /// The IDs of robots that performed actions. + /// IDs may repeat. + actionIDs: [int]; + /// The actions performed. These actions allow us to track how much soup or dirt a body carries. + actions: [Action]; + /// The 'targets' of the performed actions. Actions without targets may have any value + actionTargets: [int]; + + /// The IDs of bodies that set indicator dots + indicatorDotIDs: [int]; + /// The location of the indicator dots + indicatorDotLocs: VecTable; + /// The RGB values of the indicator dots + indicatorDotRGBs: RGBTable; + + /// The IDs of bodies that set indicator lines + indicatorLineIDs: [int]; + /// The start location of the indicator lines + indicatorLineStartLocs: VecTable; + /// The end location of the indicator lines + indicatorLineEndLocs: VecTable; + /// The RGB values of the indicator lines + indicatorLineRGBs: RGBTable; + + /// All logs sent this round. + /// Messages from a particular robot in this round start on a new line, and + /// have a header: + /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' + /// $TEAM = 'A' | 'B' + /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' + /// $ID = a number + /// $ROUND = a number + /// The header is not necessarily followed by a newline. + /// This header should only be sent once per robot per round (although + /// players may forge it, so don't crash if you get strange input.) + /// + /// You should try to only read this value once, and cache it. Reading + /// strings from a flatbuffer is much less efficient than reading other + /// buffers, because they need to be copied into an environment-provided + /// buffer and validated. + /// + /// (haha i guess you can never really escape string parsing can you) + logs: string; // TODO: maybe split into more arrays + + /// The first sent Round in a match should have index 1. (The starting state, + /// created by the MatchHeader, can be thought to have index 0.) + /// It should increase by one for each following round. + roundID: int; + + /// The IDs of player bodies. + bytecodeIDs: [int]; + /// The bytecodes used by the player bodies. + bytecodesUsed: [int]; +} + +/// Necessary due to flatbuffers requiring unions to be wrapped in tables. +table EventWrapper { + e: Event; +} + +/// If events are not otherwise delimited, this wrapper structure +/// allows a game to be stored in a single buffer. +/// The first event will be a GameHeader; the last event will be a GameFooter. +/// matchHeaders[0] is the index of the 0th match header in the event stream, +/// corresponding to matchFooters[0]. These indices allow quick traversal of +/// the file. +table GameWrapper { + /// The series of events comprising the game. + events: [EventWrapper]; + /// The indices of the headers of the matches, in order. + matchHeaders: [int]; + /// The indices of the footers of the matches, in order. + matchFooters: [int]; +} From 4c3663d198b55fd2c89171ee009b0784a0361338 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 23 Oct 2021 11:32:38 -0400 Subject: [PATCH 002/413] Move schema file --- draft_schema.fbs => schema/draft_schema.fbs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename draft_schema.fbs => schema/draft_schema.fbs (100%) diff --git a/draft_schema.fbs b/schema/draft_schema.fbs similarity index 100% rename from draft_schema.fbs rename to schema/draft_schema.fbs From c4fe64ebf8ffb70451e081ef2e3b6ea7873c02ed Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 30 Oct 2021 00:38:09 -0400 Subject: [PATCH 003/413] Update schema --- schema/draft_schema.fbs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 24698fcd..b1b88241 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,10 +54,8 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the amount of influence paid to create these bodies - /// for initial Enlightenment Centers, this is the amount of influence - /// needed to take over - influences: [int]; + /// the level of the body + level: [int]; } /// The map a round is played on. @@ -89,7 +87,12 @@ enum Action : byte { UPGRADE, //buldings MINE, // miner BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory + CONVERT_GOLD, // for alchemist laboratory. + ATTACKED, // when a body is attacked + TRANSFORM_PORTABLE, + TRANSFORM_TURRET, + UPGRADE, // builder upgrades building, + REPAIR // builder repairs building } // Metadata @@ -103,9 +106,10 @@ table BodyTypeMetadata { visionRadiusSquared: int; moveCooldown: float; bytecodeLimit: int; - level: int; dps: int; hp: int; + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level } /// Data relevant to a particular team. @@ -217,6 +221,9 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; + teamLead: [int]; + teamGold: [int]; + /// The IDs of bodies that moved. movedIDs: [int]; /// The new locations of bodies that have moved. From cdb98a89b25c9205e183376efca119405f7997d4 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Sat, 30 Oct 2021 12:30:03 -0400 Subject: [PATCH 004/413] Some schema changes --- schema/draft_schema.fbs | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b1b88241..23a8f802 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,8 +54,6 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the level of the body - level: [int]; } /// The map a round is played on. @@ -89,10 +87,10 @@ enum Action : byte { BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. ATTACKED, // when a body is attacked - TRANSFORM_PORTABLE, - TRANSFORM_TURRET, + TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, - REPAIR // builder repairs building + REPAIR, // builder repairs building + CHANGE_HP } // Metadata @@ -243,6 +241,11 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; + /// The IDs of the robots who changed their indicator strings + indicationStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicationStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots @@ -259,25 +262,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - /// All logs sent this round. - /// Messages from a particular robot in this round start on a new line, and - /// have a header: - /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - /// $TEAM = 'A' | 'B' - /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - /// $ID = a number - /// $ROUND = a number - /// The header is not necessarily followed by a newline. - /// This header should only be sent once per robot per round (although - /// players may forge it, so don't crash if you get strange input.) - /// - /// You should try to only read this value once, and cache it. Reading - /// strings from a flatbuffer is much less efficient than reading other - /// buffers, because they need to be copied into an environment-provided - /// buffer and validated. - /// - /// (haha i guess you can never really escape string parsing can you) - logs: string; // TODO: maybe split into more arrays + //logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) From a0a4f0ef99e684f01b0874f19330c7559c151c3b Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 11:18:37 -0400 Subject: [PATCH 005/413] Add repaired action --- schema/draft_schema.fbs | 11 ++++++----- schema/package-lock.json | 19 ------------------- 2 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 schema/package-lock.json diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 23a8f802..01e8db8a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -82,7 +82,7 @@ enum Action : byte { ATTACK, // combat unit types DAZZLE, // wizard SPAWN_UNIT, //archon - UPGRADE, //buldings + UPGRADE, //buildings MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. @@ -90,7 +90,8 @@ enum Action : byte { TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, REPAIR, // builder repairs building - CHANGE_HP + CHANGE_HP, + REPAIRED // prototype becomes a turret } // Metadata @@ -102,10 +103,10 @@ table BodyTypeMetadata { actionCooldown: float; actionRadiusSquared: int; visionRadiusSquared: int; - moveCooldown: float; + movingCooldown: float; bytecodeLimit: int; - dps: int; - hp: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level } diff --git a/schema/package-lock.json b/schema/package-lock.json deleted file mode 100644 index 278729f5..00000000 --- a/schema/package-lock.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "battlecode-schema", - "version": "2021.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/flatbuffers": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", - "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", - "dev": true - }, - "flatbuffers": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", - "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" - } - } -} From 7b61cd2c98ae04c68d1c97acefd7a15ee48fe9b6 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 12:21:46 -0400 Subject: [PATCH 006/413] Change terminology --- client/playback/src/gameworld.ts | 14 +------------- schema/draft_schema.fbs | 2 +- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 84e63950..af0ab7f2 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -14,28 +14,16 @@ export type DeadBodiesSchema = { y: Int32Array, } -export type EmpowerSchema = { - id: Int32Array, - x: Int32Array, - y: Int32Array - team: Int8Array, - radius: Int32Array -} - export type BodiesSchema = { id: Int32Array, team: Int8Array, type: Int8Array, x: Int32Array, y: Int32Array, - influence: Int32Array; - conviction: Int32Array; flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? ability: Int8Array, - bid: Int32Array, - parent: Int32Array, - income: Int32Array + parent: Int32Array }; // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 01e8db8a..6146e290 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -91,7 +91,7 @@ enum Action : byte { UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, - REPAIRED // prototype becomes a turret + FULLY_REPAIRED // prototype becomes a turret } // Metadata From 094740fbd179569a3521f8464bc5fd0cd5e4a388 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:30:21 -0400 Subject: [PATCH 007/413] added lead to map --- schema/draft_schema.fbs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 01e8db8a..d26f1681 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -70,6 +70,13 @@ table GameMap { randomSeed: int; /// The factor to divide cooldowns by passability: [double]; + + //lead locations + + // a vectable of lead cords + lead_locations: VecTable; + //inital lead amounts + initial_lead: [double]; } /// Actions that can be performed. From 325c753667213f7ee8023d6dd00784762e7ca910 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:51:46 -0400 Subject: [PATCH 008/413] added lead increase contants and upgrade costs --- schema/draft_schema.fbs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b4bf9840..f1b0b68a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -72,7 +72,7 @@ table GameMap { passability: [double]; //lead locations - + // a vectable of lead cords lead_locations: VecTable; //inital lead amounts @@ -116,6 +116,7 @@ table BodyTypeMetadata { hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -185,6 +186,14 @@ union Event { GameFooter } +table Constants{ + //amounts of resources added to each block per round + leadAdditiveIncease: double; + goldAdditiveIncease: double; + increase_period: int; +} + + /// The first event sent in the game. Contains all metadata about the game. table GameHeader { /// The version of the spec this game complies with. @@ -193,8 +202,14 @@ table GameHeader { teams: [TeamData]; /// Information about all body types in the game. bodyTypeMetadata: [BodyTypeMetadata]; + + //game constants + constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. From 6d4da4d86270f65d8b11949a9f482a5a1a26cf23 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:18:27 -0500 Subject: [PATCH 009/413] Begin to update gameworld --- client/playback/src/gameworld.ts | 5 +- schema/battlecode.fbs | 150 +++++++-------- schema/draft_schema.fbs | 319 ------------------------------- 3 files changed, 68 insertions(+), 406 deletions(-) delete mode 100644 schema/draft_schema.fbs diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index af0ab7f2..00ad1187 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -23,7 +23,9 @@ export type BodiesSchema = { flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? ability: Int8Array, - parent: Int32Array + parent: Int32Array, + hp: Int32Array, + level: Int8Array }; // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data @@ -35,6 +37,7 @@ export type MapStats = { randomSeed: number, passability: Float64Array, // double + lead: Int32Array; getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 57a2963c..f1b0b68a 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -24,16 +24,20 @@ table RGBTable { /// The possible types of things that can exist. /// Note that bullets are not treated as bodies. enum BodyType : byte { - /// Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - ///can be neutral until captured - ENLIGHTENMENT_CENTER, - /// politicians use their influence to self destruct and capture other units - POLITICIAN, - /// slanderers generate passive influence for the enlightenment center that created them - /// they turn into politicians at some point, and can only be identified by slanderers. - SLANDERER, - /// have the ability to identify slanderers - MUCKRAKER, + + // Core unit types + MINER, + ARCHON, + BUILDER, + LABORATORY, + + // Combat units + GUARD, + GUARD_TURRET, + ARCHER, + ARCHER_TURRET, + WIZARD, + WIZARD_TURRET } /// A list of new bodies to be placed on the map. @@ -50,10 +54,6 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the amount of influence paid to create these bodies - /// for initial Enlightenment Centers, this is the amount of influence - /// needed to take over - influences: [int]; } /// The map a round is played on. @@ -70,6 +70,13 @@ table GameMap { randomSeed: int; /// The factor to divide cooldowns by passability: [double]; + + //lead locations + + // a vectable of lead cords + lead_locations: VecTable; + //inital lead amounts + initial_lead: [double]; } /// Actions that can be performed. @@ -79,63 +86,37 @@ table GameMap { /// Actions may have 'targets', which are the units on which /// the actions were performed. enum Action : byte { - /// Politicians self-destruct and affect nearby bodies. - /// Target: radius squared - EMPOWER, - /// Slanderers passively generate influence for the - /// Enlightenment Center that created them. - /// Target: parent ID - EMBEZZLE, - /// Slanderers turn into Politicians. - /// Target: none - CAMOUFLAGE, - /// Muckrakers can expose a slanderer. - /// Target: an enemy body - EXPOSE, - /// Units can change their flag. - /// Target: new flag value - SET_FLAG, - /// Builds a unit. - /// Target: spawned unit - SPAWN_UNIT, - /// Places a bid. - /// Target: bid value - PLACE_BID, - /// A robot can change team after being empowered, - /// or when a Enlightenment Center is taken over. - /// Target: new robotID - CHANGE_TEAM, - /// A robot's influence changes. - /// Target: delta value - CHANGE_INFLUENCE, - /// A robot's conviction changes. - /// Target: delta value, i.e. red 5 -> blue 3 is -2 - CHANGE_CONVICTION, - /// Dies due to an uncaught exception. - /// Target: none - DIE_EXCEPTION + ATTACK, // combat unit types + DAZZLE, // wizard + SPAWN_UNIT, //archon + UPGRADE, //buildings + MINE, // miner + BUILD, // builder + CONVERT_GOLD, // for alchemist laboratory. + ATTACKED, // when a body is attacked + TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state + UPGRADE, // builder upgrades building, + REPAIR, // builder repairs building + CHANGE_HP, + FULLY_REPAIRED // prototype becomes a turret } // Metadata /// Metadata about all bodies of a particular type. table BodyTypeMetadata { - /// The relevant type. type: BodyType; - /// The spawn source. spawnSource: BodyType; - /// the convictionRatio of this type - convictionRatio: float; - /// cooldown of this type actionCooldown: float; - /// action radius if this type actionRadiusSquared: int; - /// sensor radius squared for this type - sensorRadiusSquared: int; - /// detection radius of this type - detectionRadiusSquared: int; - /// bytecode limit for this type + visionRadiusSquared: int; + movingCooldown: float; bytecodeLimit: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -205,6 +186,14 @@ union Event { GameFooter } +table Constants{ + //amounts of resources added to each block per round + leadAdditiveIncease: double; + goldAdditiveIncease: double; + increase_period: int; +} + + /// The first event sent in the game. Contains all metadata about the game. table GameHeader { /// The version of the spec this game complies with. @@ -213,8 +202,14 @@ table GameHeader { teams: [TeamData]; /// Information about all body types in the game. bodyTypeMetadata: [BodyTypeMetadata]; + + //game constants + constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. @@ -246,10 +241,9 @@ table MatchFooter { table Round { /// The IDs of teams in the Game. teamIDs: [int]; - /// The number of votes the teams get, 0 or 1. - teamVotes: [int]; - /// The ID of the Enlightenment Center got the bid. - teamBidderIDs: [int]; + + teamLead: [int]; + teamGold: [int]; /// The IDs of bodies that moved. movedIDs: [int]; @@ -270,6 +264,11 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; + /// The IDs of the robots who changed their indicator strings + indicationStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicationStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots @@ -286,25 +285,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - /// All logs sent this round. - /// Messages from a particular robot in this round start on a new line, and - /// have a header: - /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - /// $TEAM = 'A' | 'B' - /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - /// $ID = a number - /// $ROUND = a number - /// The header is not necessarily followed by a newline. - /// This header should only be sent once per robot per round (although - /// players may forge it, so don't crash if you get strange input.) - /// - /// You should try to only read this value once, and cache it. Reading - /// strings from a flatbuffer is much less efficient than reading other - /// buffers, because they need to be copied into an environment-provided - /// buffer and validated. - /// - /// (haha i guess you can never really escape string parsing can you) - logs: string; + //logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) @@ -315,9 +296,6 @@ table Round { bytecodeIDs: [int]; /// The bytecodes used by the player bodies. bytecodesUsed: [int]; - - /// Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - teamNumBuffs: [int]; } /// Necessary due to flatbuffers requiring unions to be wrapped in tables. diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs deleted file mode 100644 index f1b0b68a..00000000 --- a/schema/draft_schema.fbs +++ /dev/null @@ -1,319 +0,0 @@ -namespace battlecode.schema; - -/// A vector in two-dimensional space. Discrete space, of course. -/// Defaults to the 0 vector. -struct Vec { - x: int = 0; - y: int = 0; -} - -/// A table of vectors. -table VecTable { - xs: [int]; - ys: [int]; -} - - -/// A table of RGB values. -table RGBTable { - red: [int]; - green: [int]; - blue: [int]; -} - -/// The possible types of things that can exist. -/// Note that bullets are not treated as bodies. -enum BodyType : byte { - - // Core unit types - MINER, - ARCHON, - BUILDER, - LABORATORY, - - // Combat units - GUARD, - GUARD_TURRET, - ARCHER, - ARCHER_TURRET, - WIZARD, - WIZARD_TURRET -} - -/// A list of new bodies to be placed on the map. -table SpawnedBodyTable { - /// The numeric ID of the new bodies. - /// Will never be negative. - /// There will only be one body with a particular ID at a time. - /// So, there will never be two robots with the same ID, or a robot and - /// a building with the same ID. - robotIDs: [int]; - /// The teams of the new bodies. - teamIDs: [byte]; - /// The types of the new bodies. - types: [BodyType]; - /// The locations of the bodies. - locs: VecTable; -} - -/// The map a round is played on. -table GameMap { - /// The name of a map. - name: string; - /// The bottom corner of the map. - minCorner: Vec; - /// The top corner of the map. - maxCorner: Vec; - /// The bodies on the map. - bodies: SpawnedBodyTable; - /// The random seed of the map. - randomSeed: int; - /// The factor to divide cooldowns by - passability: [double]; - - //lead locations - - // a vectable of lead cords - lead_locations: VecTable; - //inital lead amounts - initial_lead: [double]; -} - -/// Actions that can be performed. -/// Purely aesthetic; have no actual effect on simulation. -/// (Although the simulation may want to track the 'parents' of -/// particular robots.) -/// Actions may have 'targets', which are the units on which -/// the actions were performed. -enum Action : byte { - ATTACK, // combat unit types - DAZZLE, // wizard - SPAWN_UNIT, //archon - UPGRADE, //buildings - MINE, // miner - BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory. - ATTACKED, // when a body is attacked - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state - UPGRADE, // builder upgrades building, - REPAIR, // builder repairs building - CHANGE_HP, - FULLY_REPAIRED // prototype becomes a turret -} - -// Metadata - -/// Metadata about all bodies of a particular type. -table BodyTypeMetadata { - type: BodyType; - spawnSource: BodyType; - actionCooldown: float; - actionRadiusSquared: int; - visionRadiusSquared: int; - movingCooldown: float; - bytecodeLimit: int; - dps: int; // dps at lowest level - hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; -} - -/// Data relevant to a particular team. -table TeamData { - /// The name of the team. - name: string; - /// The java package the team uses. - packageName: string; - /// The ID of the team this data pertains to. - teamID: byte; -} - -// Profiler tables - -/// These tables are set-up so that they match closely with speedscope's file format documented at -/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. -/// The client uses speedscope to show the recorded data in an interactive interface. - -/// A single event in a profile. Represents either an open event (meaning a -/// method has been entered) or a close event (meaning the method was exited). -table ProfilerEvent { - /// Whether this is an open event (true) or a close event (false). - isOpen: bool; - /// The bytecode counter at the time the event occurred. - at: int; - /// The index of the method name in the ProfilerFile.frames array. - frame: int; -} - -/// A profile contains all events and is labeled with a name. -table ProfilerProfile { - /// The display-friendly name of the profile. - name: string; - /// The events that occurred in the profile. - events: [ProfilerEvent]; -} - -/// A profiler file is a collection of profiles. -/// When profiling is enabled there is one of these per team per match. -table ProfilerFile { - /// The method names that are referred to in the events. - frames: [string]; - /// The recorded profiles, one per robot. - profiles: [ProfilerProfile]; -} - -/// Events - -/// An Event is a single step that needs to be processed. -/// A saved game simply consists of a long list of Events. -/// Events can be divided by either being sent separately (e.g. as separate -/// websocket messages), or by being wrapped with a GameWrapper. -/// A game consists of a series of matches; a match consists of a series of -/// rounds, and is played on a single map. Each round is a single simulation -/// step. -union Event { - /// There should only be one GameHeader, at the start of the stream. - GameHeader, - /// There should be one MatchHeader at the start of each match. - MatchHeader, - /// A single simulation step. A round may be skipped if - /// nothing happens during its time. - Round, - /// There should be one MatchFooter at the end of each simulation step. - MatchFooter, - /// There should only be one GameFooter, at the end of the stream. - GameFooter -} - -table Constants{ - //amounts of resources added to each block per round - leadAdditiveIncease: double; - goldAdditiveIncease: double; - increase_period: int; -} - - -/// The first event sent in the game. Contains all metadata about the game. -table GameHeader { - /// The version of the spec this game complies with. - specVersion: string; - /// The teams participating in the game. - teams: [TeamData]; - /// Information about all body types in the game. - bodyTypeMetadata: [BodyTypeMetadata]; - - //game constants - constants: Constants; -} - - - - -/// The final event sent in the game. -table GameFooter { - /// The ID of the winning team of the game. - winner: byte; -} - -/// Sent to start a match. -table MatchHeader { - /// The map the match was played on. - map: GameMap; - /// The maximum number of rounds in this match. - maxRounds: int; -} - -/// Sent to end a match. -table MatchFooter { - /// The ID of the winning team. - winner: byte; - /// The number of rounds played. - totalRounds: int; - /// Profiler data for team A and B if profiling is enabled. - profilerFiles: [ProfilerFile]; -} - -/// A single time-step in a Game. -/// The bulk of the data in the file is stored in tables like this. -/// Note that a struct-of-arrays format is more space efficient than an array- -/// of-structs. -table Round { - /// The IDs of teams in the Game. - teamIDs: [int]; - - teamLead: [int]; - teamGold: [int]; - - /// The IDs of bodies that moved. - movedIDs: [int]; - /// The new locations of bodies that have moved. - movedLocs: VecTable; - - /// New bodies. - spawnedBodies: SpawnedBodyTable; - - /// The IDs of bodies that died. - diedIDs: [int]; - - /// The IDs of robots that performed actions. - /// IDs may repeat. - actionIDs: [int]; - /// The actions performed. These actions allow us to track how much soup or dirt a body carries. - actions: [Action]; - /// The 'targets' of the performed actions. Actions without targets may have any value - actionTargets: [int]; - - /// The IDs of the robots who changed their indicator strings - indicationStringIDs: [int]; - /// The messages of the robots who changed their indicator strings - indicationStrings: [string]; - - /// The IDs of bodies that set indicator dots - indicatorDotIDs: [int]; - /// The location of the indicator dots - indicatorDotLocs: VecTable; - /// The RGB values of the indicator dots - indicatorDotRGBs: RGBTable; - - /// The IDs of bodies that set indicator lines - indicatorLineIDs: [int]; - /// The start location of the indicator lines - indicatorLineStartLocs: VecTable; - /// The end location of the indicator lines - indicatorLineEndLocs: VecTable; - /// The RGB values of the indicator lines - indicatorLineRGBs: RGBTable; - - //logs have been replaced with indicator strings - - /// The first sent Round in a match should have index 1. (The starting state, - /// created by the MatchHeader, can be thought to have index 0.) - /// It should increase by one for each following round. - roundID: int; - - /// The IDs of player bodies. - bytecodeIDs: [int]; - /// The bytecodes used by the player bodies. - bytecodesUsed: [int]; -} - -/// Necessary due to flatbuffers requiring unions to be wrapped in tables. -table EventWrapper { - e: Event; -} - -/// If events are not otherwise delimited, this wrapper structure -/// allows a game to be stored in a single buffer. -/// The first event will be a GameHeader; the last event will be a GameFooter. -/// matchHeaders[0] is the index of the 0th match header in the event stream, -/// corresponding to matchFooters[0]. These indices allow quick traversal of -/// the file. -table GameWrapper { - /// The series of events comprising the game. - events: [EventWrapper]; - /// The indices of the headers of the matches, in order. - matchHeaders: [int]; - /// The indices of the footers of the matches, in order. - matchFooters: [int]; -} From c873abe725405e3121aecd1f88d8a9c344cd2481 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:34:19 -0500 Subject: [PATCH 010/413] Compile typescript for current schema --- schema/battlecode.fbs | 1 - schema/ts/battlecode_generated.ts | 956 ++++++++++++++++++------------ 2 files changed, 561 insertions(+), 396 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index f1b0b68a..76f65df9 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -89,7 +89,6 @@ enum Action : byte { ATTACK, // combat unit types DAZZLE, // wizard SPAWN_UNIT, //archon - UPGRADE, //buildings MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 9e0b103f..d8474d3c 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -9,27 +9,16 @@ import { flatbuffers } from "flatbuffers" */ export namespace battlecode.schema{ export enum BodyType{ - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - ENLIGHTENMENT_CENTER= 0, - - /** - * politicians use their influence to self destruct and capture other units - */ - POLITICIAN= 1, - - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - SLANDERER= 2, - - /** - * have the ability to identify slanderers - */ - MUCKRAKER= 3 + MINER= 0, + ARCHON= 1, + BUILDER= 2, + LABORATORY= 3, + GUARD= 4, + GUARD_TURRET= 5, + ARCHER= 6, + ARCHER_TURRET= 7, + WIZARD= 8, + WIZARD_TURRET= 9 }}; /** @@ -44,73 +33,18 @@ export enum BodyType{ */ export namespace battlecode.schema{ export enum Action{ - /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared - */ - EMPOWER= 0, - - /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID - */ - EMBEZZLE= 1, - - /** - * Slanderers turn into Politicians. - * Target: none - */ - CAMOUFLAGE= 2, - - /** - * Muckrakers can expose a slanderer. - * Target: an enemy body - */ - EXPOSE= 3, - - /** - * Units can change their flag. - * Target: new flag value - */ - SET_FLAG= 4, - - /** - * Builds a unit. - * Target: spawned unit - */ - SPAWN_UNIT= 5, - - /** - * Places a bid. - * Target: bid value - */ - PLACE_BID= 6, - - /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID - */ - CHANGE_TEAM= 7, - - /** - * A robot's influence changes. - * Target: delta value - */ - CHANGE_INFLUENCE= 8, - - /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 - */ - CHANGE_CONVICTION= 9, - - /** - * Dies due to an uncaught exception. - * Target: none - */ - DIE_EXCEPTION= 10 + ATTACK= 0, + DAZZLE= 1, + SPAWN_UNIT= 2, + MINE= 3, + BUILD= 4, + CONVERT_GOLD= 5, + ATTACKED= 6, + TRANSFORM= 7, + UPGRADE= 8, + REPAIR= 9, + CHANGE_HP= 10, + FULLY_REPAIRED= 11 }}; /** @@ -712,40 +646,11 @@ locs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; -/** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - * - * @param number index - * @returns number - */ -influences(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -influencesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -influencesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - /** * @param flatbuffers.Builder builder */ static startSpawnedBodyTable(builder:flatbuffers.Builder) { - builder.startObject(5); + builder.startObject(4); }; /** @@ -843,35 +748,6 @@ static addLocs(builder:flatbuffers.Builder, locsOffset:flatbuffers.Offset) { builder.addFieldOffset(3, locsOffset, 0); }; -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset influencesOffset - */ -static addInfluences(builder:flatbuffers.Builder, influencesOffset:flatbuffers.Offset) { - builder.addFieldOffset(4, influencesOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createInfluencesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startInfluencesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -}; - /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -881,13 +757,12 @@ static endSpawnedBodyTable(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createSpawnedBodyTable(builder:flatbuffers.Builder, robotIDsOffset:flatbuffers.Offset, teamIDsOffset:flatbuffers.Offset, typesOffset:flatbuffers.Offset, locsOffset:flatbuffers.Offset, influencesOffset:flatbuffers.Offset):flatbuffers.Offset { +static createSpawnedBodyTable(builder:flatbuffers.Builder, robotIDsOffset:flatbuffers.Offset, teamIDsOffset:flatbuffers.Offset, typesOffset:flatbuffers.Offset, locsOffset:flatbuffers.Offset):flatbuffers.Offset { SpawnedBodyTable.startSpawnedBodyTable(builder); SpawnedBodyTable.addRobotIDs(builder, robotIDsOffset); SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); SpawnedBodyTable.addTypes(builder, typesOffset); SpawnedBodyTable.addLocs(builder, locsOffset); - SpawnedBodyTable.addInfluences(builder, influencesOffset); return SpawnedBodyTable.endSpawnedBodyTable(builder); } } @@ -1005,11 +880,45 @@ passabilityArray():Float64Array|null { return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 16); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +initialLead(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; +}; + +/** + * @returns number + */ +initialLeadLength():number { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Float64Array + */ +initialLeadArray():Float64Array|null { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startGameMap(builder:flatbuffers.Builder) { - builder.startObject(6); + builder.startObject(8); }; /** @@ -1081,6 +990,43 @@ static startPassabilityVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(8, numElems, 8); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadLocationsOffset + */ +static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(6, leadLocationsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset initialLeadOffset + */ +static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, initialLeadOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(8, data.length, 8); + for (var i = data.length - 1; i >= 0; i--) { + builder.addFloat64(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startInitialLeadVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(8, numElems, 8); +}; + /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -1090,7 +1036,7 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, initialLeadOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); @@ -1098,6 +1044,8 @@ static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, GameMap.addBodies(builder, bodiesOffset); GameMap.addRandomSeed(builder, randomSeed); GameMap.addPassability(builder, passabilityOffset); + GameMap.addLeadLocations(builder, leadLocationsOffset); + GameMap.addInitialLead(builder, initialLeadOffset); return GameMap.endGameMap(builder); } } @@ -1133,90 +1081,123 @@ static getRootAsBodyTypeMetadata(bb:flatbuffers.ByteBuffer, obj?:BodyTypeMetadat }; /** - * The relevant type. - * * @returns battlecode.schema.BodyType */ type():battlecode.schema.BodyType { var offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.ENLIGHTENMENT_CENTER; + return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.MINER; }; /** - * The spawn source. - * * @returns battlecode.schema.BodyType */ spawnSource():battlecode.schema.BodyType { var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.ENLIGHTENMENT_CENTER; + return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.MINER; }; /** - * the convictionRatio of this type - * * @returns number */ -convictionRatio():number { +actionCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** - * cooldown of this type - * * @returns number */ -actionCooldown():number { +actionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 10); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * action radius if this type - * * @returns number */ -actionRadiusSquared():number { +visionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 12); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * sensor radius squared for this type - * * @returns number */ -sensorRadiusSquared():number { +movingCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 14); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** - * detection radius of this type - * * @returns number */ -detectionRadiusSquared():number { +bytecodeLimit():number { var offset = this.bb!.__offset(this.bb_pos, 16); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * bytecode limit for this type - * * @returns number */ -bytecodeLimit():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; +/** + * @returns number + */ +hp():number { + var offset = this.bb!.__offset(this.bb_pos, 20); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @returns number + */ +dpsMul():number { + var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +}; + +/** + * @returns number + */ +hpMul():number { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +}; + +/** + * @param number index + * @returns number + */ +upgradeCosts(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +upgradeCostsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +upgradeCostsArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(8); + builder.startObject(12); }; /** @@ -1224,7 +1205,7 @@ static startBodyTypeMetadata(builder:flatbuffers.Builder) { * @param battlecode.schema.BodyType type */ static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { - builder.addFieldInt8(0, type, battlecode.schema.BodyType.ENLIGHTENMENT_CENTER); + builder.addFieldInt8(0, type, battlecode.schema.BodyType.MINER); }; /** @@ -1232,15 +1213,7 @@ static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { * @param battlecode.schema.BodyType spawnSource */ static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema.BodyType) { - builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.ENLIGHTENMENT_CENTER); -}; - -/** - * @param flatbuffers.Builder builder - * @param number convictionRatio - */ -static addConvictionRatio(builder:flatbuffers.Builder, convictionRatio:number) { - builder.addFieldFloat32(2, convictionRatio, 0.0); + builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.MINER); }; /** @@ -1248,7 +1221,7 @@ static addConvictionRatio(builder:flatbuffers.Builder, convictionRatio:number) { * @param number actionCooldown */ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(3, actionCooldown, 0.0); + builder.addFieldFloat32(2, actionCooldown, 0.0); }; /** @@ -1256,23 +1229,23 @@ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { * @param number actionRadiusSquared */ static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(4, actionRadiusSquared, 0); + builder.addFieldInt32(3, actionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number sensorRadiusSquared + * @param number visionRadiusSquared */ -static addSensorRadiusSquared(builder:flatbuffers.Builder, sensorRadiusSquared:number) { - builder.addFieldInt32(5, sensorRadiusSquared, 0); +static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { + builder.addFieldInt32(4, visionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number detectionRadiusSquared + * @param number movingCooldown */ -static addDetectionRadiusSquared(builder:flatbuffers.Builder, detectionRadiusSquared:number) { - builder.addFieldInt32(6, detectionRadiusSquared, 0); +static addMovingCooldown(builder:flatbuffers.Builder, movingCooldown:number) { + builder.addFieldFloat32(5, movingCooldown, 0.0); }; /** @@ -1280,7 +1253,68 @@ static addDetectionRadiusSquared(builder:flatbuffers.Builder, detectionRadiusSqu * @param number bytecodeLimit */ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { - builder.addFieldInt32(7, bytecodeLimit, 0); + builder.addFieldInt32(6, bytecodeLimit, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number dps + */ +static addDps(builder:flatbuffers.Builder, dps:number) { + builder.addFieldInt32(7, dps, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number hp + */ +static addHp(builder:flatbuffers.Builder, hp:number) { + builder.addFieldInt32(8, hp, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number dpsMul + */ +static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { + builder.addFieldFloat32(9, dpsMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number hpMul + */ +static addHpMul(builder:flatbuffers.Builder, hpMul:number) { + builder.addFieldFloat32(10, hpMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset upgradeCostsOffset + */ +static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, upgradeCostsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startUpgradeCostsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); }; /** @@ -1292,16 +1326,20 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, convictionRatio:number, actionCooldown:number, actionRadiusSquared:number, sensorRadiusSquared:number, detectionRadiusSquared:number, bytecodeLimit:number):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addDps(builder, dps); + BodyTypeMetadata.addHp(builder, hp); + BodyTypeMetadata.addDpsMul(builder, dpsMul); + BodyTypeMetadata.addHpMul(builder, hpMul); + BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } } @@ -1718,98 +1756,199 @@ framesLength():number { * @param battlecode.schema.ProfilerProfile= obj * @returns battlecode.schema.ProfilerProfile */ -profiles(index: number, obj?:battlecode.schema.ProfilerProfile):battlecode.schema.ProfilerProfile|null { - var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? (obj || new battlecode.schema.ProfilerProfile).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +profiles(index: number, obj?:battlecode.schema.ProfilerProfile):battlecode.schema.ProfilerProfile|null { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? (obj || new battlecode.schema.ProfilerProfile).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +}; + +/** + * @returns number + */ +profilesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @param flatbuffers.Builder builder + */ +static startProfilerFile(builder:flatbuffers.Builder) { + builder.startObject(2); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset framesOffset + */ +static addFrames(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, framesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createFramesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startFramesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset profilesOffset + */ +static addProfiles(builder:flatbuffers.Builder, profilesOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, profilesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createProfilesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startProfilesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { + var offset = builder.endObject(); + return offset; +}; + +static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { + ProfilerFile.startProfilerFile(builder); + ProfilerFile.addFrames(builder, framesOffset); + ProfilerFile.addProfiles(builder, profilesOffset); + return ProfilerFile.endProfilerFile(builder); +} +} +} +/** + * @constructor + */ +export namespace battlecode.schema{ +export class Constants { + bb: flatbuffers.ByteBuffer|null = null; + + bb_pos:number = 0; +/** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Constants + */ +__init(i:number, bb:flatbuffers.ByteBuffer):Constants { + this.bb_pos = i; + this.bb = bb; + return this; }; /** - * @returns number + * @param flatbuffers.ByteBuffer bb + * @param Constants= obj + * @returns Constants */ -profilesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +static getRootAsConstants(bb:flatbuffers.ByteBuffer, obj?:Constants):Constants { + return (obj || new Constants).__init(bb.readInt32(bb.position()) + bb.position(), bb); }; /** - * @param flatbuffers.Builder builder + * @returns number */ -static startProfilerFile(builder:flatbuffers.Builder) { - builder.startObject(2); +leadAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; }; /** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset framesOffset + * @returns number */ -static addFrames(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset) { - builder.addFieldOffset(0, framesOffset, 0); +goldAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; }; /** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @returns number */ -static createFramesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addOffset(data[i]); - } - return builder.endVector(); +increasePeriod():number { + var offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @param flatbuffers.Builder builder - * @param number numElems */ -static startFramesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); +static startConstants(builder:flatbuffers.Builder) { + builder.startObject(3); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset profilesOffset + * @param number leadAdditiveIncease */ -static addProfiles(builder:flatbuffers.Builder, profilesOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, profilesOffset, 0); +static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { + builder.addFieldFloat64(0, leadAdditiveIncease, 0.0); }; /** * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @param number goldAdditiveIncease */ -static createProfilesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addOffset(data[i]); - } - return builder.endVector(); +static addGoldAdditiveIncease(builder:flatbuffers.Builder, goldAdditiveIncease:number) { + builder.addFieldFloat64(1, goldAdditiveIncease, 0.0); }; /** * @param flatbuffers.Builder builder - * @param number numElems + * @param number increasePeriod */ -static startProfilesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); +static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { + builder.addFieldInt32(2, increasePeriod, 0); }; /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset */ -static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { +static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { var offset = builder.endObject(); return offset; }; -static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { - ProfilerFile.startProfilerFile(builder); - ProfilerFile.addFrames(builder, framesOffset); - ProfilerFile.addProfiles(builder, profilesOffset); - return ProfilerFile.endProfilerFile(builder); +static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { + Constants.startConstants(builder); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); + Constants.addGoldAdditiveIncease(builder, goldAdditiveIncease); + Constants.addIncreasePeriod(builder, increasePeriod); + return Constants.endConstants(builder); } } } @@ -1896,11 +2035,20 @@ bodyTypeMetadataLength():number { return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; +/** + * @param battlecode.schema.Constants= obj + * @returns battlecode.schema.Constants|null + */ +constants(obj?:battlecode.schema.Constants):battlecode.schema.Constants|null { + var offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? (obj || new battlecode.schema.Constants).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + /** * @param flatbuffers.Builder builder */ static startGameHeader(builder:flatbuffers.Builder) { - builder.startObject(3); + builder.startObject(4); }; /** @@ -1969,6 +2117,14 @@ static startBodyTypeMetadataVector(builder:flatbuffers.Builder, numElems:number) builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset constantsOffset + */ +static addConstants(builder:flatbuffers.Builder, constantsOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, constantsOffset, 0); +}; + /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -1978,11 +2134,12 @@ static endGameHeader(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameHeader(builder:flatbuffers.Builder, specVersionOffset:flatbuffers.Offset, teamsOffset:flatbuffers.Offset, bodyTypeMetadataOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameHeader(builder:flatbuffers.Builder, specVersionOffset:flatbuffers.Offset, teamsOffset:flatbuffers.Offset, bodyTypeMetadataOffset:flatbuffers.Offset, constantsOffset:flatbuffers.Offset):flatbuffers.Offset { GameHeader.startGameHeader(builder); GameHeader.addSpecVersion(builder, specVersionOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); + GameHeader.addConstants(builder, constantsOffset); return GameHeader.endGameHeader(builder); } } @@ -2350,12 +2507,10 @@ teamIDsArray():Int32Array|null { }; /** - * The number of votes the teams get, 0 or 1. - * * @param number index * @returns number */ -teamVotes(index: number):number|null { +teamLead(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2363,7 +2518,7 @@ teamVotes(index: number):number|null { /** * @returns number */ -teamVotesLength():number { +teamLeadLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2371,18 +2526,16 @@ teamVotesLength():number { /** * @returns Int32Array */ -teamVotesArray():Int32Array|null { +teamLeadArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** - * The ID of the Enlightenment Center got the bid. - * * @param number index * @returns number */ -teamBidderIDs(index: number):number|null { +teamGold(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2390,7 +2543,7 @@ teamBidderIDs(index: number):number|null { /** * @returns number */ -teamBidderIDsLength():number { +teamGoldLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2398,7 +2551,7 @@ teamBidderIDsLength():number { /** * @returns Int32Array */ -teamBidderIDsArray():Int32Array|null { +teamGoldArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2561,6 +2714,55 @@ actionTargetsArray():Int32Array|null { return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * The IDs of the robots who changed their indicator strings + * + * @param number index + * @returns number + */ +indicationStringIDs(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +indicationStringIDsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +indicationStringIDsArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * The messages of the robots who changed their indicator strings + * + * @param number index + * @param flatbuffers.Encoding= optionalEncoding + * @returns string|Uint8Array + */ +indicationStrings(index: number):string +indicationStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array +indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; +}; + +/** + * @returns number + */ +indicationStringsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + /** * The IDs of bodies that set indicator dots * @@ -2568,7 +2770,7 @@ actionTargetsArray():Int32Array|null { * @returns number */ indicatorDotIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2576,7 +2778,7 @@ indicatorDotIDs(index: number):number|null { * @returns number */ indicatorDotIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2584,7 +2786,7 @@ indicatorDotIDsLength():number { * @returns Int32Array */ indicatorDotIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2595,7 +2797,7 @@ indicatorDotIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2606,7 +2808,7 @@ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|nul * @returns battlecode.schema.RGBTable|null */ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2617,7 +2819,7 @@ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nul * @returns number */ indicatorLineIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2625,7 +2827,7 @@ indicatorLineIDs(index: number):number|null { * @returns number */ indicatorLineIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2633,7 +2835,7 @@ indicatorLineIDsLength():number { * @returns Int32Array */ indicatorLineIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2644,7 +2846,7 @@ indicatorLineIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2655,7 +2857,7 @@ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTab * @returns battlecode.schema.VecTable|null */ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 38); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2666,40 +2868,10 @@ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable * @returns battlecode.schema.RGBTable|null */ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 36); + var offset = this.bb!.__offset(this.bb_pos, 40); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; -/** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - * - * @param flatbuffers.Encoding= optionalEncoding - * @returns string|Uint8Array|null - */ -logs():string|null -logs(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null -logs(optionalEncoding?:any):string|Uint8Array|null { - var offset = this.bb!.__offset(this.bb_pos, 38); - return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; -}; - /** * The first sent Round in a match should have index 1. (The starting state, * created by the MatchHeader, can be thought to have index 0.) @@ -2708,7 +2880,7 @@ logs(optionalEncoding?:any):string|Uint8Array|null { * @returns number */ roundID():number { - var offset = this.bb!.__offset(this.bb_pos, 40); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -2719,7 +2891,7 @@ roundID():number { * @returns number */ bytecodeIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2727,7 +2899,7 @@ bytecodeIDs(index: number):number|null { * @returns number */ bytecodeIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2735,7 +2907,7 @@ bytecodeIDsLength():number { * @returns Int32Array */ bytecodeIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2746,33 +2918,6 @@ bytecodeIDsArray():Int32Array|null { * @returns number */ bytecodesUsed(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -bytecodesUsedLength():number { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -bytecodesUsedArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - * - * @param number index - * @returns number - */ -teamNumBuffs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2780,7 +2925,7 @@ teamNumBuffs(index: number):number|null { /** * @returns number */ -teamNumBuffsLength():number { +bytecodesUsedLength():number { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2788,7 +2933,7 @@ teamNumBuffsLength():number { /** * @returns Int32Array */ -teamNumBuffsArray():Int32Array|null { +bytecodesUsedArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2831,10 +2976,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamVotesOffset + * @param flatbuffers.Offset teamLeadOffset */ -static addTeamVotes(builder:flatbuffers.Builder, teamVotesOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamVotesOffset, 0); +static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadOffset, 0); }; /** @@ -2842,7 +2987,7 @@ static addTeamVotes(builder:flatbuffers.Builder, teamVotesOffset:flatbuffers.Off * @param Array. data * @returns flatbuffers.Offset */ -static createTeamVotesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2854,16 +2999,16 @@ static createTeamVotesVector(builder:flatbuffers.Builder, data:number[] | Uint8A * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamVotesVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamBidderIDsOffset + * @param flatbuffers.Offset teamGoldOffset */ -static addTeamBidderIDs(builder:flatbuffers.Builder, teamBidderIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamBidderIDsOffset, 0); +static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldOffset, 0); }; /** @@ -2871,7 +3016,7 @@ static addTeamBidderIDs(builder:flatbuffers.Builder, teamBidderIDsOffset:flatbuf * @param Array. data * @returns flatbuffers.Offset */ -static createTeamBidderIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2883,7 +3028,7 @@ static createTeamBidderIDsVector(builder:flatbuffers.Builder, data:number[] | Ui * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamBidderIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3048,12 +3193,70 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset indicationStringIDsOffset + */ +static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicationStringIDsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startIndicationStringIDsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset indicationStringsOffset + */ +static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, indicationStringsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startIndicationStringsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + /** * @param flatbuffers.Builder builder * @param flatbuffers.Offset indicatorDotIDsOffset */ static addIndicatorDotIDs(builder:flatbuffers.Builder, indicatorDotIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicatorDotIDsOffset, 0); + builder.addFieldOffset(12, indicatorDotIDsOffset, 0); }; /** @@ -3082,7 +3285,7 @@ static startIndicatorDotIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorDotLocsOffset */ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, indicatorDotLocsOffset, 0); + builder.addFieldOffset(13, indicatorDotLocsOffset, 0); }; /** @@ -3090,7 +3293,7 @@ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:f * @param flatbuffers.Offset indicatorDotRGBsOffset */ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, indicatorDotRGBsOffset, 0); + builder.addFieldOffset(14, indicatorDotRGBsOffset, 0); }; /** @@ -3098,7 +3301,7 @@ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:f * @param flatbuffers.Offset indicatorLineIDsOffset */ static addIndicatorLineIDs(builder:flatbuffers.Builder, indicatorLineIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, indicatorLineIDsOffset, 0); + builder.addFieldOffset(15, indicatorLineIDsOffset, 0); }; /** @@ -3127,7 +3330,7 @@ static startIndicatorLineIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorLineStartLocsOffset */ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStartLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, indicatorLineStartLocsOffset, 0); + builder.addFieldOffset(16, indicatorLineStartLocsOffset, 0); }; /** @@ -3135,7 +3338,7 @@ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStart * @param flatbuffers.Offset indicatorLineEndLocsOffset */ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, indicatorLineEndLocsOffset, 0); + builder.addFieldOffset(17, indicatorLineEndLocsOffset, 0); }; /** @@ -3143,15 +3346,7 @@ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocs * @param flatbuffers.Offset indicatorLineRGBsOffset */ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(16, indicatorLineRGBsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset logsOffset - */ -static addLogs(builder:flatbuffers.Builder, logsOffset:flatbuffers.Offset) { - builder.addFieldOffset(17, logsOffset, 0); + builder.addFieldOffset(18, indicatorLineRGBsOffset, 0); }; /** @@ -3159,7 +3354,7 @@ static addLogs(builder:flatbuffers.Builder, logsOffset:flatbuffers.Offset) { * @param number roundID */ static addRoundID(builder:flatbuffers.Builder, roundID:number) { - builder.addFieldInt32(18, roundID, 0); + builder.addFieldInt32(19, roundID, 0); }; /** @@ -3167,7 +3362,7 @@ static addRoundID(builder:flatbuffers.Builder, roundID:number) { * @param flatbuffers.Offset bytecodeIDsOffset */ static addBytecodeIDs(builder:flatbuffers.Builder, bytecodeIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(19, bytecodeIDsOffset, 0); + builder.addFieldOffset(20, bytecodeIDsOffset, 0); }; /** @@ -3196,7 +3391,7 @@ static startBytecodeIDsVector(builder:flatbuffers.Builder, numElems:number) { * @param flatbuffers.Offset bytecodesUsedOffset */ static addBytecodesUsed(builder:flatbuffers.Builder, bytecodesUsedOffset:flatbuffers.Offset) { - builder.addFieldOffset(20, bytecodesUsedOffset, 0); + builder.addFieldOffset(21, bytecodesUsedOffset, 0); }; /** @@ -3220,35 +3415,6 @@ static startBytecodesUsedVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamNumBuffsOffset - */ -static addTeamNumBuffs(builder:flatbuffers.Builder, teamNumBuffsOffset:flatbuffers.Offset) { - builder.addFieldOffset(21, teamNumBuffsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createTeamNumBuffsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startTeamNumBuffsVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -}; - /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -3258,11 +3424,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamVotesOffset:flatbuffers.Offset, teamBidderIDsOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, logsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset, teamNumBuffsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadOffset:flatbuffers.Offset, teamGoldOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); + Round.addTeamLead(builder, teamLeadOffset); + Round.addTeamGold(builder, teamGoldOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); @@ -3270,6 +3436,8 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); + Round.addIndicationStringIDs(builder, indicationStringIDsOffset); + Round.addIndicationStrings(builder, indicationStringsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); @@ -3277,11 +3445,9 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); - Round.addLogs(builder, logsOffset); Round.addRoundID(builder, roundID); Round.addBytecodeIDs(builder, bytecodeIDsOffset); Round.addBytecodesUsed(builder, bytecodesUsedOffset); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); return Round.endRound(builder); } } From 93d916b23e38e18ecb8fe70b8401a258353664d5 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 11:25:34 -0500 Subject: [PATCH 011/413] tmp --- client/playback/src/gameworld.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 00ad1187..05ea2f0c 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -84,8 +84,6 @@ export type Log = { text: string }; - - /** * A frozen image of the game world. * @@ -478,9 +476,6 @@ export default class GameWorld { break; /// A robot can change team after being empowered /// Target: teamID - case schema.Action.CHANGE_TEAM: - // TODO remove the robot, don't alter it - break; /// A robot's influence changes. /// Target: delta value case schema.Action.CHANGE_INFLUENCE: From 950d013ebdd6dd3d6ea205883662a77eda38f9ed Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 13 Nov 2021 12:46:41 -0500 Subject: [PATCH 012/413] Changed 'sense' to 'see' for methods --- .../battlecode/common/RobotController.java | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 57b7fce1..3fdba4d6 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -108,135 +108,135 @@ public strictfp interface RobotController { int getUpgradeLevel(); // *********************************** - // ****** GENERAL SENSOR METHODS ***** + // ****** GENERAL VISION METHODS ***** // *********************************** /** - * Senses whether a MapLocation is on the map. Will throw an exception if - * the location is not within the sensor range. + * Checks whether a MapLocation is on the map. Will throw an exception if + * the location is not within the vision range. * * @param loc the location to check * @return true if the location is on the map; false otherwise. - * @throws GameActionException if the location is not within sensor range. + * @throws GameActionException if the location is not within vision range. * * @battlecode.doc.costlymethod */ boolean onTheMap(MapLocation loc) throws GameActionException; /** - * Checks whether the given location is within the robot's sensor range, and if it is on the map. + * Checks whether the given location is within the robot's vision range, and if it is on the map. * * @param loc the location to check - * @return true if the given location is within the robot's sensor range and is on the map; false otherwise. + * @return true if the given location is within the robot's vision range and is on the map; false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseLocation(MapLocation loc); + boolean canSeeLocation(MapLocation loc); /** - * Checks whether a point at the given radius squared is within the robot's sensor range. + * Checks whether a point at the given radius squared is within the robot's vision range. * * @param radiusSquared the radius to check - * @return true if the given radius is within the robot's sensor range; false otherwise. + * @return true if the given radius is within the robot's vision range; false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseRadiusSquared(int radiusSquared); + boolean canSeeRadiusSquared(int radiusSquared); /** - * Senses the robot at the given location, or null if there is no robot + * Sees the robot at the given location, or null if there is no robot * there. * * @param loc the location to check * @return the robot at the given location. - * @throws GameActionException if the location is not within sensor range. + * @throws GameActionException if the location is not within vision range. * * @battlecode.doc.costlymethod */ - RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException; + RobotInfo canSeeRobotAtLocation(MapLocation loc) throws GameActionException; /** * Tests whether the given robot exists and if it is within this robot's - * sensor range. + * vision range. * * @param id the ID of the robot to query - * @return true if the given robot is within this robot's sensor range; + * @return true if the given robot is within this robot's vision range; * false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseRobot(int id); + boolean canSeeRobot(int id); /** - * Senses information about a particular robot given its ID. + * Sees information about a particular robot given its ID. * * @param id the ID of the robot to query - * @return a RobotInfo object for the sensed robot. - * @throws GameActionException if the robot cannot be sensed (for example, - * if it doesn't exist or is out of sensor range). + * @return a RobotInfo object for the seen robot. + * @throws GameActionException if the robot cannot be seen (for example, + * if it doesn't exist or is out of vision range). * * @battlecode.doc.costlymethod */ - RobotInfo senseRobot(int id) throws GameActionException; + RobotInfo seeRobot(int id) throws GameActionException; /** - * Returns all robots within sensor radius. The objects are returned in no + * Returns all robots within vision radius. The objects are returned in no * particular order. * * @return array of RobotInfo objects, which contain information about all - * the robots you sensed. + * the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(); + RobotInfo[] seeNearbyRobots(); /** - * Returns all robots that can be sensed within a certain distance of this + * Returns all robots that can be seen within a certain distance of this * robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. - * @return array of RobotInfo objects of all the robots you sensed. + * @return array of RobotInfo objects of all the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(int radiusSquared); + RobotInfo[] seeNearbyRobots(int radiusSquared); /** - * Returns all robots of a given team that can be sensed within a certain + * Returns all robots of a given team that can be seen within a certain * distance of this robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. * @param team filter game objects by the given team. If null is passed, * robots from any team are returned - * @return array of RobotInfo objects of all the robots you sensed. + * @return array of RobotInfo objects of all the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(int radiusSquared, Team team); + RobotInfo[] seeNearbyRobots(int radiusSquared, Team team); /** - * Returns all robots of a given team that can be sensed within a certain + * Returns all robots of a given team that can be seen within a certain * radius of a specified location. The objects are returned in no particular * order. * * @param center center of the given search radius * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. * @param team filter game objects by the given team. If null is passed, * objects from all teams are returned - * @return sorted array of RobotInfo objects of the robots you sensed. + * @return sorted array of RobotInfo objects of the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team); + RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team); /** * Given a location, returns the passability of that location. @@ -246,33 +246,33 @@ public strictfp interface RobotController { * * @param loc the given location * @return the passability of that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double sensePassability(MapLocation loc) throws GameActionException; + double seePassability(MapLocation loc) throws GameActionException; /** * Given a location, returns the lead count of that location. * * @param loc the given location * @return the amount of lead at that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double senseLead(MapLocation loc) throws GameActionException; + double seeLead(MapLocation loc) throws GameActionException; /** * Given a location, returns the gold count of that location. * * @param loc the given location * @return the amount of gold at that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double senseGold(MapLocation loc) throws GameActionException; + double seeGold(MapLocation loc) throws GameActionException; /** * Returns the location adjacent to current location in the given direction. From 1be3db2b257a00d52fdf48fe1e12d4c3b539f410 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 6 Nov 2021 12:55:19 -0400 Subject: [PATCH 013/413] update RobotInfo to include level --- .../src/main/battlecode/common/RobotInfo.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index e4415225..ecb0afa6 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -22,6 +22,11 @@ public class RobotInfo { */ public final RobotType type; + /** + * The level of the robot. + */ + public final int level; + /** * The health of the robot. */ @@ -32,11 +37,12 @@ public class RobotInfo { */ public final MapLocation location; - public RobotInfo(int ID, Team team, RobotType type, int health, MapLocation location) { + public RobotInfo(int ID, Team team, RobotType type, int level, int health, MapLocation location) { super(); this.ID = ID; this.team = team; this.type = type; + this.level = level; this.health = health; this.location = location; } @@ -68,6 +74,15 @@ public RobotType getType() { return type; } + /** + * Returns the level of this robot. + * + * @return the level of this robot. + */ + public RobotType getLevel() { + return level; + } + /** * Returns the health of this robot. * @@ -96,6 +111,7 @@ public boolean equals(Object o) { if (ID != robotInfo.ID) return false; if (team != robotInfo.team) return false; if (type != robotInfo.type) return false; + if (level != robotInfo.level) return false; if (health != robotInfo.health) return false; return location.equals(robotInfo.location); } @@ -106,6 +122,7 @@ public int hashCode() { result = ID; result = 31 * result + team.hashCode(); result = 31 * result + type.ordinal(); + result = 31 * result + level; result = 31 * result + health; result = 31 * result + location.hashCode(); return result; @@ -117,6 +134,7 @@ public String toString() { "ID=" + ID + ", team=" + team + ", type=" + type + + ", level=" + level + ", health=" + health + ", location=" + location + '}'; From a7c549ab4b44db13868abe561b96a83202ad9a33 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 6 Nov 2021 13:08:43 -0400 Subject: [PATCH 014/413] change passability array to cooldownmultiplier --- .../src/main/battlecode/world/GameMapIO.java | 18 ++++++----- .../src/main/battlecode/world/GameWorld.java | 8 ++--- engine/src/main/battlecode/world/LiveMap.java | 32 +++++++++---------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index c875c584..b47e989e 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -228,9 +228,9 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int seed = raw.randomSeed(); final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); - double[] passabilityArray = new double[width * height]; + int[] cooldownMultiplierArray = new double[width * height]; for (int i = 0; i < width * height; i++) { - passabilityArray[i] = raw.passability(i); + cooldownMultiplierArray[i] = raw.cooldownMultiplier(i); // TODO } ArrayList initBodies = new ArrayList<>(); SpawnedBodyTable bodyTable = raw.bodies(); @@ -239,7 +239,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { RobotInfo[] initialBodies = initBodies.toArray(new RobotInfo[initBodies.size()]); return new LiveMap( - width, height, origin, seed, rounds, mapName, initialBodies, passabilityArray + width, height, origin, seed, rounds, mapName, initialBodies, cooldownMultiplierArray ); } @@ -254,7 +254,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int name = builder.createString(gameMap.getMapName()); int randomSeed = gameMap.getSeed(); - double[] passabilityArray = gameMap.getPassabilityArray(); + int[] cooldownMultiplierArray = gameMap.getCooldownMultiplierArray(); // Make body tables ArrayList bodyIDs = new ArrayList<>(); ArrayList bodyTeamIDs = new ArrayList<>(); @@ -262,10 +262,10 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { ArrayList bodyLocsXs = new ArrayList<>(); ArrayList bodyLocsYs = new ArrayList<>(); ArrayList bodyInfluences = new ArrayList<>(); - ArrayList passabilityArrayList = new ArrayList<>(); + ArrayList cooldownMultipliersArrayList = new ArrayList<>(); for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) { - passabilityArrayList.add(passabilityArray[i]); + cooldownMultiplierArrayList.add(cooldownMultiplierArray[i]); } for (RobotInfo robot : gameMap.getInitialBodies()) { @@ -291,7 +291,8 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { SpawnedBodyTable.addLocs(builder, locs); SpawnedBodyTable.addInfluences(builder, influences); int bodies = SpawnedBodyTable.endSpawnedBodyTable(builder); - int passabilityArrayInt = battlecode.schema.GameMap.createPassabilityVector(builder, ArrayUtils.toPrimitive(passabilityArrayList.toArray(new Double[passabilityArrayList.size()]))); + // TODO! fix this function call to smth that doesn't exist + int cooldownMultiplierArrayInt = battlecode.schema.GameMap.createCooldownMultiplierVector(builder, ArrayUtils.toPrimitive(cooldownMultiplierArrayList.toArray(new Integer[cooldownMultiplierArrayList.size()]))); // Build LiveMap for flatbuffer battlecode.schema.GameMap.startGameMap(builder); battlecode.schema.GameMap.addName(builder, name); @@ -300,7 +301,8 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { gameMap.getOrigin().y + gameMap.getHeight())); battlecode.schema.GameMap.addBodies(builder, bodies); battlecode.schema.GameMap.addRandomSeed(builder, randomSeed); - battlecode.schema.GameMap.addPassability(builder, passabilityArrayInt); + // TODO + battlecode.schema.GameMap.addCooldownMultiplier(builder, cooldownMultiplierArrayInt); return battlecode.schema.GameMap.endGameMap(builder); } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index b4ff29ae..4f91eaf1 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -28,7 +28,7 @@ public strictfp class GameWorld { protected final IDGenerator idGenerator; protected final GameStats gameStats; - private double[] passability; + private int[] cooldownMultiplier; private InternalRobot[][] robots; private final LiveMap gameMap; private final TeamInfo teamInfo; @@ -44,7 +44,7 @@ public strictfp class GameWorld { @SuppressWarnings("unchecked") public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) { - this.passability = gm.getPassabilityArray(); + this.cooldownMultiplier = gm.getCooldownMultiplierArray(); this.robots = new InternalRobot[gm.getWidth()][gm.getHeight()]; // if represented in cartesian, should be height-width, but this should allow us to index x-y this.currentRound = 0; this.idGenerator = new IDGenerator(gm.getSeed()); @@ -183,8 +183,8 @@ public int getCurrentRound() { return this.currentRound; } - public double getPassability(MapLocation loc) { - return this.passability[locationToIndex(loc)]; + public int getCooldownMultiplier(MapLocation loc) { + return this.cooldownMultiplier[locationToIndex(loc)]; } /** diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index c4067066..6087a5d2 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -48,7 +48,7 @@ public strictfp class LiveMap { */ private final RobotInfo[] initialBodies; // only contains Enlightenment Centers - private double[] passabilityArray; // factor to multiply cooldowns by + private int[] cooldownMultiplierArray; // factor to multiply cooldowns by public LiveMap(int width, int height, @@ -64,9 +64,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.passabilityArray = new double[width * height]; - for (int i = 0; i < passabilityArray.length; i++) { - this.passabilityArray[i] = 1; // default cooldown factor is 1 + this.cooldownMultiplierArray = new int[width * height]; + for (int i = 0; i < cooldownMultiplierArray.length; i++) { + this.cooldownMultiplierArray[i] = 1; // default cooldown factor is 1 } // invariant: bodies is sorted by id @@ -80,7 +80,7 @@ public LiveMap(int width, int rounds, String mapName, RobotInfo[] initialBodies, - double[] passabilityArray) { + int[] cooldownMultiplierArray) { this.width = width; this.height = height; this.origin = origin; @@ -88,9 +88,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.passabilityArray = new double[passabilityArray.length]; - for (int i = 0; i < passabilityArray.length; i++) { - this.passabilityArray[i] = passabilityArray[i]; + this.cooldownMultiplierArray = new int[cooldownMultiplierArray.length]; + for (int i = 0; i < cooldownMultiplierArray.length; i++) { + this.cooldownMultiplierArray[i] = cooldownMultiplierArray[i]; } // invariant: bodies is sorted by id @@ -104,7 +104,7 @@ public LiveMap(int width, */ public LiveMap(LiveMap gm) { this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.initialBodies, - gm.passabilityArray); + gm.cooldownMultiplierArray); } @Override @@ -127,7 +127,7 @@ public boolean equals(LiveMap other) { if (this.seed != other.seed) return false; if (!this.mapName.equals(other.mapName)) return false; if (!this.origin.equals(other.origin)) return false; - if (!Arrays.equals(this.passabilityArray, other.passabilityArray)) return false; + if (!Arrays.equals(this.cooldownMultiplierArray, other.cooldownMultiplierArray)) return false; return Arrays.equals(this.initialBodies, other.initialBodies); } @@ -139,7 +139,7 @@ public int hashCode() { result = 31 * result + seed; result = 31 * result + rounds; result = 31 * result + mapName.hashCode(); - result = 31 * result + Arrays.hashCode(passabilityArray); + result = 31 * result + Arrays.hashCode(cooldownMultiplierArray); result = 31 * result + Arrays.hashCode(initialBodies); return result; } @@ -246,13 +246,13 @@ public MapLocation getOrigin() { return origin; } - public double[] getPassabilityArray() { - return passabilityArray; + public double[] getCooldownMultiplierArray() { + return cooldownMultiplierArray; } @Override public String toString() { - if (passabilityArray.length == 0) + if (cooldownMultiplierArray.length == 0) return "LiveMap{" + "width=" + width + ", height=" + height + @@ -261,7 +261,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", len=" + Integer.toString(passabilityArray.length) + + ", len=" + Integer.toString(cooldownMultiplierArray.length) + "}"; else return "LiveMap{" + "width=" + width + @@ -271,7 +271,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", passabilityArray=:)" + Arrays.toString(passabilityArray) + + ", cooldownMultiplierArray=:)" + Arrays.toString(cooldownMultiplierArray) + "}"; } } \ No newline at end of file From 95369a3636b806c4403a0a40c79abdce271e7fc6 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sun, 7 Nov 2021 11:47:32 -0500 Subject: [PATCH 015/413] GameConstants for InternalRobot, e.g. cooldowns --- engine/src/main/battlecode/common/GameConstants.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index e5a39ba8..5cc00b7f 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -43,12 +43,19 @@ public class GameConstants { // ********************************* // ****** COOLDOWNS **************** // ********************************* - + + /** If the number of cooldown turns is >= this number, a robot cannot act. */ + public static final int COOLDOWN_LIMIT = 10; + + /** The number of cooldown turns reduced per turn. */ + public static final int COOLDOWNS_PER_TURN = 10; // ********************************* // ****** GAME MECHANICS *********** // ********************************* + /** A prototype building's starting health, as a multiplier of max health. */ + public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1; // ********************************* // ****** GAMEPLAY PROPERTIES ****** From d0e9931b083cbf9b9420d19e8633887b16d5daec Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sun, 7 Nov 2021 11:49:15 -0500 Subject: [PATCH 016/413] initial changes to InternalRobot, including adding RobotMode, using two cooldown clocks, etc. still need to add methods for transforming (buildings), healing (archon), upgrading, etc.) --- .../main/battlecode/world/InternalRobot.java | 335 +++++------------- 1 file changed, 84 insertions(+), 251 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index f2c421e0..1b00df0e 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -11,39 +11,39 @@ * - tiebreak by robot ID (priority to lower ID) */ public strictfp class InternalRobot implements Comparable { + private enum RobotMode { + ROBOT (true, true), + PROTOTYPE (false, false), + TURRET (true, false), + PORTABLE (false, true); + + public final boolean canAct; + public final boolean canMove; + } + private final RobotControllerImpl controller; private final GameWorld gameWorld; - /** - * The robot that built this robot. - * Equal to null if this is an Enlightenment Center, because they are specified by the map. - * This reference does not inhibit garbage collection because Enlightenment Centers never die. - */ - private final InternalRobot parent; - private final int ID; private Team team; private RobotType type; private MapLocation location; - private int influence; - private int flag; - private int bid; - - private ArrayList toCreate; - private ArrayList toCreateParents; + private int level; + private RobotMode mode; + private int health; private long controlBits; private int currentBytecodeLimit; private int bytecodesUsed; private int roundsAlive; - private double cooldownTurns; + private int cooldownTurns; + private int movementCooldownTurns; /** * Used to avoid recreating the same RobotInfo object over and over. */ - private RobotInfo cachedRobotInfoTrue; // true RobotType included - private RobotInfo cachedRobotInfoFake; // slanderers appear as politicians, null for all other robot types + private RobotInfo cachedRobotInfo; /** * Create a new internal representation of a robot @@ -52,23 +52,17 @@ public strictfp class InternalRobot implements Comparable { * @param type the type of the robot * @param loc the location of the robot * @param team the team of the robot - * @param influence the influence used to create the robot */ @SuppressWarnings("unchecked") - public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, MapLocation loc, Team team, int influence) { + public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, MapLocation loc, Team team) { this.parent = parent; this.ID = id; this.team = team; this.type = type; this.location = loc; - this.influence = influence; - this.conviction = (int) Math.ceil(this.type.convictionRatio * this.influence); - this.convictionCap = type == RobotType.ENLIGHTENMENT_CENTER ? GameConstants.ROBOT_INFLUENCE_LIMIT : this.conviction; - this.flag = 0; - this.bid = 0; - - this.toCreate = new ArrayList<>(); - this.toCreateParents = new ArrayList<>(); + this.level = 1; + this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE, RobotMode.ROBOT; + this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.maxHealth); this.controlBits = 0; this.currentBytecodeLimit = type.bytecodeLimit; @@ -76,6 +70,7 @@ public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, this.roundsAlive = 0; this.cooldownTurns = 0; + this.movementCooldownTurns = 0; this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); @@ -113,20 +108,16 @@ public MapLocation getLocation() { return location; } - public int getInfluence() { - return influence; - } - - public int getConviction() { - return conviction; + public int getLevel() { + return level; } - public int getFlag() { - return flag; + public RobotMode getMode() { + return mode; } - public int getBid() { - return bid; + public int getHealth() { + return health; } public long getControlBits() { @@ -141,41 +132,47 @@ public int getRoundsAlive() { return roundsAlive; } - public double getCooldownTurns() { + public int getCooldownTurns() { return cooldownTurns; } - public RobotInfo getRobotInfo(boolean trueSense) { - RobotInfo cachedRobotInfo = this.cachedRobotInfoTrue; - RobotType infoType = type; - if (!trueSense && type == RobotType.SLANDERER) { - cachedRobotInfo = this.cachedRobotInfoFake; - infoType = RobotType.POLITICIAN; - } + public int getMovementCooldownTurns() { + return movementCooldownTurns; + } + public RobotInfo getRobotInfo() { if (cachedRobotInfo != null && cachedRobotInfo.ID == ID && cachedRobotInfo.team == team - && cachedRobotInfo.type == infoType - && cachedRobotInfo.influence == influence - && cachedRobotInfo.conviction == conviction + && cachedRobotInfo.type == type + && cachedRobotInfo.level == level + && cachedRobotInfo.health == health && cachedRobotInfo.location.equals(location)) { return cachedRobotInfo; } - RobotInfo newRobotInfo = new RobotInfo(ID, team, infoType, influence, conviction, location); - if (!trueSense && type == RobotType.SLANDERER) { - this.cachedRobotInfoFake = newRobotInfo; - } else { - this.cachedRobotInfoTrue = newRobotInfo; - } - return newRobotInfo; + this.cachedRobotInfo = new RobotInfo(ID, team, type, level, health, location); + return this.cachedRobotInfo; } // ********************************** // ****** CHECK METHODS ************* // ********************************** + /** + * Returns whether the robot can perform actions, based on mode and cooldowns. + */ + public boolean canActCooldown() { + return this.mode.canAct && this.cooldownTurns < GameConstants.COOLDOWN_LIMIT; + } + + /** + * Returns whether the robot can move, based on mode and cooldowns. + */ + public boolean canMoveCooldown() { + return this.mode.canMove && this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; + } + /** * Returns the robot's action radius squared. */ @@ -190,13 +187,6 @@ public int getSensorRadiusSquared() { return this.type.sensorRadiusSquared; } - /** - * Returns the robot's detection radius squared. - */ - public int getDetectionRadiusSquared() { - return this.type.detectionRadiusSquared; - } - /** * Returns whether this robot can perform actions on the given location. * @@ -215,15 +205,6 @@ public boolean canSenseLocation(MapLocation toSense){ return this.location.distanceSquaredTo(toSense) <= getSensorRadiusSquared(); } - /** - * Returns whether this robot can detect the given location. - * - * @param toSense the MapLocation to detect - */ - public boolean canDetectLocation(MapLocation toSense){ - return this.location.distanceSquaredTo(toSense) <= getDetectionRadiusSquared(); - } - /** * Returns whether this robot can act at a given radius away. * @@ -242,15 +223,6 @@ public boolean canSenseRadiusSquared(int radiusSquared) { return radiusSquared <= getSensorRadiusSquared(); } - /** - * Returns whether this robot can detect something a given radius away. - * - * @param radiusSquared the distance squared to detect - */ - public boolean canDetectRadiusSquared(int radiusSquared) { - return radiusSquared <= getDetectionRadiusSquared(); - } - // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** @@ -268,32 +240,19 @@ public void setLocation(MapLocation loc) { /** * Resets the action cooldown. */ - public void addCooldownTurns() { - double passability = this.gameWorld.getPassability(this.location); - double newCooldownTurns = this.type.actionCooldown / passability; + public void addCooldownTurns(int numCooldownToAdd) { + int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); + int newCooldownTurns = numCooldownToAdd * cooldownMultiplier; setCooldownTurns(this.cooldownTurns + newCooldownTurns); } /** - * Adds influence given an amount to change this - * robot's influence by. Input can be negative to - * subtract influence. Conviction changes correspondingly. - * - * Only Enlightenment Centers should be able to change influence. - * - * @param influenceAmount the amount to change influence by (can be negative) + * Resets the movement cooldown. */ - public void addInfluenceAndConviction(int influenceAmount) { - int oldInfluence = this.influence; - this.influence += influenceAmount; - if (this.influence > GameConstants.ROBOT_INFLUENCE_LIMIT) { - this.influence = GameConstants.ROBOT_INFLUENCE_LIMIT; - } - this.conviction = this.influence; - if (this.influence != oldInfluence) { - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_INFLUENCE, this.influence - oldInfluence); - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.influence - oldInfluence); - } + public void addMovementCooldownTurns(int numMovementCooldownToAdd) { + int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); + int newMovementCooldownTurns = numMovementCooldownToAdd * cooldownMultiplier; + setCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); } /** @@ -301,153 +260,44 @@ public void addInfluenceAndConviction(int influenceAmount) { * * @param newTurns the number of cooldown turns */ - public void setCooldownTurns(double newTurns) { + public void setCooldownTurns(int newTurns) { this.cooldownTurns = newTurns; } /** - * Adds conviction given an amount to change this - * robot's conviction by. Input can be negative to - * subtract conviction. + * Sets the movement cooldown given the number of turns. * - * @param convictionAmount the amount to change conviction by (can be negative) - */ - public void addConviction(int convictionAmount) { - int oldConviction = this.conviction; - this.conviction += convictionAmount; - if (this.conviction > this.convictionCap) - this.conviction = this.convictionCap; - if (this.conviction != oldConviction) - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.conviction - oldConviction); - } - - /** - * Sets the flag given a new flag value. - * - * @param newFlag the new flag value + * @param newMovementTurns the number of movement cooldown turns */ - public void setFlag(int newFlag) { - this.flag = newFlag; - } - - /** - * Sets the bid given a new bid value. - * The amount of influence bid is held hostage. - * - * @param newBid the new flag value - */ - public void setBid(int newBid) { - resetBid(); - this.bid = newBid; - addInfluenceAndConviction(-this.bid); - } - - public void resetBid() { - addInfluenceAndConviction(this.bid); - this.bid = 0; - } - - public void addToCreate(InternalRobot parent, int ID, RobotType type, int influence, int conviction, MapLocation location) { - this.toCreateParents.add(parent); - this.toCreate.add(new RobotInfo(ID, this.team, type, influence, conviction, location)); + public void setMovementCooldownTurns(int newMovementTurns) { + this.movementCooldownTurns = newMovementTurns; } /** - * Empowers given a range. Doesn't self-destruct!! - * - * @param radiusSquared the empower range - */ - public void empower(int radiusSquared) { - InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, radiusSquared); - int numBots = robots.length - 1; // excluding self - if (numBots == 0) - return; - - double convictionToGive = this.conviction - GameConstants.EMPOWER_TAX; - if (convictionToGive <= 0) - return; - - final double convictionPerBot = convictionToGive / numBots; - final double buff = this.gameWorld.getTeamInfo().getBuff(this.team); - - for (InternalRobot bot : robots) { - // check if this robot - if (bot.equals(this)) - continue; - - double conv = convictionPerBot; - if (bot.type == RobotType.ENLIGHTENMENT_CENTER && bot.team == this.team) { - // conviction doesn't get buffed, do nothing - } else if (bot.type == RobotType.ENLIGHTENMENT_CENTER) { - // complicated stuff - double convNeededToConvert = bot.conviction / buff; - if (conv <= convNeededToConvert) { - // all of conviction is buffed - conv *= buff; - } else { - // conviction buffed until conversion - conv = bot.conviction + (conv - convNeededToConvert); - } - } else { - // buff applied, cast down - conv *= buff; - } - bot.empowered(this, (int) conv, this.team); - } - - // create new bots - for (int i = 0; i < toCreate.size(); i++) { - RobotInfo info = toCreate.get(i); - int id = this.gameWorld.spawnRobot(toCreateParents.get(i), info.getType(), info.getLocation(), this.team, info.getInfluence()); - InternalRobot newBot = this.gameWorld.getObjectInfo().getRobotByID(id); - if (newBot.type != RobotType.ENLIGHTENMENT_CENTER) { - // Shouldn't be called on an enlightenment center, because if spawned center's influence exceeds limit this would send a redundant change conviction action. - newBot.addConviction(info.getConviction() - newBot.getConviction()); - } - else { - // Resets influence and conviction to cap for enlightenment centers. Already done by reset bid, but nicer to do it here. - newBot.addInfluenceAndConviction(0); - } - this.gameWorld.getMatchMaker().addAction(info.getID(), Action.CHANGE_TEAM, id); - } - } - - /** - * Adds or removes influence, conviction, or both based on the type of the robot - * and the robot's affiliation. - * Called when a Politician Empowers. - * If conviction becomes negative, the robot switches teams or is destroyed. - * - * @param amount the amount this robot's conviction changes by (including all buffs) - * @param newTeam the team of the robot that empowered + * Adds health to a robot. Input can be negative to subtract health. + * + * @param healthAmount the amount to change health by (can be negative) */ - private void empowered(InternalRobot caller, int amount, Team newTeam) { - if (this.team != newTeam) - amount = -amount; - - if (type == RobotType.ENLIGHTENMENT_CENTER) - addInfluenceAndConviction(amount); - else - addConviction(amount); - - if (this.conviction < 0) { - if (this.type.canBeConverted()) { - int newInfluence = Math.abs(this.influence); - int newConviction = -this.conviction; - caller.addToCreate(this.parent, this.ID, this.type, newInfluence, newConviction, this.location); - } - this.gameWorld.destroyRobot(getID()); + public void addHealth(int healthAmount) { + int oldHealth = this.health; + this.health += healthAmount; + if (this.health > this.type.maxHealth) + this.health = this.type.maxHealth; + if (this.health <= 0) + this.gameWorld.destroyRobot(this.ID); + if (this.health != oldHealth) { + // TODO: double check this + this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_HEALTH, this.health - oldHealth); } } /** - * Empowers given a range. Doesn't self-destruct!! - * - * @param radiusSquared the empower range + * Attacks another robot. Assumes bot is in range. + * + * @param bot the robot to be attacked */ - public void expose(InternalRobot bot) { - this.gameWorld.addBuffs(this.team, bot.influence); - this.gameWorld.destroyRobot(bot.ID); + public void attack(InternalRobot bot) { + // TODO: checks this.type and attacks accordingly } // ********************************* @@ -461,7 +311,7 @@ public void processBeginningOfRound() { public void processBeginningOfTurn() { if (this.cooldownTurns > 0) - this.cooldownTurns = Math.max(0, this.cooldownTurns - 1); + this.cooldownTurns = Math.max(0, this.cooldownTurns - GameConstants.COOLDOWNS_PER_TURN); this.currentBytecodeLimit = getType().bytecodeLimit; } @@ -472,24 +322,7 @@ public void processEndOfTurn() { } public void processEndOfRound() { - // generate passive influence - InternalRobot target = (parent == null) ? this : parent; - if (target.getType() != RobotType.ENLIGHTENMENT_CENTER) { - throw new IllegalStateException("The robot's parent is not an Enlightenment Center"); - } - int passiveInfluence = this.type.getPassiveInfluence(this.influence, this.roundsAlive, this.gameWorld.getCurrentRound()); - if (passiveInfluence > 0 && this.team.isPlayer() && this.gameWorld.getObjectInfo().existsRobot(target.ID)) { - target.addInfluenceAndConviction(passiveInfluence); - if (this.type == RobotType.SLANDERER) { - this.gameWorld.getMatchMaker().addAction(this.ID, Action.EMBEZZLE, target.ID); - } - } - - // Slanderers turn into Politicians - if (this.type == RobotType.SLANDERER && this.roundsAlive == GameConstants.CAMOUFLAGE_NUM_ROUNDS) { - this.type = RobotType.POLITICIAN; - this.gameWorld.getMatchMaker().addAction(this.ID, Action.CAMOUFLAGE, -1); - } + // anything } // ********************************* From 02ca280e690ec59019f3bd9e71a6b6e9cbaa4ea3 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Mon, 8 Nov 2021 21:27:52 -0500 Subject: [PATCH 017/413] finished draft of InternalRobot, added transforming, upgrading, attacking, etc. --- .../main/battlecode/common/GameConstants.java | 22 +++++ .../main/battlecode/world/InternalRobot.java | 99 ++++++++++++++++++- 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 5cc00b7f..58382ded 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -50,6 +50,12 @@ public class GameConstants { /** The number of cooldown turns reduced per turn. */ public static final int COOLDOWNS_PER_TURN = 10; + /** The number of cooldown turns per transformation. */ + public static final int TRANSFORM_COOLDOWN = 100; + + /** The number of cooldown turns per upgrade. */ + public static final int UPGRADE_COOLDOWN = 100; + // ********************************* // ****** GAME MECHANICS *********** // ********************************* @@ -57,6 +63,22 @@ public class GameConstants { /** A prototype building's starting health, as a multiplier of max health. */ public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1; + /** The maximum level a building can be. */ + public static final int MAX_LEVEL = 3; + + /** The amount damage is reduced by every ricochet. */ + public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8; + + /** + * The amount of healing an archon does, based on level. + * + * @param level the level of the archon + * @return the healing amount + */ + public static float getArchonHealing(int level) { + return 8 * level; // TODO: update this. maybe move to RobotType? so both archons and builders have this function + } + // ********************************* // ****** GAMEPLAY PROPERTIES ****** // ********************************* diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 1b00df0e..5c37409d 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -70,7 +70,9 @@ public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, this.roundsAlive = 0; this.cooldownTurns = 0; + this.addCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.movementCooldownTurns = 0; + this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); @@ -173,6 +175,17 @@ public boolean canMoveCooldown() { return this.mode.canMove && this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; } + /** + * Returns whether the robot can transform, based on mode and cooldowns. + */ + public boolean canTransformCooldown() { + if (this.mode == RobotMode.TURRET) + return this.cooldownTurns < GameConstants.COOLDOWN_LIMIT; + if (this.mode == RobotMode.PORTABLE) + return this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; + return false; + } + /** * Returns the robot's action radius squared. */ @@ -281,23 +294,101 @@ public void setMovementCooldownTurns(int newMovementTurns) { public void addHealth(int healthAmount) { int oldHealth = this.health; this.health += healthAmount; - if (this.health > this.type.maxHealth) - this.health = this.type.maxHealth; - if (this.health <= 0) + int maxHealth = this.type.getMaxHealth(this.level); + if (this.health > maxHealth) { + this.health = maxHealth; + if (this.mode == RobotMode.PROTOTYPE) + this.mode = RobotMode.TURRET; + } + if (this.health <= 0) { + int leadDrop = this.type.getLeadDropped(this.level); + int goldDrop = this.type.getGoldDropped(this.level); + // TODO: drop resources at this location (interact with GameWorld) this.gameWorld.destroyRobot(this.ID); + } if (this.health != oldHealth) { // TODO: double check this this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_HEALTH, this.health - oldHealth); } } + // ********************************* + // ****** ACTION METHODS ********* + // ********************************* + + /** + * Transform from turret to portable mode, or vice versa. + */ + public void transform() { + if (this.canTransformCooldown()) { + if (this.mode == RobotMode.TURRET) { + this.mode = RobotMode.PORTABLE; + this.setMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } else { + this.mode = RobotMode.TURRET; + this.setCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } + } + } + + /** + * Upgrade a building. + */ + public void upgrade() { + if (this.mode == RobotMode.ROBOT || this.mode == RobotMode.PROTOTYPE) + return; + if (this.level == GameConstants.MAX_LEVEL) + return; + this.level++; + this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); + this.addCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + } + /** * Attacks another robot. Assumes bot is in range. + * Note: this is relatively inefficient(?), can possibly optimize + * by making better helper methods in GameWorld * * @param bot the robot to be attacked */ public void attack(InternalRobot bot) { - // TODO: checks this.type and attacks accordingly + if (!this.canActLocation(bot.location)) return; // TODO: throw exception? + int dmg = this.type.getDamage(this.level); + bot.addHealth(-dmg); + + int ricochetCount = this.type.getRicochetCount(this.level); + if (ricochetCount == 0) return; + + // only wizards should execute the next chunk of code + InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, this.type.getActionRadiusSquared(this.level)); + List validTargets = new ArrayList<>(); + for (InternalRobot x : robots) { + if (x.team == this.team) continue; + if (x.equals(bot)) continue; + validTargets.add(x); + } + + class RicochetPriority implements Comparator { + public int compare(InternalRobot a, InternalRobot b) + { + int aDistToTarget = bot.location.distanceSquaredTo(a.location); + int bDistToTarget = bot.location.distanceSquaredTo(b.location); + if (aDistToTarget != bDistToTarget) + return aDistToTarget - bDistToTarget; + int aDistToAttacker = this.location.distanceSquaredTo(a.location); + int bDistToAttacker = this.location.distanceSquaredTo(b.location); + if (aDistToAttacker != bDistToAttacker) + return aDistToAttacker - bDistToAttacker; + return a.compareTo(b); + } + } + + Collections.sort(validTargets, new RicochetPriority()); + for (int i = 0; i < ricochetCount; i++) { + dmg = (int) (dmg * GameConstants.RICOCHET_DAMAGE_MULTIPLIER); + validTargets.get(i).addHealth(-dmg); + } } // ********************************* From bc3514caa123577c30c2c88c44dfc094829df31f Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Mon, 8 Nov 2021 21:48:00 -0500 Subject: [PATCH 018/413] fixed misc typos and errors, InternalRobot ready for review --- .../main/battlecode/common/GameConstants.java | 6 ++--- .../src/main/battlecode/common/RobotInfo.java | 2 +- .../main/battlecode/world/InternalRobot.java | 25 +++++++++++-------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 58382ded..5db6909d 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -61,13 +61,13 @@ public class GameConstants { // ********************************* /** A prototype building's starting health, as a multiplier of max health. */ - public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1; + public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; /** The amount damage is reduced by every ricochet. */ - public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8; + public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8f; /** * The amount of healing an archon does, based on level. @@ -75,7 +75,7 @@ public class GameConstants { * @param level the level of the archon * @return the healing amount */ - public static float getArchonHealing(int level) { + public static int getArchonHealing(int level) { return 8 * level; // TODO: update this. maybe move to RobotType? so both archons and builders have this function } diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index ecb0afa6..450ba269 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -79,7 +79,7 @@ public RobotType getType() { * * @return the level of this robot. */ - public RobotType getLevel() { + public int getLevel() { return level; } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 5c37409d..59cf9681 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -1,6 +1,9 @@ package battlecode.world; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import battlecode.common.*; import battlecode.schema.Action; @@ -19,6 +22,11 @@ private enum RobotMode { public final boolean canAct; public final boolean canMove; + + RobotMode(boolean canAct, boolean canMove) { + this.canAct = canAct; + this.canMove = canMove; + } } private final RobotControllerImpl controller; @@ -54,15 +62,14 @@ private enum RobotMode { * @param team the team of the robot */ @SuppressWarnings("unchecked") - public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, MapLocation loc, Team team) { - this.parent = parent; + public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team team) { this.ID = id; this.team = team; this.type = type; this.location = loc; this.level = 1; - this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE, RobotMode.ROBOT; - this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.maxHealth); + this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.ROBOT; + this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.getMaxHealth(this.level)); this.controlBits = 0; this.currentBytecodeLimit = type.bytecodeLimit; @@ -90,10 +97,6 @@ public GameWorld getGameWorld() { return gameWorld; } - public InternalRobot getParent() { - return parent; - } - public int getID() { return ID; } @@ -369,6 +372,8 @@ public void attack(InternalRobot bot) { validTargets.add(x); } + MapLocation attackerLocation = this.location; + class RicochetPriority implements Comparator { public int compare(InternalRobot a, InternalRobot b) { @@ -376,8 +381,8 @@ public int compare(InternalRobot a, InternalRobot b) int bDistToTarget = bot.location.distanceSquaredTo(b.location); if (aDistToTarget != bDistToTarget) return aDistToTarget - bDistToTarget; - int aDistToAttacker = this.location.distanceSquaredTo(a.location); - int bDistToAttacker = this.location.distanceSquaredTo(b.location); + int aDistToAttacker = attackerLocation.distanceSquaredTo(a.location); + int bDistToAttacker = attackerLocation.distanceSquaredTo(b.location); if (aDistToAttacker != bDistToAttacker) return aDistToAttacker - bDistToAttacker; return a.compareTo(b); From 58db789b5bc926dd9441c061da62b3f9054a281d Mon Sep 17 00:00:00 2001 From: Pranali Date: Wed, 10 Nov 2021 19:02:13 -0500 Subject: [PATCH 019/413] Updated DominationFactor enum --- .../main/battlecode/world/DominationFactor.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/engine/src/main/battlecode/world/DominationFactor.java b/engine/src/main/battlecode/world/DominationFactor.java index a1913bef..3c9a76a3 100644 --- a/engine/src/main/battlecode/world/DominationFactor.java +++ b/engine/src/main/battlecode/world/DominationFactor.java @@ -5,21 +5,21 @@ */ public enum DominationFactor { /** - * Win by all enemy robots being destroyed (early end). + * Win by all enemy archons being destroyed (early end). */ ANNIHILATED, /** - * Win by more votes. + * Win by having more Archons. */ - MORE_VOTES, + MORE_ARCHONS, /** - * Win by having more Enlightenment Centers (tiebreak 1). + * Win by more gold net worth (tiebreak 1). */ - MORE_ENLIGHTENMENT_CENTERS, + MORE_GOLD_NET_WORTH, /** - * Win by more total influence (tiebreak 2). + * Win by more lead net worth (tiebreak 2). */ - MORE_INFLUENCE, + MORE_GOLD_NET_WORTH, /** * Win by coinflip (tiebreak 3). */ From 41f7d6e2bd28a4b99ae086b57e22d150f0059fc4 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 13 Nov 2021 11:59:16 -0500 Subject: [PATCH 020/413] Removed unneccesary functions and variables --- .../src/main/battlecode/world/TeamInfo.java | 75 +------------------ 1 file changed, 3 insertions(+), 72 deletions(-) diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 045536a9..8f3d92c3 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -6,94 +6,25 @@ /** * This class is used to hold information regarding team specific values such as - * team names, and victory points. + * team names. */ public class TeamInfo { private GameWorld gameWorld; - private int[] teamVotes; - private int[] numBuffs; - private Map> buffExpirations; // team -> round number, number of buffs expiring at the beginning of that round public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; - this.teamVotes = new int[2]; - this.numBuffs = new int[2]; - this.buffExpirations = new HashMap<>(); - for (int i = 0; i < 2; i++) - this.buffExpirations.put(i, new TreeMap<>()); } // ********************************* // ***** GETTER METHODS ************ // ********************************* - // Breaks if t.ordinal() > 1 (Team NEUTRAL) - public int getVotes(Team t) { - return this.teamVotes[t.ordinal()]; - } - - // returns current buff - public double getBuff(Team t) { - return 1 + GameConstants.EXPOSE_BUFF_FACTOR * this.numBuffs[t.ordinal()]; - } - - // returns the buff at specified round - public double getBuff(Team t, int roundNumber) { - int buffs = getNumBuffs(t, roundNumber); - return 1 + GameConstants.EXPOSE_BUFF_FACTOR * buffs; - } - - // returns the number of buffs at specified round - public int getNumBuffs(Team t, int roundNumber) { - int teamIdx = t.ordinal(); - int buffs = numBuffs[teamIdx]; - TreeMap map = this.buffExpirations.get(teamIdx); - for (int round : map.keySet()) { - if (round <= roundNumber) { - buffs -= map.get(round); - } else { - break; // treemaps are in increasing order - } - } - return buffs; - } + // ********************************* // ***** UPDATE METHODS ************ // ********************************* - public void addVote(Team t) { - teamVotes[t.ordinal()]++; - } - - // called at the end of every round - public void addBuffs(int nextRound, Team t, int buffs) { - int teamIdx = t.ordinal(); - this.numBuffs[teamIdx] += buffs; - TreeMap map = this.buffExpirations.get(teamIdx); - int expirationRound = nextRound + GameConstants.EXPOSE_BUFF_NUM_ROUNDS; - map.put(expirationRound, map.getOrDefault(expirationRound, 0) + buffs); - } - - // called at the beginning of every round - public void updateNumBuffs(int currentRound) { - updateNumBuffs(currentRound, Team.A); - updateNumBuffs(currentRound, Team.B); - } - - private void updateNumBuffs(int currentRound, Team t) { - int teamIdx = t.ordinal(); - TreeMap map = this.buffExpirations.get(teamIdx); - Iterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry item = it.next(); - if (item.getKey() <= currentRound) { - this.numBuffs[teamIdx] -= item.getValue(); - it.remove(); - } else { - break; // treemaps are in increasing order - } - } - } + } From 5040889acf176d057698d2835e9edf77a7708914 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 13 Nov 2021 12:11:47 -0500 Subject: [PATCH 021/413] Rebasing off of engine --- .../main/battlecode/common/GameConstants.java | 31 +- .../src/main/battlecode/common/RobotInfo.java | 20 +- .../src/main/battlecode/world/GameMapIO.java | 18 +- .../main/battlecode/world/InternalRobot.java | 417 ++++++++++-------- 4 files changed, 254 insertions(+), 232 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 5db6909d..e5a39ba8 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -43,41 +43,12 @@ public class GameConstants { // ********************************* // ****** COOLDOWNS **************** // ********************************* - - /** If the number of cooldown turns is >= this number, a robot cannot act. */ - public static final int COOLDOWN_LIMIT = 10; - - /** The number of cooldown turns reduced per turn. */ - public static final int COOLDOWNS_PER_TURN = 10; - - /** The number of cooldown turns per transformation. */ - public static final int TRANSFORM_COOLDOWN = 100; - - /** The number of cooldown turns per upgrade. */ - public static final int UPGRADE_COOLDOWN = 100; + // ********************************* // ****** GAME MECHANICS *********** // ********************************* - /** A prototype building's starting health, as a multiplier of max health. */ - public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; - - /** The maximum level a building can be. */ - public static final int MAX_LEVEL = 3; - - /** The amount damage is reduced by every ricochet. */ - public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8f; - - /** - * The amount of healing an archon does, based on level. - * - * @param level the level of the archon - * @return the healing amount - */ - public static int getArchonHealing(int level) { - return 8 * level; // TODO: update this. maybe move to RobotType? so both archons and builders have this function - } // ********************************* // ****** GAMEPLAY PROPERTIES ****** diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index 450ba269..e4415225 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -22,11 +22,6 @@ public class RobotInfo { */ public final RobotType type; - /** - * The level of the robot. - */ - public final int level; - /** * The health of the robot. */ @@ -37,12 +32,11 @@ public class RobotInfo { */ public final MapLocation location; - public RobotInfo(int ID, Team team, RobotType type, int level, int health, MapLocation location) { + public RobotInfo(int ID, Team team, RobotType type, int health, MapLocation location) { super(); this.ID = ID; this.team = team; this.type = type; - this.level = level; this.health = health; this.location = location; } @@ -74,15 +68,6 @@ public RobotType getType() { return type; } - /** - * Returns the level of this robot. - * - * @return the level of this robot. - */ - public int getLevel() { - return level; - } - /** * Returns the health of this robot. * @@ -111,7 +96,6 @@ public boolean equals(Object o) { if (ID != robotInfo.ID) return false; if (team != robotInfo.team) return false; if (type != robotInfo.type) return false; - if (level != robotInfo.level) return false; if (health != robotInfo.health) return false; return location.equals(robotInfo.location); } @@ -122,7 +106,6 @@ public int hashCode() { result = ID; result = 31 * result + team.hashCode(); result = 31 * result + type.ordinal(); - result = 31 * result + level; result = 31 * result + health; result = 31 * result + location.hashCode(); return result; @@ -134,7 +117,6 @@ public String toString() { "ID=" + ID + ", team=" + team + ", type=" + type + - ", level=" + level + ", health=" + health + ", location=" + location + '}'; diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index b47e989e..c875c584 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -228,9 +228,9 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int seed = raw.randomSeed(); final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); - int[] cooldownMultiplierArray = new double[width * height]; + double[] passabilityArray = new double[width * height]; for (int i = 0; i < width * height; i++) { - cooldownMultiplierArray[i] = raw.cooldownMultiplier(i); // TODO + passabilityArray[i] = raw.passability(i); } ArrayList initBodies = new ArrayList<>(); SpawnedBodyTable bodyTable = raw.bodies(); @@ -239,7 +239,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { RobotInfo[] initialBodies = initBodies.toArray(new RobotInfo[initBodies.size()]); return new LiveMap( - width, height, origin, seed, rounds, mapName, initialBodies, cooldownMultiplierArray + width, height, origin, seed, rounds, mapName, initialBodies, passabilityArray ); } @@ -254,7 +254,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int name = builder.createString(gameMap.getMapName()); int randomSeed = gameMap.getSeed(); - int[] cooldownMultiplierArray = gameMap.getCooldownMultiplierArray(); + double[] passabilityArray = gameMap.getPassabilityArray(); // Make body tables ArrayList bodyIDs = new ArrayList<>(); ArrayList bodyTeamIDs = new ArrayList<>(); @@ -262,10 +262,10 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { ArrayList bodyLocsXs = new ArrayList<>(); ArrayList bodyLocsYs = new ArrayList<>(); ArrayList bodyInfluences = new ArrayList<>(); - ArrayList cooldownMultipliersArrayList = new ArrayList<>(); + ArrayList passabilityArrayList = new ArrayList<>(); for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) { - cooldownMultiplierArrayList.add(cooldownMultiplierArray[i]); + passabilityArrayList.add(passabilityArray[i]); } for (RobotInfo robot : gameMap.getInitialBodies()) { @@ -291,8 +291,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { SpawnedBodyTable.addLocs(builder, locs); SpawnedBodyTable.addInfluences(builder, influences); int bodies = SpawnedBodyTable.endSpawnedBodyTable(builder); - // TODO! fix this function call to smth that doesn't exist - int cooldownMultiplierArrayInt = battlecode.schema.GameMap.createCooldownMultiplierVector(builder, ArrayUtils.toPrimitive(cooldownMultiplierArrayList.toArray(new Integer[cooldownMultiplierArrayList.size()]))); + int passabilityArrayInt = battlecode.schema.GameMap.createPassabilityVector(builder, ArrayUtils.toPrimitive(passabilityArrayList.toArray(new Double[passabilityArrayList.size()]))); // Build LiveMap for flatbuffer battlecode.schema.GameMap.startGameMap(builder); battlecode.schema.GameMap.addName(builder, name); @@ -301,8 +300,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { gameMap.getOrigin().y + gameMap.getHeight())); battlecode.schema.GameMap.addBodies(builder, bodies); battlecode.schema.GameMap.addRandomSeed(builder, randomSeed); - // TODO - battlecode.schema.GameMap.addCooldownMultiplier(builder, cooldownMultiplierArrayInt); + battlecode.schema.GameMap.addPassability(builder, passabilityArrayInt); return battlecode.schema.GameMap.endGameMap(builder); } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 59cf9681..f2c421e0 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -1,9 +1,6 @@ package battlecode.world; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; import battlecode.common.*; import battlecode.schema.Action; @@ -14,44 +11,39 @@ * - tiebreak by robot ID (priority to lower ID) */ public strictfp class InternalRobot implements Comparable { - private enum RobotMode { - ROBOT (true, true), - PROTOTYPE (false, false), - TURRET (true, false), - PORTABLE (false, true); - - public final boolean canAct; - public final boolean canMove; - - RobotMode(boolean canAct, boolean canMove) { - this.canAct = canAct; - this.canMove = canMove; - } - } - private final RobotControllerImpl controller; private final GameWorld gameWorld; + /** + * The robot that built this robot. + * Equal to null if this is an Enlightenment Center, because they are specified by the map. + * This reference does not inhibit garbage collection because Enlightenment Centers never die. + */ + private final InternalRobot parent; + private final int ID; private Team team; private RobotType type; private MapLocation location; - private int level; - private RobotMode mode; - private int health; + private int influence; + private int flag; + private int bid; + + private ArrayList toCreate; + private ArrayList toCreateParents; private long controlBits; private int currentBytecodeLimit; private int bytecodesUsed; private int roundsAlive; - private int cooldownTurns; - private int movementCooldownTurns; + private double cooldownTurns; /** * Used to avoid recreating the same RobotInfo object over and over. */ - private RobotInfo cachedRobotInfo; + private RobotInfo cachedRobotInfoTrue; // true RobotType included + private RobotInfo cachedRobotInfoFake; // slanderers appear as politicians, null for all other robot types /** * Create a new internal representation of a robot @@ -60,16 +52,23 @@ private enum RobotMode { * @param type the type of the robot * @param loc the location of the robot * @param team the team of the robot + * @param influence the influence used to create the robot */ @SuppressWarnings("unchecked") - public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team team) { + public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, MapLocation loc, Team team, int influence) { + this.parent = parent; this.ID = id; this.team = team; this.type = type; this.location = loc; - this.level = 1; - this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.ROBOT; - this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.getMaxHealth(this.level)); + this.influence = influence; + this.conviction = (int) Math.ceil(this.type.convictionRatio * this.influence); + this.convictionCap = type == RobotType.ENLIGHTENMENT_CENTER ? GameConstants.ROBOT_INFLUENCE_LIMIT : this.conviction; + this.flag = 0; + this.bid = 0; + + this.toCreate = new ArrayList<>(); + this.toCreateParents = new ArrayList<>(); this.controlBits = 0; this.currentBytecodeLimit = type.bytecodeLimit; @@ -77,9 +76,6 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.roundsAlive = 0; this.cooldownTurns = 0; - this.addCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); - this.movementCooldownTurns = 0; - this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); @@ -97,6 +93,10 @@ public GameWorld getGameWorld() { return gameWorld; } + public InternalRobot getParent() { + return parent; + } + public int getID() { return ID; } @@ -113,16 +113,20 @@ public MapLocation getLocation() { return location; } - public int getLevel() { - return level; + public int getInfluence() { + return influence; + } + + public int getConviction() { + return conviction; } - public RobotMode getMode() { - return mode; + public int getFlag() { + return flag; } - public int getHealth() { - return health; + public int getBid() { + return bid; } public long getControlBits() { @@ -137,58 +141,41 @@ public int getRoundsAlive() { return roundsAlive; } - public int getCooldownTurns() { + public double getCooldownTurns() { return cooldownTurns; } - public int getMovementCooldownTurns() { - return movementCooldownTurns; - } + public RobotInfo getRobotInfo(boolean trueSense) { + RobotInfo cachedRobotInfo = this.cachedRobotInfoTrue; + RobotType infoType = type; + if (!trueSense && type == RobotType.SLANDERER) { + cachedRobotInfo = this.cachedRobotInfoFake; + infoType = RobotType.POLITICIAN; + } - public RobotInfo getRobotInfo() { if (cachedRobotInfo != null && cachedRobotInfo.ID == ID && cachedRobotInfo.team == team - && cachedRobotInfo.type == type - && cachedRobotInfo.level == level - && cachedRobotInfo.health == health + && cachedRobotInfo.type == infoType + && cachedRobotInfo.influence == influence + && cachedRobotInfo.conviction == conviction && cachedRobotInfo.location.equals(location)) { return cachedRobotInfo; } - this.cachedRobotInfo = new RobotInfo(ID, team, type, level, health, location); - return this.cachedRobotInfo; + RobotInfo newRobotInfo = new RobotInfo(ID, team, infoType, influence, conviction, location); + if (!trueSense && type == RobotType.SLANDERER) { + this.cachedRobotInfoFake = newRobotInfo; + } else { + this.cachedRobotInfoTrue = newRobotInfo; + } + return newRobotInfo; } // ********************************** // ****** CHECK METHODS ************* // ********************************** - /** - * Returns whether the robot can perform actions, based on mode and cooldowns. - */ - public boolean canActCooldown() { - return this.mode.canAct && this.cooldownTurns < GameConstants.COOLDOWN_LIMIT; - } - - /** - * Returns whether the robot can move, based on mode and cooldowns. - */ - public boolean canMoveCooldown() { - return this.mode.canMove && this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; - } - - /** - * Returns whether the robot can transform, based on mode and cooldowns. - */ - public boolean canTransformCooldown() { - if (this.mode == RobotMode.TURRET) - return this.cooldownTurns < GameConstants.COOLDOWN_LIMIT; - if (this.mode == RobotMode.PORTABLE) - return this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; - return false; - } - /** * Returns the robot's action radius squared. */ @@ -203,6 +190,13 @@ public int getSensorRadiusSquared() { return this.type.sensorRadiusSquared; } + /** + * Returns the robot's detection radius squared. + */ + public int getDetectionRadiusSquared() { + return this.type.detectionRadiusSquared; + } + /** * Returns whether this robot can perform actions on the given location. * @@ -221,6 +215,15 @@ public boolean canSenseLocation(MapLocation toSense){ return this.location.distanceSquaredTo(toSense) <= getSensorRadiusSquared(); } + /** + * Returns whether this robot can detect the given location. + * + * @param toSense the MapLocation to detect + */ + public boolean canDetectLocation(MapLocation toSense){ + return this.location.distanceSquaredTo(toSense) <= getDetectionRadiusSquared(); + } + /** * Returns whether this robot can act at a given radius away. * @@ -239,6 +242,15 @@ public boolean canSenseRadiusSquared(int radiusSquared) { return radiusSquared <= getSensorRadiusSquared(); } + /** + * Returns whether this robot can detect something a given radius away. + * + * @param radiusSquared the distance squared to detect + */ + public boolean canDetectRadiusSquared(int radiusSquared) { + return radiusSquared <= getDetectionRadiusSquared(); + } + // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** @@ -256,19 +268,32 @@ public void setLocation(MapLocation loc) { /** * Resets the action cooldown. */ - public void addCooldownTurns(int numCooldownToAdd) { - int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); - int newCooldownTurns = numCooldownToAdd * cooldownMultiplier; + public void addCooldownTurns() { + double passability = this.gameWorld.getPassability(this.location); + double newCooldownTurns = this.type.actionCooldown / passability; setCooldownTurns(this.cooldownTurns + newCooldownTurns); } /** - * Resets the movement cooldown. + * Adds influence given an amount to change this + * robot's influence by. Input can be negative to + * subtract influence. Conviction changes correspondingly. + * + * Only Enlightenment Centers should be able to change influence. + * + * @param influenceAmount the amount to change influence by (can be negative) */ - public void addMovementCooldownTurns(int numMovementCooldownToAdd) { - int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); - int newMovementCooldownTurns = numMovementCooldownToAdd * cooldownMultiplier; - setCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); + public void addInfluenceAndConviction(int influenceAmount) { + int oldInfluence = this.influence; + this.influence += influenceAmount; + if (this.influence > GameConstants.ROBOT_INFLUENCE_LIMIT) { + this.influence = GameConstants.ROBOT_INFLUENCE_LIMIT; + } + this.conviction = this.influence; + if (this.influence != oldInfluence) { + this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_INFLUENCE, this.influence - oldInfluence); + this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.influence - oldInfluence); + } } /** @@ -276,126 +301,155 @@ public void addMovementCooldownTurns(int numMovementCooldownToAdd) { * * @param newTurns the number of cooldown turns */ - public void setCooldownTurns(int newTurns) { + public void setCooldownTurns(double newTurns) { this.cooldownTurns = newTurns; } /** - * Sets the movement cooldown given the number of turns. + * Adds conviction given an amount to change this + * robot's conviction by. Input can be negative to + * subtract conviction. * - * @param newMovementTurns the number of movement cooldown turns + * @param convictionAmount the amount to change conviction by (can be negative) */ - public void setMovementCooldownTurns(int newMovementTurns) { - this.movementCooldownTurns = newMovementTurns; + public void addConviction(int convictionAmount) { + int oldConviction = this.conviction; + this.conviction += convictionAmount; + if (this.conviction > this.convictionCap) + this.conviction = this.convictionCap; + if (this.conviction != oldConviction) + this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.conviction - oldConviction); } /** - * Adds health to a robot. Input can be negative to subtract health. - * - * @param healthAmount the amount to change health by (can be negative) + * Sets the flag given a new flag value. + * + * @param newFlag the new flag value */ - public void addHealth(int healthAmount) { - int oldHealth = this.health; - this.health += healthAmount; - int maxHealth = this.type.getMaxHealth(this.level); - if (this.health > maxHealth) { - this.health = maxHealth; - if (this.mode == RobotMode.PROTOTYPE) - this.mode = RobotMode.TURRET; - } - if (this.health <= 0) { - int leadDrop = this.type.getLeadDropped(this.level); - int goldDrop = this.type.getGoldDropped(this.level); - // TODO: drop resources at this location (interact with GameWorld) - this.gameWorld.destroyRobot(this.ID); - } - if (this.health != oldHealth) { - // TODO: double check this - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_HEALTH, this.health - oldHealth); - } + public void setFlag(int newFlag) { + this.flag = newFlag; } - // ********************************* - // ****** ACTION METHODS ********* - // ********************************* - /** - * Transform from turret to portable mode, or vice versa. + * Sets the bid given a new bid value. + * The amount of influence bid is held hostage. + * + * @param newBid the new flag value */ - public void transform() { - if (this.canTransformCooldown()) { - if (this.mode == RobotMode.TURRET) { - this.mode = RobotMode.PORTABLE; - this.setMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); - } else { - this.mode = RobotMode.TURRET; - this.setCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); - } - } + public void setBid(int newBid) { + resetBid(); + this.bid = newBid; + addInfluenceAndConviction(-this.bid); + } + + public void resetBid() { + addInfluenceAndConviction(this.bid); + this.bid = 0; + } + + public void addToCreate(InternalRobot parent, int ID, RobotType type, int influence, int conviction, MapLocation location) { + this.toCreateParents.add(parent); + this.toCreate.add(new RobotInfo(ID, this.team, type, influence, conviction, location)); } /** - * Upgrade a building. + * Empowers given a range. Doesn't self-destruct!! + * + * @param radiusSquared the empower range */ - public void upgrade() { - if (this.mode == RobotMode.ROBOT || this.mode == RobotMode.PROTOTYPE) + public void empower(int radiusSquared) { + InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, radiusSquared); + int numBots = robots.length - 1; // excluding self + if (numBots == 0) return; - if (this.level == GameConstants.MAX_LEVEL) + + double convictionToGive = this.conviction - GameConstants.EMPOWER_TAX; + if (convictionToGive <= 0) return; - this.level++; - this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); - this.addCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - } - /** - * Attacks another robot. Assumes bot is in range. - * Note: this is relatively inefficient(?), can possibly optimize - * by making better helper methods in GameWorld - * - * @param bot the robot to be attacked - */ - public void attack(InternalRobot bot) { - if (!this.canActLocation(bot.location)) return; // TODO: throw exception? - int dmg = this.type.getDamage(this.level); - bot.addHealth(-dmg); - - int ricochetCount = this.type.getRicochetCount(this.level); - if (ricochetCount == 0) return; - - // only wizards should execute the next chunk of code - InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, this.type.getActionRadiusSquared(this.level)); - List validTargets = new ArrayList<>(); - for (InternalRobot x : robots) { - if (x.team == this.team) continue; - if (x.equals(bot)) continue; - validTargets.add(x); + final double convictionPerBot = convictionToGive / numBots; + final double buff = this.gameWorld.getTeamInfo().getBuff(this.team); + + for (InternalRobot bot : robots) { + // check if this robot + if (bot.equals(this)) + continue; + + double conv = convictionPerBot; + if (bot.type == RobotType.ENLIGHTENMENT_CENTER && bot.team == this.team) { + // conviction doesn't get buffed, do nothing + } else if (bot.type == RobotType.ENLIGHTENMENT_CENTER) { + // complicated stuff + double convNeededToConvert = bot.conviction / buff; + if (conv <= convNeededToConvert) { + // all of conviction is buffed + conv *= buff; + } else { + // conviction buffed until conversion + conv = bot.conviction + (conv - convNeededToConvert); + } + } else { + // buff applied, cast down + conv *= buff; + } + bot.empowered(this, (int) conv, this.team); } - MapLocation attackerLocation = this.location; - - class RicochetPriority implements Comparator { - public int compare(InternalRobot a, InternalRobot b) - { - int aDistToTarget = bot.location.distanceSquaredTo(a.location); - int bDistToTarget = bot.location.distanceSquaredTo(b.location); - if (aDistToTarget != bDistToTarget) - return aDistToTarget - bDistToTarget; - int aDistToAttacker = attackerLocation.distanceSquaredTo(a.location); - int bDistToAttacker = attackerLocation.distanceSquaredTo(b.location); - if (aDistToAttacker != bDistToAttacker) - return aDistToAttacker - bDistToAttacker; - return a.compareTo(b); + // create new bots + for (int i = 0; i < toCreate.size(); i++) { + RobotInfo info = toCreate.get(i); + int id = this.gameWorld.spawnRobot(toCreateParents.get(i), info.getType(), info.getLocation(), this.team, info.getInfluence()); + InternalRobot newBot = this.gameWorld.getObjectInfo().getRobotByID(id); + if (newBot.type != RobotType.ENLIGHTENMENT_CENTER) { + // Shouldn't be called on an enlightenment center, because if spawned center's influence exceeds limit this would send a redundant change conviction action. + newBot.addConviction(info.getConviction() - newBot.getConviction()); + } + else { + // Resets influence and conviction to cap for enlightenment centers. Already done by reset bid, but nicer to do it here. + newBot.addInfluenceAndConviction(0); } + this.gameWorld.getMatchMaker().addAction(info.getID(), Action.CHANGE_TEAM, id); } + } - Collections.sort(validTargets, new RicochetPriority()); - for (int i = 0; i < ricochetCount; i++) { - dmg = (int) (dmg * GameConstants.RICOCHET_DAMAGE_MULTIPLIER); - validTargets.get(i).addHealth(-dmg); + /** + * Adds or removes influence, conviction, or both based on the type of the robot + * and the robot's affiliation. + * Called when a Politician Empowers. + * If conviction becomes negative, the robot switches teams or is destroyed. + * + * @param amount the amount this robot's conviction changes by (including all buffs) + * @param newTeam the team of the robot that empowered + */ + private void empowered(InternalRobot caller, int amount, Team newTeam) { + if (this.team != newTeam) + amount = -amount; + + if (type == RobotType.ENLIGHTENMENT_CENTER) + addInfluenceAndConviction(amount); + else + addConviction(amount); + + if (this.conviction < 0) { + if (this.type.canBeConverted()) { + int newInfluence = Math.abs(this.influence); + int newConviction = -this.conviction; + caller.addToCreate(this.parent, this.ID, this.type, newInfluence, newConviction, this.location); + } + this.gameWorld.destroyRobot(getID()); } } + /** + * Empowers given a range. Doesn't self-destruct!! + * + * @param radiusSquared the empower range + */ + public void expose(InternalRobot bot) { + this.gameWorld.addBuffs(this.team, bot.influence); + this.gameWorld.destroyRobot(bot.ID); + } + // ********************************* // ****** GAMEPLAY METHODS ********* // ********************************* @@ -407,7 +461,7 @@ public void processBeginningOfRound() { public void processBeginningOfTurn() { if (this.cooldownTurns > 0) - this.cooldownTurns = Math.max(0, this.cooldownTurns - GameConstants.COOLDOWNS_PER_TURN); + this.cooldownTurns = Math.max(0, this.cooldownTurns - 1); this.currentBytecodeLimit = getType().bytecodeLimit; } @@ -418,7 +472,24 @@ public void processEndOfTurn() { } public void processEndOfRound() { - // anything + // generate passive influence + InternalRobot target = (parent == null) ? this : parent; + if (target.getType() != RobotType.ENLIGHTENMENT_CENTER) { + throw new IllegalStateException("The robot's parent is not an Enlightenment Center"); + } + int passiveInfluence = this.type.getPassiveInfluence(this.influence, this.roundsAlive, this.gameWorld.getCurrentRound()); + if (passiveInfluence > 0 && this.team.isPlayer() && this.gameWorld.getObjectInfo().existsRobot(target.ID)) { + target.addInfluenceAndConviction(passiveInfluence); + if (this.type == RobotType.SLANDERER) { + this.gameWorld.getMatchMaker().addAction(this.ID, Action.EMBEZZLE, target.ID); + } + } + + // Slanderers turn into Politicians + if (this.type == RobotType.SLANDERER && this.roundsAlive == GameConstants.CAMOUFLAGE_NUM_ROUNDS) { + this.type = RobotType.POLITICIAN; + this.gameWorld.getMatchMaker().addAction(this.ID, Action.CAMOUFLAGE, -1); + } } // ********************************* From e243cac2219b862461e53eff3e9a8100e2c38a89 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 13 Nov 2021 12:13:59 -0500 Subject: [PATCH 022/413] Reverting to be based on engine --- .../src/main/battlecode/world/GameWorld.java | 8 ++--- engine/src/main/battlecode/world/LiveMap.java | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 4f91eaf1..b4ff29ae 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -28,7 +28,7 @@ public strictfp class GameWorld { protected final IDGenerator idGenerator; protected final GameStats gameStats; - private int[] cooldownMultiplier; + private double[] passability; private InternalRobot[][] robots; private final LiveMap gameMap; private final TeamInfo teamInfo; @@ -44,7 +44,7 @@ public strictfp class GameWorld { @SuppressWarnings("unchecked") public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) { - this.cooldownMultiplier = gm.getCooldownMultiplierArray(); + this.passability = gm.getPassabilityArray(); this.robots = new InternalRobot[gm.getWidth()][gm.getHeight()]; // if represented in cartesian, should be height-width, but this should allow us to index x-y this.currentRound = 0; this.idGenerator = new IDGenerator(gm.getSeed()); @@ -183,8 +183,8 @@ public int getCurrentRound() { return this.currentRound; } - public int getCooldownMultiplier(MapLocation loc) { - return this.cooldownMultiplier[locationToIndex(loc)]; + public double getPassability(MapLocation loc) { + return this.passability[locationToIndex(loc)]; } /** diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 6087a5d2..c4067066 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -48,7 +48,7 @@ public strictfp class LiveMap { */ private final RobotInfo[] initialBodies; // only contains Enlightenment Centers - private int[] cooldownMultiplierArray; // factor to multiply cooldowns by + private double[] passabilityArray; // factor to multiply cooldowns by public LiveMap(int width, int height, @@ -64,9 +64,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.cooldownMultiplierArray = new int[width * height]; - for (int i = 0; i < cooldownMultiplierArray.length; i++) { - this.cooldownMultiplierArray[i] = 1; // default cooldown factor is 1 + this.passabilityArray = new double[width * height]; + for (int i = 0; i < passabilityArray.length; i++) { + this.passabilityArray[i] = 1; // default cooldown factor is 1 } // invariant: bodies is sorted by id @@ -80,7 +80,7 @@ public LiveMap(int width, int rounds, String mapName, RobotInfo[] initialBodies, - int[] cooldownMultiplierArray) { + double[] passabilityArray) { this.width = width; this.height = height; this.origin = origin; @@ -88,9 +88,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.cooldownMultiplierArray = new int[cooldownMultiplierArray.length]; - for (int i = 0; i < cooldownMultiplierArray.length; i++) { - this.cooldownMultiplierArray[i] = cooldownMultiplierArray[i]; + this.passabilityArray = new double[passabilityArray.length]; + for (int i = 0; i < passabilityArray.length; i++) { + this.passabilityArray[i] = passabilityArray[i]; } // invariant: bodies is sorted by id @@ -104,7 +104,7 @@ public LiveMap(int width, */ public LiveMap(LiveMap gm) { this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.initialBodies, - gm.cooldownMultiplierArray); + gm.passabilityArray); } @Override @@ -127,7 +127,7 @@ public boolean equals(LiveMap other) { if (this.seed != other.seed) return false; if (!this.mapName.equals(other.mapName)) return false; if (!this.origin.equals(other.origin)) return false; - if (!Arrays.equals(this.cooldownMultiplierArray, other.cooldownMultiplierArray)) return false; + if (!Arrays.equals(this.passabilityArray, other.passabilityArray)) return false; return Arrays.equals(this.initialBodies, other.initialBodies); } @@ -139,7 +139,7 @@ public int hashCode() { result = 31 * result + seed; result = 31 * result + rounds; result = 31 * result + mapName.hashCode(); - result = 31 * result + Arrays.hashCode(cooldownMultiplierArray); + result = 31 * result + Arrays.hashCode(passabilityArray); result = 31 * result + Arrays.hashCode(initialBodies); return result; } @@ -246,13 +246,13 @@ public MapLocation getOrigin() { return origin; } - public double[] getCooldownMultiplierArray() { - return cooldownMultiplierArray; + public double[] getPassabilityArray() { + return passabilityArray; } @Override public String toString() { - if (cooldownMultiplierArray.length == 0) + if (passabilityArray.length == 0) return "LiveMap{" + "width=" + width + ", height=" + height + @@ -261,7 +261,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", len=" + Integer.toString(cooldownMultiplierArray.length) + + ", len=" + Integer.toString(passabilityArray.length) + "}"; else return "LiveMap{" + "width=" + width + @@ -271,7 +271,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", cooldownMultiplierArray=:)" + Arrays.toString(cooldownMultiplierArray) + + ", passabilityArray=:)" + Arrays.toString(passabilityArray) + "}"; } } \ No newline at end of file From ddc0fd8d45385c4ce8d3973a6bd85d7b621cc88c Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 13 Nov 2021 12:30:19 -0500 Subject: [PATCH 023/413] Fixed typo and spacing --- engine/src/main/battlecode/world/DominationFactor.java | 2 +- engine/src/main/battlecode/world/TeamInfo.java | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/engine/src/main/battlecode/world/DominationFactor.java b/engine/src/main/battlecode/world/DominationFactor.java index 3c9a76a3..995bd3ab 100644 --- a/engine/src/main/battlecode/world/DominationFactor.java +++ b/engine/src/main/battlecode/world/DominationFactor.java @@ -19,7 +19,7 @@ public enum DominationFactor { /** * Win by more lead net worth (tiebreak 2). */ - MORE_GOLD_NET_WORTH, + MORE_LEAD_NET_WORTH, /** * Win by coinflip (tiebreak 3). */ diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 8f3d92c3..477c6a11 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -15,16 +15,12 @@ public class TeamInfo { public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; } - + // ********************************* // ***** GETTER METHODS ************ // ********************************* - - // ********************************* // ***** UPDATE METHODS ************ // ********************************* - - } From 4fd89a320de3ffb90b729fa86bf4ccefaf41a3be Mon Sep 17 00:00:00 2001 From: Pranali Date: Thu, 18 Nov 2021 18:24:15 -0500 Subject: [PATCH 024/413] Added healing and repairing function specs --- .../battlecode/common/RobotController.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 3fdba4d6..94ea7b06 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -399,6 +399,33 @@ public strictfp interface RobotController { * @battlecode.doc.costlymethod */ void attack(MapLocation loc) throws GameActionException; + + // ***************************** + // ****** ARCHON METHODS ****** + // ***************************** + + /** + * Tests whether this robot can heal a robot (not building) at the given location. + * + * Checks that the robot is an archon unit and that the given location + * is within the robot's action radius. Also checks that a + * friendly robot unit (not a building) exists in the given square. + * + * @param loc target location to heal at + * @return whether it is possible to heal a robot at the given location. + * + * @battlecode.doc.costlymethod + */ + boolean canHealRobot(MapLocation loc); + + /** + * Heals at a given location. + * + * @throws GameActionException if conditions for healing are not satisfied + * @battlecode.doc.costlymethod + */ + void healRobot(MapLocation loc) throws GameActionException; + // *********************** // **** MINER METHODS **** @@ -476,6 +503,28 @@ public strictfp interface RobotController { */ void upgrade(MapLocation loc) throws GameActionException; + /** + * Tests whether this robot can repair a building at the given location. + * + * Checks that the robot is a builder unit and that the given location + * is within the robot's action radius. Also checks that a + * friendly unit which is a building exists in the given square. + * + * @param loc target location to repair building at + * @return whether it is possible to repair a building at the given location. + * + * @battlecode.doc.costlymethod + */ + boolean canRepairBuilding(MapLocation loc); + + /** + * Repairs building at a given location. + * + * @throws GameActionException if conditions for repairing building are not satisfied + * @battlecode.doc.costlymethod + */ + void repairBuilding(MapLocation loc) throws GameActionException; + // ******************************* // **** ALCHEMIST LAB METHODS **** // ******************************* From 7c70949acdc10526467d6a9e6d3d59a22f894e45 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 20 Nov 2021 01:34:50 -0500 Subject: [PATCH 025/413] Implemented RobotController methods up until build/spawn --- .../battlecode/common/RobotController.java | 13 +- .../battlecode/world/RobotControllerImpl.java | 167 +++++++----------- 2 files changed, 75 insertions(+), 105 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 3fdba4d6..be799b8e 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -143,6 +143,17 @@ public strictfp interface RobotController { */ boolean canSeeRadiusSquared(int radiusSquared); + /** + * Checks whether a robot is at a given location. Assumes the location is valid. + * + * @param loc the location to check + * @return true if a robot is at the location. + * @throws GameActionException if the location is not within vision range or on the map. + * + * @battlecode.doc.costlymethod + */ + boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException; + /** * Sees the robot at the given location, or null if there is no robot * there. @@ -153,7 +164,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo canSeeRobotAtLocation(MapLocation loc) throws GameActionException; + RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException; /** * Tests whether the given robot exists and if it is within this robot's diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9528dd7c..faedd4dc 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -77,19 +77,15 @@ public int getRoundNum() { return gameWorld.getCurrentRound(); } - @Override - public int getTeamVotes() { - return gameWorld.getTeamInfo().getVotes(getTeam()); - } - @Override public int getRobotCount() { return gameWorld.getObjectInfo().getRobotCount(getTeam()); } @Override - public double getEmpowerFactor(Team team, int roundsInFuture) { - return gameWorld.getTeamInfo().getBuff(team, getRoundNum() + roundsInFuture); + public double getArchonCount() { + // TODO: Assumes getArchons() exists in TeamInfo + return gameWorld.getTeamInfo().getArchons(); } // ********************************* @@ -115,90 +111,69 @@ public RobotType getType() { public MapLocation getLocation() { return this.robot.getLocation(); } + + @Override + public int getHealth() { + return this.robot.getHeatlh(); + } + + @Override + public int getUpgradeLevel() { + return this.robot.getUpgradeLevel(); + } private InternalRobot getRobotByID(int id) { if (!gameWorld.getObjectInfo().existsRobot(id)) return null; return this.gameWorld.getObjectInfo().getRobotByID(id); } - - public int getInfluence() { - return this.robot.getInfluence(); - } - - public int getConviction() { - return this.robot.getConviction(); - } // *********************************** - // ****** GENERAL SENSOR METHODS ***** + // ****** GENERAL VISION METHODS ***** // *********************************** @Override public boolean onTheMap(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSenseLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within sensor range"); + if (!this.robot.canSeeLocation(loc)) + throw new GameActionException(CANT_SEE_THAT, + "Target location not within vision range"); return gameWorld.getGameMap().onTheMap(loc); } - private void assertCanSenseLocation(MapLocation loc) throws GameActionException { + private void assertCanSeeLocation(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSenseLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within sensor range"); + if (!this.robot.canSeeLocation(loc)) + throw new GameActionException(CANT_SEE_THAT, + "Target location not within vision range"); if (!gameWorld.getGameMap().onTheMap(loc)) - throw new GameActionException(CANT_SENSE_THAT, + throw new GameActionException(CANT_SEE_THAT, "Target location is not on the map"); } @Override - public boolean canSenseLocation(MapLocation loc) { + public boolean canSeeLocation(MapLocation loc) { try { - assertCanSenseLocation(loc); + assertCanSeeLocation(loc); return true; } catch (GameActionException e) { return false; } } @Override - public boolean canSenseRadiusSquared(int radiusSquared) { - return this.robot.canSenseRadiusSquared(radiusSquared); - } - - private void assertCanDetectLocation(MapLocation loc) throws GameActionException { - assertNotNull(loc); - if (!this.robot.canDetectLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within detection range"); - if (!gameWorld.getGameMap().onTheMap(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location is not on the map"); + public boolean canSeeRadiusSquared(int radiusSquared) { + return this.robot.canSeeRadiusSquared(radiusSquared); } @Override - public boolean canDetectLocation(MapLocation loc) { - try { - assertCanDetectLocation(loc); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public boolean canDetectRadiusSquared(int radiusSquared) { - return this.robot.canDetectRadiusSquared(radiusSquared); - } - - @Override - public boolean isLocationOccupied(MapLocation loc) throws GameActionException { - assertCanDetectLocation(loc); + public boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); return this.gameWorld.getRobot(loc) != null; } @Override - public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException { - assertCanSenseLocation(loc); + public RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); InternalRobot bot = gameWorld.getRobot(loc); if (bot != null) return bot.getRobotInfo(getType().canTrueSense()); @@ -206,87 +181,71 @@ public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionExceptio } @Override - public boolean canSenseRobot(int id) { - InternalRobot sensedRobot = getRobotByID(id); - return sensedRobot == null ? false : canSenseLocation(sensedRobot.getLocation()); + public boolean canSeeRobot(int id) { + InternalRobot seenRobot = getRobotByID(id); + return seenRobot == null ? false : canSeeLocation(seenRobot.getLocation()); } @Override - public RobotInfo senseRobot(int id) throws GameActionException { - if (!canSenseRobot(id)) + public RobotInfo seeRobot(int id) throws GameActionException { + if (!canSeeRobot(id)) throw new GameActionException(CANT_SENSE_THAT, - "Can't sense given robot; It may not exist anymore"); + "Can't see given robot; It may not exist anymore"); return getRobotByID(id).getRobotInfo(getType().canTrueSense()); } @Override - public RobotInfo[] senseNearbyRobots() { - return senseNearbyRobots(-1); + public RobotInfo[] seeNearbyRobots() { + return seeNearbyRobots(-1); } @Override - public RobotInfo[] senseNearbyRobots(int radiusSquared) { - return senseNearbyRobots(radiusSquared, null); + public RobotInfo[] seeNearbyRobots(int radiusSquared) { + return seeNearbyRobots(radiusSquared, null); } @Override - public RobotInfo[] senseNearbyRobots(int radiusSquared, Team team) { - return senseNearbyRobots(getLocation(), radiusSquared, team); + public RobotInfo[] seeNearbyRobots(int radiusSquared, Team team) { + return seeNearbyRobots(getLocation(), radiusSquared, team); } @Override - public RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team) { + public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team) { assertNotNull(center); int actualRadiusSquared = radiusSquared == -1 ? getType().sensorRadiusSquared : Math.min(radiusSquared, getType().sensorRadiusSquared); - InternalRobot[] allSensedRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); - List validSensedRobots = new ArrayList<>(); - for (InternalRobot sensedRobot : allSensedRobots) { + InternalRobot[] allSeenRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); + List validSeenRobots = new ArrayList<>(); + for (InternalRobot seenRobot : allSeenRobots) { // check if this robot - if (sensedRobot.equals(this.robot)) + if (seenRobot.equals(this.robot)) continue; - // check if can sense - if (!canSenseLocation(sensedRobot.getLocation())) + // check if can see + if (!canSeeLocation(seenRobot.getLocation())) continue; // check if right team - if (team != null && sensedRobot.getTeam() != team) + if (team != null && seenRobot.getTeam() != team) continue; - validSensedRobots.add(sensedRobot.getRobotInfo(getType().canTrueSense())); + validSeenRobots.add(seenRobot.getRobotInfo(getType().canTrueSense())); } - return validSensedRobots.toArray(new RobotInfo[validSensedRobots.size()]); - } - - @Override - public MapLocation[] detectNearbyRobots() { - return detectNearbyRobots(-1); + return validSeenRobots.toArray(new RobotInfo[validSeenRobots.size()]); } - @Override - public MapLocation[] detectNearbyRobots(int radiusSquared) { - return detectNearbyRobots(getLocation(), radiusSquared); + @Override + public double seePassability(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getPassability(loc); } - @Override - public MapLocation[] detectNearbyRobots(MapLocation center, int radiusSquared) { - assertNotNull(center); - int actualRadiusSquared = radiusSquared == -1 ? getType().detectionRadiusSquared : Math.min(radiusSquared, getType().detectionRadiusSquared); - InternalRobot[] allDetectedRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); - List validDetectedRobots = new ArrayList<>(); - for (InternalRobot detectedRobot : allDetectedRobots) { - // check if this robot - if (detectedRobot.equals(this.robot)) - continue; - // check if can detect - if (!canDetectLocation(detectedRobot.getLocation())) - continue; - validDetectedRobots.add(detectedRobot.getLocation()); - } - return validDetectedRobots.toArray(new MapLocation[validDetectedRobots.size()]); + @Override + public double seeLead(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getLead(loc); } @Override - public double sensePassability(MapLocation loc) throws GameActionException { - assertCanSenseLocation(loc); - return this.gameWorld.getPassability(loc); + public double seeGold(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getGold(loc); } @Override From 2343e96ae2c2697721bc1aac355e2a250ecaedde Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 20 Nov 2021 02:03:35 -0500 Subject: [PATCH 026/413] Added build/spawn methods in RobotControllerImpl --- .../battlecode/common/RobotController.java | 3 ++ .../battlecode/world/RobotControllerImpl.java | 36 +++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 0d7a6257..e4547d15 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -356,6 +356,9 @@ public strictfp interface RobotController { // ****** BUILDING/SPAWNING ********** // *********************************** + + // TODO: is upgrade level a part of type or an extra parameter? + /** * Tests whether the robot can build a robot of the given type in the * given direction. Checks that the robot is of a type that can build, diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index faedd4dc..98808069 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -335,18 +335,26 @@ public void move(Direction dir) throws GameActionException { // ****** BUILDING/SPAWNING ********** // *********************************** - private void assertCanBuildRobot(RobotType type, Direction dir, int influence) throws GameActionException { + private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActionException { assertNotNull(type); assertNotNull(dir); if (!getType().canBuild(type)) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot build robots of type" + type + "."); - if (influence <= 0) + + // CHECK FUNCTION NAMES FOR GETTING LEAD/GOLD COSTS AND SUPPLIES + int leadNeeded = type.getLeadCost(); + int goldNeeded = type.getGoldCost(); + Team team = getTeam(); + if (gameWorld.getTeamInfo().getLead(team) < leadNeeded) { throw new GameActionException(CANT_DO_THAT, - "Cannot spend nonpositive amount of influence."); - if (influence > getInfluence()) + "Insufficient amount of lead."); + } + if (gameWorld.getTeamInfo().getGold(team) < goldNeeded) { throw new GameActionException(CANT_DO_THAT, - "Cannot spend more influence than you have."); + "Insufficient amount of gold."); + } + MapLocation spawnLoc = adjacentLocation(dir); if (!onTheMap(spawnLoc)) throw new GameActionException(OUT_OF_RANGE, @@ -360,21 +368,27 @@ private void assertCanBuildRobot(RobotType type, Direction dir, int influence) t } @Override - public boolean canBuildRobot(RobotType type, Direction dir, int influence) { + public boolean canBuildRobot(RobotType type, Direction dir) { try { - assertCanBuildRobot(type, dir, influence); + assertCanBuildRobot(type, dir); return true; } catch (GameActionException e) { return false; } } + // TODO: CHECK FUNCTION NAMES @Override - public void buildRobot(RobotType type, Direction dir, int influence) throws GameActionException { - assertCanBuildRobot(type, dir, influence); + public void buildRobot(RobotType type, Direction dir) throws GameActionException { + assertCanBuildRobot(type, dir); + + int leadNeeded = type.getLeadCost(); + int goldNeeded = type.getGoldCost(); this.robot.addCooldownTurns(); - this.robot.addInfluenceAndConviction(-influence); - int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam(), influence); + this.robot.addLead(-leadNeeded); + this.robot.addGold(-goldNeeded); + + int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam()); // set cooldown turns here, because not all new robots have cooldown (eg. switching teams) InternalRobot newBot = getRobotByID(robotID); From a5202cc0efca58f7ff2b8bd65e2f240e3d89ad0c Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 11:19:25 -0500 Subject: [PATCH 027/413] Added actions specific to certain types of building, renamed small things --- .../battlecode/common/RobotController.java | 14 +- .../battlecode/world/RobotControllerImpl.java | 264 +++++++++++++++++- 2 files changed, 270 insertions(+), 8 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 94ea7b06..d198bcff 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -405,18 +405,18 @@ public strictfp interface RobotController { // ***************************** /** - * Tests whether this robot can heal a robot (not building) at the given location. + * Tests whether this robot can heal a droid at the given location. * * Checks that the robot is an archon unit and that the given location * is within the robot's action radius. Also checks that a - * friendly robot unit (not a building) exists in the given square. + * friendly droid robot exists in the given square. * * @param loc target location to heal at - * @return whether it is possible to heal a robot at the given location. + * @return whether it is possible to heal a droid robot at the given location. * * @battlecode.doc.costlymethod */ - boolean canHealRobot(MapLocation loc); + boolean canHealDroid(MapLocation loc); /** * Heals at a given location. @@ -424,7 +424,7 @@ public strictfp interface RobotController { * @throws GameActionException if conditions for healing are not satisfied * @battlecode.doc.costlymethod */ - void healRobot(MapLocation loc) throws GameActionException; + void healDroid(MapLocation loc) throws GameActionException; // *********************** @@ -437,7 +437,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * contain at least one lead. + * have positive lead amounts. * * @param loc target location to mine * @return whether it is possible to mine at the given location. @@ -460,7 +460,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * contain at least one gold. + * have positive gold amounts. * * @param loc target location to mine * @return whether it is possible to mine at the given location. diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9528dd7c..b453e33e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -576,10 +576,271 @@ public void bid(int influence) throws GameActionException { gameWorld.getMatchMaker().addAction(getID(), Action.PLACE_BID, influence); } + // ***************************** + // **** COMBAT UNIT METHODS **** + // ***************************** + + private void assertCanAttack(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canAttack()) + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot attack."); + if (!this.robot.canActLocation(loc)) + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be attacked because it is out of range."); + InternalRobot bot = getRobot(loc); + if (bot.getTeam() == getTeam()) + throw new GameActionException(CANT_DO_THAT, + "Robot is not on the enemy team."); + } + + @Override + boolean canAttack(MapLocation loc){ + try { + assertCanAttack(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void attack(MapLocation loc) throws GameActionException{ + assertCanAttack(loc); + this.robot.attack(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int attackedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); + } + + // ***************************** + // ****** ARCHON METHODS ****** + // ***************************** + + private void assertCanHealDroid(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canHealDroid()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot heal droids."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "This robot can't be healed belocation can't be min because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeHealed())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be healed."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be healed."); + } + } + + @Override + boolean canHealDroid(MapLocation loc){ + try { + assertCanHealDroid(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void healDroid(MapLocation loc) throws GameActionException{ + assertCanHealDroid(loc); + this.robot.healDroid(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int healedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); + } + + + // *********************** + // **** MINER METHODS **** + // *********************** + + private void assertCanMineLead(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canMine()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot mine."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be healed because it is out of range."); + } + int leadAmount = gameWorld.getLeadCount(loc); + if (leadAmount < 0){ + throw new GameActionException(CANT_DO_THAT, + "Lead amount must be positive to be mined."); + } + } + + @Override + boolean canMineLead(MapLocation loc){ + try { + assertCanMineLead(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void mineLead(MapLocation loc) throws GameActionException{ + assertCanMineLead(loc); + this.robot.mineLead(loc); + gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); + } + + private void assertCanMineGold(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canMine()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot mine."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "This location can't be mined because it is out of range."); + } + int goldAmount = gameWorld.getGoldCount(loc); + if (goldAmount < 0){ + throw new GameActionException(CANT_DO_THAT, + "Gold amount must be positive to be mined."); + } + } + + @Override + boolean canMineGold(MapLocation loc){ + try { + assertCanMineGold(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void mineGold(MapLocation loc) throws GameActionException{ + assertCanMineGold(loc); + this.robot.mineGold(loc); + gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); + } + + // ************************* + // **** BUILDER METHODS **** + // ************************* + + private void assertCanUpgrade(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canUpgrade()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot upgrade buildings."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be upgraded because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeUpgraded())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be upgraded."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be upgraded."); + } + if (getLead() < bot.getLeadUpgradeCost()){ + throw new GameActionException(CANT_DO_THAT, + "You don't have enough lead to upgrade this robot."); + } + if (getGold() < bot.getGoldUpgradeCost()){ + throw new GameActionException(CANT_DO_THAT, + "You don't have enough gold to upgrade this robot."); + } + } + + @Override + boolean canUpgrade(MapLocation loc){ + try { + assertCanUpgrade(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void upgrade(MapLocation loc) throws GameActionException{ + assertCanUpgrade(loc); + this.robot.upgrade(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int upgradedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); + } + + private void assertCanRepairBuilding(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canRepairBuilding()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot repair buildings."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be repaired because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeUpgraded())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be repair."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be repaired."); + } + } + + @Override + boolean canRepairBuilding(MapLocation loc){ + try { + assertCanRepairBuilding(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void repairBuilding(MapLocation loc) throws GameActionException{ + assertCanRepairBuilding(loc); + this.robot.repairBuilding(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int repairedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRD, repairedID); + } + + // ******************************* + // **** ALCHEMIST LAB METHODS **** + // ******************************* + + private void assertCanConvert() throws GameActionException { + assertIsActionReady(); + if (!getType().canConvert()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot convert lead to gold."); + } else if (LEAD_TO_GOLD_RATE > getLead()) { + throw new GameActionException(CANT_DO_THAT, + "You don't have enough lead to be able to convert to gold."); + } + } + + @Override + boolean canConvert(){ + try { + assertCanConvert(); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void convert() throws GameActionException{ + assertCanConvert(); + this.robot.convert(); + gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT); + } + // *********************************** // ****** COMMUNICATION METHODS ****** // *********************************** + //TODO: Communication needs to be fixed + private void assertCanSetFlag(int flag) throws GameActionException { if (flag < GameConstants.MIN_FLAG_VALUE || flag > GameConstants.MAX_FLAG_VALUE) { throw new GameActionException(CANT_DO_THAT, "Flag value out of range"); @@ -628,10 +889,11 @@ public int getFlag(int id) throws GameActionException { return getRobotByID(id).getFlag(); } + //TODO: move this back to public? + // *********************************** // ****** OTHER ACTION METHODS ******* // *********************************** - /** * This used to be public, but is not public in 2021 because * slanderers should not be able to self-destruct. From 51c57a90cf527e625d291a51708d477383b38731 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 11:50:56 -0500 Subject: [PATCH 028/413] Removed old unit methods --- .../battlecode/world/RobotControllerImpl.java | 152 ------------------ 1 file changed, 152 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index c791aafe..c3969894 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -396,158 +396,6 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); } - - // *********************************** - // ****** POLITICIAN METHODS ********* - // *********************************** - - private void assertCanEmpower(int radiusSquared) throws GameActionException { - assertIsReady(); - if (!getType().canEmpower()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot empower."); - if (radiusSquared > getType().actionRadiusSquared) - throw new GameActionException(CANT_DO_THAT, - "Robot's empower radius is smaller than radius specified"); - } - - @Override - public boolean canEmpower(int radiusSquared) { - try { - assertCanEmpower(radiusSquared); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void empower(int radiusSquared) throws GameActionException { - assertCanEmpower(radiusSquared); - - this.robot.addCooldownTurns(); // not needed but here for the sake of consistency - this.robot.empower(radiusSquared); - gameWorld.getMatchMaker().addAction(getID(), Action.EMPOWER, radiusSquared); - - // self-destruct - gameWorld.destroyRobot(this.robot.getID()); - } - - - // *********************************** - // ****** MUCKRAKER METHODS ********** - // *********************************** - - private void assertCanExpose(MapLocation loc) throws GameActionException { - assertIsReady(); - if (!getType().canExpose()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot expose."); - if (!onTheMap(loc)) - throw new GameActionException(OUT_OF_RANGE, - "Location is not on the map."); - if (!this.robot.canActLocation(loc)) - throw new GameActionException(CANT_DO_THAT, - "Location can't be exposed because it is out of range."); - InternalRobot bot = gameWorld.getRobot(loc); - if (bot == null) - throw new GameActionException(CANT_DO_THAT, - "There is no robot at specified location."); - if (!(bot.getType().canBeExposed())) - throw new GameActionException(CANT_DO_THAT, - "Robot at target location is not of a type that can be exposed."); - if (bot.getTeam() == getTeam()) - throw new GameActionException(CANT_DO_THAT, - "Robot at target location is not on the enemy team."); - } - - private void assertCanExpose(int id) throws GameActionException { - assertIsReady(); - if (!getType().canExpose()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot expose."); - if (!canSenseRobot(id)) - throw new GameActionException(OUT_OF_RANGE, - "The targeted robot cannot be sensed."); - InternalRobot bot = getRobotByID(id); - if (!this.robot.canActLocation(bot.getLocation())) - throw new GameActionException(OUT_OF_RANGE, - "Robot can't be exposed because it is out of range."); - if (!(bot.getType().canBeExposed())) - throw new GameActionException(CANT_DO_THAT, - "Robot is not of a type that can be exposed."); - if (bot.getTeam() == getTeam()) - throw new GameActionException(CANT_DO_THAT, - "Robot is not on the enemy team."); - } - - @Override - public boolean canExpose(MapLocation loc) { - try { - assertCanExpose(loc); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public boolean canExpose(int id) { - try { - assertCanExpose(id); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void expose(MapLocation loc) throws GameActionException { - assertCanExpose(loc); - - this.robot.addCooldownTurns(); - InternalRobot bot = gameWorld.getRobot(loc); - int exposedID = bot.getID(); - this.robot.expose(bot); - gameWorld.getMatchMaker().addAction(getID(), Action.EXPOSE, exposedID); - } - - @Override - public void expose(int id) throws GameActionException { - assertCanExpose(id); - - this.robot.addCooldownTurns(); - InternalRobot bot = getRobotByID(id); - this.robot.expose(bot); - gameWorld.getMatchMaker().addAction(getID(), Action.EXPOSE, id); - } - - // *********************************** - // *** ENLIGHTENMENT CENTER METHODS ** - // *********************************** - - private void assertCanBid(int influence) throws GameActionException { - if (!getType().canBid()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot bid."); - } else if (influence <= 0) { - throw new GameActionException(CANT_DO_THAT, - "Can only bid non-negative amounts of influence."); - } else if (influence > getInfluence()) { - throw new GameActionException(CANT_DO_THAT, - "Not possible to bid influence you don't have."); - } - } - - @Override - public boolean canBid(int influence) { - try { - assertCanBid(influence); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void bid(int influence) throws GameActionException { - assertCanBid(influence); - - this.robot.setBid(influence); - gameWorld.getMatchMaker().addAction(getID(), Action.PLACE_BID, influence); - } // ***************************** // **** COMBAT UNIT METHODS **** From 9668186d5bbbbeaa707413930d849e727e00fd10 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 11:55:47 -0500 Subject: [PATCH 029/413] Tweak schema --- schema/battlecode.fbs | 1 - 1 file changed, 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 76f65df9..af3fd031 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -92,7 +92,6 @@ enum Action : byte { MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. - ATTACKED, // when a body is attacked TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, REPAIR, // builder repairs building From be189a546d56e8b7e8410991c8893a015fab8bb1 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 12:46:40 -0500 Subject: [PATCH 030/413] New units and actions in schema --- schema/battlecode.fbs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index af3fd031..74f4879f 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -33,11 +33,8 @@ enum BodyType : byte { // Combat units GUARD, - GUARD_TURRET, - ARCHER, - ARCHER_TURRET, WIZARD, - WIZARD_TURRET + TURRET } /// A list of new bodies to be placed on the map. @@ -96,7 +93,10 @@ enum Action : byte { UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, - FULLY_REPAIRED // prototype becomes a turret + FULLY_REPAIRED, // prototype becomes a turret + LOCAL_ABYSS, + LOCAL_FURY, + LOCAL_VORTEX } // Metadata From 992e587901eb7ffd9642eb85ac16267c41f62583 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 12:48:02 -0500 Subject: [PATCH 031/413] No local vortex --- schema/battlecode.fbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 74f4879f..702193f8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -96,7 +96,7 @@ enum Action : byte { FULLY_REPAIRED, // prototype becomes a turret LOCAL_ABYSS, LOCAL_FURY, - LOCAL_VORTEX + LOCAL_CHARGE } // Metadata From 497749e7949ff6849f76bcd871a5ff249f165973 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 12:48:34 -0500 Subject: [PATCH 032/413] In-progress gameworld updates --- client/playback/src/gameworld.ts | 76 ++++++++++++++++---------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 05ea2f0c..2f41f262 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -22,7 +22,7 @@ export type BodiesSchema = { y: Int32Array, flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? - ability: Int8Array, + action: Int8Array, parent: Int32Array, hp: Int32Array, level: Int8Array @@ -38,6 +38,7 @@ export type MapStats = { passability: Float64Array, // double lead: Int32Array; + gold: Int32Array; getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; @@ -46,14 +47,13 @@ export type MapStats = { export type TeamStats = { // An array of numbers corresponding to team stats, which map to RobotTypes // Corresponds to robot type (including NONE. length 5) - robots: [number, number, number, number, number], - votes: number, - influence: [number, number, number, number, number], - conviction: [number, number, number, number, number], - numBuffs: number, - bidderID: number, - bid: number, - income: number + // First four are droids (guard, wizard, builder, miner), last three are buildings (turret, archon, lab) + robots: [number, number, number, number, number[], number[], number[]], + lead: number, + gold: number, + total_hp: [number, number, number, number, number[], number[], number[]], + lead_income: number, + gold_income: number }; export type IndicatorDotsSchema = { @@ -84,6 +84,8 @@ export type Log = { text: string }; + + /** * A frozen image of the game world. * @@ -100,11 +102,6 @@ export default class GameWorld { */ bodies: StructOfArrays; - /** - * Bodies that empowered this round. - */ - empowered: StructOfArrays; - /* * Stats for each team */ @@ -186,14 +183,6 @@ export default class GameWorld { constructor(meta: Metadata, config: playbackConfig) { this.meta = meta; - this.empowered = new StructOfArrays({ - id: new Int32Array(0), - x: new Int32Array(0), - y: new Int32Array(0), - team: new Int8Array(0), - radius: new Int32Array(0) - }, 'id'); - this.diedBodies = new StructOfArrays({ id: new Int32Array(0), x: new Int32Array(0), @@ -206,27 +195,24 @@ export default class GameWorld { type: new Int8Array(0), x: new Int32Array(0), y: new Int32Array(0), - influence: new Int32Array(0), - conviction: new Int32Array(0), flag: new Int32Array(0), bytecodesUsed: new Int32Array(0), - ability: new Int8Array(0), - bid: new Int32Array(0), + action: new Int8Array(0), parent: new Int32Array(0), - income: new Int32Array(0) + hp: new Int32Array(0), + level: new Int8Array(0) }, 'id'); - // Instantiate teamStats this.teamStats = new Map(); for (let team in this.meta.teams) { var teamID = this.meta.teams[team].teamID; this.teamStats.set(teamID, { robots: [ - 0, // ENLIGHTENMENT_CENTER - 0, // POLITICIAN - 0, // SLANDERER - 0, // MUCKRAKER + 0, + 0, + 0, + 0, 0, // NONE ], votes: 0, @@ -359,7 +345,7 @@ export default class GameWorld { /** * Process a set of changes. */ - processDelta(delta: schema.Round) { + processDelta(delta: schema.Round) { // Change to reflect current game if (delta.roundID() != this.turn + 1) { throw new Error(`Bad Round: this.turn = ${this.turn}, round.roundID() = ${delta.roundID()}`); } @@ -418,18 +404,31 @@ export default class GameWorld { /// Politicians self-destruct and affect nearby bodies /// Target: none - case schema.Action.EMPOWER: + + + case schema.Action.ATTACK: //this.bodies.alter({ id: robotID, ability: 1}); - this.empowered.insert({'id': robotID, 'x': body.x, 'y': body.y, 'team': body.team, 'radius': target}); + this.bodies.alter({id: robotID, action: schema.Action.ATTACK as number}); this.abilityRobots.push(robotID); break; /// Slanderers passively generate influence for the /// Enlightenment Center that created them. /// Target: parent ID - case schema.Action.EMBEZZLE: - this.bodies.alter({ id: robotID, ability: 3}); + case schema.Action.LOCAL_ABYSS: + this.bodies.alter({id: robotID, action: schema.Action.LOCAL_ABYSS as number}); + this.abilityRobots.push(robotID); + break; + + case schema.Action.LOCAL_CHARGE: + this.bodies.alter({id: robotID, action: schema.Action.LOCAL_CHARGE as number}); this.abilityRobots.push(robotID); break; + + case schema.Action.LOCAL_FURY: + this.bodies.alter({id: robotID, action: schema.Action.LOCAL_FURY as number}); + this.abilityRobots.push(robotID); + break; + /// Slanderers turn into Politicians. /// Target: none case schema.Action.CAMOUFLAGE: @@ -476,6 +475,9 @@ export default class GameWorld { break; /// A robot can change team after being empowered /// Target: teamID + case schema.Action.CHANGE_TEAM: + // TODO remove the robot, don't alter it + break; /// A robot's influence changes. /// Target: delta value case schema.Action.CHANGE_INFLUENCE: From 59d1d2a3f6dd7e536195a4818ea79be64c6bde1e Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 20 Nov 2021 12:49:38 -0500 Subject: [PATCH 033/413] Updated gameworld file --- .../src/main/battlecode/world/GameWorld.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index b4ff29ae..ade8f473 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -29,6 +29,8 @@ public strictfp class GameWorld { protected final GameStats gameStats; private double[] passability; + private int[] leadCount; + private int[] goldCount; private InternalRobot[][] robots; private final LiveMap gameMap; private final TeamInfo teamInfo; @@ -40,11 +42,11 @@ public strictfp class GameWorld { private Random rand; private final GameMaker.MatchMaker matchMaker; - private int[] buffsToAdd; - @SuppressWarnings("unchecked") public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) { this.passability = gm.getPassabilityArray(); + this.leadCount = gm.getLeadArray(); + this.goldCount = gm.getGoldArray(); this.robots = new InternalRobot[gm.getWidth()][gm.getHeight()]; // if represented in cartesian, should be height-width, but this should allow us to index x-y this.currentRound = 0; this.idGenerator = new IDGenerator(gm.getSeed()); @@ -187,6 +189,14 @@ public double getPassability(MapLocation loc) { return this.passability[locationToIndex(loc)]; } + public int getLeadCount(MapLocation loc) { + return this.leadCount[locationToIndex(loc)]; + } + + public int getGoldCount(MapLocation loc) { + return this.goldCount[locationToIndex(loc)]; + } + /** * Helper method that converts a location into an index. * @@ -256,10 +266,6 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int // ****** GAMEPLAY ***************** // ********************************* - public void addBuffs(Team t, int numBuffs) { - this.buffsToAdd[t.ordinal()] += numBuffs; - } - public void processBeginningOfRound() { // Increment round counter currentRound++; From d28a42fd98db9f7293bb9d3e414af132d17d0d5f Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 10:00:51 -0500 Subject: [PATCH 034/413] Add new (red) sprites! --- .../src/static/img/robots/red_archon.png | Bin 0 -> 2125 bytes .../static/img/robots/red_archon_portable.png | Bin 0 -> 2225 bytes .../static/img/robots/red_archon_prototype.png | Bin 0 -> 1736 bytes .../src/static/img/robots/red_builder.png | Bin 0 -> 2035 bytes .../visualizer/src/static/img/robots/red_lab.png | Bin 0 -> 1801 bytes .../src/static/img/robots/red_miner.png | Bin 0 -> 2226 bytes .../src/static/img/robots/red_sage.png | Bin 0 -> 2111 bytes .../src/static/img/robots/red_soldier.png | Bin 0 -> 2484 bytes .../src/static/img/robots/red_watchtower.png | Bin 0 -> 1732 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 client/visualizer/src/static/img/robots/red_archon.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_prototype.png create mode 100644 client/visualizer/src/static/img/robots/red_builder.png create mode 100644 client/visualizer/src/static/img/robots/red_lab.png create mode 100644 client/visualizer/src/static/img/robots/red_miner.png create mode 100644 client/visualizer/src/static/img/robots/red_sage.png create mode 100644 client/visualizer/src/static/img/robots/red_soldier.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower.png diff --git a/client/visualizer/src/static/img/robots/red_archon.png b/client/visualizer/src/static/img/robots/red_archon.png new file mode 100644 index 0000000000000000000000000000000000000000..43e4085e36d8453316b2dc34abbc05bf555f7b6d GIT binary patch literal 2125 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_builder.png b/client/visualizer/src/static/img/robots/red_builder.png new file mode 100644 index 0000000000000000000000000000000000000000..8d923079028e814ad91b66a2d0f90353f2e90a8a GIT binary patch literal 2035 zcmZ`)3pkW%8~)~G4JoG%hWHG%Xbuc*i@}UoO_&g_aahJ-WSTK&jE=~*4u4jP%AcAg z)J8d5|KI)&W0zX7<7BpG4@D|N57K3IVQ zT5uph3;+ZZ<$y_xoZ>~Ivgs@0{IEx^S5hzsvS!xHt7?vaql*Vv* zVmqk=c9mfVVP%?#1y?B&jsuqA=>_iRi&)@Zf(^kE>!=2TAXyX{W#{Aa#hM&iIbfqD z5`i6&7#|-`h_@#2MMsEMwzjrJOA?Vp!b1$aIDsb#lj3<|lXoWXeOy@L2oYN#Ve@&Q z(l;!eA1iUdVwHu~pLge!u%k9A@x*Jd1-&3qxkI!fSQ6L0At_mzwPX0O#C&e7(%;eA z(vrN&{abdU(mRD$G+)Ap`XFLQ(0CG-NFaiGvZ^PossBIYW3P?kemu6s@x8%E>5o+b z8~Y!e`NQm*f=pDl?1L7*yPwr8bU}`4Wa9c|JF0CCp+a98@+HlM>Kl!E8NlK9eWtt1 zd{5j|OLpZac?FHVTYtT@Bwu<|fT-mw5aZ$QYzrq-;b`0W{dAka<)^MU+$8(o$Gxn z=k}U$N{SbGpW__o7a!L(%FN%6SGU#7<4h-?993}Yt`FEmhET3Tt zq%Jm5eywH%Vl(INnPC+7yMH)$i6(x$yqDskPZ3x-WnK#K4xVC2<%(y>VJrJxKp3Yw zC68{MxFb1tpr>1V(;bKJJi&wuz6Scn<%8^#sPW6Cr7>nj9fi@UqZsZ#Dc5?AXbH8? zPQ)8)Gos4IF}G40?a*>j*A>n)foq>dmgs3-Lj zF`V{KYx5jAM$)oonlGs}^p&f2>W}LlN7fuiHw_|M@QtNC0kpAKk;Rx&itp%Ukw2;} z=|`%mp-s-IG;G5kBbbcqz=&LmJK=WQ(kN8Ew?S6=_0Z&(`P@#nmQlOYLmc@1f>C*U zCvc%zaqt!f5S~D~a}m^#BUP%w(N<`9!yssYVjf4~b#xUSx;I4*$*Gh%S&eOQN7-_~ zCl<;3uWbjc)b|g5Wed-}f}6{kNH~aoI%%9-#60(wp^H6JBgsu`B@d>i{VSNj=^3?I z$~}Lv>U2d?y=8G{;c$=Ha%S92q27+0#|977OHfS-#{DR;{ehfW7y86iNH=I2gSjel z-1VFXjo`?*KQELu#QY}F?gzthH`?eShpCajWISo}EkRNT+&Gabfumu5xAH0j7gN#2 zUKWBvk2<=*;PVGqldD?GF3%*7R1S}ADMwPi&$3Tn@rW}!jNWH4?PdSG^i_M=w{IM9 z!uZ{q!Sk9KZTbebD=Mme8euy-i8N=;lJ>0EyRP1AzWTy=cjdx(KX)^CvMc{`c!i0M zON}?*#NmI6kU;1A`3n2wA=pG5D)~S0{+iv%Rh${p5D{7Ho{sNS7nXX5OcmXXXdkZ3 zI#G7*#IU-cJ>5gH}Cyl1=|p#eLly zG>$ea7N*%;GdLOsxVI+Lq1uNs<@ z?#C4WK3Uy^7YWn4(-LcrUP9<>T1lNkYI?kLF5ux#P@C{tKc@E13WQ literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_lab.png b/client/visualizer/src/static/img/robots/red_lab.png new file mode 100644 index 0000000000000000000000000000000000000000..4283697b722539a00ea33113730e951452bd5afc GIT binary patch literal 1801 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YpB>EalY!TNUQ$vhE5fi__d#v}V;ln%CXzyEI) zvqM3_<4tvg$^Yw@uNw8mUbVezD>+4TWm5m@nBAx6oxFFCuS_sPh3U7kr>SMngOwX* zdVW(dOgo_Ptna162b2W z-z;Ej-onzorj@UAIY*AnqnyIeXS(0pM1Qbp+PYYPQ_l1GoY35bYPLUA9*HZmPd_su zDQGU!>rhtB$0vRke-zF*$Nfq3{nm%6iR!YiW>4rlJhM`N4Qon9WRaMGn2q2*!DS8# z`_SuQPHA(kMqUc7b)9YOUy-tJSP-+xIcMlb1}8$nB1awj8hr%MU~u@SUHZ} zXbItW1m|Afx&D{+(gz#A z&6@CH!Bl}wZjIB|G#s1lIybpvv7Ud*i<#5Z7tj6@)!t~vTrsO)iQDz5cP~8V94ZQ9JOb!+SMk%hH|Aj78ms*Fv?e$un8|^OSG`HCC!=z~OV-^Q5 zPk%7;Y1lr~yX%x=lw^{am1d=}9NxitU#i)yA|Q`VWyzx{w;cQ5IzOvT)Do8SI-9+4 zo$^jYjg3N=x3Ka&IADCMG0o@TwX=>-4Aea?ta+Sy>y%>{*N10S!B)lB1-}?A&H6X&n}#7pYr?WrfJ{480`u9<}+)}YZjvzW+BxrDUKI8Io8eD<8q@Q zZo<5)lX&wor<&zd^(GXx7f!EuV6|yw&kQ-QDVDnbR$kC^+IQFY)QKs#roVG^aIRE3 zQnAQu?d41JIe%_tTrl&4nsIyN>4RHCoo26i`;=+=uRFHeR(;#mUaPry+JtIDnU&89 zJ14LiDM$aC-Q&`ifv1?`)yr;Y&U}&J;yZXx%IbfiHSRu;C21Dalt!D#asQY zchqCMa~J=QnxD_bxQ?N2;pYQqXLR^}o%+mkuE%4hGrZ4NH_g)ut-gC{)w@|48Cz`2 zl^(Ufvl6=cRDiYkql@ESi9VOW8QQm;pX?Bv&MRFA~Cf<&3D^gyvx%Xbe!AH*zJ>KuG z*8ThN@6f;}KNtRv+#I+=s?trQI_0cE>~>3&$S+>?w-)$p%=3A0?A6KC)9=h?i~ZR6 jsqD{gjyFmMicIy4-ZRgOv~!l70o4bdu6{1-oD!M<^o+UT literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_miner.png b/client/visualizer/src/static/img/robots/red_miner.png new file mode 100644 index 0000000000000000000000000000000000000000..15319db2f19ca41dadb5e2ac53b30d3b5b769169 GIT binary patch literal 2226 zcmZ`)3sh3s8a|*BXeQX0`x2wL99%>+H!=n%;_#FzfFvR+ASXr`0g5<@ zNdltC)ntJ|RA6NqZvrk*gbA)DEV>^^=JI1eN1OxB*2GO61VIu%I+n0K@^|O6SBEU zpwc%YlAA1aH8D{ZT6#X8Q^<~8u9PHLd@aQb;*~piJDe?k$y*^MDYHZtGe*EoOji24 z+1uKZ7P$YDU9R+5;TOjhaut2xv!iH9!Wce}ujt8wp0KF?|BSD_mWyvsVhi2=HTWw1 zwQ9%m{ugKdGP|fC;gv1>qJ^LDXCbS&AUAaqe(AE^)K`UiD!w$eY8u7UKTd5VD1qC% z;Tto{SyY>r^V=K}F?{3@q~*QFv}Gf|#Vyggr_8eOQjtNUN$|ZpwA1@9SmyIh@hVgh zMJ|}`Yne0EF`nmEqOKsH9OefKeL{H+hZk&MtfOa+S;nRAFnf|es9=?|3yF7l@tcO z3>qE0)T?9IhG>tkCw{bAE@nbnkU3`%%k7$Imkg))7JNiZ98bn*6Dt(gIqymb-tL~xHCW16I@%& zwE?;f+%;i!XCGkjSBIgS^ud0hOmyhXj=xt;5Md`Sy`EhqJ-UKmU@fmt{w8td7~&@k1MSWDPu#SPUgw`kvuIYh3)?w%-X80VFo^CS|2oc9#@)8dAoKoKkVyb$5JCAp1 zUyk`XABYcnMeQ)XVrL%(e9z(A8=Q3QIv;BUHSw}@(o?%vwCO3z+bD;8E-bf?EpX7r zU`l_Tw~>zRn@7ByKzP%&ZSEwR29E!L-vQ z$Sswmw$io>nz13b%;M`F-58%4FPE9|9$jN3%JEvff(-|ppJdIXk=6wA{z&#J%EW(* zZQssdnU~bvG@POALkO(eADc1+gXGnX-l$npK4TyEiS~^Doa2UrQY**o8m0%&KO{Zd ze6lIi=h>JfMcT2VXz-OBn|F*4xBU;rx4T;p?tlzwvhcl8z~53@KR0ZA!T4~|RQ|D> zw^rxc9Y1oHEVE=jwk@>S+`1_x;AHsq^uf9Ax9$?KY5{K<|+B5EL?F z4J$+orv76<*skIG#UDJ+HxFR4M77TA(nu@cy{kR5wM!s%yVF3iT(2U2=sIek5sKbA z45-HJg=VS9GBk9|1B*aWw?Gw{H+wgqactL6Y@P1e)UejgKOiMr5_SU?V(!NTFfRig z-z^Jg1b{3n+o(@_KFKQ?rI-f~ex{!8nlNqD*R3g!`fG)!xK~O%y$v-dogUI-|51z_ zN6*~q%!M>~{027o2%&J8q>7xlX6Whe`*)mP=x=*UcJy6$jM-wLy>aG)`71)zTm=H2 zMi{r@Q3F20iuTxbhyy*5E!A<1O4Z=2^|Hx}`^z=@1$Pr(ZlJt_)=26O`gBje&U~F_ zVS6+~-s;}+0===u3V)zMw6lIBS~H|vuB#;mLP>dlL2$ E4-1rPmjD0& literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_sage.png b/client/visualizer/src/static/img/robots/red_sage.png new file mode 100644 index 0000000000000000000000000000000000000000..d80e3d33a5139e7bc812186eac2b56c30e38f6dc GIT binary patch literal 2111 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 B1gro6 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower.png b/client/visualizer/src/static/img/robots/red_watchtower.png new file mode 100644 index 0000000000000000000000000000000000000000..3246172bc8d28a781fbc8c5e4fd45e645d8881c6 GIT binary patch literal 1732 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YWz)5S3)gZ1sqlYLhV1llf}7`*9r@R(Ea|M(*| z8HSC#1`a>=PxD^ocginyne|KO=_xlguYbFpYF)VNozHVYi&GpqX;F9ip8V&V7hb)F zsq$Xw-{(TtVz2UttUG1wRUe|aTkp#Bn*X~`+zYbRS@2)<#l9)`%D?^%ei@p#+9vqm zNo!G$T?_qFoOdbfu_+5Ryi2?iSkb`nqTtsHwF4dg_gha@i#E86C}}jA&VA>cvhu^b z)oKf*9&QlRsWpvdTP`)>SCm6kZSC2GIc4iZJxqBte9KxDE-d`FFe#<%%*>@)HJ8q0 z8660^R8s5v>q^k+oZ#8^mvfm67y9@%tetr7hC|yG;ehT+|FduS9gke9UiFi`c+&L_ z)z#clk3!|Q%Jj$T9M;VgKPF?u`TC;K#@;q`=48U&wrObe|p~q=EhB{U(V@tS!K6p?%CwTpN}lLw@SM3B`p=1 zX(zLIug0pCPnYm*tG1lIa#{C2PNw9mS3b==rEBdTHf%lcLJ$ml-xWSg33~>am$Q^-Wrk+p;3#N9BA|maXXdb1cqk@1BO- zd0O{pKINH^W446B{^LZITeo8GT{|LDbG|3VAtAY_P{dtR;i-a_*5#>bPkg_o*ySqe0&v%}#so=a+b^hk&8B9+5=36aoSke;aR`tnn z-t`lwB#nyZTfJCP`f24<+n!*DO~>30?^IA`R@psOUiHnI&pZ>Z>d8Or@nQ3*nP_tS zG;a$3uD{DJ+*7zQ?UiEi>R;;@iypXCyYk?zkS Date: Sat, 4 Dec 2021 10:02:53 -0500 Subject: [PATCH 035/413] Recompile schema files --- client/playback/src/gameworld.ts | 1 - schema/ts/battlecode_generated.ts | 21 ++++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 2f41f262..90672ea7 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -405,7 +405,6 @@ export default class GameWorld { /// Politicians self-destruct and affect nearby bodies /// Target: none - case schema.Action.ATTACK: //this.bodies.alter({ id: robotID, ability: 1}); this.bodies.alter({id: robotID, action: schema.Action.ATTACK as number}); diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index d8474d3c..582c570e 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -14,11 +14,8 @@ export enum BodyType{ BUILDER= 2, LABORATORY= 3, GUARD= 4, - GUARD_TURRET= 5, - ARCHER= 6, - ARCHER_TURRET= 7, - WIZARD= 8, - WIZARD_TURRET= 9 + WIZARD= 5, + TURRET= 6 }}; /** @@ -39,12 +36,14 @@ export enum Action{ MINE= 3, BUILD= 4, CONVERT_GOLD= 5, - ATTACKED= 6, - TRANSFORM= 7, - UPGRADE= 8, - REPAIR= 9, - CHANGE_HP= 10, - FULLY_REPAIRED= 11 + TRANSFORM= 6, + UPGRADE= 7, + REPAIR= 8, + CHANGE_HP= 9, + FULLY_REPAIRED= 10, + LOCAL_ABYSS= 11, + LOCAL_FURY= 12, + LOCAL_CHARGE= 13 }}; /** From 67a342fad87b755aa492cab0d7bc0afc3f89193a Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 10:14:48 -0500 Subject: [PATCH 036/413] Tweak schema --- schema/battlecode.fbs | 7 +++---- schema/ts/battlecode_generated.ts | 27 +++++++++++++-------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 702193f8..ba8c1227 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -71,9 +71,9 @@ table GameMap { //lead locations // a vectable of lead cords - lead_locations: VecTable; + leadLocations: VecTable; //inital lead amounts - initial_lead: [double]; + initialLead: [double]; } /// Actions that can be performed. @@ -84,12 +84,11 @@ table GameMap { /// the actions were performed. enum Action : byte { ATTACK, // combat unit types - DAZZLE, // wizard SPAWN_UNIT, //archon MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state + TRANSFORM, // Swaps a building between portable and turret mode UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 582c570e..9fd99ca2 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -31,19 +31,18 @@ export enum BodyType{ export namespace battlecode.schema{ export enum Action{ ATTACK= 0, - DAZZLE= 1, - SPAWN_UNIT= 2, - MINE= 3, - BUILD= 4, - CONVERT_GOLD= 5, - TRANSFORM= 6, - UPGRADE= 7, - REPAIR= 8, - CHANGE_HP= 9, - FULLY_REPAIRED= 10, - LOCAL_ABYSS= 11, - LOCAL_FURY= 12, - LOCAL_CHARGE= 13 + SPAWN_UNIT= 1, + MINE= 2, + BUILD= 3, + CONVERT_GOLD= 4, + TRANSFORM= 5, + UPGRADE= 6, + REPAIR= 7, + CHANGE_HP= 8, + FULLY_REPAIRED= 9, + LOCAL_ABYSS= 10, + LOCAL_FURY= 11, + LOCAL_CHARGE= 12 }}; /** From 79d5777f92785ea24b213490d1047dce65f5c633 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 10:39:05 -0500 Subject: [PATCH 037/413] Handle all actions --- client/playback/src/gameworld.ts | 169 +++++++++++++----------------- schema/battlecode.fbs | 11 +- schema/ts/battlecode_generated.ts | 68 ++++++------ 3 files changed, 115 insertions(+), 133 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 90672ea7..33e74073 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -25,7 +25,9 @@ export type BodiesSchema = { action: Int8Array, parent: Int32Array, hp: Int32Array, - level: Int8Array + level: Int8Array, + portable: Int8Array, + prototype: Int8Array }; // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data @@ -37,8 +39,10 @@ export type MapStats = { randomSeed: number, passability: Float64Array, // double - lead: Int32Array; - gold: Int32Array; + leadLocations: [Victor]; + leadAmounts: Int32Array + goldLocations: [Victor]; + goldAmounts: Int32Array getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; @@ -84,8 +88,6 @@ export type Log = { text: string }; - - /** * A frozen image of the game world. * @@ -177,7 +179,7 @@ export default class GameWorld { * IDs of robots who performed a temporary ability in the previous round, * which should be removed in the current round. */ - private abilityRobots: number[] = []; + private actionRobots: number[] = []; private bidRobots: number[] = []; constructor(meta: Metadata, config: playbackConfig) { @@ -200,7 +202,9 @@ export default class GameWorld { action: new Int8Array(0), parent: new Int32Array(0), hp: new Int32Array(0), - level: new Int8Array(0) + level: new Int8Array(0), + portable: new Int8Array(0), + turret: new Int8Array(0) }, 'id'); // Instantiate teamStats @@ -208,20 +212,12 @@ export default class GameWorld { for (let team in this.meta.teams) { var teamID = this.meta.teams[team].teamID; this.teamStats.set(teamID, { - robots: [ - 0, - 0, - 0, - 0, - 0, // NONE - ], - votes: 0, - influence: [0, 0, 0, 0, 0], - conviction: [0, 0, 0, 0, 0], - numBuffs: 0, - bidderID: -1, - bid: 0, - income: 0 + robots: [0, 0, 0, 0, [0, 0, 0], [0, 0, 0], [0, 0, 0]], + lead: 0, + gold: 0, + total_hp: [0, 0, 0, 0, [0, 0, 0], [0, 0, 0], [0, 0, 0]], + lead_income: 0, + gold_income: 0 }); } @@ -232,7 +228,11 @@ export default class GameWorld { maxCorner: new Victor(0,0), bodies: new schema.SpawnedBodyTable(), randomSeed: 0, + passability: new Float64Array(0), + lead: new Int32Array(0), + gold: new Int32Array(0), + getIdx: (x:number, y:number) => 0, getLoc: (idx: number) => new Victor(0,0) }; @@ -301,6 +301,16 @@ export default class GameWorld { this.mapStats.passability = Float64Array.from(map.passabilityArray()); + const leadLocations = map.leadLocations(this._vecTableSlot1); + if (leadLocations) { + this.bodies.alterBulk({ + id: delta.movedIDsArray(), + x: movedLocs.xsArray(), + y: movedLocs.ysArray(), + }); + } + this.mapStats.leadLocations = Float64Array.from(map.lead()); + const width = (maxCorner.x() - minCorner.x()); this.mapStats.getIdx = (x:number, y:number) => ( Math.floor(y)*width + Math.floor(x) @@ -335,8 +345,7 @@ export default class GameWorld { this.teamStats.set(key, deepcopy(value)); }); this.mapStats = deepcopy(source.mapStats); - this.empowered.copyFrom(source.empowered); - this.abilityRobots = Array.from(source.abilityRobots); + this.actionRobots = Array.from(source.actionRobots); this.bidRobots = Array.from(source.bidRobots); this.logs = Array.from(source.logs); this.logsShift = source.logsShift; @@ -355,10 +364,8 @@ export default class GameWorld { let teamID = delta.teamIDs(i); let statObj = this.teamStats.get(teamID); - statObj.votes += delta.teamVotes(i); - statObj.numBuffs = delta.teamNumBuffs(i); - statObj.bidderID = delta.teamBidderIDs(i); - statObj.bid = 0; + statObj.lead += delta.teamLeadIncome(i); + statObj.gold += delta.teamGoldIncome(i); this.teamStats.set(teamID, statObj); } @@ -380,8 +387,8 @@ export default class GameWorld { } // Remove abilities from previous round - this.bodies.alterBulk({id: new Int32Array(this.abilityRobots), ability: new Int8Array(this.abilityRobots.length)}); - this.abilityRobots = []; + this.bodies.alterBulk({id: new Int32Array(this.actionRobots), ability: new Int8Array(this.actionRobots.length)}); + this.actionRobots = []; this.empowered.clear(); // Remove bids from previous round @@ -398,104 +405,69 @@ export default class GameWorld { const target = delta.actionTargets(i); const body = this.bodies.lookup(robotID); const teamStatsObj: TeamStats = this.teamStats.get(body.team); + const setAction = () => { + this.bodies.alter({id: robotID, action: action as number}); + this.actionRobots.push(robotID); + }; // should be called for actions performed *by* the robot. switch (action) { // TODO: validate actions? // Actions list from battlecode.fbs enum Action - - /// Politicians self-destruct and affect nearby bodies - /// Target: none - + case schema.Action.ATTACK: - //this.bodies.alter({ id: robotID, ability: 1}); - this.bodies.alter({id: robotID, action: schema.Action.ATTACK as number}); - this.abilityRobots.push(robotID); + setAction(); break; /// Slanderers passively generate influence for the /// Enlightenment Center that created them. /// Target: parent ID case schema.Action.LOCAL_ABYSS: - this.bodies.alter({id: robotID, action: schema.Action.LOCAL_ABYSS as number}); - this.abilityRobots.push(robotID); + setAction(); break; case schema.Action.LOCAL_CHARGE: - this.bodies.alter({id: robotID, action: schema.Action.LOCAL_CHARGE as number}); - this.abilityRobots.push(robotID); + setAction(); break; case schema.Action.LOCAL_FURY: - this.bodies.alter({id: robotID, action: schema.Action.LOCAL_FURY as number}); - this.abilityRobots.push(robotID); + setAction(); break; - /// Slanderers turn into Politicians. - /// Target: none - case schema.Action.CAMOUFLAGE: - - if (body.type !== schema.BodyType.SLANDERER) { - throw new Error("non-slanderer camouflaged"); - } - this.bodies.alter({ id: robotID, type: schema.BodyType.POLITICIAN}); - this.bodies.alter({ id: robotID, ability: (body.team == 1 ? 4 : 5)}); - this.abilityRobots.push(robotID); - - teamStatsObj.robots[schema.BodyType.SLANDERER]--; - teamStatsObj.robots[schema.BodyType.POLITICIAN]++; - - teamStatsObj.conviction[schema.BodyType.SLANDERER] -= body.conviction; - teamStatsObj.conviction[schema.BodyType.POLITICIAN] += body.conviction; - - teamStatsObj.influence[schema.BodyType.SLANDERER] -= body.influence; - teamStatsObj.influence[schema.BodyType.POLITICIAN] += body.influence; + case schema.Action.CONVERT_GOLD: + setAction(); + teamStatsObj.gold += target; + teamStatsObj.lead -= 0; break; - /// Muckrakers can expose a scandal. - /// Target: an enemy body. - case schema.Action.EXPOSE: - this.bodies.alter({ id: robotID, ability: 2}); - this.abilityRobots.push(robotID); + + case schema.Action.TRANSFORM: + setAction(); + this.bodies.alter({ id: robotID, portable: 1}); break; - /// Units can change their flag. - /// Target: a new flag value. - case schema.Action.SET_FLAG: - this.bodies.alter({ id: robotID, flag: target}); + + case schema.Action.UPGRADE: + setAction(); + this.bodies.alter({ id: robotID, level: body.level + 1}); break; + /// Builds a unit (enlightent center). /// Target: spawned unit case schema.Action.SPAWN_UNIT: + setAction(); this.bodies.alter({id: target, parent: robotID}); break; - /// Places a bid (enlightent center). - /// Target: bid placed - case schema.Action.PLACE_BID: - this.bodies.alter({id: robotID, bid: target}); - this.bidRobots.push(robotID); - if (robotID === teamStatsObj.bidderID) teamStatsObj.bid = target; - break; - /// A robot can change team after being empowered - /// Target: teamID - case schema.Action.CHANGE_TEAM: - // TODO remove the robot, don't alter it + case schema.Action.REPAIR: + setAction(); break; - /// A robot's influence changes. - /// Target: delta value - case schema.Action.CHANGE_INFLUENCE: - this.bodies.alter({ id: robotID, influence: body.influence + target}); - - if(!teamStatsObj) {continue;} // In case this is a neutral bot - teamStatsObj.influence[body.type] += target; - this.teamStats.set(body.team, teamStatsObj); + + case schema.Action.CHANGE_HP: + this.bodies.alter({ id: robotID, hp: body.hp + target}); + teamStatsObj.total_hp[body.type][body.level] += target; break; - /// A robot's conviction changes. - /// Target: delta value, i.e. red 5 -> blue 3 is -2 - case schema.Action.CHANGE_CONVICTION: - this.bodies.alter({ id: robotID, conviction: body.conviction + target}); - - if(!teamStatsObj) {continue;} // In case this is a neutral bot - teamStatsObj.conviction[body.type] += target; - this.teamStats.set(body.team, teamStatsObj); + + case schema.Action.FULLY_REPAIRED: + this.bodies.alter({ id: robotID, prototype: 0}); + teamStatsObj.total_hp[body.type][body.level] += target; break; - + case schema.Action.DIE_EXCEPTION: console.log(`Exception occured: robotID(${robotID}), target(${target}`); break; @@ -504,6 +476,7 @@ export default class GameWorld { console.log(`Undefined action: action(${action}), robotID(${robotID}, target(${target}))`); break; } + this.teamStats.set(body.team, teamStatsObj); // TODO: is this necessary } } diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index ba8c1227..6191bfd8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -73,7 +73,7 @@ table GameMap { // a vectable of lead cords leadLocations: VecTable; //inital lead amounts - initialLead: [double]; + leadAmounts: [double]; } /// Actions that can be performed. @@ -95,7 +95,10 @@ enum Action : byte { FULLY_REPAIRED, // prototype becomes a turret LOCAL_ABYSS, LOCAL_FURY, - LOCAL_CHARGE + LOCAL_CHARGE, + /// Dies due to an uncaught exception. + /// Target: none + DIE_EXCEPTION } // Metadata @@ -239,8 +242,8 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLead: [int]; - teamGold: [int]; + teamLeadIncome: [int]; + teamGoldIncome: [int]; /// The IDs of bodies that moved. movedIDs: [int]; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 9fd99ca2..c32f55e3 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -42,7 +42,13 @@ export enum Action{ FULLY_REPAIRED= 9, LOCAL_ABYSS= 10, LOCAL_FURY= 11, - LOCAL_CHARGE= 12 + LOCAL_CHARGE= 12, + + /** + * Dies due to an uncaught exception. + * Target: none + */ + DIE_EXCEPTION= 13 }}; /** @@ -891,7 +897,7 @@ leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -initialLead(index: number):number|null { +leadAmounts(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; }; @@ -899,7 +905,7 @@ initialLead(index: number):number|null { /** * @returns number */ -initialLeadLength():number { +leadAmountsLength():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -907,7 +913,7 @@ initialLeadLength():number { /** * @returns Float64Array */ -initialLeadArray():Float64Array|null { +leadAmountsArray():Float64Array|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -998,10 +1004,10 @@ static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuf /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset initialLeadOffset + * @param flatbuffers.Offset leadAmountsOffset */ -static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(7, initialLeadOffset, 0); +static addLeadAmounts(builder:flatbuffers.Builder, leadAmountsOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, leadAmountsOffset, 0); }; /** @@ -1009,7 +1015,7 @@ static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers * @param Array. data * @returns flatbuffers.Offset */ -static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadAmountsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(8, data.length, 8); for (var i = data.length - 1; i >= 0; i--) { builder.addFloat64(data[i]); @@ -1021,7 +1027,7 @@ static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint * @param flatbuffers.Builder builder * @param number numElems */ -static startInitialLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadAmountsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(8, numElems, 8); }; @@ -1034,7 +1040,7 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, initialLeadOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, leadAmountsOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); @@ -1043,7 +1049,7 @@ static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, GameMap.addRandomSeed(builder, randomSeed); GameMap.addPassability(builder, passabilityOffset); GameMap.addLeadLocations(builder, leadLocationsOffset); - GameMap.addInitialLead(builder, initialLeadOffset); + GameMap.addLeadAmounts(builder, leadAmountsOffset); return GameMap.endGameMap(builder); } } @@ -2508,7 +2514,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -teamLead(index: number):number|null { +teamLeadIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2516,7 +2522,7 @@ teamLead(index: number):number|null { /** * @returns number */ -teamLeadLength():number { +teamLeadIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2524,7 +2530,7 @@ teamLeadLength():number { /** * @returns Int32Array */ -teamLeadArray():Int32Array|null { +teamLeadIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2533,7 +2539,7 @@ teamLeadArray():Int32Array|null { * @param number index * @returns number */ -teamGold(index: number):number|null { +teamGoldIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2541,7 +2547,7 @@ teamGold(index: number):number|null { /** * @returns number */ -teamGoldLength():number { +teamGoldIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2549,7 +2555,7 @@ teamGoldLength():number { /** * @returns Int32Array */ -teamGoldArray():Int32Array|null { +teamGoldIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2974,10 +2980,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadOffset + * @param flatbuffers.Offset teamLeadIncomeOffset */ -static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadOffset, 0); +static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadIncomeOffset, 0); }; /** @@ -2985,7 +2991,7 @@ static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2997,16 +3003,16 @@ static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldOffset + * @param flatbuffers.Offset teamGoldIncomeOffset */ -static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldOffset, 0); +static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldIncomeOffset, 0); }; /** @@ -3014,7 +3020,7 @@ static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3026,7 +3032,7 @@ static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3422,11 +3428,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadOffset:flatbuffers.Offset, teamGoldOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLead(builder, teamLeadOffset); - Round.addTeamGold(builder, teamGoldOffset); + Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); + Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); From 41c177d54b51a1d8ed45b9804ced820d932d14ab Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:22:21 -0500 Subject: [PATCH 038/413] Update schema --- schema/battlecode.fbs | 16 +++--- schema/ts/battlecode_generated.ts | 94 ++++++++++++++++--------------- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 702193f8..6191bfd8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -71,9 +71,9 @@ table GameMap { //lead locations // a vectable of lead cords - lead_locations: VecTable; + leadLocations: VecTable; //inital lead amounts - initial_lead: [double]; + leadAmounts: [double]; } /// Actions that can be performed. @@ -84,19 +84,21 @@ table GameMap { /// the actions were performed. enum Action : byte { ATTACK, // combat unit types - DAZZLE, // wizard SPAWN_UNIT, //archon MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state + TRANSFORM, // Swaps a building between portable and turret mode UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, FULLY_REPAIRED, // prototype becomes a turret LOCAL_ABYSS, LOCAL_FURY, - LOCAL_CHARGE + LOCAL_CHARGE, + /// Dies due to an uncaught exception. + /// Target: none + DIE_EXCEPTION } // Metadata @@ -240,8 +242,8 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLead: [int]; - teamGold: [int]; + teamLeadIncome: [int]; + teamGoldIncome: [int]; /// The IDs of bodies that moved. movedIDs: [int]; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index d8474d3c..c32f55e3 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -14,11 +14,8 @@ export enum BodyType{ BUILDER= 2, LABORATORY= 3, GUARD= 4, - GUARD_TURRET= 5, - ARCHER= 6, - ARCHER_TURRET= 7, - WIZARD= 8, - WIZARD_TURRET= 9 + WIZARD= 5, + TURRET= 6 }}; /** @@ -34,17 +31,24 @@ export enum BodyType{ export namespace battlecode.schema{ export enum Action{ ATTACK= 0, - DAZZLE= 1, - SPAWN_UNIT= 2, - MINE= 3, - BUILD= 4, - CONVERT_GOLD= 5, - ATTACKED= 6, - TRANSFORM= 7, - UPGRADE= 8, - REPAIR= 9, - CHANGE_HP= 10, - FULLY_REPAIRED= 11 + SPAWN_UNIT= 1, + MINE= 2, + BUILD= 3, + CONVERT_GOLD= 4, + TRANSFORM= 5, + UPGRADE= 6, + REPAIR= 7, + CHANGE_HP= 8, + FULLY_REPAIRED= 9, + LOCAL_ABYSS= 10, + LOCAL_FURY= 11, + LOCAL_CHARGE= 12, + + /** + * Dies due to an uncaught exception. + * Target: none + */ + DIE_EXCEPTION= 13 }}; /** @@ -893,7 +897,7 @@ leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -initialLead(index: number):number|null { +leadAmounts(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; }; @@ -901,7 +905,7 @@ initialLead(index: number):number|null { /** * @returns number */ -initialLeadLength():number { +leadAmountsLength():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -909,7 +913,7 @@ initialLeadLength():number { /** * @returns Float64Array */ -initialLeadArray():Float64Array|null { +leadAmountsArray():Float64Array|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -1000,10 +1004,10 @@ static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuf /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset initialLeadOffset + * @param flatbuffers.Offset leadAmountsOffset */ -static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(7, initialLeadOffset, 0); +static addLeadAmounts(builder:flatbuffers.Builder, leadAmountsOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, leadAmountsOffset, 0); }; /** @@ -1011,7 +1015,7 @@ static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers * @param Array. data * @returns flatbuffers.Offset */ -static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadAmountsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(8, data.length, 8); for (var i = data.length - 1; i >= 0; i--) { builder.addFloat64(data[i]); @@ -1023,7 +1027,7 @@ static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint * @param flatbuffers.Builder builder * @param number numElems */ -static startInitialLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadAmountsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(8, numElems, 8); }; @@ -1036,7 +1040,7 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, initialLeadOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, leadAmountsOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); @@ -1045,7 +1049,7 @@ static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, GameMap.addRandomSeed(builder, randomSeed); GameMap.addPassability(builder, passabilityOffset); GameMap.addLeadLocations(builder, leadLocationsOffset); - GameMap.addInitialLead(builder, initialLeadOffset); + GameMap.addLeadAmounts(builder, leadAmountsOffset); return GameMap.endGameMap(builder); } } @@ -2510,7 +2514,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -teamLead(index: number):number|null { +teamLeadIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2518,7 +2522,7 @@ teamLead(index: number):number|null { /** * @returns number */ -teamLeadLength():number { +teamLeadIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2526,7 +2530,7 @@ teamLeadLength():number { /** * @returns Int32Array */ -teamLeadArray():Int32Array|null { +teamLeadIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2535,7 +2539,7 @@ teamLeadArray():Int32Array|null { * @param number index * @returns number */ -teamGold(index: number):number|null { +teamGoldIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2543,7 +2547,7 @@ teamGold(index: number):number|null { /** * @returns number */ -teamGoldLength():number { +teamGoldIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2551,7 +2555,7 @@ teamGoldLength():number { /** * @returns Int32Array */ -teamGoldArray():Int32Array|null { +teamGoldIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2976,10 +2980,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadOffset + * @param flatbuffers.Offset teamLeadIncomeOffset */ -static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadOffset, 0); +static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadIncomeOffset, 0); }; /** @@ -2987,7 +2991,7 @@ static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2999,16 +3003,16 @@ static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldOffset + * @param flatbuffers.Offset teamGoldIncomeOffset */ -static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldOffset, 0); +static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldIncomeOffset, 0); }; /** @@ -3016,7 +3020,7 @@ static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3028,7 +3032,7 @@ static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3424,11 +3428,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadOffset:flatbuffers.Offset, teamGoldOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLead(builder, teamLeadOffset); - Round.addTeamGold(builder, teamGoldOffset); + Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); + Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); From 6c3560e02a8c23029f3d2704abcb16f782e51138 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:41:56 -0500 Subject: [PATCH 039/413] Add build cost to schema --- schema/battlecode.fbs | 7 ++--- schema/ts/battlecode_generated.ts | 45 +++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 6191bfd8..cb0c68c0 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -112,11 +112,12 @@ table BodyTypeMetadata { visionRadiusSquared: int; movingCooldown: float; bytecodeLimit: int; + buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; + dpsMul: float; // dps multiplier for level + hpMul: float; // hp multiplier per level + upgradeCosts: [int]; } /// Data relevant to a particular team. diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index c32f55e3..2c71e46b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1143,7 +1143,7 @@ bytecodeLimit():number { /** * @returns number */ -dps():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1151,7 +1151,7 @@ dps():number { /** * @returns number */ -hp():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1159,8 +1159,16 @@ hp():number { /** * @returns number */ -dpsMul():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @returns number + */ +dpsMul():number { + var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1168,7 +1176,7 @@ dpsMul():number { * @returns number */ hpMul():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1177,7 +1185,7 @@ hpMul():number { * @returns number */ upgradeCosts(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -1185,7 +1193,7 @@ upgradeCosts(index: number):number|null { * @returns number */ upgradeCostsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -1193,7 +1201,7 @@ upgradeCostsLength():number { * @returns Int32Array */ upgradeCostsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -1201,7 +1209,7 @@ upgradeCostsArray():Int32Array|null { * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(12); + builder.startObject(13); }; /** @@ -1260,12 +1268,20 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(7, buildCost, 0); +}; + /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(7, dps, 0); + builder.addFieldInt32(8, dps, 0); }; /** @@ -1273,7 +1289,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(8, hp, 0); + builder.addFieldInt32(9, hp, 0); }; /** @@ -1281,7 +1297,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(9, dpsMul, 0.0); + builder.addFieldFloat32(10, dpsMul, 0.0); }; /** @@ -1289,7 +1305,7 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(10, hpMul, 0.0); + builder.addFieldFloat32(11, hpMul, 0.0); }; /** @@ -1297,7 +1313,7 @@ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { * @param flatbuffers.Offset upgradeCostsOffset */ static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, upgradeCostsOffset, 0); + builder.addFieldOffset(12, upgradeCostsOffset, 0); }; /** @@ -1330,7 +1346,7 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, buildCost:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); @@ -1339,6 +1355,7 @@ static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schem BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); From 89c9bf66ae7cccb9a173bf548adb6fd5bd6ec383 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:47:33 -0500 Subject: [PATCH 040/413] More schema tweaks --- schema/battlecode.fbs | 11 +++----- schema/ts/battlecode_generated.ts | 42 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index cb0c68c0..1b23ecfe 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -187,11 +187,11 @@ union Event { GameFooter } -table Constants{ +table Constants { //amounts of resources added to each block per round leadAdditiveIncease: double; goldAdditiveIncease: double; - increase_period: int; + increasePeriod: int; } @@ -208,9 +208,6 @@ table GameHeader { constants: Constants; } - - - /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. @@ -266,9 +263,9 @@ table Round { actionTargets: [int]; /// The IDs of the robots who changed their indicator strings - indicationStringIDs: [int]; + indicaortStringIDs: [int]; /// The messages of the robots who changed their indicator strings - indicationStrings: [string]; + indicatorStrings: [string]; /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2c71e46b..2ba18c03 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -2741,7 +2741,7 @@ actionTargetsArray():Int32Array|null { * @param number index * @returns number */ -indicationStringIDs(index: number):number|null { +indicaortStringIDs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2749,7 +2749,7 @@ indicationStringIDs(index: number):number|null { /** * @returns number */ -indicationStringIDsLength():number { +indicaortStringIDsLength():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2757,7 +2757,7 @@ indicationStringIDsLength():number { /** * @returns Int32Array */ -indicationStringIDsArray():Int32Array|null { +indicaortStringIDsArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2769,9 +2769,9 @@ indicationStringIDsArray():Int32Array|null { * @param flatbuffers.Encoding= optionalEncoding * @returns string|Uint8Array */ -indicationStrings(index: number):string -indicationStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array -indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { +indicatorStrings(index: number):string +indicatorStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array +indicatorStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; }; @@ -2779,7 +2779,7 @@ indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { /** * @returns number */ -indicationStringsLength():number { +indicatorStringsLength():number { var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3216,10 +3216,10 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicationStringIDsOffset + * @param flatbuffers.Offset indicaortStringIDsOffset */ -static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicationStringIDsOffset, 0); +static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicaortStringIDsOffset, 0); }; /** @@ -3227,7 +3227,7 @@ static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOf * @param Array. data * @returns flatbuffers.Offset */ -static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3239,16 +3239,16 @@ static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[ * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicationStringIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicaortStringIDsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicationStringsOffset + * @param flatbuffers.Offset indicatorStringsOffset */ -static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, indicationStringsOffset, 0); +static addIndicatorStrings(builder:flatbuffers.Builder, indicatorStringsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, indicatorStringsOffset, 0); }; /** @@ -3256,7 +3256,7 @@ static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset * @param Array. data * @returns flatbuffers.Offset */ -static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { +static createIndicatorStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); @@ -3268,7 +3268,7 @@ static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffe * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicationStringsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3445,7 +3445,7 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicaortStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); @@ -3457,8 +3457,8 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); - Round.addIndicationStringIDs(builder, indicationStringIDsOffset); - Round.addIndicationStrings(builder, indicationStringsOffset); + Round.addIndicaortStringIDs(builder, indicaortStringIDsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From 3fec55856986cac3e6d7e1480df699bc58fb02c3 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:07:48 -0500 Subject: [PATCH 041/413] Minor schema changes --- schema/battlecode.fbs | 4 +- schema/ts/battlecode_generated.ts | 72 +++++++++++++++---------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1b23ecfe..0d432ce8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -107,16 +107,16 @@ enum Action : byte { table BodyTypeMetadata { type: BodyType; spawnSource: BodyType; - actionCooldown: float; actionRadiusSquared: int; visionRadiusSquared: int; + actionCooldown: float; movingCooldown: float; bytecodeLimit: int; - buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level + buildCost: int; upgradeCosts: [int]; } diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2ba18c03..44e7be78 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1103,15 +1103,15 @@ spawnSource():battlecode.schema.BodyType { /** * @returns number */ -actionCooldown():number { +actionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 8); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -actionRadiusSquared():number { +visionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 10); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1119,9 +1119,9 @@ actionRadiusSquared():number { /** * @returns number */ -visionRadiusSquared():number { +actionCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** @@ -1143,7 +1143,7 @@ bytecodeLimit():number { /** * @returns number */ -buildCost():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1151,7 +1151,7 @@ buildCost():number { /** * @returns number */ -dps():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1159,15 +1159,15 @@ dps():number { /** * @returns number */ -hp():number { +dpsMul():number { var offset = this.bb!.__offset(this.bb_pos, 22); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** * @returns number */ -dpsMul():number { +hpMul():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1175,9 +1175,9 @@ dpsMul():number { /** * @returns number */ -hpMul():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** @@ -1230,26 +1230,26 @@ static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema /** * @param flatbuffers.Builder builder - * @param number actionCooldown + * @param number actionRadiusSquared */ -static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(2, actionCooldown, 0.0); +static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { + builder.addFieldInt32(2, actionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number actionRadiusSquared + * @param number visionRadiusSquared */ -static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(3, actionRadiusSquared, 0); +static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { + builder.addFieldInt32(3, visionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number visionRadiusSquared + * @param number actionCooldown */ -static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { - builder.addFieldInt32(4, visionRadiusSquared, 0); +static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { + builder.addFieldFloat32(4, actionCooldown, 0.0); }; /** @@ -1268,20 +1268,12 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(7, buildCost, 0); -}; - /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(8, dps, 0); + builder.addFieldInt32(7, dps, 0); }; /** @@ -1289,7 +1281,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(9, hp, 0); + builder.addFieldInt32(8, hp, 0); }; /** @@ -1297,7 +1289,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(10, dpsMul, 0.0); + builder.addFieldFloat32(9, dpsMul, 0.0); }; /** @@ -1305,7 +1297,15 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(11, hpMul, 0.0); + builder.addFieldFloat32(10, hpMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(11, buildCost, 0); }; /** @@ -1346,20 +1346,20 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, buildCost:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); BodyTypeMetadata.addHpMul(builder, hpMul); + BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } From 25c8d7b38133fb115a884c6e63a204b8675e7207 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:09:30 -0500 Subject: [PATCH 042/413] Update metadata --- client/playback/src/metadata.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/client/playback/src/metadata.ts b/client/playback/src/metadata.ts index 49fe963b..47fcc78e 100644 --- a/client/playback/src/metadata.ts +++ b/client/playback/src/metadata.ts @@ -48,12 +48,17 @@ export default class Metadata { this.types[body.type()] = new BodyTypeMetaData( body.type(), body.spawnSource(), - body.convictionRatio(), - body.actionCooldown(), body.actionRadiusSquared(), - body.sensorRadiusSquared(), - body.detectionRadiusSquared(), - body.bytecodeLimit() + body.visionRadiusSquared(), + body.actionCooldown(), + body.movingCooldown(), + body.bytecodeLimit(), + body.dps(), + body.hp(), + body.dpsMul(), + body.hpMul(), + body.buildCost(), + Array.from(body.upgradeCostsArray()) ); } // SAFE @@ -87,7 +92,10 @@ export class Team { */ export class BodyTypeMetaData { constructor(public type: schema.BodyType, public spawnSource:schema.BodyType, - public convictionRatio:number, public actionCooldown:number, public actionRadiusSquared:number, public sensorRadiusSquared:number, - public detectionRadiusSquared:number, public bytecodeLimit:number) { + public actionRadiusSquared:number, public visionRadiusSquared:number, + public actionCooldown:number, public movingCooldown:number, + public bytecodeLimit:number, + public dps:number, public hp:number, public dpsMul:number, public hpMul:number, + public buildCost:number, public upgradeCosts:number[]) { } } From ef0a9462cc86f05efe6d4e886fb13c4816741dc2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 13 Nov 2021 12:55:01 -0500 Subject: [PATCH 043/413] address comments on internal robot --- .../main/battlecode/common/GameConstants.java | 8 + .../src/main/battlecode/common/RobotMode.java | 20 ++ .../main/battlecode/world/InternalRobot.java | 196 ++++++++++-------- 3 files changed, 135 insertions(+), 89 deletions(-) create mode 100644 engine/src/main/battlecode/common/RobotMode.java diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index e5a39ba8..d206ac0d 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -49,6 +49,14 @@ public class GameConstants { // ****** GAME MECHANICS *********** // ********************************* + /** A prototype building's starting health, as a multiplier of max health. */ + public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; + + /** The maximum level a building can be. */ + public static final int MAX_LEVEL = 3; + + /** The amount damage is reduced by every ricochet. */ + public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8f; // ********************************* // ****** GAMEPLAY PROPERTIES ****** diff --git a/engine/src/main/battlecode/common/RobotMode.java b/engine/src/main/battlecode/common/RobotMode.java new file mode 100644 index 00000000..9673ea6d --- /dev/null +++ b/engine/src/main/battlecode/common/RobotMode.java @@ -0,0 +1,20 @@ +package battlecode.common; + +/** + * Holds the different "modes" a robot can be in, mostly useful for buildings. + */ +public enum RobotMode { + + ROBOT (true, true), + PROTOTYPE (false, false), + TURRET (true, false), + PORTABLE (false, true); + + public final boolean canAct; + public final boolean canMove; + + RobotMode(boolean canAct, boolean canMove) { + this.canAct = canAct; + this.canMove = canMove; + } +} \ No newline at end of file diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index f2c421e0..daf7987e 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -37,7 +37,8 @@ public strictfp class InternalRobot implements Comparable { private int bytecodesUsed; private int roundsAlive; - private double cooldownTurns; + private int actionCooldownTurns; + private int movementCooldownTurns; /** * Used to avoid recreating the same RobotInfo object over and over. @@ -75,7 +76,10 @@ public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, this.bytecodesUsed = 0; this.roundsAlive = 0; - this.cooldownTurns = 0; + this.actionCooldownTurns = 0; + this.addActionCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); + this.movementCooldownTurns = 0; + this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); @@ -141,8 +145,8 @@ public int getRoundsAlive() { return roundsAlive; } - public double getCooldownTurns() { - return cooldownTurns; + public int getActionCooldownTurns() { + return actionCooldownTurns; } public RobotInfo getRobotInfo(boolean trueSense) { @@ -176,6 +180,31 @@ public RobotInfo getRobotInfo(boolean trueSense) { // ****** CHECK METHODS ************* // ********************************** + /** + * Returns whether the robot can perform actions, based on mode and cooldowns. + */ + public boolean canActCooldown() { + return this.mode.canAct && this.actionCooldownTurns < GameConstants.COOLDOWN_LIMIT; + } + + /** + * Returns whether the robot can move, based on mode and cooldowns. + */ + public boolean canMoveCooldown() { + return this.mode.canMove && this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; + } + + /** + * Returns whether the robot can transform, based on mode and cooldowns. + */ + public boolean canTransformCooldown() { + if (this.mode == RobotMode.TURRET) + return this.actionCooldownTurns < GameConstants.COOLDOWN_LIMIT; + if (this.mode == RobotMode.PORTABLE) + return this.movementCooldownTurns < GameConstants.COOLDOWN_LIMIT; + return false; + } + /** * Returns the robot's action radius squared. */ @@ -268,10 +297,10 @@ public void setLocation(MapLocation loc) { /** * Resets the action cooldown. */ - public void addCooldownTurns() { - double passability = this.gameWorld.getPassability(this.location); - double newCooldownTurns = this.type.actionCooldown / passability; - setCooldownTurns(this.cooldownTurns + newCooldownTurns); + public void addActionCooldownTurns(int numActionCooldownToAdd) { + int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); + int newActionCooldownTurns = numActionCooldownToAdd * cooldownMultiplier; + setActionCooldownTurns(this.actionCooldownTurns + newActionCooldownTurns); } /** @@ -283,26 +312,19 @@ public void addCooldownTurns() { * * @param influenceAmount the amount to change influence by (can be negative) */ - public void addInfluenceAndConviction(int influenceAmount) { - int oldInfluence = this.influence; - this.influence += influenceAmount; - if (this.influence > GameConstants.ROBOT_INFLUENCE_LIMIT) { - this.influence = GameConstants.ROBOT_INFLUENCE_LIMIT; - } - this.conviction = this.influence; - if (this.influence != oldInfluence) { - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_INFLUENCE, this.influence - oldInfluence); - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.influence - oldInfluence); - } + public void addMovementCooldownTurns(int numMovementCooldownToAdd) { + int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); + int newMovementCooldownTurns = numMovementCooldownToAdd * cooldownMultiplier; + setMovementCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); } /** * Sets the action cooldown given the number of turns. * - * @param newTurns the number of cooldown turns + * @param newActionTurns the number of action cooldown turns */ - public void setCooldownTurns(double newTurns) { - this.cooldownTurns = newTurns; + public void setActionCooldownTurns(int newActionTurns) { + this.actionCooldownTurns = newActionTurns; } /** @@ -326,8 +348,24 @@ public void addConviction(int convictionAmount) { * * @param newFlag the new flag value */ - public void setFlag(int newFlag) { - this.flag = newFlag; + public void addHealth(int healthAmount) { + int oldHealth = this.health; + this.health += healthAmount; + int maxHealth = this.type.getMaxHealth(this.level); + if (this.health > maxHealth) { + this.health = maxHealth; + if (this.mode == RobotMode.PROTOTYPE) + this.mode = RobotMode.TURRET; + } + if (this.health <= 0) { + int leadDrop = this.type.getLeadDropped(this.level); + int goldDrop = this.type.getGoldDropped(this.level); + // TODO: drop resources at this location (interact with GameWorld) + this.gameWorld.destroyRobot(this.ID); + } else if (this.health != oldHealth) { + // TODO: double check this + this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_HEALTH, this.health - oldHealth); + } } /** @@ -336,20 +374,16 @@ public void setFlag(int newFlag) { * * @param newBid the new flag value */ - public void setBid(int newBid) { - resetBid(); - this.bid = newBid; - addInfluenceAndConviction(-this.bid); - } - - public void resetBid() { - addInfluenceAndConviction(this.bid); - this.bid = 0; - } - - public void addToCreate(InternalRobot parent, int ID, RobotType type, int influence, int conviction, MapLocation location) { - this.toCreateParents.add(parent); - this.toCreate.add(new RobotInfo(ID, this.team, type, influence, conviction, location)); + public void transform() { + if (this.canTransformCooldown()) { + if (this.mode == RobotMode.TURRET) { + this.mode = RobotMode.PORTABLE; + this.addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } else { + this.mode = RobotMode.TURRET; + this.addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } + } } /** @@ -366,33 +400,38 @@ public void empower(int radiusSquared) { double convictionToGive = this.conviction - GameConstants.EMPOWER_TAX; if (convictionToGive <= 0) return; + this.level++; + this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); + this.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + } - final double convictionPerBot = convictionToGive / numBots; - final double buff = this.gameWorld.getTeamInfo().getBuff(this.team); + /** + * Attacks another robot. Assumes bot is in range. + * Note: this is relatively inefficient(?), can possibly optimize + * by making better helper methods in GameWorld + * + * @param bot the robot to be attacked + */ + public void attack(InternalRobot bot) { + if (!this.canActLocation(bot.location)) + return; // TODO: throw exception? + int dmg = this.type.getDamage(this.level); + bot.addHealth(-dmg); + + int ricochetCount = this.type.getRicochetCount(this.level); + if (ricochetCount == 0) + return; - for (InternalRobot bot : robots) { - // check if this robot - if (bot.equals(this)) + // only wizards should execute the next chunk of code + InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, this.type.getActionRadiusSquared(this.level)); + List validTargets = new ArrayList<>(); + for (InternalRobot x : robots) { + if (x.team == this.team) continue; - - double conv = convictionPerBot; - if (bot.type == RobotType.ENLIGHTENMENT_CENTER && bot.team == this.team) { - // conviction doesn't get buffed, do nothing - } else if (bot.type == RobotType.ENLIGHTENMENT_CENTER) { - // complicated stuff - double convNeededToConvert = bot.conviction / buff; - if (conv <= convNeededToConvert) { - // all of conviction is buffed - conv *= buff; - } else { - // conviction buffed until conversion - conv = bot.conviction + (conv - convNeededToConvert); - } - } else { - // buff applied, cast down - conv *= buff; - } - bot.empowered(this, (int) conv, this.team); + if (x.equals(bot)) + continue; + validTargets.add(x); } // create new bots @@ -412,31 +451,10 @@ public void empower(int radiusSquared) { } } - /** - * Adds or removes influence, conviction, or both based on the type of the robot - * and the robot's affiliation. - * Called when a Politician Empowers. - * If conviction becomes negative, the robot switches teams or is destroyed. - * - * @param amount the amount this robot's conviction changes by (including all buffs) - * @param newTeam the team of the robot that empowered - */ - private void empowered(InternalRobot caller, int amount, Team newTeam) { - if (this.team != newTeam) - amount = -amount; - - if (type == RobotType.ENLIGHTENMENT_CENTER) - addInfluenceAndConviction(amount); - else - addConviction(amount); - - if (this.conviction < 0) { - if (this.type.canBeConverted()) { - int newInfluence = Math.abs(this.influence); - int newConviction = -this.conviction; - caller.addToCreate(this.parent, this.ID, this.type, newInfluence, newConviction, this.location); - } - this.gameWorld.destroyRobot(getID()); + Collections.sort(validTargets, new RicochetPriority()); + for (int i = 0; i < ricochetCount && i < validTargets.size(); i++) { + dmg = (int) (dmg * GameConstants.RICOCHET_DAMAGE_MULTIPLIER); + validTargets.get(i).addHealth(-dmg); } } @@ -460,8 +478,8 @@ public void processBeginningOfRound() { } public void processBeginningOfTurn() { - if (this.cooldownTurns > 0) - this.cooldownTurns = Math.max(0, this.cooldownTurns - 1); + this.actionCooldownTurns = Math.max(0, this.actionCooldownTurns - GameConstants.COOLDOWNS_PER_TURN); + this.movementCooldownTurns = Math.max(0, this.movementCooldownTurns - GameConstants.COOLDOWNS_PER_TURN); this.currentBytecodeLimit = getType().bytecodeLimit; } From 8f6fdfe1d8985c45a86849737c0c14033a9b9ef7 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 12:20:33 -0500 Subject: [PATCH 044/413] original internalrobot --- .../main/battlecode/world/InternalRobot.java | 218 +++++------------- 1 file changed, 59 insertions(+), 159 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index daf7987e..8d266892 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -1,6 +1,9 @@ package battlecode.world; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import battlecode.common.*; import battlecode.schema.Action; @@ -11,26 +14,17 @@ * - tiebreak by robot ID (priority to lower ID) */ public strictfp class InternalRobot implements Comparable { + private final RobotControllerImpl controller; private final GameWorld gameWorld; - /** - * The robot that built this robot. - * Equal to null if this is an Enlightenment Center, because they are specified by the map. - * This reference does not inhibit garbage collection because Enlightenment Centers never die. - */ - private final InternalRobot parent; - private final int ID; private Team team; private RobotType type; private MapLocation location; - private int influence; - private int flag; - private int bid; - - private ArrayList toCreate; - private ArrayList toCreateParents; + private int level; + private RobotMode mode; + private int health; private long controlBits; private int currentBytecodeLimit; @@ -43,8 +37,7 @@ public strictfp class InternalRobot implements Comparable { /** * Used to avoid recreating the same RobotInfo object over and over. */ - private RobotInfo cachedRobotInfoTrue; // true RobotType included - private RobotInfo cachedRobotInfoFake; // slanderers appear as politicians, null for all other robot types + private RobotInfo cachedRobotInfo; /** * Create a new internal representation of a robot @@ -53,23 +46,16 @@ public strictfp class InternalRobot implements Comparable { * @param type the type of the robot * @param loc the location of the robot * @param team the team of the robot - * @param influence the influence used to create the robot */ @SuppressWarnings("unchecked") - public InternalRobot(GameWorld gw, InternalRobot parent, int id, RobotType type, MapLocation loc, Team team, int influence) { - this.parent = parent; + public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team team) { this.ID = id; this.team = team; this.type = type; this.location = loc; - this.influence = influence; - this.conviction = (int) Math.ceil(this.type.convictionRatio * this.influence); - this.convictionCap = type == RobotType.ENLIGHTENMENT_CENTER ? GameConstants.ROBOT_INFLUENCE_LIMIT : this.conviction; - this.flag = 0; - this.bid = 0; - - this.toCreate = new ArrayList<>(); - this.toCreateParents = new ArrayList<>(); + this.level = 1; + this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.ROBOT; + this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.getMaxHealth(this.level)); this.controlBits = 0; this.currentBytecodeLimit = type.bytecodeLimit; @@ -97,10 +83,6 @@ public GameWorld getGameWorld() { return gameWorld; } - public InternalRobot getParent() { - return parent; - } - public int getID() { return ID; } @@ -117,20 +99,16 @@ public MapLocation getLocation() { return location; } - public int getInfluence() { - return influence; - } - - public int getConviction() { - return conviction; + public int getLevel() { + return level; } - public int getFlag() { - return flag; + public RobotMode getMode() { + return mode; } - public int getBid() { - return bid; + public int getHealth() { + return health; } public long getControlBits() { @@ -149,31 +127,23 @@ public int getActionCooldownTurns() { return actionCooldownTurns; } - public RobotInfo getRobotInfo(boolean trueSense) { - RobotInfo cachedRobotInfo = this.cachedRobotInfoTrue; - RobotType infoType = type; - if (!trueSense && type == RobotType.SLANDERER) { - cachedRobotInfo = this.cachedRobotInfoFake; - infoType = RobotType.POLITICIAN; - } + public int getMovementCooldownTurns() { + return movementCooldownTurns; + } + public RobotInfo getRobotInfo() { if (cachedRobotInfo != null && cachedRobotInfo.ID == ID && cachedRobotInfo.team == team - && cachedRobotInfo.type == infoType - && cachedRobotInfo.influence == influence - && cachedRobotInfo.conviction == conviction + && cachedRobotInfo.type == type + && cachedRobotInfo.level == level + && cachedRobotInfo.health == health && cachedRobotInfo.location.equals(location)) { return cachedRobotInfo; } - RobotInfo newRobotInfo = new RobotInfo(ID, team, infoType, influence, conviction, location); - if (!trueSense && type == RobotType.SLANDERER) { - this.cachedRobotInfoFake = newRobotInfo; - } else { - this.cachedRobotInfoTrue = newRobotInfo; - } - return newRobotInfo; + this.cachedRobotInfo = new RobotInfo(ID, team, type, level, health, location); + return this.cachedRobotInfo; } // ********************************** @@ -219,13 +189,6 @@ public int getSensorRadiusSquared() { return this.type.sensorRadiusSquared; } - /** - * Returns the robot's detection radius squared. - */ - public int getDetectionRadiusSquared() { - return this.type.detectionRadiusSquared; - } - /** * Returns whether this robot can perform actions on the given location. * @@ -244,15 +207,6 @@ public boolean canSenseLocation(MapLocation toSense){ return this.location.distanceSquaredTo(toSense) <= getSensorRadiusSquared(); } - /** - * Returns whether this robot can detect the given location. - * - * @param toSense the MapLocation to detect - */ - public boolean canDetectLocation(MapLocation toSense){ - return this.location.distanceSquaredTo(toSense) <= getDetectionRadiusSquared(); - } - /** * Returns whether this robot can act at a given radius away. * @@ -271,15 +225,6 @@ public boolean canSenseRadiusSquared(int radiusSquared) { return radiusSquared <= getSensorRadiusSquared(); } - /** - * Returns whether this robot can detect something a given radius away. - * - * @param radiusSquared the distance squared to detect - */ - public boolean canDetectRadiusSquared(int radiusSquared) { - return radiusSquared <= getDetectionRadiusSquared(); - } - // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** @@ -304,13 +249,7 @@ public void addActionCooldownTurns(int numActionCooldownToAdd) { } /** - * Adds influence given an amount to change this - * robot's influence by. Input can be negative to - * subtract influence. Conviction changes correspondingly. - * - * Only Enlightenment Centers should be able to change influence. - * - * @param influenceAmount the amount to change influence by (can be negative) + * Resets the movement cooldown. */ public void addMovementCooldownTurns(int numMovementCooldownToAdd) { int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); @@ -328,25 +267,18 @@ public void setActionCooldownTurns(int newActionTurns) { } /** - * Adds conviction given an amount to change this - * robot's conviction by. Input can be negative to - * subtract conviction. + * Sets the movement cooldown given the number of turns. * - * @param convictionAmount the amount to change conviction by (can be negative) + * @param newMovementTurns the number of movement cooldown turns */ - public void addConviction(int convictionAmount) { - int oldConviction = this.conviction; - this.conviction += convictionAmount; - if (this.conviction > this.convictionCap) - this.conviction = this.convictionCap; - if (this.conviction != oldConviction) - this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_CONVICTION, this.conviction - oldConviction); + public void setMovementCooldownTurns(int newMovementTurns) { + this.movementCooldownTurns = newMovementTurns; } /** - * Sets the flag given a new flag value. - * - * @param newFlag the new flag value + * Adds health to a robot. Input can be negative to subtract health. + * + * @param healthAmount the amount to change health by (can be negative) */ public void addHealth(int healthAmount) { int oldHealth = this.health; @@ -368,11 +300,12 @@ public void addHealth(int healthAmount) { } } + // ********************************* + // ****** ACTION METHODS ********* + // ********************************* + /** - * Sets the bid given a new bid value. - * The amount of influence bid is held hostage. - * - * @param newBid the new flag value + * Transform from turret to portable mode, or vice versa. */ public void transform() { if (this.canTransformCooldown()) { @@ -387,18 +320,12 @@ public void transform() { } /** - * Empowers given a range. Doesn't self-destruct!! - * - * @param radiusSquared the empower range + * Upgrade a building. */ - public void empower(int radiusSquared) { - InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, radiusSquared); - int numBots = robots.length - 1; // excluding self - if (numBots == 0) + public void upgrade() { + if (this.mode == RobotMode.ROBOT || this.mode == RobotMode.PROTOTYPE) return; - - double convictionToGive = this.conviction - GameConstants.EMPOWER_TAX; - if (convictionToGive <= 0) + if (this.level == GameConstants.MAX_LEVEL) return; this.level++; this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); @@ -434,22 +361,22 @@ public void attack(InternalRobot bot) { validTargets.add(x); } - // create new bots - for (int i = 0; i < toCreate.size(); i++) { - RobotInfo info = toCreate.get(i); - int id = this.gameWorld.spawnRobot(toCreateParents.get(i), info.getType(), info.getLocation(), this.team, info.getInfluence()); - InternalRobot newBot = this.gameWorld.getObjectInfo().getRobotByID(id); - if (newBot.type != RobotType.ENLIGHTENMENT_CENTER) { - // Shouldn't be called on an enlightenment center, because if spawned center's influence exceeds limit this would send a redundant change conviction action. - newBot.addConviction(info.getConviction() - newBot.getConviction()); - } - else { - // Resets influence and conviction to cap for enlightenment centers. Already done by reset bid, but nicer to do it here. - newBot.addInfluenceAndConviction(0); + MapLocation attackerLocation = this.location; + + class RicochetPriority implements Comparator { + public int compare(InternalRobot a, InternalRobot b) + { + int aDistToTarget = bot.location.distanceSquaredTo(a.location); + int bDistToTarget = bot.location.distanceSquaredTo(b.location); + if (aDistToTarget != bDistToTarget) + return aDistToTarget - bDistToTarget; + int aDistToAttacker = attackerLocation.distanceSquaredTo(a.location); + int bDistToAttacker = attackerLocation.distanceSquaredTo(b.location); + if (aDistToAttacker != bDistToAttacker) + return aDistToAttacker - bDistToAttacker; + return a.compareTo(b); } - this.gameWorld.getMatchMaker().addAction(info.getID(), Action.CHANGE_TEAM, id); } - } Collections.sort(validTargets, new RicochetPriority()); for (int i = 0; i < ricochetCount && i < validTargets.size(); i++) { @@ -458,16 +385,6 @@ public void attack(InternalRobot bot) { } } - /** - * Empowers given a range. Doesn't self-destruct!! - * - * @param radiusSquared the empower range - */ - public void expose(InternalRobot bot) { - this.gameWorld.addBuffs(this.team, bot.influence); - this.gameWorld.destroyRobot(bot.ID); - } - // ********************************* // ****** GAMEPLAY METHODS ********* // ********************************* @@ -490,24 +407,7 @@ public void processEndOfTurn() { } public void processEndOfRound() { - // generate passive influence - InternalRobot target = (parent == null) ? this : parent; - if (target.getType() != RobotType.ENLIGHTENMENT_CENTER) { - throw new IllegalStateException("The robot's parent is not an Enlightenment Center"); - } - int passiveInfluence = this.type.getPassiveInfluence(this.influence, this.roundsAlive, this.gameWorld.getCurrentRound()); - if (passiveInfluence > 0 && this.team.isPlayer() && this.gameWorld.getObjectInfo().existsRobot(target.ID)) { - target.addInfluenceAndConviction(passiveInfluence); - if (this.type == RobotType.SLANDERER) { - this.gameWorld.getMatchMaker().addAction(this.ID, Action.EMBEZZLE, target.ID); - } - } - - // Slanderers turn into Politicians - if (this.type == RobotType.SLANDERER && this.roundsAlive == GameConstants.CAMOUFLAGE_NUM_ROUNDS) { - this.type = RobotType.POLITICIAN; - this.gameWorld.getMatchMaker().addAction(this.ID, Action.CAMOUFLAGE, -1); - } + // anything } // ********************************* From 0d1fbf791fa80b6c147f6f0f76240fe317908e9a Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 12:24:05 -0500 Subject: [PATCH 045/413] internal-robot game constants --- .../src/main/battlecode/common/GameConstants.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index d206ac0d..cac85611 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -43,7 +43,18 @@ public class GameConstants { // ********************************* // ****** COOLDOWNS **************** // ********************************* - + + /** If the number of cooldown turns is >= this number, a robot cannot act. */ + public static final int COOLDOWN_LIMIT = 10; + + /** The number of cooldown turns reduced per turn. */ + public static final int COOLDOWNS_PER_TURN = 10; + + /** The number of cooldown turns per transformation. */ + public static final int TRANSFORM_COOLDOWN = 100; + + /** The number of cooldown turns per upgrade. */ + public static final int UPGRADE_COOLDOWN = 100; // ********************************* // ****** GAME MECHANICS *********** From 893a9246d5ebbbc08b28cad5048b0d9c80fc46f5 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 12:32:44 -0500 Subject: [PATCH 046/413] robotinfo --- .../src/main/battlecode/common/RobotInfo.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index e4415225..450ba269 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -22,6 +22,11 @@ public class RobotInfo { */ public final RobotType type; + /** + * The level of the robot. + */ + public final int level; + /** * The health of the robot. */ @@ -32,11 +37,12 @@ public class RobotInfo { */ public final MapLocation location; - public RobotInfo(int ID, Team team, RobotType type, int health, MapLocation location) { + public RobotInfo(int ID, Team team, RobotType type, int level, int health, MapLocation location) { super(); this.ID = ID; this.team = team; this.type = type; + this.level = level; this.health = health; this.location = location; } @@ -68,6 +74,15 @@ public RobotType getType() { return type; } + /** + * Returns the level of this robot. + * + * @return the level of this robot. + */ + public int getLevel() { + return level; + } + /** * Returns the health of this robot. * @@ -96,6 +111,7 @@ public boolean equals(Object o) { if (ID != robotInfo.ID) return false; if (team != robotInfo.team) return false; if (type != robotInfo.type) return false; + if (level != robotInfo.level) return false; if (health != robotInfo.health) return false; return location.equals(robotInfo.location); } @@ -106,6 +122,7 @@ public int hashCode() { result = ID; result = 31 * result + team.hashCode(); result = 31 * result + type.ordinal(); + result = 31 * result + level; result = 31 * result + health; result = 31 * result + location.hashCode(); return result; @@ -117,6 +134,7 @@ public String toString() { "ID=" + ID + ", team=" + team + ", type=" + type + + ", level=" + level + ", health=" + health + ", location=" + location + '}'; From d626586b22a532a549d73a8214bc49465d2488b8 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:10 -0500 Subject: [PATCH 047/413] Schema body types and resource drops --- schema/battlecode.fbs | 22 ++- schema/ts/battlecode_generated.ts | 236 ++++++++++++++++++++++++------ 2 files changed, 205 insertions(+), 53 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 0d432ce8..55dbb14d 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -25,16 +25,16 @@ table RGBTable { /// Note that bullets are not treated as bodies. enum BodyType : byte { - // Core unit types + // robots MINER, - ARCHON, - BUILDER, - LABORATORY, - - // Combat units GUARD, WIZARD, - TURRET + BUILDER, + + // buildings + ARCHON, + LABORATORY, + WATCHTOWER } /// A list of new bodies to be placed on the map. @@ -263,10 +263,16 @@ table Round { actionTargets: [int]; /// The IDs of the robots who changed their indicator strings - indicaortStringIDs: [int]; + indicatorStringIDs: [int]; /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; + leadDrops: VecTable; + leadDropsValues: [int]; + + goldDrops: VecTable; + goldDropsValues: [int]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 44e7be78..2bf2620b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,12 +10,12 @@ import { flatbuffers } from "./flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, - ARCHON= 1, - BUILDER= 2, - LABORATORY= 3, - GUARD= 4, - WIZARD= 5, - TURRET= 6 + GUARD= 1, + WIZARD= 2, + BUILDER= 3, + ARCHON= 4, + LABORATORY= 5, + WATCHTOWER= 6 }}; /** @@ -2741,7 +2741,7 @@ actionTargetsArray():Int32Array|null { * @param number index * @returns number */ -indicaortStringIDs(index: number):number|null { +indicatorStringIDs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2749,7 +2749,7 @@ indicaortStringIDs(index: number):number|null { /** * @returns number */ -indicaortStringIDsLength():number { +indicatorStringIDsLength():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2757,7 +2757,7 @@ indicaortStringIDsLength():number { /** * @returns Int32Array */ -indicaortStringIDsArray():Int32Array|null { +indicatorStringIDsArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2784,6 +2784,74 @@ indicatorStringsLength():number { return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 28); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +leadDropsValues(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +leadDropsValuesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +leadDropsValuesArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 32); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +goldDropsValues(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +goldDropsValuesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +goldDropsValuesArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * The IDs of bodies that set indicator dots * @@ -2791,7 +2859,7 @@ indicatorStringsLength():number { * @returns number */ indicatorDotIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2799,7 +2867,7 @@ indicatorDotIDs(index: number):number|null { * @returns number */ indicatorDotIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2807,7 +2875,7 @@ indicatorDotIDsLength():number { * @returns Int32Array */ indicatorDotIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2818,7 +2886,7 @@ indicatorDotIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 38); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2829,7 +2897,7 @@ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|nul * @returns battlecode.schema.RGBTable|null */ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); + var offset = this.bb!.__offset(this.bb_pos, 40); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2840,7 +2908,7 @@ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nul * @returns number */ indicatorLineIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2848,7 +2916,7 @@ indicatorLineIDs(index: number):number|null { * @returns number */ indicatorLineIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2856,7 +2924,7 @@ indicatorLineIDsLength():number { * @returns Int32Array */ indicatorLineIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2867,7 +2935,7 @@ indicatorLineIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 36); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2878,7 +2946,7 @@ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTab * @returns battlecode.schema.VecTable|null */ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 38); + var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2889,7 +2957,7 @@ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable * @returns battlecode.schema.RGBTable|null */ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 40); + var offset = this.bb!.__offset(this.bb_pos, 48); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2901,7 +2969,7 @@ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nu * @returns number */ roundID():number { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 50); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -2912,7 +2980,7 @@ roundID():number { * @returns number */ bytecodeIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2920,7 +2988,7 @@ bytecodeIDs(index: number):number|null { * @returns number */ bytecodeIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2928,7 +2996,7 @@ bytecodeIDsLength():number { * @returns Int32Array */ bytecodeIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2939,7 +3007,7 @@ bytecodeIDsArray():Int32Array|null { * @returns number */ bytecodesUsed(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2947,7 +3015,7 @@ bytecodesUsed(index: number):number|null { * @returns number */ bytecodesUsedLength():number { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2955,7 +3023,7 @@ bytecodesUsedLength():number { * @returns Int32Array */ bytecodesUsedArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2963,7 +3031,7 @@ bytecodesUsedArray():Int32Array|null { * @param flatbuffers.Builder builder */ static startRound(builder:flatbuffers.Builder) { - builder.startObject(22); + builder.startObject(26); }; /** @@ -3216,10 +3284,10 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicaortStringIDsOffset + * @param flatbuffers.Offset indicatorStringIDsOffset */ -static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicaortStringIDsOffset, 0); +static addIndicatorStringIDs(builder:flatbuffers.Builder, indicatorStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicatorStringIDsOffset, 0); }; /** @@ -3227,7 +3295,7 @@ static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffs * @param Array. data * @returns flatbuffers.Offset */ -static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicatorStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3239,7 +3307,7 @@ static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicaortStringIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringIDsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3272,12 +3340,86 @@ static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadDropsOffset + */ +static addLeadDrops(builder:flatbuffers.Builder, leadDropsOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, leadDropsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadDropsValuesOffset + */ +static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, leadDropsValuesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startLeadDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset goldDropsOffset + */ +static addGoldDrops(builder:flatbuffers.Builder, goldDropsOffset:flatbuffers.Offset) { + builder.addFieldOffset(14, goldDropsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset goldDropsValuesOffset + */ +static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(15, goldDropsValuesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startGoldDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + /** * @param flatbuffers.Builder builder * @param flatbuffers.Offset indicatorDotIDsOffset */ static addIndicatorDotIDs(builder:flatbuffers.Builder, indicatorDotIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, indicatorDotIDsOffset, 0); + builder.addFieldOffset(16, indicatorDotIDsOffset, 0); }; /** @@ -3306,7 +3448,7 @@ static startIndicatorDotIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorDotLocsOffset */ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, indicatorDotLocsOffset, 0); + builder.addFieldOffset(17, indicatorDotLocsOffset, 0); }; /** @@ -3314,7 +3456,7 @@ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:f * @param flatbuffers.Offset indicatorDotRGBsOffset */ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, indicatorDotRGBsOffset, 0); + builder.addFieldOffset(18, indicatorDotRGBsOffset, 0); }; /** @@ -3322,7 +3464,7 @@ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:f * @param flatbuffers.Offset indicatorLineIDsOffset */ static addIndicatorLineIDs(builder:flatbuffers.Builder, indicatorLineIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, indicatorLineIDsOffset, 0); + builder.addFieldOffset(19, indicatorLineIDsOffset, 0); }; /** @@ -3351,7 +3493,7 @@ static startIndicatorLineIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorLineStartLocsOffset */ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStartLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(16, indicatorLineStartLocsOffset, 0); + builder.addFieldOffset(20, indicatorLineStartLocsOffset, 0); }; /** @@ -3359,7 +3501,7 @@ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStart * @param flatbuffers.Offset indicatorLineEndLocsOffset */ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(17, indicatorLineEndLocsOffset, 0); + builder.addFieldOffset(21, indicatorLineEndLocsOffset, 0); }; /** @@ -3367,7 +3509,7 @@ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocs * @param flatbuffers.Offset indicatorLineRGBsOffset */ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(18, indicatorLineRGBsOffset, 0); + builder.addFieldOffset(22, indicatorLineRGBsOffset, 0); }; /** @@ -3375,7 +3517,7 @@ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset * @param number roundID */ static addRoundID(builder:flatbuffers.Builder, roundID:number) { - builder.addFieldInt32(19, roundID, 0); + builder.addFieldInt32(23, roundID, 0); }; /** @@ -3383,7 +3525,7 @@ static addRoundID(builder:flatbuffers.Builder, roundID:number) { * @param flatbuffers.Offset bytecodeIDsOffset */ static addBytecodeIDs(builder:flatbuffers.Builder, bytecodeIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(20, bytecodeIDsOffset, 0); + builder.addFieldOffset(24, bytecodeIDsOffset, 0); }; /** @@ -3412,7 +3554,7 @@ static startBytecodeIDsVector(builder:flatbuffers.Builder, numElems:number) { * @param flatbuffers.Offset bytecodesUsedOffset */ static addBytecodesUsed(builder:flatbuffers.Builder, bytecodesUsedOffset:flatbuffers.Offset) { - builder.addFieldOffset(21, bytecodesUsedOffset, 0); + builder.addFieldOffset(25, bytecodesUsedOffset, 0); }; /** @@ -3445,7 +3587,7 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicaortStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropsOffset:flatbuffers.Offset, leadDropsValuesOffset:flatbuffers.Offset, goldDropsOffset:flatbuffers.Offset, goldDropsValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); @@ -3457,8 +3599,12 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); - Round.addIndicaortStringIDs(builder, indicaortStringIDsOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); Round.addIndicatorStrings(builder, indicatorStringsOffset); + Round.addLeadDrops(builder, leadDropsOffset); + Round.addLeadDropsValues(builder, leadDropsValuesOffset); + Round.addGoldDrops(builder, goldDropsOffset); + Round.addGoldDropsValues(builder, goldDropsValuesOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From 5ba75642e97956edaeff238357e20a720a1a2d4f Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:55 -0500 Subject: [PATCH 048/413] whoops --- schema/ts/battlecode_generated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2bf2620b..9eb1644b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. From 7a9e4adf2a0cc4b7fd8a3f07503dc56cdbdecef3 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 12:48:00 -0500 Subject: [PATCH 049/413] remove ricochet attacking --- .../main/battlecode/world/InternalRobot.java | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 8d266892..74a78eed 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -345,44 +345,6 @@ public void attack(InternalRobot bot) { return; // TODO: throw exception? int dmg = this.type.getDamage(this.level); bot.addHealth(-dmg); - - int ricochetCount = this.type.getRicochetCount(this.level); - if (ricochetCount == 0) - return; - - // only wizards should execute the next chunk of code - InternalRobot[] robots = gameWorld.getAllRobotsWithinRadiusSquared(this.location, this.type.getActionRadiusSquared(this.level)); - List validTargets = new ArrayList<>(); - for (InternalRobot x : robots) { - if (x.team == this.team) - continue; - if (x.equals(bot)) - continue; - validTargets.add(x); - } - - MapLocation attackerLocation = this.location; - - class RicochetPriority implements Comparator { - public int compare(InternalRobot a, InternalRobot b) - { - int aDistToTarget = bot.location.distanceSquaredTo(a.location); - int bDistToTarget = bot.location.distanceSquaredTo(b.location); - if (aDistToTarget != bDistToTarget) - return aDistToTarget - bDistToTarget; - int aDistToAttacker = attackerLocation.distanceSquaredTo(a.location); - int bDistToAttacker = attackerLocation.distanceSquaredTo(b.location); - if (aDistToAttacker != bDistToAttacker) - return aDistToAttacker - bDistToAttacker; - return a.compareTo(b); - } - } - - Collections.sort(validTargets, new RicochetPriority()); - for (int i = 0; i < ricochetCount && i < validTargets.size(); i++) { - dmg = (int) (dmg * GameConstants.RICOCHET_DAMAGE_MULTIPLIER); - validTargets.get(i).addHealth(-dmg); - } } // ********************************* From 7948f29dffdebb348b3e424ac585f2713c53ca17 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:14:38 -0500 Subject: [PATCH 050/413] rename ROBOT to DROID in RobotMode --- engine/src/main/battlecode/common/RobotMode.java | 2 +- engine/src/main/battlecode/world/InternalRobot.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotMode.java b/engine/src/main/battlecode/common/RobotMode.java index 9673ea6d..bc0f2870 100644 --- a/engine/src/main/battlecode/common/RobotMode.java +++ b/engine/src/main/battlecode/common/RobotMode.java @@ -5,7 +5,7 @@ */ public enum RobotMode { - ROBOT (true, true), + DROID (true, true), PROTOTYPE (false, false), TURRET (true, false), PORTABLE (false, true); diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 74a78eed..7398e616 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -54,7 +54,7 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.type = type; this.location = loc; this.level = 1; - this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.ROBOT; + this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.DROID; this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.getMaxHealth(this.level)); this.controlBits = 0; @@ -323,7 +323,7 @@ public void transform() { * Upgrade a building. */ public void upgrade() { - if (this.mode == RobotMode.ROBOT || this.mode == RobotMode.PROTOTYPE) + if (this.mode == RobotMode.DROID || this.mode == RobotMode.PROTOTYPE) return; if (this.level == GameConstants.MAX_LEVEL) return; From a1d123d197f0096655503c2a720c8f25d582381f Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 13:33:29 -0500 Subject: [PATCH 051/413] gameworld changes --- client/playback/src/gameworld.ts | 163 +++++++++++++++---------------- 1 file changed, 79 insertions(+), 84 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 33e74073..aa73217e 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -6,6 +6,7 @@ import {playbackConfig} from './game'; // necessary because victor doesn't use exports.default import Victor = require('victor'); import deepcopy = require('deepcopy'); +import { indexOf } from 'core-js/library/js/array'; // TODO use Victor for representing positions export type DeadBodiesSchema = { @@ -39,10 +40,8 @@ export type MapStats = { randomSeed: number, passability: Float64Array, // double - leadLocations: [Victor]; - leadAmounts: Int32Array - goldLocations: [Victor]; - goldAmounts: Int32Array + leadVals: Int32Array; + goldVals: Int32Array; getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; @@ -52,12 +51,12 @@ export type TeamStats = { // An array of numbers corresponding to team stats, which map to RobotTypes // Corresponds to robot type (including NONE. length 5) // First four are droids (guard, wizard, builder, miner), last three are buildings (turret, archon, lab) - robots: [number, number, number, number, number[], number[], number[]], + robots: [number[], number[], number[], number[], number[], number[], number[]], lead: number, gold: number, - total_hp: [number, number, number, number, number[], number[], number[]], - lead_income: number, - gold_income: number + total_hp: [number[], number[], number[], number[], number[], number[], number[]], + leadIncome: number, + goldIncome: number }; export type IndicatorDotsSchema = { @@ -204,7 +203,7 @@ export default class GameWorld { hp: new Int32Array(0), level: new Int8Array(0), portable: new Int8Array(0), - turret: new Int8Array(0) + prototype: new Int8Array(0) }, 'id'); // Instantiate teamStats @@ -212,12 +211,12 @@ export default class GameWorld { for (let team in this.meta.teams) { var teamID = this.meta.teams[team].teamID; this.teamStats.set(teamID, { - robots: [0, 0, 0, 0, [0, 0, 0], [0, 0, 0], [0, 0, 0]], + robots: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], lead: 0, gold: 0, - total_hp: [0, 0, 0, 0, [0, 0, 0], [0, 0, 0], [0, 0, 0]], - lead_income: 0, - gold_income: 0 + total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + leadIncome: 0, + goldIncome: 0 }); } @@ -230,8 +229,8 @@ export default class GameWorld { randomSeed: 0, passability: new Float64Array(0), - lead: new Int32Array(0), - gold: new Int32Array(0), + leadVals: new Int32Array(0), + goldVals: new Int32Array(0), getIdx: (x:number, y:number) => 0, getLoc: (idx: number) => new Victor(0,0) @@ -301,15 +300,17 @@ export default class GameWorld { this.mapStats.passability = Float64Array.from(map.passabilityArray()); - const leadLocations = map.leadLocations(this._vecTableSlot1); - if (leadLocations) { - this.bodies.alterBulk({ - id: delta.movedIDsArray(), - x: movedLocs.xsArray(), - y: movedLocs.ysArray(), - }); + const leadVals = map.leadVals(this._vecTableSlot1); + if (leadVals) { + + const xs = leadVals.xsArray(); + const ys = leadVals.ysArray(); + + xs.forEach((x, i) => { + const y = ys[i] + this.mapStats.leadVals[x][y] = 1; + }) } - this.mapStats.leadLocations = Float64Array.from(map.lead()); const width = (maxCorner.x() - minCorner.x()); this.mapStats.getIdx = (x:number, y:number) => ( @@ -366,6 +367,8 @@ export default class GameWorld { statObj.lead += delta.teamLeadIncome(i); statObj.gold += delta.teamGoldIncome(i); + statObj.leadIncome = delta.teamLeadIncome(i); + statObj.goldIncome = delta.teamGoldIncome(i); this.teamStats.set(teamID, statObj); } @@ -389,7 +392,6 @@ export default class GameWorld { // Remove abilities from previous round this.bodies.alterBulk({id: new Int32Array(this.actionRobots), ability: new Int8Array(this.actionRobots.length)}); this.actionRobots = []; - this.empowered.clear(); // Remove bids from previous round this.bodies.alterBulk({id: new Int32Array(this.bidRobots), bid: new Int32Array(this.bidRobots.length)}); @@ -480,58 +482,58 @@ export default class GameWorld { } } - for (let team in this.meta.teams) { - let teamID = this.meta.teams[team].teamID; - let teamStats = this.teamStats.get(teamID) as TeamStats; - teamStats.income = 0; - } + // for (let team in this.meta.teams) { + // let teamID = this.meta.teams[team].teamID; + // let teamStats = this.teamStats.get(teamID) as TeamStats; + // teamStats.income = 0; + // } // income - this.bodies.arrays.type.forEach((type, i) => { - let robotID = this.bodies.arrays.id[i]; - let team = this.bodies.arrays.team[i]; - let ability = this.bodies.arrays.ability[i]; - let influence = this.bodies.arrays.influence[i]; - let income = this.bodies.arrays.income[i]; - let parent = this.bodies.arrays.parent[i]; - var teamStatsObj = this.teamStats.get(team); - if (ability === 3) { - let delta = Math.floor((1/50 + 0.03 * Math.exp(-0.001 * influence)) * influence); - teamStatsObj.income += delta; - this.bodies.alter({id: parent, income: delta}); - } else if (type === schema.BodyType.ENLIGHTENMENT_CENTER && teamStatsObj) { - let delta = Math.ceil(0.2 * Math.sqrt(this.turn)); - teamStatsObj.income += delta; - this.bodies.alter({id: robotID, income: delta}); - } else if (income !== 0) { - this.bodies.alter({id: robotID, income: 0}); - } - this.teamStats.set(team, teamStatsObj); - }) - - // Died bodies - if (delta.diedIDsLength() > 0) { - // Update team stats - var indices = this.bodies.lookupIndices(delta.diedIDsArray()); - for(let i = 0; i < delta.diedIDsLength(); i++) { - let index = indices[i]; - let team = this.bodies.arrays.team[index]; - let type = this.bodies.arrays.type[index]; - let statObj = this.teamStats.get(team); - if(!statObj) {continue;} // In case this is a neutral bot - statObj.robots[type] -= 1; - let influence = this.bodies.arrays.influence[index]; - let conviction = this.bodies.arrays.conviction[index]; - statObj.influence[type] -= influence; // cancel extra negative influence - statObj.conviction[type] -= conviction; // cancel extra negative conviction - this.teamStats.set(team, statObj); - } - - // Update bodies soa - this.insertDiedBodies(delta); - - this.bodies.deleteBulk(delta.diedIDsArray()); - } + // this.bodies.arrays.type.forEach((type, i) => { + // let robotID = this.bodies.arrays.id[i]; + // let team = this.bodies.arrays.team[i]; + // let ability = this.bodies.arrays.ability[i]; + // let influence = this.bodies.arrays.influence[i]; + // let income = this.bodies.arrays.income[i]; + // let parent = this.bodies.arrays.parent[i]; + // var teamStatsObj = this.teamStats.get(team); + // if (ability === 3) { + // let delta = Math.floor((1/50 + 0.03 * Math.exp(-0.001 * influence)) * influence); + // teamStatsObj.income += delta; + // this.bodies.alter({id: parent, income: delta}); + // } else if (type === schema.BodyType.ENLIGHTENMENT_CENTER && teamStatsObj) { + // let delta = Math.ceil(0.2 * Math.sqrt(this.turn)); + // teamStatsObj.income += delta; + // this.bodies.alter({id: robotID, income: delta}); + // } else if (income !== 0) { + // this.bodies.alter({id: robotID, income: 0}); + // } + // this.teamStats.set(team, teamStatsObj); + // }) + + // // Died bodies + // if (delta.diedIDsLength() > 0) { + // // Update team stats + // var indices = this.bodies.lookupIndices(delta.diedIDsArray()); + // for(let i = 0; i < delta.diedIDsLength(); i++) { + // let index = indices[i]; + // let team = this.bodies.arrays.team[index]; + // let type = this.bodies.arrays.type[index]; + // let statObj = this.teamStats.get(team); + // if(!statObj) {continue;} // In case this is a neutral bot + // statObj.robots[type] -= 1; + // let influence = this.bodies.arrays.influence[index]; + // let conviction = this.bodies.arrays.conviction[index]; + // statObj.influence[type] -= influence; // cancel extra negative influence + // statObj.conviction[type] -= conviction; // cancel extra negative conviction + // this.teamStats.set(team, statObj); + // } + + // // Update bodies soa + // this.insertDiedBodies(delta); + + // this.bodies.deleteBulk(delta.diedIDsArray()); + // } // Insert indicator dots and lines this.insertIndicatorDots(delta); @@ -632,16 +634,13 @@ export default class GameWorld { // Store frequently used arrays var teams = bodies.teamIDsArray(); var types = bodies.typesArray(); - var influences = bodies.influencesArray(); - var convictions: Int32Array = influences.map((influence, i) => Math.ceil(influence * this.meta.types[types[i]].convictionRatio)); //new Int32Array(bodies.robotIDsLength()); // Update spawn stats for(let i = 0; i < bodies.robotIDsLength(); i++) { - if(teams[i] == 0) continue; + // if(teams[i] == 0) continue; var statObj = this.teamStats.get(teams[i]); - statObj.robots[types[i]] += 1; - statObj.influence[types[i]] += influences[i]; - statObj.conviction[types[i]] += convictions[i]; + statObj.robots[types[i]][1] += 1; // TODO: handle level + statObj.total_hp[types[i]][1] += 3000; // TODO: extract meta info this.teamStats.set(teams[i], statObj); } @@ -660,8 +659,6 @@ export default class GameWorld { id: bodies.robotIDsArray(), team: teams, type: types, - influence: influences, - conviction: convictions, x: locs.xsArray(), y: locs.ysArray(), flag: new Int32Array(bodies.robotIDsLength()), @@ -741,6 +738,4 @@ export default class GameWorld { } this.logs.push(roundLogs); } - - } From 3144cc416c7fca119a7807180c5476780ac5bbc7 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:06 -0500 Subject: [PATCH 052/413] preliminary engine feedback --- schema/battlecode.fbs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 55dbb14d..1347def8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -25,11 +25,11 @@ table RGBTable { /// Note that bullets are not treated as bodies. enum BodyType : byte { - // robots + // droids MINER, - GUARD, - WIZARD, BUILDER, + SOLDIER, + SAGE, // buildings ARCHON, @@ -68,11 +68,11 @@ table GameMap { /// The factor to divide cooldowns by passability: [double]; - //lead locations + // lead locations // a vectable of lead cords leadLocations: VecTable; - //inital lead amounts + // inital lead amounts leadAmounts: [double]; } @@ -110,14 +110,15 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; actionCooldown: float; - movingCooldown: float; + movementCooldown: float; bytecodeLimit: int; dps: int; // dps at lowest level hp: int; // hp at lowest level dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level buildCost: int; - upgradeCosts: [int]; + upgradeCostLead: [int]; + upgradeCostGold: [int]; } /// Data relevant to a particular team. @@ -240,8 +241,8 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLeadIncome: [int]; - teamGoldIncome: [int]; + teamLeadChange: [int]; + teamGoldChange: [int]; /// The IDs of bodies that moved. movedIDs: [int]; @@ -267,11 +268,11 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; - leadDrops: VecTable; - leadDropsValues: [int]; + leadDropLocations: VecTable; + leadDropValues: [int]; - goldDrops: VecTable; - goldDropsValues: [int]; + goldDropLocations: VecTable; + goldDropValues: [int]; /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; From 8344692b1355f37fff4155c7beb9538d5e1b26d1 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:49 -0500 Subject: [PATCH 053/413] regenerate ts file --- schema/ts/battlecode_generated.ts | 187 +++++++++++++++++++----------- 1 file changed, 121 insertions(+), 66 deletions(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 9eb1644b..63d97fbf 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,9 +10,9 @@ import { flatbuffers } from "flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, - GUARD= 1, - WIZARD= 2, - BUILDER= 3, + BUILDER= 1, + SOLDIER= 2, + SAGE= 3, ARCHON= 4, LABORATORY= 5, WATCHTOWER= 6 @@ -1127,7 +1127,7 @@ actionCooldown():number { /** * @returns number */ -movingCooldown():number { +movementCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 14); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1184,7 +1184,7 @@ buildCost():number { * @param number index * @returns number */ -upgradeCosts(index: number):number|null { +upgradeCostLead(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -1192,7 +1192,7 @@ upgradeCosts(index: number):number|null { /** * @returns number */ -upgradeCostsLength():number { +upgradeCostLeadLength():number { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -1200,16 +1200,41 @@ upgradeCostsLength():number { /** * @returns Int32Array */ -upgradeCostsArray():Int32Array|null { +upgradeCostLeadArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * @param number index + * @returns number + */ +upgradeCostGold(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +upgradeCostGoldLength():number { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +upgradeCostGoldArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(13); + builder.startObject(14); }; /** @@ -1254,10 +1279,10 @@ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { /** * @param flatbuffers.Builder builder - * @param number movingCooldown + * @param number movementCooldown */ -static addMovingCooldown(builder:flatbuffers.Builder, movingCooldown:number) { - builder.addFieldFloat32(5, movingCooldown, 0.0); +static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) { + builder.addFieldFloat32(5, movementCooldown, 0.0); }; /** @@ -1310,10 +1335,39 @@ static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostsOffset + * @param flatbuffers.Offset upgradeCostLeadOffset + */ +static addUpgradeCostLead(builder:flatbuffers.Builder, upgradeCostLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, upgradeCostLeadOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createUpgradeCostLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startUpgradeCostLeadVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset upgradeCostGoldOffset */ -static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, upgradeCostsOffset, 0); +static addUpgradeCostGold(builder:flatbuffers.Builder, upgradeCostGoldOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, upgradeCostGoldOffset, 0); }; /** @@ -1321,7 +1375,7 @@ static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffe * @param Array. data * @returns flatbuffers.Offset */ -static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createUpgradeCostGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -1333,7 +1387,7 @@ static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uin * @param flatbuffers.Builder builder * @param number numElems */ -static startUpgradeCostsVector(builder:flatbuffers.Builder, numElems:number) { +static startUpgradeCostGoldVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -1346,21 +1400,22 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); + BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); BodyTypeMetadata.addHpMul(builder, hpMul); BodyTypeMetadata.addBuildCost(builder, buildCost); - BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); + BodyTypeMetadata.addUpgradeCostLead(builder, upgradeCostLeadOffset); + BodyTypeMetadata.addUpgradeCostGold(builder, upgradeCostGoldOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } } @@ -2531,7 +2586,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -teamLeadIncome(index: number):number|null { +teamLeadChange(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2539,7 +2594,7 @@ teamLeadIncome(index: number):number|null { /** * @returns number */ -teamLeadIncomeLength():number { +teamLeadChangeLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2547,7 +2602,7 @@ teamLeadIncomeLength():number { /** * @returns Int32Array */ -teamLeadIncomeArray():Int32Array|null { +teamLeadChangeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2556,7 +2611,7 @@ teamLeadIncomeArray():Int32Array|null { * @param number index * @returns number */ -teamGoldIncome(index: number):number|null { +teamGoldChange(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2564,7 +2619,7 @@ teamGoldIncome(index: number):number|null { /** * @returns number */ -teamGoldIncomeLength():number { +teamGoldChangeLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2572,7 +2627,7 @@ teamGoldIncomeLength():number { /** * @returns Int32Array */ -teamGoldIncomeArray():Int32Array|null { +teamGoldChangeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2788,7 +2843,7 @@ indicatorStringsLength():number { * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ -leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { +leadDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2797,7 +2852,7 @@ leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -leadDropsValues(index: number):number|null { +leadDropValues(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2805,7 +2860,7 @@ leadDropsValues(index: number):number|null { /** * @returns number */ -leadDropsValuesLength():number { +leadDropValuesLength():number { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2813,7 +2868,7 @@ leadDropsValuesLength():number { /** * @returns Int32Array */ -leadDropsValuesArray():Int32Array|null { +leadDropValuesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2822,7 +2877,7 @@ leadDropsValuesArray():Int32Array|null { * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ -goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { +goldDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2831,7 +2886,7 @@ goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -goldDropsValues(index: number):number|null { +goldDropValues(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2839,7 +2894,7 @@ goldDropsValues(index: number):number|null { /** * @returns number */ -goldDropsValuesLength():number { +goldDropValuesLength():number { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2847,7 +2902,7 @@ goldDropsValuesLength():number { /** * @returns Int32Array */ -goldDropsValuesArray():Int32Array|null { +goldDropValuesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3065,10 +3120,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadIncomeOffset + * @param flatbuffers.Offset teamLeadChangeOffset */ -static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadIncomeOffset, 0); +static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadChangeOffset, 0); }; /** @@ -3076,7 +3131,7 @@ static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3088,16 +3143,16 @@ static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadChangeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldIncomeOffset + * @param flatbuffers.Offset teamGoldChangeOffset */ -static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldIncomeOffset, 0); +static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldChangeOffset, 0); }; /** @@ -3105,7 +3160,7 @@ static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3117,7 +3172,7 @@ static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldChangeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3342,18 +3397,18 @@ static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropsOffset + * @param flatbuffers.Offset leadDropLocationsOffset */ -static addLeadDrops(builder:flatbuffers.Builder, leadDropsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, leadDropsOffset, 0); +static addLeadDropLocations(builder:flatbuffers.Builder, leadDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, leadDropLocationsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropsValuesOffset + * @param flatbuffers.Offset leadDropValuesOffset */ -static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, leadDropsValuesOffset, 0); +static addLeadDropValues(builder:flatbuffers.Builder, leadDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, leadDropValuesOffset, 0); }; /** @@ -3361,7 +3416,7 @@ static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:fla * @param Array. data * @returns flatbuffers.Offset */ -static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3373,24 +3428,24 @@ static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | * @param flatbuffers.Builder builder * @param number numElems */ -static startLeadDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropsOffset + * @param flatbuffers.Offset goldDropLocationsOffset */ -static addGoldDrops(builder:flatbuffers.Builder, goldDropsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, goldDropsOffset, 0); +static addGoldDropLocations(builder:flatbuffers.Builder, goldDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(14, goldDropLocationsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropsValuesOffset + * @param flatbuffers.Offset goldDropValuesOffset */ -static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, goldDropsValuesOffset, 0); +static addGoldDropValues(builder:flatbuffers.Builder, goldDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(15, goldDropValuesOffset, 0); }; /** @@ -3398,7 +3453,7 @@ static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:fla * @param Array. data * @returns flatbuffers.Offset */ -static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createGoldDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3410,7 +3465,7 @@ static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | * @param flatbuffers.Builder builder * @param number numElems */ -static startGoldDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startGoldDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3587,11 +3642,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropsOffset:flatbuffers.Offset, leadDropsValuesOffset:flatbuffers.Offset, goldDropsOffset:flatbuffers.Offset, goldDropsValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangeOffset:flatbuffers.Offset, teamGoldChangeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); - Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); + Round.addTeamLeadChange(builder, teamLeadChangeOffset); + Round.addTeamGoldChange(builder, teamGoldChangeOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); @@ -3601,10 +3656,10 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionTargets(builder, actionTargetsOffset); Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); Round.addIndicatorStrings(builder, indicatorStringsOffset); - Round.addLeadDrops(builder, leadDropsOffset); - Round.addLeadDropsValues(builder, leadDropsValuesOffset); - Round.addGoldDrops(builder, goldDropsOffset); - Round.addGoldDropsValues(builder, goldDropsValuesOffset); + Round.addLeadDropLocations(builder, leadDropLocationsOffset); + Round.addLeadDropValues(builder, leadDropValuesOffset); + Round.addGoldDropLocations(builder, goldDropLocationsOffset); + Round.addGoldDropValues(builder, goldDropValuesOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From ca0749508f295327baf3c39574b8a1bcc81a6e24 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 13 Nov 2021 09:48:37 -0500 Subject: [PATCH 054/413] Added new RobotType variables, functions, GameConstants. --- .../main/battlecode/common/GameConstants.java | 46 +++ .../src/main/battlecode/common/RobotType.java | 330 +++++++++++------- 2 files changed, 249 insertions(+), 127 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index cac85611..65b43f74 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -63,6 +63,52 @@ public class GameConstants { /** A prototype building's starting health, as a multiplier of max health. */ public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; + // NEED TO CHANGE: what is the actual cooldown value for the following values: + + public static final int BUILDING_UPGRADE_COOLDOWN = 500; + public static final float FRESH_ROBOT_ARCHON_COOLDOWN = 10f; + // turret to portable, or portable to turret + public static final int BUILDING_CONVERSION_COOLDOWN = 10000; + + + // ********************************* + // ****** LEVEL MULTIPLIERS ******** + // ********************************* + + public static final float PLACEHOLDER_LEVEL_MULTIPLIER = 1.2f; + + public static final float DPS_1_TO_2 = PLACEHOLDER_LEVEL_MULTIPLIER; + public static final float HP_1_TO_2 = PLACEHOLDER_LEVEL_MULTIPLIER; + + public static final float DPS_2_TO_3 = PLACEHOLDER_LEVEL_MULTIPLIER; + public static final float HP_2_TO_3 = PLACEHOLDER_LEVEL_MULTIPLIER; + + public static final float DPS_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; + public static final float HP_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; + + // NEED TO CHANGE: + // turret vision = unit vision + ??? + // building portable mode move cooldown = ??? + + public static final float RICOCHET_UPGRADE_MULTIPLIER = 1.5f; + public static final float BUILDING_UPGRADE_COST_MULTIPLER = 0.5f; + + // ********************************* + // ****** GAME MECHANICS *********** + // ********************************* + + public static final float PROTOTYPE_HP_PERCENTAGE = 0.1f; + public static final float AUTOMATIC_ARCHON_HEAL_AMOUNT = 10f; + public static final float AUTOMATIC_BUILDER_HEAL_AMOUNT = 10f; + + public static final float PER_ALCHEMIST_DECREASE_RATE = 0.1f; + + public static final int LEAD_TO_GOLD_RATE = 20; + public static final int INITIAL_LEAD = 200; + + + // Older constants below, maintaining them for now. + /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 4e2e8952..4bbf2b80 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -1,96 +1,168 @@ package battlecode.common; +/** +* Contains the two currency types for supporting robot build costs. +*/ +public enum CurrencyType { + AU, PB +} + +/** +* Contains the Building levels. +*/ +public enum BuildingLevel { + PROTOTYPE, TURRET, PORTABLE +} + /** * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ + +PLACEHOLDER_ACTION_RADIUS = 100; +PLACEHOLDER_VISION_RADIUS = 100; +PLACEHOLDER_BYTECODE_LIMIT = 7500; +NO_COOLDOWN_CLOCK = 10000000; + public enum RobotType { - // spawnSource, convictionRatio, actionCooldown, initialCooldown, actionRadiusSquared, sensorRadiusSquared, detectionRadiusSquared, bytecodeLimit + // Build Cost Amount, Build Cost Type (one of "Pb" or "Au"), Action Cooldown, Move Cooldown + // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit, IsBuilding, RicochetCount + /** - * Enlightenment Centers produce various types of robots, as well as - * passively generate influence and bid for votes each round. Can be - * converted by Politicians. - * + * Archons are portable buildings that heal and generate robots. + * Losing all archons means losing the game. + * * @battlecode.doc.robottype */ - ENLIGHTENMENT_CENTER (null, 1, 2, 0, 2, 40, 40, 20000), - // SS CR AC IC AR SR DR BL + ARCHON (250, CurrencyType.AU, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB /** - * Politicians Empower adjacent units, strengthening friendly robots, - * converting enemy Politicians and Enlightenment Centers, and destroying - * enemy Slanderers and Muckrakers with their impassioned speeches. + * A lead robot + * Can mine gold or lead at their or an adjacent location. * * @battlecode.doc.robottype */ - POLITICIAN (ENLIGHTENMENT_CENTER, 1, 1, 10, 9, 25, 25, 15000), - // SS CR AC IC AR SR DR BL + MINER ( 50, CurrencyType.PB, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC /** - * Slanderers passively generate influence for their parent Enlightenment - * Center each round. They are camoflauged as Politicians to enemy units. - * Can be converted by Politicians. + * A lead robot + * Can build, repair, and upgrade non-Archon buildings. * * @battlecode.doc.robottype */ - SLANDERER (ENLIGHTENMENT_CENTER, 1, 2, 0, 0, 20, 20, 7500), - // SS CR AC IC AR SR DR BL + BUILDER ( 40, CurrencyType.PB, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC /** - * Muckrakers search the map for enemy Slanderers to Expose, which destroys - * the Slanderer and gives a buff to their team. + * Alchemist's laboratory + * Converts lead into gold * * @battlecode.doc.robottype */ - MUCKRAKER (ENLIGHTENMENT_CENTER, 0.7f, 1.5f, 10, 12, 30, 40, 15000), - // SS CR AC IC AR SR DR BL - ; + LABORATORY (800, CurrencyType.PB, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB, RC + + /** + * Lead attacking robot, low-range, medium-damage. + */ + GUARD ( 75, CurrencyType.PB, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC /** - * For units, this is the structure that spawns it. For non-spawnable robots, this is null. + * Lead attacking robot, high-range, low-damage. + */ + ARCHER ( 75, CurrencyType.PB, 10, 15, 20, 80, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + + /** + * Gold robot, medium-range, high-damage. */ - public final RobotType spawnSource; + WIZARD ( 50, CurrencyType.AU, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + + /** + * Guard turret + */ + // NEED TO CHANGE: These are placeholder values only + GUARD_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC /** - * The ratio of influence to apply when determining the - * robot's conviction. + * Archer turret + */ + // NEED TO CHANGE: These are placeholder values only + ARCHER_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + + /** + * Wizard turret + * Has upgradeable ricochet count. + */ + // NEED TO CHANGE: These are placeholder values only + WIZARD_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 2), + // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + ; + + /** + * Cost to build a given robot or building. */ - public final float convictionRatio; + public final float buildCostAmount; /** - * Cooldown turns for how long before a robot can take - * action (Build/Move/Empower/Expose) again. + * Type of currency for build cost amount. */ - public final float actionCooldown; + public final float buildCostType; + + /** + * Action cooldown. + */ + public final int actionCooldown; /** - * Initial cooldown turns when a robot is built. + * Move cooldown. */ - public final float initialCooldown; + public final int moveCooldown; /** - * Radius squared range of robots' abilities. For Politicians, this is - * the AoE range of their Empower ability. For Muckrakers, this is - * from how far they can Expose a Slanderer. + * Damage per second for each robot in Level 1. + */ + public final float DPSLv1; + + /** + * Initial health per robot for Level 1. + */ + public final float HPLv1; + + /** + * Radius range of robots' abilities. */ public final int actionRadiusSquared; /** - * The radius squared range in which the robot can sense another - * robot's information. For Politicians, Slanderers, and - * Enlightenment Centers, this is the same as their detection - * radius squared. For Muckrakers, slightly reduced. + * The radius range in which the robot can sense another + * robot's information. */ - public final int sensorRadiusSquared; + public final int visionRadiusSquared; /** - * The radius squared range in which the robot can detect the presence - * of other robots. + * How much of the build cost can be reclaimed. */ - public final int detectionRadiusSquared; + public final double reclaimCostPercentage; /** * Base bytecode limit of this robot. */ public final int bytecodeLimit; + /** + * Whether this is a Building. + */ + public final boolean isBuilding; + + /** + * Ricochet count. + */ + public final int ricochetCount; + /** * Returns whether the type can build robots of the specified type. * @@ -102,128 +174,132 @@ public boolean canBuild(RobotType type) { } /** - * Returns whether the type can distinguish slanderers and politicians. - * - * @return whether the type can distinguish slanderers and politicians. + * Returns the max HP for a robot by level. + * @param level of the robot + * @return the max HP for a robot by level. */ - public boolean canTrueSense() { - return this == ENLIGHTENMENT_CENTER || this == MUCKRAKER; + public int getMaxHealth(int level){ + + int health = type.HPLv1; + if(level >= 2) + health *= GameConstants.HP1_TO_2; + if(level == 3) + health *= GameConstants.HP_2_TO_3; + + // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + return (int)health; + // end code + } /** - * Returns whether the type can apply a teamwide buff. - * - * @return whether the type can apply a teamwide buff + * Returns the starting HP for a robot by level. + * @param level of the robot + * @return the starting HP for a robot by level. */ - public boolean canBuffTeam() { - return this == MUCKRAKER; + public int getStartingHealth(int level){ + // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + return (int) (type.HPLv1 * GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER); + // end code } /** - * Returns whether the type can move. - * - * @return whether the type can move + * @return the squared action radius. */ - public boolean canMove() { - return this == POLITICIAN || this == SLANDERER || this == MUCKRAKER; + public int getActionRadiusSquared(int level){ + return this.actionRadiusSquared; } /** - * Returns whether the type can Empower adjacent units. - * - * @return whether the type can Empower adjacent units + * @return the squared vision radius. */ - public boolean canEmpower() { - return this == POLITICIAN; + public int getVisionRadiusSquared(int level){ + return this.visionRadiusSquared; } /** - * Returns whether the type can camouflage themselves. - * - * @return whether the type can camouflage themselves + * @param level + * @return the DPS for a robot by level. */ - public boolean canCamouflage() { - return this == SLANDERER; + public int getDamage(int level){ + + int dps = type.DPSLv1; + if(level >= 2) + dps *= GameConstants.DPS1_TO_2; + if(level == 3) + dps *= GameConstants.DPS_2_TO_3; + + // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + return (int) dps; + // end code } /** - * Returns whether the type can Expose nearby robots. - * - * @return whether the type can Expose nearby robots + * @param level + * @return the ricochet count by level, controlled by a multiplier and rounded down. */ - public boolean canExpose() { - return this == MUCKRAKER; + public int getRicochetCount(int level){ + // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level)); + // end code } /** - * Returns whether the type can be Exposed. - * - * @return whether the type can be Exposed - */ - public boolean canBeExposed() { - return this == SLANDERER; + * @return whether or not a given robot is a building. + */ + public boolean isBuilding(){ + return this.isBuilding; } /** - * Returns whether the type can be converted to the other team. - * - * @return whether the type can be converted to the other team + * @param level of destroyed building. + * @return the amount of lead dropped, based on a multiplier by level. */ - public boolean canBeConverted() { - return this == ENLIGHTENMENT_CENTER || this == POLITICIAN; + public int getLeadDropped(){ + if(this.buildCostType != CurrencyType.PB) return 0; + return this.getCurrencyDropped(); } /** - * Returns whether the type can submit a bid. - * - * @return whether the type can submit a bid + * @param level of destroyed building. + * @return the amount of gold dropped, based on a multiplier by level. */ - public boolean canBid() { - return this == ENLIGHTENMENT_CENTER; + public int getGoldDropped(){ + if(this.buildCostType != CurrencyType.AU) return 0; + return this.getCurrencyDropped(); } /** - * Returns the influence cost for building a robot with a particular conviction. + * Calculates the total cost of a building based on level/upgrade multiplier. + * @param level of destroyed building + * @return amount of currency dropped by building for the building's build currency type. + Will be modified by getGoldDropped or getLeadDropped to access the right currency. */ - public int getInfluenceCostForConviction(int conviction) { - int influence = (int) (conviction / this.convictionRatio); - while (Math.ceil(this.convictionRatio * (influence - 1)) >= conviction) - influence--; - return influence; + private int getCurrencyDropped(int level){ + // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + return (int) (this.buildCostAmount * Math.pow(BUILDING_UPGRADE_COST_MULTIPLIER, level)); + // end code } - /** - * Returns the amount of passive influence that this robot generates. - * - * @param robotInfluence the amount of influence that this robot has - * @param roundsAlive the number of rounds the robot has been alive for - * @param roundNum the round number - */ - public int getPassiveInfluence(int robotInfluence, int roundsAlive, int roundNum) { - switch (this) { - case ENLIGHTENMENT_CENTER: - return (int) Math.ceil(GameConstants.PASSIVE_INFLUENCE_RATIO_ENLIGHTENMENT_CENTER * Math.sqrt(roundNum)); - case SLANDERER: - if (roundsAlive <= GameConstants.EMBEZZLE_NUM_ROUNDS) - return (int) (robotInfluence * - (1.0 / GameConstants.EMBEZZLE_NUM_ROUNDS + - GameConstants.EMBEZZLE_SCALE_FACTOR * Math.exp(-GameConstants.EMBEZZLE_DECAY_FACTOR * robotInfluence))); - return 0; - default: - return 0; - } - } + RobotType(int buildCostAmount, CurrencyType buildCostType, + int actionCooldown, int moveCooldown, + int DPSLv1, int HPLv1, + int actionRadiusSquared, int visionRadiusSquared, + float reclaimCostPercentage, int bytecodeLimit, boolean isBuilding, + int ricochetCount) { - RobotType(RobotType spawnSource, float convictionRatio, float actionCooldown, float initialCooldown, - int actionRadiusSquared, int sensorRadiusSquared, int detectionRadiusSquared, - int bytecodeLimit) { - this.spawnSource = spawnSource; - this.convictionRatio = convictionRatio; - this.actionCooldown = actionCooldown; - this.initialCooldown = initialCooldown; - this.actionRadiusSquared = actionRadiusSquared; - this.sensorRadiusSquared = sensorRadiusSquared; - this.detectionRadiusSquared = detectionRadiusSquared; - this.bytecodeLimit = bytecodeLimit; + this.buildCostAmount = buildCostAmount; + this.buildCostType = buildCostType; + this.actionCooldown = actionCooldown; + this.moveCooldown = moveCooldown; + this.DPSLv1 = DPSLv1; + this.HPLv1 = HPLv1; + this.actionRadiusSquared = actionRadiusSquared; + this.visionRadiusSquared = visionRadiusSquared; + this.reclaimCostPercentage = reclaimCostPercentage; + this.bytecodeLimit = bytecodeLimit; + this.isBuilding = isBuilding; + this.ricochetCount = ricochetCount; } + } From aea8a29514356ef37be9f0d9895b9931d5f4c318 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 13 Nov 2021 12:00:56 -0500 Subject: [PATCH 055/413] Moved richocet upgrade multiplier. --- engine/src/main/battlecode/common/GameConstants.java | 2 -- engine/src/main/battlecode/common/RobotType.java | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 65b43f74..58778c78 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -70,7 +70,6 @@ public class GameConstants { // turret to portable, or portable to turret public static final int BUILDING_CONVERSION_COOLDOWN = 10000; - // ********************************* // ****** LEVEL MULTIPLIERS ******** // ********************************* @@ -90,7 +89,6 @@ public class GameConstants { // turret vision = unit vision + ??? // building portable mode move cooldown = ??? - public static final float RICOCHET_UPGRADE_MULTIPLIER = 1.5f; public static final float BUILDING_UPGRADE_COST_MULTIPLER = 0.5f; // ********************************* diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 4bbf2b80..7ba8742a 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -239,6 +239,7 @@ public int getDamage(int level){ * @return the ricochet count by level, controlled by a multiplier and rounded down. */ public int getRicochetCount(int level){ + int RICOCHET_UPGRADE_MULTIPLIER = 1.5; // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level)); // end code From bca4386d4f0881ab6f05e6bb6d20f23c65318d41 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 20 Nov 2021 09:30:26 -0500 Subject: [PATCH 056/413] Revert "Moved richocet upgrade multiplier." This reverts commit 6f5f4be172226177705167b285dbc0ac11948b93. --- engine/src/main/battlecode/common/RobotType.java | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 7ba8742a..4bbf2b80 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -239,7 +239,6 @@ public int getDamage(int level){ * @return the ricochet count by level, controlled by a multiplier and rounded down. */ public int getRicochetCount(int level){ - int RICOCHET_UPGRADE_MULTIPLIER = 1.5; // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level)); // end code From fcfeb3070ae0cd9c5c7e8909ca5859c35ac39385 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 20 Nov 2021 09:52:51 -0500 Subject: [PATCH 057/413] Most changes from code review applied. --- .../main/battlecode/common/GameConstants.java | 7 +- .../src/main/battlecode/common/RobotType.java | 193 ++++++++---------- 2 files changed, 92 insertions(+), 108 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 58778c78..ab4964d5 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -36,6 +36,7 @@ public class GameConstants { /** The bytecode penalty that is imposed each time an exception is thrown. */ public static final int EXCEPTION_BYTECODE_PENALTY = 500; + ///** Maximum ID a Robot will have */ //public static final int MAX_ROBOT_ID = 32000; Cannot be guaranteed in Battlecode 2021. @@ -63,7 +64,7 @@ public class GameConstants { /** A prototype building's starting health, as a multiplier of max health. */ public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; - // NEED TO CHANGE: what is the actual cooldown value for the following values: + // TODO: what is the actual cooldown value for the following values: public static final int BUILDING_UPGRADE_COOLDOWN = 500; public static final float FRESH_ROBOT_ARCHON_COOLDOWN = 10f; @@ -85,7 +86,7 @@ public class GameConstants { public static final float DPS_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; public static final float HP_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; - // NEED TO CHANGE: + // TODO // turret vision = unit vision + ??? // building portable mode move cooldown = ??? @@ -103,6 +104,8 @@ public class GameConstants { public static final int LEAD_TO_GOLD_RATE = 20; public static final int INITIAL_LEAD = 200; + + public static final float RECLAIM_COST_PERCENTAGE = 0.2; // Older constants below, maintaining them for now. diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 4bbf2b80..44b3b632 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -7,13 +7,6 @@ public enum CurrencyType { AU, PB } -/** -* Contains the Building levels. -*/ -public enum BuildingLevel { - PROTOTYPE, TURRET, PORTABLE -} - /** * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ @@ -25,8 +18,8 @@ public enum BuildingLevel { public enum RobotType { - // Build Cost Amount, Build Cost Type (one of "Pb" or "Au"), Action Cooldown, Move Cooldown - // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit, IsBuilding, RicochetCount + // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown + // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit, RicochetCount /** * Archons are portable buildings that heal and generate robots. @@ -34,83 +27,83 @@ public enum RobotType { * * @battlecode.doc.robottype */ - ARCHON (250, CurrencyType.AU, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB + ARCHON (0, 250, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC, BL /** * A lead robot * Can mine gold or lead at their or an adjacent location. * * @battlecode.doc.robottype */ - MINER ( 50, CurrencyType.PB, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + MINER ( 50, 0, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * A lead robot * Can build, repair, and upgrade non-Archon buildings. * * @battlecode.doc.robottype */ - BUILDER ( 40, CurrencyType.PB, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + BUILDER ( 40, 0, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL,BCG, AC MC DPS HP AR VR RCP RC BL /** * Alchemist's laboratory * Converts lead into gold * * @battlecode.doc.robottype */ - LABORATORY (800, CurrencyType.PB, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB, RC + LABORATORY (800, 0, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * Lead attacking robot, low-range, medium-damage. */ - GUARD ( 75, CurrencyType.PB, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + GUARD ( 75, 0, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * Lead attacking robot, high-range, low-damage. */ - ARCHER ( 75, CurrencyType.PB, 10, 15, 20, 80, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + ARCHER ( 75, 0, 10, 15, 20, 80, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * Gold robot, medium-range, high-damage. */ - WIZARD ( 50, CurrencyType.AU, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT, false, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + WIZARD ( 0, 50, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * Guard turret */ - // NEED TO CHANGE: These are placeholder values only - GUARD_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + // TODO These are placeholder values only + GUARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCA, BCG, AC MC DPS HP AR VR RCP RC BL /** * Archer turret */ - // NEED TO CHANGE: These are placeholder values only - ARCHER_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 0), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + // TODO These are placeholder values only + ARCHER_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP RC BL /** * Wizard turret * Has upgradeable ricochet count. */ - // NEED TO CHANGE: These are placeholder values only - WIZARD_TURRET ( 50, CurrencyType.PB, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT, true, 2), - // BCA, BCT, AC MC DPS HP AR VR RCP BL IB RC + // TODO These are placeholder values only + WIZARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 2, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL RC ; /** - * Cost to build a given robot or building. + * Lead cost to build a given robot or building */ - public final float buildCostAmount; + public final int buildCostLead; /** - * Type of currency for build cost amount. + * Gold cost to build a given robot or building */ - public final float buildCostType; + public final int buildCostGold; /** * Action cooldown. @@ -144,24 +137,43 @@ public enum RobotType { public final int visionRadiusSquared; /** - * How much of the build cost can be reclaimed. + * Base bytecode limit of this robot. */ - public final double reclaimCostPercentage; + public final int bytecodeLimit; /** - * Base bytecode limit of this robot. + * Ricochet count. */ - public final int bytecodeLimit; + public final int ricochetCount; /** - * Whether this is a Building. + * @return the squared action radius. */ - public final boolean isBuilding; + public int getActionRadiusSquared(int level) { + return this.actionRadiusSquared; + } /** - * Ricochet count. + * @return the squared vision radius. */ - public final int ricochetCount; + public int getVisionRadiusSquared(int level) { + return this.visionRadiusSquared; + } + + + /** + * @return whether or not a given robot is a building. + */ + public boolean isBuilding() { + return ( + this == ARCHON + || this == LABORATORY + || this == GUARD_TURRET + || this == ARCHER_TURRET + || this == WIZARD_TURRET + ); + } + /** * Returns whether the type can build robots of the specified type. @@ -178,17 +190,14 @@ public boolean canBuild(RobotType type) { * @param level of the robot * @return the max HP for a robot by level. */ - public int getMaxHealth(int level){ - + public int getMaxHealth(int level) { int health = type.HPLv1; if(level >= 2) health *= GameConstants.HP1_TO_2; if(level == 3) health *= GameConstants.HP_2_TO_3; - // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp - return (int)health; - // end code + return (int) health; } @@ -197,31 +206,15 @@ public int getMaxHealth(int level){ * @param level of the robot * @return the starting HP for a robot by level. */ - public int getStartingHealth(int level){ - // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp + public int getStartingHealth(int level) { return (int) (type.HPLv1 * GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER); - // end code - } - - /** - * @return the squared action radius. - */ - public int getActionRadiusSquared(int level){ - return this.actionRadiusSquared; - } - - /** - * @return the squared vision radius. - */ - public int getVisionRadiusSquared(int level){ - return this.visionRadiusSquared; } /** * @param level * @return the DPS for a robot by level. */ - public int getDamage(int level){ + public int getDamage(int level) { int dps = type.DPSLv1; if(level >= 2) @@ -229,77 +222,65 @@ public int getDamage(int level){ if(level == 3) dps *= GameConstants.DPS_2_TO_3; - // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp return (int) dps; - // end code } /** * @param level * @return the ricochet count by level, controlled by a multiplier and rounded down. */ - public int getRicochetCount(int level){ - // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp - return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level)); - // end code + public int getRicochetCount(int level) { + return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level - 1)); } - /** - * @return whether or not a given robot is a building. - */ - public boolean isBuilding(){ - return this.isBuilding; - } /** - * @param level of destroyed building. + * @param level * @return the amount of lead dropped, based on a multiplier by level. */ - public int getLeadDropped(){ - if(this.buildCostType != CurrencyType.PB) return 0; - return this.getCurrencyDropped(); + public int getLeadWorth(int level) { + return this.getCurrencyWorth(this.buildCostLead, level); } /** - * @param level of destroyed building. + * @param level * @return the amount of gold dropped, based on a multiplier by level. */ - public int getGoldDropped(){ - if(this.buildCostType != CurrencyType.AU) return 0; - return this.getCurrencyDropped(); + public int getGoldWorth(int level) { + return this.getCurrencyDropped(this.buildCostGold, level); } /** * Calculates the total cost of a building based on level/upgrade multiplier. - * @param level of destroyed building - * @return amount of currency dropped by building for the building's build currency type. - Will be modified by getGoldDropped or getLeadDropped to access the right currency. + * @param level + * @param baseWorth to build the building + * @return worth of building in the currency */ - private int getCurrencyDropped(int level){ - // 11/13/21: https://www.w3schools.com/java/java_type_casting.asp - return (int) (this.buildCostAmount * Math.pow(BUILDING_UPGRADE_COST_MULTIPLIER, level)); - // end code + private int getCurrencyWorth(int baseWorth, int level) { + return (int) (this.buildCostAmount * Math.pow(BUILDING_UPGRADE_COST_MULTIPLIER, level - 1)); + } + + public int getLeadDropped(int level) { + } - RobotType(int buildCostAmount, CurrencyType buildCostType, - int actionCooldown, int moveCooldown, - int DPSLv1, int HPLv1, - int actionRadiusSquared, int visionRadiusSquared, - float reclaimCostPercentage, int bytecodeLimit, boolean isBuilding, - int ricochetCount) { + public int getGoldDropped(int level) { - this.buildCostAmount = buildCostAmount; - this.buildCostType = buildCostType; + } + + RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, + int DPSLv1, int HPLv1, int actionRadiusSquared, int visionRadiusSquared, int ricochetCount, int bytecodeLimit) { + + this.buildCostLead = buildCostLead; + this.buildCostGold = buildCostGold; this.actionCooldown = actionCooldown; this.moveCooldown = moveCooldown; this.DPSLv1 = DPSLv1; this.HPLv1 = HPLv1; this.actionRadiusSquared = actionRadiusSquared; this.visionRadiusSquared = visionRadiusSquared; - this.reclaimCostPercentage = reclaimCostPercentage; - this.bytecodeLimit = bytecodeLimit; - this.isBuilding = isBuilding; this.ricochetCount = ricochetCount; + this.bytecodeLimit = bytecodeLimit; } -} +} \ No newline at end of file From 5b8e617b46cc8bb39a3480642e9f554e11b43e43 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 20 Nov 2021 12:29:09 -0500 Subject: [PATCH 058/413] initial changes for revisions --- .../main/battlecode/common/GameConstants.java | 3 - .../src/main/battlecode/common/RobotType.java | 155 ++++++++---------- 2 files changed, 72 insertions(+), 86 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index ab4964d5..be223bd5 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -105,9 +105,6 @@ public class GameConstants { public static final int LEAD_TO_GOLD_RATE = 20; public static final int INITIAL_LEAD = 200; - public static final float RECLAIM_COST_PERCENTAGE = 0.2; - - // Older constants below, maintaining them for now. /** The maximum level a building can be. */ diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 44b3b632..a74ad418 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -1,12 +1,5 @@ package battlecode.common; -/** -* Contains the two currency types for supporting robot build costs. -*/ -public enum CurrencyType { - AU, PB -} - /** * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ @@ -19,7 +12,7 @@ public enum CurrencyType { public enum RobotType { // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown - // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit, RicochetCount + // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit /** * Archons are portable buildings that heal and generate robots. @@ -27,72 +20,52 @@ public enum RobotType { * * @battlecode.doc.robottype */ - ARCHON (0, 250, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC, BL + ARCHON ( 0, 250, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL /** * A lead robot * Can mine gold or lead at their or an adjacent location. * * @battlecode.doc.robottype */ - MINER ( 50, 0, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL + MINER ( 50, 0, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL /** * A lead robot * Can build, repair, and upgrade non-Archon buildings. * * @battlecode.doc.robottype */ - BUILDER ( 40, 0, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL,BCG, AC MC DPS HP AR VR RCP RC BL + BUILDER ( 40, 0, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL,BCG, AC MC DPS HP AR VR RCP BL /** * Alchemist's laboratory * Converts lead into gold * * @battlecode.doc.robottype */ - LABORATORY (800, 0, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL + LABORATORY (800, 0, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL /** * Lead attacking robot, low-range, medium-damage. */ - GUARD ( 75, 0, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL + GUARD ( 75, 0, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL - /** - * Lead attacking robot, high-range, low-damage. - */ - ARCHER ( 75, 0, 10, 15, 20, 80, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL - /** * Gold robot, medium-range, high-damage. */ - WIZARD ( 0, 50, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL + WIZARD ( 0, 50, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL /** * Guard turret */ // TODO These are placeholder values only - GUARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCA, BCG, AC MC DPS HP AR VR RCP RC BL + GUARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), + // BCA, BCG, AC MC DPS HP AR VR RCP BL - /** - * Archer turret - */ - // TODO These are placeholder values only - ARCHER_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP RC BL - - /** - * Wizard turret - * Has upgradeable ricochet count. - */ - // TODO These are placeholder values only - WIZARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, 2, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL RC ; /** @@ -141,11 +114,6 @@ public enum RobotType { */ public final int bytecodeLimit; - /** - * Ricochet count. - */ - public final int ricochetCount; - /** * @return the squared action radius. */ @@ -169,22 +137,9 @@ public boolean isBuilding() { this == ARCHON || this == LABORATORY || this == GUARD_TURRET - || this == ARCHER_TURRET - || this == WIZARD_TURRET ); } - - /** - * Returns whether the type can build robots of the specified type. - * - * @param type the RobotType to be built - * @return whether the type can build robots of the specified type - */ - public boolean canBuild(RobotType type) { - return this == type.spawnSource; - } - /** * Returns the max HP for a robot by level. * @param level of the robot @@ -225,51 +180,85 @@ public int getDamage(int level) { return (int) dps; } + // COST RELATED FUNCTIONS + /** - * @param level - * @return the ricochet count by level, controlled by a multiplier and rounded down. + * @param level to upgrade to + * @return cost to upgrade (lead if level -> 2, gold if level -> 3) + */ + public int getUpgradeCost(int level) { + Map toLevel2 = new HashMap(); + toLevel2.put(RobotType.ARCHON, 2500); + toLevel2.put(RobotType.LABORATORY, 400); + toLevel2.put(RobotType.GUARD_TURRET, 25); + + Map toLevel3 = new HashMap(); + toLevel3.put(RobotType.ARCHON, 5000); + toLevel3.put(RobotType.LABORATORY, 800); + toLevel3.put(RobotType.GUARD_TURRET, 50); + + if (level == 1) return 0; + if (level == 2) return toLevel2.get(this); + // otherwise, level 3 + return toLevel3.get(this); + } + + /** + * @param level to upgrade to + * @return lead component of cost to upgrade. */ - public int getRicochetCount(int level) { - return (int) (this.ricochetCount * Math.pow(GameConstants.RICOCHET_UPGRADE_MULTIPLIER, level - 1)); + public int getLeadUpgradeCost(int level) { + if (level == 2) return getUpgradeCost(level); + return 0; } /** - * @param level - * @return the amount of lead dropped, based on a multiplier by level. + * @param level to upgrade to + * @return gold component of cost to upgrade. + */ + public int getGoldUpgradeCost(int level) { + if (level == 3) return getUpgradeCost(level); + return 0; + } + + /** + * @param level, current + * @return lead component of worth */ public int getLeadWorth(int level) { - return this.getCurrencyWorth(this.buildCostLead, level); + int total = this.buildCostLead; + if(level >= 2) total += getLeadUpgradeCost(level); + return total; } /** - * @param level - * @return the amount of gold dropped, based on a multiplier by level. + * @param level, current + * @return gold component of worth */ public int getGoldWorth(int level) { - return this.getCurrencyDropped(this.buildCostGold, level); + int total = this.buildCostGold; + if(level == 3) total += getGoldUpgradeCost(level); + return total; } /** - * Calculates the total cost of a building based on level/upgrade multiplier. - * @param level - * @param baseWorth to build the building - * @return worth of building in the currency + * @param level, current */ - private int getCurrencyWorth(int baseWorth, int level) { - return (int) (this.buildCostAmount * Math.pow(BUILDING_UPGRADE_COST_MULTIPLIER, level - 1)); + public int getGoldDropped(int level) { + int total = getLeadWorth() * reclaimCostPercentage; } + /** + * @param level, current + */ public int getLeadDropped(int level) { - - } - - public int getGoldDropped(int level) { - + int total = getGoldWorth() * reclaimCostPercentage; } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, - int DPSLv1, int HPLv1, int actionRadiusSquared, int visionRadiusSquared, int ricochetCount, int bytecodeLimit) { + int DPSLv1, int HPLv1, int actionRadiusSquared, int visionRadiusSquared, float reclaimCostPercentage, + int ricochetCount, int bytecodeLimit) { this.buildCostLead = buildCostLead; this.buildCostGold = buildCostGold; @@ -279,7 +268,7 @@ public int getGoldDropped(int level) { this.HPLv1 = HPLv1; this.actionRadiusSquared = actionRadiusSquared; this.visionRadiusSquared = visionRadiusSquared; - this.ricochetCount = ricochetCount; + this.reclaimCostPercentage = reclaimCostPercentage; this.bytecodeLimit = bytecodeLimit; } From 2dada3aa32f90f45d6a380d0ea309cc4f6ab5ca4 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 20 Nov 2021 12:33:51 -0500 Subject: [PATCH 059/413] Initial changes for revision, gradle does not succeed --- engine/src/main/battlecode/common/RobotType.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index a74ad418..7ce76631 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -212,7 +212,6 @@ public int getLeadUpgradeCost(int level) { return 0; } - /** * @param level to upgrade to * @return gold component of cost to upgrade. @@ -246,14 +245,14 @@ public int getGoldWorth(int level) { * @param level, current */ public int getGoldDropped(int level) { - int total = getLeadWorth() * reclaimCostPercentage; + int total = getGoldWorth() * reclaimCostPercentage; } /** * @param level, current */ public int getLeadDropped(int level) { - int total = getGoldWorth() * reclaimCostPercentage; + int total = getLeadWorth() * reclaimCostPercentage; } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, From 617503b1e231dd6fd060c6245f3b97505de04461 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 20 Nov 2021 13:06:34 -0500 Subject: [PATCH 060/413] Does not run on gradle, added Andy's changes from the other branch. --- .../src/main/battlecode/common/RobotType.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 7ce76631..31e2dfb1 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -4,13 +4,14 @@ * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ -PLACEHOLDER_ACTION_RADIUS = 100; -PLACEHOLDER_VISION_RADIUS = 100; -PLACEHOLDER_BYTECODE_LIMIT = 7500; -NO_COOLDOWN_CLOCK = 10000000; - public enum RobotType { + public final int PLACEHOLDER_ACTION_RADIUS = 100; + public final int PLACEHOLDER_VISION_RADIUS = 100; + public final int PLACEHOLDER_BYTECODE_LIMIT = 7500; + public final int NO_COOLDOWN_CLOCK = 10000000; + + // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit @@ -20,8 +21,8 @@ public enum RobotType { * * @battlecode.doc.robottype */ - ARCHON ( 0, 250, 10, NO_COOLDOWN_CLOCK, -5, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL + ARCHON ( 0, 250, 10, NO_COOLDOWN_CLOCK, -AUTOMATIC_ARCHON_HEAL_AMOUNT, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), + // BCL, BCG, AC MC DPS HP AR VR RCP BL /** * A lead robot * Can mine gold or lead at their or an adjacent location. @@ -36,8 +37,8 @@ public enum RobotType { * * @battlecode.doc.robottype */ - BUILDER ( 40, 0, 10, 10, -10, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL,BCG, AC MC DPS HP AR VR RCP BL + BUILDER ( 40, 0, 10, 10, -AUTOMATIC_BUILDER_HEAL_AMOUNT, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), + // BCL,BCG, AC MC DPS HP AR VR RCP BL /** * Alchemist's laboratory * Converts lead into gold @@ -180,6 +181,20 @@ public int getDamage(int level) { return (int) dps; } + /** + * @param level + * @return the healing per turn for a robot by level. + */ + public int getHealing(int level){ + int hps = -type.DPSLv1; + if(level >= 2) + hps *= GameConstants.HPS1_TO_2; + if(level >= 3) + hps *= GameConstants.HPS_2_TO_3; + + return (int) hps; + } + // COST RELATED FUNCTIONS /** @@ -269,6 +284,7 @@ public int getLeadDropped(int level) { this.visionRadiusSquared = visionRadiusSquared; this.reclaimCostPercentage = reclaimCostPercentage; this.bytecodeLimit = bytecodeLimit; + } } \ No newline at end of file From 7f7819190d6bde23583e4cd283637ad4f46237a9 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 4 Dec 2021 11:58:22 -0500 Subject: [PATCH 061/413] Fixing one set of errors related to syntax. --- engine/src/main/battlecode/common/RobotType.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 31e2dfb1..c1cb2081 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -4,14 +4,19 @@ * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ -public enum RobotType { - public final int PLACEHOLDER_ACTION_RADIUS = 100; - public final int PLACEHOLDER_VISION_RADIUS = 100; - public final int PLACEHOLDER_BYTECODE_LIMIT = 7500; - public final int NO_COOLDOWN_CLOCK = 10000000; +public class TemporaryConstants{ + + public static int PLACEHOLDER_ACTION_RADIUS = 100; + public static int PLACEHOLDER_VISION_RADIUS = 100; + public static int PLACEHOLDER_BYTECODE_LIMIT = 7500; + public static int NO_COOLDOWN_CLOCK = 10000000; + +} +public enum RobotType { + // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit From 3fce884300e53de7706476d6af2aae796937af8a Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 4 Dec 2021 13:37:57 -0500 Subject: [PATCH 062/413] Need to check compile, but changes done for new design. --- .../main/battlecode/common/GameConstants.java | 14 +- .../src/main/battlecode/common/RobotType.java | 197 ++++++++---------- 2 files changed, 90 insertions(+), 121 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index be223bd5..aa79228e 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -9,6 +9,7 @@ public class GameConstants { /** * The current spec version the server compiles with. */ + public static final String SPEC_VERSION = "1.0"; // ********************************* @@ -37,10 +38,6 @@ public class GameConstants { /** The bytecode penalty that is imposed each time an exception is thrown. */ public static final int EXCEPTION_BYTECODE_PENALTY = 500; - - ///** Maximum ID a Robot will have */ - //public static final int MAX_ROBOT_ID = 32000; Cannot be guaranteed in Battlecode 2021. - // ********************************* // ****** COOLDOWNS **************** // ********************************* @@ -69,7 +66,8 @@ public class GameConstants { public static final int BUILDING_UPGRADE_COOLDOWN = 500; public static final float FRESH_ROBOT_ARCHON_COOLDOWN = 10f; // turret to portable, or portable to turret - public static final int BUILDING_CONVERSION_COOLDOWN = 10000; + public static final int BUILDING_CONVERSION_COOLDOWN = 10; + public static final float BUILDING_UPGRADE_COST_MULTIPLER = 0.5f; // ********************************* // ****** LEVEL MULTIPLIERS ******** @@ -90,8 +88,6 @@ public class GameConstants { // turret vision = unit vision + ??? // building portable mode move cooldown = ??? - public static final float BUILDING_UPGRADE_COST_MULTIPLER = 0.5f; - // ********************************* // ****** GAME MECHANICS *********** // ********************************* @@ -104,15 +100,13 @@ public class GameConstants { public static final int LEAD_TO_GOLD_RATE = 20; public static final int INITIAL_LEAD = 200; + public static final float PROTOTYPE_HP_PERCENTAGE = 0.9f; // Older constants below, maintaining them for now. /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; - /** The amount damage is reduced by every ricochet. */ - public static final float RICOCHET_DAMAGE_MULTIPLIER = 0.8f; - // ********************************* // ****** GAMEPLAY PROPERTIES ****** // ********************************* diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index c1cb2081..425820d4 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -5,72 +5,57 @@ */ -public class TemporaryConstants{ - - public static int PLACEHOLDER_ACTION_RADIUS = 100; - public static int PLACEHOLDER_VISION_RADIUS = 100; - public static int PLACEHOLDER_BYTECODE_LIMIT = 7500; - public static int NO_COOLDOWN_CLOCK = 10000000; - -} - - public enum RobotType { // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown - // DPS Lv1, HP Lv1, Action Radius (squared), Vision Radius (squared), Reclaim Cost Percentage, Bytecode Limit + // HP Lv1, DPS Lv1, Action Radius (squared), Vision Radius (squared), Bytecode Limit /** * Archons are portable buildings that heal and generate robots. * Losing all archons means losing the game. * - * @battlecode.doc.robottype - */ - ARCHON ( 0, 250, 10, NO_COOLDOWN_CLOCK, -AUTOMATIC_ARCHON_HEAL_AMOUNT, 700, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL + * @battlecode.doc.robot */ + ARCHON ( 0, 250, 10, 24, 1000, -2, 20, 34, 20000), + // BCL BCG AC MC HP DPS AR VR BL + /** - * A lead robot - * Can mine gold or lead at their or an adjacent location. + * Alchemist's laboratory + * Converts lead into gold * - * @battlecode.doc.robottype - */ - MINER ( 50, 0, 2, 10, 0, 40, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL + * @battlecode.doc.robot */ + LABORATORY (800, 0, 10, 24, 130, 5, 20, 34, 10000), + // BCL BCG AC MC HP DPS AR VR BL + + /** + * Guard turret + */ + WATCHTOWER ( 180, 0, 10, 24, 130, 5, 20, 34, 10000), + // BCL BCG AC MC HP DPS AR VR BL + /** - * A lead robot - * Can build, repair, and upgrade non-Archon buildings. + * Can mine gold or lead at their or an adjacent location. * - * @battlecode.doc.robottype - */ - BUILDER ( 40, 0, 10, 10, -AUTOMATIC_BUILDER_HEAL_AMOUNT, 30, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL,BCG, AC MC DPS HP AR VR RCP BL + * @battlecode.doc.robot */ + MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), + // BCL, BCG, AC MC HP DPS AR VR BL /** - * Alchemist's laboratory - * Converts lead into gold + * Can build and repair buildings. * - * @battlecode.doc.robottype - */ - LABORATORY (800, 0, 10, NO_COOLDOWN_CLOCK, 0, 500, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL - + * @battlecode.doc.robot */ + BUILDER ( 40, 0, 10, 20, 30, -1, 5, 20, 7500), + // BCL BCG AC MC HP DPS AR VR BL + /** - * Lead attacking robot, low-range, medium-damage. + * Ranged attacking robot. */ - GUARD ( 75, 0, 10, 20, 35, 120, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL + SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), + // BCL BCG AC MC HP DPS AR VR BL /** - * Gold robot, medium-range, high-damage. + * Gold robot, causes Anomalies. */ - WIZARD ( 0, 50, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0, PLACEHOLDER_BYTECODE_LIMIT), - // BCL, BCG, AC MC DPS HP AR VR RCP BL - - /** - * Guard turret - */ - // TODO These are placeholder values only - GUARD_TURRET ( 50, 0, 20, 20, 75, 70, PLACEHOLDER_ACTION_RADIUS, PLACEHOLDER_VISION_RADIUS, 0.2, PLACEHOLDER_BYTECODE_LIMIT), - // BCA, BCG, AC MC DPS HP AR VR RCP BL + SAGE ( 0, 50,200, 25, 45, 100, 13, 20, 10000) + // BCL BCG AC MC HP DPS AR VR BL ; @@ -80,7 +65,7 @@ public enum RobotType { public final int buildCostLead; /** - * Gold cost to build a given robot or building + * Gold cost to build a given robot or building (except for Archon's) */ public final int buildCostGold; @@ -95,14 +80,14 @@ public enum RobotType { public final int moveCooldown; /** - * Damage per second for each robot in Level 1. + * Initial health per robot for Level 1. */ - public final float DPSLv1; - + public final int HPLv1; + /** - * Initial health per robot for Level 1. + * Damage per second for each robot in Level 1. */ - public final float HPLv1; + public final float DPSLv1; /** * Radius range of robots' abilities. @@ -152,14 +137,19 @@ public boolean isBuilding() { * @return the max HP for a robot by level. */ public int getMaxHealth(int level) { - int health = type.HPLv1; - if(level >= 2) - health *= GameConstants.HP1_TO_2; - if(level == 3) - health *= GameConstants.HP_2_TO_3; - - return (int) health; - + if(this.isBuilding() || level == 1) return this.HPLv1; + if(this == RobotType.ARCHON){ + if(level == 2) return 1100; + if(level == 3) return 1200; + } + if(this == RobotType.LABORATORY){ + if(level == 2) return 110; + if(level == 3) return 120; + } + if(this == RobotType.WATCHTOWER){ + if(level == 2) return 143; + if(level == 3) return 156; + } } /** @@ -168,7 +158,7 @@ public int getMaxHealth(int level) { * @return the starting HP for a robot by level. */ public int getStartingHealth(int level) { - return (int) (type.HPLv1 * GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER); + return (int) (this.HPLv1 * GameConstants.PROTOTYPE_HP_PERCENTAGE); } /** @@ -177,13 +167,21 @@ public int getStartingHealth(int level) { */ public int getDamage(int level) { - int dps = type.DPSLv1; - if(level >= 2) - dps *= GameConstants.DPS1_TO_2; - if(level == 3) - dps *= GameConstants.DPS_2_TO_3; - - return (int) dps; + if(this.isBuilding() || level == 1 || this == RobotType.LABORATORY) + return this.HPLv1; + + if(this == RobotType.ARCHON){ + if(level == 2) return 3; + if(level == 3) return 4; + } + if(this == RobotType.LABORATORY){ + return 0; + } + if(this == RobotType.WATCHTOWER){ + if(level == 2) return 6; + if(level == 3) return 7; + } + } /** @@ -191,44 +189,18 @@ public int getDamage(int level) { * @return the healing per turn for a robot by level. */ public int getHealing(int level){ - int hps = -type.DPSLv1; - if(level >= 2) - hps *= GameConstants.HPS1_TO_2; - if(level >= 3) - hps *= GameConstants.HPS_2_TO_3; - - return (int) hps; + if(this != RobotType.ARCHON || this != RobotType.BUILDER) return 0; + return (int)(-1 * this.DPSLv1); } // COST RELATED FUNCTIONS - /** - * @param level to upgrade to - * @return cost to upgrade (lead if level -> 2, gold if level -> 3) - */ - public int getUpgradeCost(int level) { - Map toLevel2 = new HashMap(); - toLevel2.put(RobotType.ARCHON, 2500); - toLevel2.put(RobotType.LABORATORY, 400); - toLevel2.put(RobotType.GUARD_TURRET, 25); - - Map toLevel3 = new HashMap(); - toLevel3.put(RobotType.ARCHON, 5000); - toLevel3.put(RobotType.LABORATORY, 800); - toLevel3.put(RobotType.GUARD_TURRET, 50); - - if (level == 1) return 0; - if (level == 2) return toLevel2.get(this); - // otherwise, level 3 - return toLevel3.get(this); - } - /** * @param level to upgrade to * @return lead component of cost to upgrade. */ public int getLeadUpgradeCost(int level) { - if (level == 2) return getUpgradeCost(level); + if (level == 2) return 600; return 0; } @@ -237,7 +209,7 @@ public int getLeadUpgradeCost(int level) { * @return gold component of cost to upgrade. */ public int getGoldUpgradeCost(int level) { - if (level == 3) return getUpgradeCost(level); + if (level == 3) return 100; return 0; } @@ -246,9 +218,7 @@ public int getGoldUpgradeCost(int level) { * @return lead component of worth */ public int getLeadWorth(int level) { - int total = this.buildCostLead; - if(level >= 2) total += getLeadUpgradeCost(level); - return total; + return this.buildCostLead + this.getLeadUpgradeCost(level); } /** @@ -256,38 +226,43 @@ public int getLeadWorth(int level) { * @return gold component of worth */ public int getGoldWorth(int level) { - int total = this.buildCostGold; - if(level == 3) total += getGoldUpgradeCost(level); - return total; + return this.buildCostGold + this.getGoldUpgradeCost(level); + } + + /** + * @return Reclaim cost percentage for when robot is destroyed. + */ + public int getReclaimCostPercentage(){ + return (this.isBuilding()) ? 0.2 : 0; } /** * @param level, current */ public int getGoldDropped(int level) { - int total = getGoldWorth() * reclaimCostPercentage; + int total = (int) (this.getGoldWorth(level) * this.reclaimCostPercentage); } /** * @param level, current */ public int getLeadDropped(int level) { - int total = getLeadWorth() * reclaimCostPercentage; + int total = (int) (this.getLeadWorth(level) * this.reclaimCostPercentage); } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, - int DPSLv1, int HPLv1, int actionRadiusSquared, int visionRadiusSquared, float reclaimCostPercentage, - int ricochetCount, int bytecodeLimit) { + int HPLv1, int DPSLv1, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { this.buildCostLead = buildCostLead; this.buildCostGold = buildCostGold; this.actionCooldown = actionCooldown; this.moveCooldown = moveCooldown; - this.DPSLv1 = DPSLv1; this.HPLv1 = HPLv1; + this.DPSLv1 = DPSLv1; + this.actionRadiusSquared = actionRadiusSquared; this.visionRadiusSquared = visionRadiusSquared; - this.reclaimCostPercentage = reclaimCostPercentage; + this.bytecodeLimit = bytecodeLimit; } From 8b2d30fbe849129ac5bb1a5e799346169f79f31c Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Sat, 4 Dec 2021 14:02:01 -0500 Subject: [PATCH 063/413] One error remaining related to float/double conversion, unsure how to fix. --- .../src/main/battlecode/common/RobotType.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 425820d4..520d8d69 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -29,15 +29,15 @@ public enum RobotType { /** * Guard turret */ - WATCHTOWER ( 180, 0, 10, 24, 130, 5, 20, 34, 10000), - // BCL BCG AC MC HP DPS AR VR BL + WATCHTOWER (180, 0, 10, 24, 130, 5, 20, 34, 10000), + // BCL BCG AC MC HP DPS AR VR BL /** * Can mine gold or lead at their or an adjacent location. * * @battlecode.doc.robot */ MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), - // BCL, BCG, AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DPS AR VR BL /** * Can build and repair buildings. * @@ -49,7 +49,7 @@ public enum RobotType { * Ranged attacking robot. */ SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DPS AR VR BL /** * Gold robot, causes Anomalies. @@ -87,7 +87,7 @@ public enum RobotType { /** * Damage per second for each robot in Level 1. */ - public final float DPSLv1; + public final int DPSLv1; /** * Radius range of robots' abilities. @@ -127,7 +127,7 @@ public boolean isBuilding() { return ( this == ARCHON || this == LABORATORY - || this == GUARD_TURRET + || this == WATCHTOWER ); } @@ -232,22 +232,22 @@ public int getGoldWorth(int level) { /** * @return Reclaim cost percentage for when robot is destroyed. */ - public int getReclaimCostPercentage(){ - return (this.isBuilding()) ? 0.2 : 0; + public float getReclaimCostPercentage(){ + return (this.isBuilding()) ? 0.2f : 0; } /** * @param level, current */ public int getGoldDropped(int level) { - int total = (int) (this.getGoldWorth(level) * this.reclaimCostPercentage); + int total = (int) (this.getGoldWorth(level) * this.getReclaimCostPercentage()); } /** * @param level, current */ public int getLeadDropped(int level) { - int total = (int) (this.getLeadWorth(level) * this.reclaimCostPercentage); + int total = (int) (this.getLeadWorth(level) * this.getReclaimCostPercentage()); } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, From 87a9a6b16b8d2f34039722aa7c72ea996ad5062f Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Fri, 10 Dec 2021 05:45:35 -0500 Subject: [PATCH 064/413] lol --- .../main/battlecode/common/GameConstants.java | 44 +---- .../src/main/battlecode/common/RobotType.java | 164 +++++++++--------- 2 files changed, 82 insertions(+), 126 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index aa79228e..0d6da9bf 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -9,7 +9,6 @@ public class GameConstants { /** * The current spec version the server compiles with. */ - public static final String SPEC_VERSION = "1.0"; // ********************************* @@ -61,48 +60,11 @@ public class GameConstants { /** A prototype building's starting health, as a multiplier of max health. */ public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; - // TODO: what is the actual cooldown value for the following values: - - public static final int BUILDING_UPGRADE_COOLDOWN = 500; - public static final float FRESH_ROBOT_ARCHON_COOLDOWN = 10f; - // turret to portable, or portable to turret - public static final int BUILDING_CONVERSION_COOLDOWN = 10; - public static final float BUILDING_UPGRADE_COST_MULTIPLER = 0.5f; - - // ********************************* - // ****** LEVEL MULTIPLIERS ******** - // ********************************* - - public static final float PLACEHOLDER_LEVEL_MULTIPLIER = 1.2f; - - public static final float DPS_1_TO_2 = PLACEHOLDER_LEVEL_MULTIPLIER; - public static final float HP_1_TO_2 = PLACEHOLDER_LEVEL_MULTIPLIER; - - public static final float DPS_2_TO_3 = PLACEHOLDER_LEVEL_MULTIPLIER; - public static final float HP_2_TO_3 = PLACEHOLDER_LEVEL_MULTIPLIER; - - public static final float DPS_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; - public static final float HP_UNIT_TO_TURRET = PLACEHOLDER_LEVEL_MULTIPLIER; - - // TODO - // turret vision = unit vision + ??? - // building portable mode move cooldown = ??? - - // ********************************* - // ****** GAME MECHANICS *********** - // ********************************* - + /** The amount of health a prototype building has as a multiplier. */ public static final float PROTOTYPE_HP_PERCENTAGE = 0.1f; - public static final float AUTOMATIC_ARCHON_HEAL_AMOUNT = 10f; - public static final float AUTOMATIC_BUILDER_HEAL_AMOUNT = 10f; - - public static final float PER_ALCHEMIST_DECREASE_RATE = 0.1f; - - public static final int LEAD_TO_GOLD_RATE = 20; - public static final int INITIAL_LEAD = 200; - public static final float PROTOTYPE_HP_PERCENTAGE = 0.9f; - // Older constants below, maintaining them for now. + /** The multiplier for reclaiming a building's cost. */ + public static final float RECLAIM_COST_MULTIPLIER = 0.2f; /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 520d8d69..7907c724 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -7,8 +7,8 @@ public enum RobotType { - // Build Cost Lead, Build Cost Gold, Action Cooldown, Move Cooldown - // HP Lv1, DPS Lv1, Action Radius (squared), Vision Radius (squared), Bytecode Limit + // Build Cost Lead, Build Cost Gold, Action Cooldown, Movement Cooldown + // Health (level 1), Damage (level 1), Action Radius (squared), Vision Radius (squared), Bytecode Limit /** * Archons are portable buildings that heal and generate robots. @@ -16,7 +16,7 @@ public enum RobotType { * * @battlecode.doc.robot */ ARCHON ( 0, 250, 10, 24, 1000, -2, 20, 34, 20000), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DMG AR VR BL /** * Alchemist's laboratory @@ -24,39 +24,38 @@ public enum RobotType { * * @battlecode.doc.robot */ LABORATORY (800, 0, 10, 24, 130, 5, 20, 34, 10000), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DMG AR VR BL /** * Guard turret */ WATCHTOWER (180, 0, 10, 24, 130, 5, 20, 34, 10000), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DMG AR VR BL /** * Can mine gold or lead at their or an adjacent location. * * @battlecode.doc.robot */ - MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), - // BCL BCG AC MC HP DPS AR VR BL + MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), + // BCL BCG AC MC HP DMG AR VR BL /** * Can build and repair buildings. * * @battlecode.doc.robot */ BUILDER ( 40, 0, 10, 20, 30, -1, 5, 20, 7500), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DMG AR VR BL /** * Ranged attacking robot. */ SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), - // BCL BCG AC MC HP DPS AR VR BL + // BCL BCG AC MC HP DMG AR VR BL /** * Gold robot, causes Anomalies. */ SAGE ( 0, 50,200, 25, 45, 100, 13, 20, 10000) - // BCL BCG AC MC HP DPS AR VR BL - + // BCL BCG AC MC HP DMG AR VR BL ; /** @@ -75,19 +74,19 @@ public enum RobotType { public final int actionCooldown; /** - * Move cooldown. + * Movement cooldown. */ - public final int moveCooldown; + public final int movementCooldown; /** * Initial health per robot for Level 1. */ - public final int HPLv1; + public final int health; /** - * Damage per second for each robot in Level 1. + * Damage for each robot in Level 1. */ - public final int DPSLv1; + public final int damage; /** * Radius range of robots' abilities. @@ -101,27 +100,26 @@ public enum RobotType { public final int visionRadiusSquared; /** - * Base bytecode limit of this robot. + * Base bytecode limit of this robot */ public final int bytecodeLimit; /** - * @return the squared action radius. + * @return the squared action radius */ public int getActionRadiusSquared(int level) { return this.actionRadiusSquared; } /** - * @return the squared vision radius. + * @return the squared vision radius */ public int getVisionRadiusSquared(int level) { return this.visionRadiusSquared; } - /** - * @return whether or not a given robot is a building. + * @return whether or not a given robot is a building */ public boolean isBuilding() { return ( @@ -132,139 +130,135 @@ public boolean isBuilding() { } /** - * Returns the max HP for a robot by level. + * Returns the max health of a robot by level. * @param level of the robot - * @return the max HP for a robot by level. + * @return the max health of a robot by level */ public int getMaxHealth(int level) { - if(this.isBuilding() || level == 1) return this.HPLv1; - if(this == RobotType.ARCHON){ - if(level == 2) return 1100; - if(level == 3) return 1200; - } - if(this == RobotType.LABORATORY){ - if(level == 2) return 110; - if(level == 3) return 120; - } - if(this == RobotType.WATCHTOWER){ - if(level == 2) return 143; - if(level == 3) return 156; + if (!this.isBuilding() || level == 1) { + return this.health; + } else if (this == ARCHON) { + return level == 2 ? 1100 : 1200; + } else if (this == LABORATORY) { + return level == 2 ? 110 : 120; + } else { + return level == 2 ? 143 : 156; } } /** - * Returns the starting HP for a robot by level. + * Returns the starting health of a robot by level. * @param level of the robot - * @return the starting HP for a robot by level. + * @return the starting health of a robot by level */ public int getStartingHealth(int level) { - return (int) (this.HPLv1 * GameConstants.PROTOTYPE_HP_PERCENTAGE); + return (int) (this.health * this.isBuilding() ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1); } /** + * Returns the damage of a robot by level. * @param level - * @return the DPS for a robot by level. + * @return the damage for a robot by level */ public int getDamage(int level) { - - if(this.isBuilding() || level == 1 || this == RobotType.LABORATORY) - return this.HPLv1; - - if(this == RobotType.ARCHON){ - if(level == 2) return 3; - if(level == 3) return 4; - } - if(this == RobotType.LABORATORY){ + if (!this.isBuilding() || level == 1) { + return this.damage; + } else if (this == RobotType.ARCHON) { + return level == 2 ? 3 : 4; + } else if (this == RobotType.LABORATORY) { return 0; + } else { + return level == 2 ? 6 : 7; } - if(this == RobotType.WATCHTOWER){ - if(level == 2) return 6; - if(level == 3) return 7; - } - } /** * @param level - * @return the healing per turn for a robot by level. + * @return the healing per turn for a robot by level */ - public int getHealing(int level){ - if(this != RobotType.ARCHON || this != RobotType.BUILDER) return 0; - return (int)(-1 * this.DPSLv1); + public int getHealing(int level) { + if (this == ARCHON || this == BUILDER) { + return (int) (-1 * this.getDamage(level)); + } else { + return 0; + } } // COST RELATED FUNCTIONS /** - * @param level to upgrade to - * @return lead component of cost to upgrade. + * @param level the level to upgrade to + * @return lead component of cost to upgrade */ public int getLeadUpgradeCost(int level) { - if (level == 2) return 600; - return 0; + return level == 2 ? 600 : 0; } /** - * @param level to upgrade to + * @param level the level to upgrade to * @return gold component of cost to upgrade. */ public int getGoldUpgradeCost(int level) { - if (level == 3) return 100; - return 0; + return level == 3 ? 100 : 0; } /** - * @param level, current + * @param level the robot's current level * @return lead component of worth */ public int getLeadWorth(int level) { - return this.buildCostLead + this.getLeadUpgradeCost(level); + int leadWorth = this.buildCostLead; + for (int i = 2; i <= level; i++) { + leadWorth += this.getLeadUpgradeCost(i); + } + return leadWorth; } /** - * @param level, current + * @param level the robot's current level * @return gold component of worth */ public int getGoldWorth(int level) { - return this.buildCostGold + this.getGoldUpgradeCost(level); + int goldWorth = this.buildCostGold; + for (int i = 2; i <= level; i++) { + goldWorth += this.getGoldUpgradeCost(i); + } + return goldWorth; } /** * @return Reclaim cost percentage for when robot is destroyed. */ - public float getReclaimCostPercentage(){ + public float getReclaimCostPercentage() { return (this.isBuilding()) ? 0.2f : 0; } /** - * @param level, current + * @param level the robot's current level + * @return the amount of lead dropped */ - public int getGoldDropped(int level) { - int total = (int) (this.getGoldWorth(level) * this.getReclaimCostPercentage()); + public int getLeadDropped(int level) { + return this.isBuilding() ? (int) (this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER) : 0; } /** - * @param level, current + * @param level the robot's current level + * @return the amount of gold dropped */ - public int getLeadDropped(int level) { - int total = (int) (this.getLeadWorth(level) * this.getReclaimCostPercentage()); + public int getGoldDropped(int level) { + return this.isBuilding() ? (int) (this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER) : 0; } - RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int moveCooldown, - int HPLv1, int DPSLv1, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { - + RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int movementCooldown, + int health, int damage, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { this.buildCostLead = buildCostLead; this.buildCostGold = buildCostGold; this.actionCooldown = actionCooldown; - this.moveCooldown = moveCooldown; - this.HPLv1 = HPLv1; - this.DPSLv1 = DPSLv1; - + this.movementCooldown = movementCooldown; + this.health = health; + this.damage = damage; this.actionRadiusSquared = actionRadiusSquared; this.visionRadiusSquared = visionRadiusSquared; - this.bytecodeLimit = bytecodeLimit; - } - } \ No newline at end of file From e40991675a8766c637d1d950e0e7c4b7e93f917e Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Fri, 10 Dec 2021 05:51:49 -0500 Subject: [PATCH 065/413] compile w gradlew --- .../src/main/battlecode/common/RobotType.java | 2 +- .../main/battlecode/world/InternalRobot.java | 25 ------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 7907c724..ace845b1 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -152,7 +152,7 @@ public int getMaxHealth(int level) { * @return the starting health of a robot by level */ public int getStartingHealth(int level) { - return (int) (this.health * this.isBuilding() ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1); + return (int) (this.health * (this.isBuilding() ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1)); } /** diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 7398e616..6825ff0c 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -182,13 +182,6 @@ public int getActionRadiusSquared() { return this.type.actionRadiusSquared; } - /** - * Returns the robot's sensor radius squared. - */ - public int getSensorRadiusSquared() { - return this.type.sensorRadiusSquared; - } - /** * Returns whether this robot can perform actions on the given location. * @@ -198,15 +191,6 @@ public boolean canActLocation(MapLocation toSense){ return this.location.distanceSquaredTo(toSense) <= getActionRadiusSquared(); } - /** - * Returns whether this robot can sense the given location. - * - * @param toSense the MapLocation to sense - */ - public boolean canSenseLocation(MapLocation toSense){ - return this.location.distanceSquaredTo(toSense) <= getSensorRadiusSquared(); - } - /** * Returns whether this robot can act at a given radius away. * @@ -216,15 +200,6 @@ public boolean canActRadiusSquared(int radiusSquared) { return radiusSquared <= getActionRadiusSquared(); } - /** - * Returns whether this robot can sense something a given radius away. - * - * @param radiusSquared the distance squared to sense - */ - public boolean canSenseRadiusSquared(int radiusSquared) { - return radiusSquared <= getSensorRadiusSquared(); - } - // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** From eff04d549d2af04f25781b6eeb32693204db91b6 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Fri, 10 Dec 2021 05:53:17 -0500 Subject: [PATCH 066/413] remove extra lines --- engine/src/main/battlecode/common/RobotType.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index ace845b1..f93d61c9 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -3,8 +3,6 @@ /** * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. */ - - public enum RobotType { // Build Cost Lead, Build Cost Gold, Action Cooldown, Movement Cooldown From ed4eaf8838f33adbd365ca7f32f672bfe098e4b7 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 13 Nov 2021 12:46:41 -0500 Subject: [PATCH 067/413] Changed 'sense' to 'see' for methods --- .../battlecode/common/RobotController.java | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 57b7fce1..3fdba4d6 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -108,135 +108,135 @@ public strictfp interface RobotController { int getUpgradeLevel(); // *********************************** - // ****** GENERAL SENSOR METHODS ***** + // ****** GENERAL VISION METHODS ***** // *********************************** /** - * Senses whether a MapLocation is on the map. Will throw an exception if - * the location is not within the sensor range. + * Checks whether a MapLocation is on the map. Will throw an exception if + * the location is not within the vision range. * * @param loc the location to check * @return true if the location is on the map; false otherwise. - * @throws GameActionException if the location is not within sensor range. + * @throws GameActionException if the location is not within vision range. * * @battlecode.doc.costlymethod */ boolean onTheMap(MapLocation loc) throws GameActionException; /** - * Checks whether the given location is within the robot's sensor range, and if it is on the map. + * Checks whether the given location is within the robot's vision range, and if it is on the map. * * @param loc the location to check - * @return true if the given location is within the robot's sensor range and is on the map; false otherwise. + * @return true if the given location is within the robot's vision range and is on the map; false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseLocation(MapLocation loc); + boolean canSeeLocation(MapLocation loc); /** - * Checks whether a point at the given radius squared is within the robot's sensor range. + * Checks whether a point at the given radius squared is within the robot's vision range. * * @param radiusSquared the radius to check - * @return true if the given radius is within the robot's sensor range; false otherwise. + * @return true if the given radius is within the robot's vision range; false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseRadiusSquared(int radiusSquared); + boolean canSeeRadiusSquared(int radiusSquared); /** - * Senses the robot at the given location, or null if there is no robot + * Sees the robot at the given location, or null if there is no robot * there. * * @param loc the location to check * @return the robot at the given location. - * @throws GameActionException if the location is not within sensor range. + * @throws GameActionException if the location is not within vision range. * * @battlecode.doc.costlymethod */ - RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException; + RobotInfo canSeeRobotAtLocation(MapLocation loc) throws GameActionException; /** * Tests whether the given robot exists and if it is within this robot's - * sensor range. + * vision range. * * @param id the ID of the robot to query - * @return true if the given robot is within this robot's sensor range; + * @return true if the given robot is within this robot's vision range; * false otherwise. * * @battlecode.doc.costlymethod */ - boolean canSenseRobot(int id); + boolean canSeeRobot(int id); /** - * Senses information about a particular robot given its ID. + * Sees information about a particular robot given its ID. * * @param id the ID of the robot to query - * @return a RobotInfo object for the sensed robot. - * @throws GameActionException if the robot cannot be sensed (for example, - * if it doesn't exist or is out of sensor range). + * @return a RobotInfo object for the seen robot. + * @throws GameActionException if the robot cannot be seen (for example, + * if it doesn't exist or is out of vision range). * * @battlecode.doc.costlymethod */ - RobotInfo senseRobot(int id) throws GameActionException; + RobotInfo seeRobot(int id) throws GameActionException; /** - * Returns all robots within sensor radius. The objects are returned in no + * Returns all robots within vision radius. The objects are returned in no * particular order. * * @return array of RobotInfo objects, which contain information about all - * the robots you sensed. + * the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(); + RobotInfo[] seeNearbyRobots(); /** - * Returns all robots that can be sensed within a certain distance of this + * Returns all robots that can be seen within a certain distance of this * robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. - * @return array of RobotInfo objects of all the robots you sensed. + * @return array of RobotInfo objects of all the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(int radiusSquared); + RobotInfo[] seeNearbyRobots(int radiusSquared); /** - * Returns all robots of a given team that can be sensed within a certain + * Returns all robots of a given team that can be seen within a certain * distance of this robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. * @param team filter game objects by the given team. If null is passed, * robots from any team are returned - * @return array of RobotInfo objects of all the robots you sensed. + * @return array of RobotInfo objects of all the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(int radiusSquared, Team team); + RobotInfo[] seeNearbyRobots(int radiusSquared, Team team); /** - * Returns all robots of a given team that can be sensed within a certain + * Returns all robots of a given team that can be seen within a certain * radius of a specified location. The objects are returned in no particular * order. * * @param center center of the given search radius * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within sensor radius are returned. - * if radiusSquared is larger than the robot's sensor radius, the sensor + * this robot. If -1 is passed, all robots within vision radius are returned. + * if radiusSquared is larger than the robot's vision radius, the vision * radius is used. * @param team filter game objects by the given team. If null is passed, * objects from all teams are returned - * @return sorted array of RobotInfo objects of the robots you sensed. + * @return sorted array of RobotInfo objects of the robots you saw. * * @battlecode.doc.costlymethod */ - RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team); + RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team); /** * Given a location, returns the passability of that location. @@ -246,33 +246,33 @@ public strictfp interface RobotController { * * @param loc the given location * @return the passability of that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double sensePassability(MapLocation loc) throws GameActionException; + double seePassability(MapLocation loc) throws GameActionException; /** * Given a location, returns the lead count of that location. * * @param loc the given location * @return the amount of lead at that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double senseLead(MapLocation loc) throws GameActionException; + double seeLead(MapLocation loc) throws GameActionException; /** * Given a location, returns the gold count of that location. * * @param loc the given location * @return the amount of gold at that location. - * @throws GameActionException if the robot cannot sense the given location + * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod */ - double senseGold(MapLocation loc) throws GameActionException; + double seeGold(MapLocation loc) throws GameActionException; /** * Returns the location adjacent to current location in the given direction. From ce0224766048f3eef099a988e75e98afddbed8d0 Mon Sep 17 00:00:00 2001 From: Pranali Date: Thu, 18 Nov 2021 18:24:15 -0500 Subject: [PATCH 068/413] Added healing and repairing function specs --- .../battlecode/common/RobotController.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 3fdba4d6..94ea7b06 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -399,6 +399,33 @@ public strictfp interface RobotController { * @battlecode.doc.costlymethod */ void attack(MapLocation loc) throws GameActionException; + + // ***************************** + // ****** ARCHON METHODS ****** + // ***************************** + + /** + * Tests whether this robot can heal a robot (not building) at the given location. + * + * Checks that the robot is an archon unit and that the given location + * is within the robot's action radius. Also checks that a + * friendly robot unit (not a building) exists in the given square. + * + * @param loc target location to heal at + * @return whether it is possible to heal a robot at the given location. + * + * @battlecode.doc.costlymethod + */ + boolean canHealRobot(MapLocation loc); + + /** + * Heals at a given location. + * + * @throws GameActionException if conditions for healing are not satisfied + * @battlecode.doc.costlymethod + */ + void healRobot(MapLocation loc) throws GameActionException; + // *********************** // **** MINER METHODS **** @@ -476,6 +503,28 @@ public strictfp interface RobotController { */ void upgrade(MapLocation loc) throws GameActionException; + /** + * Tests whether this robot can repair a building at the given location. + * + * Checks that the robot is a builder unit and that the given location + * is within the robot's action radius. Also checks that a + * friendly unit which is a building exists in the given square. + * + * @param loc target location to repair building at + * @return whether it is possible to repair a building at the given location. + * + * @battlecode.doc.costlymethod + */ + boolean canRepairBuilding(MapLocation loc); + + /** + * Repairs building at a given location. + * + * @throws GameActionException if conditions for repairing building are not satisfied + * @battlecode.doc.costlymethod + */ + void repairBuilding(MapLocation loc) throws GameActionException; + // ******************************* // **** ALCHEMIST LAB METHODS **** // ******************************* From 6bf66b0a9d8453e0da448c85bca795a22b2c895d Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 11:19:25 -0500 Subject: [PATCH 069/413] Added actions specific to certain types of building, renamed small things --- .../battlecode/common/RobotController.java | 14 +- .../battlecode/world/RobotControllerImpl.java | 264 +++++++++++++++++- 2 files changed, 270 insertions(+), 8 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 94ea7b06..d198bcff 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -405,18 +405,18 @@ public strictfp interface RobotController { // ***************************** /** - * Tests whether this robot can heal a robot (not building) at the given location. + * Tests whether this robot can heal a droid at the given location. * * Checks that the robot is an archon unit and that the given location * is within the robot's action radius. Also checks that a - * friendly robot unit (not a building) exists in the given square. + * friendly droid robot exists in the given square. * * @param loc target location to heal at - * @return whether it is possible to heal a robot at the given location. + * @return whether it is possible to heal a droid robot at the given location. * * @battlecode.doc.costlymethod */ - boolean canHealRobot(MapLocation loc); + boolean canHealDroid(MapLocation loc); /** * Heals at a given location. @@ -424,7 +424,7 @@ public strictfp interface RobotController { * @throws GameActionException if conditions for healing are not satisfied * @battlecode.doc.costlymethod */ - void healRobot(MapLocation loc) throws GameActionException; + void healDroid(MapLocation loc) throws GameActionException; // *********************** @@ -437,7 +437,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * contain at least one lead. + * have positive lead amounts. * * @param loc target location to mine * @return whether it is possible to mine at the given location. @@ -460,7 +460,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * contain at least one gold. + * have positive gold amounts. * * @param loc target location to mine * @return whether it is possible to mine at the given location. diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9528dd7c..b453e33e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -576,10 +576,271 @@ public void bid(int influence) throws GameActionException { gameWorld.getMatchMaker().addAction(getID(), Action.PLACE_BID, influence); } + // ***************************** + // **** COMBAT UNIT METHODS **** + // ***************************** + + private void assertCanAttack(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canAttack()) + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot attack."); + if (!this.robot.canActLocation(loc)) + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be attacked because it is out of range."); + InternalRobot bot = getRobot(loc); + if (bot.getTeam() == getTeam()) + throw new GameActionException(CANT_DO_THAT, + "Robot is not on the enemy team."); + } + + @Override + boolean canAttack(MapLocation loc){ + try { + assertCanAttack(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void attack(MapLocation loc) throws GameActionException{ + assertCanAttack(loc); + this.robot.attack(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int attackedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); + } + + // ***************************** + // ****** ARCHON METHODS ****** + // ***************************** + + private void assertCanHealDroid(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canHealDroid()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot heal droids."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "This robot can't be healed belocation can't be min because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeHealed())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be healed."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be healed."); + } + } + + @Override + boolean canHealDroid(MapLocation loc){ + try { + assertCanHealDroid(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void healDroid(MapLocation loc) throws GameActionException{ + assertCanHealDroid(loc); + this.robot.healDroid(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int healedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); + } + + + // *********************** + // **** MINER METHODS **** + // *********************** + + private void assertCanMineLead(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canMine()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot mine."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be healed because it is out of range."); + } + int leadAmount = gameWorld.getLeadCount(loc); + if (leadAmount < 0){ + throw new GameActionException(CANT_DO_THAT, + "Lead amount must be positive to be mined."); + } + } + + @Override + boolean canMineLead(MapLocation loc){ + try { + assertCanMineLead(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void mineLead(MapLocation loc) throws GameActionException{ + assertCanMineLead(loc); + this.robot.mineLead(loc); + gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); + } + + private void assertCanMineGold(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canMine()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot mine."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "This location can't be mined because it is out of range."); + } + int goldAmount = gameWorld.getGoldCount(loc); + if (goldAmount < 0){ + throw new GameActionException(CANT_DO_THAT, + "Gold amount must be positive to be mined."); + } + } + + @Override + boolean canMineGold(MapLocation loc){ + try { + assertCanMineGold(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void mineGold(MapLocation loc) throws GameActionException{ + assertCanMineGold(loc); + this.robot.mineGold(loc); + gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); + } + + // ************************* + // **** BUILDER METHODS **** + // ************************* + + private void assertCanUpgrade(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canUpgrade()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot upgrade buildings."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be upgraded because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeUpgraded())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be upgraded."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be upgraded."); + } + if (getLead() < bot.getLeadUpgradeCost()){ + throw new GameActionException(CANT_DO_THAT, + "You don't have enough lead to upgrade this robot."); + } + if (getGold() < bot.getGoldUpgradeCost()){ + throw new GameActionException(CANT_DO_THAT, + "You don't have enough gold to upgrade this robot."); + } + } + + @Override + boolean canUpgrade(MapLocation loc){ + try { + assertCanUpgrade(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void upgrade(MapLocation loc) throws GameActionException{ + assertCanUpgrade(loc); + this.robot.upgrade(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int upgradedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); + } + + private void assertCanRepairBuilding(MapLocation loc) throws GameActionException { + assertIsActionReady(); + if (!getType().canRepairBuilding()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot repair buildings."); + }else if (!this.robot.canActLocation(loc)){ + throw new GameActionException(OUT_OF_RANGE, + "Robot can't be repaired because it is out of range."); + } + InternalRobot bot = gameWorld.getRobot(loc); + if (!(bot.getType().canBeUpgraded())){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not of a type that can be repair."); + } + if (bot.getTeam() != getTeam()){ + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be repaired."); + } + } + + @Override + boolean canRepairBuilding(MapLocation loc){ + try { + assertCanRepairBuilding(loc); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void repairBuilding(MapLocation loc) throws GameActionException{ + assertCanRepairBuilding(loc); + this.robot.repairBuilding(loc); + InternalRobot bot = gameWorld.getRobot(loc); + int repairedID = bot.getID(); + gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRD, repairedID); + } + + // ******************************* + // **** ALCHEMIST LAB METHODS **** + // ******************************* + + private void assertCanConvert() throws GameActionException { + assertIsActionReady(); + if (!getType().canConvert()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot convert lead to gold."); + } else if (LEAD_TO_GOLD_RATE > getLead()) { + throw new GameActionException(CANT_DO_THAT, + "You don't have enough lead to be able to convert to gold."); + } + } + + @Override + boolean canConvert(){ + try { + assertCanConvert(); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + void convert() throws GameActionException{ + assertCanConvert(); + this.robot.convert(); + gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT); + } + // *********************************** // ****** COMMUNICATION METHODS ****** // *********************************** + //TODO: Communication needs to be fixed + private void assertCanSetFlag(int flag) throws GameActionException { if (flag < GameConstants.MIN_FLAG_VALUE || flag > GameConstants.MAX_FLAG_VALUE) { throw new GameActionException(CANT_DO_THAT, "Flag value out of range"); @@ -628,10 +889,11 @@ public int getFlag(int id) throws GameActionException { return getRobotByID(id).getFlag(); } + //TODO: move this back to public? + // *********************************** // ****** OTHER ACTION METHODS ******* // *********************************** - /** * This used to be public, but is not public in 2021 because * slanderers should not be able to self-destruct. From b67186dbaf24766e67126d3e7311eb29ba9fdba4 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 20 Nov 2021 01:34:50 -0500 Subject: [PATCH 070/413] Implemented RobotController methods up until build/spawn --- .../battlecode/common/RobotController.java | 13 +- .../battlecode/world/RobotControllerImpl.java | 167 +++++++----------- 2 files changed, 75 insertions(+), 105 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index d198bcff..32482d48 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -143,6 +143,17 @@ public strictfp interface RobotController { */ boolean canSeeRadiusSquared(int radiusSquared); + /** + * Checks whether a robot is at a given location. Assumes the location is valid. + * + * @param loc the location to check + * @return true if a robot is at the location. + * @throws GameActionException if the location is not within vision range or on the map. + * + * @battlecode.doc.costlymethod + */ + boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException; + /** * Sees the robot at the given location, or null if there is no robot * there. @@ -153,7 +164,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo canSeeRobotAtLocation(MapLocation loc) throws GameActionException; + RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException; /** * Tests whether the given robot exists and if it is within this robot's diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index b453e33e..3c0ae644 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -77,19 +77,15 @@ public int getRoundNum() { return gameWorld.getCurrentRound(); } - @Override - public int getTeamVotes() { - return gameWorld.getTeamInfo().getVotes(getTeam()); - } - @Override public int getRobotCount() { return gameWorld.getObjectInfo().getRobotCount(getTeam()); } @Override - public double getEmpowerFactor(Team team, int roundsInFuture) { - return gameWorld.getTeamInfo().getBuff(team, getRoundNum() + roundsInFuture); + public double getArchonCount() { + // TODO: Assumes getArchons() exists in TeamInfo + return gameWorld.getTeamInfo().getArchons(); } // ********************************* @@ -115,90 +111,69 @@ public RobotType getType() { public MapLocation getLocation() { return this.robot.getLocation(); } + + @Override + public int getHealth() { + return this.robot.getHeatlh(); + } + + @Override + public int getUpgradeLevel() { + return this.robot.getUpgradeLevel(); + } private InternalRobot getRobotByID(int id) { if (!gameWorld.getObjectInfo().existsRobot(id)) return null; return this.gameWorld.getObjectInfo().getRobotByID(id); } - - public int getInfluence() { - return this.robot.getInfluence(); - } - - public int getConviction() { - return this.robot.getConviction(); - } // *********************************** - // ****** GENERAL SENSOR METHODS ***** + // ****** GENERAL VISION METHODS ***** // *********************************** @Override public boolean onTheMap(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSenseLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within sensor range"); + if (!this.robot.canSeeLocation(loc)) + throw new GameActionException(CANT_SEE_THAT, + "Target location not within vision range"); return gameWorld.getGameMap().onTheMap(loc); } - private void assertCanSenseLocation(MapLocation loc) throws GameActionException { + private void assertCanSeeLocation(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSenseLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within sensor range"); + if (!this.robot.canSeeLocation(loc)) + throw new GameActionException(CANT_SEE_THAT, + "Target location not within vision range"); if (!gameWorld.getGameMap().onTheMap(loc)) - throw new GameActionException(CANT_SENSE_THAT, + throw new GameActionException(CANT_SEE_THAT, "Target location is not on the map"); } @Override - public boolean canSenseLocation(MapLocation loc) { + public boolean canSeeLocation(MapLocation loc) { try { - assertCanSenseLocation(loc); + assertCanSeeLocation(loc); return true; } catch (GameActionException e) { return false; } } @Override - public boolean canSenseRadiusSquared(int radiusSquared) { - return this.robot.canSenseRadiusSquared(radiusSquared); - } - - private void assertCanDetectLocation(MapLocation loc) throws GameActionException { - assertNotNull(loc); - if (!this.robot.canDetectLocation(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location not within detection range"); - if (!gameWorld.getGameMap().onTheMap(loc)) - throw new GameActionException(CANT_SENSE_THAT, - "Target location is not on the map"); + public boolean canSeeRadiusSquared(int radiusSquared) { + return this.robot.canSeeRadiusSquared(radiusSquared); } @Override - public boolean canDetectLocation(MapLocation loc) { - try { - assertCanDetectLocation(loc); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public boolean canDetectRadiusSquared(int radiusSquared) { - return this.robot.canDetectRadiusSquared(radiusSquared); - } - - @Override - public boolean isLocationOccupied(MapLocation loc) throws GameActionException { - assertCanDetectLocation(loc); + public boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); return this.gameWorld.getRobot(loc) != null; } @Override - public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException { - assertCanSenseLocation(loc); + public RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); InternalRobot bot = gameWorld.getRobot(loc); if (bot != null) return bot.getRobotInfo(getType().canTrueSense()); @@ -206,87 +181,71 @@ public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionExceptio } @Override - public boolean canSenseRobot(int id) { - InternalRobot sensedRobot = getRobotByID(id); - return sensedRobot == null ? false : canSenseLocation(sensedRobot.getLocation()); + public boolean canSeeRobot(int id) { + InternalRobot seenRobot = getRobotByID(id); + return seenRobot == null ? false : canSeeLocation(seenRobot.getLocation()); } @Override - public RobotInfo senseRobot(int id) throws GameActionException { - if (!canSenseRobot(id)) + public RobotInfo seeRobot(int id) throws GameActionException { + if (!canSeeRobot(id)) throw new GameActionException(CANT_SENSE_THAT, - "Can't sense given robot; It may not exist anymore"); + "Can't see given robot; It may not exist anymore"); return getRobotByID(id).getRobotInfo(getType().canTrueSense()); } @Override - public RobotInfo[] senseNearbyRobots() { - return senseNearbyRobots(-1); + public RobotInfo[] seeNearbyRobots() { + return seeNearbyRobots(-1); } @Override - public RobotInfo[] senseNearbyRobots(int radiusSquared) { - return senseNearbyRobots(radiusSquared, null); + public RobotInfo[] seeNearbyRobots(int radiusSquared) { + return seeNearbyRobots(radiusSquared, null); } @Override - public RobotInfo[] senseNearbyRobots(int radiusSquared, Team team) { - return senseNearbyRobots(getLocation(), radiusSquared, team); + public RobotInfo[] seeNearbyRobots(int radiusSquared, Team team) { + return seeNearbyRobots(getLocation(), radiusSquared, team); } @Override - public RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team) { + public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team) { assertNotNull(center); int actualRadiusSquared = radiusSquared == -1 ? getType().sensorRadiusSquared : Math.min(radiusSquared, getType().sensorRadiusSquared); - InternalRobot[] allSensedRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); - List validSensedRobots = new ArrayList<>(); - for (InternalRobot sensedRobot : allSensedRobots) { + InternalRobot[] allSeenRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); + List validSeenRobots = new ArrayList<>(); + for (InternalRobot seenRobot : allSeenRobots) { // check if this robot - if (sensedRobot.equals(this.robot)) + if (seenRobot.equals(this.robot)) continue; - // check if can sense - if (!canSenseLocation(sensedRobot.getLocation())) + // check if can see + if (!canSeeLocation(seenRobot.getLocation())) continue; // check if right team - if (team != null && sensedRobot.getTeam() != team) + if (team != null && seenRobot.getTeam() != team) continue; - validSensedRobots.add(sensedRobot.getRobotInfo(getType().canTrueSense())); + validSeenRobots.add(seenRobot.getRobotInfo(getType().canTrueSense())); } - return validSensedRobots.toArray(new RobotInfo[validSensedRobots.size()]); - } - - @Override - public MapLocation[] detectNearbyRobots() { - return detectNearbyRobots(-1); + return validSeenRobots.toArray(new RobotInfo[validSeenRobots.size()]); } - @Override - public MapLocation[] detectNearbyRobots(int radiusSquared) { - return detectNearbyRobots(getLocation(), radiusSquared); + @Override + public double seePassability(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getPassability(loc); } - @Override - public MapLocation[] detectNearbyRobots(MapLocation center, int radiusSquared) { - assertNotNull(center); - int actualRadiusSquared = radiusSquared == -1 ? getType().detectionRadiusSquared : Math.min(radiusSquared, getType().detectionRadiusSquared); - InternalRobot[] allDetectedRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); - List validDetectedRobots = new ArrayList<>(); - for (InternalRobot detectedRobot : allDetectedRobots) { - // check if this robot - if (detectedRobot.equals(this.robot)) - continue; - // check if can detect - if (!canDetectLocation(detectedRobot.getLocation())) - continue; - validDetectedRobots.add(detectedRobot.getLocation()); - } - return validDetectedRobots.toArray(new MapLocation[validDetectedRobots.size()]); + @Override + public double seeLead(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getLead(loc); } @Override - public double sensePassability(MapLocation loc) throws GameActionException { - assertCanSenseLocation(loc); - return this.gameWorld.getPassability(loc); + public double seeGold(MapLocation loc) throws GameActionException { + assertCanSeeLocation(loc); + return this.gameWorld.getGold(loc); } @Override From 4732c1ecf36c9e37ff55549153f4079f235433c9 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 20 Nov 2021 02:03:35 -0500 Subject: [PATCH 071/413] Added build/spawn methods in RobotControllerImpl --- .../battlecode/common/RobotController.java | 3 ++ .../battlecode/world/RobotControllerImpl.java | 36 +++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 32482d48..70fa648b 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -356,6 +356,9 @@ public strictfp interface RobotController { // ****** BUILDING/SPAWNING ********** // *********************************** + + // TODO: is upgrade level a part of type or an extra parameter? + /** * Tests whether the robot can build a robot of the given type in the * given direction. Checks that the robot is of a type that can build, diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 3c0ae644..c791aafe 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -335,18 +335,26 @@ public void move(Direction dir) throws GameActionException { // ****** BUILDING/SPAWNING ********** // *********************************** - private void assertCanBuildRobot(RobotType type, Direction dir, int influence) throws GameActionException { + private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActionException { assertNotNull(type); assertNotNull(dir); if (!getType().canBuild(type)) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot build robots of type" + type + "."); - if (influence <= 0) + + // CHECK FUNCTION NAMES FOR GETTING LEAD/GOLD COSTS AND SUPPLIES + int leadNeeded = type.getLeadCost(); + int goldNeeded = type.getGoldCost(); + Team team = getTeam(); + if (gameWorld.getTeamInfo().getLead(team) < leadNeeded) { throw new GameActionException(CANT_DO_THAT, - "Cannot spend nonpositive amount of influence."); - if (influence > getInfluence()) + "Insufficient amount of lead."); + } + if (gameWorld.getTeamInfo().getGold(team) < goldNeeded) { throw new GameActionException(CANT_DO_THAT, - "Cannot spend more influence than you have."); + "Insufficient amount of gold."); + } + MapLocation spawnLoc = adjacentLocation(dir); if (!onTheMap(spawnLoc)) throw new GameActionException(OUT_OF_RANGE, @@ -360,21 +368,27 @@ private void assertCanBuildRobot(RobotType type, Direction dir, int influence) t } @Override - public boolean canBuildRobot(RobotType type, Direction dir, int influence) { + public boolean canBuildRobot(RobotType type, Direction dir) { try { - assertCanBuildRobot(type, dir, influence); + assertCanBuildRobot(type, dir); return true; } catch (GameActionException e) { return false; } } + // TODO: CHECK FUNCTION NAMES @Override - public void buildRobot(RobotType type, Direction dir, int influence) throws GameActionException { - assertCanBuildRobot(type, dir, influence); + public void buildRobot(RobotType type, Direction dir) throws GameActionException { + assertCanBuildRobot(type, dir); + + int leadNeeded = type.getLeadCost(); + int goldNeeded = type.getGoldCost(); this.robot.addCooldownTurns(); - this.robot.addInfluenceAndConviction(-influence); - int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam(), influence); + this.robot.addLead(-leadNeeded); + this.robot.addGold(-goldNeeded); + + int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam()); // set cooldown turns here, because not all new robots have cooldown (eg. switching teams) InternalRobot newBot = getRobotByID(robotID); From 0f5537d4a323237d09765b74f3d526d37470a102 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 11:50:56 -0500 Subject: [PATCH 072/413] Removed old unit methods --- .../battlecode/world/RobotControllerImpl.java | 152 ------------------ 1 file changed, 152 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index c791aafe..c3969894 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -396,158 +396,6 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); } - - // *********************************** - // ****** POLITICIAN METHODS ********* - // *********************************** - - private void assertCanEmpower(int radiusSquared) throws GameActionException { - assertIsReady(); - if (!getType().canEmpower()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot empower."); - if (radiusSquared > getType().actionRadiusSquared) - throw new GameActionException(CANT_DO_THAT, - "Robot's empower radius is smaller than radius specified"); - } - - @Override - public boolean canEmpower(int radiusSquared) { - try { - assertCanEmpower(radiusSquared); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void empower(int radiusSquared) throws GameActionException { - assertCanEmpower(radiusSquared); - - this.robot.addCooldownTurns(); // not needed but here for the sake of consistency - this.robot.empower(radiusSquared); - gameWorld.getMatchMaker().addAction(getID(), Action.EMPOWER, radiusSquared); - - // self-destruct - gameWorld.destroyRobot(this.robot.getID()); - } - - - // *********************************** - // ****** MUCKRAKER METHODS ********** - // *********************************** - - private void assertCanExpose(MapLocation loc) throws GameActionException { - assertIsReady(); - if (!getType().canExpose()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot expose."); - if (!onTheMap(loc)) - throw new GameActionException(OUT_OF_RANGE, - "Location is not on the map."); - if (!this.robot.canActLocation(loc)) - throw new GameActionException(CANT_DO_THAT, - "Location can't be exposed because it is out of range."); - InternalRobot bot = gameWorld.getRobot(loc); - if (bot == null) - throw new GameActionException(CANT_DO_THAT, - "There is no robot at specified location."); - if (!(bot.getType().canBeExposed())) - throw new GameActionException(CANT_DO_THAT, - "Robot at target location is not of a type that can be exposed."); - if (bot.getTeam() == getTeam()) - throw new GameActionException(CANT_DO_THAT, - "Robot at target location is not on the enemy team."); - } - - private void assertCanExpose(int id) throws GameActionException { - assertIsReady(); - if (!getType().canExpose()) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot expose."); - if (!canSenseRobot(id)) - throw new GameActionException(OUT_OF_RANGE, - "The targeted robot cannot be sensed."); - InternalRobot bot = getRobotByID(id); - if (!this.robot.canActLocation(bot.getLocation())) - throw new GameActionException(OUT_OF_RANGE, - "Robot can't be exposed because it is out of range."); - if (!(bot.getType().canBeExposed())) - throw new GameActionException(CANT_DO_THAT, - "Robot is not of a type that can be exposed."); - if (bot.getTeam() == getTeam()) - throw new GameActionException(CANT_DO_THAT, - "Robot is not on the enemy team."); - } - - @Override - public boolean canExpose(MapLocation loc) { - try { - assertCanExpose(loc); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public boolean canExpose(int id) { - try { - assertCanExpose(id); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void expose(MapLocation loc) throws GameActionException { - assertCanExpose(loc); - - this.robot.addCooldownTurns(); - InternalRobot bot = gameWorld.getRobot(loc); - int exposedID = bot.getID(); - this.robot.expose(bot); - gameWorld.getMatchMaker().addAction(getID(), Action.EXPOSE, exposedID); - } - - @Override - public void expose(int id) throws GameActionException { - assertCanExpose(id); - - this.robot.addCooldownTurns(); - InternalRobot bot = getRobotByID(id); - this.robot.expose(bot); - gameWorld.getMatchMaker().addAction(getID(), Action.EXPOSE, id); - } - - // *********************************** - // *** ENLIGHTENMENT CENTER METHODS ** - // *********************************** - - private void assertCanBid(int influence) throws GameActionException { - if (!getType().canBid()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot bid."); - } else if (influence <= 0) { - throw new GameActionException(CANT_DO_THAT, - "Can only bid non-negative amounts of influence."); - } else if (influence > getInfluence()) { - throw new GameActionException(CANT_DO_THAT, - "Not possible to bid influence you don't have."); - } - } - - @Override - public boolean canBid(int influence) { - try { - assertCanBid(influence); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void bid(int influence) throws GameActionException { - assertCanBid(influence); - - this.robot.setBid(influence); - gameWorld.getMatchMaker().addAction(getID(), Action.PLACE_BID, influence); - } // ***************************** // **** COMBAT UNIT METHODS **** From 7047bee138f45ecc2fb070615c4022a62bc87093 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 12:53:38 -0500 Subject: [PATCH 073/413] Updated action cooldowns and changing currency --- .../battlecode/world/RobotControllerImpl.java | 98 ++++++++++++++++--- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index c3969894..1eaaa92d 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -257,37 +257,70 @@ public MapLocation adjacentLocation(Direction dir) { // ****** READINESS METHODS ********** // *********************************** - private void assertIsReady() throws GameActionException { - if (getCooldownTurns() >= 1) + private void assertActionIsReady() throws GameActionException { + if (getActionCooldownTurns() >= 1) throw new GameActionException(IS_NOT_READY, "This robot's action cooldown has not expired."); } /** * Check if the robot is ready to perform an action. Returns true if - * the current cooldown counter is strictly less than 1. + * the current action cooldown counter is strictly less than 1. * * @return true if the robot can do an action, false otherwise */ @Override - public boolean isReady() { + public boolean isActionReady() { try { - assertIsReady(); + assertIsActionReady(); return true; } catch (GameActionException e) { return false; } } /** - * Return the cooldown turn counter of the robot. If this is < 1, the robot + * Return the action cooldown turn counter of the robot. If this is < 1, the robot * can perform an action; otherwise, it cannot. * The counter is decreased by 1 at the start of every * turn, and increased to varying degrees by different actions taken. * - * @return the number of cooldown turns as a float + * @return the number of action cooldown turns as a float */ @Override - public double getCooldownTurns() { - return this.robot.getCooldownTurns(); + public double getActionCooldownTurns() { + return this.robot.getActionCooldownTurns(); + } + + private void assertMovementIsReady() throws GameActionException { + if (getMovementCooldownTurns() >= 1) + throw new GameActionException(IS_NOT_READY, + "This robot's movement cooldown has not expired."); + } + + /** + * Check if the robot is ready to move. Returns true if + * the current movement cooldown counter is strictly less than 1. + * + * @return true if the robot can move, false otherwise + */ + @Override + public boolean isMovementReady() { + try { + assertIsMovementReady(); + return true; + } catch (GameActionException e) { return false; } + } + + /** + * Return the movement cooldown turn counter of the robot. If this is < 1, the robot + * can move; otherwise, it cannot. + * The counter is decreased by 1 at the start of every + * turn, and increased by moving. + * + * @return the number of cooldown movement turns as a float + */ + @Override + public double getMovementCooldownTurns() { + return this.robot.getMovementCooldownTurns(); } // *********************************** @@ -296,6 +329,7 @@ public double getCooldownTurns() { private void assertCanMove(Direction dir) throws GameActionException { assertNotNull(dir); + assertIsMovementReady(); if (!getType().canMove()) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot move."); @@ -322,7 +356,6 @@ public boolean canMove(Direction dir) { @Override public void move(Direction dir) throws GameActionException { assertCanMove(dir); - MapLocation center = adjacentLocation(dir); this.robot.addCooldownTurns(); this.gameWorld.moveRobot(getLocation(), center); @@ -338,6 +371,7 @@ public void move(Direction dir) throws GameActionException { private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActionException { assertNotNull(type); assertNotNull(dir); + assertIsActionReady(); if (!getType().canBuild(type)) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot build robots of type" + type + "."); @@ -362,7 +396,7 @@ private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActio if (isLocationOccupied(spawnLoc)) throw new GameActionException(CANT_MOVE_THERE, "Cannot spawn to an occupied location; " + spawnLoc + " is occupied."); - if (!isReady()) + if (!isActionReady()) throw new GameActionException(IS_NOT_READY, "Robot is still cooling down! You need to wait before you can perform another action."); } @@ -385,8 +419,10 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException this.robot.addCooldownTurns(); - this.robot.addLead(-leadNeeded); - this.robot.addGold(-goldNeeded); + //TODO: why is this on the robot? + Team robotTeam = this.robot.getTeam(); + robotTeam.addLead(-leadNeeded); + robotTeam.addGold(-goldNeeded); int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam()); @@ -402,6 +438,7 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException // ***************************** private void assertCanAttack(MapLocation loc) throws GameActionException { + assertNotNull(loc); assertIsActionReady(); if (!getType().canAttack()) throw new GameActionException(CANT_DO_THAT, @@ -427,6 +464,7 @@ boolean canAttack(MapLocation loc){ void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); this.robot.attack(loc); + this.robot.addActionCooldownTurns(); InternalRobot bot = gameWorld.getRobot(loc); int attackedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); @@ -437,13 +475,14 @@ void attack(MapLocation loc) throws GameActionException{ // ***************************** private void assertCanHealDroid(MapLocation loc) throws GameActionException { + assertNotNull(loc); assertIsActionReady(); if (!getType().canHealDroid()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot heal droids."); }else if (!this.robot.canActLocation(loc)){ throw new GameActionException(OUT_OF_RANGE, - "This robot can't be healed belocation can't be min because it is out of range."); + "This robot can't be healed because location is out of range."); } InternalRobot bot = gameWorld.getRobot(loc); if (!(bot.getType().canBeHealed())){ @@ -468,6 +507,7 @@ boolean canHealDroid(MapLocation loc){ void healDroid(MapLocation loc) throws GameActionException{ assertCanHealDroid(loc); this.robot.healDroid(loc); + this.robot.addActionCooldownTurns(); InternalRobot bot = gameWorld.getRobot(loc); int healedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); @@ -479,13 +519,14 @@ void healDroid(MapLocation loc) throws GameActionException{ // *********************** private void assertCanMineLead(MapLocation loc) throws GameActionException { + assertNotNull(loc); assertIsActionReady(); if (!getType().canMine()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot mine."); }else if (!this.robot.canActLocation(loc)){ throw new GameActionException(OUT_OF_RANGE, - "Robot can't be healed because it is out of range."); + "This location can't be mined because it is out of range."); } int leadAmount = gameWorld.getLeadCount(loc); if (leadAmount < 0){ @@ -506,10 +547,13 @@ boolean canMineLead(MapLocation loc){ void mineLead(MapLocation loc) throws GameActionException{ assertCanMineLead(loc); this.robot.mineLead(loc); + this.robot.addLead(1); //TODO: do we want to this here or in the implementation + this.robot.addActionCooldownTurns(); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } private void assertCanMineGold(MapLocation loc) throws GameActionException { + assertNotNull(loc); assertIsActionReady(); if (!getType().canMine()) { throw new GameActionException(CANT_DO_THAT, @@ -537,6 +581,9 @@ boolean canMineGold(MapLocation loc){ void mineGold(MapLocation loc) throws GameActionException{ assertCanMineGold(loc); this.robot.mineGold(loc); + Team robotTeam = this.robot.getTeam(); + robotTeam.addGold(1); + this.robot.addActionCooldownTurns(); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } @@ -545,6 +592,7 @@ void mineGold(MapLocation loc) throws GameActionException{ // ************************* private void assertCanUpgrade(MapLocation loc) throws GameActionException { + assertNotNull(loc); assertIsActionReady(); if (!getType().canUpgrade()) { throw new GameActionException(CANT_DO_THAT, @@ -585,6 +633,19 @@ void upgrade(MapLocation loc) throws GameActionException{ assertCanUpgrade(loc); this.robot.upgrade(loc); InternalRobot bot = gameWorld.getRobot(loc); + RobotType type = bot.getType(); + int upgradeLevel = bot.getUpgradeLevel(); + + int leadNeeded = type.getLeadUpgradeCost(upgradeLevel); + int goldNeeded = type.getGoldUpgradeCost(upgradeLevel); + + + this.robot.addActionCooldownTurns(); + + + Team robotTeam = this.robot.getTeam(); + robotTeam.addGold(-goldNeeded); + robotTeam.addLead(-leadNeeded); int upgradedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); } @@ -621,6 +682,8 @@ boolean canRepairBuilding(MapLocation loc){ void repairBuilding(MapLocation loc) throws GameActionException{ assertCanRepairBuilding(loc); this.robot.repairBuilding(loc); + this.robot.addActionCooldownTurns(); + InternalRobot bot = gameWorld.getRobot(loc); int repairedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRD, repairedID); @@ -653,6 +716,11 @@ boolean canConvert(){ void convert() throws GameActionException{ assertCanConvert(); this.robot.convert(); + this.robot.addActionCooldownTurns(); + Team robotTeam = this.robot.getTeam(); + robotTeam.addLead(-LEAD_TO_GOLD_RATE); + robotTeam.addGold(1); + gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT); } From ff0ce79218d412d77d0496342e149fe7b4401c4e Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 4 Dec 2021 11:39:21 -0500 Subject: [PATCH 074/413] Readded disintegration mechanic --- .../src/main/battlecode/common/RobotController.java | 7 +++++++ .../main/battlecode/world/RobotControllerImpl.java | 12 ++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 70fa648b..024b3b72 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -613,6 +613,13 @@ public strictfp interface RobotController { // ****** OTHER ACTION METHODS ******* // *********************************** + /** + * Destroys the robot. + * + * @battlecode.doc.costlymethod + **/ + void disintegrate(); + /** * Causes your team to lose the game. It's like typing "gg." * diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 1eaaa92d..e32fb9ea 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -471,7 +471,7 @@ void attack(MapLocation loc) throws GameActionException{ } // ***************************** - // ****** ARCHON METHODS ****** + // ****** ARCHON METHODS ******* // ***************************** private void assertCanHealDroid(MapLocation loc) throws GameActionException { @@ -778,16 +778,12 @@ public int getFlag(int id) throws GameActionException { return getRobotByID(id).getFlag(); } - //TODO: move this back to public? - // *********************************** // ****** OTHER ACTION METHODS ******* // *********************************** - /** - * This used to be public, but is not public in 2021 because - * slanderers should not be able to self-destruct. - */ - private void disintegrate() { + + @Override + public void disintegrate() { throw new RobotDeathException(); } From f5b7309eaf34b83c4506ca4dd9f6d27eafc8ba58 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 20 Nov 2021 13:12:38 -0500 Subject: [PATCH 075/413] Changed cooldowns, made attack work on actual robot --- engine/src/main/battlecode/world/RobotControllerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index e32fb9ea..2b076b29 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -357,7 +357,7 @@ public boolean canMove(Direction dir) { public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - this.robot.addCooldownTurns(); + this.robot.addMovementCooldownTurns(); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); @@ -417,7 +417,7 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); - this.robot.addCooldownTurns(); + this.robot.addActionCooldownTurns(); //TODO: why is this on the robot? Team robotTeam = this.robot.getTeam(); @@ -463,9 +463,9 @@ boolean canAttack(MapLocation loc){ @Override void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); - this.robot.attack(loc); this.robot.addActionCooldownTurns(); InternalRobot bot = gameWorld.getRobot(loc); + this.robot.attack(bot); int attackedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); } From a0775bd4c8ee9243840187e754e6aa9ab36b4e28 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sat, 4 Dec 2021 12:01:33 -0500 Subject: [PATCH 076/413] Made minor naming and other changes to compile --- .../main/battlecode/world/RobotControllerImpl.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 2b076b29..83ca2b48 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -419,16 +419,16 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException this.robot.addActionCooldownTurns(); - //TODO: why is this on the robot? Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-leadNeeded); robotTeam.addGold(-goldNeeded); int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam()); - // set cooldown turns here, because not all new robots have cooldown (eg. switching teams) - InternalRobot newBot = getRobotByID(robotID); - newBot.setCooldownTurns(type.initialCooldown); + // Undo because setting cooldown is automatically done + // // set cooldown turns here, because not all new robots have cooldown (eg. switching teams) + // InternalRobot newBot = getRobotByID(robotID); + // newBot.setCooldownTurns(type.initialCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); } @@ -698,7 +698,7 @@ private void assertCanConvert() throws GameActionException { if (!getType().canConvert()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot convert lead to gold."); - } else if (LEAD_TO_GOLD_RATE > getLead()) { + } else if (GameConstants.LEAD_TO_GOLD_RATE > getLead()) { throw new GameActionException(CANT_DO_THAT, "You don't have enough lead to be able to convert to gold."); } @@ -718,10 +718,10 @@ void convert() throws GameActionException{ this.robot.convert(); this.robot.addActionCooldownTurns(); Team robotTeam = this.robot.getTeam(); - robotTeam.addLead(-LEAD_TO_GOLD_RATE); + robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE); robotTeam.addGold(1); - gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT); + gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY); } // *********************************** From 0c58a17ed44cff33919fce8569ae5d0af428eda4 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 4 Dec 2021 12:50:30 -0500 Subject: [PATCH 077/413] RobotControllerImpl Bug Fixes --- .../battlecode/common/RobotController.java | 37 +++++++++--- .../battlecode/world/RobotControllerImpl.java | 58 ++++++++++--------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 024b3b72..f00c5b72 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -302,25 +302,46 @@ public strictfp interface RobotController { // *********************************** /** - * Tests whether the robot can perform an action. Returns + * Tests whether the robot can act. Returns * getCooldownTurns() < 1. * - * @return true if the robot can perform an action. + * @return true if the robot can act. * * @battlecode.doc.costlymethod */ - boolean isReady(); + boolean isActionReady(); /** - * Returns the number of cooldown turns remaining before this unit can act again. - * When this number is strictly less than 1, isReady() is true and the robot - * can perform actions again. + * Returns the number of action cooldown turns remaining before this unit can act again. + * When this number is strictly less than 1, isActionReady() is true and the robot + * can act again. * - * @return the number of cooldown turns remaining before this unit can act again. + * @return the number of action turns remaining before this unit can act again. * * @battlecode.doc.costlymethod */ - double getCooldownTurns(); + double getActionCooldownTurns(); + + /** + * Tests whether the robot can move. Returns + * getCooldownTurns() < 1. + * + * @return true if the robot can move. + * + * @battlecode.doc.costlymethod + */ + boolean isMovementReady(); + + /** + * Returns the number of movement cooldown turns remaining before this unit can move again. + * When this number is strictly less than 1, isMovementReady() is true and the robot + * can move again. + * + * @return the number of cooldown turns remaining before this unit can move again. + * + * @battlecode.doc.costlymethod + */ + double getMovementCooldownTurns(); // *********************************** // ****** MOVEMENT METHODS *********** diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 83ca2b48..ed685f33 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -83,7 +83,7 @@ public int getRobotCount() { } @Override - public double getArchonCount() { + public int getArchonCount() { // TODO: Assumes getArchons() exists in TeamInfo return gameWorld.getTeamInfo().getArchons(); } @@ -239,13 +239,13 @@ public double seePassability(MapLocation loc) throws GameActionException { @Override public double seeLead(MapLocation loc) throws GameActionException { assertCanSeeLocation(loc); - return this.gameWorld.getLead(loc); + return this.gameWorld.getLeadAtLocation(loc); } @Override public double seeGold(MapLocation loc) throws GameActionException { assertCanSeeLocation(loc); - return this.gameWorld.getGold(loc); + return this.gameWorld.getGoldAtLocation(loc); } @Override @@ -257,7 +257,11 @@ public MapLocation adjacentLocation(Direction dir) { // ****** READINESS METHODS ********** // *********************************** - private void assertActionIsReady() throws GameActionException { + private boolean isLocationOccupied(MapLocation loc) throws GameActionException { + return this.gameWorld.getRobot(loc) != null; + } + + private void assertIsActionReady() throws GameActionException { if (getActionCooldownTurns() >= 1) throw new GameActionException(IS_NOT_READY, "This robot's action cooldown has not expired."); @@ -290,7 +294,7 @@ public double getActionCooldownTurns() { return this.robot.getActionCooldownTurns(); } - private void assertMovementIsReady() throws GameActionException { + private void assertIsMovementReady() throws GameActionException { if (getMovementCooldownTurns() >= 1) throw new GameActionException(IS_NOT_READY, "This robot's movement cooldown has not expired."); @@ -340,7 +344,7 @@ private void assertCanMove(Direction dir) throws GameActionException { if (isLocationOccupied(loc)) throw new GameActionException(CANT_MOVE_THERE, "Cannot move to an occupied location; " + loc + " is occupied."); - if (!isReady()) + if (!isMovementReady()) throw new GameActionException(IS_NOT_READY, "Robot is still cooling down! You need to wait before you can perform another action."); } @@ -446,14 +450,14 @@ private void assertCanAttack(MapLocation loc) throws GameActionException { if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, "Robot can't be attacked because it is out of range."); - InternalRobot bot = getRobot(loc); + RobotInfo bot = seeRobotAtLocation(loc); if (bot.getTeam() == getTeam()) throw new GameActionException(CANT_DO_THAT, "Robot is not on the enemy team."); } @Override - boolean canAttack(MapLocation loc){ + public boolean canAttack(MapLocation loc){ try { assertCanAttack(loc); return true; @@ -461,7 +465,7 @@ boolean canAttack(MapLocation loc){ } @Override - void attack(MapLocation loc) throws GameActionException{ + public void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); this.robot.addActionCooldownTurns(); InternalRobot bot = gameWorld.getRobot(loc); @@ -496,7 +500,7 @@ private void assertCanHealDroid(MapLocation loc) throws GameActionException { } @Override - boolean canHealDroid(MapLocation loc){ + public boolean canHealDroid(MapLocation loc){ try { assertCanHealDroid(loc); return true; @@ -504,7 +508,7 @@ boolean canHealDroid(MapLocation loc){ } @Override - void healDroid(MapLocation loc) throws GameActionException{ + public void healDroid(MapLocation loc) throws GameActionException{ assertCanHealDroid(loc); this.robot.healDroid(loc); this.robot.addActionCooldownTurns(); @@ -536,7 +540,7 @@ private void assertCanMineLead(MapLocation loc) throws GameActionException { } @Override - boolean canMineLead(MapLocation loc){ + public boolean canMineLead(MapLocation loc){ try { assertCanMineLead(loc); return true; @@ -544,7 +548,7 @@ boolean canMineLead(MapLocation loc){ } @Override - void mineLead(MapLocation loc) throws GameActionException{ + public void mineLead(MapLocation loc) throws GameActionException{ assertCanMineLead(loc); this.robot.mineLead(loc); this.robot.addLead(1); //TODO: do we want to this here or in the implementation @@ -570,7 +574,7 @@ private void assertCanMineGold(MapLocation loc) throws GameActionException { } @Override - boolean canMineGold(MapLocation loc){ + public boolean canMineGold(MapLocation loc){ try { assertCanMineGold(loc); return true; @@ -578,7 +582,7 @@ boolean canMineGold(MapLocation loc){ } @Override - void mineGold(MapLocation loc) throws GameActionException{ + public void mineGold(MapLocation loc) throws GameActionException{ assertCanMineGold(loc); this.robot.mineGold(loc); Team robotTeam = this.robot.getTeam(); @@ -594,6 +598,7 @@ void mineGold(MapLocation loc) throws GameActionException{ private void assertCanUpgrade(MapLocation loc) throws GameActionException { assertNotNull(loc); assertIsActionReady(); + Team team = getTeam(); if (!getType().canUpgrade()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot upgrade buildings."); @@ -610,18 +615,18 @@ private void assertCanUpgrade(MapLocation loc) throws GameActionException { throw new GameActionException(CANT_DO_THAT, "Robot is not on your team so can't be upgraded."); } - if (getLead() < bot.getLeadUpgradeCost()){ + if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadUpgradeCost()){ throw new GameActionException(CANT_DO_THAT, "You don't have enough lead to upgrade this robot."); } - if (getGold() < bot.getGoldUpgradeCost()){ + if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldUpgradeCost()){ throw new GameActionException(CANT_DO_THAT, "You don't have enough gold to upgrade this robot."); } } @Override - boolean canUpgrade(MapLocation loc){ + public boolean canUpgrade(MapLocation loc){ try { assertCanUpgrade(loc); return true; @@ -629,7 +634,7 @@ boolean canUpgrade(MapLocation loc){ } @Override - void upgrade(MapLocation loc) throws GameActionException{ + public void upgrade(MapLocation loc) throws GameActionException{ assertCanUpgrade(loc); this.robot.upgrade(loc); InternalRobot bot = gameWorld.getRobot(loc); @@ -671,7 +676,7 @@ private void assertCanRepairBuilding(MapLocation loc) throws GameActionException } @Override - boolean canRepairBuilding(MapLocation loc){ + public boolean canRepairBuilding(MapLocation loc){ try { assertCanRepairBuilding(loc); return true; @@ -679,14 +684,14 @@ boolean canRepairBuilding(MapLocation loc){ } @Override - void repairBuilding(MapLocation loc) throws GameActionException{ + public void repairBuilding(MapLocation loc) throws GameActionException{ assertCanRepairBuilding(loc); this.robot.repairBuilding(loc); this.robot.addActionCooldownTurns(); InternalRobot bot = gameWorld.getRobot(loc); int repairedID = bot.getID(); - gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRD, repairedID); + gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRED, repairedID); } // ******************************* @@ -695,17 +700,18 @@ void repairBuilding(MapLocation loc) throws GameActionException{ private void assertCanConvert() throws GameActionException { assertIsActionReady(); + Team team = getTeam(); if (!getType().canConvert()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot convert lead to gold."); - } else if (GameConstants.LEAD_TO_GOLD_RATE > getLead()) { + } else if (GameConstants.LEAD_TO_GOLD_RATE > gameWorld.getTeamInfo().getLead(team)) { throw new GameActionException(CANT_DO_THAT, "You don't have enough lead to be able to convert to gold."); } } @Override - boolean canConvert(){ + public boolean canConvert(){ try { assertCanConvert(); return true; @@ -713,7 +719,7 @@ boolean canConvert(){ } @Override - void convert() throws GameActionException{ + public void convert() throws GameActionException{ assertCanConvert(); this.robot.convert(); this.robot.addActionCooldownTurns(); @@ -758,7 +764,7 @@ private void assertCanGetFlag(int id) throws GameActionException { "Robot of given ID does not exist."); if (getType() != RobotType.ENLIGHTENMENT_CENTER && bot.getType() != RobotType.ENLIGHTENMENT_CENTER && - !canSenseLocation(bot.getLocation())) + !canSeeLocation(bot.getLocation())) throw new GameActionException(CANT_SENSE_THAT, "Robot at location is out of sensor range and not an Enlightenment Center."); } From ed7e77452b49b4f18a52a5506b61f26e31a0d702 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Thu, 9 Dec 2021 05:08:27 -0500 Subject: [PATCH 078/413] Moved all cooldown costs into RobotControllerImpl, added transformation mechanic in RobotControllerImpl, RobotController --- .../battlecode/common/RobotController.java | 24 +++++++ .../main/battlecode/world/InternalRobot.java | 4 -- .../battlecode/world/RobotControllerImpl.java | 66 ++++++++++++++----- 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index f00c5b72..ef3f0d65 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -584,6 +584,30 @@ public strictfp interface RobotController { */ void convert() throws GameActionException; + // ******************************* + // **** GENERAL TOWER METHODS **** + // ******************************* + + /** + * Tests whether this tower can transform. + * + * Checks that the robot is a turret or portable + * + * @return whether it is possible to transform + * + * @battlecode.doc.costlymethod + */ + boolean canTransform(); + + /** + * Transform from turret into portable or vice versa. + * + * @throws GameActionException if conditions for transforming are not satisfied + * @battlecode.doc.costlymethod + */ + void transform() throws GameActionException; + + // *********************************** // ****** COMMUNICATION METHODS ****** // *********************************** diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 6825ff0c..a8cd6176 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -286,10 +286,8 @@ public void transform() { if (this.canTransformCooldown()) { if (this.mode == RobotMode.TURRET) { this.mode = RobotMode.PORTABLE; - this.addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); } else { this.mode = RobotMode.TURRET; - this.addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); } } } @@ -304,8 +302,6 @@ public void upgrade() { return; this.level++; this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); - this.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); } /** diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index ed685f33..b8f24430 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -265,6 +265,9 @@ private void assertIsActionReady() throws GameActionException { if (getActionCooldownTurns() >= 1) throw new GameActionException(IS_NOT_READY, "This robot's action cooldown has not expired."); + if (!robot.getMode().canAct) + throw new GameActionException(CANT_DO_THAT, + "This robot is not in a mode that can act."); } /** @@ -334,7 +337,7 @@ public double getMovementCooldownTurns() { private void assertCanMove(Direction dir) throws GameActionException { assertNotNull(dir); assertIsMovementReady(); - if (!getType().canMove()) + if (robot.getMode().canMove) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot move."); MapLocation loc = adjacentLocation(dir); @@ -357,11 +360,12 @@ public boolean canMove(Direction dir) { } catch (GameActionException e) { return false; } } + // TODO: Check cooldown turns @Override public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - this.robot.addMovementCooldownTurns(); + this.robot.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); @@ -413,7 +417,7 @@ public boolean canBuildRobot(RobotType type, Direction dir) { } catch (GameActionException e) { return false; } } - // TODO: CHECK FUNCTION NAMES + // TODO: Change cooldown turns to build turn @Override public void buildRobot(RobotType type, Direction dir) throws GameActionException { assertCanBuildRobot(type, dir); @@ -421,7 +425,7 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.BUILD_COOLDOWN); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-leadNeeded); @@ -467,7 +471,7 @@ public boolean canAttack(MapLocation loc){ @Override public void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.ATTACK_COOLDOWN); InternalRobot bot = gameWorld.getRobot(loc); this.robot.attack(bot); int attackedID = bot.getID(); @@ -511,7 +515,7 @@ public boolean canHealDroid(MapLocation loc){ public void healDroid(MapLocation loc) throws GameActionException{ assertCanHealDroid(loc); this.robot.healDroid(loc); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.HEAL_COOLDOWN); InternalRobot bot = gameWorld.getRobot(loc); int healedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); @@ -552,7 +556,7 @@ public void mineLead(MapLocation loc) throws GameActionException{ assertCanMineLead(loc); this.robot.mineLead(loc); this.robot.addLead(1); //TODO: do we want to this here or in the implementation - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.MINE_COOLDOWN); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } @@ -587,7 +591,7 @@ public void mineGold(MapLocation loc) throws GameActionException{ this.robot.mineGold(loc); Team robotTeam = this.robot.getTeam(); robotTeam.addGold(1); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.MINE_COOLDOWN); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } @@ -645,12 +649,11 @@ public void upgrade(MapLocation loc) throws GameActionException{ int goldNeeded = type.getGoldUpgradeCost(upgradeLevel); - this.robot.addActionCooldownTurns(); - - Team robotTeam = this.robot.getTeam(); robotTeam.addGold(-goldNeeded); robotTeam.addLead(-leadNeeded); + this.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); int upgradedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); } @@ -687,7 +690,7 @@ public boolean canRepairBuilding(MapLocation loc){ public void repairBuilding(MapLocation loc) throws GameActionException{ assertCanRepairBuilding(loc); this.robot.repairBuilding(loc); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.REPAIR_COOLDOWN); InternalRobot bot = gameWorld.getRobot(loc); int repairedID = bot.getID(); @@ -711,18 +714,19 @@ private void assertCanConvert() throws GameActionException { } @Override - public boolean canConvert(){ + public boolean canConvert() { try { assertCanConvert(); return true; } catch (GameActionException e) { return false; } } + // TODO: Implement convert in InternalRobot @Override - public void convert() throws GameActionException{ + public void convert() throws GameActionException { assertCanConvert(); this.robot.convert(); - this.robot.addActionCooldownTurns(); + this.robot.addActionCooldownTurns(GameConstants.CONVERT_COOLDOWN); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE); robotTeam.addGold(1); @@ -730,6 +734,38 @@ public void convert() throws GameActionException{ gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY); } + // ******************************* + // **** GENERAL TOWER METHODS **** + // ******************************* + + private void assertCanTransform() throws GameActionException { + assertIsActionReady(); + if (!robot.getMode() == RobotMode.TURRET || !robot.getMode() == RobotMode.PORTABLE) { + throw new GameActionException(CANT_DO_THAT, + "Robot is not transformable."); + } + } + + @Override + public boolean canTransform() { + try { + assertCanTransform(); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + public void transform() throws GameActionException { + assertCanTransform(); + robot.transform(); + RobotMode mode = robot.getMode(); + if (mode == RobotMode.TURRET) { + addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } else { + addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + } + } + // *********************************** // ****** COMMUNICATION METHODS ****** // *********************************** From bee1286fce34befab3ea2bbcd480f5f9e017fb50 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 10:38:58 -0500 Subject: [PATCH 079/413] Implemented lead, gold, and archon methods for TeamInfo --- .../src/main/battlecode/world/TeamInfo.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 477c6a11..26a3906e 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -3,6 +3,7 @@ import battlecode.common.GameConstants; import battlecode.common.Team; import java.util.*; +import static battlecode.common.GameActionExceptionType.*; /** * This class is used to hold information regarding team specific values such as @@ -11,16 +12,99 @@ public class TeamInfo { private GameWorld gameWorld; + int archonCount; + int leadCount; + int goldCount; + /** + * Create a new representation of TeamInfo + * + * @param gameWorld the gameWorld the team exists in + * @param archonCount the number of remaining archons + * @param leadCount the amount of lead stored + * @param goldCount the amount of gold stored + */ public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; + this.archonCount = 0; + this.leadCount = 0; + this.goldCount = 0; } // ********************************* // ***** GETTER METHODS ************ // ********************************* + /** + * Get the number of remaining Archons. + * + * @return the number of archons remaining + */ + public int getArchonCount() { + return this.archonCount; + } + + /** + * Get the amount of lead. + * + * @return the team's lead count + */ + public int getLead() { + return this.leadCount; + } + + /** + * Get the amount of gold. + * + * @return the team's gold count + */ + public int getGold() { + return this.goldCount; + } + // ********************************* // ***** UPDATE METHODS ************ // ********************************* + + /** + * Set the number of Archons. + * + * @param newArchonCount the new number of Archons + * + * @throws GameActionException if the newArchonCount is negative + */ + public void setArchonCount(int newArchonCount) throws GameActionException { + if (newArchonCount < 0) { + throw new GameActionException(CANT_DO_THAT, "Invalid change in number of archons"); + } + this.archonCount = newArchonCount; + } + + /** + * Add to the amount of lead. If leadChange is negative, subtract from lead instead. + * + * @param leadChange the change in the lead count + * + * @throws GameActionException if the resulting amount of lead is negative + */ + public void changeLead(int leadChange) throws GameActionException { + if (leadCount + leadChange < 0) { + throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of lead"); + } + this.leadCount += leadChange; + } + + /** + * Add to the amount of gold. If goldChange is negative, subtract from gold instead. + * + * @param goldChange the change in the gold count + * + * @throws GameActionException if the resulting amount of gold is negative + */ + public void changeGold(int goldChange) throws GameActionException { + if (goldCount + goldChange < 0) { + throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of gold"); + } + this.goldCount += goldChange; + } } From f96146119a506ba478ad9d44fe229b07985e6384 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 11:07:47 -0500 Subject: [PATCH 080/413] Add canAction functions used by RobotControllerImpl --- .../src/main/battlecode/common/RobotType.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index f93d61c9..06f1bf6c 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -116,6 +116,48 @@ public int getVisionRadiusSquared(int level) { return this.visionRadiusSquared; } + /** + * @return whether this type can attack + */ + public boolean canAttack() { + return (this == WATCHTOWER + || this == SOLDIER); + } + + /** + * @param builtType type of robot being built + * @return whether this type can build the given robot type + */ + public boolean canBuild(RobotType builtType) { + return (this == ARCHON && (builtType == MINER || + builtType == BUILDER || + builtType == SOLDIER || + builtType == SAGE)) || + (this == BUILDER && (builtType == LABORATORY || + builtType == WATCHTOWER)); + } + + /** + * @return whether this type can anomolies + */ + public boolean canUseAnomoly() { + return this == SAGE; + } + + /** + * @return whether this type can convert + */ + public boolean canConvert() { + return this == LABORATORY; + } + + /** + * @return whether this type can mine + */ + public boolean canMine() { + return this == MINER; + } + /** * @return whether or not a given robot is a building */ From 09d85b79015abd573ce57da062c52e898d2be56f Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 11:10:53 -0500 Subject: [PATCH 081/413] Fixed spelling --- engine/src/main/battlecode/common/RobotType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 06f1bf6c..8f1291a6 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -138,9 +138,9 @@ public boolean canBuild(RobotType builtType) { } /** - * @return whether this type can anomolies + * @return whether this type can anomalies */ - public boolean canUseAnomoly() { + public boolean canUseAnomaly() { return this == SAGE; } From 14aac684af808bd1ec027773783708f9c6854475 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 11:24:00 -0500 Subject: [PATCH 082/413] Made parameters private, changed exception type --- .../src/main/battlecode/world/TeamInfo.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 26a3906e..46fff191 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -12,9 +12,9 @@ public class TeamInfo { private GameWorld gameWorld; - int archonCount; - int leadCount; - int goldCount; + private int archonCount; + private int leadCount; + private int goldCount; /** * Create a new representation of TeamInfo @@ -71,11 +71,11 @@ public int getGold() { * * @param newArchonCount the new number of Archons * - * @throws GameActionException if the newArchonCount is negative + * @throws IllegalArgumentException if the newArchonCount is negative */ - public void setArchonCount(int newArchonCount) throws GameActionException { + public void setArchonCount(int newArchonCount) throws IllegalArgumentException { if (newArchonCount < 0) { - throw new GameActionException(CANT_DO_THAT, "Invalid change in number of archons"); + throw new IllegalArgumentException("Invalid archon count"); } this.archonCount = newArchonCount; } @@ -85,11 +85,11 @@ public void setArchonCount(int newArchonCount) throws GameActionException { * * @param leadChange the change in the lead count * - * @throws GameActionException if the resulting amount of lead is negative + * @throws IllegalArgumentException if the resulting amount of lead is negative */ - public void changeLead(int leadChange) throws GameActionException { + public void changeLead(int leadChange) throws IllegalArgumentException { if (leadCount + leadChange < 0) { - throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of lead"); + throw new IllegalArgumentException("Invalid lead change"); } this.leadCount += leadChange; } @@ -99,11 +99,11 @@ public void changeLead(int leadChange) throws GameActionException { * * @param goldChange the change in the gold count * - * @throws GameActionException if the resulting amount of gold is negative + * @throws IllegalArgumentException if the resulting amount of gold is negative */ - public void changeGold(int goldChange) throws GameActionException { + public void changeGold(int goldChange) throws IllegalArgumentException { if (goldCount + goldChange < 0) { - throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of gold"); + throw new IllegalArgumentException("Invalid gold change"); } this.goldCount += goldChange; } From 6e3ea28ce12a45d443ea62d37b11573bd7a30576 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 11:34:18 -0500 Subject: [PATCH 083/413] GameWorld end of round and other methods updated, except for anomalies --- .../main/battlecode/common/GameConstants.java | 14 +- .../src/main/battlecode/world/GameWorld.java | 131 ++++++------------ engine/src/main/battlecode/world/LiveMap.java | 37 +++++ 3 files changed, 88 insertions(+), 94 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 0d6da9bf..535314e8 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -16,16 +16,16 @@ public class GameConstants { // ********************************* /** The minimum possible map height. */ - public static final int MAP_MIN_HEIGHT = 32; + public static final int MAP_MIN_HEIGHT = 30; /** The maximum possible map height. */ - public static final int MAP_MAX_HEIGHT = 64; + public static final int MAP_MAX_HEIGHT = 80; /** The minimum possible map width. */ - public static final int MAP_MIN_WIDTH = 32; + public static final int MAP_MIN_WIDTH = 30; /** The maximum possible map width. */ - public static final int MAP_MAX_WIDTH = 64; + public static final int MAP_MAX_WIDTH = 80; // ********************************* // ****** GAME PARAMETERS ********** @@ -36,6 +36,12 @@ public class GameConstants { /** The bytecode penalty that is imposed each time an exception is thrown. */ public static final int EXCEPTION_BYTECODE_PENALTY = 500; + + /** The amount of lead each team gains per turn. */ + public static final int PASSIVE_LEAD_INCREASE = 5; + + /** The number of rounds between adding lead resources to the map. */ + public static final int ADD_RESOURCE_EVERY_ROUNDS = 20; // ********************************* // ****** COOLDOWNS **************** diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index b4ff29ae..7b5e0f82 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -60,8 +60,6 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match this.rand = new Random(this.gameMap.getSeed()); this.matchMaker = matchMaker; - this.buffsToAdd = new int[2]; - controlProvider.matchStarted(this); // Add the robots contained in the LiveMap to this world. @@ -70,7 +68,8 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match RobotInfo robot = initialBodies[i]; MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y); int newID = spawnRobot(null, robot.type, newLocation, robot.team, robot.influence); - initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, robot.influence, robot.conviction, newLocation); // update with non-deterministic ID and offset location + + initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, 1, robot.health, newLocation); } // Write match header at beginning of match @@ -256,14 +255,10 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int // ****** GAMEPLAY ***************** // ********************************* - public void addBuffs(Team t, int numBuffs) { - this.buffsToAdd[t.ordinal()] += numBuffs; - } public void processBeginningOfRound() { // Increment round counter currentRound++; - this.teamInfo.updateNumBuffs(currentRound); // Process beginning of each robot's round objectInfo.eachRobot((robot) -> { @@ -296,61 +291,53 @@ public boolean setWinnerIfAnnihilated() { } /** - * Sets the winner if one of the teams has more votes than the other. - * - * @return whether or not a winner was set + * @return whether a team has more archons */ - public boolean setWinnerIfMoreVotes() { - int numVotesA = teamInfo.getVotes(Team.A); - int numVotesB = teamInfo.getVotes(Team.B); - if (numVotesA > numVotesB) { - setWinner(Team.A, DominationFactor.MORE_VOTES); + public boolean setWinnerIfMoreArchons(){ + int archonCountA = objectInfo.getRobotTypeCount(Team.A, RobotType.ARCHON); + int archonCountB = objectInfo.getRobotTypeCount(Team.B, RobotType.ARCHON); + + if(archonCountA > archonCountB){ + setWinner(Team.A, DominationFactor.MORE_ARCHONS); return true; - } else if (numVotesB > numVotesA) { - setWinner(Team.B, DominationFactor.MORE_VOTES); + } else if (archonCountA < archonCountB) { + setWinner(Team.B, DominationFactor.MORE_ARCHONS); return true; } return false; } /** - * Sets the winner if one of the teams has more Enlightenment Centers than the other. - * - * @return whether or not a winner was set + * @return whether a team has a greater net Au value */ - public boolean setWinnerIfMoreEnlightenmentCenters() { - int[] numEnlightenmentCenters = new int[2]; + public boolean setWinnerIfMoreGoldValue(){ + int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - if (robot.getType() != RobotType.ENLIGHTENMENT_CENTER) continue; - if (robot.getTeam() == Team.NEUTRAL) continue; - numEnlightenmentCenters[robot.getTeam().ordinal()]++; + totalInfluences[robot.getTeam().ordinal()] += robot.getGoldWorth(); } - if (numEnlightenmentCenters[0] > numEnlightenmentCenters[1]) { - setWinner(Team.A, DominationFactor.MORE_ENLIGHTENMENT_CENTERS); + if (totalInfluences[0] > totalInfluences[1]) { + setWinner(Team.A, DominationFactor.MORE_GOLD_NET_WORTH); return true; - } else if (numEnlightenmentCenters[1] > numEnlightenmentCenters[0]) { - setWinner(Team.B, DominationFactor.MORE_ENLIGHTENMENT_CENTERS); + } else if (totalInfluences[1] > totalInfluences[0]) { + setWinner(Team.B, DominationFactor.MORE_GOLD_NET_WORTH); return true; } return false; } /** - * Sets the winner if one of the teams has higher total unit influence. - * - * @return whether or not a winner was set + * @return whether a team has a greater net Pb value */ - public boolean setWinnerIfMoreInfluence() { + public boolean setWinnerIfMoreLeadValue(){ int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - if (robot.getTeam() == Team.NEUTRAL) continue; - totalInfluences[robot.getTeam().ordinal()] += robot.getInfluence(); + totalInfluences[robot.getTeam().ordinal()] += robot.getLeadWorth(); } if (totalInfluences[0] > totalInfluences[1]) { - setWinner(Team.A, DominationFactor.MORE_INFLUENCE); + setWinner(Team.A, DominationFactor.MORE_LEAD_NET_WORTH); return true; } else if (totalInfluences[1] > totalInfluences[0]) { - setWinner(Team.B, DominationFactor.MORE_INFLUENCE); + setWinner(Team.B, DominationFactor.MORE_LEAD_NET_WORTH); return true; } return false; @@ -368,69 +355,33 @@ public boolean timeLimitReached() { } public void processEndOfRound() { - int[] highestBids = new int[2]; - InternalRobot[] highestBidders = new InternalRobot[2]; - // Process end of each robot's round - objectInfo.eachRobot((robot) -> { - if (robot.getTeam().isPlayer() && robot.getType().canBid()) { - int bid = robot.getBid(); - int teamIdx = robot.getTeam().ordinal(); - if (bid > highestBids[teamIdx] || highestBidders[teamIdx] == null || - (bid == highestBids[teamIdx] && robot.compareTo(highestBidders[teamIdx]) < 0)) { - highestBids[teamIdx] = bid; - highestBidders[teamIdx] = robot; + // Add lead resources to the map + if(this.currentRound == GameConstants.ADD_RESOURCE_EVERY_ROUNDS) + for(int x = 0; x < gameMap.getWidth(); x++) + for(int y = 0; y < gameMap.getHeight(); y++){ + if(gameMap.getLeadAtLocation(x, y) >= 1) + gameMap.addLeadAtLocation(x, y, 5); } - robot.resetBid(); - } + + // Add lead resources to the team + teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); + + // Process end of each robot's round (currently empty in InternalRobot) + objectInfo.eachRobot((robot) -> { robot.processEndOfRound(); return true; }); - // Process bidding - int[] teamVotes = new int[2]; - int[] teamBidderIDs = new int[2]; - - if (highestBids[0] > highestBids[1] && highestBids[0] > 0) { - // Team.A wins - teamVotes[0] = 1; - teamBidderIDs[0] = highestBidders[0].getID(); - highestBidders[0].addInfluenceAndConviction(-highestBids[0]); - this.teamInfo.addVote(Team.A); - } else if (highestBids[1] > highestBids[0] && highestBids[1] > 0) { - // Team.B wins - teamVotes[1] = 1; - teamBidderIDs[1] = highestBidders[1].getID(); - highestBidders[1].addInfluenceAndConviction(-highestBids[1]); - this.teamInfo.addVote(Team.B); - } - - for (int i = 0; i < 2; i++) { - if (teamVotes[i] == 0 && highestBidders[i] != null) { - // Didn't win. If didn't place bid, halfBid == 0 - int halfBid = (highestBids[i] + 1) / 2; - highestBidders[i].addInfluenceAndConviction(-halfBid); - teamBidderIDs[i] = highestBidders[i].getID(); - } - } - - // Add buffs from expose - int nextRound = currentRound + 1; - for (int i = 0; i < 2; i++) { - this.teamInfo.addBuffs(nextRound, Team.values()[i], this.buffsToAdd[i]); - this.buffsToAdd[i] = 0; // reset - } - - // Send team info (votes, bidder IDs, and num buffs) to matchmaker - for (int i = 0; i < 2; i++) - this.matchMaker.addTeamInfo(Team.values()[i], teamVotes[i], teamBidderIDs[i], this.teamInfo.getNumBuffs(Team.values()[i], nextRound)); + // Trigger any anomalies + // Check for end of match setWinnerIfAnnihilated(); if (timeLimitReached() && gameStats.getWinner() == null) - if (!setWinnerIfMoreVotes()) - if (!setWinnerIfMoreEnlightenmentCenters()) - if (!setWinnerIfMoreInfluence()) + if (!setWinnerIfMoreArchons()) + if (!setWinnerIfMoreGoldValue()) + if (!setWinnerIfMoreLeadValue()) setWinnerArbitrary(); if (gameStats.getWinner() != null) diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index c4067066..3b14ee89 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -26,6 +26,11 @@ public strictfp class LiveMap { */ private final MapLocation origin; + /** + * How much lead is stored per square. + */ + private final int[][] leadMap; + /** * The random seed contained in the map file */ @@ -250,6 +255,38 @@ public double[] getPassabilityArray() { return passabilityArray; } + /** + * @param x to get lead at + * @param y to get lead at + * @return the amount of lead at this location + */ + public getLeadAtLocation(int x, int y){ + assert onTheMap(new MapLocation(x, y)); + return this.leadMap[x][y]; + } + + /** + * Changes the amount of lead to amount + * @param x to set lead at + * @param y to set lead at + * @param amount of lead to put at this location + */ + public setLeadAtLocation(int x, int y, int amount){ + assert onTheMap(new MapLocation(x, y)); + this.leadMap[x][y] = amount; + } + + /** + * Adds the amount of lead to current amount at a given square + * @param x to set lead at + * @param y to set lead at + * @param amountToAdd + */ + public addLeadAtLocation(int x, int y, int amountToAdd){ + assert onTheMap(new MapLocation(x, y)); + this.leadMap[x][y] += amountToAdd; + } + @Override public String toString() { if (passabilityArray.length == 0) From c3dda8c7b7ba0d7dbb8401bed1ac67321c51b2e5 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 11:35:01 -0500 Subject: [PATCH 084/413] Added enum for anomalies --- .../main/battlecode/common/AnomalyInfo.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 engine/src/main/battlecode/common/AnomalyInfo.java diff --git a/engine/src/main/battlecode/common/AnomalyInfo.java b/engine/src/main/battlecode/common/AnomalyInfo.java new file mode 100644 index 00000000..8596e991 --- /dev/null +++ b/engine/src/main/battlecode/common/AnomalyInfo.java @@ -0,0 +1,22 @@ +package battlecode.common; + +/** + * Holds the different anomalies in the game. + */ +public enum AnomalyType { + + ABYSS (true, true, GameConstants.ABYSS_COOLDOWN), + CHARGE (true, true, GameConstants.CHARGE_COOLDOWN), + FURY (true, true, GameConstants.FURY_COOLDOWN), + VORTEX (true, false, -1); + + public final boolean isGlobalAnomaly; + public final boolean isSageAnomaly; + public final int sageCooldown; + + AnomalyMode(boolean isGlobalAnomaly, boolean isLocalAnomaly, int sageCooldown) { + this.isGlobalAnomaly = isGlobalAnomaly; + this.isLocalAnomaly = isLocalAnomaly; + this.sageCooldown = sageCooldown; + } +} \ No newline at end of file From dc1364081dba36c4496118adfd30bfa90f982052 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 11:37:07 -0500 Subject: [PATCH 085/413] Added that sages can attack --- engine/src/main/battlecode/common/RobotType.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 8f1291a6..7697a6f5 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -121,7 +121,8 @@ public int getVisionRadiusSquared(int level) { */ public boolean canAttack() { return (this == WATCHTOWER - || this == SOLDIER); + || this == SOLDIER + || this == SAGE); } /** @@ -145,7 +146,7 @@ public boolean canUseAnomaly() { } /** - * @return whether this type can convert + * @return whether this type can convert lead into gold */ public boolean canConvert() { return this == LABORATORY; From f46e974aec7bbd98e0ddef52a434926004b46bd7 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 12:14:41 -0500 Subject: [PATCH 086/413] Basic updates to GameMapIO and RobotInfo --- .../src/main/battlecode/common/RobotInfo.java | 38 +------------------ .../src/main/battlecode/world/GameMapIO.java | 33 ++++++++++------ 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index da7ab4ae..e584c7d2 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -22,28 +22,16 @@ public class RobotInfo { */ public final RobotType type; - /** - * The influence of the robot. - */ - public final int influence; - - /** - * The conviction of the robot. - */ - public final int conviction; - /** * The current location of the robot. */ public final MapLocation location; - public RobotInfo(int ID, Team team, RobotType type, int influence, int conviction, MapLocation location) { + public RobotInfo(int ID, Team team, RobotType type, MapLocation location) { super(); this.ID = ID; this.team = team; this.type = type; - this.influence = influence; - this.conviction = conviction; this.location = location; } @@ -74,24 +62,6 @@ public RobotType getType() { return type; } - /** - * Returns the influence of this robot. - * - * @return the influence of this robot - */ - public int getInfluence() { - return influence; - } - - /** - * Returns the conviction of this robot. - * - * @return the conviction of this robot - */ - public int getConviction() { - return conviction; - } - /** * Returns the location of this robot. * @@ -111,8 +81,6 @@ public boolean equals(Object o) { if (ID != robotInfo.ID) return false; if (team != robotInfo.team) return false; if (type != robotInfo.type) return false; - if (influence != robotInfo.influence) return false; - if (conviction != robotInfo.conviction) return false; return location.equals(robotInfo.location); } @@ -122,8 +90,6 @@ public int hashCode() { result = ID; result = 31 * result + team.hashCode(); result = 31 * result + type.ordinal(); - result = 31 * result + influence; - result = 31 * result + conviction; result = 31 * result + location.hashCode(); return result; } @@ -134,8 +100,6 @@ public String toString() { "ID=" + ID + ", team=" + team + ", type=" + type + - ", influence=" + influence + - ", conviction=" + conviction + ", location=" + location + '}'; } diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index c875c584..a58a2d4e 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -29,9 +29,9 @@ public final strictfp class GameMapIO { private static final ClassLoader BACKUP_LOADER = GameMapIO.class.getClassLoader(); /** - * The file extension for battlecode 2021 match files. + * The file extension for battlecode 2022 match files. */ - public static final String MAP_EXTENSION = ".map21"; + public static final String MAP_EXTENSION = ".map22"; /** * The package we check for maps in if they can't be found in the file system. @@ -229,8 +229,12 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); double[] passabilityArray = new double[width * height]; + int[] leadArray = new int[width * height]; + int[] goldArray = new int[width * height]; for (int i = 0; i < width * height; i++) { passabilityArray[i] = raw.passability(i); + goldArray[i] = raw.gold(i); + leadArray[i] = raw.lead(i); } ArrayList initBodies = new ArrayList<>(); SpawnedBodyTable bodyTable = raw.bodies(); @@ -239,7 +243,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { RobotInfo[] initialBodies = initBodies.toArray(new RobotInfo[initBodies.size()]); return new LiveMap( - width, height, origin, seed, rounds, mapName, initialBodies, passabilityArray + width, height, origin, seed, rounds, mapName, initialBodies, passabilityArray, leadArray, goldArray ); } @@ -255,17 +259,22 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int name = builder.createString(gameMap.getMapName()); int randomSeed = gameMap.getSeed(); double[] passabilityArray = gameMap.getPassabilityArray(); + double[] leadArray = gameMap.getLeadArray(); + double[] goldArray = gameMap.getGoldArray(); // Make body tables ArrayList bodyIDs = new ArrayList<>(); ArrayList bodyTeamIDs = new ArrayList<>(); ArrayList bodyTypes = new ArrayList<>(); ArrayList bodyLocsXs = new ArrayList<>(); ArrayList bodyLocsYs = new ArrayList<>(); - ArrayList bodyInfluences = new ArrayList<>(); ArrayList passabilityArrayList = new ArrayList<>(); + ArrayList leadArrayList = new ArrayList<>(); + ArrayList goldArrayList = new ArrayList<>(); for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) { passabilityArrayList.add(passabilityArray[i]); + leadArrayList.add(leadArray[i]); + goldArrayList.add(goldArray[i]); } for (RobotInfo robot : gameMap.getInitialBodies()) { @@ -274,7 +283,6 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { bodyTypes.add(FlatHelpers.getBodyTypeFromRobotType(robot.type)); bodyLocsXs.add(robot.location.x); bodyLocsYs.add(robot.location.y); - bodyInfluences.add(robot.getInfluence()); } int robotIDs = SpawnedBodyTable.createRobotIDsVector(builder, ArrayUtils.toPrimitive(bodyIDs.toArray(new Integer[bodyIDs.size()]))); @@ -283,15 +291,15 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int locs = VecTable.createVecTable(builder, VecTable.createXsVector(builder, ArrayUtils.toPrimitive(bodyLocsXs.toArray(new Integer[bodyLocsXs.size()]))), VecTable.createYsVector(builder, ArrayUtils.toPrimitive(bodyLocsYs.toArray(new Integer[bodyLocsYs.size()])))); - int influences = SpawnedBodyTable.createInfluencesVector(builder, ArrayUtils.toPrimitive(bodyInfluences.toArray(new Integer[bodyInfluences.size()]))); SpawnedBodyTable.startSpawnedBodyTable(builder); SpawnedBodyTable.addRobotIDs(builder, robotIDs); SpawnedBodyTable.addTeamIDs(builder, teamIDs); SpawnedBodyTable.addTypes(builder, types); SpawnedBodyTable.addLocs(builder, locs); - SpawnedBodyTable.addInfluences(builder, influences); int bodies = SpawnedBodyTable.endSpawnedBodyTable(builder); int passabilityArrayInt = battlecode.schema.GameMap.createPassabilityVector(builder, ArrayUtils.toPrimitive(passabilityArrayList.toArray(new Double[passabilityArrayList.size()]))); + int leadArrayInt = battlecode.schema.GameMap.createLeadVector(builder, ArrayUtils.toPrimitive(leadArrayList.toArray(new Integer[leadArrayList.size()]))); + int goldArrayInt = battlecode.schema.GameMap.createGoldVector(builder, ArrayUtils.toPrimitive(goldArrayList.toArray(new Integer[goldArrayList.size()]))); // Build LiveMap for flatbuffer battlecode.schema.GameMap.startGameMap(builder); battlecode.schema.GameMap.addName(builder, name); @@ -301,6 +309,8 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { battlecode.schema.GameMap.addBodies(builder, bodies); battlecode.schema.GameMap.addRandomSeed(builder, randomSeed); battlecode.schema.GameMap.addPassability(builder, passabilityArrayInt); + battlecode.schema.GameMap.addLead(builder, leadArrayInt); + battlecode.schema.GameMap.addGold(builder, goldArrayInt); return battlecode.schema.GameMap.endGameMap(builder); } @@ -311,16 +321,15 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { private static void initInitialBodiesFromSchemaBodyTable(SpawnedBodyTable bodyTable, ArrayList initialBodies) { VecTable locs = bodyTable.locs(); for (int i = 0; i < bodyTable.robotIDsLength(); i++) { - // all initial bodies should be enlightenment centers, with some influence and 0 conviction + // all initial bodies should be archons RobotType bodyType = FlatHelpers.getRobotTypeFromBodyType(bodyTable.types(i)); int bodyID = bodyTable.robotIDs(i); int bodyX = locs.xs(i); int bodyY = locs.ys(i); Team bodyTeam = TeamMapping.team(bodyTable.teamIDs(i)); - int bodyInfluence = bodyTable.influences(i); - if (bodyType == RobotType.ENLIGHTENMENT_CENTER) - initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, bodyInfluence, bodyInfluence, new MapLocation(bodyX, bodyY))); - // ignore robots that are not enlightenment centers, TODO throw error? + if (bodyType == RobotType.ARCHON) + initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, new MapLocation(bodyX, bodyY))); + // ignore robots that are not archons, TODO throw error? } } } From a770718350adbb02ece19a29f866b1e55c89efef Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 12:40:04 -0500 Subject: [PATCH 087/413] Unfinished changes to GameWorld for reference --- .../src/main/battlecode/common/GameConstants.java | 2 +- .../battlecode/world/AnomalyScheduleEntry.java | 15 +++++++++++++++ engine/src/main/battlecode/world/GameWorld.java | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 engine/src/main/battlecode/world/AnomalyScheduleEntry.java diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 535314e8..8d8dc868 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -83,5 +83,5 @@ public class GameConstants { public static final int GAME_DEFAULT_SEED = 6370; /** The maximum number of rounds in a game. **/ - public static final int GAME_MAX_NUMBER_OF_ROUNDS = 1500; + public static final int GAME_MAX_NUMBER_OF_ROUNDS = 2000; } diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java new file mode 100644 index 00000000..b0b1f81c --- /dev/null +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -0,0 +1,15 @@ +package battlecode.world; + +public class AnomalyScheduleEntry { + + private int roundNumber; + public AnomalyInfo anomalyType; + + public AnomalyScheduleEntry(int round, int anomaly){ + this.roundNumber = round; + this.anomalyType = anomaly; + } + + + +} \ No newline at end of file diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 7b5e0f82..daa7bb9b 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -376,6 +376,7 @@ public void processEndOfRound() { // Trigger any anomalies + // Check for end of match setWinnerIfAnnihilated(); if (timeLimitReached() && gameStats.getWinner() == null) From 8646f753ae350c804cce02b88e3c4764adfcea40 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 12:42:56 -0500 Subject: [PATCH 088/413] Minor changes to anomaly --- engine/src/main/battlecode/world/AnomalyScheduleEntry.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index b0b1f81c..3c9abe5f 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -2,14 +2,12 @@ public class AnomalyScheduleEntry { - private int roundNumber; - public AnomalyInfo anomalyType; + public final int roundNumber; + public final AnomalyInfo anomalyType; public AnomalyScheduleEntry(int round, int anomaly){ this.roundNumber = round; this.anomalyType = anomaly; } - - } \ No newline at end of file From 998c26a8448440e9bb1d2ab3f1ed4c5c8d9f8d16 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:30:51 -0500 Subject: [PATCH 089/413] Updated anomaly enum --- .../main/battlecode/common/AnomalyInfo.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/engine/src/main/battlecode/common/AnomalyInfo.java b/engine/src/main/battlecode/common/AnomalyInfo.java index 8596e991..c8a738a5 100644 --- a/engine/src/main/battlecode/common/AnomalyInfo.java +++ b/engine/src/main/battlecode/common/AnomalyInfo.java @@ -5,18 +5,24 @@ */ public enum AnomalyType { - ABYSS (true, true, GameConstants.ABYSS_COOLDOWN), - CHARGE (true, true, GameConstants.CHARGE_COOLDOWN), - FURY (true, true, GameConstants.FURY_COOLDOWN), - VORTEX (true, false, -1); + ABYSS (true, true, 0.1, 0.2), + CHARGE (true, true, 0.05, 0.1), + FURY (true, true, 0.05, 0.1), + VORTEX (true, false, 0, 0), + SINGULARITY (); + public final boolean isGlobalAnomaly; public final boolean isSageAnomaly; - public final int sageCooldown; + public final float globalPercentage; + public final float sagePercentage; - AnomalyMode(boolean isGlobalAnomaly, boolean isLocalAnomaly, int sageCooldown) { + + AnomalyMode(boolean isGlobalAnomaly, boolean isLocalAnomaly, float globalPercentage, float sagePercentage) { this.isGlobalAnomaly = isGlobalAnomaly; this.isLocalAnomaly = isLocalAnomaly; - this.sageCooldown = sageCooldown; + this.globalPercentage = globalPercentage; + this.sagePercentage = sagePercentage; + } } \ No newline at end of file From beb78faab5a4c25f5b2c4d57df953f73bde7fe26 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:31:55 -0500 Subject: [PATCH 090/413] Added sage methods --- .../battlecode/common/RobotController.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index ef3f0d65..2ea47ccb 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -435,6 +435,29 @@ public strictfp interface RobotController { */ void attack(MapLocation loc) throws GameActionException; + // ***************************** + // ******** SAGE METHODS ******* + // ***************************** + + /** + * Tests whether this robot can use an anomaly centered at the robots location. + * + * Checks that the robot is a sage. + * + * @return whether it is possible to use an anomaly centered at the robots location. + * + * @battlecode.doc.costlymethod + */ + boolean canUseAnomaly(AnomalyType anomaly); + + /** + * Use anomaly centered at robots location. + * + * @throws GameActionException if conditions for using anomaly are not satisfied + * @battlecode.doc.costlymethod + */ + void useAnomaly(AnomalyType anomaly) throws GameActionException; + // ***************************** // ****** ARCHON METHODS ****** // ***************************** From 4830b026d2d30307f1087e3812b4c964e1bf2b30 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:32:41 -0500 Subject: [PATCH 091/413] Added heal and repair functionality --- .../main/battlecode/world/InternalRobot.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index a8cd6176..56db95d1 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -304,6 +304,18 @@ public void upgrade() { this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); } + /** + * Repair another robot. Assumes bot is in range. + * + * @param bot the robot to be repaired + */ + public void repair(InternalRobot bot) { + if (!this.canActLocation(bot.location)) + return; // TODO: throw exception? + int repairAmount = this.type.getHealing(this.level); + bot.addHealth(healingAmount); + } + /** * Attacks another robot. Assumes bot is in range. * Note: this is relatively inefficient(?), can possibly optimize @@ -318,6 +330,20 @@ public void attack(InternalRobot bot) { bot.addHealth(-dmg); } + /** + * Heals another robot. Assumes bot is in range. + * Note: this is relatively inefficient(?), can possibly optimize + * by making better helper methods in GameWorld + * + * @param bot the robot to be healed + */ + public void heal(InternalRobot bot) { + if (!this.canActLocation(bot.location)) + return; // TODO: throw exception? + int healingAmount = this.type.getHealing(this.level); + bot.addHealth(healingAmount); + } + // ********************************* // ****** GAMEPLAY METHODS ********* // ********************************* From 29da58125510a8efdb481ecec08a7bba7dd36bef Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:37:50 -0500 Subject: [PATCH 092/413] Updated cooldowns, exceptions, sage methods and minor other changes --- .../battlecode/world/RobotControllerImpl.java | 96 +++++++++++++------ 1 file changed, 67 insertions(+), 29 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index b8f24430..f823f4b5 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -114,7 +114,7 @@ public MapLocation getLocation() { @Override public int getHealth() { - return this.robot.getHeatlh(); + return this.robot.getHealth(); } @Override @@ -360,12 +360,12 @@ public boolean canMove(Direction dir) { } catch (GameActionException e) { return false; } } - // TODO: Check cooldown turns @Override public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - this.robot.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); + RobotType type = this.robot.getType(); + this.robot.addMovementCooldownTurns(type.movementCooldown); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); @@ -389,11 +389,11 @@ private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActio int goldNeeded = type.getGoldCost(); Team team = getTeam(); if (gameWorld.getTeamInfo().getLead(team) < leadNeeded) { - throw new GameActionException(CANT_DO_THAT, + throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of lead."); } if (gameWorld.getTeamInfo().getGold(team) < goldNeeded) { - throw new GameActionException(CANT_DO_THAT, + throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of gold."); } @@ -404,9 +404,6 @@ private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActio if (isLocationOccupied(spawnLoc)) throw new GameActionException(CANT_MOVE_THERE, "Cannot spawn to an occupied location; " + spawnLoc + " is occupied."); - if (!isActionReady()) - throw new GameActionException(IS_NOT_READY, - "Robot is still cooling down! You need to wait before you can perform another action."); } @Override @@ -424,8 +421,9 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); + RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(GameConstants.BUILD_COOLDOWN); + this.robot.addActionCooldownTurns(type.actionCooldown); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-leadNeeded); @@ -471,13 +469,46 @@ public boolean canAttack(MapLocation loc){ @Override public void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); - this.robot.addActionCooldownTurns(GameConstants.ATTACK_COOLDOWN); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); this.robot.attack(bot); int attackedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); } + // ***************************** + // ******** SAGE METHODS ******* + // ***************************** + + private void assertCanUseAnomaly(AnomalyType anomaly) throws GameActionException { + assertIsActionReady(); + if (!getType().canUseAnomaly()) { + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot use anomaly."); + } + if (!anomaly.isSageAnomaly){ + throw new GameActionException(CANT_DO_THAT, + "Sage can not use anomaly of type " + anomaly.toString()); + } + } + + @Override + public boolean canUseAnomaly(AnomalyType anomaly){ + try { + assertCanUseAnomaly(anomaly); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + public void useAnomaly(AnomalyType anomaly) throws GameActionException{ + assertCanUseAnomaly(anomaly); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); + gameWorld.getMatchMaker().addAction(getID(), Action.USE_ANOMALY, anomaly); + } + // ***************************** // ****** ARCHON METHODS ******* // ***************************** @@ -514,9 +545,10 @@ public boolean canHealDroid(MapLocation loc){ @Override public void healDroid(MapLocation loc) throws GameActionException{ assertCanHealDroid(loc); - this.robot.healDroid(loc); - this.robot.addActionCooldownTurns(GameConstants.HEAL_COOLDOWN); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); + this.robot.healDroid(bot); int healedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); } @@ -555,8 +587,10 @@ public boolean canMineLead(MapLocation loc){ public void mineLead(MapLocation loc) throws GameActionException{ assertCanMineLead(loc); this.robot.mineLead(loc); - this.robot.addLead(1); //TODO: do we want to this here or in the implementation - this.robot.addActionCooldownTurns(GameConstants.MINE_COOLDOWN); + Team robotTeam = this.robot.getTeam(); + robotTeam.addLead(1); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } @@ -591,7 +625,8 @@ public void mineGold(MapLocation loc) throws GameActionException{ this.robot.mineGold(loc); Team robotTeam = this.robot.getTeam(); robotTeam.addGold(1); - this.robot.addActionCooldownTurns(GameConstants.MINE_COOLDOWN); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } @@ -620,11 +655,11 @@ private void assertCanUpgrade(MapLocation loc) throws GameActionException { "Robot is not on your team so can't be upgraded."); } if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadUpgradeCost()){ - throw new GameActionException(CANT_DO_THAT, + throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough lead to upgrade this robot."); } if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldUpgradeCost()){ - throw new GameActionException(CANT_DO_THAT, + throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough gold to upgrade this robot."); } } @@ -640,7 +675,6 @@ public boolean canUpgrade(MapLocation loc){ @Override public void upgrade(MapLocation loc) throws GameActionException{ assertCanUpgrade(loc); - this.robot.upgrade(loc); InternalRobot bot = gameWorld.getRobot(loc); RobotType type = bot.getType(); int upgradeLevel = bot.getUpgradeLevel(); @@ -648,12 +682,14 @@ public void upgrade(MapLocation loc) throws GameActionException{ int leadNeeded = type.getLeadUpgradeCost(upgradeLevel); int goldNeeded = type.getGoldUpgradeCost(upgradeLevel); - + bot.upgrade(); Team robotTeam = this.robot.getTeam(); robotTeam.addGold(-goldNeeded); robotTeam.addLead(-leadNeeded); - this.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - this.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + RobotType type = this.robot.getType(); + this.addActionCooldownTurns(type.actionCooldown); + bot.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); + bot.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); int upgradedID = bot.getID(); gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); } @@ -689,8 +725,11 @@ public boolean canRepairBuilding(MapLocation loc){ @Override public void repairBuilding(MapLocation loc) throws GameActionException{ assertCanRepairBuilding(loc); - this.robot.repairBuilding(loc); - this.robot.addActionCooldownTurns(GameConstants.REPAIR_COOLDOWN); + InternalRobot bot = gameWorld.getRobot(loc); + + this.robot.repair(bot); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); int repairedID = bot.getID(); @@ -726,7 +765,8 @@ public boolean canConvert() { public void convert() throws GameActionException { assertCanConvert(); this.robot.convert(); - this.robot.addActionCooldownTurns(GameConstants.CONVERT_COOLDOWN); + RobotType type = this.robot.getType(); + this.robot.addActionCooldownTurns(type.actionCooldown); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE); robotTeam.addGold(1); @@ -740,6 +780,7 @@ public void convert() throws GameActionException { private void assertCanTransform() throws GameActionException { assertIsActionReady(); + assertIsMovementReady(); if (!robot.getMode() == RobotMode.TURRET || !robot.getMode() == RobotMode.PORTABLE) { throw new GameActionException(CANT_DO_THAT, "Robot is not transformable."); @@ -759,11 +800,8 @@ public void transform() throws GameActionException { assertCanTransform(); robot.transform(); RobotMode mode = robot.getMode(); - if (mode == RobotMode.TURRET) { - addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); - } else { - addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); - } + addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); } // *********************************** From c793d0caf7b5fb0941b0eb5a0d8da50e1f8bfb94 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:48:44 -0500 Subject: [PATCH 093/413] Added singularity --- engine/src/main/battlecode/common/AnomalyInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/AnomalyInfo.java b/engine/src/main/battlecode/common/AnomalyInfo.java index c8a738a5..cce4e420 100644 --- a/engine/src/main/battlecode/common/AnomalyInfo.java +++ b/engine/src/main/battlecode/common/AnomalyInfo.java @@ -9,7 +9,7 @@ public enum AnomalyType { CHARGE (true, true, 0.05, 0.1), FURY (true, true, 0.05, 0.1), VORTEX (true, false, 0, 0), - SINGULARITY (); + SINGULARITY (true, false, 0, 0); public final boolean isGlobalAnomaly; From ff82d6a732ad5256e422cd099d9c22f832a4350a Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 13:52:18 -0500 Subject: [PATCH 094/413] Added calls for handling anomalies --- .../src/main/battlecode/world/RobotControllerImpl.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index f823f4b5..bd01dbb0 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -505,6 +505,16 @@ public boolean canUseAnomaly(AnomalyType anomaly){ public void useAnomaly(AnomalyType anomaly) throws GameActionException{ assertCanUseAnomaly(anomaly); RobotType type = this.robot.getType(); + switch (anomaly) { + case ABYSS: + gameWorld.causeAbyss(this.robot); + case CHARGE: + gameWorld.causeCharge(this.robot); + case FURY: + gameWorld.causeFury(this.robot); + default: + throw IllegalArgumentException("Anomaly is not of the right type, should not get here"); + } this.robot.addActionCooldownTurns(type.actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.USE_ANOMALY, anomaly); } From 0aacf001a08c462b58c54ce37177f95698b7b8c2 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 14:03:32 -0500 Subject: [PATCH 095/413] First version of Abyss --- .../main/battlecode/common/GameConstants.java | 1 + .../src/main/battlecode/world/GameWorld.java | 97 ++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 8d8dc868..ff5cb46d 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -84,4 +84,5 @@ public class GameConstants { /** The maximum number of rounds in a game. **/ public static final int GAME_MAX_NUMBER_OF_ROUNDS = 2000; + } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index daa7bb9b..1915c2d0 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -374,7 +374,7 @@ public void processEndOfRound() { }); // Trigger any anomalies - + // Check for end of match @@ -435,6 +435,101 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti profilerCollections.put(team, profilerCollection); } + + // ********************************* + // ******** ANOMALY ************** + // ********************************* + + /** + * Performs the Abyss anomaly. + * Changes the resources in the squares and the team. + * @param reduceFactor associated with anomaly (a decimal percentage) + * @param locations that can be affected by the Abyss. + */ + public void causeAbyssGridUpdate(int reduceFactor, ArrayList locations){ + + while(locations.hasNext()){ + MapLocation currentLocation = locations.next(); + int x = currentLocation.x; + int y = currentLocation.y; + int currentLead = gameMap.getLeadAtLocation(x, y); + int leadUpdate = (int) (reduceFactor * currentLead); + gameMap.setLeadAtLocation(x, y, currentLead - leadUpdate); + } + } + + /** + * Finds all of the locations that a given Sage can affect with an Anomaly. + * @param robot that is causing the anomaly. Must be a Sage. + * @return all of the locations that are within range of this sage. + */ + public void getSageActionLocations(InternalRobot robot){ + + ArrayList actionLocations = new ArrayList(); + + assert robot.type == RobotType.SAGE; + MapLocation center = robot.getLocation(); + + int radius = robot.getActionRadiusSquared(robot.level); + int rawStartX = Math.floor(Math.max(0, center.x - radius)); + int rawStartY = Math.floor(Math.max(0, center.y - radius)); + int rawEndX = Math.ceil(Math.max(this.map.getWidth(), center.x + radius)); + int rawEndY = Math.ceil(Math.max(this.map.getHeight(), center.y + radius)); + + for(int x = rawStartX; x < rawEndX, x++) + for(int y = rawStartY; y < rawEndY; y++){ + MapLocation proposedLocation = new MapLocation(x, y)); + if(robot.canActLocation(proposedLocation)) + actionLocations.add(proposedLocation); + } + + return actionLocations; + } + + /** + * Mutates state to perform the Sage Abyss anomaly. + * @param robot that is the Sage + * @param anomaly that corresponds to Abyss type + */ + public void causeAbyssSage(InternalRobot robot, AnomalyInfo anomaly){ + + assert anomaly == AnomalyType.ABYSS; + ArrayList actionLocations = new ArrayList(); + + for(int x = 0; x < this.map.getWidth(); x++) + for(int y = 0; y < this.map.getHeight(); y++) + actionLocations.add(new MapLocation(x, y)); + + // calculate the right effect range + this.causeAbyssGridUpdate(anomaly.sagePercentage, actionLocations); + } + + /** + * Mutates state to perform the global Abyss anomaly. + * @param anomaly that corresponds to Abyss type + */ + public void causeAbyssGlobal(AnomalyInfo anomaly){ + assert anomaly == AnomalyType.ABYSS; + this.causeAbyssGridUpdate(anomaly.globalPercentage, 0, 0, gameMap.getWidth(), gameMap.getHeight()); + + // change team resources + teamInfo.changeLead( (int) ( -1 * GameConstants.ABYSS_LOSS_PERCENTANGE * teamInfo.getLead()) ); + teamInfo.changeGold( (int) ( -1 * GameConstants.ABYSS_LOSS_PERCENTANGE * teamInfo.getGold()) ); + } + + public void causeFurySage(){ + + + + } + + public void causeFuryGlobal(){ + + } + + // unallocated : charge (sage, global) is taken + // vortex is taken + } From 19974f279e706e81303659df8662e08afe8deec0 Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 14:23:13 -0500 Subject: [PATCH 096/413] Switched repair to heal, inlined getting type, fixed typo --- .../main/battlecode/common/AnomalyInfo.java | 2 +- .../main/battlecode/world/InternalRobot.java | 12 ------- .../battlecode/world/RobotControllerImpl.java | 32 +++++++------------ 3 files changed, 12 insertions(+), 34 deletions(-) diff --git a/engine/src/main/battlecode/common/AnomalyInfo.java b/engine/src/main/battlecode/common/AnomalyInfo.java index cce4e420..3918f8cb 100644 --- a/engine/src/main/battlecode/common/AnomalyInfo.java +++ b/engine/src/main/battlecode/common/AnomalyInfo.java @@ -18,7 +18,7 @@ public enum AnomalyType { public final float sagePercentage; - AnomalyMode(boolean isGlobalAnomaly, boolean isLocalAnomaly, float globalPercentage, float sagePercentage) { + AnomalyType(boolean isGlobalAnomaly, boolean isLocalAnomaly, float globalPercentage, float sagePercentage) { this.isGlobalAnomaly = isGlobalAnomaly; this.isLocalAnomaly = isLocalAnomaly; this.globalPercentage = globalPercentage; diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 56db95d1..c228c0af 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -304,18 +304,6 @@ public void upgrade() { this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); } - /** - * Repair another robot. Assumes bot is in range. - * - * @param bot the robot to be repaired - */ - public void repair(InternalRobot bot) { - if (!this.canActLocation(bot.location)) - return; // TODO: throw exception? - int repairAmount = this.type.getHealing(this.level); - bot.addHealth(healingAmount); - } - /** * Attacks another robot. Assumes bot is in range. * Note: this is relatively inefficient(?), can possibly optimize diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index bd01dbb0..4c481dea 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -364,8 +364,7 @@ public boolean canMove(Direction dir) { public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - RobotType type = this.robot.getType(); - this.robot.addMovementCooldownTurns(type.movementCooldown); + this.robot.addMovementCooldownTurns(this.robot.getType().movementCooldown); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); @@ -421,9 +420,8 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-leadNeeded); @@ -469,8 +467,7 @@ public boolean canAttack(MapLocation loc){ @Override public void attack(MapLocation loc) throws GameActionException{ assertCanAttack(loc); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); this.robot.attack(bot); int attackedID = bot.getID(); @@ -504,7 +501,6 @@ public boolean canUseAnomaly(AnomalyType anomaly){ @Override public void useAnomaly(AnomalyType anomaly) throws GameActionException{ assertCanUseAnomaly(anomaly); - RobotType type = this.robot.getType(); switch (anomaly) { case ABYSS: gameWorld.causeAbyss(this.robot); @@ -515,7 +511,7 @@ public void useAnomaly(AnomalyType anomaly) throws GameActionException{ default: throw IllegalArgumentException("Anomaly is not of the right type, should not get here"); } - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.USE_ANOMALY, anomaly); } @@ -555,8 +551,7 @@ public boolean canHealDroid(MapLocation loc){ @Override public void healDroid(MapLocation loc) throws GameActionException{ assertCanHealDroid(loc); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); this.robot.healDroid(bot); int healedID = bot.getID(); @@ -599,8 +594,7 @@ public void mineLead(MapLocation loc) throws GameActionException{ this.robot.mineLead(loc); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(1); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } @@ -635,8 +629,7 @@ public void mineGold(MapLocation loc) throws GameActionException{ this.robot.mineGold(loc); Team robotTeam = this.robot.getTeam(); robotTeam.addGold(1); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } @@ -696,8 +689,7 @@ public void upgrade(MapLocation loc) throws GameActionException{ Team robotTeam = this.robot.getTeam(); robotTeam.addGold(-goldNeeded); robotTeam.addLead(-leadNeeded); - RobotType type = this.robot.getType(); - this.addActionCooldownTurns(type.actionCooldown); + this.addActionCooldownTurns(this.robot.getType().actionCooldown); bot.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); bot.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); int upgradedID = bot.getID(); @@ -737,9 +729,8 @@ public void repairBuilding(MapLocation loc) throws GameActionException{ assertCanRepairBuilding(loc); InternalRobot bot = gameWorld.getRobot(loc); - this.robot.repair(bot); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.heal(bot); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); int repairedID = bot.getID(); @@ -775,8 +766,7 @@ public boolean canConvert() { public void convert() throws GameActionException { assertCanConvert(); this.robot.convert(); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); Team robotTeam = this.robot.getTeam(); robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE); robotTeam.addGold(1); From 4f1767999c5faf18549827a2e97a1ef4ad5ebfd8 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 14:41:45 -0500 Subject: [PATCH 097/413] Copies of the anomaly schedule --- .../world/AnomalyScheduleEntry.java | 15 +++++++ .../src/main/battlecode/world/GameWorld.java | 11 +++-- engine/src/main/battlecode/world/LiveMap.java | 44 +++++++++++++++++++ .../battlecode/world/RobotControllerImpl.java | 7 +++ 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index 3c9abe5f..59d66aa3 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -10,4 +10,19 @@ public AnomalyScheduleEntry(int round, int anomaly){ this.anomalyType = anomaly; } + /** + * @return a copy of the entry + */ + public copyEntry(AnomalyType anomalyType){ + return new AnomalyScheduleEntry( + anomalyType.round, + new AnomalyType( + anomalyType.isGlobalAnomaly, + anomalyType.isLocalAnomaly, + anomalyType.globalPercentage, + anomalyType.sagePercentage + ) + ); + } + } \ No newline at end of file diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 1915c2d0..876460ac 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -174,6 +174,13 @@ public Team getWinner() { return this.gameStats.getWinner(); } + /** + * Defensively copied at the level of LiveMap. + */ + public AnomalyScheduleEntry[] getAnomalySchedule(){ + return this.gameMap.getAnomalySchedule(); + } + public boolean isRunning() { return this.running; } @@ -374,8 +381,7 @@ public void processEndOfRound() { }); // Trigger any anomalies - - + // Check for end of match setWinnerIfAnnihilated(); @@ -519,7 +525,6 @@ public void causeAbyssGlobal(AnomalyInfo anomaly){ public void causeFurySage(){ - } diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 3b14ee89..a0919d60 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -46,6 +46,16 @@ public strictfp class LiveMap { */ private final String mapName; + /** + * List of anomalies that will occur at certain rounds. + */ + private final AnomalyScheduleEntry[] anomalySchedule; + + /** + * Index of next anomaly to occur (excluding Singularity which always occurs) + */ + private int nextAnomalyIndex; + /** * The bodies to spawn on the map; MapLocations are in world space - * i.e. in game correct MapLocations that need to have the origin @@ -76,6 +86,11 @@ public LiveMap(int width, // invariant: bodies is sorted by id Arrays.sort(this.initialBodies, (a, b) -> Integer.compare(a.getID(), b.getID())); + + // TODO: initialize with potentially hardcoded anomalies + this.anomalySchedule = {}; + this.nextAnomalyIndex = 0; + } public LiveMap(int width, @@ -287,6 +302,35 @@ public addLeadAtLocation(int x, int y, int amountToAdd){ this.leadMap[x][y] += amountToAdd; } + /** + * @return a copy of the next Anomaly that hasn't happened yet. + */ + public viewNextAnomaly(){ + return this.anomalySchedule[this.nextAnomalyIndex].copyEntry(); + } + + /** + * Removes the current anomaly by advancing to the next one. + * @return the next Anomaly. + */ + public takeNextAnomaly(){ + return this.anomalySchedule[this.nextAnomalyIndex++].copyEntry(); + } + + /** + * @return a copy of the anomaly schedule + */ + public AnomalyScheduleEntry[] getAnomalySchedule(){ + + AnomalyScheduleEntry[] anomalyCopy = new AnomalyScheduleEntry[this.anomalySchedule.length]; + + for(int i = 0; i < this.anomalySchedule.length ; i++) + anomalyCopy[i] = this.anomalySchedule[i].copyEntry(); + + return anomalyCopy; + } + + @Override public String toString() { if (passabilityArray.length == 0) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index b8f24430..b314ed68 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -128,6 +128,13 @@ private InternalRobot getRobotByID(int id) { return this.gameWorld.getObjectInfo().getRobotByID(id); } + /** + * Returns a fully copied version of the anomaly schedule. + */ + public AnomalyScheduleEntry[] getAnomalySchedule(){ + this.gameWorld.getAnomalySchedule(); + } + // *********************************** // ****** GENERAL VISION METHODS ***** From 12d40b04e21d469a946039a2d170370a48ce5aba Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 14:42:35 -0500 Subject: [PATCH 098/413] Converted passability to rubble in all files except schema/GameMap, instrumenter/bytecode/resources/MethodCosts.txt, world/maps/* --- .../battlecode/common/RobotController.java | 8 ++--- .../src/main/battlecode/world/GameMapIO.java | 16 +++++----- .../src/main/battlecode/world/GameWorld.java | 8 ++--- engine/src/main/battlecode/world/LiveMap.java | 32 +++++++++---------- .../src/main/battlecode/world/MapBuilder.java | 30 ++++++++--------- .../battlecode/world/RobotControllerImpl.java | 4 +-- .../main/battlecode/world/TestMapBuilder.java | 10 +++--- 7 files changed, 54 insertions(+), 54 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 57b7fce1..b6c23cf8 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -239,18 +239,18 @@ public strictfp interface RobotController { RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team); /** - * Given a location, returns the passability of that location. + * Given a location, returns the rubble of that location. * - * Lower passability means that robots on this location may be penalized + * Higher rubble means that robots on this location may be penalized * greater cooldowns for making actions. * * @param loc the given location - * @return the passability of that location. + * @return the rubble of that location. * @throws GameActionException if the robot cannot sense the given location * * @battlecode.doc.costlymethod */ - double sensePassability(MapLocation loc) throws GameActionException; + double senseRubble(MapLocation loc) throws GameActionException; /** * Given a location, returns the lead count of that location. diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index c875c584..f1c81481 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -228,9 +228,9 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int seed = raw.randomSeed(); final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); - double[] passabilityArray = new double[width * height]; + int[] rubbleArray = new int[width * height]; for (int i = 0; i < width * height; i++) { - passabilityArray[i] = raw.passability(i); + rubbleArray[i] = raw.rubble(i); } ArrayList initBodies = new ArrayList<>(); SpawnedBodyTable bodyTable = raw.bodies(); @@ -239,7 +239,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { RobotInfo[] initialBodies = initBodies.toArray(new RobotInfo[initBodies.size()]); return new LiveMap( - width, height, origin, seed, rounds, mapName, initialBodies, passabilityArray + width, height, origin, seed, rounds, mapName, initialBodies, rubbleArray ); } @@ -254,7 +254,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int name = builder.createString(gameMap.getMapName()); int randomSeed = gameMap.getSeed(); - double[] passabilityArray = gameMap.getPassabilityArray(); + int[] rubbleArray = gameMap.getRubbleArray(); // Make body tables ArrayList bodyIDs = new ArrayList<>(); ArrayList bodyTeamIDs = new ArrayList<>(); @@ -262,10 +262,10 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { ArrayList bodyLocsXs = new ArrayList<>(); ArrayList bodyLocsYs = new ArrayList<>(); ArrayList bodyInfluences = new ArrayList<>(); - ArrayList passabilityArrayList = new ArrayList<>(); + ArrayList rubbleArrayList = new ArrayList<>(); for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) { - passabilityArrayList.add(passabilityArray[i]); + rubbleArrayList.add(rubbleArray[i]); } for (RobotInfo robot : gameMap.getInitialBodies()) { @@ -291,7 +291,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { SpawnedBodyTable.addLocs(builder, locs); SpawnedBodyTable.addInfluences(builder, influences); int bodies = SpawnedBodyTable.endSpawnedBodyTable(builder); - int passabilityArrayInt = battlecode.schema.GameMap.createPassabilityVector(builder, ArrayUtils.toPrimitive(passabilityArrayList.toArray(new Double[passabilityArrayList.size()]))); + int rubbleArrayInt = battlecode.schema.GameMap.createRubbleVector(builder, ArrayUtils.toPrimitive(rubbleArrayList.toArray(new Integer[rubbleArrayList.size()]))); // Build LiveMap for flatbuffer battlecode.schema.GameMap.startGameMap(builder); battlecode.schema.GameMap.addName(builder, name); @@ -300,7 +300,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { gameMap.getOrigin().y + gameMap.getHeight())); battlecode.schema.GameMap.addBodies(builder, bodies); battlecode.schema.GameMap.addRandomSeed(builder, randomSeed); - battlecode.schema.GameMap.addPassability(builder, passabilityArrayInt); + battlecode.schema.GameMap.addRubble(builder, rubbleArrayInt); return battlecode.schema.GameMap.endGameMap(builder); } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index b4ff29ae..9b2bd96b 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -28,7 +28,7 @@ public strictfp class GameWorld { protected final IDGenerator idGenerator; protected final GameStats gameStats; - private double[] passability; + private int[] rubble; private InternalRobot[][] robots; private final LiveMap gameMap; private final TeamInfo teamInfo; @@ -44,7 +44,7 @@ public strictfp class GameWorld { @SuppressWarnings("unchecked") public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) { - this.passability = gm.getPassabilityArray(); + this.rubble = gm.getRubbleArray(); this.robots = new InternalRobot[gm.getWidth()][gm.getHeight()]; // if represented in cartesian, should be height-width, but this should allow us to index x-y this.currentRound = 0; this.idGenerator = new IDGenerator(gm.getSeed()); @@ -183,8 +183,8 @@ public int getCurrentRound() { return this.currentRound; } - public double getPassability(MapLocation loc) { - return this.passability[locationToIndex(loc)]; + public double getRubble(MapLocation loc) { + return this.rubble[locationToIndex(loc)]; } /** diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index c4067066..923a4ef0 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -48,7 +48,7 @@ public strictfp class LiveMap { */ private final RobotInfo[] initialBodies; // only contains Enlightenment Centers - private double[] passabilityArray; // factor to multiply cooldowns by + private int[] rubbleArray; // factor to multiply cooldowns by public LiveMap(int width, int height, @@ -64,9 +64,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.passabilityArray = new double[width * height]; - for (int i = 0; i < passabilityArray.length; i++) { - this.passabilityArray[i] = 1; // default cooldown factor is 1 + this.rubbleArray = new int[width * height]; + for (int i = 0; i < rubbleArray.length; i++) { + this.rubbleArray[i] = 1; // default cooldown factor is 1 } // invariant: bodies is sorted by id @@ -80,7 +80,7 @@ public LiveMap(int width, int rounds, String mapName, RobotInfo[] initialBodies, - double[] passabilityArray) { + int[] rubbleArray) { this.width = width; this.height = height; this.origin = origin; @@ -88,9 +88,9 @@ public LiveMap(int width, this.rounds = rounds; this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); - this.passabilityArray = new double[passabilityArray.length]; - for (int i = 0; i < passabilityArray.length; i++) { - this.passabilityArray[i] = passabilityArray[i]; + this.rubbleArray = new int[rubbleArray.length]; + for (int i = 0; i < rubbleArray.length; i++) { + this.rubbleArray[i] = rubbleArray[i]; } // invariant: bodies is sorted by id @@ -104,7 +104,7 @@ public LiveMap(int width, */ public LiveMap(LiveMap gm) { this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.initialBodies, - gm.passabilityArray); + gm.rubbleArray); } @Override @@ -127,7 +127,7 @@ public boolean equals(LiveMap other) { if (this.seed != other.seed) return false; if (!this.mapName.equals(other.mapName)) return false; if (!this.origin.equals(other.origin)) return false; - if (!Arrays.equals(this.passabilityArray, other.passabilityArray)) return false; + if (!Arrays.equals(this.rubbleArray, other.rubbleArray)) return false; return Arrays.equals(this.initialBodies, other.initialBodies); } @@ -139,7 +139,7 @@ public int hashCode() { result = 31 * result + seed; result = 31 * result + rounds; result = 31 * result + mapName.hashCode(); - result = 31 * result + Arrays.hashCode(passabilityArray); + result = 31 * result + Arrays.hashCode(rubbleArray); result = 31 * result + Arrays.hashCode(initialBodies); return result; } @@ -246,13 +246,13 @@ public MapLocation getOrigin() { return origin; } - public double[] getPassabilityArray() { - return passabilityArray; + public int[] getRubbleArray() { + return rubbleArray; } @Override public String toString() { - if (passabilityArray.length == 0) + if (rubbleArray.length == 0) return "LiveMap{" + "width=" + width + ", height=" + height + @@ -261,7 +261,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", len=" + Integer.toString(passabilityArray.length) + + ", len=" + Integer.toString(rubbleArray.length) + "}"; else return "LiveMap{" + "width=" + width + @@ -271,7 +271,7 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", passabilityArray=:)" + Arrays.toString(passabilityArray) + + ", rubbleArray=:)" + Arrays.toString(rubbleArray) + "}"; } } \ No newline at end of file diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 31b1547b..e9f8af4c 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -19,7 +19,7 @@ public enum MapSymmetry {rotational, horizontal, vertical}; public MapLocation origin; public int seed; private MapSymmetry symmetry; - private double[] passabilityArray; + private int[] rubbleArray; private int idCounter; private List bodies; @@ -35,9 +35,9 @@ public MapBuilder(String name, int width, int height, int originX, int originY, // default values this.symmetry = MapSymmetry.vertical; this.idCounter = 0; - this.passabilityArray = new double[width*height]; - for (int i = 0; i < passabilityArray.length; i++) { - passabilityArray[i] = 1; // default cooldown factor is 1 + this.rubbleArray = new int[width*height]; + for (int i = 0; i < rubbleArray.length; i++) { + rubbleArray[i] = 1; // default cooldown factor is 1 } } @@ -81,8 +81,8 @@ public void addEnlightenmentCenter(int x, int y, Team team, int influence) { ); } - public void setPassability(int x, int y, double value) { - this.passabilityArray[locationToIndex(x, y)] = value; + public void setRubble(int x, int y, int value) { + this.rubbleArray[locationToIndex(x, y)] = value; } public void setSymmetry(MapSymmetry symmetry) { @@ -142,9 +142,9 @@ public void addSymmetricNeutralEnlightenmentCenter(int x, int y, int influence) addEnlightenmentCenter(symmetricX(x), symmetricY(y), Team.NEUTRAL, influence); } - public void setSymmetricPassability(int x, int y, double value) { - this.passabilityArray[locationToIndex(x, y)] = value; - this.passabilityArray[locationToIndex(symmetricX(x), symmetricY(y))] = value; + public void setSymmetricRubble(int x, int y, int value) { + this.rubbleArray[locationToIndex(x, y)] = value; + this.rubbleArray[locationToIndex(symmetricX(x), symmetricY(y))] = value; } // ******************** @@ -153,7 +153,7 @@ public void setSymmetricPassability(int x, int y, double value) { public LiveMap build() { return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, - bodies.toArray(new RobotInfo[bodies.size()]), passabilityArray); + bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray); } /** @@ -208,13 +208,13 @@ public void assertIsValid() { for (int y = 0; y < height; y++) { MapLocation current = new MapLocation(x, y); // This should also be a GameConstant, but I'm speed-coding this and we can fix this later - if (passabilityArray[locationToIndex(current.x, current.y)] < 0.1 || passabilityArray[locationToIndex(current.x, current.y)] > 1.0) { - throw new RuntimeException("Map passability not between 0.1 and 1.0"); + if (rubbleArray[locationToIndex(current.x, current.y)] <= 100 || rubbleArray[locationToIndex(current.x, current.y)] >= 0) { + throw new RuntimeException("Map rubble not between 0 and 100"); } } } - // assert passability and Enlightenment Center symmetry + // assert rubble and Enlightenment Center symmetry ArrayList allMapSymmetries = getSymmetry(robots); System.out.println("This map has the following symmetries: " + allMapSymmetries); boolean doesContain = false; @@ -222,7 +222,7 @@ public void assertIsValid() { if (sss == symmetry) doesContain = true; } if (!doesContain) { - throw new RuntimeException("Passability and Enlightenment Centers must be symmetric according to the given symmetry; they are not currently."); + throw new RuntimeException("Rubble and Enlightenment Centers must be symmetric according to the given symmetry; they are not currently."); } } @@ -249,7 +249,7 @@ private ArrayList getSymmetry(RobotInfo[] robots) { for (int i = possible.size()-1; i >= 0; i--) { // iterating backwards so we can remove in the loop MapSymmetry symmetry = possible.get(i); MapLocation symm = new MapLocation(symmetricX(x, symmetry), symmetricY(y, symmetry)); - if (passabilityArray[locationToIndex(current.x, current.y)] != passabilityArray[locationToIndex(symm.x, symm.y)]) possible.remove(symmetry); + if (rubbleArray[locationToIndex(current.x, current.y)] != rubbleArray[locationToIndex(symm.x, symm.y)]) possible.remove(symmetry); RobotInfo sri = robots[locationToIndex(symm.x, symm.y)]; if (!(cri == null) || !(sri == null)) { if (cri == null || sri == null) { diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9528dd7c..e2dd224a 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -284,9 +284,9 @@ public MapLocation[] detectNearbyRobots(MapLocation center, int radiusSquared) { } @Override - public double sensePassability(MapLocation loc) throws GameActionException { + public int senseRubble(MapLocation loc) throws GameActionException { assertCanSenseLocation(loc); - return this.gameWorld.getPassability(loc); + return this.gameWorld.getRubble(loc); } @Override diff --git a/engine/src/main/battlecode/world/TestMapBuilder.java b/engine/src/main/battlecode/world/TestMapBuilder.java index 15485aba..df941097 100644 --- a/engine/src/main/battlecode/world/TestMapBuilder.java +++ b/engine/src/main/battlecode/world/TestMapBuilder.java @@ -14,7 +14,7 @@ public class TestMapBuilder { private int height; private int seed; private int rounds; - private double[] passabilityArray; + private int[] rubbleArray; private List bodies; @@ -44,11 +44,11 @@ public TestMapBuilder addEnlightenmentCenter(int id, Team team, int influence, M return this; } - public TestMapBuilder setPassability() { - this.passabilityArray = new double[width * height]; + public TestMapBuilder setRubble() { + this.rubbleArray = new double[width * height]; for(int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - this.passabilityArray[i + j * width] = (i * j + i + j) / (i * j + 1); + this.rubbleArray[i + j * width] = (i * j + i + j) / (i * j + 1); } } return this; @@ -60,6 +60,6 @@ public TestMapBuilder addBody(RobotInfo info) { } public LiveMap build() { - return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, bodies.toArray(new RobotInfo[bodies.size()]), passabilityArray); + return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray); } } From f8a61a02ea9469953a5b7de19c41a5068cbfc923 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 14:45:41 -0500 Subject: [PATCH 099/413] Fixed leftover double int conversions for passaibility and rubble --- engine/src/main/battlecode/common/RobotController.java | 6 +++--- engine/src/main/battlecode/world/GameWorld.java | 2 +- engine/src/main/battlecode/world/TestMapBuilder.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index b6c23cf8..8e49353d 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -250,7 +250,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - double senseRubble(MapLocation loc) throws GameActionException; + int senseRubble(MapLocation loc) throws GameActionException; /** * Given a location, returns the lead count of that location. @@ -261,7 +261,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - double senseLead(MapLocation loc) throws GameActionException; + int senseLead(MapLocation loc) throws GameActionException; /** * Given a location, returns the gold count of that location. @@ -272,7 +272,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - double senseGold(MapLocation loc) throws GameActionException; + int senseGold(MapLocation loc) throws GameActionException; /** * Returns the location adjacent to current location in the given direction. diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 9b2bd96b..e3b850f9 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -183,7 +183,7 @@ public int getCurrentRound() { return this.currentRound; } - public double getRubble(MapLocation loc) { + public int getRubble(MapLocation loc) { return this.rubble[locationToIndex(loc)]; } diff --git a/engine/src/main/battlecode/world/TestMapBuilder.java b/engine/src/main/battlecode/world/TestMapBuilder.java index df941097..c0d4ddf0 100644 --- a/engine/src/main/battlecode/world/TestMapBuilder.java +++ b/engine/src/main/battlecode/world/TestMapBuilder.java @@ -45,7 +45,7 @@ public TestMapBuilder addEnlightenmentCenter(int id, Team team, int influence, M } public TestMapBuilder setRubble() { - this.rubbleArray = new double[width * height]; + this.rubbleArray = new int[width * height]; for(int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { this.rubbleArray[i + j * width] = (i * j + i + j) / (i * j + 1); From 1f31305b6763b8ca010d5109bec14a277c85f06b Mon Sep 17 00:00:00 2001 From: Pranali Date: Fri, 10 Dec 2021 14:53:03 -0500 Subject: [PATCH 100/413] Updated calls to trigger anomalies --- engine/src/main/battlecode/world/RobotControllerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 4c481dea..4b97d84b 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -503,11 +503,11 @@ public void useAnomaly(AnomalyType anomaly) throws GameActionException{ assertCanUseAnomaly(anomaly); switch (anomaly) { case ABYSS: - gameWorld.causeAbyss(this.robot); + gameWorld.causeAbyssSage(this.robot, anomaly); case CHARGE: - gameWorld.causeCharge(this.robot); + gameWorld.causeChargeSage(this.robot, anomaly); case FURY: - gameWorld.causeFury(this.robot); + gameWorld.causeFurySage(this.robot, anomaly); default: throw IllegalArgumentException("Anomaly is not of the right type, should not get here"); } From 6b6d3a24c0f6666b4f5bdc66b4747b8d5ba21925 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 15:15:44 -0500 Subject: [PATCH 101/413] More work for anomalies --- .../src/main/battlecode/world/GameWorld.java | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 876460ac..da6df016 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -452,7 +452,7 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti * @param reduceFactor associated with anomaly (a decimal percentage) * @param locations that can be affected by the Abyss. */ - public void causeAbyssGridUpdate(int reduceFactor, ArrayList locations){ + private void causeAbyssGridUpdate(int reduceFactor, ArrayList locations){ while(locations.hasNext()){ MapLocation currentLocation = locations.next(); @@ -469,7 +469,7 @@ public void causeAbyssGridUpdate(int reduceFactor, ArrayList locati * @param robot that is causing the anomaly. Must be a Sage. * @return all of the locations that are within range of this sage. */ - public void getSageActionLocations(InternalRobot robot){ + private void getSageActionLocations(InternalRobot robot){ ArrayList actionLocations = new ArrayList(); @@ -519,21 +519,44 @@ public void causeAbyssGlobal(AnomalyInfo anomaly){ this.causeAbyssGridUpdate(anomaly.globalPercentage, 0, 0, gameMap.getWidth(), gameMap.getHeight()); // change team resources - teamInfo.changeLead( (int) ( -1 * GameConstants.ABYSS_LOSS_PERCENTANGE * teamInfo.getLead()) ); - teamInfo.changeGold( (int) ( -1 * GameConstants.ABYSS_LOSS_PERCENTANGE * teamInfo.getGold()) ); + teamInfo.changeLead( (int) ( -1 * anomaly.globalPercentage * teamInfo.getLead()) ); + teamInfo.changeGold( (int) ( -1 * anomaly.globalPercentage * teamInfo.getGold()) ); } - public void causeFurySage(){ + /** + * Mutates state to perform the Sage Fury. + * @param robot that is performing the Fury. + * @param anomaly that corresponds to Fury type + */ + public void causeFurySage(InternalRobot robot, AnomalyInfo anomaly){ + assert robot.getType() == RobotType.type; + assert anomaly == AnomalyType.FURY; + objectInfo.eachRobot((robot) -> { + if (robot.isBuilding() && (robot.getType() == TURRET)){ + robot.addHealth((int) (-1 * robot.getType().getMaxHealth() * anomaly.sagePercentage)); + } + }); + } - public void causeFuryGlobal(){ + /** + * Mutates state to peform the global Fury. + * @param anomaly that corresponds to Fury type + */ + // public void causeFuryGlobal(AnomalyInfo anomaly){ - } + // assert anomaly == AnomalyType.FURY; + + // this.getSageActionLocations(robot); + + // } + + public void causeChargeSage(){} + + public void causeChargeGlobal(){} - // unallocated : charge (sage, global) is taken - // vortex is taken } From 8dfa728f2e9b02f3d0e9103b6c1e3e59c551d212 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 10 Dec 2021 15:28:38 -0500 Subject: [PATCH 102/413] Implemented alchemist loneliness --- engine/src/main/battlecode/common/GameConstants.java | 7 ++++--- engine/src/main/battlecode/common/RobotController.java | 7 +++++++ .../src/main/battlecode/world/RobotControllerImpl.java | 10 ++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 0d6da9bf..2b5f6199 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -50,9 +50,6 @@ public class GameConstants { /** The number of cooldown turns per transformation. */ public static final int TRANSFORM_COOLDOWN = 100; - /** The number of cooldown turns per upgrade. */ - public static final int UPGRADE_COOLDOWN = 100; - // ********************************* // ****** GAME MECHANICS *********** // ********************************* @@ -69,6 +66,10 @@ public class GameConstants { /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; + public static final double ALCHEMIST_LONELINESS_A = 20; + public static final double ALCHEMIST_LONELINESS_B = 15; + public static final double ALCHEMIST_LONELINESS_K = 0.02; + // ********************************* // ****** GAMEPLAY PROPERTIES ****** // ********************************* diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 2ea47ccb..3f49af05 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -599,6 +599,13 @@ public strictfp interface RobotController { */ boolean canConvert(); + /** + * Get lead to gold conversion rate. + * + * @battlecode.doc.costlymethod + */ + public int getGoldExchangeRate(); + /** * Convert lead into gold. * diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index bd01dbb0..0778418b 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -771,14 +771,20 @@ public boolean canConvert() { } // TODO: Implement convert in InternalRobot + @Override + public int getGoldExchangeRate() { + return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * + Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * nearbyRobotCount)) + } + @Override public void convert() throws GameActionException { assertCanConvert(); - this.robot.convert(); RobotType type = this.robot.getType(); this.robot.addActionCooldownTurns(type.actionCooldown); Team robotTeam = this.robot.getTeam(); - robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE); + int nearbyRobotCount = seeNearbyRobots(); + robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE * getGoldExchangeRate()); robotTeam.addGold(1); gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY); From 95b4be42b7715226c57839ca069e0389e7b15f0f Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 17:59:00 -0500 Subject: [PATCH 103/413] First version of GameWorld changes --- .../src/main/battlecode/world/GameWorld.java | 180 ++++++++++++------ .../main/battlecode/world/InternalRobot.java | 7 + .../battlecode/world/RobotControllerImpl.java | 10 + 3 files changed, 144 insertions(+), 53 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 08dc156a..a9242abd 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -268,6 +268,29 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int return returnLocations.toArray(new MapLocation[0]); } + /** + * @return all of the locations on the grid. + */ + private void getAllLocations(){ + + ArrayList actionLocations = new ArrayList(); + + for(int x = 0; x < this.map.getWidth(); x++) + for(int y = 0; y < this.map.getHeight(); y++) + actionLocations.add(new MapLocation(x, y)); + + return actionLocations; + } + + /** + * @param cooldown without multiplier applied. + * @param location with rubble of interest, if any + * @return the cooldown due to rubble. + */ + public int getCooldownMultiplier(int cooldown, MapLocation location){ + return Math.floor( (1 + this.getRubble(location) / 10) * cooldown); + } + // ********************************* // ****** GAMEPLAY ***************** // ********************************* @@ -390,7 +413,15 @@ public void processEndOfRound() { }); // Trigger any anomalies - + // note: singularity is handled below in the "check for end of match" + if(this.gameMap.viewNextAnomaly().round == this.currentRound){ + AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; + if(anomaly == AnomalyType.ABYSS) this.causeAbyssGlobal(anomaly); + if(anomaly == AnomalyType.CHARGE) this.causeChargeGlobal(anomaly); + if(anomaly == AnomalyType.FURY) this.causeFuryGlobal(anomaly); + // TODO: uncomment this whenever causeVortexGlobal is called. + // if(anomaly == AnomalyType.VORTEX) this.causeVortexGlobal(anomaly); + } // Check for end of match setWinnerIfAnnihilated(); @@ -428,10 +459,15 @@ public int spawnRobot(InternalRobot parent, RobotType type, MapLocation location // ********************************* public void destroyRobot(int id) { + InternalRobot robot = objectInfo.getRobotByID(id); removeRobot(robot.getLocation()); - - // TODO: take care of things that happen when robot dies + + int leadDropped = robot.getType().getLeadDropped(); + int goldDropped = robot.getType().getGoldDropped(); + + this.leadCount[locationToIndex(robot.getLocation())] += leadDropped; + this.goldCount[locationToIndex(robot.getLocation())] += goldDropped; controlProvider.robotKilled(robot); objectInfo.destroyRobot(id); @@ -455,50 +491,56 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti // ******** ANOMALY ************** // ********************************* + /** + * Finds all of the locations that a given Sage can affect with an Anomaly. + * @param robot that is causing the anomaly. Must be a Sage. + * @return all of the locations that are within range of this sage. + */ + private void getSageActionLocations(InternalRobot robot){ + + assert robot.getType() == RobotType.SAGE; + MapLocation center = robot.getLocation(); + + return getAllLocationsWithinRadiusSquared(center, robot.getType().getActionRadiusSquared()); + } + /** * Performs the Abyss anomaly. * Changes the resources in the squares and the team. * @param reduceFactor associated with anomaly (a decimal percentage) * @param locations that can be affected by the Abyss. */ - private void causeAbyssGridUpdate(int reduceFactor, ArrayList locations){ + private void causeAbyssGridUpdate(float reduceFactor, ArrayList locations){ while(locations.hasNext()){ MapLocation currentLocation = locations.next(); int x = currentLocation.x; int y = currentLocation.y; + int currentLead = gameMap.getLeadAtLocation(x, y); int leadUpdate = (int) (reduceFactor * currentLead); gameMap.setLeadAtLocation(x, y, currentLead - leadUpdate); + + int currentGold = gameMap.getGoldAtLocation(x, y); + int goldUpdate = (int) (reduceFactor * currentGold); + gameMap.setLeadAtLocation(x, y, currentGold - goldUpdate); } } /** - * Finds all of the locations that a given Sage can affect with an Anomaly. - * @param robot that is causing the anomaly. Must be a Sage. - * @return all of the locations that are within range of this sage. + * Performs the Fury anomaly. + * Changes the health of the relevant robots. + * @param reduceFactor associated with anomaly (a decimal percentage) + * @param locations that can be affected by the Fury (by radius, not by state of robot) */ - private void getSageActionLocations(InternalRobot robot){ - - ArrayList actionLocations = new ArrayList(); - - assert robot.type == RobotType.SAGE; - MapLocation center = robot.getLocation(); + public void causeFuryUpdate(float reduceFactor, MapLocation[] locations){ - int radius = robot.getActionRadiusSquared(robot.level); - int rawStartX = Math.floor(Math.max(0, center.x - radius)); - int rawStartY = Math.floor(Math.max(0, center.y - radius)); - int rawEndX = Math.ceil(Math.max(this.map.getWidth(), center.x + radius)); - int rawEndY = Math.ceil(Math.max(this.map.getHeight(), center.y + radius)); - - for(int x = rawStartX; x < rawEndX, x++) - for(int y = rawStartY; y < rawEndY; y++){ - MapLocation proposedLocation = new MapLocation(x, y)); - if(robot.canActLocation(proposedLocation)) - actionLocations.add(proposedLocation); + for(int i = 0; i < locations.length; i++){ + InternalRobot robot = this.getRobot(locations[i]); + if(robot.isBulding() && robot.getType() == TURRET){ + robot.addHealth((int) (-1 * robot.getType().getMaxHealth() * reduceFactor)); } - - return actionLocations; + } } /** @@ -506,26 +548,23 @@ private void getSageActionLocations(InternalRobot robot){ * @param robot that is the Sage * @param anomaly that corresponds to Abyss type */ - public void causeAbyssSage(InternalRobot robot, AnomalyInfo anomaly){ + public void causeAbyssSage(InternalRobot robot, AnomalyType anomaly){ + assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.ABYSS; - ArrayList actionLocations = new ArrayList(); - - for(int x = 0; x < this.map.getWidth(); x++) - for(int y = 0; y < this.map.getHeight(); y++) - actionLocations.add(new MapLocation(x, y)); // calculate the right effect range - this.causeAbyssGridUpdate(anomaly.sagePercentage, actionLocations); + this.causeAbyssGridUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); } /** * Mutates state to perform the global Abyss anomaly. * @param anomaly that corresponds to Abyss type */ - public void causeAbyssGlobal(AnomalyInfo anomaly){ + public void causeAbyssGlobal(AnomalyType anomaly){ + assert anomaly == AnomalyType.ABYSS; - this.causeAbyssGridUpdate(anomaly.globalPercentage, 0, 0, gameMap.getWidth(), gameMap.getHeight()); + this.causeAbyssGridUpdate(anomaly.globalPercentage, this.getAllLocations()); // change team resources teamInfo.changeLead( (int) ( -1 * anomaly.globalPercentage * teamInfo.getLead()) ); @@ -534,38 +573,73 @@ public void causeAbyssGlobal(AnomalyInfo anomaly){ /** * Mutates state to perform the Sage Fury. - * @param robot that is performing the Fury. + * @param robot performing the Fury, must be a Sage * @param anomaly that corresponds to Fury type */ - public void causeFurySage(InternalRobot robot, AnomalyInfo anomaly){ + public void causeFurySage(InternalRobot robot, AnomalyType anomaly){ - assert robot.getType() == RobotType.type; + assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.FURY; - objectInfo.eachRobot((robot) -> { - if (robot.isBuilding() && (robot.getType() == TURRET)){ - robot.addHealth((int) (-1 * robot.getType().getMaxHealth() * anomaly.sagePercentage)); - } - }); - + this.causeFuryUpdate(robot.sagePercentage, this.getSageActionLocations(robot)); } /** * Mutates state to peform the global Fury. * @param anomaly that corresponds to Fury type */ - // public void causeFuryGlobal(AnomalyInfo anomaly){ - - // assert anomaly == AnomalyType.FURY; - - // this.getSageActionLocations(robot); - - // } + public void causeFuryGlobal(AnomalyType anomaly){ + assert anomaly == AnomalyType.FURY; + this.causeFuryUpdate(robot.globalPercentage, this.getAllLocations()); + } - public void causeChargeSage(){} + /** + * Mutates state to perform the Sage Charge. + * @param robot performing the Charge, must be a Sage + * @param anomaly that corresponds to Charge type + */ + public void causeChargeSage(InternalRobot robot, AnomalyType anomaly){ + assert robot.getType() == RobotType.SAGE; + assert anomaly == AnomalyType.CHARGE; + + InternalRobot[] actionLocations = this.getSageActionLocations(robot); + for(int i = 0; i < actionLocations.length; i++){ + InternalRobot currentRobot = getRobot(actionLocations[i]); + currentRobot.addHealth((int) (-1 * anomaly.sagePercentage * currentRobot.getMaxHealth())); + } + } - public void causeChargeGlobal(){} + /** + * Mutates state to peform the global Charge. + * @param anomaly that corresponds to Charge type + */ + public void causeChargeGlobal(AnomalyType anomaly){ + assert anomaly == AnomalyType.CHARGE; + + // need to determine top 5 percentage of friendly robots + // max health + + // 12/10/21: https://www.baeldung.com/java-stream-to-array + // 12/10/21: https://www.geeksforgeeks.org/arrays-stream-method-in-java/ + // above (references for what kinds of functions to call): + // converting stream to array, getting the stream + Stream droids = Arrays.stream(robots).filter(robot -> robot.isBuilding()).toArray(InternalRobot[]::new); + // end citations + + // for syntax/logic on how to sort in reverse order + // 12/10/21: https://www.baeldung.com/java-8-sort-lambda + droids.sort( + (InternalRobot robot1, InternalRobot robot2) -> + (robot2.numberOfVisibleFriendlyRobots() - robot1.numberOfVisibleFriendlyRobots()) + ); + // end citation + + int affectedDroidsLimit = (int) (anomaly.globalPercentage * droids.length); + for(int i = 0; i < affectedDroidsLimit; i++){ + this.destroyRobot(droids[i].getID()); + } + } } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index c228c0af..2d2baabf 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -387,6 +387,13 @@ public void die_exception() { // ****** MISC. METHODS ******************** // ***************************************** + /** + * @return the number of friendly robots within sensor (vision) radius. + */ + public RobotInfo[] numberOfVisibleFriendlyRobots(){ + return this.controller.numberOfVisibleFriendlyRobots(); + } + @Override public boolean equals(Object o) { return o != null && (o instanceof InternalRobot) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 4bf1b208..25ecab70 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -237,6 +237,16 @@ public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team t return validSeenRobots.toArray(new RobotInfo[validSeenRobots.size()]); } + /** + * @return the number of friendly robots within sensor (vision) radius. + */ + public RobotInfo[] numberOfVisibleFriendlyRobots(){ + return this.seeNearbyRobots( + this.robot.getVisionRadiusSquared() + this.robot.getTeam() + ).length; + } + @Override public int seeRubble(MapLocation loc) throws GameActionException { assertCanSenseLocation(loc); From 4e173a8aa4d1869491d36894d1fa01e003d85ee8 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 19:49:49 -0500 Subject: [PATCH 104/413] Changes to fix compilation issues --- .../{AnomalyInfo.java => AnomalyType.java} | 4 +- .../world/AnomalyScheduleEntry.java | 15 ++-- .../src/main/battlecode/world/GameWorld.java | 77 ++++++++----------- .../main/battlecode/world/InternalRobot.java | 7 +- engine/src/main/battlecode/world/LiveMap.java | 19 +++-- .../battlecode/world/RobotControllerImpl.java | 6 +- 6 files changed, 61 insertions(+), 67 deletions(-) rename engine/src/main/battlecode/common/{AnomalyInfo.java => AnomalyType.java} (80%) diff --git a/engine/src/main/battlecode/common/AnomalyInfo.java b/engine/src/main/battlecode/common/AnomalyType.java similarity index 80% rename from engine/src/main/battlecode/common/AnomalyInfo.java rename to engine/src/main/battlecode/common/AnomalyType.java index 3918f8cb..118365a6 100644 --- a/engine/src/main/battlecode/common/AnomalyInfo.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -18,9 +18,9 @@ public enum AnomalyType { public final float sagePercentage; - AnomalyType(boolean isGlobalAnomaly, boolean isLocalAnomaly, float globalPercentage, float sagePercentage) { + AnomalyType(boolean isGlobalAnomaly, boolean isSageAnomaly, float globalPercentage, float sagePercentage) { this.isGlobalAnomaly = isGlobalAnomaly; - this.isLocalAnomaly = isLocalAnomaly; + this.isSageAnomaly = isSageAnomaly; this.globalPercentage = globalPercentage; this.sagePercentage = sagePercentage; diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index 59d66aa3..357ecb83 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -1,11 +1,12 @@ package battlecode.world; +import battlecode.common.*; public class AnomalyScheduleEntry { public final int roundNumber; - public final AnomalyInfo anomalyType; + public final AnomalyType anomalyType; - public AnomalyScheduleEntry(int round, int anomaly){ + public AnomalyScheduleEntry(int round, AnomalyType anomaly){ this.roundNumber = round; this.anomalyType = anomaly; } @@ -13,12 +14,12 @@ public AnomalyScheduleEntry(int round, int anomaly){ /** * @return a copy of the entry */ - public copyEntry(AnomalyType anomalyType){ - return new AnomalyScheduleEntry( - anomalyType.round, - new AnomalyType( + public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType){ + return AnomalyScheduleEntry( + this.roundNumber, + AnomalyType( anomalyType.isGlobalAnomaly, - anomalyType.isLocalAnomaly, + anomalyType.isSageAnomaly, anomalyType.globalPercentage, anomalyType.sagePercentage ) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index a9242abd..0b532cec 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -69,7 +69,7 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match for (int i = 0; i < initialBodies.length; i++) { RobotInfo robot = initialBodies[i]; MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y); - int newID = spawnRobot(null, robot.type, newLocation, robot.team, robot.influence); + int newID = spawnRobot(robot.type, newLocation, robot.team); initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, 1, robot.health, newLocation); } @@ -271,15 +271,8 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int /** * @return all of the locations on the grid. */ - private void getAllLocations(){ - - ArrayList actionLocations = new ArrayList(); - - for(int x = 0; x < this.map.getWidth(); x++) - for(int y = 0; y < this.map.getHeight(); y++) - actionLocations.add(new MapLocation(x, y)); - - return actionLocations; + private MapLocation[] getAllLocations(){ + return getAllLocationsWithinRadiusSquared(new MapLocation(0, 0), Integer.MAX_VALUE); } /** @@ -288,7 +281,7 @@ private void getAllLocations(){ * @return the cooldown due to rubble. */ public int getCooldownMultiplier(int cooldown, MapLocation location){ - return Math.floor( (1 + this.getRubble(location) / 10) * cooldown); + return (int) ((1 + this.getRubble(location) / 10) * cooldown); } // ********************************* @@ -352,7 +345,7 @@ public boolean setWinnerIfMoreArchons(){ public boolean setWinnerIfMoreGoldValue(){ int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - totalInfluences[robot.getTeam().ordinal()] += robot.getGoldWorth(); + totalInfluences[robot.getTeam().ordinal()] += robot.getType().getGoldWorth(robot.getLevel()); } if (totalInfluences[0] > totalInfluences[1]) { setWinner(Team.A, DominationFactor.MORE_GOLD_NET_WORTH); @@ -370,7 +363,7 @@ public boolean setWinnerIfMoreGoldValue(){ public boolean setWinnerIfMoreLeadValue(){ int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - totalInfluences[robot.getTeam().ordinal()] += robot.getLeadWorth(); + totalInfluences[robot.getTeam().ordinal()] += robot.getType().getLeadWorth(robot.getLevel()); } if (totalInfluences[0] > totalInfluences[1]) { setWinner(Team.A, DominationFactor.MORE_LEAD_NET_WORTH); @@ -414,7 +407,7 @@ public void processEndOfRound() { // Trigger any anomalies // note: singularity is handled below in the "check for end of match" - if(this.gameMap.viewNextAnomaly().round == this.currentRound){ + if(this.gameMap.viewNextAnomaly().roundNumber == this.currentRound){ AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; if(anomaly == AnomalyType.ABYSS) this.causeAbyssGlobal(anomaly); if(anomaly == AnomalyType.CHARGE) this.causeChargeGlobal(anomaly); @@ -439,8 +432,8 @@ public void processEndOfRound() { // ****** SPAWNING ***************** // ********************************* - public int spawnRobot(InternalRobot parent, int ID, RobotType type, MapLocation location, Team team, int influence) { - InternalRobot robot = new InternalRobot(this, parent, ID, type, location, team, influence); + public int spawnRobot(int ID, RobotType type, MapLocation location, Team team) { + InternalRobot robot = new InternalRobot(this, ID, type, location, team); objectInfo.spawnRobot(robot); addRobot(location, robot); @@ -449,9 +442,9 @@ public int spawnRobot(InternalRobot parent, int ID, RobotType type, MapLocation return ID; } - public int spawnRobot(InternalRobot parent, RobotType type, MapLocation location, Team team, int influence) { + public int spawnRobot(RobotType type, MapLocation location, Team team) { int ID = idGenerator.nextID(); - return spawnRobot(parent, ID, type, location, team, influence); + return spawnRobot(ID, type, location, team); } // ********************************* @@ -463,8 +456,8 @@ public void destroyRobot(int id) { InternalRobot robot = objectInfo.getRobotByID(id); removeRobot(robot.getLocation()); - int leadDropped = robot.getType().getLeadDropped(); - int goldDropped = robot.getType().getGoldDropped(); + int leadDropped = robot.getType().getLeadDropped(robot.getLevel()); + int goldDropped = robot.getType().getGoldDropped(robot.getLevel()); this.leadCount[locationToIndex(robot.getLocation())] += leadDropped; this.goldCount[locationToIndex(robot.getLocation())] += goldDropped; @@ -496,12 +489,12 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti * @param robot that is causing the anomaly. Must be a Sage. * @return all of the locations that are within range of this sage. */ - private void getSageActionLocations(InternalRobot robot){ + private MapLocation[] getSageActionLocations(InternalRobot robot){ assert robot.getType() == RobotType.SAGE; MapLocation center = robot.getLocation(); - return getAllLocationsWithinRadiusSquared(center, robot.getType().getActionRadiusSquared()); + return getAllLocationsWithinRadiusSquared(center, robot.getType().getActionRadiusSquared(robot.getLevel())); } /** @@ -510,10 +503,11 @@ private void getSageActionLocations(InternalRobot robot){ * @param reduceFactor associated with anomaly (a decimal percentage) * @param locations that can be affected by the Abyss. */ - private void causeAbyssGridUpdate(float reduceFactor, ArrayList locations){ + private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations){ - while(locations.hasNext()){ - MapLocation currentLocation = locations.next(); + for(int i = 0; i < locations.length; i++){ + + MapLocation currentLocation = locations[i]; int x = currentLocation.x; int y = currentLocation.y; @@ -537,8 +531,8 @@ public void causeFuryUpdate(float reduceFactor, MapLocation[] locations){ for(int i = 0; i < locations.length; i++){ InternalRobot robot = this.getRobot(locations[i]); - if(robot.isBulding() && robot.getType() == TURRET){ - robot.addHealth((int) (-1 * robot.getType().getMaxHealth() * reduceFactor)); + if(robot.getType().isBuilding() && robot.getMode() == RobotMode.TURRET){ + robot.addHealth((int) (-1 * robot.getType().getMaxHealth(robot.getLevel()) * reduceFactor)); } } } @@ -581,7 +575,7 @@ public void causeFurySage(InternalRobot robot, AnomalyType anomaly){ assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.FURY; - this.causeFuryUpdate(robot.sagePercentage, this.getSageActionLocations(robot)); + this.causeFuryUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); } /** @@ -590,7 +584,7 @@ public void causeFurySage(InternalRobot robot, AnomalyType anomaly){ */ public void causeFuryGlobal(AnomalyType anomaly){ assert anomaly == AnomalyType.FURY; - this.causeFuryUpdate(robot.globalPercentage, this.getAllLocations()); + this.causeFuryUpdate(anomaly.globalPercentage, this.getAllLocations()); } /** @@ -602,10 +596,10 @@ public void causeChargeSage(InternalRobot robot, AnomalyType anomaly){ assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.CHARGE; - InternalRobot[] actionLocations = this.getSageActionLocations(robot); + MapLocation[] actionLocations = this.getSageActionLocations(robot); for(int i = 0; i < actionLocations.length; i++){ InternalRobot currentRobot = getRobot(actionLocations[i]); - currentRobot.addHealth((int) (-1 * anomaly.sagePercentage * currentRobot.getMaxHealth())); + currentRobot.addHealth((int) (-1 * anomaly.sagePercentage * currentRobot.getType().getMaxHealth(currentRobot.getLevel()))); } } @@ -614,25 +608,22 @@ public void causeChargeSage(InternalRobot robot, AnomalyType anomaly){ * @param anomaly that corresponds to Charge type */ public void causeChargeGlobal(AnomalyType anomaly){ + assert anomaly == AnomalyType.CHARGE; - // need to determine top 5 percentage of friendly robots - // max health + ArrayList rawDroids = new ArrayList(); - // 12/10/21: https://www.baeldung.com/java-stream-to-array - // 12/10/21: https://www.geeksforgeeks.org/arrays-stream-method-in-java/ - // above (references for what kinds of functions to call): - // converting stream to array, getting the stream - Stream droids = Arrays.stream(robots).filter(robot -> robot.isBuilding()).toArray(InternalRobot[]::new); - // end citations + for(InternalRobot currentRobot : this.objectInfo.robotsArray()) + if(!currentRobot.getType().isBuilding()) + rawDroids.add(currentRobot); + + InternalRobot[] droids = rawDroids.toArray(new InternalRobot[rawDroids.size()]); - // for syntax/logic on how to sort in reverse order - // 12/10/21: https://www.baeldung.com/java-8-sort-lambda - droids.sort( + Arrays.sort( + droids, (InternalRobot robot1, InternalRobot robot2) -> (robot2.numberOfVisibleFriendlyRobots() - robot1.numberOfVisibleFriendlyRobots()) ); - // end citation int affectedDroidsLimit = (int) (anomaly.globalPercentage * droids.length); for(int i = 0; i < affectedDroidsLimit; i++){ diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 2d2baabf..ec3fca25 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -218,8 +218,7 @@ public void setLocation(MapLocation loc) { * Resets the action cooldown. */ public void addActionCooldownTurns(int numActionCooldownToAdd) { - int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); - int newActionCooldownTurns = numActionCooldownToAdd * cooldownMultiplier; + int newActionCooldownTurns = this.gameWorld.getCooldownMultiplier(numActionCooldownToAdd, this.location); setActionCooldownTurns(this.actionCooldownTurns + newActionCooldownTurns); } @@ -228,7 +227,7 @@ public void addActionCooldownTurns(int numActionCooldownToAdd) { */ public void addMovementCooldownTurns(int numMovementCooldownToAdd) { int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); - int newMovementCooldownTurns = numMovementCooldownToAdd * cooldownMultiplier; + int newMovementCooldownTurns = this.gameWorld.getCooldownMultiplier(numMovementCooldownToAdd, this.location); setMovementCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); } @@ -390,7 +389,7 @@ public void die_exception() { /** * @return the number of friendly robots within sensor (vision) radius. */ - public RobotInfo[] numberOfVisibleFriendlyRobots(){ + public int numberOfVisibleFriendlyRobots(){ return this.controller.numberOfVisibleFriendlyRobots(); } diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index ec75813a..e6866392 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -88,7 +88,7 @@ public LiveMap(int width, Arrays.sort(this.initialBodies, (a, b) -> Integer.compare(a.getID(), b.getID())); // TODO: initialize with potentially hardcoded anomalies - this.anomalySchedule = {}; + this.anomalySchedule = null; this.nextAnomalyIndex = 0; } @@ -275,7 +275,7 @@ public int[] getRubbleArray() { * @param y to get lead at * @return the amount of lead at this location */ - public getLeadAtLocation(int x, int y){ + public int getLeadAtLocation(int x, int y){ assert onTheMap(new MapLocation(x, y)); return this.leadMap[x][y]; } @@ -286,7 +286,7 @@ public getLeadAtLocation(int x, int y){ * @param y to set lead at * @param amount of lead to put at this location */ - public setLeadAtLocation(int x, int y, int amount){ + public void setLeadAtLocation(int x, int y, int amount){ assert onTheMap(new MapLocation(x, y)); this.leadMap[x][y] = amount; } @@ -297,7 +297,7 @@ public setLeadAtLocation(int x, int y, int amount){ * @param y to set lead at * @param amountToAdd */ - public addLeadAtLocation(int x, int y, int amountToAdd){ + public void addLeadAtLocation(int x, int y, int amountToAdd){ assert onTheMap(new MapLocation(x, y)); this.leadMap[x][y] += amountToAdd; } @@ -305,7 +305,7 @@ public addLeadAtLocation(int x, int y, int amountToAdd){ /** * @return a copy of the next Anomaly that hasn't happened yet. */ - public viewNextAnomaly(){ + public AnomalyScheduleEntry viewNextAnomaly(){ return this.anomalySchedule[this.nextAnomalyIndex].copyEntry(); } @@ -313,7 +313,7 @@ public viewNextAnomaly(){ * Removes the current anomaly by advancing to the next one. * @return the next Anomaly. */ - public takeNextAnomaly(){ + public AnomalyScheduleEntry takeNextAnomaly(){ return this.anomalySchedule[this.nextAnomalyIndex++].copyEntry(); } @@ -333,7 +333,7 @@ public AnomalyScheduleEntry[] getAnomalySchedule(){ @Override public String toString() { - if (rubbleArray.length == 0) + if (rubbleArray.length == 0){ return "LiveMap{" + "width=" + width + ", height=" + height + @@ -344,7 +344,9 @@ public String toString() { ", initialBodies=" + Arrays.toString(initialBodies) + ", len=" + Integer.toString(rubbleArray.length) + "}"; - else return "LiveMap{" + + } + else{ + return "LiveMap{" + "width=" + width + ", height=" + height + ", origin=" + origin + @@ -354,5 +356,6 @@ public String toString() { ", initialBodies=" + Arrays.toString(initialBodies) + ", rubbleArray=:)" + Arrays.toString(rubbleArray) + "}"; + } } } \ No newline at end of file diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 25ecab70..788086eb 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -240,9 +240,9 @@ public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team t /** * @return the number of friendly robots within sensor (vision) radius. */ - public RobotInfo[] numberOfVisibleFriendlyRobots(){ + public int numberOfVisibleFriendlyRobots(){ return this.seeNearbyRobots( - this.robot.getVisionRadiusSquared() + this.robot.getVisionRadiusSquared(), this.robot.getTeam() ).length; } @@ -782,7 +782,7 @@ public boolean canConvert() { @Override public int getGoldExchangeRate() { return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * - Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * nearbyRobotCount)) + Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * nearbyRobotCount)); } @Override From b9f5e17dde73251497354d567246f98ebaac6b79 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Fri, 10 Dec 2021 20:40:28 -0500 Subject: [PATCH 105/413] added cite --- engine/src/main/battlecode/world/GameWorld.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 0b532cec..07c0e578 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -622,7 +622,9 @@ public void causeChargeGlobal(AnomalyType anomaly){ Arrays.sort( droids, (InternalRobot robot1, InternalRobot robot2) -> + // 12/10/21: https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/ (robot2.numberOfVisibleFriendlyRobots() - robot1.numberOfVisibleFriendlyRobots()) + // end reference on how to compare things with subtraction ); int affectedDroidsLimit = (int) (anomaly.globalPercentage * droids.length); From 59e7485dae845a853c27484032f6353bd985acf4 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sun, 19 Dec 2021 17:03:21 -0500 Subject: [PATCH 106/413] incomplete random game generator --- client/playback/src/gen/create.ts | 86 +++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 27f84172..81298174 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -9,10 +9,13 @@ let SIZE = 32; const maxID = 4096; const bodyTypeList = [ - schema.BodyType.ENLIGHTENMENT_CENTER, - schema.BodyType.POLITICIAN, - schema.BodyType.SLANDERER, - schema.BodyType.MUCKRAKER + schema.BodyType.MINER, + schema.BodyType.ARCHON, + schema.BodyType.BUILDER, + schema.BodyType.LABORATORY, + schema.BodyType.GUARD, + schema.BodyType.WIZARD, + schema.BodyType.WATCHTOWER ]; const bodyVariety = bodyTypeList.length; @@ -27,13 +30,14 @@ function trimEdge(x: number, l: number, r: number): number{ return Math.min(Math.max(l, x), r); } +//I think this is the same as +//schemaspawnedBodyTable type BodiesType = { robotIDs: number[], teamIDs: number[], types: number[], xs: number[], ys: number[], - influences: number[] }; type MapType = { @@ -111,7 +115,7 @@ function makeRandomBodies(manager: IDsManager, unitCount: number): BodiesType{ types: Array(unitCount), xs: Array(unitCount), ys: Array(unitCount), - influences: Array(unitCount) + //levels: Array(unitCount) }; for(let i=0; i -1 ){ + buildings.push(bodies.robotIDs[j]) + } xs[j] = trimEdge(xs[j] + velxs[j], 0, SIZE-1); ys[j] = trimEdge(ys[j] + velys[j], 0, SIZE-1); if(xs[j] === 0 || xs[j] == SIZE-1) velxs[j] = -velxs[j]; @@ -524,19 +534,43 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = for (let j = 0; j < unitCount; j++) { let action: number | null = null; let actionTarget: number | null = null; + let actions = [] switch (bodies.types[j]) { - case schema.BodyType.POLITICIAN: - action = schema.Action.EMPOWER; + case schema.BodyType.MINER: + action = schema.Action.MINE; + break; + case schema.BodyType.ARCHON: + actions = [schema.Action.SPAWN_UNIT, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; + action = actions[Math.floor(Math.random() * actions.length)]; + break; + case schema.BodyType.GUARD: + actions = [schema.Action.ATTACK]; + action = actions[Math.floor(Math.random() * actions.length)]; + break; + case schema.BodyType.BUILDER: + actions = [schema.Action.BUILD, schema.Action.REPAIR, schema.Action.UPGRADE]; + action = actions[Math.floor(Math.random() * actions.length)]; + break; + case schema.BodyType.LABORATORY: + actions = [schema.Action.CONVERT_GOLD, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; + action = actions[Math.floor(Math.random() * actions.length)]; + break; + case schema.BodyType.WIZARD: + actions = [schema.Action.ATTACK, schema.Action.LOCAL_ABYSS, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; + action = actions[Math.floor(Math.random() * actions.length)]; break; - case schema.BodyType.MUCKRAKER: - action = schema.Action.EXPOSE; + case schema.BodyType.WATCHTOWER: + actions = [schema.Action.ATTACK, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; + action = actions[Math.floor(Math.random() * actions.length)]; break; - case schema.BodyType.SLANDERER: - action = schema.Action.EMBEZZLE; default: break; } + let building_target_actions = [schema.Action.REPAIR, schema.Action.UPGRADE] if (action !== null) { + if (building_target_actions.indexOf(action) > -1){ + actionTarget = buildings[Math.floor(Math.random() * buildings.length)]; + } actionIDs.push(bodies.robotIDs[j]); actions.push(action); actionTargets.push(actionTarget); @@ -579,11 +613,11 @@ function createVotesGame(turns: number) { for (let i = 1; i < turns+1; i++) { const bb_teamIDs = schema.Round.createTeamIDsVector(builder, [1, 2]); - const bb_teamVPs = schema.Round.createTeamVotesVector(builder, [1, (Math.random() > 0.5 ? 1 : 0)]); + //const bb_teamVPs = schema.Round.createTeamVotesVector(builder, [1, (Math.random() > 0.5 ? 1 : 0)]); schema.Round.startRound(builder); schema.Round.addRoundID(builder, i); schema.Round.addTeamIDs(builder, bb_teamIDs); - schema.Round.addTeamVotes(builder, bb_teamVPs); + //schema.Round.addTeamVotes(builder, bb_teamVPs); events.push(createEventWrapper(builder, schema.Round.endRound(builder), schema.Event.Round)); } From 6a1449aaae6c56c729dc838d7b7f99a0c2291ac9 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 19 Dec 2021 20:57:26 -0500 Subject: [PATCH 107/413] Minimum working gameworld --- client/playback/src/gameworld.ts | 68 +++++++++++++++++++++---------- client/playback/src/gen/create.ts | 4 +- client/playback/src/metadata.ts | 10 +++-- schema/battlecode.fbs | 5 +-- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index aa73217e..524e19be 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -6,7 +6,6 @@ import {playbackConfig} from './game'; // necessary because victor doesn't use exports.default import Victor = require('victor'); import deepcopy = require('deepcopy'); -import { indexOf } from 'core-js/library/js/array'; // TODO use Victor for representing positions export type DeadBodiesSchema = { @@ -55,8 +54,8 @@ export type TeamStats = { lead: number, gold: number, total_hp: [number[], number[], number[], number[], number[], number[], number[]], - leadIncome: number, - goldIncome: number + leadChange: number, + goldChange: number }; export type IndicatorDotsSchema = { @@ -215,8 +214,8 @@ export default class GameWorld { lead: 0, gold: 0, total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], - leadIncome: 0, - goldIncome: 0 + leadChange: 0, + goldChange: 0 }); } @@ -300,15 +299,15 @@ export default class GameWorld { this.mapStats.passability = Float64Array.from(map.passabilityArray()); - const leadVals = map.leadVals(this._vecTableSlot1); - if (leadVals) { + const leadLocations = map.leadLocations(this._vecTableSlot1); + if (leadLocations) { - const xs = leadVals.xsArray(); - const ys = leadVals.ysArray(); + const xs = leadLocations.xsArray(); + const ys = leadLocations.ysArray(); xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[x][y] = 1; + this.mapStats.leadVals[x][y] = map.leadAmountsArray[i]; }) } @@ -365,10 +364,10 @@ export default class GameWorld { let teamID = delta.teamIDs(i); let statObj = this.teamStats.get(teamID); - statObj.lead += delta.teamLeadIncome(i); - statObj.gold += delta.teamGoldIncome(i); - statObj.leadIncome = delta.teamLeadIncome(i); - statObj.goldIncome = delta.teamGoldIncome(i); + statObj.lead += delta.teamLeadChange(i); + statObj.gold += delta.teamGoldChange(i); + statObj.leadChange = delta.teamLeadChange(i); + statObj.goldChange = delta.teamGoldChange(i); this.teamStats.set(teamID, statObj); } @@ -397,6 +396,29 @@ export default class GameWorld { this.bodies.alterBulk({id: new Int32Array(this.bidRobots), bid: new Int32Array(this.bidRobots.length)}); this.bidRobots = []; + // Map changes + const leadLocations = delta.leadDropLocations(this._vecTableSlot1); + if (leadLocations) { + const xs = leadLocations.xsArray(); + const ys = leadLocations.ysArray(); + + xs.forEach((x, i) => { + const y = ys[i] + this.mapStats.leadVals[x][y] = delta.leadDropLocations[i]; + }) + } + + const goldLocations = delta.goldDropLocations(this._vecTableSlot1); + if (goldLocations) { + const xs = goldLocations.xsArray(); + const ys = goldLocations.ysArray(); + + xs.forEach((x, i) => { + const y = ys[i] + this.mapStats.goldVals[x][y] = delta.goldDropLocations[i]; + }) + } + // Actions if(delta.actionsLength() > 0){ const arrays = this.bodies.arrays; @@ -556,14 +578,16 @@ export default class GameWorld { }); } - // Process logs - if (this.config.processLogs) this.parseLogs(delta.roundID(), delta.logs() ? delta.logs(flatbuffers.Encoding.UTF16_STRING) : ""); - else this.logsShift++; + // TODO: process indicator strings - while (this.logs.length >= 25) { - this.logs.shift(); - this.logsShift++; - } + // // Process logs + // if (this.config.processLogs) this.parseLogs(delta.roundID(), delta.logs() ? delta.logs(flatbuffers.Encoding.UTF16_STRING) : ""); + // else this.logsShift++; + + // while (this.logs.length >= 25) { + // this.logs.shift(); + // this.logsShift++; + // } // console.log(delta.roundID(), this.logsShift, this.logs[0]); } @@ -640,7 +664,7 @@ export default class GameWorld { // if(teams[i] == 0) continue; var statObj = this.teamStats.get(teams[i]); statObj.robots[types[i]][1] += 1; // TODO: handle level - statObj.total_hp[types[i]][1] += 3000; // TODO: extract meta info + statObj.total_hp[types[i]][1] += this.meta.types[types[i]].hp; // TODO: extract meta info this.teamStats.set(teams[i], statObj); } diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 81298174..d4d832a3 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -543,7 +543,7 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = actions = [schema.Action.SPAWN_UNIT, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; action = actions[Math.floor(Math.random() * actions.length)]; break; - case schema.BodyType.GUARD: + case schema.BodyType.SOLDIER: actions = [schema.Action.ATTACK]; action = actions[Math.floor(Math.random() * actions.length)]; break; @@ -555,7 +555,7 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = actions = [schema.Action.CONVERT_GOLD, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; action = actions[Math.floor(Math.random() * actions.length)]; break; - case schema.BodyType.WIZARD: + case schema.BodyType.SAGE: actions = [schema.Action.ATTACK, schema.Action.LOCAL_ABYSS, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; action = actions[Math.floor(Math.random() * actions.length)]; break; diff --git a/client/playback/src/metadata.ts b/client/playback/src/metadata.ts index 47fcc78e..578702f5 100644 --- a/client/playback/src/metadata.ts +++ b/client/playback/src/metadata.ts @@ -51,14 +51,15 @@ export default class Metadata { body.actionRadiusSquared(), body.visionRadiusSquared(), body.actionCooldown(), - body.movingCooldown(), + body.movementCooldown(), body.bytecodeLimit(), body.dps(), body.hp(), body.dpsMul(), body.hpMul(), body.buildCost(), - Array.from(body.upgradeCostsArray()) + Array.from(body.upgradeCostLeadArray()), + Array.from(body.upgradeCostGoldArray()) ); } // SAFE @@ -93,9 +94,10 @@ export class Team { export class BodyTypeMetaData { constructor(public type: schema.BodyType, public spawnSource:schema.BodyType, public actionRadiusSquared:number, public visionRadiusSquared:number, - public actionCooldown:number, public movingCooldown:number, + public actionCooldown:number, public movementCooldown:number, public bytecodeLimit:number, public dps:number, public hp:number, public dpsMul:number, public hpMul:number, - public buildCost:number, public upgradeCosts:number[]) { + public buildCost:number, public upgradeCostLead:number[], + public upgradeCostGold:number[]) { } } diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1347def8..de69d0f3 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -79,10 +79,7 @@ table GameMap { /// Actions that can be performed. /// Purely aesthetic; have no actual effect on simulation. /// (Although the simulation may want to track the 'parents' of -/// particular robots.) -/// Actions may have 'targets', which are the units on which -/// the actions were performed. -enum Action : byte { +/// particular robots.)als ATTACK, // combat unit types SPAWN_UNIT, //archon MINE, // miner From 50e87adbac69ab0b0646baa894883243634a3f5a Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 19 Dec 2021 21:32:32 -0500 Subject: [PATCH 108/413] minimal working gen --- client/playback/src/gen/create.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index d4d832a3..ebdd598f 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -13,8 +13,8 @@ const bodyTypeList = [ schema.BodyType.ARCHON, schema.BodyType.BUILDER, schema.BodyType.LABORATORY, - schema.BodyType.GUARD, - schema.BodyType.WIZARD, + schema.BodyType.SOLDIER, + schema.BodyType.SAGE, schema.BodyType.WATCHTOWER ]; @@ -208,7 +208,15 @@ function createGameHeader(builder: flatbuffers.Builder): flatbuffers.Offset { // Is there any way to automate this? for (const body of bodyTypeList) { const btmd = schema.BodyTypeMetadata; - bodies.push(btmd.createBodyTypeMetadata(builder, body, body, 10, 10, 2, 6, 10, 10000, 5, 2, 6, 3, 5)); //TODO: make robots interesting + if (body in [schema.BodyType.MINER, schema.BodyType.BUILDER, schema.BodyType.SAGE, schema.BodyType.SOLDIER]) { + var gold_costs = btmd.createUpgradeCostGoldVector(builder, [1]) + var lead_costs = btmd.createUpgradeCostLeadVector(builder, [1]) + } + else { + var gold_costs = btmd.createUpgradeCostGoldVector(builder, [1,2,3]) + var lead_costs = btmd.createUpgradeCostLeadVector(builder, [1,2,3]) + } + bodies.push(btmd.createBodyTypeMetadata(builder, body, body, 10, 10, 2, 6, 10, 10000, 5, 2, 6, 3, gold_costs, lead_costs)); //TODO: make robots interesting } const teams: flatbuffers.Offset[] = []; @@ -322,7 +330,7 @@ function createStandGame(turns: number) { robotIDs.push(i); teamIDs.push(1); - types.push(schema.BodyType.WIZARD); + types.push(schema.BodyType.SAGE); xs[i] = Math.floor(i/2) * 2 + 5; ys[i] = 5*(i%2)+5; @@ -726,7 +734,7 @@ function main(){ const prefix = "../examples/"; games.forEach(pair => { - const filename = `${prefix}${pair.name}.bc21` + const filename = `${prefix}${pair.name}.bc22` const stream = createWriteStream(filename); const game = pair.game; From 81e073c68e9ad10cd4b6b07387e2efeeda3d55bd Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 19 Dec 2021 23:12:34 -0500 Subject: [PATCH 109/413] roughly patch up client so that it runs --- client/README.md | 2 +- client/visualizer/src/config.ts | 12 ++---- client/visualizer/src/constants.ts | 39 ++++++++++++------- client/visualizer/src/gamearea/renderer.ts | 27 ++++++------- client/visualizer/src/main/looper.ts | 39 +++++++++---------- client/visualizer/src/main/sidebar.ts | 4 +- client/visualizer/src/main/tournament_new.ts | 2 +- .../src/mapeditor/action/generator.ts | 21 +++++----- client/visualizer/src/mapeditor/form.ts | 4 +- .../visualizer/src/mapeditor/forms/robots.ts | 34 ++++++++-------- .../src/mapeditor/forms/symmetry.ts | 4 +- client/visualizer/src/mapeditor/mapeditor.ts | 2 +- client/visualizer/src/runner.ts | 15 +++---- client/visualizer/src/sidebar/stats.ts | 18 +++++---- 14 files changed, 109 insertions(+), 114 deletions(-) diff --git a/client/README.md b/client/README.md index cddf1305..87ad5a92 100644 --- a/client/README.md +++ b/client/README.md @@ -14,7 +14,7 @@ Look at `package.json`. This NPM module does not have any dependencies or meaningful output, but it is for wrapping scripts of `playback` and `visualizer` in one place. * `npm run install-all`: Installs npm packages in `playback` and `visualizer`. **Execute this when you start** - * `npm run build`, `npm run build_playback` + * `npm run build`, `npm run build-playback` * `npm run electron`: Run the client in electron. You might want to run this most of the time. * `npm run watch`: Watch for the changes of `visualizer`. Note that it *does not watch* `playback`. * `npm run prod-electron`, `npm run prod-electron-no-sign`, `npm run prod-test` diff --git a/client/visualizer/src/config.ts b/client/visualizer/src/config.ts index 29c88572..5623c0c9 100644 --- a/client/visualizer/src/config.ts +++ b/client/visualizer/src/config.ts @@ -71,14 +71,9 @@ export interface Config { seeActionRadius: boolean; /** - * Whether or not to display the sensor radius. + * Whether or not to display the vision radius. */ - seeSensorRadius: boolean; - - /** - * Whether or not to display the detection radius. - */ - seeDetectionRadius: boolean; + seeVisionRadius: boolean; /** * The mode of the game @@ -165,8 +160,7 @@ export function defaults(supplied?: any): Config { mode: Mode.QUEUE, splash: true, seeActionRadius: false, - seeSensorRadius: false, - seeDetectionRadius: false, + seeVisionRadius: false, showGrid: false, viewSwamp: true, shorterLogHeader: false, diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 90ce47f3..72af9158 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -2,13 +2,16 @@ import { schema } from 'battlecode-playback'; import { Symmetry } from './mapeditor/index'; // Body types -export const ENLIGHTENMENT_CENTER = schema.BodyType.ENLIGHTENMENT_CENTER; -export const POLITICIAN = schema.BodyType.POLITICIAN; -export const SLANDERER = schema.BodyType.SLANDERER; -export const MUCKRAKER = schema.BodyType.MUCKRAKER; +export const ARCHON = schema.BodyType.ARCHON; +export const BUILDER = schema.BodyType.BUILDER; +export const LABORATORY = schema.BodyType.LABORATORY; +export const MINER = schema.BodyType.MINER; +export const SAGE = schema.BodyType.SAGE; +export const SOLDIER = schema.BodyType.SOLDIER; +export const WATCHTOWER = schema.BodyType.WATCHTOWER; -export const bodyTypeList: number[] = [ENLIGHTENMENT_CENTER, POLITICIAN, SLANDERER, MUCKRAKER]; -export const initialBodyTypeList: number[] = [ENLIGHTENMENT_CENTER]; +export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER]; +export const initialBodyTypeList: number[] = [ARCHON]; export const bodyTypePriority: number[] = []; // for guns, drones, etc. that should be drawn over other robots @@ -39,7 +42,7 @@ export const buffFactor = (numBuffs: number): number => { } export const ACTION_RADIUS_COLOR = "#46ff00"; -export const SENSOR_RADIUS_COLOR = "#0000ff"; +export const VISION_RADIUS_COLOR = "#0000ff"; // Expected bot image size export const IMAGE_SIZE = 128; @@ -169,14 +172,20 @@ export const SERVER_MAPS: Map = new Map([ export function bodyTypeToString(bodyType: schema.BodyType) { switch (bodyType) { - case ENLIGHTENMENT_CENTER: - return "enlightenmentCenter"; - case POLITICIAN: - return "politician"; - case SLANDERER: - return "slanderer"; - case MUCKRAKER: - return "muckraker"; + case ARCHON: + return "archon"; + case WATCHTOWER: + return "watchtower"; + case BUILDER: + return "builder"; + case MINER: + return "miner"; + case SAGE: + return "sage"; + case SOLDIER: + return "soldier"; + case LABORATORY: + return "laboratory"; default: throw new Error("invalid body type"); } } diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index 75814f78..cc88999a 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -200,15 +200,16 @@ export default class Renderer { priorityIndices.forEach((i) => renderBot(i)); // Render empowered bodies - const empowered = world.empowered; - const empowered_id = world.empowered.arrays.id; - const empowered_x = world.empowered.arrays.x; - const empowered_y = world.empowered.arrays.y; - const empowered_team = world.empowered.arrays.team; - - for (let i = 0; i < empowered.length; i++) { - drawEffect(empowered_team[i] == 1 ? "empower_red" : "empower_blue", empowered_x[i], this.flip(empowered_y[i], minY, maxY)); - } + // TODO: something similar for lead and gold + // const empowered = world.empowered; + // const empowered_id = world.empowered.arrays.id; + // const empowered_x = world.empowered.arrays.x; + // const empowered_y = world.empowered.arrays.y; + // const empowered_team = world.empowered.arrays.team; + + // for (let i = 0; i < empowered.length; i++) { + // drawEffect(empowered_team[i] == 1 ? "empower_red" : "empower_blue", empowered_x[i], this.flip(empowered_y[i], minY, maxY)); + // } this.setInfoStringEvent(world, xs, ys); } @@ -245,12 +246,8 @@ export default class Renderer { this.drawBotRadius(x, y, this.metadata.types[type].actionRadiusSquared, cst.ACTION_RADIUS_COLOR); } - if (this.conf.seeSensorRadius || single) { - this.drawBotRadius(x, y, this.metadata.types[type].sensorRadiusSquared, cst.SENSOR_RADIUS_COLOR); - } - - if (this.conf.seeDetectionRadius || single) { - this.drawBotRadius(x, y, this.metadata.types[type].detectionRadiusSquared, cst.SENSOR_RADIUS_COLOR); + if (this.conf.seeVisionRadius || single) { + this.drawBotRadius(x, y, this.metadata.types[type].visionRadiusSquared, cst.VISION_RADIUS_COLOR); } } diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index ed665929..43c545c9 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -307,46 +307,43 @@ export default class Looper { * team in the current game world. */ private updateStats(world: GameWorld, meta: Metadata) { - let totalInfluence = 0; - let totalConviction = 0; let teamIDs: number[] = []; let teamNames: string[] = []; - - this.stats.resetECs(); - for (let i = 0; i < world.bodies.length; i++) { - const type = world.bodies.arrays.type[i]; - if (type === schema.BodyType.ENLIGHTENMENT_CENTER) { - this.stats.addEC(world.bodies.arrays.team[i]); - } - } + let totalHP = 0; + + // this.stats.resetECs(); + // for (let i = 0; i < world.bodies.length; i++) { + // const type = world.bodies.arrays.type[i]; + // if (type === schema.BodyType.ENLIGHTENMENT_CENTER) { + // this.stats.addEC(world.bodies.arrays.team[i]); + // } + // } for (let team in meta.teams) { let teamID = meta.teams[team].teamID; let teamStats = world.teamStats.get(teamID) as TeamStats; - totalInfluence += teamStats.influence.reduce((a, b) => a + b); - totalConviction += teamStats.conviction.reduce((a, b) => a + b); teamIDs.push(teamID); teamNames.push(meta.teams[team].name); + totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); } for (let team in meta.teams) { let teamID = meta.teams[team].teamID; let teamStats = world.teamStats.get(teamID) as TeamStats; + let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); // Update each robot count this.stats.robots.forEach((type: schema.BodyType) => { - this.stats.setRobotCount(teamID, type, teamStats.robots[type]); - this.stats.setRobotConviction(teamID, type, teamStats.conviction[type], totalConviction); - this.stats.setRobotInfluence(teamID, type, teamStats.influence[type]); + this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level + this.stats.setRobotInfluence(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b)); // TODO: differentiate levels, maybe }); // Set votes - this.stats.setVotes(teamID, teamStats.votes); - this.stats.setTeamInfluence(teamID, teamStats.influence.reduce((a, b) => a + b), - totalInfluence); - this.stats.setBuffs(teamID, teamStats.numBuffs); - this.stats.setBid(teamID, teamStats.bid); - this.stats.setIncome(teamID, teamStats.income, world.turn); + // this.stats.setVotes(teamID, teamStats.votes); + this.stats.setTeamInfluence(teamID, teamHP, totalHP); + // this.stats.setBuffs(teamID, teamStats.numBuffs); + // this.stats.setBid(teamID, teamStats.bid); + this.stats.setIncome(teamID, teamStats.leadChange, world.turn); // TODO: show gold change } if (this.match.winner && this.match.current.turn == this.match.lastTurn) { diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index 3b85d93e..820e916b 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -169,7 +169,7 @@ export default class Sidebar { press "Kill ongoing processes". Note that the part of the match that has already loaded will remain in the client.

- From the web client: You can always upload a .bc21 file by + From the web client: You can always upload a .bc22 file by clicking the upload button in the Queue section.

Use the control buttons at the top of the screen to @@ -220,7 +220,7 @@ export default class Sidebar { (Note: the name of your .map21 file must be the same as the name of your map.)

- Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc21.`; + Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; if (this.conf.tournamentMode) { innerHTML += diff --git a/client/visualizer/src/main/tournament_new.ts b/client/visualizer/src/main/tournament_new.ts index 31d0a536..442d3f63 100644 --- a/client/visualizer/src/main/tournament_new.ts +++ b/client/visualizer/src/main/tournament_new.ts @@ -20,7 +20,7 @@ export function readTournament(jsonFile: File, cbTournament: (t: Tournament) => team2: arr[1], map: arr[2], winner: arr[3], - url: "https://2021.battlecode.org/replays/" + arr[4] + ".bc21" + url: "https://2022.battlecode.org/replays/" + arr[4] + ".bc22" })); const desc: TournamentMatch[][] = data.filter(game => game != null).map((game) => (game.map(parseMatch))); const tournament = new Tournament(desc); diff --git a/client/visualizer/src/mapeditor/action/generator.ts b/client/visualizer/src/mapeditor/action/generator.ts index e42badef..e5441ea0 100644 --- a/client/visualizer/src/mapeditor/action/generator.ts +++ b/client/visualizer/src/mapeditor/action/generator.ts @@ -10,7 +10,7 @@ type BodiesSchema = { types: schema.BodyType[], xs: number[], ys: number[], - influences: number[] + // influences: number[] }; export type UploadedMap = { @@ -62,13 +62,13 @@ export default class MapGenerator { /** * Adds a robot body to the internal array */ - private static addBody(robotID: number, teamID: number, type: schema.BodyType, x: number, y: number, influence: number) { + private static addBody(robotID: number, teamID: number, type: schema.BodyType, x: number, y: number) { this.bodiesArray.robotIDs.push(robotID); // ignored by engine this.bodiesArray.teamIDs.push(teamID); this.bodiesArray.types.push(type); this.bodiesArray.xs.push(x); this.bodiesArray.ys.push(y); - this.bodiesArray.influences.push(influence); + // this.bodiesArray.influences.push(influence); } /** @@ -82,8 +82,8 @@ export default class MapGenerator { unit.teamID || 0, // Must be set if not a neutral tree unit.type, unit.x, - unit.y, - unit.influence + unit.y + // unit.influence ); }); } @@ -100,8 +100,8 @@ export default class MapGenerator { teamIDs: [], types: [], xs: [], - ys: [], - influences: [] + ys: []//, + // influences: [] }; // Get header information from form @@ -120,13 +120,13 @@ export default class MapGenerator { let teamIDsVectorB = schema.SpawnedBodyTable.createTeamIDsVector(builder, this.bodiesArray.teamIDs); let typesVectorB = schema.SpawnedBodyTable.createTypesVector(builder, this.bodiesArray.types); let locsVecTableB = this.createVecTable(builder, this.bodiesArray.xs, this.bodiesArray.ys); - let influencesVectorB = schema.SpawnedBodyTable.createInfluencesVector(builder, this.bodiesArray.influences); + // let influencesVectorB = schema.SpawnedBodyTable.createInfluencesVector(builder, this.bodiesArray.influences); schema.SpawnedBodyTable.startSpawnedBodyTable(builder) schema.SpawnedBodyTable.addRobotIDs(builder, robotIDsVectorB); schema.SpawnedBodyTable.addTeamIDs(builder, teamIDsVectorB); schema.SpawnedBodyTable.addTypes(builder, typesVectorB); schema.SpawnedBodyTable.addLocs(builder, locsVecTableB); - schema.SpawnedBodyTable.addInfluences(builder, influencesVectorB); + // schema.SpawnedBodyTable.addInfluences(builder, influencesVectorB); const bodies = schema.SpawnedBodyTable.endSpawnedBodyTable(builder); const passability = schema.GameMap.createPassabilityVector(builder, map.passability); @@ -184,7 +184,7 @@ export default class MapGenerator { const maxCorner = map.maxCorner()!; const bodies = map.bodies()!; - const influences = bodies.influencesArray()!; + // const influences = bodies.influencesArray() const types = bodies.typesArray()!; const teamIDs = bodies.teamIDsArray()!; const xs = bodies.locs()!.xsArray()!; @@ -197,7 +197,6 @@ export default class MapGenerator { y: ys[i], type: types[i], teamID: teamIDs[i], - influence: influences[i], radius: 0.5 }); } diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 867a81a0..6b5576f2 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -13,8 +13,8 @@ export type MapUnit = { y: number, type: schema.BodyType, radius: 0.5, - teamID?: number, - influence: number + teamID?: number + // influence: number }; export type GameMap = { diff --git a/client/visualizer/src/mapeditor/forms/robots.ts b/client/visualizer/src/mapeditor/forms/robots.ts index bc76c71f..950aaf1a 100644 --- a/client/visualizer/src/mapeditor/forms/robots.ts +++ b/client/visualizer/src/mapeditor/forms/robots.ts @@ -43,9 +43,9 @@ export default class RobotForm { this.team = document.createElement("select"); this.x = document.createElement("input"); this.y = document.createElement("input"); - this.influence = document.createElement("input"); - this.influence.value = String(cst.INITIAL_INFLUENCE); - this.influence.disabled = true; + // this.influence = document.createElement("input"); + // this.influence.value = String(cst.INITIAL_INFLUENCE); + // this.influence.disabled = true; // Create the form this.loadInputs(); @@ -88,13 +88,13 @@ export default class RobotForm { const team: HTMLDivElement = document.createElement("div"); const x: HTMLDivElement = document.createElement("div"); const y: HTMLDivElement = document.createElement("div"); - const influence: HTMLDivElement = document.createElement("div"); + // const influence: HTMLDivElement = document.createElement("div"); //form.appendChild(id); form.appendChild(type); form.appendChild(team); form.appendChild(x); form.appendChild(y); - form.appendChild(influence); + // form.appendChild(influence); form.appendChild(document.createElement("br")); id.appendChild(document.createTextNode("ID: ")); @@ -117,8 +117,8 @@ export default class RobotForm { y.appendChild(this.y); // Influence - influence.appendChild(document.createTextNode("I: ")); - influence.appendChild(this.influence); + // influence.appendChild(document.createTextNode("I: ")); + // influence.appendChild(this.influence); return form; } @@ -144,12 +144,12 @@ export default class RobotForm { this.y.value = isNaN(value) ? "" : String(value); }; - this.influence.onchange = () => { - let value: number = this.getInfluence(); - value = Math.max(value, 50); - value = Math.min(value, 500); - this.influence.value = isNaN(value) ? "" : String(value); - } + // this.influence.onchange = () => { + // let value: number = this.getInfluence(); + // value = Math.max(value, 50); + // value = Math.min(value, 500); + // this.influence.value = isNaN(value) ? "" : String(value); + // } this.team.onchange = () => { if (this.getTeam() !== 0) { @@ -199,8 +199,8 @@ export default class RobotForm { if (body && id) { this.type.value = String(body.type); this.team.value = String(body.teamID); - this.influence.disabled = (this.getTeam() !== 0); - this.influence.value = String(body.influence); + // this.influence.disabled = (this.getTeam() !== 0); + // this.influence.value = String(body.influence); } } @@ -220,8 +220,8 @@ export default class RobotForm { y: this.getY(), radius: 0.5, type: this.getType(), - teamID: this.getTeam(), - influence: this.getInfluence() + teamID: this.getTeam() + // influence: this.getInfluence() } } } diff --git a/client/visualizer/src/mapeditor/forms/symmetry.ts b/client/visualizer/src/mapeditor/forms/symmetry.ts index 0041d137..7a8cb477 100644 --- a/client/visualizer/src/mapeditor/forms/symmetry.ts +++ b/client/visualizer/src/mapeditor/forms/symmetry.ts @@ -147,8 +147,8 @@ export default class SymmetryForm { y: newLoc.y, radius: body.radius, type: type, - teamID: this.flipTeamID(teamID), - influence: body.influence + teamID: this.flipTeamID(teamID) + // influence: body.influence }); } }); diff --git a/client/visualizer/src/mapeditor/mapeditor.ts b/client/visualizer/src/mapeditor/mapeditor.ts index 30c858a6..248f9841 100644 --- a/client/visualizer/src/mapeditor/mapeditor.ts +++ b/client/visualizer/src/mapeditor/mapeditor.ts @@ -93,7 +93,7 @@ export default class MapEditor { (Note: the name of your .map21 file must be the same as the name of your map.)

- Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc21.`; + Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; return div; } diff --git a/client/visualizer/src/runner.ts b/client/visualizer/src/runner.ts index 76349474..a527cab7 100644 --- a/client/visualizer/src/runner.ts +++ b/client/visualizer/src/runner.ts @@ -139,9 +139,9 @@ export default class Runner { let uploadLabel = document.createElement("label"); uploadLabel.setAttribute("for", "file-upload"); uploadLabel.setAttribute("class", "custom-button"); - uploadLabel.innerText = 'Upload a .bc21 replay file'; + uploadLabel.innerText = 'Upload a .bc22 replay file'; if (this.conf.tournamentMode) { - uploadLabel.innerText = "Upload a .bc21 or .json file"; + uploadLabel.innerText = "Upload a .bc22 or .json file"; } // create the functional button @@ -149,9 +149,9 @@ export default class Runner { upload.textContent = 'upload'; upload.id = "file-upload"; upload.setAttribute('type', 'file'); - upload.accept = '.bc21'; + upload.accept = '.bc22'; if (this.conf.tournamentMode) { - upload.accept = '.bc21,.json'; + upload.accept = '.bc22,.json'; } upload.onchange = () => this.loadMatch(upload.files as FileList); upload.onclick = () => upload.value = ""; @@ -482,11 +482,8 @@ export default class Runner { case 78: // "n" - Toggle action radius this.conf.seeActionRadius = !this.conf.seeActionRadius; break; - case 77: // "m" - Toggle sensor radius - this.conf.seeSensorRadius = !this.conf.seeSensorRadius; - break; - case 188: // "," - Toggle detection radius - this.conf.seeDetectionRadius = !this.conf.seeDetectionRadius; + case 77: // "m" - Toggle vision radius + this.conf.seeVisionRadius = !this.conf.seeVisionRadius; break; case 71: // "g" - Toogle grid view this.conf.showGrid = !this.conf.showGrid; diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 3932d611..f85ce6dc 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -140,20 +140,22 @@ export default class Stats { tdRobot.style.height = "100px"; tdRobot.style.width = "100px"; - const img: HTMLImageElement = this.robotImages[robotName][inGameID]; - img.style.width = "60%"; - img.style.height = "60%"; + // const img: HTMLImageElement = this.robotImages[robotName][inGameID]; + // img.style.width = "60%"; + // img.style.height = "60%"; + // TODO: images - tdRobot.appendChild(img); + // tdRobot.appendChild(img); robotImages.appendChild(tdRobot); for (let value in this.robotTds[teamID]) { let tdCount: HTMLTableCellElement = this.robotTds[teamID][value][robot]; robotCounts[value].appendChild(tdCount); - if (robot === schema.BodyType.ENLIGHTENMENT_CENTER && value === "count") { - tdCount.style.fontWeight = "bold"; - tdCount.style.fontSize = "18px"; - } + // TODO: figure out what's going on here + // if (robot === schema.BodyType.ENLIGHTENMENT_CENTER && value === "count") { + // tdCount.style.fontWeight = "bold"; + // tdCount.style.fontSize = "18px"; + // } } } table.appendChild(robotImages); From e6e79c22b628f249038153285fe1dfa8dd589dc7 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 10:46:00 -0500 Subject: [PATCH 110/413] more patch ups --- client/visualizer/src/gamearea/renderer.ts | 10 +++--- client/visualizer/src/imageloader.ts | 41 +++++++++++++--------- client/visualizer/src/main/controls.ts | 6 ++-- client/visualizer/src/main/looper.ts | 11 +++--- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index cc88999a..5ff5a54c 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -135,7 +135,7 @@ export default class Renderer { const length = bodies.length; const types = bodies.arrays.type; const teams = bodies.arrays.team; - const convictions = bodies.arrays.conviction; + const hps = bodies.arrays.hp; const ids = bodies.arrays.id; const xs = bodies.arrays.x; const ys = bodies.arrays.y; @@ -179,12 +179,14 @@ export default class Renderer { const renderBot = (i: number) => { const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][teams[i]]; - this.drawBot(img, realXs[i], realYs[i], convictions[i]); + this.drawBot(img, realXs[i], realYs[i], hps[i]); + // TODO: draw bot this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID); // draw effect - let effect: string | null = cst.abilityToEffectString(abilities[i]); - if (effect !== null) drawEffect(effect, realXs[i], realYs[i]); + // TODO: handle abilities/actions + // let effect: string | null = cst.abilityToEffectString(abilities[i]); + // if (effect !== null) drawEffect(effect, realXs[i], realYs[i]); } let priorityIndices: number[] = []; diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index 7afbb524..e54c2f2e 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -74,10 +74,13 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { const result = { tiles: [], robots: { - enlightenmentCenter: [], - politician: [], - muckraker: [], - slanderer: [], + archon: [], + watchtower: [], + builder: [], + miner: [], + sage: [], + soldier: [], + laboratory: [], }, effects: { death: null, @@ -156,23 +159,29 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { } // robot sprites - loadImage(result.robots.enlightenmentCenter, RED, 'robots/center_red'); - loadImage(result.robots.muckraker, RED, 'robots/muck_red'); - loadImage(result.robots.politician, RED, 'robots/polit_red'); - loadImage(result.robots.slanderer, RED, 'robots/slanderer_red'); + loadImage(result.robots.archon, RED, 'robots/center_red'); + loadImage(result.robots.watchtower, RED, 'robots/muck_red'); + loadImage(result.robots.builder, RED, 'robots/polit_red'); + loadImage(result.robots.miner, RED, 'robots/slanderer_red'); + loadImage(result.robots.sage, RED, 'robots/slanderer_red'); + loadImage(result.robots.soldier, RED, 'robots/center'); + loadImage(result.robots.laboratory, RED, 'robots/center'); - loadImage(result.robots.enlightenmentCenter, BLU, 'robots/center_blue'); - loadImage(result.robots.muckraker, BLU, 'robots/muck_blue'); - loadImage(result.robots.politician, BLU, 'robots/polit_blue'); - loadImage(result.robots.slanderer, BLU, 'robots/slanderer_blue'); + loadImage(result.robots.archon, BLU, 'robots/center_blue'); + loadImage(result.robots.watchtower, BLU, 'robots/muck_blue'); + loadImage(result.robots.builder, BLU, 'robots/polit_blue'); + loadImage(result.robots.miner, BLU, 'robots/slanderer_blue'); + loadImage(result.robots.sage, BLU, 'robots/slanderer_red'); + loadImage(result.robots.soldier, BLU, 'robots/center'); + loadImage(result.robots.laboratory, BLU, 'robots/center'); - loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); + // loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); // effects - loadImage(result.effects, 'death', 'effects/death/death_empty'); + // loadImage(result.effects, 'death', 'effects/death/death_empty'); - loadImage(result.effects.embezzle, 0, 'effects/embezzle/slanderer_embezzle_empty_1'); - loadImage(result.effects.embezzle, 1, 'effects/embezzle/slanderer_embezzle_empty_2'); + // loadImage(result.effects.embezzle, 0, 'effects/embezzle/slanderer_embezzle_empty_1'); + // loadImage(result.effects.embezzle, 1, 'effects/embezzle/slanderer_embezzle_empty_2'); { const makeTransparent = (data: ImageData): ImageData => { diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 85360c3b..094ebbd0 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -437,15 +437,13 @@ export default class Controls { * Bytecodes Used: bytecodes" */ // TODO fix this (different stats) - setInfoString(id, x: number, y: number, influence: number, conviction: number, bodyType: string, bytecodes: number, flag: number, bid?: number, parent?: number): void { + setInfoString(id, x: number, y: number, hp: number, bodyType: string, bytecodes: number, flag: number, parent?: number): void { // console.log(carryDirt); let infoString = `ID: ${id} | `; infoString += `Location: (${x}, ${y})
`; - infoString += `Influence: ${influence} | `; - infoString += `Conviction: ${conviction}
`; + infoString += `HP: ${hp} | `; infoString += `Flag: ${flag} | `; infoString += `Bytecodes Used: ${bytecodes}`; - if (bid !== undefined) infoString += ` | Bid: ${bid}`; if (parent !== undefined) infoString += ` | Parent: ${parent}`; // (${bodyType})
diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 43c545c9..69e13fb3 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -243,16 +243,17 @@ export default class Looper { let id = bodies.id[index]; let x = bodies.x[index]; let y = bodies.y[index]; - let influence = bodies.influence[index]; - let conviction = bodies.conviction[index]; + // let influence = bodies.influence[index]; + // let conviction = bodies.conviction[index]; + let hp = bodies.hp[index]; // TODO: show max HP, DPS let type = bodies.type[index]; let bytecodes = bodies.bytecodesUsed[index]; let flag = bodies.flag[index]; let parent = bodies.parent[index]; - let bid = bodies.bid[index]; + // let bid = bodies.bid[index]; - this.controls.setInfoString(id, x, y, influence, conviction, cst.bodyTypeToString(type), bytecodes, flag, - bid !== 0 ? bid : undefined, parent !== 0 ? parent : undefined); + this.controls.setInfoString(id, x, y, hp, cst.bodyTypeToString(type), bytecodes, flag, + parent !== 0 ? parent : undefined); } } From 0247bcaba54874421277415b2bb8bac78b4d8081 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 11:35:17 -0500 Subject: [PATCH 111/413] fix --- schema/battlecode.fbs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index de69d0f3..1347def8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -79,7 +79,10 @@ table GameMap { /// Actions that can be performed. /// Purely aesthetic; have no actual effect on simulation. /// (Although the simulation may want to track the 'parents' of -/// particular robots.)als +/// particular robots.) +/// Actions may have 'targets', which are the units on which +/// the actions were performed. +enum Action : byte { ATTACK, // combat unit types SPAWN_UNIT, //archon MINE, // miner From 49192544af407fcd212768736bbe8321cc848a64 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Mon, 20 Dec 2021 12:04:33 -0500 Subject: [PATCH 112/413] Swapping images (blue_miner.png is missing) --- client/visualizer/src/constants.ts | 2 +- client/visualizer/src/imageloader.ts | 38 +++++++++--------- .../src/static/img/robots/blue_archon.png | Bin 0 -> 2039 bytes .../img/robots/blue_archon_portable.png | Bin 0 -> 2245 bytes .../img/robots/blue_archon_prototype.png | Bin 0 -> 1815 bytes .../src/static/img/robots/blue_builder.png | Bin 0 -> 1941 bytes .../src/static/img/robots/blue_lab.png | Bin 0 -> 1938 bytes .../src/static/img/robots/blue_miner.png | Bin 0 -> 3103 bytes .../src/static/img/robots/blue_sage.png | Bin 0 -> 1962 bytes .../src/static/img/robots/blue_soldier.png | Bin 0 -> 2145 bytes .../src/static/img/robots/blue_watchtower.png | Bin 0 -> 1773 bytes .../src/static/img/robots/center.png | Bin 3095 -> 0 bytes .../src/static/img/robots/center_blue.png | Bin 3184 -> 0 bytes .../src/static/img/robots/center_red.png | Bin 3192 -> 0 bytes .../visualizer/src/static/img/robots/muck.png | Bin 3040 -> 0 bytes .../src/static/img/robots/muck_blue.png | Bin 2884 -> 0 bytes .../src/static/img/robots/muck_red.png | Bin 2879 -> 0 bytes .../src/static/img/robots/polit.png | Bin 2762 -> 0 bytes .../src/static/img/robots/polit_blue.png | Bin 2579 -> 0 bytes .../src/static/img/robots/polit_red.png | Bin 2588 -> 0 bytes .../src/static/img/robots/slanderer.png | Bin 2935 -> 0 bytes .../src/static/img/robots/slanderer_blue.png | Bin 2753 -> 0 bytes .../src/static/img/robots/slanderer_red.png | Bin 2751 -> 0 bytes 23 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 client/visualizer/src/static/img/robots/blue_archon.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_portable.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_prototype.png create mode 100644 client/visualizer/src/static/img/robots/blue_builder.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab.png create mode 100644 client/visualizer/src/static/img/robots/blue_miner.png create mode 100644 client/visualizer/src/static/img/robots/blue_sage.png create mode 100644 client/visualizer/src/static/img/robots/blue_soldier.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower.png delete mode 100644 client/visualizer/src/static/img/robots/center.png delete mode 100644 client/visualizer/src/static/img/robots/center_blue.png delete mode 100644 client/visualizer/src/static/img/robots/center_red.png delete mode 100644 client/visualizer/src/static/img/robots/muck.png delete mode 100644 client/visualizer/src/static/img/robots/muck_blue.png delete mode 100644 client/visualizer/src/static/img/robots/muck_red.png delete mode 100644 client/visualizer/src/static/img/robots/polit.png delete mode 100644 client/visualizer/src/static/img/robots/polit_blue.png delete mode 100644 client/visualizer/src/static/img/robots/polit_red.png delete mode 100644 client/visualizer/src/static/img/robots/slanderer.png delete mode 100644 client/visualizer/src/static/img/robots/slanderer_blue.png delete mode 100644 client/visualizer/src/static/img/robots/slanderer_red.png diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 72af9158..40de2e26 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -45,7 +45,7 @@ export const ACTION_RADIUS_COLOR = "#46ff00"; export const VISION_RADIUS_COLOR = "#0000ff"; // Expected bot image size -export const IMAGE_SIZE = 128; +export const IMAGE_SIZE = 50; // Game canvas rendering sizes export const INDICATOR_DOT_SIZE = .3; diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index e54c2f2e..e9fccd82 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -7,10 +7,12 @@ export type AllImages = { star: Image, tiles: Array, robots: { - enlightenmentCenter: Array, - politician: Array, - muckraker: Array, - slanderer: Array + archon: Array, + builder: Array, + lab: Array, + sage: Array, + soldier: Array, + watchtower: Array, }, effects: { // TODO }, @@ -159,21 +161,21 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { } // robot sprites - loadImage(result.robots.archon, RED, 'robots/center_red'); - loadImage(result.robots.watchtower, RED, 'robots/muck_red'); - loadImage(result.robots.builder, RED, 'robots/polit_red'); - loadImage(result.robots.miner, RED, 'robots/slanderer_red'); - loadImage(result.robots.sage, RED, 'robots/slanderer_red'); - loadImage(result.robots.soldier, RED, 'robots/center'); - loadImage(result.robots.laboratory, RED, 'robots/center'); + loadImage(result.robots.archon, RED, 'robots/red_archon_portable'); + loadImage(result.robots.watchtower, RED, 'robots/red_watchtower'); + loadImage(result.robots.builder, RED, 'robots/red_builder'); + loadImage(result.robots.miner, RED, 'robots/red_miner'); + loadImage(result.robots.sage, RED, 'robots/red_sage'); + loadImage(result.robots.soldier, RED, 'robots/red_soldier'); + loadImage(result.robots.laboratory, RED, 'robots/red_lab'); - loadImage(result.robots.archon, BLU, 'robots/center_blue'); - loadImage(result.robots.watchtower, BLU, 'robots/muck_blue'); - loadImage(result.robots.builder, BLU, 'robots/polit_blue'); - loadImage(result.robots.miner, BLU, 'robots/slanderer_blue'); - loadImage(result.robots.sage, BLU, 'robots/slanderer_red'); - loadImage(result.robots.soldier, BLU, 'robots/center'); - loadImage(result.robots.laboratory, BLU, 'robots/center'); + loadImage(result.robots.archon, BLU, 'robots/blue_archon_portable'); + loadImage(result.robots.watchtower, BLU, 'robots/blue_watchtower'); + loadImage(result.robots.builder, BLU, 'robots/blue_builder'); + loadImage(result.robots.miner, BLU, 'robots/blue_miner'); + loadImage(result.robots.sage, BLU, 'robots/blue_sage'); + loadImage(result.robots.soldier, BLU, 'robots/blue_soldier'); + loadImage(result.robots.laboratory, BLU, 'robots/blue_lab'); // loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); diff --git a/client/visualizer/src/static/img/robots/blue_archon.png b/client/visualizer/src/static/img/robots/blue_archon.png new file mode 100644 index 0000000000000000000000000000000000000000..c95e62cf8334940228d6db441318df6d10e804e7 GIT binary patch literal 2039 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 aTz|No+>;ho{R|KW)lHtRelF{r5}E*R_VgM6 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_lab.png b/client/visualizer/src/static/img/robots/blue_lab.png new file mode 100644 index 0000000000000000000000000000000000000000..062e43c2078dbdffd3f52d2b74a9049825effb41 GIT binary patch literal 1938 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 Ud(e-Bvww9h57?O9H1Uf4A1mbkEC2ui literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_sage.png b/client/visualizer/src/static/img/robots/blue_sage.png new file mode 100644 index 0000000000000000000000000000000000000000..8b94c928904af31ddeb6d5cda2e14ca4289a8884 GIT binary patch literal 1962 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*Y2e)5S3)gY|9X?V?*A0&gd7=v3|L&2`zCb${C@ z&!6-Egw>_SZ{KF7Xc5!XqB}utIV%(A*%wTcPBicKnl{7RfBwtYJ)L$d{>g4=jkt3D zE0c__;**u9rI!2UWZYY(xKBJ;TW?#@#Y5&U>+;UX`f&YI^i`_tT|PZI>A~ZbKelw; zQJUr4wR^3?r5`Rz3ClmY>vylq1y(osFmNr=netibTpj;qP39&;wm$c8r<~BK%)3$*f@~O$@Ei(Vxb-n-1Lvn_ zTezOMNz9HHbv$y2xu?;=pu1jve>95{uTI&!s@)ESJdbORMfSZCyD0AVVBU(}8L1Y( zTxC=q-9Pz#r}dO4rGL&&T-MxvpJU1MV29XWD&H7&{&n2zWpupzMSh;C+_yJ1{<@tL zKc5cr($ndcR=jucH?P0Q#fsxnivFkeADHoT{l|i9{~Et@oR4gIYrgPqf$B~Ui-2UQ zgF<_PJt@ITw3V9%@mx4dUkS2Im}x{q|!_yg@`kYJf|)=pz@?;@#Hp(Ukgf3Zf-hp z#pH7F>}=*DUV+mZTr014FPidXlJ<197rI8es?D1lYg)s0Gi+q*2oUxvSBMba>Esmc zymX4H)aNTPNmiV9+*{|o+4fP*T9r}hc4YGDlTtsO;(gvYomg%s+wpvU*+l;<2E#(nZE@Cm&sHpRoi%|WFzoc!Lm{3^q8x6t3GQ;% zW4Ic8tIJR8;f}Re-hK3Swd;s>S$<`q`}Vlxx2+BZZ#R8d#1ycclW$}8hm$f@U7IS_ zE+}feQ@-o}8X11aEN>;z#!j}&))r+PEs_E@3q#YdGwn1#Tc6&)`MfpHhJy+df2i<2 zYo5OH{dTFO}kJEBi{rlfV1;)h}<~zB#?k_Op~-A8-7DjpiRX zRUP8qU%KeoZmIg=!K<5xTOC&ES_�YWnO_RI&Pgb?=AzmLKyqcU_&otlZ?|-@g@i zcX)4I&eHt+*Zakx&m?Zme-Nk15tOX2x*_lG6t;r-nRol%y4>JVn*Zang?*H8l)!Gj#mYx^WL$9nf1K|{`2+J)6RLTB=^xAmRal;`elF{r5}E*kZxM9> literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_soldier.png b/client/visualizer/src/static/img/robots/blue_soldier.png new file mode 100644 index 0000000000000000000000000000000000000000..c773272996b2926311d190ed54e7e8aa17b103ad GIT binary patch literal 2145 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower.png b/client/visualizer/src/static/img/robots/blue_watchtower.png new file mode 100644 index 0000000000000000000000000000000000000000..09532afe5429f04c48d71cd97e136fbaea79397a GIT binary patch literal 1773 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*atr)5S3)gY|9H?Y!FtJX0U9J1{FZ*D$B@&j0#r za?Cu=yW`3{#oo(A#-z-i^x|6QX91=@m9FxMn{+zfEsXpU~f|E?(yQMQ(dRw91v$NzYnim9{=uvuX?P#S5HstMa9*R_)dXB2I-ZNa1?o2XcyTn!7lOF%$QRTs-TjUKBq6)QZy*j#6kL)Sjf5vhc|XT!ETANO3F z9+SS$`&@R3s?2*!u?=fFT#hQ8zkDZQzq_9Gm6_+;1D3p#Om@3rZ@hM1fbvs|X_^WG z2}LTU=DDss^&cHxYzPb~KdfmL7JGQV`xl+Qh|LF|d|*GiK!!{Eqp4}XXyy(jF?Ef_ z5i*VwPfq;nC%1!(H|&XbUrLYiwHyP>Lm`sP+gX#Abemo{)!m?X=ShdDzbk9}9+m^r zWdR3&OgEYwSM=>< z!OyR7f3Ik>>&6?;GS_&g7p3H6Z4KLZ=f@52*KWy06;hLvKEJ8W7Vz!6an;X1lXuZc z!FRux^QpP}xENPgeKMPuo$`!Fa)tR_`2(e&R;JdjGO$b%HRE_LC@AK>CigbZhYeew}Mck7qmvOkqs-L{^z%tyEW)y0W*P0Ya?)>i*i{4;s+l1Vv} zm9IH(nzU*98UIM-uQA$(E}vSkJHu()w1SGef1D(C=IqfdO1<$(sZX5sgv8x*eBzgj z`nGK82tRY!&R^~Ei_cdZzZ}`qP6z730k~kep&Ig@l%BU zt^H~yRiC>3zOlB1U6#E(!Edo@d|!CVl&G`Ygw9v~dm;FPJ^BCHf+g{vI6!5-r>mdK II;Vst0LkCDDF6Tf literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/center.png b/client/visualizer/src/static/img/robots/center.png deleted file mode 100644 index 6b63a6dc55a59eba172c9c52d100f40ce8ae77e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3095 zcmbVO2~-nj9{&=qlqxq=L1c)aa^!*#Ab=1O1Vk_(3L0~8MWEt8}Ogy@DmCNvld4`I?MzBC%agGiY( zH!_kQE|x2}VjdjM3c#bmAqoV1I>nQk%ulAkgk%bpN1(t|FG4cS)0^Pw<3slJ_J+AU zkCfN)ED0||R|2o)`TwW<2AKeDL9Xy`^XM8=S3C4DfgH_h=6vgHgm=!5gaT-;TATsW%G$--d=i_sHKh8|@r){U+Oz_2=;#fViMA1S+E^w`xbBtjXv z%zpoholYjrg+3Oc|6)-cls9vq1zWL6%LiLWdh~YEHsSc^N2W|7#)blivF^P?`574Z z3!?kp(<4)jTaH{?*SQwCo&Ce;7OFFF`7HHaPHC;>l9Fkae`8-@`M0Bk#U0JD<`Ar& zo>*VVu?1(_S{lm@a$JDsSpLi&L)=~?&DCt-#dgOfwutT6xslMloOqDX*7CERb&eyZ zpX_jd4-2&9n$xu?qJfUoWiq+luFxxS3hDtE7vOs!8s!Bzn}W!9Xi-&9^?XV!d-f zP`?GZ^|t!M$;8^guIP^&NRRBXO2E#VN+guqy<3_16XBCoTp~szP`m%QhCwoGz-W^< zn+C14uXUiHiKgvbhGB;u9;bLgS-*y z34l1@+Q4n$kn3fqq1nAU5?EF{!gaec2;9QaCc-I zXzxwm?J8Lst>I}q~}4-BHUF>y~)(M z)3x_bkfdRj*l6H?YNic9~=Q~$i1h~7H zdfKnIs*X2%wR9CY>DPexQio5w&ri(|We*a<8CpZcXzUZqz`M64FPD1u(T%~4AT1VM ziwL1~ZM6dZ`!q|z=+lh}V?`B@W_#=}Gmo25F`9ELHw?vnb#C=j&h?hQlL>Fv=DpaR z^x0`!FiHqKc}214(Ba7kZ0UZz99NL#S)L4a^G(Z|*|la?dYp5RrPt!b@6}C}E2|q@ zK6fjMeVN~lWwiU{);MsUuth$5zTVd6T-f=!$ZtIE<`W!8q$V0yt&}w!bW37tT|;7K z@R)+Ei#9FT^}gM)(8RJp!@}z7{V~JlZ0H6SDX#na8DqzG4bAw{wz|&7@3sa$-C&Xv z0kU@2ZA)VdHw#mue)>GFrN_$J)m1+nTq@pfX+W-&nQ=6Smk@h@$>+&}k+bG3N?*D= z@}hqAV1Y7e8Hzm-bg1wa6U2st@{V$EWvs)dxLkWy!%r6etn`$h7!Q8sM zr{?bC&M=PPOy9)YpV>lm*MZ6G%Y$R#!OzuAXQ0(dzFo4Ys;gh9?*F*m;a9ZR%|L&< zhVO_Qy)HLx%rFJoKpg0|c$ayhEcn)m_6LX7gpS3W`|i}<+RbkswMd<9=~{+ypTZow z+=$Ui#!d%uluPa*8^5`e^#zS(thLIOo_?x+$mHu46ldGnAj~f(jM)=*o7`Kk?H)Ed zpgA+}!slpZ>SPjfC;CeJwdm2O!}`P-n}MXT#AKtO$1WAc*OHoqpoXe(JNwHv7j5x* zzxFGAhNlj1z0v!TQ>W|j)+<>J_EoW`HucJfog*$CJm7^@+1Z$E>i8f}^mTAsZ(qp? zQ?^}jz=QU%ql`tsw8-f8Hj~=n8zH6Q>lpusCRy(kY(bid^!R-_8;od6Yo9qI%8b802*|sg znb{Mx7%5y8+hEnxPS#@#@2ZdN824rwKZ`z6xu@dlTI_~Z=F6=AU69~ZCwL!M-w{+s z9TK7J7r?Q^A)va^`|-)7z;sZf4k|uBbY|G9-?>EP5_)hwc=qLGCpen)DH^<>k5U3M z%CJZ7>4Z{Htai)h@d^{|kWpg9MfGOmV~KAfH(_IRK22)PB4aq?deSXjt?Mu!wJt+? zJCX76QcQh^PKdi4b3~|PA%gmEayP$_K6K50Z@Ud=M%8sb@ChFMsND2NAL${l3`A+i Z-=ZJ#SALjlfd1425FQf6IvdQ%`3*;zw>1C& diff --git a/client/visualizer/src/static/img/robots/center_blue.png b/client/visualizer/src/static/img/robots/center_blue.png deleted file mode 100644 index 07d924d28234f38faa964fcdb64d7938847201d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3184 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 diff --git a/client/visualizer/src/static/img/robots/polit.png b/client/visualizer/src/static/img/robots/polit.png deleted file mode 100644 index c086bed24a9bfbb67bda172300d0b60744667e3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2762 zcmbVO3se(V8lDLRV|X-z5uv3HQCkp_nS_v#fk=2MpwW~!QZ2(|5~h+&Oo9YZ8lPKt zk1j_+tBV>ruEh#SDQdMSsr6W`58N(o)z&R%)mBA?MSOwE-taoMwU5)BGr4!}{qFZa zzW@Gb)@kO=_T~n1AqetLNlr`yquupzJiz~FGl?@`7;j3>wLp;13D*Nxhxxn=LF}t^ zMvgT{Jr^e#gNV>F1(e8UFab0K#l+f71i6^9A_bJ5HYx?(pR@@OTB{UfN2)QkDS;}a zlgrFhdfB`TvTQM_&q` zTi{J8D70ElIEt2(l!!_qM2uOFiWLe4ib+t3LMXZV2Z6u0q}G<1cPae)@T_?6G#|pBTT4Rgt3GPrb5QbSPGe6p&r}*i2;yWwR+6P3w<#d#!OhONlQT(BMEsS+LBRfqR=$T!W5fH zDrqTjbE+#E6P{qE2rFaGV3?v&p){i|BNDMlf`nw#MlDlf34QJWl}K1ArNE_{5J)DG zXJ8l}A;BY}!Y~DnVZ%^0qosAFKZ8bPh{d=RpyfY-f|Ah^R^oTTS`ybWW&;5NrVWIi zLQO`!02xaop1>3_W?&e27xDahNMt{_rM6;QIMg2>VHi40ln zDuL1ST5w(=Q%I?Z$S7f?oFIgRRvIBx$i*_DPOFva#267p5@YA*n`v+biK0KvS7pX zVRY6K!c4{KLAHLk?$BRz-a;(>ZP)*pcrSGQmv#DQTpvj*Sx6Z56zHj_z!ePY>ORAw zpg-4ZXz#gBH3|pq&ov$EyWnN4b5lk@Z3cb$?o)aX1i7zINsP;|)!fRTYD{09s z;pORljoZ-=CI|ACy?yuS>Brk{H6K}G_T{k;U5!fX+%l!h!~NiD==@{-70C0TVc^!o z4OcIQUoJTJ1MPKzyKKFD!kZk-?@=HsIOTbP`|McvTc0nVxpRMeOfsV6)Oc5P-wUf= z<$aT@@o4gYG>MAT>}NIeI~#9jf{|5KLk%A5erH4O-buHUxlL*PA6Ulb7Ahjnx~

G3*yx;tmAP>GDzf*C+YUHTJAyF{>#5x^Tj<@72kD04-O%E>5R%OEB&Gnm$rUj9Fhp*#AuX!#V6uchFx^$p_ zH!qLxnBcf}r#`y8!hV>m;qty4w+7;T^HjeO?rMeBKy}!bXI`z)+)Ek9zckw5)cOeH zKVQyYk!tU(h=+budD^l5SW=pK7W1)BLTo#D`4bK#?FMPgXXoFD)vID(%7Ifg&952H8St!cKWod~HoNW2Yj6W}w7w#3_15pTes>h2E) zblh9%huF68h6Fmx&YuD;Vqb4P#}0`L3c14m@8dXNVm_zyl@R!%{;Tty9 zZpYEpXW50jUW0odt2p+ifgjTy-7~m{W^20oC;zYardOX+-|3#bH#X%s62IRZ>=8R% z1E&SHR|WqSyVa~&wbQo=+WJvw`ka9CCqqxIXm@&6et3D>ky(a+7Y4$TY^JvU)ROz$ z)uBBBIQ({a_XlE+*0qc58|7LJr)*snG&Sp*#dxe`F|L8>&E~9 diff --git a/client/visualizer/src/static/img/robots/polit_blue.png b/client/visualizer/src/static/img/robots/polit_blue.png deleted file mode 100644 index 6c8c9156773c72d1cffb190f030d7ae30836e571..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2579 zcmbVO3se(V8on74Ap{W7+Jj|v4An(2$s{3xObrYH6woL|UV_VJ%uGTg$;2d>04ofS zcC`;h4r^Pbp14ZIEmFnjYEkN=)uL3kthnm~TI-_FihBg93b+$q$M(40vz>G9+&lMv z_xs=fnN7*dm-u?m@&*9-CMLwCFf;8QUQ?L&*(kh)nYfmORW<5pc(@!{2ulzNB0^*$u|y!2qewU^j)2D>J|oRa=+Kn7 z#pAM=FC{ z#jNMUlMX~~59ACigu}3lIejHjIrknreM@q(Qk?sz3h~7J}>W-de4RpOU zv_1XAoX0h5=2r%2Uj6Y<-BNfZ)ZkUzi>|$cspyZ(I#2GbVh2Fgs|Vy;da_mhTgpG_ zdH2rsnEhXzZ)vRezRl|Kv845g%1`HScq0W9U>AS4AZ!1OE8Z5eZ%0AwMkVh`gGbQK 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 diff --git a/client/visualizer/src/static/img/robots/slanderer.png b/client/visualizer/src/static/img/robots/slanderer.png deleted file mode 100644 index 8196719245da8ae285910474c10e1888431a0037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2935 zcmbVO3se(V8lHpz4hn>bk0RC~fDkarB!oal14JSwKp;X?@KG5i17yvMNq8=32v~Jp z1r$VkP$(+UdTP;%tt~34R$K8wQL9}nqE^KxxTU(b(z6o;)^@G!Y0li4`}qFvf8PIO zy)t3GtBaQl006FXnKX&~TI^$-6Zt+Kfp(A|&?rka0f5^H`=C?@yG;WC$D0~eiaA9Q zk6;EJ2UQ!=aZbL@NTLB?PGr6j#a7~GC>_t#=*7(b&yF!6jatlH9IAj7#%MfCBP%5E zVc+CYL7?iMTMI%jdI61lv@gH>3G%y~%f!L5iC&LSr;*40_1U zh^8BI%wi^K=?fQh#xYvGX(UW!z_|ISk;~)2c9({MYHSQ=%ptVH%GDSb*Wx-{Z#I!w z-Wb-HWiT5|S%%-C9y|V(0y4A;#h8v)+M?5qsW6%6<&tiU1mu-yld8aobCYnBA&0>5 zdAX#SzIJbnNHl??W&@!z7__5_QjVGo@p&9R6u4NUR~zz7td|6EDQd>WOncVYWXkwq zDi}sW$*l2$VG#nuFQ5v8T9Z-m8)&$S$3p}#BH;fDN|uZoHKTtBR%1wpfzY9(!x|l$ ziF1wmOeQoIMkLyxH4vm?(z=kB_vO*iO2Uw#(UJ$Ir1^6p`MhW$Pb3tw`5fM`xe5g$ z*PG0!9>e8QF_R1qN25_A8KEMK7aA&HlLKX=JV82JB*+l5aXv3Z&4+Oq)W2@QD#QSD#mv0qGk z?I1FZiOg!j$kj>4vqxrH4K!RX2#VRSftZQe^N*{UBiou+MBvYP@Palk3nximQx`8_ zCPRif4<&F(CK;_itUK=S8E-;!UvK)KOWrF@|NlDuE2fWx70W{PnK;=~xlFq=TzmI< zkreK4^EG_-Ql}b)lkLww9qYT~VytuHdXkzT`*O&kgX76|kI1DGRetTm9jUpsFn!(z zZ|R)y1il*=2z7?9lEf2%psM*i3Atwu)4u!w|iELe+-7O4j ziaC|7{iYwC)EEyW^3R>CqS7T)&iirg+t1%QJ{0l(w@-(z)qSj+t#muNjYFArYiXqq zMdog`h2PLV#{5q|r3fPlY`@tdh^XJ!Z z-*_4^u*_q*@0DjOQzjp>37tD*tzr8ssJfO%4k^_RRn}Ek!mMpF;2!;3aIgi5a=B;| zf@gd}dD_DPGuPnK^VHp2dVhFU^qs?=de_Itp^b#n%UosU2Q`&27*(tOy+5dV{=@K; z*`U(pp7Nn{=UdZj``3DYxvPiXz~dEB8AVu^#|afbPLl5Xgkh1bu=cTf69DGWC5akb z<`U(%+ESJ@uwf}>-AVr_R(?|)(9yHn4cxgdP?8fjb-^zVUH|C%`pJRKvdYyT*0U(Y zj7UHU>9YWYp)M{pYxI zK(*6VIUS9F3MU)APc?2IUM;LArVjd*oa_gQ9_))GXbJT|nCcyf*jid0SMn(!Ei^f> zz(tJq-7}(A>Y;^hi-H_yg2n;|7ypuAurSs(bnOmXe8y2G+W`64y3->3*93r950=Sm zXzK}OkmHeS7fvduwUzM>oBZ;F9YY-+_&bsz64cP{*xHWu|IjMt1bkOznSHpLdil0T zo~U{GH-%SI&B0M~|E7n7B#*9KN!ES%#SuVCEdA;#bzbL4fob%5#@zIDSMQR(Hw01eu1JAb6-f?L{+Q$M+;Fk9uSZrAT6 z)>~oLoh?&~%FF9OmgQFB(J=7yvy|B4pV>yvBzBynSp=NwH9c_a*N*GyZ~ zwARNFy0`aZae3Ke4k^oMWgeVxBA!t;1+opzsjJ*fRwj+Eb^=@6p)Y0gi3HE}#nf@o zKl4DyLfz@#?j7avNF+&D>n${;^j^tgU-xD!aC%TyabMgU2=C@Wuw)gUAdOIs=dB=*U zCBV_jz9mPO&7hu}i|j1_d!CI~U2}H7YpHu=|7$Ftmmu9YH_iHA^|u&W diff --git a/client/visualizer/src/static/img/robots/slanderer_blue.png b/client/visualizer/src/static/img/robots/slanderer_blue.png deleted file mode 100644 index 5ead144a6fb2d1c6e20b609899d27f61d195a669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2753 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 JylG~p^WV#B;z Date: Mon, 20 Dec 2021 12:54:02 -0500 Subject: [PATCH 113/413] updated year --- EMAILS.md | 4 +- build.gradle | 4 +- client/package-lock.json | 12 +- client/package.json | 2 +- client/playback/package-lock.json | 1110 +- client/visualizer/electron-main.js | 2 +- client/visualizer/package-lock.json | 10627 +++++++++++++++- client/visualizer/package.json | 2 +- client/visualizer/src/config.ts | 2 +- client/visualizer/src/gamearea/gamearea.ts | 4 +- client/visualizer/src/main/sidebar.ts | 2 +- gradle.properties | 2 +- schema/java/battlecode/schema/Action.java | 69 +- schema/java/battlecode/schema/BodyType.java | 27 +- .../battlecode/schema/BodyTypeMetadata.java | 122 +- .../java/battlecode/schema/EventWrapper.java | 20 +- schema/java/battlecode/schema/GameFooter.java | 18 +- schema/java/battlecode/schema/GameHeader.java | 37 +- schema/java/battlecode/schema/GameMap.java | 42 +- .../java/battlecode/schema/GameWrapper.java | 28 +- .../java/battlecode/schema/MatchFooter.java | 24 +- .../java/battlecode/schema/MatchHeader.java | 22 +- .../java/battlecode/schema/ProfilerEvent.java | 18 +- .../java/battlecode/schema/ProfilerFile.java | 26 +- .../battlecode/schema/ProfilerProfile.java | 24 +- schema/java/battlecode/schema/RGBTable.java | 24 +- schema/java/battlecode/schema/Round.java | 267 +- .../battlecode/schema/SpawnedBodyTable.java | 50 +- schema/java/battlecode/schema/TeamData.java | 18 +- schema/java/battlecode/schema/Vec.java | 11 +- schema/java/battlecode/schema/VecTable.java | 22 +- schema/package.json | 2 +- 32 files changed, 12193 insertions(+), 451 deletions(-) diff --git a/EMAILS.md b/EMAILS.md index aad38446..9c3ee9f8 100644 --- a/EMAILS.md +++ b/EMAILS.md @@ -17,8 +17,8 @@ We currently maintain the following lists on Mailman: 1. Update the administrator to the Battlecode contact email (this is the publicly viewable list owner), and set yourself and others to be moderators. After doing this, you will need to re-authenticate (you're no longer the admin), using the password that was emailed to you. 1. Set list parameters. Below are some examples. - - Description: MIT Battlecode 2021 - - Subject prefix: [battlecode-21] + - Description: MIT Battlecode 2022 + - Subject prefix: [battlecode-22] - Hide sender = Yes. All sent emails will appear to come from the list, not you. - Strip Reply-To header = Yes, explicit Reply-To = the battlecode address. This configures replies to not go back to the list. - In the privacy menu: diff --git a/build.gradle b/build.gradle index d442c6e6..fba0d3d7 100644 --- a/build.gradle +++ b/build.gradle @@ -20,8 +20,8 @@ if (!project.hasProperty("maps")) { } if (project.hasProperty("release_version")) { - if (!project.property("release_version").startsWith("2021")) { - throw new StopExecutionException("release version must start with 2021!") + if (!project.property("release_version").startsWith("2022")) { + throw new StopExecutionException("release version must start with 2022!") } } diff --git a/client/package-lock.json b/client/package-lock.json index f5728034..1068690b 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,5 +1,13 @@ { "name": "battlecode-client", - "version": "2021.0.0", - "lockfileVersion": 1 + "version": "2022.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "battlecode-client", + "version": "2022.0.0", + "license": "GPL-3.0" + } + } } diff --git a/client/package.json b/client/package.json index 1d6650d9..7366f91a 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "battlecode-client", - "version": "2021.0.0", + "version": "2022.0.0", "description": "Client wrapper of visualizer and playback", "main": "visualizer/electron-main.js", "scripts": { diff --git a/client/playback/package-lock.json b/client/playback/package-lock.json index 384eed44..a1afa9bb 100644 --- a/client/playback/package-lock.json +++ b/client/playback/package-lock.json @@ -1,7 +1,1097 @@ { "name": "battlecode-playback", + "lockfileVersion": 2, "requires": true, - "lockfileVersion": 1, + "packages": { + "": { + "name": "battlecode-playback", + "license": "GPL-3.0", + "dependencies": { + "battlecode-schema": "file:../../schema", + "core-js": "^3.3.6", + "deepcopy": "^2.0.0", + "pako": "^1.0.10", + "victor": "^1.1.0" + }, + "devDependencies": { + "@types/blue-tape": "^0.1.33", + "@types/core-js": "^2.5.2", + "@types/node": "^12.12.5", + "@types/pako": "^1.0.1", + "@types/victor": "^1.1.0", + "blue-tape": "^1.0.0", + "npm-force-resolutions": "0.0.3", + "stream": "0.0.2", + "tap-dot": "^2.0.0", + "ts-node": "^8.4.1", + "tslint": "^5.20.0", + "typescript": "^3.6.4" + } + }, + "../../schema": { + "name": "battlecode-schema", + "version": "2022.0.0", + "license": "GPL-3.0", + "dependencies": { + "@types/flatbuffers": "^1.9.1", + "flatbuffers": "^1.11.0" + } + }, + "../../schema/node_modules/@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==" + }, + "../../schema/node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, + "node_modules/@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.0.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "dependencies": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/blue-tape": { + "version": "0.1.33", + "resolved": "https://registry.npmjs.org/@types/blue-tape/-/blue-tape-0.1.33.tgz", + "integrity": "sha512-l5cQcLM3aPh55bBQ4geWQ8hZ4Ew+s4RvyhMaBpgW3aJ2HUfRgwd8ENKrk/utC4Hz1dJAiehyIa4vN6emxBMaog==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tape": "*" + } + }, + "node_modules/@types/core-js": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.2.tgz", + "integrity": "sha512-+NPqjXgyA02xTHKJDeDca9u8Zr42ts6jhdND4C3PrPeQ35RJa0dmfAedXW7a9K4N1QcBbuWI1nSfGK4r1eVFCQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true + }, + "node_modules/@types/pako": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz", + "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==", + "dev": true + }, + "node_modules/@types/tape": { + "version": "4.2.33", + "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", + "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/victor/-/victor-1.1.0.tgz", + "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==", + "dev": true + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/battlecode-schema": { + "resolved": "../../schema", + "link": true + }, + "node_modules/blue-tape": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/blue-tape/-/blue-tape-1.0.0.tgz", + "integrity": "sha1-dYHQTAc5XJXEJrLtbR7bRUp2uSs=", + "dev": true, + "dependencies": { + "tape": ">=2.0.0 <5.0.0" + }, + "bin": { + "blue-tape": "bin/blue-tape.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/core-js": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.6.tgz", + "integrity": "sha512-u4oM8SHwmDuh5mWZdDg9UwNVq5s1uqq6ZDLLIs07VY+VJU91i3h4f3K/pgFvtUQPGdeStrZ+odKyfyt4EnKHfA==", + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "node_modules/deepcopy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.0.0.tgz", + "integrity": "sha512-d5ZK7pJw7F3k6M5vqDjGiiUS9xliIyWkdzBjnPhnSeRGjkYOGZMCFkdKVwV/WiHOe0NwzB8q+iDo7afvSf0arA==", + "dependencies": { + "type-detect": "^4.0.8" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/emitter-component": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", + "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-format": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz", + "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww=", + "dev": true + }, + "node_modules/make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/npm-force-resolutions": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.3.tgz", + "integrity": "sha512-xbIPAGzD3nrJHDLtnRFt/O83teTA8ju5pWTf8W6OKL4D0XD9EjdRNJhzg4bSXWuucE+l1HGdTpOJR/l1Mi1Ycg==", + "dev": true, + "dependencies": { + "json-format": "^1.0.1", + "source-map-support": "^0.5.5" + }, + "bin": { + "npm-force-resolutions": "index.js" + } + }, + "node_modules/object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/re-emitter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz", + "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=", + "dev": true, + "dependencies": { + "emitter-component": "^1.1.1" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap-dot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tap-dot/-/tap-dot-2.0.0.tgz", + "integrity": "sha512-7N1yPcRDgdfHCUbG6lZ0hXo53NyXhKIjJNhqKBixl9HVEG4QasG16Nlvr8wRnqr2ZRYVWmbmxwF3NOBbTLtQLQ==", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "tap-out": "^1.3.2", + "through2": "^2.0.0" + }, + "bin": { + "tap-dot": "bin/dot" + } + }, + "node_modules/tap-out": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz", + "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=", + "dev": true, + "dependencies": { + "re-emitter": "^1.0.0", + "readable-stream": "^2.0.0", + "split": "^1.0.0", + "trim": "0.0.1" + }, + "bin": { + "tap-out": "bin/cmd.js" + } + }, + "node_modules/tape": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz", + "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==", + "dev": true, + "dependencies": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.4", + "has": "~1.0.3", + "inherits": "~2.0.4", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.11.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "node_modules/ts-node": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", + "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + }, + "peerDependencies": { + "typescript": ">=2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "node_modules/tslint": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", + "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/victor/-/victor-1.1.0.tgz", + "integrity": "sha1-3jzHexVYmxsMeyLD2tKXA0qwAro=" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.5.5", @@ -643,6 +1733,15 @@ "emitter-component": "^1.1.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", @@ -674,15 +1773,6 @@ "function-bind": "^1.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", diff --git a/client/visualizer/electron-main.js b/client/visualizer/electron-main.js index dda44328..7a63e710 100644 --- a/client/visualizer/electron-main.js +++ b/client/visualizer/electron-main.js @@ -30,7 +30,7 @@ function createWindow () { protocol: 'file:', slashes: true, options: { - title: 'Battlecode 2021' + title: 'Battlecode 2022' } })); diff --git a/client/visualizer/package-lock.json b/client/visualizer/package-lock.json index f5f89e84..14a9454e 100644 --- a/client/visualizer/package-lock.json +++ b/client/visualizer/package-lock.json @@ -1,15 +1,10358 @@ { "name": "battlecode-visualizer", - "version": "2021.0.0", - "lockfileVersion": 1, + "version": "2022.0.0", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "7zip-bin": { + "packages": { + "": { + "name": "battlecode-visualizer", + "version": "2022.0.0", + "license": "GPL-3.0", + "dependencies": { + "@types/chart.js": "^2.9.30", + "battlecode-playback": "file:../playback", + "chart.js": "^2.9.4", + "speedscope": "1.5.2", + "victor": "^1.1.0" + }, + "devDependencies": { + "@types/blue-tape": "^0.1.33", + "@types/electron": "^1.6.10", + "@types/node": "^12.12.14", + "@types/victor": "^1.1.0", + "awesome-typescript-loader": "^5.2.1", + "copy-webpack-plugin": "^5.0.5", + "css-loader": "^3.2.1", + "electron": "^10.1.5", + "electron-builder": "^22.1.0", + "file-loader": "^5.0.2", + "json-loader": "^0.5.7", + "node": "^14.15.0", + "style-loader": "^1.0.1", + "ts-loader": "^6.2.1", + "tslint": "^5.20.1", + "typescript": "^3.7.3", + "url-loader": "^3.0.0", + "webpack": "^5.4.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0", + "webpack-merge": "^4.2.2" + } + }, + "../../schema": { + "name": "battlecode-schema", + "version": "2022.0.0", + "license": "GPL-3.0", + "dependencies": { + "@types/flatbuffers": "^1.9.1", + "flatbuffers": "^1.11.0" + } + }, + "../../schema/node_modules/@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==" + }, + "../../schema/node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, + "../playback": { + "name": "battlecode-playback", + "license": "GPL-3.0", + "dependencies": { + "battlecode-schema": "file:../../schema", + "core-js": "^3.3.6", + "deepcopy": "^2.0.0", + "pako": "^1.0.10", + "victor": "^1.1.0" + }, + "devDependencies": { + "@types/blue-tape": "^0.1.33", + "@types/core-js": "^2.5.2", + "@types/node": "^12.12.5", + "@types/pako": "^1.0.1", + "@types/victor": "^1.1.0", + "blue-tape": "^1.0.0", + "npm-force-resolutions": "0.0.3", + "stream": "0.0.2", + "tap-dot": "^2.0.0", + "ts-node": "^8.4.1", + "tslint": "^5.20.0", + "typescript": "^3.6.4" + } + }, + "../playback/node_modules/@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.0.0" + } + }, + "../playback/node_modules/@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "dependencies": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "../playback/node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/@types/blue-tape": { + "version": "0.1.33", + "resolved": "https://registry.npmjs.org/@types/blue-tape/-/blue-tape-0.1.33.tgz", + "integrity": "sha512-l5cQcLM3aPh55bBQ4geWQ8hZ4Ew+s4RvyhMaBpgW3aJ2HUfRgwd8ENKrk/utC4Hz1dJAiehyIa4vN6emxBMaog==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tape": "*" + } + }, + "../playback/node_modules/@types/core-js": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.2.tgz", + "integrity": "sha512-+NPqjXgyA02xTHKJDeDca9u8Zr42ts6jhdND4C3PrPeQ35RJa0dmfAedXW7a9K4N1QcBbuWI1nSfGK4r1eVFCQ==", + "dev": true + }, + "../playback/node_modules/@types/node": { + "version": "12.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true + }, + "../playback/node_modules/@types/pako": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz", + "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==", + "dev": true + }, + "../playback/node_modules/@types/tape": { + "version": "4.2.33", + "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", + "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "../playback/node_modules/@types/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/victor/-/victor-1.1.0.tgz", + "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==", + "dev": true + }, + "../playback/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, + "../playback/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "../playback/node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "../playback/node_modules/battlecode-schema": { + "resolved": "../../schema", + "link": true + }, + "../playback/node_modules/blue-tape": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/blue-tape/-/blue-tape-1.0.0.tgz", + "integrity": "sha1-dYHQTAc5XJXEJrLtbR7bRUp2uSs=", + "dev": true, + "dependencies": { + "tape": ">=2.0.0 <5.0.0" + }, + "bin": { + "blue-tape": "bin/blue-tape.js" + } + }, + "../playback/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../playback/node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "../playback/node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "../playback/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "../playback/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "../playback/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "../playback/node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "../playback/node_modules/core-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.0.tgz", + "integrity": "sha512-AHPTNKzyB+YwgDWoSOCaid9PUSEF6781vsfiK8qUz62zRR448/XgK2NtCbpiUGizbep8Lrpt0Du19PpGGZvw3Q==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "../playback/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "../playback/node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "../playback/node_modules/deepcopy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.0.0.tgz", + "integrity": "sha512-d5ZK7pJw7F3k6M5vqDjGiiUS9xliIyWkdzBjnPhnSeRGjkYOGZMCFkdKVwV/WiHOe0NwzB8q+iDo7afvSf0arA==", + "dependencies": { + "type-detect": "^4.0.8" + } + }, + "../playback/node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "../playback/node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "../playback/node_modules/emitter-component": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", + "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=", + "dev": true + }, + "../playback/node_modules/es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "../playback/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "../playback/node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "../playback/node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "../playback/node_modules/glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "../playback/node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "../playback/node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "../playback/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "../playback/node_modules/is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "../playback/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "../playback/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "../playback/node_modules/json-format": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz", + "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww=", + "dev": true + }, + "../playback/node_modules/make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "../playback/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../playback/node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "../playback/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../playback/node_modules/npm-force-resolutions": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.3.tgz", + "integrity": "sha512-xbIPAGzD3nrJHDLtnRFt/O83teTA8ju5pWTf8W6OKL4D0XD9EjdRNJhzg4bSXWuucE+l1HGdTpOJR/l1Mi1Ycg==", + "dev": true, + "dependencies": { + "json-format": "^1.0.1", + "source-map-support": "^0.5.5" + }, + "bin": { + "npm-force-resolutions": "index.js" + } + }, + "../playback/node_modules/object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "../playback/node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "../playback/node_modules/pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" + }, + "../playback/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "../playback/node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "../playback/node_modules/re-emitter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz", + "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==", + "dev": true + }, + "../playback/node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "../playback/node_modules/resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "../playback/node_modules/resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "dependencies": { + "through": "~2.3.4" + } + }, + "../playback/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "../playback/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "../playback/node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "../playback/node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "../playback/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "../playback/node_modules/stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=", + "dev": true, + "dependencies": { + "emitter-component": "^1.1.1" + } + }, + "../playback/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "../playback/node_modules/string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../playback/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../playback/node_modules/tap-dot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tap-dot/-/tap-dot-2.0.0.tgz", + "integrity": "sha512-7N1yPcRDgdfHCUbG6lZ0hXo53NyXhKIjJNhqKBixl9HVEG4QasG16Nlvr8wRnqr2ZRYVWmbmxwF3NOBbTLtQLQ==", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "tap-out": "^1.3.2", + "through2": "^2.0.0" + }, + "bin": { + "tap-dot": "bin/dot" + } + }, + "../playback/node_modules/tap-out": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz", + "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=", + "dev": true, + "dependencies": { + "re-emitter": "^1.0.0", + "readable-stream": "^2.0.0", + "split": "^1.0.0", + "trim": "0.0.1" + }, + "bin": { + "tap-out": "bin/cmd.js" + } + }, + "../playback/node_modules/tape": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz", + "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==", + "dev": true, + "dependencies": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.4", + "has": "~1.0.3", + "inherits": "~2.0.4", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.11.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "../playback/node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "../playback/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "../playback/node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "../playback/node_modules/ts-node": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", + "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + }, + "peerDependencies": { + "typescript": ">=2.0" + } + }, + "../playback/node_modules/ts-node/node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "../playback/node_modules/tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "../playback/node_modules/tslint": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", + "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "../playback/node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "../playback/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "../playback/node_modules/typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "../playback/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "../playback/node_modules/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/victor/-/victor-1.1.0.tgz", + "integrity": "sha1-3jzHexVYmxsMeyLD2tKXA0qwAro=" + }, + "../playback/node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "../playback/node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "../playback/node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "dev": true, + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@electron/get": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz", + "integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^9.6.0", + "progress": "^2.0.3", + "sanitize-filename": "^1.6.2", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=8.6" + }, + "optionalDependencies": { + "global-agent": "^2.0.2", + "global-tunnel-ng": "^2.7.1" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/blue-tape": { + "version": "0.1.33", + "resolved": "https://registry.npmjs.org/@types/blue-tape/-/blue-tape-0.1.33.tgz", + "integrity": "sha512-l5cQcLM3aPh55bBQ4geWQ8hZ4Ew+s4RvyhMaBpgW3aJ2HUfRgwd8ENKrk/utC4Hz1dJAiehyIa4vN6emxBMaog==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tape": "*" + } + }, + "node_modules/@types/chart.js": { + "version": "2.9.30", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", + "integrity": "sha512-EgjxUUZFvf6ls3kW2CwyrnSJhgyKxgwrlp/W5G9wqyPEO9iFatO63zAA7L24YqgMxiDjQ+tG7ODU+2yWH91lPg==", + "dependencies": { + "moment": "^2.10.2" + } + }, + "node_modules/@types/debug": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", + "dev": true + }, + "node_modules/@types/electron": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@types/electron/-/electron-1.6.10.tgz", + "integrity": "sha512-MOCVyzIwkBEloreoCVrTV108vSf8fFIJPsGruLCoAoBZdxtnJUqKA4lNonf/2u1twSjAspPEfmEheC+TLm/cMw==", + "deprecated": "This is a stub types definition for electron (https://github.com/electron/electron). electron provides its own type definitions, so you don't need @types/electron installed!", + "dev": true, + "dependencies": { + "electron": "*" + } + }, + "node_modules/@types/eslint": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.4.tgz", + "integrity": "sha512-YCY4kzHMsHoyKspQH+nwSe+70Kep7Vjt2X+dZe5Vs2vkRudqtoFoUIv1RlJmZB8Hbp7McneupoZij4PadxsK5Q==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", + "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.4.tgz", + "integrity": "sha512-50GO5ez44lxK5MDH90DYHFFfqxH7+fTqEEnvguQRzJ/tY9qFrMSHLiYHite+F3SNmf7+LHC1eMXojuD+E3Qcyg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.4.tgz", + "integrity": "sha512-o3oj1bETk8kBwzz1WlO6JWL/AfAA3Vm6J1B3C9CsdxHYp7XgPiH7OEXPUbZTndHlRaIElrANkQfe6ZmfJb3H2w==", + "dev": true + }, + "node_modules/@types/tape": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.13.0.tgz", + "integrity": "sha512-0V8cKowBdsiA9nbxAg7531sF2cdPZNiUogcfIUeUGm+bejUBE/bvibz3rH36iQP9bQjO/sOzFwU97/uC5mCyoA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/victor/-/victor-1.1.0.tgz", + "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz", + "integrity": "sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "dependencies": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/7zip-bin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.0.3.tgz", + "integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "dependencies": { + "string-width": "^3.0.0" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/app-builder-bin": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.10.tgz", + "integrity": "sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ==", + "dev": true + }, + "node_modules/app-builder-lib": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.9.1.tgz", + "integrity": "sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A==", + "dev": true, + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "7zip-bin": "~5.0.3", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chromium-pickle-js": "^0.2.0", + "debug": "^4.3.0", + "ejs": "^3.1.5", + "electron-publish": "22.9.1", + "fs-extra": "^9.0.1", + "hosted-git-info": "^3.0.5", + "is-ci": "^2.0.0", + "isbinaryfile": "^4.0.6", + "js-yaml": "^3.14.0", + "lazy-val": "^1.0.4", + "minimatch": "^3.0.4", + "normalize-package-data": "^2.5.0", + "read-config-file": "6.0.0", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.2", + "temp-file": "^3.3.7" + }, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/app-builder-lib/node_modules/debug": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/awesome-typescript-loader": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz", + "integrity": "sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.1.0", + "lodash": "^4.17.5", + "micromatch": "^3.1.9", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.3", + "webpack-log": "^1.2.0" + }, + "peerDependencies": { + "typescript": "^2.7 || ^3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/battlecode-playback": { + "resolved": "../playback", + "link": true + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bluebird-lst": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5" + } + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/boolean": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.2.tgz", + "integrity": "sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==", + "dev": true, + "optional": true + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/browserslist": { + "version": "4.14.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz", + "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001157", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.591", + "escalade": "^3.1.1", + "node-releases": "^1.1.66" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/builder-util": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.9.1.tgz", + "integrity": "sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw==", + "dev": true, + "dependencies": { + "@types/debug": "^4.1.5", + "@types/fs-extra": "^9.0.1", + "7zip-bin": "~5.0.3", + "app-builder-bin": "3.5.10", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "debug": "^4.3.0", + "fs-extra": "^9.0.1", + "is-ci": "^2.0.0", + "js-yaml": "^3.14.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.3.7" + } + }, + "node_modules/builder-util-runtime": { + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz", + "integrity": "sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=8.2.5" + } + }, + "node_modules/builder-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/builder-util/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/builder-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/builder-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/builder-util/node_modules/debug": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/builder-util/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builder-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/builder-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001158", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001158.tgz", + "integrity": "sha512-s5loVYY+yKpuVA3HyW8BarzrtJvwHReuzugQXlv1iR3LKSReoFXRm86mT6hT7PEF5RxW+XQZg+6nYjlywYzQ+g==", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "dependencies": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "node_modules/chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "dependencies": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "node_modules/chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "optional": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/configstore/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/configstore/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "dev": true, + "dependencies": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/core-js": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.7.0.tgz", + "integrity": "sha512-NwS7fI5M5B85EwpWuIwJN4i/fbisQUwLwiSNUWeXlkAZ0sbBjLEvLvFLf1uzAUV66PcEPt4xCGCmOZSxVf3xzA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/css-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dmg-builder": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.9.1.tgz", + "integrity": "sha512-jc+DAirqmQrNT6KbDHdfEp8D1kD0DBTnsLhwUR3MX+hMBun5bT134LQzpdK0GKvd22GqF8L1Cz/NOgaVjscAXQ==", + "dev": true, + "dependencies": { + "app-builder-lib": "22.9.1", + "builder-util": "22.9.1", + "fs-extra": "^9.0.1", + "iconv-lite": "^0.6.2", + "js-yaml": "^3.14.0", + "sanitize-filename": "^1.6.3" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", + "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", + "dev": true, + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.5.tgz", + "integrity": "sha512-fys/KnEfJq05TtMij+lFvLuKkuVH030CHYx03iZrW5DNNLwjE6cW3pysJ420lB0FRSfPjTHBMu2eVCf5TG71zQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@electron/get": "^1.0.1", + "@types/node": "^12.0.12", + "extract-zip": "^1.0.3" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 8.6" + } + }, + "node_modules/electron-builder": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.9.1.tgz", + "integrity": "sha512-GXPt8l5Mxwm1QKYopUM6/Tdh9W3695G6Ax+IFyj5pQ51G4SD5L1uq4/RkPSsOgs3rP7jNSV6g6OfDzdtVufPdA==", + "dev": true, + "dependencies": { + "@types/yargs": "^15.0.5", + "app-builder-lib": "22.9.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "dmg-builder": "22.9.1", + "fs-extra": "^9.0.1", + "is-ci": "^2.0.0", + "lazy-val": "^1.0.4", + "read-config-file": "6.0.0", + "sanitize-filename": "^1.6.3", + "update-notifier": "^4.1.1", + "yargs": "^16.0.3" + }, + "bin": { + "electron-builder": "out/cli/cli.js", + "install-app-deps": "out/cli/install-app-deps.js" + }, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/electron-builder/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/electron-builder/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/electron-builder/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/electron-builder/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/electron-builder/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-builder/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-builder/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-builder/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-publish": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz", + "integrity": "sha512-ducLjRJLEeU87FaTCWaUyDjCoLXHkawkltP2zqS/n2PyGke54ZIql0tBuUheht4EpR8AhFbVJ11spSn1gy8r6w==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^9.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "fs-extra": "^9.0.1", + "lazy-val": "^1.0.4", + "mime": "^2.4.6" + } + }, + "node_modules/electron-publish/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/electron-publish/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/electron-publish/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/electron-publish/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/electron-publish/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-publish/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-publish/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-publish/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-publish/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-publish/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.596", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.596.tgz", + "integrity": "sha512-nLO2Wd2yU42eSoNJVQKNf89CcEGqeFZd++QsnN2XIgje1s/19AgctfjLIbPORlvcCO8sYjLwX4iUgDdusOY8Sg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "dependencies": { + "original": "^1.0.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "dependencies": { + "type": "^2.0.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/extract-zip/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/file-loader": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz", + "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.4.0", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/filelist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", + "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/global-agent": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", + "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "core-js": "^3.6.5", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "dependencies": { + "ini": "^1.3.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-modules/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-tunnel-ng": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", + "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", + "dev": true, + "optional": true, + "dependencies": { + "encodeurl": "^1.0.2", + "lodash": "^4.17.10", + "npm-conf": "^1.1.3", + "tunnel": "^0.0.6" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/globalthis": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", + "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", + "dev": true, + "optional": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "dependencies": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "node_modules/json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lazy-val": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz", + "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", + "integrity": "sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/loglevel": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", + "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-loglevel?utm_medium=referral&utm_source=npm_fund" + } + }, + "node_modules/loglevelnext": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "dependencies": { + "es6-symbol": "^3.1.1", + "object.assign": "^4.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node": { + "version": "14.15.0", + "resolved": "https://registry.npmjs.org/node/-/node-14.15.0.tgz", + "integrity": "sha512-FrsP5wcA72CXNgQUk7zIdZm4vciBa/ahzaGC5iv3T0coNvz7hGsiI4pMdqqr0OXlVqyvSxDHzUUrhxlY3Hb2Kg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-bin-setup": "^1.0.0" + }, + "bin": { + "node": "bin/node" + }, + "engines": { + "npm": ">=5.0.0" + } + }, + "node_modules/node-bin-setup": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.0.6.tgz", + "integrity": "sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q==", + "dev": true + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-releases": { + "version": "1.1.66", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", + "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "dev": true, + "optional": true, + "dependencies": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz", + "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opn/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "dependencies": { + "url-parse": "^1.4.3" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "dependencies": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "dependencies": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", + "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "node_modules/postcss/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true, + "optional": true + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-config-file": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.0.0.tgz", + "integrity": "sha512-PHjROSdpceKUmqS06wqwP92VrM46PZSTubmNIMJ5DrMwg1OgenSTSEHIkCa6TiOJ+y/J0xnG1fFwG3M+Oi1aNA==", + "dev": true, + "dependencies": { + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", + "js-yaml": "^3.13.1", + "json5": "^2.1.2", + "lazy-val": "^1.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/read-config-file/node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags/node_modules/es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "node_modules/selfsigned": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", + "dev": true, + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true, + "optional": true + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + } + }, + "node_modules/sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "dependencies": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/speedscope": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/speedscope/-/speedscope-1.5.2.tgz", + "integrity": "sha512-oGFmFEbhqQawTlOJMhyLNyB0nl+PEZKnAPOXZiRc+o1Mb++MAP/wb5aB2OEUZhg/7FoFgYGft9qmPz78FRAu4A==", + "dependencies": { + "opn": "5.3.0" + }, + "bin": { + "speedscope": "bin/cli.js" + } + }, + "node_modules/speedscope/node_modules/opn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true, + "optional": true + }, + "node_modules/ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-loader": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", + "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.7.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/style-loader/node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/style-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-file": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.7.tgz", + "integrity": "sha512-9tBJKt7GZAQt/Rg0QzVWA8Am8c1EFl+CAv04/aBVqlx5oyfQ508sFIABshQ0xbZu6mBrFLWIUXO/bbLYghW70g==", + "dev": true, + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^8.1.0" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.8.tgz", + "integrity": "sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.0.3.tgz", - "integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ==", + "dev": true, + "dependencies": { + "jest-worker": "^26.6.1", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.3.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dev": true, + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8.6" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/ts-loader/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/ts-loader/node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/ts-loader/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-3.0.0.tgz", + "integrity": "sha512-a84JJbIA5xTFTWyjjcPdnsu+41o/SNE8SpXMdUvXs6Q+LuhCD9E2+0VCiuDWqgo3GGXVlFHzArDmBpj9PgWn4A==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/victor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/victor/-/victor-1.1.0.tgz", + "integrity": "sha1-3jzHexVYmxsMeyLD2tKXA0qwAro=" + }, + "node_modules/watchpack": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.0.1.tgz", + "integrity": "sha512-vO8AKGX22ZRo6PiOFM9dC0re8IcKh8Kd/aH2zeqUc6w4/jBGlTy2P7fTC6ekT0NjVeGjgU2dGC5rNstKkeLEQg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.4.0.tgz", + "integrity": "sha512-udpYTyqz8toTTdaOsL2QKPLeZLt2IEm9qY7yTXuFEQhKu5bk0yQD9BtAdVQksmz4jFbbWOiWmm3NHarO0zr/ng==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.45", + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^8.0.4", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.3.1", + "eslint-scope": "^5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.1.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "pkg-dir": "^4.2.0", + "schema-utils": "^3.0.0", + "tapable": "^2.0.0", + "terser-webpack-plugin": "^5.0.3", + "watchpack": "^2.0.0", + "webpack-sources": "^2.1.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "peerDependencies": { + "webpack": "4.x.x" + } + }, + "node_modules/webpack-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/webpack-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack-dev-middleware/node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dev": true, + "dependencies": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/webpack-dev-server/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/string-width/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/string-width/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "dependencies": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "loglevelnext": "^1.0.1", + "uuid": "^3.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.3.1.tgz", + "integrity": "sha512-G1XD3MRGrGfNcf6Hg0LVZG7GIKcYkbfHa5QMxt1HDUTdYoXH0JR1xXyg+MaKLF73E9A27uWNVxvFivNRYeUB6w==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack/node_modules/tapable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.1.1.tgz", + "integrity": "sha512-Wib1S8m2wdpLbmQz0RBEVosIyvb/ykfKXf3ZIDqvWoMg/zTNm6G/tDSuUM61J1kNCDXWJrLHGSFeMhAG+gAGpQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "dependencies": { + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yargs": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", + "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.2", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + }, + "dependencies": { "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", @@ -391,6 +10734,12 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "7zip-bin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.0.3.tgz", + "integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==", + "dev": true + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -423,13 +10772,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "dev": true, + "requires": {} }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-align": { "version": "3.0.0", @@ -513,8 +10864,8 @@ "integrity": "sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A==", "dev": true, "requires": { - "7zip-bin": "~5.0.3", "@develar/schema-utils": "~2.6.5", + "7zip-bin": "~5.0.3", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", "builder-util": "22.9.1", @@ -780,10 +11131,22 @@ "battlecode-playback": { "version": "file:../playback", "requires": { + "@types/blue-tape": "^0.1.33", + "@types/core-js": "^2.5.2", + "@types/node": "^12.12.5", + "@types/pako": "^1.0.1", + "@types/victor": "^1.1.0", "battlecode-schema": "file:../../schema", + "blue-tape": "^1.0.0", "core-js": "^3.3.6", "deepcopy": "^2.0.0", + "npm-force-resolutions": "0.0.3", "pako": "^1.0.10", + "stream": "0.0.2", + "tap-dot": "^2.0.0", + "ts-node": "^8.4.1", + "tslint": "^5.20.0", + "typescript": "^3.6.4", "victor": "^1.1.0" }, "dependencies": { @@ -791,6 +11154,7 @@ "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, "requires": { "@babel/highlight": "^7.0.0" } @@ -799,6 +11163,7 @@ "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -809,6 +11174,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -817,6 +11183,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -826,12 +11193,14 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -842,6 +11211,7 @@ "version": "0.1.33", "resolved": "https://registry.npmjs.org/@types/blue-tape/-/blue-tape-0.1.33.tgz", "integrity": "sha512-l5cQcLM3aPh55bBQ4geWQ8hZ4Ew+s4RvyhMaBpgW3aJ2HUfRgwd8ENKrk/utC4Hz1dJAiehyIa4vN6emxBMaog==", + "dev": true, "requires": { "@types/node": "*", "@types/tape": "*" @@ -850,22 +11220,26 @@ "@types/core-js": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.2.tgz", - "integrity": "sha512-+NPqjXgyA02xTHKJDeDca9u8Zr42ts6jhdND4C3PrPeQ35RJa0dmfAedXW7a9K4N1QcBbuWI1nSfGK4r1eVFCQ==" + "integrity": "sha512-+NPqjXgyA02xTHKJDeDca9u8Zr42ts6jhdND4C3PrPeQ35RJa0dmfAedXW7a9K4N1QcBbuWI1nSfGK4r1eVFCQ==", + "dev": true }, "@types/node": { "version": "12.12.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", - "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==" + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true }, "@types/pako": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz", - "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==" + "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==", + "dev": true }, "@types/tape": { "version": "4.2.33", "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", + "dev": true, "requires": { "@types/node": "*" } @@ -873,27 +11247,32 @@ "@types/victor": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@types/victor/-/victor-1.1.0.tgz", - "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==" + "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==", + "dev": true }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true }, "arg": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", - "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==" + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -901,7 +11280,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "battlecode-schema": { "version": "file:../../schema", @@ -926,6 +11306,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/blue-tape/-/blue-tape-1.0.0.tgz", "integrity": "sha1-dYHQTAc5XJXEJrLtbR7bRUp2uSs=", + "dev": true, "requires": { "tape": ">=2.0.0 <5.0.0" } @@ -934,6 +11315,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -942,17 +11324,20 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -964,7 +11349,8 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -972,6 +11358,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -979,17 +11366,20 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "core-js": { "version": "3.6.0", @@ -999,12 +11389,14 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true }, "deepcopy": { "version": "2.0.0", @@ -1018,6 +11410,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -1025,22 +11418,26 @@ "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true }, "diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==" + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true }, "emitter-component": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", - "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=" + "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=", + "dev": true }, "es-abstract": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", @@ -1058,6 +11455,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -1067,22 +11465,26 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "requires": { "is-callable": "^1.1.3" } @@ -1090,17 +11492,20 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "glob": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1114,6 +11519,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -1122,6 +11528,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1129,12 +11536,14 @@ "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -1143,22 +11552,26 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, "requires": { "has": "^1.0.1" } @@ -1167,6 +11580,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, "requires": { "has-symbols": "^1.0.0" } @@ -1174,17 +11588,20 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1193,17 +11610,20 @@ "json-format": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz", - "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww=" + "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww=", + "dev": true }, "make-error": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1211,12 +11631,14 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -1225,6 +11647,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.3.tgz", "integrity": "sha512-xbIPAGzD3nrJHDLtnRFt/O83teTA8ju5pWTf8W6OKL4D0XD9EjdRNJhzg4bSXWuucE+l1HGdTpOJR/l1Mi1Ycg==", + "dev": true, "requires": { "json-format": "^1.0.1", "source-map-support": "^0.5.5" @@ -1233,17 +11656,20 @@ "object-inspect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -1256,27 +11682,32 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "re-emitter": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz", - "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==" + "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==", + "dev": true }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1291,6 +11722,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -1299,6 +11731,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, "requires": { "through": "~2.3.4" } @@ -1306,17 +11739,20 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "source-map-support": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -1325,7 +11761,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -1333,6 +11770,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, "requires": { "through": "2" } @@ -1340,20 +11778,32 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "stream": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=", + "dev": true, "requires": { "emitter-component": "^1.1.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.0", @@ -1364,6 +11814,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" @@ -1373,23 +11824,17 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1398,6 +11843,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/tap-dot/-/tap-dot-2.0.0.tgz", "integrity": "sha512-7N1yPcRDgdfHCUbG6lZ0hXo53NyXhKIjJNhqKBixl9HVEG4QasG16Nlvr8wRnqr2ZRYVWmbmxwF3NOBbTLtQLQ==", + "dev": true, "requires": { "chalk": "^1.1.1", "tap-out": "^1.3.2", @@ -1408,6 +11854,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz", "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=", + "dev": true, "requires": { "re-emitter": "^1.0.0", "readable-stream": "^2.0.0", @@ -1419,6 +11866,7 @@ "version": "4.11.0", "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz", "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==", + "dev": true, "requires": { "deep-equal": "~1.0.1", "defined": "~1.0.0", @@ -1438,12 +11886,14 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -1452,12 +11902,14 @@ "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true }, "ts-node": { "version": "8.4.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", + "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", @@ -1469,19 +11921,22 @@ "diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==" + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true } } }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true }, "tslint": { "version": "5.20.0", "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -1502,6 +11957,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1510,6 +11966,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1519,12 +11976,14 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -1535,6 +11994,7 @@ "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, "requires": { "tslib": "^1.8.1" } @@ -1547,12 +12007,14 @@ "typescript": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", - "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==" + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, "victor": { "version": "1.1.0", @@ -1562,17 +12024,20 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } }, @@ -1833,9 +12298,9 @@ "integrity": "sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw==", "dev": true, "requires": { - "7zip-bin": "~5.0.3", "@types/debug": "^4.1.5", "@types/fs-extra": "^9.0.1", + "7zip-bin": "~5.0.3", "app-builder-bin": "3.5.10", "bluebird-lst": "^1.0.9", "builder-util-runtime": "8.7.2", @@ -6800,6 +17265,15 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -6860,15 +17334,6 @@ "es-abstract": "^1.18.0-next.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", diff --git a/client/visualizer/package.json b/client/visualizer/package.json index 401b8dbb..eee91255 100644 --- a/client/visualizer/package.json +++ b/client/visualizer/package.json @@ -1,6 +1,6 @@ { "name": "battlecode-visualizer", - "version": "2021.0.0", + "version": "2022.0.0", "description": "Visualizing the game using playback", "private": true, "scripts": { diff --git a/client/visualizer/src/config.ts b/client/visualizer/src/config.ts index 5623c0c9..7d3652fc 100644 --- a/client/visualizer/src/config.ts +++ b/client/visualizer/src/config.ts @@ -144,7 +144,7 @@ export enum Mode { */ export function defaults(supplied?: any): Config { let conf: Config = { - gameVersion: "2021.3.0.5", //TODO: Change this on each release! + gameVersion: "2022.0.0.0", //TODO: Change this on each release! fullscreen: false, width: 600, height: 600, diff --git a/client/visualizer/src/gamearea/gamearea.ts b/client/visualizer/src/gamearea/gamearea.ts index 2f4a149d..639f6f58 100644 --- a/client/visualizer/src/gamearea/gamearea.ts +++ b/client/visualizer/src/gamearea/gamearea.ts @@ -74,7 +74,7 @@ export default class GameArea { splashSubtitle.id = "splashSubtitle"; if (!this.conf.tournamentMode) { - splashTitle.appendChild(document.createTextNode("Battlecode 2021 Client")); + splashTitle.appendChild(document.createTextNode("Battlecode 2022 Client")); splashSubtitle.appendChild(document.createTextNode("v" + this.conf.gameVersion)); } else { @@ -88,7 +88,7 @@ export default class GameArea { (async function (splashDiv, version) { var options = { - host: '2021.battlecode.org', + host: '2022.battlecode.org', path: '/version.txt' }; diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index 820e916b..12b8c5e3 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -299,7 +299,7 @@ export default class Sidebar { logo.id = "logo"; let boldText = document.createElement("b"); - boldText.innerHTML = "Battlecode 2021"; + boldText.innerHTML = "Battlecode 2022"; logo.appendChild(boldText); return logo; } diff --git a/gradle.properties b/gradle.properties index 1565098d..3d94d4be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,4 @@ maps=maptestsmall profilerEnabled=false source=src mapLocation=maps -release_version=2021.3.0.5 +release_version=2022.0.0.0 diff --git a/schema/java/battlecode/schema/Action.java b/schema/java/battlecode/schema/Action.java index a21287a3..b7990cad 100644 --- a/schema/java/battlecode/schema/Action.java +++ b/schema/java/battlecode/schema/Action.java @@ -12,65 +12,26 @@ */ public final class Action { private Action() { } - /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared - */ - public static final byte EMPOWER = 0; - /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID - */ - public static final byte EMBEZZLE = 1; - /** - * Slanderers turn into Politicians. - * Target: none - */ - public static final byte CAMOUFLAGE = 2; - /** - * Muckrakers can expose a slanderer. - * Target: an enemy body - */ - public static final byte EXPOSE = 3; - /** - * Units can change their flag. - * Target: new flag value - */ - public static final byte SET_FLAG = 4; - /** - * Builds a unit. - * Target: spawned unit - */ - public static final byte SPAWN_UNIT = 5; - /** - * Places a bid. - * Target: bid value - */ - public static final byte PLACE_BID = 6; - /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID - */ - public static final byte CHANGE_TEAM = 7; - /** - * A robot's influence changes. - * Target: delta value - */ - public static final byte CHANGE_INFLUENCE = 8; - /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 - */ - public static final byte CHANGE_CONVICTION = 9; + public static final byte ATTACK = 0; + public static final byte SPAWN_UNIT = 1; + public static final byte MINE = 2; + public static final byte BUILD = 3; + public static final byte CONVERT_GOLD = 4; + public static final byte TRANSFORM = 5; + public static final byte UPGRADE = 6; + public static final byte REPAIR = 7; + public static final byte CHANGE_HP = 8; + public static final byte FULLY_REPAIRED = 9; + public static final byte LOCAL_ABYSS = 10; + public static final byte LOCAL_FURY = 11; + public static final byte LOCAL_CHARGE = 12; /** * Dies due to an uncaught exception. * Target: none */ - public static final byte DIE_EXCEPTION = 10; + public static final byte DIE_EXCEPTION = 13; - public static final String[] names = { "EMPOWER", "EMBEZZLE", "CAMOUFLAGE", "EXPOSE", "SET_FLAG", "SPAWN_UNIT", "PLACE_BID", "CHANGE_TEAM", "CHANGE_INFLUENCE", "CHANGE_CONVICTION", "DIE_EXCEPTION", }; + public static final String[] names = { "ATTACK", "SPAWN_UNIT", "MINE", "BUILD", "CONVERT_GOLD", "TRANSFORM", "UPGRADE", "REPAIR", "CHANGE_HP", "FULLY_REPAIRED", "LOCAL_ABYSS", "LOCAL_FURY", "LOCAL_CHARGE", "DIE_EXCEPTION", }; public static String name(int e) { return names[e]; } } diff --git a/schema/java/battlecode/schema/BodyType.java b/schema/java/battlecode/schema/BodyType.java index ee34e38d..aa900424 100644 --- a/schema/java/battlecode/schema/BodyType.java +++ b/schema/java/battlecode/schema/BodyType.java @@ -8,26 +8,15 @@ */ public final class BodyType { private BodyType() { } - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - public static final byte ENLIGHTENMENT_CENTER = 0; - /** - * politicians use their influence to self destruct and capture other units - */ - public static final byte POLITICIAN = 1; - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - public static final byte SLANDERER = 2; - /** - * have the ability to identify slanderers - */ - public static final byte MUCKRAKER = 3; + public static final byte MINER = 0; + public static final byte BUILDER = 1; + public static final byte SOLDIER = 2; + public static final byte SAGE = 3; + public static final byte ARCHON = 4; + public static final byte LABORATORY = 5; + public static final byte WATCHTOWER = 6; - public static final String[] names = { "ENLIGHTENMENT_CENTER", "POLITICIAN", "SLANDERER", "MUCKRAKER", }; + public static final String[] names = { "MINER", "BUILDER", "SOLDIER", "SAGE", "ARCHON", "LABORATORY", "WATCHTOWER", }; public static String name(int e) { return names[e]; } } diff --git a/schema/java/battlecode/schema/BodyTypeMetadata.java b/schema/java/battlecode/schema/BodyTypeMetadata.java index 8b7e63ba..cf3e3b93 100644 --- a/schema/java/battlecode/schema/BodyTypeMetadata.java +++ b/schema/java/battlecode/schema/BodyTypeMetadata.java @@ -7,82 +7,104 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * Metadata about all bodies of a particular type. */ +@SuppressWarnings("unused") public final class BodyTypeMetadata extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb) { return getRootAsBodyTypeMetadata(_bb, new BodyTypeMetadata()); } public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb, BodyTypeMetadata obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - /** - * The relevant type. - */ public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * The spawn source. - */ public byte spawnSource() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * the convictionRatio of this type - */ - public float convictionRatio() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * cooldown of this type - */ - public float actionCooldown() { int o = __offset(10); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * action radius if this type - */ - public int actionRadiusSquared() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * sensor radius squared for this type - */ - public int sensorRadiusSquared() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * detection radius of this type - */ - public int detectionRadiusSquared() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * bytecode limit for this type - */ - public int bytecodeLimit() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public float actionCooldown() { int o = __offset(12); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + public float movementCooldown() { int o = __offset(14); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + public int bytecodeLimit() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int dps() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int hp() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public float dpsMul() { int o = __offset(22); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + public float hpMul() { int o = __offset(24); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + public int buildCost() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int upgradeCostLead(int j) { int o = __offset(28); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int upgradeCostLeadLength() { int o = __offset(28); return o != 0 ? __vector_len(o) : 0; } + public IntVector upgradeCostLeadVector() { return upgradeCostLeadVector(new IntVector()); } + public IntVector upgradeCostLeadVector(IntVector obj) { int o = __offset(28); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer upgradeCostLeadAsByteBuffer() { return __vector_as_bytebuffer(28, 4); } + public ByteBuffer upgradeCostLeadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 28, 4); } + public int upgradeCostGold(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int upgradeCostGoldLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } + public IntVector upgradeCostGoldVector() { return upgradeCostGoldVector(new IntVector()); } + public IntVector upgradeCostGoldVector(IntVector obj) { int o = __offset(30); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer upgradeCostGoldAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } + public ByteBuffer upgradeCostGoldInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, byte spawnSource, - float convictionRatio, - float actionCooldown, int actionRadiusSquared, - int sensorRadiusSquared, - int detectionRadiusSquared, - int bytecodeLimit) { - builder.startObject(8); + int visionRadiusSquared, + float actionCooldown, + float movementCooldown, + int bytecodeLimit, + int dps, + int hp, + float dpsMul, + float hpMul, + int buildCost, + int upgradeCostLeadOffset, + int upgradeCostGoldOffset) { + builder.startTable(14); + BodyTypeMetadata.addUpgradeCostGold(builder, upgradeCostGoldOffset); + BodyTypeMetadata.addUpgradeCostLead(builder, upgradeCostLeadOffset); + BodyTypeMetadata.addBuildCost(builder, buildCost); + BodyTypeMetadata.addHpMul(builder, hpMul); + BodyTypeMetadata.addDpsMul(builder, dpsMul); + BodyTypeMetadata.addHp(builder, hp); + BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); - BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); BodyTypeMetadata.addSpawnSource(builder, spawnSource); BodyTypeMetadata.addType(builder, type); return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(8); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startTable(14); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } public static void addSpawnSource(FlatBufferBuilder builder, byte spawnSource) { builder.addByte(1, spawnSource, 0); } - public static void addConvictionRatio(FlatBufferBuilder builder, float convictionRatio) { builder.addFloat(2, convictionRatio, 0.0f); } - public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(3, actionCooldown, 0.0f); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(4, actionRadiusSquared, 0); } - public static void addSensorRadiusSquared(FlatBufferBuilder builder, int sensorRadiusSquared) { builder.addInt(5, sensorRadiusSquared, 0); } - public static void addDetectionRadiusSquared(FlatBufferBuilder builder, int detectionRadiusSquared) { builder.addInt(6, detectionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(7, bytecodeLimit, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(2, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(3, visionRadiusSquared, 0); } + public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(4, actionCooldown, 0.0f); } + public static void addMovementCooldown(FlatBufferBuilder builder, float movementCooldown) { builder.addFloat(5, movementCooldown, 0.0f); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(6, bytecodeLimit, 0); } + public static void addDps(FlatBufferBuilder builder, int dps) { builder.addInt(7, dps, 0); } + public static void addHp(FlatBufferBuilder builder, int hp) { builder.addInt(8, hp, 0); } + public static void addDpsMul(FlatBufferBuilder builder, float dpsMul) { builder.addFloat(9, dpsMul, 0.0f); } + public static void addHpMul(FlatBufferBuilder builder, float hpMul) { builder.addFloat(10, hpMul, 0.0f); } + public static void addBuildCost(FlatBufferBuilder builder, int buildCost) { builder.addInt(11, buildCost, 0); } + public static void addUpgradeCostLead(FlatBufferBuilder builder, int upgradeCostLeadOffset) { builder.addOffset(12, upgradeCostLeadOffset, 0); } + public static int createUpgradeCostLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startUpgradeCostLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addUpgradeCostGold(FlatBufferBuilder builder, int upgradeCostGoldOffset) { builder.addOffset(13, upgradeCostGoldOffset, 0); } + public static int createUpgradeCostGoldVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startUpgradeCostGoldVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public BodyTypeMetadata get(int j) { return get(new BodyTypeMetadata(), j); } + public BodyTypeMetadata get(BodyTypeMetadata obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/EventWrapper.java b/schema/java/battlecode/schema/EventWrapper.java index 3eb73a91..5b0aa36b 100644 --- a/schema/java/battlecode/schema/EventWrapper.java +++ b/schema/java/battlecode/schema/EventWrapper.java @@ -7,34 +7,42 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * Necessary due to flatbuffers requiring unions to be wrapped in tables. */ +@SuppressWarnings("unused") public final class EventWrapper extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb) { return getRootAsEventWrapper(_bb, new EventWrapper()); } public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb, EventWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public EventWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public byte eType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; } + public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o + bb_pos) : null; } public static int createEventWrapper(FlatBufferBuilder builder, byte e_type, int eOffset) { - builder.startObject(2); + builder.startTable(2); EventWrapper.addE(builder, eOffset); EventWrapper.addEType(builder, e_type); return EventWrapper.endEventWrapper(builder); } - public static void startEventWrapper(FlatBufferBuilder builder) { builder.startObject(2); } + public static void startEventWrapper(FlatBufferBuilder builder) { builder.startTable(2); } public static void addEType(FlatBufferBuilder builder, byte eType) { builder.addByte(0, eType, 0); } public static void addE(FlatBufferBuilder builder, int eOffset) { builder.addOffset(1, eOffset, 0); } public static int endEventWrapper(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public EventWrapper get(int j) { return get(new EventWrapper(), j); } + public EventWrapper get(EventWrapper obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/GameFooter.java b/schema/java/battlecode/schema/GameFooter.java index b5512bb5..eb94d47b 100644 --- a/schema/java/battlecode/schema/GameFooter.java +++ b/schema/java/battlecode/schema/GameFooter.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * The final event sent in the game. */ +@SuppressWarnings("unused") public final class GameFooter extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static GameFooter getRootAsGameFooter(ByteBuffer _bb) { return getRootAsGameFooter(_bb, new GameFooter()); } public static GameFooter getRootAsGameFooter(ByteBuffer _bb, GameFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public GameFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -24,16 +25,23 @@ public final class GameFooter extends Table { public static int createGameFooter(FlatBufferBuilder builder, byte winner) { - builder.startObject(1); + builder.startTable(1); GameFooter.addWinner(builder, winner); return GameFooter.endGameFooter(builder); } - public static void startGameFooter(FlatBufferBuilder builder) { builder.startObject(1); } + public static void startGameFooter(FlatBufferBuilder builder) { builder.startTable(1); } public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } public static int endGameFooter(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public GameFooter get(int j) { return get(new GameFooter(), j); } + public GameFooter get(GameFooter obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/GameHeader.java b/schema/java/battlecode/schema/GameHeader.java index 77363711..41069ab2 100644 --- a/schema/java/battlecode/schema/GameHeader.java +++ b/schema/java/battlecode/schema/GameHeader.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * The first event sent in the game. Contains all metadata about the game. */ +@SuppressWarnings("unused") public final class GameHeader extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static GameHeader getRootAsGameHeader(ByteBuffer _bb) { return getRootAsGameHeader(_bb, new GameHeader()); } public static GameHeader getRootAsGameHeader(ByteBuffer _bb, GameHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public GameHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -26,28 +27,36 @@ public final class GameHeader extends Table { /** * The teams participating in the game. */ - public TeamData teams(int j) { return teams(new TeamData(), j); } - public TeamData teams(TeamData obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.TeamData teams(int j) { return teams(new battlecode.schema.TeamData(), j); } + public battlecode.schema.TeamData teams(battlecode.schema.TeamData obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int teamsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.TeamData.Vector teamsVector() { return teamsVector(new battlecode.schema.TeamData.Vector()); } + public battlecode.schema.TeamData.Vector teamsVector(battlecode.schema.TeamData.Vector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } /** * Information about all body types in the game. */ - public BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new BodyTypeMetadata(), j); } - public BodyTypeMetadata bodyTypeMetadata(BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new battlecode.schema.BodyTypeMetadata(), j); } + public battlecode.schema.BodyTypeMetadata bodyTypeMetadata(battlecode.schema.BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int bodyTypeMetadataLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.BodyTypeMetadata.Vector bodyTypeMetadataVector() { return bodyTypeMetadataVector(new battlecode.schema.BodyTypeMetadata.Vector()); } + public battlecode.schema.BodyTypeMetadata.Vector bodyTypeMetadataVector(battlecode.schema.BodyTypeMetadata.Vector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } + public battlecode.schema.Constants constants() { return constants(new battlecode.schema.Constants()); } + public battlecode.schema.Constants constants(battlecode.schema.Constants obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } public static int createGameHeader(FlatBufferBuilder builder, int specVersionOffset, int teamsOffset, - int bodyTypeMetadataOffset) { - builder.startObject(3); + int bodyTypeMetadataOffset, + int constantsOffset) { + builder.startTable(4); + GameHeader.addConstants(builder, constantsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addSpecVersion(builder, specVersionOffset); return GameHeader.endGameHeader(builder); } - public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startGameHeader(FlatBufferBuilder builder) { builder.startTable(4); } public static void addSpecVersion(FlatBufferBuilder builder, int specVersionOffset) { builder.addOffset(0, specVersionOffset, 0); } public static void addTeams(FlatBufferBuilder builder, int teamsOffset) { builder.addOffset(1, teamsOffset, 0); } public static int createTeamsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } @@ -55,9 +64,17 @@ public static int createGameHeader(FlatBufferBuilder builder, public static void addBodyTypeMetadata(FlatBufferBuilder builder, int bodyTypeMetadataOffset) { builder.addOffset(2, bodyTypeMetadataOffset, 0); } public static int createBodyTypeMetadataVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startBodyTypeMetadataVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addConstants(FlatBufferBuilder builder, int constantsOffset) { builder.addOffset(3, constantsOffset, 0); } public static int endGameHeader(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public GameHeader get(int j) { return get(new GameHeader(), j); } + public GameHeader get(GameHeader obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/GameMap.java b/schema/java/battlecode/schema/GameMap.java index 09b78818..100460a5 100644 --- a/schema/java/battlecode/schema/GameMap.java +++ b/schema/java/battlecode/schema/GameMap.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * The map a round is played on. */ +@SuppressWarnings("unused") public final class GameMap extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static GameMap getRootAsGameMap(ByteBuffer _bb) { return getRootAsGameMap(_bb, new GameMap()); } public static GameMap getRootAsGameMap(ByteBuffer _bb, GameMap obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public GameMap __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -26,18 +27,18 @@ public final class GameMap extends Table { /** * The bottom corner of the map. */ - public Vec minCorner() { return minCorner(new Vec()); } - public Vec minCorner(Vec obj) { int o = __offset(6); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + public battlecode.schema.Vec minCorner() { return minCorner(new battlecode.schema.Vec()); } + public battlecode.schema.Vec minCorner(battlecode.schema.Vec obj) { int o = __offset(6); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } /** * The top corner of the map. */ - public Vec maxCorner() { return maxCorner(new Vec()); } - public Vec maxCorner(Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + public battlecode.schema.Vec maxCorner() { return maxCorner(new battlecode.schema.Vec()); } + public battlecode.schema.Vec maxCorner(battlecode.schema.Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } /** * The bodies on the map. */ - public SpawnedBodyTable bodies() { return bodies(new SpawnedBodyTable()); } - public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.SpawnedBodyTable bodies() { return bodies(new battlecode.schema.SpawnedBodyTable()); } + public battlecode.schema.SpawnedBodyTable bodies(battlecode.schema.SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The random seed of the map. */ @@ -47,10 +48,20 @@ public final class GameMap extends Table { */ public double passability(int j) { int o = __offset(14); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } public int passabilityLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } + public DoubleVector passabilityVector() { return passabilityVector(new DoubleVector()); } + public DoubleVector passabilityVector(DoubleVector obj) { int o = __offset(14); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer passabilityAsByteBuffer() { return __vector_as_bytebuffer(14, 8); } public ByteBuffer passabilityInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 8); } + public battlecode.schema.VecTable leadLocations() { return leadLocations(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable leadLocations(battlecode.schema.VecTable obj) { int o = __offset(16); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public double leadAmounts(int j) { int o = __offset(18); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } + public int leadAmountsLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } + public DoubleVector leadAmountsVector() { return leadAmountsVector(new DoubleVector()); } + public DoubleVector leadAmountsVector(DoubleVector obj) { int o = __offset(18); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer leadAmountsAsByteBuffer() { return __vector_as_bytebuffer(18, 8); } + public ByteBuffer leadAmountsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 8); } - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(6); } + public static void startGameMap(FlatBufferBuilder builder) { builder.startTable(8); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } @@ -59,9 +70,20 @@ public final class GameMap extends Table { public static void addPassability(FlatBufferBuilder builder, int passabilityOffset) { builder.addOffset(5, passabilityOffset, 0); } public static int createPassabilityVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } public static void startPassabilityVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } + public static void addLeadLocations(FlatBufferBuilder builder, int leadLocationsOffset) { builder.addOffset(6, leadLocationsOffset, 0); } + public static void addLeadAmounts(FlatBufferBuilder builder, int leadAmountsOffset) { builder.addOffset(7, leadAmountsOffset, 0); } + public static int createLeadAmountsVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } + public static void startLeadAmountsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } public static int endGameMap(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public GameMap get(int j) { return get(new GameMap(), j); } + public GameMap get(GameMap obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/GameWrapper.java b/schema/java/battlecode/schema/GameWrapper.java index 25a0c03e..8067e8d1 100644 --- a/schema/java/battlecode/schema/GameWrapper.java +++ b/schema/java/battlecode/schema/GameWrapper.java @@ -7,7 +7,6 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * If events are not otherwise delimited, this wrapper structure * allows a game to be stored in a single buffer. @@ -16,23 +15,29 @@ * corresponding to matchFooters[0]. These indices allow quick traversal of * the file. */ +@SuppressWarnings("unused") public final class GameWrapper extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb) { return getRootAsGameWrapper(_bb, new GameWrapper()); } public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb, GameWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public GameWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** * The series of events comprising the game. */ - public EventWrapper events(int j) { return events(new EventWrapper(), j); } - public EventWrapper events(EventWrapper obj, int j) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.EventWrapper events(int j) { return events(new battlecode.schema.EventWrapper(), j); } + public battlecode.schema.EventWrapper events(battlecode.schema.EventWrapper obj, int j) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int eventsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.EventWrapper.Vector eventsVector() { return eventsVector(new battlecode.schema.EventWrapper.Vector()); } + public battlecode.schema.EventWrapper.Vector eventsVector(battlecode.schema.EventWrapper.Vector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } /** * The indices of the headers of the matches, in order. */ public int matchHeaders(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int matchHeadersLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public IntVector matchHeadersVector() { return matchHeadersVector(new IntVector()); } + public IntVector matchHeadersVector(IntVector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer matchHeadersAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } public ByteBuffer matchHeadersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } /** @@ -40,6 +45,8 @@ public final class GameWrapper extends Table { */ public int matchFooters(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int matchFootersLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public IntVector matchFootersVector() { return matchFootersVector(new IntVector()); } + public IntVector matchFootersVector(IntVector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer matchFootersAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } public ByteBuffer matchFootersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } @@ -47,14 +54,14 @@ public static int createGameWrapper(FlatBufferBuilder builder, int eventsOffset, int matchHeadersOffset, int matchFootersOffset) { - builder.startObject(3); + builder.startTable(3); GameWrapper.addMatchFooters(builder, matchFootersOffset); GameWrapper.addMatchHeaders(builder, matchHeadersOffset); GameWrapper.addEvents(builder, eventsOffset); return GameWrapper.endGameWrapper(builder); } - public static void startGameWrapper(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startGameWrapper(FlatBufferBuilder builder) { builder.startTable(3); } public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(0, eventsOffset, 0); } public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -65,8 +72,15 @@ public static int createGameWrapper(FlatBufferBuilder builder, public static int createMatchFootersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startMatchFootersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endGameWrapper(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public GameWrapper get(int j) { return get(new GameWrapper(), j); } + public GameWrapper get(GameWrapper obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/MatchFooter.java b/schema/java/battlecode/schema/MatchFooter.java index 8777c9ea..962821a6 100644 --- a/schema/java/battlecode/schema/MatchFooter.java +++ b/schema/java/battlecode/schema/MatchFooter.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * Sent to end a match. */ +@SuppressWarnings("unused") public final class MatchFooter extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb) { return getRootAsMatchFooter(_bb, new MatchFooter()); } public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb, MatchFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public MatchFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -28,30 +29,39 @@ public final class MatchFooter extends Table { /** * Profiler data for team A and B if profiling is enabled. */ - public ProfilerFile profilerFiles(int j) { return profilerFiles(new ProfilerFile(), j); } - public ProfilerFile profilerFiles(ProfilerFile obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.ProfilerFile profilerFiles(int j) { return profilerFiles(new battlecode.schema.ProfilerFile(), j); } + public battlecode.schema.ProfilerFile profilerFiles(battlecode.schema.ProfilerFile obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int profilerFilesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.ProfilerFile.Vector profilerFilesVector() { return profilerFilesVector(new battlecode.schema.ProfilerFile.Vector()); } + public battlecode.schema.ProfilerFile.Vector profilerFilesVector(battlecode.schema.ProfilerFile.Vector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } public static int createMatchFooter(FlatBufferBuilder builder, byte winner, int totalRounds, int profilerFilesOffset) { - builder.startObject(3); + builder.startTable(3); MatchFooter.addProfilerFiles(builder, profilerFilesOffset); MatchFooter.addTotalRounds(builder, totalRounds); MatchFooter.addWinner(builder, winner); return MatchFooter.endMatchFooter(builder); } - public static void startMatchFooter(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startMatchFooter(FlatBufferBuilder builder) { builder.startTable(3); } public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } public static void addTotalRounds(FlatBufferBuilder builder, int totalRounds) { builder.addInt(1, totalRounds, 0); } public static void addProfilerFiles(FlatBufferBuilder builder, int profilerFilesOffset) { builder.addOffset(2, profilerFilesOffset, 0); } public static int createProfilerFilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startProfilerFilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endMatchFooter(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public MatchFooter get(int j) { return get(new MatchFooter(), j); } + public MatchFooter get(MatchFooter obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/MatchHeader.java b/schema/java/battlecode/schema/MatchHeader.java index b167ea98..e2e2b042 100644 --- a/schema/java/battlecode/schema/MatchHeader.java +++ b/schema/java/battlecode/schema/MatchHeader.java @@ -7,21 +7,22 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * Sent to start a match. */ +@SuppressWarnings("unused") public final class MatchHeader extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb) { return getRootAsMatchHeader(_bb, new MatchHeader()); } public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb, MatchHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public MatchHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** * The map the match was played on. */ - public GameMap map() { return map(new GameMap()); } - public GameMap map(GameMap obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.GameMap map() { return map(new battlecode.schema.GameMap()); } + public battlecode.schema.GameMap map(battlecode.schema.GameMap obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The maximum number of rounds in this match. */ @@ -30,18 +31,25 @@ public final class MatchHeader extends Table { public static int createMatchHeader(FlatBufferBuilder builder, int mapOffset, int maxRounds) { - builder.startObject(2); + builder.startTable(2); MatchHeader.addMaxRounds(builder, maxRounds); MatchHeader.addMap(builder, mapOffset); return MatchHeader.endMatchHeader(builder); } - public static void startMatchHeader(FlatBufferBuilder builder) { builder.startObject(2); } + public static void startMatchHeader(FlatBufferBuilder builder) { builder.startTable(2); } public static void addMap(FlatBufferBuilder builder, int mapOffset) { builder.addOffset(0, mapOffset, 0); } public static void addMaxRounds(FlatBufferBuilder builder, int maxRounds) { builder.addInt(1, maxRounds, 0); } public static int endMatchHeader(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public MatchHeader get(int j) { return get(new MatchHeader(), j); } + public MatchHeader get(MatchHeader obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/ProfilerEvent.java b/schema/java/battlecode/schema/ProfilerEvent.java index 58c47f12..11941e62 100644 --- a/schema/java/battlecode/schema/ProfilerEvent.java +++ b/schema/java/battlecode/schema/ProfilerEvent.java @@ -7,7 +7,6 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * These tables are set-up so that they match closely with speedscope's file format documented at * https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. @@ -15,10 +14,12 @@ * A single event in a profile. Represents either an open event (meaning a * method has been entered) or a close event (meaning the method was exited). */ +@SuppressWarnings("unused") public final class ProfilerEvent extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb) { return getRootAsProfilerEvent(_bb, new ProfilerEvent()); } public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb, ProfilerEvent obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public ProfilerEvent __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -38,20 +39,27 @@ public static int createProfilerEvent(FlatBufferBuilder builder, boolean isOpen, int at, int frame) { - builder.startObject(3); + builder.startTable(3); ProfilerEvent.addFrame(builder, frame); ProfilerEvent.addAt(builder, at); ProfilerEvent.addIsOpen(builder, isOpen); return ProfilerEvent.endProfilerEvent(builder); } - public static void startProfilerEvent(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startProfilerEvent(FlatBufferBuilder builder) { builder.startTable(3); } public static void addIsOpen(FlatBufferBuilder builder, boolean isOpen) { builder.addBoolean(0, isOpen, false); } public static void addAt(FlatBufferBuilder builder, int at) { builder.addInt(1, at, 0); } public static void addFrame(FlatBufferBuilder builder, int frame) { builder.addInt(2, frame, 0); } public static int endProfilerEvent(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public ProfilerEvent get(int j) { return get(new ProfilerEvent(), j); } + public ProfilerEvent get(ProfilerEvent obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/ProfilerFile.java b/schema/java/battlecode/schema/ProfilerFile.java index c101925d..ff535bfe 100644 --- a/schema/java/battlecode/schema/ProfilerFile.java +++ b/schema/java/battlecode/schema/ProfilerFile.java @@ -7,15 +7,16 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A profiler file is a collection of profiles. * When profiling is enabled there is one of these per team per match. */ +@SuppressWarnings("unused") public final class ProfilerFile extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb) { return getRootAsProfilerFile(_bb, new ProfilerFile()); } public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb, ProfilerFile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public ProfilerFile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -23,23 +24,27 @@ public final class ProfilerFile extends Table { */ public String frames(int j) { int o = __offset(4); return o != 0 ? __string(__vector(o) + j * 4) : null; } public int framesLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public StringVector framesVector() { return framesVector(new StringVector()); } + public StringVector framesVector(StringVector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } /** * The recorded profiles, one per robot. */ - public ProfilerProfile profiles(int j) { return profiles(new ProfilerProfile(), j); } - public ProfilerProfile profiles(ProfilerProfile obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.ProfilerProfile profiles(int j) { return profiles(new battlecode.schema.ProfilerProfile(), j); } + public battlecode.schema.ProfilerProfile profiles(battlecode.schema.ProfilerProfile obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int profilesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.ProfilerProfile.Vector profilesVector() { return profilesVector(new battlecode.schema.ProfilerProfile.Vector()); } + public battlecode.schema.ProfilerProfile.Vector profilesVector(battlecode.schema.ProfilerProfile.Vector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } public static int createProfilerFile(FlatBufferBuilder builder, int framesOffset, int profilesOffset) { - builder.startObject(2); + builder.startTable(2); ProfilerFile.addProfiles(builder, profilesOffset); ProfilerFile.addFrames(builder, framesOffset); return ProfilerFile.endProfilerFile(builder); } - public static void startProfilerFile(FlatBufferBuilder builder) { builder.startObject(2); } + public static void startProfilerFile(FlatBufferBuilder builder) { builder.startTable(2); } public static void addFrames(FlatBufferBuilder builder, int framesOffset) { builder.addOffset(0, framesOffset, 0); } public static int createFramesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startFramesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -47,8 +52,15 @@ public static int createProfilerFile(FlatBufferBuilder builder, public static int createProfilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startProfilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endProfilerFile(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public ProfilerFile get(int j) { return get(new ProfilerFile(), j); } + public ProfilerFile get(ProfilerFile obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/ProfilerProfile.java b/schema/java/battlecode/schema/ProfilerProfile.java index 15312ead..3e711644 100644 --- a/schema/java/battlecode/schema/ProfilerProfile.java +++ b/schema/java/battlecode/schema/ProfilerProfile.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A profile contains all events and is labeled with a name. */ +@SuppressWarnings("unused") public final class ProfilerProfile extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb) { return getRootAsProfilerProfile(_bb, new ProfilerProfile()); } public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb, ProfilerProfile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public ProfilerProfile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -26,27 +27,36 @@ public final class ProfilerProfile extends Table { /** * The events that occurred in the profile. */ - public ProfilerEvent events(int j) { return events(new ProfilerEvent(), j); } - public ProfilerEvent events(ProfilerEvent obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public battlecode.schema.ProfilerEvent events(int j) { return events(new battlecode.schema.ProfilerEvent(), j); } + public battlecode.schema.ProfilerEvent events(battlecode.schema.ProfilerEvent obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int eventsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public battlecode.schema.ProfilerEvent.Vector eventsVector() { return eventsVector(new battlecode.schema.ProfilerEvent.Vector()); } + public battlecode.schema.ProfilerEvent.Vector eventsVector(battlecode.schema.ProfilerEvent.Vector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } public static int createProfilerProfile(FlatBufferBuilder builder, int nameOffset, int eventsOffset) { - builder.startObject(2); + builder.startTable(2); ProfilerProfile.addEvents(builder, eventsOffset); ProfilerProfile.addName(builder, nameOffset); return ProfilerProfile.endProfilerProfile(builder); } - public static void startProfilerProfile(FlatBufferBuilder builder) { builder.startObject(2); } + public static void startProfilerProfile(FlatBufferBuilder builder) { builder.startTable(2); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(1, eventsOffset, 0); } public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endProfilerProfile(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public ProfilerProfile get(int j) { return get(new ProfilerProfile(), j); } + public ProfilerProfile get(ProfilerProfile obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/RGBTable.java b/schema/java/battlecode/schema/RGBTable.java index 6164af79..6b59668a 100644 --- a/schema/java/battlecode/schema/RGBTable.java +++ b/schema/java/battlecode/schema/RGBTable.java @@ -7,26 +7,33 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A table of RGB values. */ +@SuppressWarnings("unused") public final class RGBTable extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static RGBTable getRootAsRGBTable(ByteBuffer _bb) { return getRootAsRGBTable(_bb, new RGBTable()); } public static RGBTable getRootAsRGBTable(ByteBuffer _bb, RGBTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public RGBTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int red(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int redLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public IntVector redVector() { return redVector(new IntVector()); } + public IntVector redVector(IntVector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer redAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer redInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } public int green(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int greenLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public IntVector greenVector() { return greenVector(new IntVector()); } + public IntVector greenVector(IntVector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer greenAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } public ByteBuffer greenInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } public int blue(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int blueLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public IntVector blueVector() { return blueVector(new IntVector()); } + public IntVector blueVector(IntVector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer blueAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } public ByteBuffer blueInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } @@ -34,14 +41,14 @@ public static int createRGBTable(FlatBufferBuilder builder, int redOffset, int greenOffset, int blueOffset) { - builder.startObject(3); + builder.startTable(3); RGBTable.addBlue(builder, blueOffset); RGBTable.addGreen(builder, greenOffset); RGBTable.addRed(builder, redOffset); return RGBTable.endRGBTable(builder); } - public static void startRGBTable(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startRGBTable(FlatBufferBuilder builder) { builder.startTable(3); } public static void addRed(FlatBufferBuilder builder, int redOffset) { builder.addOffset(0, redOffset, 0); } public static int createRedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -52,8 +59,15 @@ public static int createRGBTable(FlatBufferBuilder builder, public static int createBlueVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBlueVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endRGBTable(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public RGBTable get(int j) { return get(new RGBTable(), j); } + public RGBTable get(RGBTable obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/Round.java b/schema/java/battlecode/schema/Round.java index c36316ae..33c4d08f 100644 --- a/schema/java/battlecode/schema/Round.java +++ b/schema/java/battlecode/schema/Round.java @@ -7,17 +7,18 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A single time-step in a Game. * The bulk of the data in the file is stored in tables like this. * Note that a struct-of-arrays format is more space efficient than an array- * of-structs. */ +@SuppressWarnings("unused") public final class Round extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static Round getRootAsRound(ByteBuffer _bb) { return getRootAsRound(_bb, new Round()); } public static Round getRootAsRound(ByteBuffer _bb, Round obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public Round __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -25,44 +26,48 @@ public final class Round extends Table { */ public int teamIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int teamIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public IntVector teamIDsVector() { return teamIDsVector(new IntVector()); } + public IntVector teamIDsVector(IntVector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } - /** - * The number of votes the teams get, 0 or 1. - */ - public int teamVotes(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamVotesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamVotesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer teamVotesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - /** - * The ID of the Enlightenment Center got the bid. - */ - public int teamBidderIDs(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamBidderIDsLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamBidderIDsAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer teamBidderIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + public int teamLeadChange(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamLeadChangeLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public IntVector teamLeadChangeVector() { return teamLeadChangeVector(new IntVector()); } + public IntVector teamLeadChangeVector(IntVector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer teamLeadChangeAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer teamLeadChangeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int teamGoldChange(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamGoldChangeLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public IntVector teamGoldChangeVector() { return teamGoldChangeVector(new IntVector()); } + public IntVector teamGoldChangeVector(IntVector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer teamGoldChangeAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer teamGoldChangeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } /** * The IDs of bodies that moved. */ public int movedIDs(int j) { int o = __offset(10); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int movedIDsLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; } + public IntVector movedIDsVector() { return movedIDsVector(new IntVector()); } + public IntVector movedIDsVector(IntVector obj) { int o = __offset(10); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer movedIDsAsByteBuffer() { return __vector_as_bytebuffer(10, 4); } public ByteBuffer movedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 4); } /** * The new locations of bodies that have moved. */ - public VecTable movedLocs() { return movedLocs(new VecTable()); } - public VecTable movedLocs(VecTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.VecTable movedLocs() { return movedLocs(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable movedLocs(battlecode.schema.VecTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * New bodies. */ - public SpawnedBodyTable spawnedBodies() { return spawnedBodies(new SpawnedBodyTable()); } - public SpawnedBodyTable spawnedBodies(SpawnedBodyTable obj) { int o = __offset(14); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.SpawnedBodyTable spawnedBodies() { return spawnedBodies(new battlecode.schema.SpawnedBodyTable()); } + public battlecode.schema.SpawnedBodyTable spawnedBodies(battlecode.schema.SpawnedBodyTable obj) { int o = __offset(14); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The IDs of bodies that died. */ public int diedIDs(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int diedIDsLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public IntVector diedIDsVector() { return diedIDsVector(new IntVector()); } + public IntVector diedIDsVector(IntVector obj) { int o = __offset(16); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer diedIDsAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } public ByteBuffer diedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } /** @@ -71,6 +76,8 @@ public final class Round extends Table { */ public int actionIDs(int j) { int o = __offset(18); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int actionIDsLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } + public IntVector actionIDsVector() { return actionIDsVector(new IntVector()); } + public IntVector actionIDsVector(IntVector obj) { int o = __offset(18); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer actionIDsAsByteBuffer() { return __vector_as_bytebuffer(18, 4); } public ByteBuffer actionIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 4); } /** @@ -78,6 +85,8 @@ public final class Round extends Table { */ public byte actions(int j) { int o = __offset(20); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } public int actionsLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; } + public ByteVector actionsVector() { return actionsVector(new ByteVector()); } + public ByteVector actionsVector(ByteVector obj) { int o = __offset(20); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer actionsAsByteBuffer() { return __vector_as_bytebuffer(20, 1); } public ByteBuffer actionsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 1); } /** @@ -85,102 +94,114 @@ public final class Round extends Table { */ public int actionTargets(int j) { int o = __offset(22); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int actionTargetsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } + public IntVector actionTargetsVector() { return actionTargetsVector(new IntVector()); } + public IntVector actionTargetsVector(IntVector obj) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer actionTargetsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } public ByteBuffer actionTargetsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } + /** + * The IDs of the robots who changed their indicator strings + */ + public int indicatorStringIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorStringIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } + public IntVector indicatorStringIDsVector() { return indicatorStringIDsVector(new IntVector()); } + public IntVector indicatorStringIDsVector(IntVector obj) { int o = __offset(24); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer indicatorStringIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } + public ByteBuffer indicatorStringIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } + /** + * The messages of the robots who changed their indicator strings + */ + public String indicatorStrings(int j) { int o = __offset(26); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int indicatorStringsLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; } + public StringVector indicatorStringsVector() { return indicatorStringsVector(new StringVector()); } + public StringVector indicatorStringsVector(StringVector obj) { int o = __offset(26); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } + public battlecode.schema.VecTable leadDropLocations() { return leadDropLocations(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable leadDropLocations(battlecode.schema.VecTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public int leadDropValues(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadDropValuesLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } + public IntVector leadDropValuesVector() { return leadDropValuesVector(new IntVector()); } + public IntVector leadDropValuesVector(IntVector obj) { int o = __offset(30); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer leadDropValuesAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } + public ByteBuffer leadDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + public battlecode.schema.VecTable goldDropLocations() { return goldDropLocations(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable goldDropLocations(battlecode.schema.VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public int goldDropValues(int j) { int o = __offset(34); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int goldDropValuesLength() { int o = __offset(34); return o != 0 ? __vector_len(o) : 0; } + public IntVector goldDropValuesVector() { return goldDropValuesVector(new IntVector()); } + public IntVector goldDropValuesVector(IntVector obj) { int o = __offset(34); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer goldDropValuesAsByteBuffer() { return __vector_as_bytebuffer(34, 4); } + public ByteBuffer goldDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 34, 4); } /** * The IDs of bodies that set indicator dots */ - public int indicatorDotIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorDotIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } - public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } + public int indicatorDotIDs(int j) { int o = __offset(36); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorDotIDsLength() { int o = __offset(36); return o != 0 ? __vector_len(o) : 0; } + public IntVector indicatorDotIDsVector() { return indicatorDotIDsVector(new IntVector()); } + public IntVector indicatorDotIDsVector(IntVector obj) { int o = __offset(36); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(36, 4); } + public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 36, 4); } /** * The location of the indicator dots */ - public VecTable indicatorDotLocs() { return indicatorDotLocs(new VecTable()); } - public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.VecTable indicatorDotLocs() { return indicatorDotLocs(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable indicatorDotLocs(battlecode.schema.VecTable obj) { int o = __offset(38); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator dots */ - public RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new RGBTable()); } - public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new battlecode.schema.RGBTable()); } + public battlecode.schema.RGBTable indicatorDotRGBs(battlecode.schema.RGBTable obj) { int o = __offset(40); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The IDs of bodies that set indicator lines */ - public int indicatorLineIDs(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorLineIDsLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } - public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + public int indicatorLineIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorLineIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } + public IntVector indicatorLineIDsVector() { return indicatorLineIDsVector(new IntVector()); } + public IntVector indicatorLineIDsVector(IntVector obj) { int o = __offset(42); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } + public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } /** * The start location of the indicator lines */ - public VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new VecTable()); } - public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable indicatorLineStartLocs(battlecode.schema.VecTable obj) { int o = __offset(44); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The end location of the indicator lines */ - public VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new VecTable()); } - public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(34); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public battlecode.schema.VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable indicatorLineEndLocs(battlecode.schema.VecTable obj) { int o = __offset(46); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator lines */ - public RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new RGBTable()); } - public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(36); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - */ - public String logs() { int o = __offset(38); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer logsAsByteBuffer() { return __vector_as_bytebuffer(38, 1); } - public ByteBuffer logsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 38, 1); } + public battlecode.schema.RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new battlecode.schema.RGBTable()); } + public battlecode.schema.RGBTable indicatorLineRGBs(battlecode.schema.RGBTable obj) { int o = __offset(48); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The first sent Round in a match should have index 1. (The starting state, * created by the MatchHeader, can be thought to have index 0.) * It should increase by one for each following round. */ - public int roundID() { int o = __offset(40); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int roundID() { int o = __offset(50); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The IDs of player bodies. */ - public int bytecodeIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodeIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } - public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } + public int bytecodeIDs(int j) { int o = __offset(52); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodeIDsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; } + public IntVector bytecodeIDsVector() { return bytecodeIDsVector(new IntVector()); } + public IntVector bytecodeIDsVector(IntVector obj) { int o = __offset(52); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(52, 4); } + public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 4); } /** * The bytecodes used by the player bodies. */ - public int bytecodesUsed(int j) { int o = __offset(44); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodesUsedLength() { int o = __offset(44); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(44, 4); } - public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 44, 4); } - /** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - */ - public int teamNumBuffs(int j) { int o = __offset(46); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamNumBuffsLength() { int o = __offset(46); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamNumBuffsAsByteBuffer() { return __vector_as_bytebuffer(46, 4); } - public ByteBuffer teamNumBuffsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 46, 4); } + public int bytecodesUsed(int j) { int o = __offset(54); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodesUsedLength() { int o = __offset(54); return o != 0 ? __vector_len(o) : 0; } + public IntVector bytecodesUsedVector() { return bytecodesUsedVector(new IntVector()); } + public IntVector bytecodesUsedVector(IntVector obj) { int o = __offset(54); return o != 0 ? obj.__assign(__vector(o), bb) : null; } + public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(54, 4); } + public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 54, 4); } public static int createRound(FlatBufferBuilder builder, int teamIDsOffset, - int teamVotesOffset, - int teamBidderIDsOffset, + int teamLeadChangeOffset, + int teamGoldChangeOffset, int movedIDsOffset, int movedLocsOffset, int spawnedBodiesOffset, @@ -188,6 +209,12 @@ public static int createRound(FlatBufferBuilder builder, int actionIDsOffset, int actionsOffset, int actionTargetsOffset, + int indicatorStringIDsOffset, + int indicatorStringsOffset, + int leadDropLocationsOffset, + int leadDropValuesOffset, + int goldDropLocationsOffset, + int goldDropValuesOffset, int indicatorDotIDsOffset, int indicatorDotLocsOffset, int indicatorDotRGBsOffset, @@ -195,17 +222,13 @@ public static int createRound(FlatBufferBuilder builder, int indicatorLineStartLocsOffset, int indicatorLineEndLocsOffset, int indicatorLineRGBsOffset, - int logsOffset, int roundID, int bytecodeIDsOffset, - int bytecodesUsedOffset, - int teamNumBuffsOffset) { - builder.startObject(22); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); + int bytecodesUsedOffset) { + builder.startTable(26); Round.addBytecodesUsed(builder, bytecodesUsedOffset); Round.addBytecodeIDs(builder, bytecodeIDsOffset); Round.addRoundID(builder, roundID); - Round.addLogs(builder, logsOffset); Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); @@ -213,6 +236,12 @@ public static int createRound(FlatBufferBuilder builder, Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); + Round.addGoldDropValues(builder, goldDropValuesOffset); + Round.addGoldDropLocations(builder, goldDropLocationsOffset); + Round.addLeadDropValues(builder, leadDropValuesOffset); + Round.addLeadDropLocations(builder, leadDropLocationsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); Round.addActionTargets(builder, actionTargetsOffset); Round.addActions(builder, actionsOffset); Round.addActionIDs(builder, actionIDsOffset); @@ -220,22 +249,22 @@ public static int createRound(FlatBufferBuilder builder, Round.addSpawnedBodies(builder, spawnedBodiesOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addMovedIDs(builder, movedIDsOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); + Round.addTeamGoldChange(builder, teamGoldChangeOffset); + Round.addTeamLeadChange(builder, teamLeadChangeOffset); Round.addTeamIDs(builder, teamIDsOffset); return Round.endRound(builder); } - public static void startRound(FlatBufferBuilder builder) { builder.startObject(22); } + public static void startRound(FlatBufferBuilder builder) { builder.startTable(26); } public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(0, teamIDsOffset, 0); } public static int createTeamIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamVotes(FlatBufferBuilder builder, int teamVotesOffset) { builder.addOffset(1, teamVotesOffset, 0); } - public static int createTeamVotesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamVotesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamBidderIDs(FlatBufferBuilder builder, int teamBidderIDsOffset) { builder.addOffset(2, teamBidderIDsOffset, 0); } - public static int createTeamBidderIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamBidderIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamLeadChange(FlatBufferBuilder builder, int teamLeadChangeOffset) { builder.addOffset(1, teamLeadChangeOffset, 0); } + public static int createTeamLeadChangeVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamLeadChangeVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamGoldChange(FlatBufferBuilder builder, int teamGoldChangeOffset) { builder.addOffset(2, teamGoldChangeOffset, 0); } + public static int createTeamGoldChangeVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamGoldChangeVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addMovedIDs(FlatBufferBuilder builder, int movedIDsOffset) { builder.addOffset(3, movedIDsOffset, 0); } public static int createMovedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startMovedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -248,36 +277,54 @@ public static int createRound(FlatBufferBuilder builder, public static int createActionIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startActionIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addActions(FlatBufferBuilder builder, int actionsOffset) { builder.addOffset(8, actionsOffset, 0); } - public static int createActionsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static int createActionsVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); } + public static int createActionsVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); } public static void startActionsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } public static void addActionTargets(FlatBufferBuilder builder, int actionTargetsOffset) { builder.addOffset(9, actionTargetsOffset, 0); } public static int createActionTargetsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startActionTargetsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(10, indicatorDotIDsOffset, 0); } + public static void addIndicatorStringIDs(FlatBufferBuilder builder, int indicatorStringIDsOffset) { builder.addOffset(10, indicatorStringIDsOffset, 0); } + public static int createIndicatorStringIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startIndicatorStringIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorStrings(FlatBufferBuilder builder, int indicatorStringsOffset) { builder.addOffset(11, indicatorStringsOffset, 0); } + public static int createIndicatorStringsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startIndicatorStringsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addLeadDropLocations(FlatBufferBuilder builder, int leadDropLocationsOffset) { builder.addOffset(12, leadDropLocationsOffset, 0); } + public static void addLeadDropValues(FlatBufferBuilder builder, int leadDropValuesOffset) { builder.addOffset(13, leadDropValuesOffset, 0); } + public static int createLeadDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startLeadDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addGoldDropLocations(FlatBufferBuilder builder, int goldDropLocationsOffset) { builder.addOffset(14, goldDropLocationsOffset, 0); } + public static void addGoldDropValues(FlatBufferBuilder builder, int goldDropValuesOffset) { builder.addOffset(15, goldDropValuesOffset, 0); } + public static int createGoldDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startGoldDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(16, indicatorDotIDsOffset, 0); } public static int createIndicatorDotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorDotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(11, indicatorDotLocsOffset, 0); } - public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(12, indicatorDotRGBsOffset, 0); } - public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(13, indicatorLineIDsOffset, 0); } + public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(17, indicatorDotLocsOffset, 0); } + public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(18, indicatorDotRGBsOffset, 0); } + public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(19, indicatorLineIDsOffset, 0); } public static int createIndicatorLineIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorLineIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(14, indicatorLineStartLocsOffset, 0); } - public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(15, indicatorLineEndLocsOffset, 0); } - public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(16, indicatorLineRGBsOffset, 0); } - public static void addLogs(FlatBufferBuilder builder, int logsOffset) { builder.addOffset(17, logsOffset, 0); } - public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(18, roundID, 0); } - public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(19, bytecodeIDsOffset, 0); } + public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(20, indicatorLineStartLocsOffset, 0); } + public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(21, indicatorLineEndLocsOffset, 0); } + public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(22, indicatorLineRGBsOffset, 0); } + public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(23, roundID, 0); } + public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(24, bytecodeIDsOffset, 0); } public static int createBytecodeIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodeIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(20, bytecodesUsedOffset, 0); } + public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(25, bytecodesUsedOffset, 0); } public static int createBytecodesUsedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodesUsedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamNumBuffs(FlatBufferBuilder builder, int teamNumBuffsOffset) { builder.addOffset(21, teamNumBuffsOffset, 0); } - public static int createTeamNumBuffsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamNumBuffsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endRound(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public Round get(int j) { return get(new Round(), j); } + public Round get(Round obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/SpawnedBodyTable.java b/schema/java/battlecode/schema/SpawnedBodyTable.java index 3616e911..c25bd19b 100644 --- a/schema/java/battlecode/schema/SpawnedBodyTable.java +++ b/schema/java/battlecode/schema/SpawnedBodyTable.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A list of new bodies to be placed on the map. */ +@SuppressWarnings("unused") public final class SpawnedBodyTable extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb) { return getRootAsSpawnedBodyTable(_bb, new SpawnedBodyTable()); } public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb, SpawnedBodyTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public SpawnedBodyTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -26,6 +27,8 @@ public final class SpawnedBodyTable extends Table { */ public int robotIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int robotIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public IntVector robotIDsVector() { return robotIDsVector(new IntVector()); } + public IntVector robotIDsVector(IntVector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer robotIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer robotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } /** @@ -33,6 +36,8 @@ public final class SpawnedBodyTable extends Table { */ public byte teamIDs(int j) { int o = __offset(6); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } public int teamIDsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteVector teamIDsVector() { return teamIDsVector(new ByteVector()); } + public ByteVector teamIDsVector(ByteVector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } /** @@ -40,31 +45,22 @@ public final class SpawnedBodyTable extends Table { */ public byte types(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } public int typesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteVector typesVector() { return typesVector(new ByteVector()); } + public ByteVector typesVector(ByteVector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer typesAsByteBuffer() { return __vector_as_bytebuffer(8, 1); } public ByteBuffer typesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); } /** * The locations of the bodies. */ - public VecTable locs() { return locs(new VecTable()); } - public VecTable locs(VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - */ - public int influences(int j) { int o = __offset(12); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int influencesLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer influencesAsByteBuffer() { return __vector_as_bytebuffer(12, 4); } - public ByteBuffer influencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 4); } + public battlecode.schema.VecTable locs() { return locs(new battlecode.schema.VecTable()); } + public battlecode.schema.VecTable locs(battlecode.schema.VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } public static int createSpawnedBodyTable(FlatBufferBuilder builder, int robotIDsOffset, int teamIDsOffset, int typesOffset, - int locsOffset, - int influencesOffset) { - builder.startObject(5); - SpawnedBodyTable.addInfluences(builder, influencesOffset); + int locsOffset) { + builder.startTable(4); SpawnedBodyTable.addLocs(builder, locsOffset); SpawnedBodyTable.addTypes(builder, typesOffset); SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); @@ -72,23 +68,29 @@ public static int createSpawnedBodyTable(FlatBufferBuilder builder, return SpawnedBodyTable.endSpawnedBodyTable(builder); } - public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(5); } + public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startTable(4); } public static void addRobotIDs(FlatBufferBuilder builder, int robotIDsOffset) { builder.addOffset(0, robotIDsOffset, 0); } public static int createRobotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRobotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(1, teamIDsOffset, 0); } - public static int createTeamIDsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static int createTeamIDsVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); } + public static int createTeamIDsVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); } public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } public static void addTypes(FlatBufferBuilder builder, int typesOffset) { builder.addOffset(2, typesOffset, 0); } - public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); } + public static int createTypesVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); } public static void startTypesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } public static void addLocs(FlatBufferBuilder builder, int locsOffset) { builder.addOffset(3, locsOffset, 0); } - public static void addInfluences(FlatBufferBuilder builder, int influencesOffset) { builder.addOffset(4, influencesOffset, 0); } - public static int createInfluencesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startInfluencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endSpawnedBodyTable(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public SpawnedBodyTable get(int j) { return get(new SpawnedBodyTable(), j); } + public SpawnedBodyTable get(SpawnedBodyTable obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/TeamData.java b/schema/java/battlecode/schema/TeamData.java index 57e3e4db..b8ce13c1 100644 --- a/schema/java/battlecode/schema/TeamData.java +++ b/schema/java/battlecode/schema/TeamData.java @@ -7,14 +7,15 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * Data relevant to a particular team. */ +@SuppressWarnings("unused") public final class TeamData extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static TeamData getRootAsTeamData(ByteBuffer _bb) { return getRootAsTeamData(_bb, new TeamData()); } public static TeamData getRootAsTeamData(ByteBuffer _bb, TeamData obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public TeamData __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } /** @@ -38,20 +39,27 @@ public static int createTeamData(FlatBufferBuilder builder, int nameOffset, int packageNameOffset, byte teamID) { - builder.startObject(3); + builder.startTable(3); TeamData.addPackageName(builder, packageNameOffset); TeamData.addName(builder, nameOffset); TeamData.addTeamID(builder, teamID); return TeamData.endTeamData(builder); } - public static void startTeamData(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startTeamData(FlatBufferBuilder builder) { builder.startTable(3); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addPackageName(FlatBufferBuilder builder, int packageNameOffset) { builder.addOffset(1, packageNameOffset, 0); } public static void addTeamID(FlatBufferBuilder builder, byte teamID) { builder.addByte(2, teamID, 0); } public static int endTeamData(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public TeamData get(int j) { return get(new TeamData(), j); } + public TeamData get(TeamData obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/java/battlecode/schema/Vec.java b/schema/java/battlecode/schema/Vec.java index a9cdcb68..d37153c2 100644 --- a/schema/java/battlecode/schema/Vec.java +++ b/schema/java/battlecode/schema/Vec.java @@ -7,13 +7,13 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A vector in two-dimensional space. Discrete space, of course. * Defaults to the 0 vector. */ +@SuppressWarnings("unused") public final class Vec extends Struct { - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public Vec __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int x() { return bb.getInt(bb_pos + 0); } @@ -25,5 +25,12 @@ public static int createVec(FlatBufferBuilder builder, int x, int y) { builder.putInt(x); return builder.offset(); } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public Vec get(int j) { return get(new Vec(), j); } + public Vec get(Vec obj, int j) { return obj.__assign(__element(j), bb); } + } } diff --git a/schema/java/battlecode/schema/VecTable.java b/schema/java/battlecode/schema/VecTable.java index 82da91e7..67da2579 100644 --- a/schema/java/battlecode/schema/VecTable.java +++ b/schema/java/battlecode/schema/VecTable.java @@ -7,35 +7,40 @@ import java.util.*; import com.google.flatbuffers.*; -@SuppressWarnings("unused") /** * A table of vectors. */ +@SuppressWarnings("unused") public final class VecTable extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_2_0_0(); } public static VecTable getRootAsVecTable(ByteBuffer _bb) { return getRootAsVecTable(_bb, new VecTable()); } public static VecTable getRootAsVecTable(ByteBuffer _bb, VecTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } - public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public VecTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int xs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int xsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public IntVector xsVector() { return xsVector(new IntVector()); } + public IntVector xsVector(IntVector obj) { int o = __offset(4); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer xsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer xsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } public int ys(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } public int ysLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public IntVector ysVector() { return ysVector(new IntVector()); } + public IntVector ysVector(IntVector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), bb) : null; } public ByteBuffer ysAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } public ByteBuffer ysInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } public static int createVecTable(FlatBufferBuilder builder, int xsOffset, int ysOffset) { - builder.startObject(2); + builder.startTable(2); VecTable.addYs(builder, ysOffset); VecTable.addXs(builder, xsOffset); return VecTable.endVecTable(builder); } - public static void startVecTable(FlatBufferBuilder builder) { builder.startObject(2); } + public static void startVecTable(FlatBufferBuilder builder) { builder.startTable(2); } public static void addXs(FlatBufferBuilder builder, int xsOffset) { builder.addOffset(0, xsOffset, 0); } public static int createXsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startXsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -43,8 +48,15 @@ public static int createVecTable(FlatBufferBuilder builder, public static int createYsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startYsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endVecTable(FlatBufferBuilder builder) { - int o = builder.endObject(); + int o = builder.endTable(); return o; } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public VecTable get(int j) { return get(new VecTable(), j); } + public VecTable get(VecTable obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } } diff --git a/schema/package.json b/schema/package.json index df4343ce..b380aba2 100644 --- a/schema/package.json +++ b/schema/package.json @@ -1,6 +1,6 @@ { "name": "battlecode-schema", - "version": "2021.0.0", + "version": "2022.0.0", "private": "true", "description": "flatbuffers parser for battlecode match files", "main": "ts/index.ts", From 15c94d894e95838f903465cfab11799290987350 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Mon, 20 Dec 2021 13:00:32 -0500 Subject: [PATCH 114/413] debug --- client/playback/src/gen/create.ts | 7 ++++ client/visualizer/src/gamearea/renderer.ts | 39 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index ebdd598f..e5dd1d50 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -598,6 +598,13 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = schema.Round.addActions(builder, bb_actions); schema.Round.addActionTargets(builder, bb_actionTargets); + const goldXs = [Math.floor(SIZE*Math.random())] + const goldYs = [Math.floor(SIZE*Math.random())] + const goldLocs = createVecTable(builder, goldXs, goldYs); + const goldVals = schema.Round.createGoldDropValuesVector(builder, [1]); + schema.Round.addGoldDropLocations(builder, goldLocs); + schema.Round.addGoldDropValues(builder, goldVals); + events.push(createEventWrapper(builder, schema.Round.endRound(builder), schema.Event.Round)); } diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index 5ff5a54c..f527718e 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -56,9 +56,10 @@ export default class Renderer { else this.ctx.translate(-viewMin.y, -viewMin.x); this.renderBackground(world); + this.renderResources(world); this.renderBodies(world, curTime, nextStep, lerpAmount); - + world.mapStats.goldVals this.renderIndicatorDotsLines(world); this.setMouseoverEvent(world); @@ -130,6 +131,42 @@ export default class Renderer { this.ctx.restore(); } + private renderResources(world: GameWorld) { + this.ctx.save(); + this.ctx.globalAlpha = 1; + + let minX = world.minCorner.x; + let minY = world.minCorner.y; + let width = world.maxCorner.x - world.minCorner.x; + let height = world.maxCorner.y - world.minCorner.y; + + + const leadImg = this.imgs.star; + const goldImg = this.imgs.star; + + const map = world.mapStats; + const scale = 1; + + for (let i = 0; i < width; i++) for (let j = 0; j < height; j++){ + let idxVal = map.getIdx(i,j); + let plotJ = height-j-1; + + this.ctx.globalAlpha = 1; + const cx = (minX+i)*scale, cy = (minY+plotJ)*scale; + + if(map.goldVals[idxVal] > 0){ + if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx, cy, scale, scale); + else this.ctx.drawImage(goldImg, cy, cx, scale, scale); + } + if(map.leadVals[idxVal] > 0){ + if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx, cy, scale, scale); + else this.ctx.drawImage(leadImg, cy, cx, scale, scale); + } + } + + this.ctx.restore(); + } + private renderBodies(world: GameWorld, curTime: number, nextStep?: NextStep, lerpAmount?: number) { const bodies = world.bodies; const length = bodies.length; From 382c765fecc21e69014db0460310d230db721290 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 13:04:13 -0500 Subject: [PATCH 115/413] Create before adding --- client/playback/src/gen/create.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index e5dd1d50..88eef933 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -590,6 +590,11 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = const bb_actions = schema.Round.createActionsVector(builder, actions); const bb_actionTargets = schema.Round.createActionTargetsVector(builder, actionTargets); + const goldXs = [Math.floor(SIZE*Math.random())] + const goldYs = [Math.floor(SIZE*Math.random())] + const goldLocs = createVecTable(builder, goldXs, goldYs); + const goldVals = schema.Round.createGoldDropValuesVector(builder, [1]); + schema.Round.startRound(builder); schema.Round.addRoundID(builder, i); schema.Round.addMovedLocs(builder, movedLocs); @@ -597,11 +602,7 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = schema.Round.addActionIDs(builder, bb_actionIDs); schema.Round.addActions(builder, bb_actions); schema.Round.addActionTargets(builder, bb_actionTargets); - - const goldXs = [Math.floor(SIZE*Math.random())] - const goldYs = [Math.floor(SIZE*Math.random())] - const goldLocs = createVecTable(builder, goldXs, goldYs); - const goldVals = schema.Round.createGoldDropValuesVector(builder, [1]); + schema.Round.addGoldDropLocations(builder, goldLocs); schema.Round.addGoldDropValues(builder, goldVals); From a28e6f8d3f5e366daba9f6ca6a2cc8710b4ab2b9 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Mon, 20 Dec 2021 13:42:14 -0500 Subject: [PATCH 116/413] lead and gold loading and rendering from schema --- client/playback/src/gameworld.ts | 12 ++++++++---- client/visualizer/src/imageloader.ts | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 524e19be..40073a63 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -289,6 +289,9 @@ export default class GameWorld { this.maxCorner.y = maxCorner.y(); this.mapStats.maxCorner.x = maxCorner.x(); this.mapStats.maxCorner.y = maxCorner.y(); + + this.mapStats.goldVals = new Int32Array(maxCorner.x()*maxCorner.y()) + this.mapStats.leadVals = new Int32Array(maxCorner.x()*maxCorner.y()) const bodies = map.bodies(this._bodiesSlot); if (bodies && bodies.robotIDsLength) { @@ -307,7 +310,8 @@ export default class GameWorld { xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[x][y] = map.leadAmountsArray[i]; + + this.mapStats.leadVals[this.mapStats.getIdx(x,y)] = map.leadAmountsArray[i]; }) } @@ -404,7 +408,7 @@ export default class GameWorld { xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[x][y] = delta.leadDropLocations[i]; + this.mapStats.leadVals[this.mapStats.getIdx(x,y)] = delta.leadDropValues[i]; }) } @@ -412,10 +416,10 @@ export default class GameWorld { if (goldLocations) { const xs = goldLocations.xsArray(); const ys = goldLocations.ysArray(); - + let inst = this; xs.forEach((x, i) => { const y = ys[i] - this.mapStats.goldVals[x][y] = delta.goldDropLocations[i]; + inst.mapStats.goldVals[inst.mapStats.getIdx(x,y)] = delta.goldDropValues(i); }) } diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index e9fccd82..0463b629 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -14,6 +14,10 @@ export type AllImages = { soldier: Array, watchtower: Array, }, + resources: { + lead: Image, + gold: Image + } effects: { // TODO }, controls: { @@ -84,6 +88,10 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { soldier: [], laboratory: [], }, + resources: { + lead: null, + gold: null + }, effects: { death: null, embezzle: [], @@ -177,6 +185,10 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { loadImage(result.robots.soldier, BLU, 'robots/blue_soldier'); loadImage(result.robots.laboratory, BLU, 'robots/blue_lab'); + loadImage(result.resources, 'lead', 'star'); + loadImage(result.resources, 'gold', 'star'); + + // loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); // effects From 741bbdea6c2ed1d04b5b7faab0c91245d7235616 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Mon, 20 Dec 2021 14:30:33 -0500 Subject: [PATCH 117/413] progress on sidebar --- client/visualizer/src/main/looper.ts | 5 ++- client/visualizer/src/sidebar/stats.ts | 56 +++++++++++++++++--------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 69e13fb3..c64f01ac 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -334,14 +334,15 @@ export default class Looper { let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); // Update each robot count + console.log(teamStats.robots) this.stats.robots.forEach((type: schema.BodyType) => { this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level - this.stats.setRobotInfluence(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b)); // TODO: differentiate levels, maybe + this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b), teamHP); // TODO: differentiate levels, maybe }); // Set votes // this.stats.setVotes(teamID, teamStats.votes); - this.stats.setTeamInfluence(teamID, teamHP, totalHP); + //### this.stats.setTeamInfluence(teamID, teamHP, totalHP); // this.stats.setBuffs(teamID, teamStats.numBuffs); // this.stats.setBid(teamID, teamStats.bid); this.stats.setIncome(teamID, teamStats.leadChange, world.turn); // TODO: show gold change diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index f85ce6dc..b9ca6403 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -128,8 +128,8 @@ export default class Stats { for (let value in this.robotTds[teamID]) { robotCounts[value] = document.createElement("tr"); const title = document.createElement("td"); - if (value === "conviction") title.innerHTML = "C"; - if (value === "influence") title.innerHTML = "I"; + if (value === "count") title.innerHTML = "Count"; + if (value === "hp") title.innerHTML = "HP"; robotCounts[value].appendChild(title); } @@ -137,15 +137,15 @@ export default class Stats { let robotName: string = cst.bodyTypeToString(robot); let tdRobot: HTMLTableCellElement = document.createElement("td"); tdRobot.className = "robotSpriteStats"; - tdRobot.style.height = "100px"; - tdRobot.style.width = "100px"; + tdRobot.style.height = "45px"; + tdRobot.style.width = "60px"; - // const img: HTMLImageElement = this.robotImages[robotName][inGameID]; - // img.style.width = "60%"; - // img.style.height = "60%"; + const img: HTMLImageElement = this.robotImages[robotName][inGameID]; + img.style.width = "100%"; + img.style.height = "100%"; // TODO: images - // tdRobot.appendChild(img); + tdRobot.appendChild(img); robotImages.appendChild(tdRobot); for (let value in this.robotTds[teamID]) { @@ -463,7 +463,7 @@ export default class Stats { // Create td elements for the robot counts and store them in robotTds // so we can update these robot counts later; maps robot type to count - for (let value of ["count", "conviction", "influence"]) { + for (let value of ["count", "hp"]) { this.robotTds[teamID][value] = new Map(); for (let robot of this.robots) { let td: HTMLTableCellElement = document.createElement("td"); @@ -561,20 +561,21 @@ export default class Stats { */ setRobotCount(teamID: number, robotType: schema.BodyType, count: number) { let td: HTMLTableCellElement = this.robotTds[teamID]["count"][robotType]; + console.log(count, robotType); td.innerHTML = String(count); } /** - * Change the robot conviction on the stats bar + * Change the robot HP (previously conviction) on the stats bar */ - setRobotConviction(teamID: number, robotType: schema.BodyType, conviction: number, totalConviction: number) { - let td: HTMLTableCellElement = this.robotTds[teamID]["conviction"][robotType]; - td.innerHTML = String(conviction); + setRobotHP(teamID: number, robotType: schema.BodyType, HP: number, totalHP: number) { + let td: HTMLTableCellElement = this.robotTds[teamID]["hp"][robotType]; + td.innerHTML = String(HP); const robotName: string = cst.bodyTypeToString(robotType); let img = this.robotImages[robotName][teamID]; - const size = (55 + 45 * conviction / totalConviction); + const size = (55 + 45 * HP / totalHP); img.style.width = size + "%"; img.style.height = size + "%"; } @@ -582,10 +583,10 @@ export default class Stats { /** * Change the robot influence on the stats bar */ - setRobotInfluence(teamID: number, robotType: schema.BodyType, influence: number) { + /**### setRobotInfluence(teamID: number, robotType: schema.BodyType, influence: number) { let td: HTMLTableCellElement = this.robotTds[teamID]["influence"][robotType]; td.innerHTML = String(influence); - } + }*/ /** * Change the votes of the given team @@ -607,12 +608,12 @@ export default class Stats { // } } - setTeamInfluence(teamID: number, influence: number, totalInfluence: number) { + /** setTeamInfluence(teamID: number, influence: number, totalInfluence: number) { const relBar: HTMLDivElement = this.relativeBars[teamID]; relBar.innerText = String(influence); if (totalInfluence == 0) relBar.style.width = '50%'; else relBar.style.width = String(Math.round(influence * 100 / totalInfluence)) + "%"; - } + }*/ setBuffs(teamID: number, numBuffs: number) { //this.buffDisplays[teamID].numBuffs.textContent = String(numBuffs); @@ -620,7 +621,8 @@ export default class Stats { this.buffDisplays[teamID].buff.style.fontSize = 14 * Math.sqrt(Math.min(9, cst.buffFactor(numBuffs))) + "px"; } - setIncome(teamID: number, income: number, turn: number) { + setIncome(teamID: number, income: number, turn: number) { // leadIncome, goldIncome + this.incomeDisplays[teamID].income.textContent = String(income); if (!this.teamMapToTurnsIncomeSet.has(teamID)) { this.teamMapToTurnsIncomeSet.set(teamID, new Set()); @@ -636,6 +638,22 @@ export default class Stats { teamTurnsIncomeSet?.add(turn); this.incomeChart.update(); } + /** this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later + this.incomeDisplays[teamID].goldIncome.textContent = String(goldIncome); + if (!this.teamMapToTurnsIncomeSet.has(teamID)) { + this.teamMapToTurnsIncomeSet.set(teamID, new Set()); + } + let teamTurnsIncomeSet = this.teamMapToTurnsIncomeSet.get(teamID); + + if (!teamTurnsIncomeSet!.has(turn)) { + //@ts-ignore + this.incomeChart.data.datasets![teamID - 1].data?.push({y:income, x: turn}); + this.incomeChart.data.datasets?.forEach((d) => { + d.data?.sort((a, b) => a.x - b.x); + }); + teamTurnsIncomeSet?.add(turn); + this.incomeChart.update(); + }*/ } setWinner(teamID: number, teamNames: Array, teamIDs: Array) { From a420aad0acb51912f909e08fd6ee00a03be827cd Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 14:40:28 -0500 Subject: [PATCH 118/413] correctly track counts --- client/playback/src/gameworld.ts | 50 +++++++++++++++++--------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 40073a63..3b09ecf9 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -200,7 +200,7 @@ export default class GameWorld { action: new Int8Array(0), parent: new Int32Array(0), hp: new Int32Array(0), - level: new Int8Array(0), + level: new Int8Array(1), portable: new Int8Array(0), prototype: new Int8Array(0) }, 'id'); @@ -472,6 +472,10 @@ export default class GameWorld { case schema.Action.UPGRADE: setAction(); + teamStatsObj.robots[body.type][body.level - 1] -= 1; + teamStatsObj.robots[body.type][body.level + 1 - 1] += 1; + teamStatsObj.total_hp[body.type][body.level - 1] -= body.hp; + teamStatsObj.total_hp[body.type][body.level + 1 - 1] += body.hp; this.bodies.alter({ id: robotID, level: body.level + 1}); break; @@ -537,29 +541,27 @@ export default class GameWorld { // this.teamStats.set(team, teamStatsObj); // }) - // // Died bodies - // if (delta.diedIDsLength() > 0) { - // // Update team stats - // var indices = this.bodies.lookupIndices(delta.diedIDsArray()); - // for(let i = 0; i < delta.diedIDsLength(); i++) { - // let index = indices[i]; - // let team = this.bodies.arrays.team[index]; - // let type = this.bodies.arrays.type[index]; - // let statObj = this.teamStats.get(team); - // if(!statObj) {continue;} // In case this is a neutral bot - // statObj.robots[type] -= 1; - // let influence = this.bodies.arrays.influence[index]; - // let conviction = this.bodies.arrays.conviction[index]; - // statObj.influence[type] -= influence; // cancel extra negative influence - // statObj.conviction[type] -= conviction; // cancel extra negative conviction - // this.teamStats.set(team, statObj); - // } + // Died bodies + if (delta.diedIDsLength() > 0) { + // Update team stats + var indices = this.bodies.lookupIndices(delta.diedIDsArray()); + for(let i = 0; i < delta.diedIDsLength(); i++) { + let index = indices[i]; + let team = this.bodies.arrays.team[index]; + let type = this.bodies.arrays.type[index]; + let statObj = this.teamStats.get(team); + if(!statObj) {continue;} // In case this is a neutral bot + statObj.robots[type][this.bodies.arrays.level[index] - 1] -= 1; + let hp = this.bodies.arrays.hp[index]; + statObj.total_hp[type][this.bodies.arrays.level[index] - 1] -= hp; + this.teamStats.set(team, statObj); + } - // // Update bodies soa - // this.insertDiedBodies(delta); + // Update bodies soa + this.insertDiedBodies(delta); - // this.bodies.deleteBulk(delta.diedIDsArray()); - // } + this.bodies.deleteBulk(delta.diedIDsArray()); + } // Insert indicator dots and lines this.insertIndicatorDots(delta); @@ -667,8 +669,8 @@ export default class GameWorld { for(let i = 0; i < bodies.robotIDsLength(); i++) { // if(teams[i] == 0) continue; var statObj = this.teamStats.get(teams[i]); - statObj.robots[types[i]][1] += 1; // TODO: handle level - statObj.total_hp[types[i]][1] += this.meta.types[types[i]].hp; // TODO: extract meta info + statObj.robots[types[i]][0] += 1; // TODO: handle level + statObj.total_hp[types[i]][0] += this.meta.types[types[i]].hp; // TODO: extract meta info this.teamStats.set(teams[i], statObj); } From 9ce148a5b6eca73e8854167a2fa1477939c6239b Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 15:12:34 -0500 Subject: [PATCH 119/413] Fix counts --- client/playback/src/gameworld.ts | 7 ++++++- client/playback/src/gen/create.ts | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 3b09ecf9..f0eefd5a 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -200,7 +200,7 @@ export default class GameWorld { action: new Int8Array(0), parent: new Int32Array(0), hp: new Int32Array(0), - level: new Int8Array(1), + level: new Int8Array(0), portable: new Int8Array(0), prototype: new Int8Array(0) }, 'id'); @@ -685,6 +685,10 @@ export default class GameWorld { // Initialize convictions // Insert bodies + + const levels = new Int8Array(bodies.robotIDsLength()); + levels.fill(1); + this.bodies.insertBulk({ id: bodies.robotIDsArray(), team: teams, @@ -696,6 +700,7 @@ export default class GameWorld { ability: new Int8Array(bodies.robotIDsLength()), bid: new Int32Array(bodies.robotIDsLength()), parent: new Int32Array(bodies.robotIDsLength()), + level: levels }); } diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 88eef933..8e7313d2 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -37,7 +37,8 @@ type BodiesType = { teamIDs: number[], types: number[], xs: number[], - ys: number[], + ys: number[]//, + //levels: number[] }; type MapType = { @@ -114,7 +115,7 @@ function makeRandomBodies(manager: IDsManager, unitCount: number): BodiesType{ teamIDs: Array(unitCount), types: Array(unitCount), xs: Array(unitCount), - ys: Array(unitCount), + ys: Array(unitCount) //levels: Array(unitCount) }; @@ -124,7 +125,7 @@ function makeRandomBodies(manager: IDsManager, unitCount: number): BodiesType{ bodies.types[i] = bodyTypeList[random(0, bodyVariety-1)]; bodies.xs[i] = random(0, SIZE-1); bodies.ys[i] = random(0, SIZE-1); - //bodies.levels[i] = random(1, 3); + //bodies.levels[i] = 1; //random(1, 3); TODO: upgrades } return bodies; From 7208b66fbb468c46d8fd699d5e97ef8b0cf5d72d Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Mon, 20 Dec 2021 15:42:36 -0500 Subject: [PATCH 120/413] progress --- client/visualizer/src/gamearea/renderer.ts | 14 +++++++++++++- client/visualizer/src/imageloader.ts | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index f527718e..329cdfa9 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -215,7 +215,19 @@ export default class Renderer { } const renderBot = (i: number) => { - const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][teams[i]]; + const DEFAULT: number = 0; + const PORTABLE: number = 1; + const PROTOTYPE: number = 2; + let body_status = DEFAULT + console.log(i, bodies.length, types.length, "hhh"); + console.log(bodies[i]); + if (Boolean(bodies[i].portable)){ + body_status = PORTABLE; + } + if (Boolean(bodies[i].prototype)){ + body_status = PROTOTYPE; + } + const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]]; this.drawBot(img, realXs[i], realYs[i], hps[i]); // TODO: draw bot this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID); diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index 0463b629..a71ec203 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -41,6 +41,10 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { const NEUTRAL: number = 0; const RED: number = 1; const BLU: number = 2; + //To index additional states for buildings + const DEFAULT: number = 0; + const PORTABLE: number = 1; + const PROTOTYPE: number = 2; function loadImage(obj, slot, path, src?) : void { const f = loadImage; @@ -169,7 +173,10 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { } // robot sprites - loadImage(result.robots.archon, RED, 'robots/red_archon_portable'); + loadImage(result.robots.archon, DEFAULT * 2 + RED, 'robots/red_archon'); + loadImage(result.robots.archon, PROTOTYPE * 2 + RED, 'robots/red_archon_prototype'); + loadImage(result.robots.archon, PORTABLE * 2 + RED, 'robots/red_archon_portable'); + loadImage(result.robots.watchtower, RED, 'robots/red_watchtower'); loadImage(result.robots.builder, RED, 'robots/red_builder'); loadImage(result.robots.miner, RED, 'robots/red_miner'); @@ -177,7 +184,11 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { loadImage(result.robots.soldier, RED, 'robots/red_soldier'); loadImage(result.robots.laboratory, RED, 'robots/red_lab'); - loadImage(result.robots.archon, BLU, 'robots/blue_archon_portable'); + + loadImage(result.robots.archon, DEFAULT * 2 + BLU, 'robots/blue_archon'); + loadImage(result.robots.archon, PROTOTYPE * 2 + BLU, 'robots/blue_archon_prototype'); + loadImage(result.robots.archon, PORTABLE * 2 + BLU, 'robots/blue_archon_portable'); + loadImage(result.robots.watchtower, BLU, 'robots/blue_watchtower'); loadImage(result.robots.builder, BLU, 'robots/blue_builder'); loadImage(result.robots.miner, BLU, 'robots/blue_miner'); From fbd41054926ba91ba218c349b60fc700a7b065a0 Mon Sep 17 00:00:00 2001 From: meeeeee Date: Mon, 20 Dec 2021 16:11:49 -0500 Subject: [PATCH 121/413] edits to the chart in visualizer --- client/visualizer/src/main/looper.ts | 4 +- client/visualizer/src/sidebar/stats.ts | 72 ++++++++++++++------------ 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index c64f01ac..c7fd377c 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -334,7 +334,6 @@ export default class Looper { let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); // Update each robot count - console.log(teamStats.robots) this.stats.robots.forEach((type: schema.BodyType) => { this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b), teamHP); // TODO: differentiate levels, maybe @@ -345,7 +344,8 @@ export default class Looper { //### this.stats.setTeamInfluence(teamID, teamHP, totalHP); // this.stats.setBuffs(teamID, teamStats.numBuffs); // this.stats.setBid(teamID, teamStats.bid); - this.stats.setIncome(teamID, teamStats.leadChange, world.turn); // TODO: show gold change + this.stats.setIncome(teamID, teamStats.leadChange, teamStats.goldChange, world.turn); + // this.stats.setIncome(teamID, 3 + teamID, 5 + teamID, world.turn); } if (this.match.winner && this.match.current.turn == this.match.lastTurn) { diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index b9ca6403..4f8bb401 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -22,7 +22,8 @@ type BuffDisplay = { } type IncomeDisplay = { - income: HTMLSpanElement + leadIncome: HTMLSpanElement + goldIncome: HTMLSpanElement } /** @@ -289,11 +290,15 @@ export default class Stats { private initIncomeDisplays(teamIDs: Array) { const incomeDisplays: IncomeDisplay[] = []; teamIDs.forEach((id: number) => { - const income = document.createElement("span"); - income.style.color = hex[id]; - income.style.fontWeight = "bold"; - income.textContent = "1"; - incomeDisplays[id] = {income: income}; + const leadIncome = document.createElement("span"); + const goldIncome = document.createElement("span"); + leadIncome.style.color = hex[id]; + leadIncome.style.fontWeight = "bold"; + leadIncome.textContent = "1"; + goldIncome.style.color = hex[id]; + goldIncome.style.fontWeight = "bold"; + goldIncome.textContent = "2"; + incomeDisplays[id] = {leadIncome: leadIncome, goldIncome: goldIncome}; }); return incomeDisplays; } @@ -326,10 +331,10 @@ export default class Stats { table.style.width = "100%"; const title = document.createElement('td'); - title.colSpan = 2; + title.colSpan = 4; const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'Total Income Per Turn'; + label.innerText = 'Total Lead & Gold Income Per Turn'; const row = document.createElement("tr"); @@ -338,7 +343,8 @@ export default class Stats { // cell.appendChild(document.createTextNode("1.001")); // cell.appendChild(this.buffDisplays[id].numBuffs); // cell.appendChild(document.createTextNode(" = ")); - cell.appendChild(this.incomeDisplays[id].income); + cell.appendChild(this.incomeDisplays[id].leadIncome); + cell.appendChild(this.incomeDisplays[id].goldIncome); row.appendChild(cell); }); @@ -504,17 +510,31 @@ export default class Stats { type: 'line', data: { datasets: [{ - label: 'Red', + label: 'Red Lead', data: [], backgroundColor: 'rgba(255, 99, 132, 0)', - borderColor: 'rgb(219, 54, 39)', + borderColor: 'rgb(131,24,27)', pointRadius: 0, }, { - label: 'Blue', + label: 'Blue Lead', data: [], backgroundColor: 'rgba(54, 162, 235, 0)', - borderColor: 'rgb(79, 126, 230)', + borderColor: 'rgb(108, 140, 188)', + pointRadius: 0, + }, + { + label: 'Red Gold', + data: [], + backgroundColor: 'rgba(162, 162, 235, 0)', + borderColor: 'rgb(205,162,163)', + pointRadius: 0, + }, + { + label: 'Blue Gold', + data: [], + backgroundColor: 'rgba(54, 0, 235, 0)', + borderColor: 'rgb(68, 176, 191)', pointRadius: 0, }] }, @@ -621,24 +641,8 @@ export default class Stats { this.buffDisplays[teamID].buff.style.fontSize = 14 * Math.sqrt(Math.min(9, cst.buffFactor(numBuffs))) + "px"; } - setIncome(teamID: number, income: number, turn: number) { // leadIncome, goldIncome - - this.incomeDisplays[teamID].income.textContent = String(income); - if (!this.teamMapToTurnsIncomeSet.has(teamID)) { - this.teamMapToTurnsIncomeSet.set(teamID, new Set()); - } - let teamTurnsIncomeSet = this.teamMapToTurnsIncomeSet.get(teamID); - - if (!teamTurnsIncomeSet!.has(turn)) { - //@ts-ignore - this.incomeChart.data.datasets![teamID - 1].data?.push({y:income, x: turn}); - this.incomeChart.data.datasets?.forEach((d) => { - d.data?.sort((a, b) => a.x - b.x); - }); - teamTurnsIncomeSet?.add(turn); - this.incomeChart.update(); - } - /** this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later + setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number) { // incomes + this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later this.incomeDisplays[teamID].goldIncome.textContent = String(goldIncome); if (!this.teamMapToTurnsIncomeSet.has(teamID)) { this.teamMapToTurnsIncomeSet.set(teamID, new Set()); @@ -647,13 +651,15 @@ export default class Stats { if (!teamTurnsIncomeSet!.has(turn)) { //@ts-ignore - this.incomeChart.data.datasets![teamID - 1].data?.push({y:income, x: turn}); + this.incomeChart.data.datasets![teamID - 1].data?.push({y: leadIncome, x: turn}); + //@ts-ignore + this.incomeChart.data.datasets![teamID + 1].data?.push({y: goldIncome, x: turn}); this.incomeChart.data.datasets?.forEach((d) => { d.data?.sort((a, b) => a.x - b.x); }); teamTurnsIncomeSet?.add(turn); this.incomeChart.update(); - }*/ + } } setWinner(teamID: number, teamNames: Array, teamIDs: Array) { From e33703e37fbf88d276bb64599e1ca44d08292e0e Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Mon, 20 Dec 2021 17:05:49 -0500 Subject: [PATCH 122/413] portables and prototypes arrays --- client/visualizer/src/gamearea/renderer.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index 329cdfa9..555dbb72 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -176,7 +176,9 @@ export default class Renderer { const ids = bodies.arrays.id; const xs = bodies.arrays.x; const ys = bodies.arrays.y; - const abilities = bodies.arrays.ability; + const actions = bodies.arrays.action; + const portables = bodies.arrays.portable; + const prototypes = bodies.arrays.prototype; const minY = world.minCorner.y; const maxY = world.maxCorner.y -1; @@ -219,12 +221,12 @@ export default class Renderer { const PORTABLE: number = 1; const PROTOTYPE: number = 2; let body_status = DEFAULT - console.log(i, bodies.length, types.length, "hhh"); - console.log(bodies[i]); - if (Boolean(bodies[i].portable)){ + // console.log(i, bodies.length, types.length, "hhh"); + // console.log(bodies[i]); + if (Boolean(portables[i])){ body_status = PORTABLE; } - if (Boolean(bodies[i].prototype)){ + if (Boolean(prototypes[i])){ body_status = PROTOTYPE; } const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]]; From db5ee5666aeddfe33ed1661ab9f3cd46b9344b67 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Tue, 21 Dec 2021 15:59:29 -0500 Subject: [PATCH 123/413] Lead and gold working (size based on amount), generated maps contain gold spawning for testing --- client/playback/src/gen/create.ts | 2 +- client/visualizer/src/gamearea/renderer.ts | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 88eef933..29fadb4c 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -593,7 +593,7 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = const goldXs = [Math.floor(SIZE*Math.random())] const goldYs = [Math.floor(SIZE*Math.random())] const goldLocs = createVecTable(builder, goldXs, goldYs); - const goldVals = schema.Round.createGoldDropValuesVector(builder, [1]); + const goldVals = schema.Round.createGoldDropValuesVector(builder, [Math.floor(100*Math.random())]); schema.Round.startRound(builder); schema.Round.addRoundID(builder, i); diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index f527718e..22a05021 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -141,26 +141,33 @@ export default class Renderer { let height = world.maxCorner.y - world.minCorner.y; - const leadImg = this.imgs.star; - const goldImg = this.imgs.star; + const leadImg = this.imgs.resources.lead; + const goldImg = this.imgs.resources.gold; const map = world.mapStats; const scale = 1; + const sigmoid = (x) => { + return 1 / (1 + Math.exp(-x)) + } + for (let i = 0; i < width; i++) for (let j = 0; j < height; j++){ let idxVal = map.getIdx(i,j); let plotJ = height-j-1; + this.ctx.globalAlpha = 1; const cx = (minX+i)*scale, cy = (minY+plotJ)*scale; if(map.goldVals[idxVal] > 0){ - if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx, cy, scale, scale); - else this.ctx.drawImage(goldImg, cy, cx, scale, scale); + let size = sigmoid(map.goldVals[idxVal] / 50); + if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1-size)/2, cy + (1-size)/2, scale * size, scale * size); + else this.ctx.drawImage(goldImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); } if(map.leadVals[idxVal] > 0){ - if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx, cy, scale, scale); - else this.ctx.drawImage(leadImg, cy, cx, scale, scale); + let size = sigmoid(map.goldVals[idxVal] / 50); + if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1-size)/2, cy + (1-size)/2, scale * size, scale * size); + else this.ctx.drawImage(leadImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); } } From bd22da47b8eae92eae7dd5510cc6a459af2c5356 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Tue, 21 Dec 2021 17:00:31 -0600 Subject: [PATCH 124/413] various syntax fixes --- .../main/battlecode/common/GameConstants.java | 2 +- .../main/battlecode/doc/RobotTypeTaglet.java | 2 +- .../bytecode/InstrumentingMethodVisitor.java | 6 +- .../src/main/battlecode/server/GameMaker.java | 10 +- engine/src/main/battlecode/server/Server.java | 14 +-- .../world/AnomalyScheduleEntry.java | 4 +- .../src/main/battlecode/world/GameWorld.java | 94 ++++++++----------- .../main/battlecode/world/InternalRobot.java | 4 +- engine/src/main/battlecode/world/LiveMap.java | 24 ++--- .../src/main/battlecode/world/ObjectInfo.java | 2 +- .../battlecode/world/RobotControllerImpl.java | 65 +++++++------ .../main/battlecode/world/TestMapBuilder.java | 2 +- .../main/battlecode/world/maps/Circle.java | 2 +- .../battlecode/world/maps/MapTestSmall.java | 2 +- .../battlecode/world/RobotControllerTest.java | 10 +- .../test/battlecode/world/TestMapBuilder.java | 2 +- 16 files changed, 110 insertions(+), 135 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 24d0490f..63e6e44a 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -72,6 +72,7 @@ public class GameConstants { /** The maximum level a building can be. */ public static final int MAX_LEVEL = 3; + /** Constants for alchemists converting lead to gold. */ public static final double ALCHEMIST_LONELINESS_A = 20; public static final double ALCHEMIST_LONELINESS_B = 15; public static final double ALCHEMIST_LONELINESS_K = 0.02; @@ -85,5 +86,4 @@ public class GameConstants { /** The maximum number of rounds in a game. **/ public static final int GAME_MAX_NUMBER_OF_ROUNDS = 2000; - } diff --git a/engine/src/main/battlecode/doc/RobotTypeTaglet.java b/engine/src/main/battlecode/doc/RobotTypeTaglet.java index 17ee8ed1..00dd0cd6 100644 --- a/engine/src/main/battlecode/doc/RobotTypeTaglet.java +++ b/engine/src/main/battlecode/doc/RobotTypeTaglet.java @@ -52,7 +52,7 @@ public boolean isInlineTag() { return false; } - public String toString(Tag tag){ + public String toString(Tag tag) { throw new IllegalArgumentException("The robot tag may not be used inline."); } diff --git a/engine/src/main/battlecode/instrumenter/bytecode/InstrumentingMethodVisitor.java b/engine/src/main/battlecode/instrumenter/bytecode/InstrumentingMethodVisitor.java index 5f350673..5ab0e4ae 100644 --- a/engine/src/main/battlecode/instrumenter/bytecode/InstrumentingMethodVisitor.java +++ b/engine/src/main/battlecode/instrumenter/bytecode/InstrumentingMethodVisitor.java @@ -280,8 +280,8 @@ private void addDebugHandler() { private void addRobotDeathHandler() { LabelNode robotDeathLabel = new LabelNode(new Label()); LabelNode firstTryCatch = null; - for(AbstractInsnNode node : instructions.toArray()) { - if(node.getType()==AbstractInsnNode.LABEL&&tryCatchStarts.contains(node)) { + for (AbstractInsnNode node : instructions.toArray()) { + if (node.getType()==AbstractInsnNode.LABEL&&tryCatchStarts.contains(node)) { firstTryCatch = (LabelNode)node; break; } @@ -436,7 +436,7 @@ private void visitMethodInsnNode(MethodInsnNode n) { } if (n.owner.equals("java/lang/String")) { - if((n.name.equals("")&&n.desc.equals("([B)V")) + if ((n.name.equals("")&&n.desc.equals("([B)V")) ||(n.name.equals("")&&n.desc.equals("([BII)V")) ||(n.name.equals("getBytes")&&n.desc.equals("()[B"))) { instructions.insertBefore(n,new LdcInsnNode("UTF-16")); diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index f548f134..bcd12599 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -197,7 +197,7 @@ public byte[] toBytes() { * @param saveFile the file to save to */ public void writeGame(File saveFile) { - if(saveFile == null) { + if (saveFile == null) { throw new RuntimeException("Null file provided to writeGame"); } @@ -236,7 +236,7 @@ public MatchMaker getMatchMaker() { return this.matchMaker; } - public void makeGameHeader(){ + public void makeGameHeader() { changeState(State.GAME_HEADER, State.IN_GAME); @@ -273,7 +273,7 @@ public void makeGameHeader(){ }); } - public int makeBodyTypeMetadata(FlatBufferBuilder builder){ + public int makeBodyTypeMetadata(FlatBufferBuilder builder) { TIntArrayList bodyTypeMetadataOffsets = new TIntArrayList(); // Add robot metadata @@ -294,7 +294,7 @@ public int makeBodyTypeMetadata(FlatBufferBuilder builder){ return GameHeader.createBodyTypeMetadataVector(builder, bodyTypeMetadataOffsets.toArray()); } - private byte robotTypeToBodyType(RobotType type){ + private byte robotTypeToBodyType(RobotType type) { if (type == RobotType.ENLIGHTENMENT_CENTER) return BodyType.ENLIGHTENMENT_CENTER; if (type == RobotType.POLITICIAN) return BodyType.POLITICIAN; if (type == RobotType.SLANDERER) return BodyType.SLANDERER; @@ -302,7 +302,7 @@ private byte robotTypeToBodyType(RobotType type){ return Byte.MIN_VALUE; } - public void makeGameFooter(Team winner){ + public void makeGameFooter(Team winner) { changeState(State.IN_GAME, State.DONE); createEvent((builder) -> EventWrapper.createEventWrapper(builder, Event.GameFooter, diff --git a/engine/src/main/battlecode/server/Server.java b/engine/src/main/battlecode/server/Server.java index 8b8dd891..2e1c6b22 100644 --- a/engine/src/main/battlecode/server/Server.java +++ b/engine/src/main/battlecode/server/Server.java @@ -78,31 +78,31 @@ public Server(Config options, boolean interactive) { // ***** NOTIFICATIONS ********** // ****************************** - public void startNotification(){ + public void startNotification() { state = ServerState.READY; } - public void pauseNotification(){ + public void pauseNotification() { state = ServerState.PAUSED; } - public void resumeNotification(){ - if (state == ServerState.PAUSED){ + public void resumeNotification() { + if (state == ServerState.PAUSED) { state = ServerState.RUNNING; } } - public void runNotification(){ + public void runNotification() { if (state != ServerState.PAUSED) { state = ServerState.RUNNING; } } - public void addGameNotification(GameInfo gameInfo){ + public void addGameNotification(GameInfo gameInfo) { this.gameQueue.add(gameInfo); } - public void terminateNotification(){ + public void terminateNotification() { this.gameQueue.add(POISON); } diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index 357ecb83..521cfed2 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -6,7 +6,7 @@ public class AnomalyScheduleEntry { public final int roundNumber; public final AnomalyType anomalyType; - public AnomalyScheduleEntry(int round, AnomalyType anomaly){ + public AnomalyScheduleEntry(int round, AnomalyType anomaly) { this.roundNumber = round; this.anomalyType = anomaly; } @@ -14,7 +14,7 @@ public AnomalyScheduleEntry(int round, AnomalyType anomaly){ /** * @return a copy of the entry */ - public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType){ + public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType) { return AnomalyScheduleEntry( this.roundNumber, AnomalyType( diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 07c0e578..749ed771 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -119,7 +119,7 @@ public synchronized GameState runRound() { return GameState.RUNNING; } - private void updateDynamicBodies(){ + private void updateDynamicBodies() { objectInfo.eachDynamicBodyByExecOrder((body) -> { if (body instanceof InternalRobot) { return updateRobot((InternalRobot) body); @@ -179,7 +179,7 @@ public Team getWinner() { /** * Defensively copied at the level of LiveMap. */ - public AnomalyScheduleEntry[] getAnomalySchedule(){ + public AnomalyScheduleEntry[] getAnomalySchedule() { return this.gameMap.getAnomalySchedule(); } @@ -271,7 +271,7 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int /** * @return all of the locations on the grid. */ - private MapLocation[] getAllLocations(){ + private MapLocation[] getAllLocations() { return getAllLocationsWithinRadiusSquared(new MapLocation(0, 0), Integer.MAX_VALUE); } @@ -280,7 +280,7 @@ private MapLocation[] getAllLocations(){ * @param location with rubble of interest, if any * @return the cooldown due to rubble. */ - public int getCooldownMultiplier(int cooldown, MapLocation location){ + public int getCooldownMultiplier(int cooldown, MapLocation location) { return (int) ((1 + this.getRubble(location) / 10) * cooldown); } @@ -325,11 +325,11 @@ public boolean setWinnerIfAnnihilated() { /** * @return whether a team has more archons */ - public boolean setWinnerIfMoreArchons(){ + public boolean setWinnerIfMoreArchons() { int archonCountA = objectInfo.getRobotTypeCount(Team.A, RobotType.ARCHON); int archonCountB = objectInfo.getRobotTypeCount(Team.B, RobotType.ARCHON); - if(archonCountA > archonCountB){ + if (archonCountA > archonCountB) { setWinner(Team.A, DominationFactor.MORE_ARCHONS); return true; } else if (archonCountA < archonCountB) { @@ -342,7 +342,7 @@ public boolean setWinnerIfMoreArchons(){ /** * @return whether a team has a greater net Au value */ - public boolean setWinnerIfMoreGoldValue(){ + public boolean setWinnerIfMoreGoldValue() { int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { totalInfluences[robot.getTeam().ordinal()] += robot.getType().getGoldWorth(robot.getLevel()); @@ -360,7 +360,7 @@ public boolean setWinnerIfMoreGoldValue(){ /** * @return whether a team has a greater net Pb value */ - public boolean setWinnerIfMoreLeadValue(){ + public boolean setWinnerIfMoreLeadValue() { int[] totalInfluences = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { totalInfluences[robot.getTeam().ordinal()] += robot.getType().getLeadWorth(robot.getLevel()); @@ -387,15 +387,13 @@ public boolean timeLimitReached() { } public void processEndOfRound() { - // Add lead resources to the map - if(this.currentRound == GameConstants.ADD_RESOURCE_EVERY_ROUNDS) - for(int x = 0; x < gameMap.getWidth(); x++) - for(int y = 0; y < gameMap.getHeight(); y++){ - if(gameMap.getLeadAtLocation(x, y) >= 1) + if (this.currentRound == GameConstants.ADD_RESOURCE_EVERY_ROUNDS) + for (int x = 0; x < gameMap.getWidth(); x++) + for (int y = 0; y < gameMap.getHeight(); y++) + if (gameMap.getLeadAtLocation(x, y) >= 1) gameMap.addLeadAtLocation(x, y, 5); - } - + // Add lead resources to the team teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); @@ -407,13 +405,13 @@ public void processEndOfRound() { // Trigger any anomalies // note: singularity is handled below in the "check for end of match" - if(this.gameMap.viewNextAnomaly().roundNumber == this.currentRound){ + if (this.gameMap.viewNextAnomaly().roundNumber == this.currentRound) { AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; - if(anomaly == AnomalyType.ABYSS) this.causeAbyssGlobal(anomaly); - if(anomaly == AnomalyType.CHARGE) this.causeChargeGlobal(anomaly); - if(anomaly == AnomalyType.FURY) this.causeFuryGlobal(anomaly); + if (anomaly == AnomalyType.ABYSS) this.causeAbyssGlobal(anomaly); + if (anomaly == AnomalyType.CHARGE) this.causeChargeGlobal(anomaly); + if (anomaly == AnomalyType.FURY) this.causeFuryGlobal(anomaly); // TODO: uncomment this whenever causeVortexGlobal is called. - // if(anomaly == AnomalyType.VORTEX) this.causeVortexGlobal(anomaly); + // if (anomaly == AnomalyType.VORTEX) this.causeVortexGlobal(anomaly); } // Check for end of match @@ -489,11 +487,9 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti * @param robot that is causing the anomaly. Must be a Sage. * @return all of the locations that are within range of this sage. */ - private MapLocation[] getSageActionLocations(InternalRobot robot){ - + private MapLocation[] getSageActionLocations(InternalRobot robot) { assert robot.getType() == RobotType.SAGE; MapLocation center = robot.getLocation(); - return getAllLocationsWithinRadiusSquared(center, robot.getType().getActionRadiusSquared(robot.getLevel())); } @@ -503,10 +499,8 @@ private MapLocation[] getSageActionLocations(InternalRobot robot){ * @param reduceFactor associated with anomaly (a decimal percentage) * @param locations that can be affected by the Abyss. */ - private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations){ - - for(int i = 0; i < locations.length; i++){ - + private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations) { + for (int i = 0; i < locations.length; i++) { MapLocation currentLocation = locations[i]; int x = currentLocation.x; int y = currentLocation.y; @@ -527,11 +521,10 @@ private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations){ * @param reduceFactor associated with anomaly (a decimal percentage) * @param locations that can be affected by the Fury (by radius, not by state of robot) */ - public void causeFuryUpdate(float reduceFactor, MapLocation[] locations){ - - for(int i = 0; i < locations.length; i++){ + public void causeFuryUpdate(float reduceFactor, MapLocation[] locations) { + for (int i = 0; i < locations.length; i++) { InternalRobot robot = this.getRobot(locations[i]); - if(robot.getType().isBuilding() && robot.getMode() == RobotMode.TURRET){ + if (robot.getType().isBuilding() && robot.getMode() == RobotMode.TURRET) { robot.addHealth((int) (-1 * robot.getType().getMaxHealth(robot.getLevel()) * reduceFactor)); } } @@ -542,11 +535,9 @@ public void causeFuryUpdate(float reduceFactor, MapLocation[] locations){ * @param robot that is the Sage * @param anomaly that corresponds to Abyss type */ - public void causeAbyssSage(InternalRobot robot, AnomalyType anomaly){ - + public void causeAbyssSage(InternalRobot robot, AnomalyType anomaly) { assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.ABYSS; - // calculate the right effect range this.causeAbyssGridUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); } @@ -555,14 +546,12 @@ public void causeAbyssSage(InternalRobot robot, AnomalyType anomaly){ * Mutates state to perform the global Abyss anomaly. * @param anomaly that corresponds to Abyss type */ - public void causeAbyssGlobal(AnomalyType anomaly){ - + public void causeAbyssGlobal(AnomalyType anomaly) { assert anomaly == AnomalyType.ABYSS; this.causeAbyssGridUpdate(anomaly.globalPercentage, this.getAllLocations()); - // change team resources - teamInfo.changeLead( (int) ( -1 * anomaly.globalPercentage * teamInfo.getLead()) ); - teamInfo.changeGold( (int) ( -1 * anomaly.globalPercentage * teamInfo.getGold()) ); + teamInfo.changeLead((int) (-1 * anomaly.globalPercentage * teamInfo.getLead())); + teamInfo.changeGold((int) (-1 * anomaly.globalPercentage * teamInfo.getGold())); } /** @@ -570,11 +559,9 @@ public void causeAbyssGlobal(AnomalyType anomaly){ * @param robot performing the Fury, must be a Sage * @param anomaly that corresponds to Fury type */ - public void causeFurySage(InternalRobot robot, AnomalyType anomaly){ - + public void causeFurySage(InternalRobot robot, AnomalyType anomaly) { assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.FURY; - this.causeFuryUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); } @@ -582,7 +569,7 @@ public void causeFurySage(InternalRobot robot, AnomalyType anomaly){ * Mutates state to peform the global Fury. * @param anomaly that corresponds to Fury type */ - public void causeFuryGlobal(AnomalyType anomaly){ + public void causeFuryGlobal(AnomalyType anomaly) { assert anomaly == AnomalyType.FURY; this.causeFuryUpdate(anomaly.globalPercentage, this.getAllLocations()); } @@ -592,12 +579,12 @@ public void causeFuryGlobal(AnomalyType anomaly){ * @param robot performing the Charge, must be a Sage * @param anomaly that corresponds to Charge type */ - public void causeChargeSage(InternalRobot robot, AnomalyType anomaly){ + public void causeChargeSage(InternalRobot robot, AnomalyType anomaly) { assert robot.getType() == RobotType.SAGE; assert anomaly == AnomalyType.CHARGE; MapLocation[] actionLocations = this.getSageActionLocations(robot); - for(int i = 0; i < actionLocations.length; i++){ + for (int i = 0; i < actionLocations.length; i++) { InternalRobot currentRobot = getRobot(actionLocations[i]); currentRobot.addHealth((int) (-1 * anomaly.sagePercentage * currentRobot.getType().getMaxHealth(currentRobot.getLevel()))); } @@ -607,18 +594,15 @@ public void causeChargeSage(InternalRobot robot, AnomalyType anomaly){ * Mutates state to peform the global Charge. * @param anomaly that corresponds to Charge type */ - public void causeChargeGlobal(AnomalyType anomaly){ - + public void causeChargeGlobal(AnomalyType anomaly) { assert anomaly == AnomalyType.CHARGE; ArrayList rawDroids = new ArrayList(); - - for(InternalRobot currentRobot : this.objectInfo.robotsArray()) - if(!currentRobot.getType().isBuilding()) + for (InternalRobot currentRobot : this.objectInfo.robotsArray()) + if (!currentRobot.getType().isBuilding()) rawDroids.add(currentRobot); - - InternalRobot[] droids = rawDroids.toArray(new InternalRobot[rawDroids.size()]); + InternalRobot[] droids = rawDroids.toArray(new InternalRobot[rawDroids.size()]); Arrays.sort( droids, (InternalRobot robot1, InternalRobot robot2) -> @@ -628,12 +612,8 @@ public void causeChargeGlobal(AnomalyType anomaly){ ); int affectedDroidsLimit = (int) (anomaly.globalPercentage * droids.length); - for(int i = 0; i < affectedDroidsLimit; i++){ + for (int i = 0; i < affectedDroidsLimit; i++) { this.destroyRobot(droids[i].getID()); } - } - } - - diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index ec3fca25..1d326903 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -187,7 +187,7 @@ public int getActionRadiusSquared() { * * @param toSense the MapLocation to act */ - public boolean canActLocation(MapLocation toSense){ + public boolean canActLocation(MapLocation toSense) { return this.location.distanceSquaredTo(toSense) <= getActionRadiusSquared(); } @@ -389,7 +389,7 @@ public void die_exception() { /** * @return the number of friendly robots within sensor (vision) radius. */ - public int numberOfVisibleFriendlyRobots(){ + public int numberOfVisibleFriendlyRobots() { return this.controller.numberOfVisibleFriendlyRobots(); } diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index e6866392..b3a1dbc8 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -224,7 +224,7 @@ public boolean onTheMap(MapLocation loc) { * @return true if the given circle is on the map, * false if it's not */ - public boolean onTheMap(MapLocation loc, int radius){ + public boolean onTheMap(MapLocation loc, int radius) { return (onTheMap(loc.translate(-radius, 0)) && onTheMap(loc.translate(radius, 0)) && onTheMap(loc.translate(0, -radius)) && @@ -275,7 +275,7 @@ public int[] getRubbleArray() { * @param y to get lead at * @return the amount of lead at this location */ - public int getLeadAtLocation(int x, int y){ + public int getLeadAtLocation(int x, int y) { assert onTheMap(new MapLocation(x, y)); return this.leadMap[x][y]; } @@ -286,7 +286,7 @@ public int getLeadAtLocation(int x, int y){ * @param y to set lead at * @param amount of lead to put at this location */ - public void setLeadAtLocation(int x, int y, int amount){ + public void setLeadAtLocation(int x, int y, int amount) { assert onTheMap(new MapLocation(x, y)); this.leadMap[x][y] = amount; } @@ -297,7 +297,7 @@ public void setLeadAtLocation(int x, int y, int amount){ * @param y to set lead at * @param amountToAdd */ - public void addLeadAtLocation(int x, int y, int amountToAdd){ + public void addLeadAtLocation(int x, int y, int amountToAdd) { assert onTheMap(new MapLocation(x, y)); this.leadMap[x][y] += amountToAdd; } @@ -305,7 +305,7 @@ public void addLeadAtLocation(int x, int y, int amountToAdd){ /** * @return a copy of the next Anomaly that hasn't happened yet. */ - public AnomalyScheduleEntry viewNextAnomaly(){ + public AnomalyScheduleEntry viewNextAnomaly() { return this.anomalySchedule[this.nextAnomalyIndex].copyEntry(); } @@ -313,27 +313,23 @@ public AnomalyScheduleEntry viewNextAnomaly(){ * Removes the current anomaly by advancing to the next one. * @return the next Anomaly. */ - public AnomalyScheduleEntry takeNextAnomaly(){ + public AnomalyScheduleEntry takeNextAnomaly() { return this.anomalySchedule[this.nextAnomalyIndex++].copyEntry(); } /** * @return a copy of the anomaly schedule */ - public AnomalyScheduleEntry[] getAnomalySchedule(){ - + public AnomalyScheduleEntry[] getAnomalySchedule() { AnomalyScheduleEntry[] anomalyCopy = new AnomalyScheduleEntry[this.anomalySchedule.length]; - - for(int i = 0; i < this.anomalySchedule.length ; i++) + for (int i = 0; i < this.anomalySchedule.length ; i++) anomalyCopy[i] = this.anomalySchedule[i].copyEntry(); - return anomalyCopy; } - @Override public String toString() { - if (rubbleArray.length == 0){ + if (rubbleArray.length == 0) { return "LiveMap{" + "width=" + width + ", height=" + height + @@ -345,7 +341,7 @@ public String toString() { ", len=" + Integer.toString(rubbleArray.length) + "}"; } - else{ + else { return "LiveMap{" + "width=" + width + ", height=" + height + diff --git a/engine/src/main/battlecode/world/ObjectInfo.java b/engine/src/main/battlecode/world/ObjectInfo.java index be652777..5a04b130 100644 --- a/engine/src/main/battlecode/world/ObjectInfo.java +++ b/engine/src/main/battlecode/world/ObjectInfo.java @@ -41,7 +41,7 @@ public strictfp class ObjectInfo { Team.class); private int[] robotCount = new int[3]; - public ObjectInfo(LiveMap gm){ + public ObjectInfo(LiveMap gm) { this.mapWidth = gm.getWidth(); this.mapHeight = gm.getHeight(); this.mapTopLeft = gm.getOrigin(); diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 788086eb..ffe9da5e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -131,7 +131,7 @@ private InternalRobot getRobotByID(int id) { /** * Returns a fully copied version of the anomaly schedule. */ - public AnomalyScheduleEntry[] getAnomalySchedule(){ + public AnomalyScheduleEntry[] getAnomalySchedule() { this.gameWorld.getAnomalySchedule(); } @@ -240,7 +240,7 @@ public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team t /** * @return the number of friendly robots within sensor (vision) radius. */ - public int numberOfVisibleFriendlyRobots(){ + public int numberOfVisibleFriendlyRobots() { return this.seeNearbyRobots( this.robot.getVisionRadiusSquared(), this.robot.getTeam() @@ -475,7 +475,7 @@ private void assertCanAttack(MapLocation loc) throws GameActionException { } @Override - public boolean canAttack(MapLocation loc){ + public boolean canAttack(MapLocation loc) { try { assertCanAttack(loc); return true; @@ -483,7 +483,7 @@ public boolean canAttack(MapLocation loc){ } @Override - public void attack(MapLocation loc) throws GameActionException{ + public void attack(MapLocation loc) throws GameActionException { assertCanAttack(loc); this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); InternalRobot bot = gameWorld.getRobot(loc); @@ -502,14 +502,14 @@ private void assertCanUseAnomaly(AnomalyType anomaly) throws GameActionException throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot use anomaly."); } - if (!anomaly.isSageAnomaly){ + if (!anomaly.isSageAnomaly) { throw new GameActionException(CANT_DO_THAT, "Sage can not use anomaly of type " + anomaly.toString()); } } @Override - public boolean canUseAnomaly(AnomalyType anomaly){ + public boolean canUseAnomaly(AnomalyType anomaly) { try { assertCanUseAnomaly(anomaly); return true; @@ -517,7 +517,7 @@ public boolean canUseAnomaly(AnomalyType anomaly){ } @Override - public void useAnomaly(AnomalyType anomaly) throws GameActionException{ + public void useAnomaly(AnomalyType anomaly) throws GameActionException { assertCanUseAnomaly(anomaly); switch (anomaly) { case ABYSS: @@ -543,23 +543,23 @@ private void assertCanHealDroid(MapLocation loc) throws GameActionException { if (!getType().canHealDroid()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot heal droids."); - }else if (!this.robot.canActLocation(loc)){ + } else if (!this.robot.canActLocation(loc)) { throw new GameActionException(OUT_OF_RANGE, "This robot can't be healed because location is out of range."); } InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeHealed())){ + if (!(bot.getType().canBeHealed())) { throw new GameActionException(CANT_DO_THAT, "Robot is not of a type that can be healed."); } - if (bot.getTeam() != getTeam()){ + if (bot.getTeam() != getTeam()) { throw new GameActionException(CANT_DO_THAT, "Robot is not on your team so can't be healed."); } } @Override - public boolean canHealDroid(MapLocation loc){ + public boolean canHealDroid(MapLocation loc) { try { assertCanHealDroid(loc); return true; @@ -567,7 +567,7 @@ public boolean canHealDroid(MapLocation loc){ } @Override - public void healDroid(MapLocation loc) throws GameActionException{ + public void healDroid(MapLocation loc) throws GameActionException { assertCanHealDroid(loc); this.robot.addActionCooldownTurns(GameConstants.HEAL_COOLDOWN); InternalRobot bot = gameWorld.getRobot(loc); @@ -586,19 +586,19 @@ private void assertCanMineLead(MapLocation loc) throws GameActionException { if (!getType().canMine()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot mine."); - }else if (!this.robot.canActLocation(loc)){ + } else if (!this.robot.canActLocation(loc)) { throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); } int leadAmount = gameWorld.getLeadCount(loc); - if (leadAmount < 0){ + if (leadAmount < 0) { throw new GameActionException(CANT_DO_THAT, "Lead amount must be positive to be mined."); } } @Override - public boolean canMineLead(MapLocation loc){ + public boolean canMineLead(MapLocation loc) { try { assertCanMineLead(loc); return true; @@ -606,7 +606,7 @@ public boolean canMineLead(MapLocation loc){ } @Override - public void mineLead(MapLocation loc) throws GameActionException{ + public void mineLead(MapLocation loc) throws GameActionException { assertCanMineLead(loc); this.robot.mineLead(loc); Team robotTeam = this.robot.getTeam(); @@ -621,19 +621,19 @@ private void assertCanMineGold(MapLocation loc) throws GameActionException { if (!getType().canMine()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot mine."); - }else if (!this.robot.canActLocation(loc)){ + } else if (!this.robot.canActLocation(loc)) { throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); } int goldAmount = gameWorld.getGoldCount(loc); - if (goldAmount < 0){ + if (goldAmount < 0) { throw new GameActionException(CANT_DO_THAT, "Gold amount must be positive to be mined."); } } @Override - public boolean canMineGold(MapLocation loc){ + public boolean canMineGold(MapLocation loc) { try { assertCanMineGold(loc); return true; @@ -641,7 +641,7 @@ public boolean canMineGold(MapLocation loc){ } @Override - public void mineGold(MapLocation loc) throws GameActionException{ + public void mineGold(MapLocation loc) throws GameActionException { assertCanMineGold(loc); this.robot.mineGold(loc); Team robotTeam = this.robot.getTeam(); @@ -661,31 +661,31 @@ private void assertCanUpgrade(MapLocation loc) throws GameActionException { if (!getType().canUpgrade()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot upgrade buildings."); - }else if (!this.robot.canActLocation(loc)){ + } else if (!this.robot.canActLocation(loc)) { throw new GameActionException(OUT_OF_RANGE, "Robot can't be upgraded because it is out of range."); } InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeUpgraded())){ + if (!(bot.getType().canBeUpgraded())) { throw new GameActionException(CANT_DO_THAT, "Robot is not of a type that can be upgraded."); } - if (bot.getTeam() != getTeam()){ + if (bot.getTeam() != getTeam()) { throw new GameActionException(CANT_DO_THAT, "Robot is not on your team so can't be upgraded."); } - if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadUpgradeCost()){ + if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadUpgradeCost()) { throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough lead to upgrade this robot."); } - if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldUpgradeCost()){ + if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldUpgradeCost()) { throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough gold to upgrade this robot."); } } @Override - public boolean canUpgrade(MapLocation loc){ + public boolean canUpgrade(MapLocation loc) { try { assertCanUpgrade(loc); return true; @@ -693,7 +693,7 @@ public boolean canUpgrade(MapLocation loc){ } @Override - public void upgrade(MapLocation loc) throws GameActionException{ + public void upgrade(MapLocation loc) throws GameActionException { assertCanUpgrade(loc); InternalRobot bot = gameWorld.getRobot(loc); RobotType type = bot.getType(); @@ -718,23 +718,23 @@ private void assertCanRepairBuilding(MapLocation loc) throws GameActionException if (!getType().canRepairBuilding()) { throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot repair buildings."); - }else if (!this.robot.canActLocation(loc)){ + } else if (!this.robot.canActLocation(loc)) { throw new GameActionException(OUT_OF_RANGE, "Robot can't be repaired because it is out of range."); } InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeUpgraded())){ + if (!(bot.getType().canBeUpgraded())) { throw new GameActionException(CANT_DO_THAT, "Robot is not of a type that can be repair."); } - if (bot.getTeam() != getTeam()){ + if (bot.getTeam() != getTeam()) { throw new GameActionException(CANT_DO_THAT, "Robot is not on your team so can't be repaired."); } } @Override - public boolean canRepairBuilding(MapLocation loc){ + public boolean canRepairBuilding(MapLocation loc) { try { assertCanRepairBuilding(loc); return true; @@ -742,7 +742,7 @@ public boolean canRepairBuilding(MapLocation loc){ } @Override - public void repairBuilding(MapLocation loc) throws GameActionException{ + public void repairBuilding(MapLocation loc) throws GameActionException { assertCanRepairBuilding(loc); InternalRobot bot = gameWorld.getRobot(loc); @@ -778,7 +778,6 @@ public boolean canConvert() { } catch (GameActionException e) { return false; } } - // TODO: Implement convert in InternalRobot @Override public int getGoldExchangeRate() { return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * diff --git a/engine/src/main/battlecode/world/TestMapBuilder.java b/engine/src/main/battlecode/world/TestMapBuilder.java index c0d4ddf0..2023612e 100644 --- a/engine/src/main/battlecode/world/TestMapBuilder.java +++ b/engine/src/main/battlecode/world/TestMapBuilder.java @@ -46,7 +46,7 @@ public TestMapBuilder addEnlightenmentCenter(int id, Team team, int influence, M public TestMapBuilder setRubble() { this.rubbleArray = new int[width * height]; - for(int i = 0; i < width; i++) { + for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { this.rubbleArray[i + j * width] = (i * j + i + j) / (i * j + 1); } diff --git a/engine/src/main/battlecode/world/maps/Circle.java b/engine/src/main/battlecode/world/maps/Circle.java index 272f51eb..a0abf931 100644 --- a/engine/src/main/battlecode/world/maps/Circle.java +++ b/engine/src/main/battlecode/world/maps/Circle.java @@ -46,7 +46,7 @@ public static void makeCircle() throws IOException { mapBuilder.addSymmetricNeutralEnlightenmentCenter(0, 0, 300); mapBuilder.addSymmetricNeutralEnlightenmentCenter(0, 2*half, 300); - for(int i = 0; i <= half; i++) { + for (int i = 0; i <= half; i++) { for (int j = 0; j <= 2*half; j++) { int d = new MapLocation(i, j).distanceSquaredTo(center); mapBuilder.setSymmetricPassability(i, j, diff --git a/engine/src/main/battlecode/world/maps/MapTestSmall.java b/engine/src/main/battlecode/world/maps/MapTestSmall.java index 51aaf5c3..4cf150bb 100644 --- a/engine/src/main/battlecode/world/maps/MapTestSmall.java +++ b/engine/src/main/battlecode/world/maps/MapTestSmall.java @@ -42,7 +42,7 @@ public static void makeSimple() throws IOException { mapBuilder.addSymmetricEnlightenmentCenter(5, 5); Random random = new Random(6147); - for(int i = 0; i < mapBuilder.width / 2; i++) { + for (int i = 0; i < mapBuilder.width / 2; i++) { for (int j = 0; j < mapBuilder.height; j++) { mapBuilder.setSymmetricPassability(i, j, random.nextDouble()*0.9+0.1); } diff --git a/engine/src/test/battlecode/world/RobotControllerTest.java b/engine/src/test/battlecode/world/RobotControllerTest.java index 4d5a9510..b70dac0d 100644 --- a/engine/src/test/battlecode/world/RobotControllerTest.java +++ b/engine/src/test/battlecode/world/RobotControllerTest.java @@ -192,7 +192,7 @@ public class RobotControllerTest { // final int soldierB = game.spawn(7, 5, RobotType.MINER, Team.B); // game.round((id, rc) -> { - // if(id != soldierA) return; + // if (id != soldierA) return; // RobotInfo actualBot = rc.senseRobotAtLocation(new MapLocation(3,5)); // RobotInfo nullBot = rc.senseRobotAtLocation(new MapLocation(5,7)); @@ -215,7 +215,7 @@ public class RobotControllerTest { // int[] testIDs = new int[TEST_UNITS]; - // for(int i=0; i { - // if(rc.getType() == RobotType.SOLDIER) { + // if (rc.getType() == RobotType.SOLDIER) { // executionOrder.add(id); // } else if (id == archonA) { // assertTrue(rc.canHireGardener(Direction.EAST)); @@ -239,7 +239,7 @@ public class RobotControllerTest { // // Assert IDs aren't in order (random change, but very unlikely unless something is wrong) // boolean sorted = true; - // for(int i=0; i Date: Tue, 21 Dec 2021 17:02:07 -0600 Subject: [PATCH 125/413] added upgrade cooldown back to gameconstants --- engine/src/main/battlecode/common/GameConstants.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 63e6e44a..aeb3fec4 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -56,6 +56,9 @@ public class GameConstants { /** The number of cooldown turns per transformation. */ public static final int TRANSFORM_COOLDOWN = 100; + /** The number of cooldown turns per upgrade. */ + public static final int UPGRADE_COOLDOWN = 100; + // ********************************* // ****** GAME MECHANICS *********** // ********************************* From 470de4d6c7ee67b8b2c608741184e3299e970908 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Tue, 21 Dec 2021 17:02:37 -0600 Subject: [PATCH 126/413] delete extra lines --- engine/src/main/battlecode/common/AnomalyType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/engine/src/main/battlecode/common/AnomalyType.java b/engine/src/main/battlecode/common/AnomalyType.java index 118365a6..6c027a0e 100644 --- a/engine/src/main/battlecode/common/AnomalyType.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -4,25 +4,21 @@ * Holds the different anomalies in the game. */ public enum AnomalyType { - ABYSS (true, true, 0.1, 0.2), CHARGE (true, true, 0.05, 0.1), FURY (true, true, 0.05, 0.1), VORTEX (true, false, 0, 0), SINGULARITY (true, false, 0, 0); - public final boolean isGlobalAnomaly; public final boolean isSageAnomaly; public final float globalPercentage; public final float sagePercentage; - AnomalyType(boolean isGlobalAnomaly, boolean isSageAnomaly, float globalPercentage, float sagePercentage) { this.isGlobalAnomaly = isGlobalAnomaly; this.isSageAnomaly = isSageAnomaly; this.globalPercentage = globalPercentage; this.sagePercentage = sagePercentage; - } } \ No newline at end of file From 2bd9ab97790f3d6106e7a1c01ba9ad87214485f7 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Tue, 21 Dec 2021 17:07:18 -0600 Subject: [PATCH 127/413] getCooldownMultiplier --> getCooldownWithMultiplier --- engine/src/main/battlecode/world/GameWorld.java | 2 +- engine/src/main/battlecode/world/InternalRobot.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 749ed771..0014f0c7 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -280,7 +280,7 @@ private MapLocation[] getAllLocations() { * @param location with rubble of interest, if any * @return the cooldown due to rubble. */ - public int getCooldownMultiplier(int cooldown, MapLocation location) { + public int getCooldownWithMultiplier(int cooldown, MapLocation location) { return (int) ((1 + this.getRubble(location) / 10) * cooldown); } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 1d326903..6ae7af42 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -218,7 +218,7 @@ public void setLocation(MapLocation loc) { * Resets the action cooldown. */ public void addActionCooldownTurns(int numActionCooldownToAdd) { - int newActionCooldownTurns = this.gameWorld.getCooldownMultiplier(numActionCooldownToAdd, this.location); + int newActionCooldownTurns = this.gameWorld.getCooldownWithMultiplier(numActionCooldownToAdd, this.location); setActionCooldownTurns(this.actionCooldownTurns + newActionCooldownTurns); } @@ -226,8 +226,8 @@ public void addActionCooldownTurns(int numActionCooldownToAdd) { * Resets the movement cooldown. */ public void addMovementCooldownTurns(int numMovementCooldownToAdd) { - int cooldownMultiplier = this.gameWorld.getCooldownMultiplier(this.location); - int newMovementCooldownTurns = this.gameWorld.getCooldownMultiplier(numMovementCooldownToAdd, this.location); + int cooldownMultiplier = this.gameWorld.getCooldownWithMultiplier(this.location); + int newMovementCooldownTurns = this.gameWorld.getCooldownWithMultiplier(numMovementCooldownToAdd, this.location); setMovementCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); } From 2a355831ec237ee60f3c8b1d54f25929012e0442 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Tue, 21 Dec 2021 17:12:08 -0600 Subject: [PATCH 128/413] clean up AnomalyScheduleEntry --- .../main/battlecode/world/AnomalyScheduleEntry.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index 521cfed2..f8e05502 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -15,15 +15,6 @@ public AnomalyScheduleEntry(int round, AnomalyType anomaly) { * @return a copy of the entry */ public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType) { - return AnomalyScheduleEntry( - this.roundNumber, - AnomalyType( - anomalyType.isGlobalAnomaly, - anomalyType.isSageAnomaly, - anomalyType.globalPercentage, - anomalyType.sagePercentage - ) - ); + return new AnomalyScheduleEntry(this.roundNumber, this.anomalyType); } - } \ No newline at end of file From b3fedd2e9e2b6e1665bf113da2506ddb73c0ad74 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Tue, 21 Dec 2021 18:53:23 -0600 Subject: [PATCH 129/413] internalrobot --- engine/src/main/battlecode/world/GameWorld.java | 4 ++-- engine/src/main/battlecode/world/InternalRobot.java | 5 ++--- .../src/main/battlecode/world/RobotControllerImpl.java | 10 ++++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 0014f0c7..2ced4c60 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -281,7 +281,7 @@ private MapLocation[] getAllLocations() { * @return the cooldown due to rubble. */ public int getCooldownWithMultiplier(int cooldown, MapLocation location) { - return (int) ((1 + this.getRubble(location) / 10) * cooldown); + return (int) ((1 + getRubble(location) / 10.0) * cooldown); } // ********************************* @@ -607,7 +607,7 @@ public void causeChargeGlobal(AnomalyType anomaly) { droids, (InternalRobot robot1, InternalRobot robot2) -> // 12/10/21: https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/ - (robot2.numberOfVisibleFriendlyRobots() - robot1.numberOfVisibleFriendlyRobots()) + (robot2.getNumVisibleFriendlyRobots() - robot1.getNumVisibleFriendlyRobots()) // end reference on how to compare things with subtraction ); diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 6ae7af42..8a4842ac 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -226,7 +226,6 @@ public void addActionCooldownTurns(int numActionCooldownToAdd) { * Resets the movement cooldown. */ public void addMovementCooldownTurns(int numMovementCooldownToAdd) { - int cooldownMultiplier = this.gameWorld.getCooldownWithMultiplier(this.location); int newMovementCooldownTurns = this.gameWorld.getCooldownWithMultiplier(numMovementCooldownToAdd, this.location); setMovementCooldownTurns(this.movementCooldownTurns + newMovementCooldownTurns); } @@ -389,8 +388,8 @@ public void die_exception() { /** * @return the number of friendly robots within sensor (vision) radius. */ - public int numberOfVisibleFriendlyRobots() { - return this.controller.numberOfVisibleFriendlyRobots(); + public int getNumVisibleFriendlyRobots() { + return this.controller.getNumVisibleFriendlyRobots(); } @Override diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index ffe9da5e..7f079bb5 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -240,7 +240,7 @@ public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team t /** * @return the number of friendly robots within sensor (vision) radius. */ - public int numberOfVisibleFriendlyRobots() { + public int getNumVisibleFriendlyRobots() { return this.seeNearbyRobots( this.robot.getVisionRadiusSquared(), this.robot.getTeam() @@ -804,7 +804,7 @@ public void convert() throws GameActionException { private void assertCanTransform() throws GameActionException { assertIsActionReady(); assertIsMovementReady(); - if (!robot.getMode() == RobotMode.TURRET || !robot.getMode() == RobotMode.PORTABLE) { + if (robot.getMode() != RobotMode.TURRET && robot.getMode() != RobotMode.PORTABLE) { throw new GameActionException(CANT_DO_THAT, "Robot is not transformable."); } @@ -823,8 +823,10 @@ public void transform() throws GameActionException { assertCanTransform(); robot.transform(); RobotMode mode = robot.getMode(); - addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); - addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + if (mode == RobotMode.TURRET) + addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + else + addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); } // *********************************** From d9b6f96f19a84e60c8a2408546da7c8f17024201 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 01:08:28 -0600 Subject: [PATCH 130/413] gameworld --- .../main/battlecode/common/GameConstants.java | 5 +- .../src/main/battlecode/world/GameWorld.java | 185 +++++++++--------- .../main/battlecode/world/InternalRobot.java | 6 +- 3 files changed, 96 insertions(+), 100 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index aeb3fec4..2255e6b0 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -41,7 +41,10 @@ public class GameConstants { public static final int PASSIVE_LEAD_INCREASE = 5; /** The number of rounds between adding lead resources to the map. */ - public static final int ADD_RESOURCE_EVERY_ROUNDS = 20; + public static final int ADD_LEAD_EVERY_ROUNDS = 20; + + /** The amount of lead to add each round that lead is added. */ + public static final int ADD_LEAD = 5; // ********************************* // ****** COOLDOWNS **************** diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 2ced4c60..131050fc 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -70,7 +70,6 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match RobotInfo robot = initialBodies[i]; MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y); int newID = spawnRobot(robot.type, newLocation, robot.team); - initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, 1, robot.health, newLocation); } @@ -81,7 +80,7 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match /** * Run a single round of the game. * - * @return the state of the game after the round has run. + * @return the state of the game after the round has run */ public synchronized GameState runRound() { if (!this.isRunning()) { @@ -269,16 +268,16 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int } /** - * @return all of the locations on the grid. + * @return all of the locations on the grid */ private MapLocation[] getAllLocations() { return getAllLocationsWithinRadiusSquared(new MapLocation(0, 0), Integer.MAX_VALUE); } /** - * @param cooldown without multiplier applied. + * @param cooldown without multiplier applied * @param location with rubble of interest, if any - * @return the cooldown due to rubble. + * @return the cooldown due to rubble */ public int getCooldownWithMultiplier(int cooldown, MapLocation location) { return (int) ((1 + getRubble(location) / 10.0) * cooldown); @@ -343,14 +342,14 @@ public boolean setWinnerIfMoreArchons() { * @return whether a team has a greater net Au value */ public boolean setWinnerIfMoreGoldValue() { - int[] totalInfluences = new int[2]; + int[] totalGoldValues = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - totalInfluences[robot.getTeam().ordinal()] += robot.getType().getGoldWorth(robot.getLevel()); + totalGoldValues[robot.getTeam().ordinal()] += robot.getType().getGoldWorth(robot.getLevel()); } - if (totalInfluences[0] > totalInfluences[1]) { + if (totalGoldValues[0] > totalGoldValues[1]) { setWinner(Team.A, DominationFactor.MORE_GOLD_NET_WORTH); return true; - } else if (totalInfluences[1] > totalInfluences[0]) { + } else if (totalGoldValues[1] > totalGoldValues[0]) { setWinner(Team.B, DominationFactor.MORE_GOLD_NET_WORTH); return true; } @@ -361,14 +360,14 @@ public boolean setWinnerIfMoreGoldValue() { * @return whether a team has a greater net Pb value */ public boolean setWinnerIfMoreLeadValue() { - int[] totalInfluences = new int[2]; + int[] totalLeadValues = new int[2]; for (InternalRobot robot : objectInfo.robotsArray()) { - totalInfluences[robot.getTeam().ordinal()] += robot.getType().getLeadWorth(robot.getLevel()); + totalLeadValues[robot.getTeam().ordinal()] += robot.getType().getLeadWorth(robot.getLevel()); } - if (totalInfluences[0] > totalInfluences[1]) { + if (totalLeadValues[0] > totalLeadValues[1]) { setWinner(Team.A, DominationFactor.MORE_LEAD_NET_WORTH); return true; - } else if (totalInfluences[1] > totalInfluences[0]) { + } else if (totalLeadValues[1] > totalLeadValues[0]) { setWinner(Team.B, DominationFactor.MORE_LEAD_NET_WORTH); return true; } @@ -388,11 +387,11 @@ public boolean timeLimitReached() { public void processEndOfRound() { // Add lead resources to the map - if (this.currentRound == GameConstants.ADD_RESOURCE_EVERY_ROUNDS) + if ((this.currentRound + 1) % GameConstants.ADD_LEAD_EVERY_ROUNDS == 0) // +1 so we don't add lead the first round for (int x = 0; x < gameMap.getWidth(); x++) for (int y = 0; y < gameMap.getHeight(); y++) - if (gameMap.getLeadAtLocation(x, y) >= 1) - gameMap.addLeadAtLocation(x, y, 5); + if (gameMap.getLeadAtLocation(x, y) > 0) + gameMap.addLeadAtLocation(x, y, GameConstants.ADD_LEAD); // Add lead resources to the team teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); @@ -407,11 +406,10 @@ public void processEndOfRound() { // note: singularity is handled below in the "check for end of match" if (this.gameMap.viewNextAnomaly().roundNumber == this.currentRound) { AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; - if (anomaly == AnomalyType.ABYSS) this.causeAbyssGlobal(anomaly); - if (anomaly == AnomalyType.CHARGE) this.causeChargeGlobal(anomaly); - if (anomaly == AnomalyType.FURY) this.causeFuryGlobal(anomaly); - // TODO: uncomment this whenever causeVortexGlobal is called. - // if (anomaly == AnomalyType.VORTEX) this.causeVortexGlobal(anomaly); + if (anomaly == AnomalyType.ABYSS) causeAbyssGlobal(anomaly); + if (anomaly == AnomalyType.CHARGE) causeChargeGlobal(anomaly); + if (anomaly == AnomalyType.FURY) causeFuryGlobal(anomaly); + if (anomaly == AnomalyType.VORTEX) causeVortexGlobal(anomaly); } // Check for end of match @@ -450,7 +448,6 @@ public int spawnRobot(RobotType type, MapLocation location, Team team) { // ********************************* public void destroyRobot(int id) { - InternalRobot robot = objectInfo.getRobotByID(id); removeRobot(robot.getLocation()); @@ -474,7 +471,6 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti if (profilerCollections == null) { profilerCollections = new HashMap<>(); } - profilerCollections.put(team, profilerCollection); } @@ -484,8 +480,8 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti /** * Finds all of the locations that a given Sage can affect with an Anomaly. - * @param robot that is causing the anomaly. Must be a Sage. - * @return all of the locations that are within range of this sage. + * @param robot that is causing the anomaly; must be a Sage + * @return all of the locations that are within range of this sage */ private MapLocation[] getSageActionLocations(InternalRobot robot) { assert robot.getType() == RobotType.SAGE; @@ -494,10 +490,9 @@ private MapLocation[] getSageActionLocations(InternalRobot robot) { } /** - * Performs the Abyss anomaly. - * Changes the resources in the squares and the team. + * Performs the Abyss anomaly. Changes the resources in the squares and the team. * @param reduceFactor associated with anomaly (a decimal percentage) - * @param locations that can be affected by the Abyss. + * @param locations that can be affected by the Abyss */ private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations) { for (int i = 0; i < locations.length; i++) { @@ -515,105 +510,101 @@ private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations) { } } - /** - * Performs the Fury anomaly. - * Changes the health of the relevant robots. - * @param reduceFactor associated with anomaly (a decimal percentage) - * @param locations that can be affected by the Fury (by radius, not by state of robot) - */ - public void causeFuryUpdate(float reduceFactor, MapLocation[] locations) { - for (int i = 0; i < locations.length; i++) { - InternalRobot robot = this.getRobot(locations[i]); - if (robot.getType().isBuilding() && robot.getMode() == RobotMode.TURRET) { - robot.addHealth((int) (-1 * robot.getType().getMaxHealth(robot.getLevel()) * reduceFactor)); - } - } - } - /** * Mutates state to perform the Sage Abyss anomaly. * @param robot that is the Sage - * @param anomaly that corresponds to Abyss type */ - public void causeAbyssSage(InternalRobot robot, AnomalyType anomaly) { + public void causeAbyssSage(InternalRobot robot) { assert robot.getType() == RobotType.SAGE; - assert anomaly == AnomalyType.ABYSS; // calculate the right effect range - this.causeAbyssGridUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); + this.causeAbyssGridUpdate(AnomalyType.ABYSS.sagePercentage, this.getSageActionLocations(robot)); } /** * Mutates state to perform the global Abyss anomaly. - * @param anomaly that corresponds to Abyss type */ - public void causeAbyssGlobal(AnomalyType anomaly) { - assert anomaly == AnomalyType.ABYSS; - this.causeAbyssGridUpdate(anomaly.globalPercentage, this.getAllLocations()); + public void causeAbyssGlobal() { + this.causeAbyssGridUpdate(AnomalyType.ABYSS.globalPercentage, this.getAllLocations()); // change team resources - teamInfo.changeLead((int) (-1 * anomaly.globalPercentage * teamInfo.getLead())); - teamInfo.changeGold((int) (-1 * anomaly.globalPercentage * teamInfo.getGold())); - } - - /** - * Mutates state to perform the Sage Fury. - * @param robot performing the Fury, must be a Sage - * @param anomaly that corresponds to Fury type - */ - public void causeFurySage(InternalRobot robot, AnomalyType anomaly) { - assert robot.getType() == RobotType.SAGE; - assert anomaly == AnomalyType.FURY; - this.causeFuryUpdate(anomaly.sagePercentage, this.getSageActionLocations(robot)); - } - - /** - * Mutates state to peform the global Fury. - * @param anomaly that corresponds to Fury type - */ - public void causeFuryGlobal(AnomalyType anomaly) { - assert anomaly == AnomalyType.FURY; - this.causeFuryUpdate(anomaly.globalPercentage, this.getAllLocations()); + teamInfo.changeLead((int) (-1 * AnomalyType.ABYSS.globalPercentage * teamInfo.getLead())); + teamInfo.changeGold((int) (-1 * AnomalyType.ABYSS.globalPercentage * teamInfo.getGold())); } /** * Mutates state to perform the Sage Charge. * @param robot performing the Charge, must be a Sage - * @param anomaly that corresponds to Charge type */ - public void causeChargeSage(InternalRobot robot, AnomalyType anomaly) { + public void causeChargeSage(InternalRobot robot) { assert robot.getType() == RobotType.SAGE; - assert anomaly == AnomalyType.CHARGE; MapLocation[] actionLocations = this.getSageActionLocations(robot); for (int i = 0; i < actionLocations.length; i++) { InternalRobot currentRobot = getRobot(actionLocations[i]); - currentRobot.addHealth((int) (-1 * anomaly.sagePercentage * currentRobot.getType().getMaxHealth(currentRobot.getLevel()))); + if (currentRobot != null && currentRobot.getTeam() != robot.getTeam()) + currentRobot.addHealth((int) (-1 * AnomalyType.CHARGE.sagePercentage * currentRobot.getType().getMaxHealth(currentRobot.getLevel()))); } } /** * Mutates state to peform the global Charge. - * @param anomaly that corresponds to Charge type */ - public void causeChargeGlobal(AnomalyType anomaly) { - assert anomaly == AnomalyType.CHARGE; - - ArrayList rawDroids = new ArrayList(); - for (InternalRobot currentRobot : this.objectInfo.robotsArray()) - if (!currentRobot.getType().isBuilding()) - rawDroids.add(currentRobot); - - InternalRobot[] droids = rawDroids.toArray(new InternalRobot[rawDroids.size()]); - Arrays.sort( - droids, - (InternalRobot robot1, InternalRobot robot2) -> - // 12/10/21: https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/ - (robot2.getNumVisibleFriendlyRobots() - robot1.getNumVisibleFriendlyRobots()) - // end reference on how to compare things with subtraction - ); - - int affectedDroidsLimit = (int) (anomaly.globalPercentage * droids.length); + public void causeChargeGlobal() { + ArrayList droids = new ArrayList(); + for (InternalRobot currentRobot : this.objectInfo.robotsArray()) { + if (currentRobot.getMode() == RobotMode.DROID) { + droids.add(currentRobot); + currentRobot.updateNumVisibleFriendlyRobots(); + } + } + Collections.sort(droids, new SortByFriends()); + + int affectedDroidsLimit = (int) (AnomalyType.CHARGE.globalPercentage * droids.size()); for (int i = 0; i < affectedDroidsLimit; i++) { - this.destroyRobot(droids[i].getID()); + this.destroyRobot(droids.get(i).getID()); } } + + /** Used to sort droids for charge */ + class SortByFriends implements Comparator { + public int compare(InternalRobot a, InternalRobot b) { + return a.numVisibleFriendlyRobots - b.numVisibleFriendlyRobots; + } + } + + /** + * Performs the Fury anomaly. Changes the health of the relevant robots. + * @param reduceFactor associated with anomaly (a decimal percentage) + * @param locations that can be affected by the Fury (by radius, not by state of robot) + */ + public void causeFuryUpdate(float reduceFactor, MapLocation[] locations) { + for (int i = 0; i < locations.length; i++) { + InternalRobot robot = this.getRobot(locations[i]); + if (robot.getMode() == RobotMode.TURRET) { + robot.addHealth((int) (-1 * robot.getType().getMaxHealth(robot.getLevel()) * reduceFactor)); + } + } + } + + /** + * Mutates state to perform the Sage Fury. + * @param robot performing the Fury, must be a Sage + */ + public void causeFurySage(InternalRobot robot) { + assert robot.getType() == RobotType.SAGE; + this.causeFuryUpdate(AnomalyType.FURY.sagePercentage, this.getSageActionLocations(robot)); + } + + /** + * Mutates state to peform the global Fury. + */ + public void causeFuryGlobal() { + this.causeFuryUpdate(AnomalyType.FURY.globalPercentage, this.getAllLocations()); + } + + /** + * Mutates state to peform the global Vortex. + */ + public void causeVortexGlobal() { + // TODO + } } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 8a4842ac..a7f3a953 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -33,6 +33,7 @@ public strictfp class InternalRobot implements Comparable { private int roundsAlive; private int actionCooldownTurns; private int movementCooldownTurns; + private int numVisibleFriendlyRobots; /** * Used to avoid recreating the same RobotInfo object over and over. @@ -66,6 +67,7 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.addActionCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.movementCooldownTurns = 0; this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); + this.numVisibleFriendlyRobots = 0; this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); @@ -388,8 +390,8 @@ public void die_exception() { /** * @return the number of friendly robots within sensor (vision) radius. */ - public int getNumVisibleFriendlyRobots() { - return this.controller.getNumVisibleFriendlyRobots(); + public int updateNumVisibleFriendlyRobots() { + return this.numVisibleFriendlyRobots = this.controller.getNumVisibleFriendlyRobots(); } @Override From 9608229fa6981c99cf249220077befeee6d9e61c Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 03:09:12 -0600 Subject: [PATCH 131/413] fixed GameWorld's usage of LiveMap; doesn't update the LiveMap when things change --- .../src/main/battlecode/world/GameWorld.java | 47 ++++++++++--------- engine/src/main/battlecode/world/LiveMap.java | 46 +++++------------- .../battlecode/world/RobotControllerImpl.java | 4 +- 3 files changed, 40 insertions(+), 57 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 131050fc..fe513d9c 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -29,8 +29,8 @@ public strictfp class GameWorld { protected final GameStats gameStats; private int[] rubble; - private int[] leadCount; - private int[] goldCount; + private int[] lead; + private int[] gold; private InternalRobot[][] robots; private final LiveMap gameMap; private final TeamInfo teamInfo; @@ -45,8 +45,8 @@ public strictfp class GameWorld { @SuppressWarnings("unchecked") public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) { this.rubble = gm.getRubbleArray(); - this.leadCount = gm.getLeadArray(); - this.goldCount = gm.getGoldArray(); + this.lead = gm.getLeadArray(); + this.gold = new int[this.lead.length]; this.robots = new InternalRobot[gm.getWidth()][gm.getHeight()]; // if represented in cartesian, should be height-width, but this should allow us to index x-y this.currentRound = 0; this.idGenerator = new IDGenerator(gm.getSeed()); @@ -194,12 +194,20 @@ public int getRubble(MapLocation loc) { return this.rubble[locationToIndex(loc)]; } - public int getLeadCount(MapLocation loc) { - return this.leadCount[locationToIndex(loc)]; + public int getLead(MapLocation loc) { + return this.lead[locationToIndex(loc)]; } - public int getGoldCount(MapLocation loc) { - return this.goldCount[locationToIndex(loc)]; + public int setLead(MapLocation loc, int amount) { + this.lead[locationToIndex(loc)] = amount; + } + + public int getGold(MapLocation loc) { + return this.gold[locationToIndex(loc)]; + } + + public int setGold(MapLocation loc, int amount) { + this.gold[locationToIndex(loc)] = amount; } /** @@ -388,10 +396,9 @@ public boolean timeLimitReached() { public void processEndOfRound() { // Add lead resources to the map if ((this.currentRound + 1) % GameConstants.ADD_LEAD_EVERY_ROUNDS == 0) // +1 so we don't add lead the first round - for (int x = 0; x < gameMap.getWidth(); x++) - for (int y = 0; y < gameMap.getHeight(); y++) - if (gameMap.getLeadAtLocation(x, y) > 0) - gameMap.addLeadAtLocation(x, y, GameConstants.ADD_LEAD); + for (int i = 0; i < this.lead.length) + if (this.lead[i] > 0) + this.lead[i] += GameConstants.ADD_LEAD; // Add lead resources to the team teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); @@ -454,8 +461,8 @@ public void destroyRobot(int id) { int leadDropped = robot.getType().getLeadDropped(robot.getLevel()); int goldDropped = robot.getType().getGoldDropped(robot.getLevel()); - this.leadCount[locationToIndex(robot.getLocation())] += leadDropped; - this.goldCount[locationToIndex(robot.getLocation())] += goldDropped; + this.lead[locationToIndex(robot.getLocation())] += leadDropped; + this.gold[locationToIndex(robot.getLocation())] += goldDropped; controlProvider.robotKilled(robot); objectInfo.destroyRobot(id); @@ -496,17 +503,13 @@ private MapLocation[] getSageActionLocations(InternalRobot robot) { */ private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations) { for (int i = 0; i < locations.length; i++) { - MapLocation currentLocation = locations[i]; - int x = currentLocation.x; - int y = currentLocation.y; - - int currentLead = gameMap.getLeadAtLocation(x, y); + int currentLead = getLead(locations[i]); int leadUpdate = (int) (reduceFactor * currentLead); - gameMap.setLeadAtLocation(x, y, currentLead - leadUpdate); + setLead(locations[i], currentLead - leadUpdate); - int currentGold = gameMap.getGoldAtLocation(x, y); + int currentGold = getGold(locations[i]); int goldUpdate = (int) (reduceFactor * currentGold); - gameMap.setLeadAtLocation(x, y, currentGold - goldUpdate); + setGold(locations[i], currentGold - goldUpdate); } } diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index b3a1dbc8..0c4145e4 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -27,9 +27,14 @@ public strictfp class LiveMap { private final MapLocation origin; /** - * How much lead is stored per square. + * Factor to multiply cooldowns by */ - private final int[][] leadMap; + private int[] rubbleArray; + + /** + * How much lead is on each square + */ + private final int[] leadArray; /** * The random seed contained in the map file @@ -63,8 +68,6 @@ public strictfp class LiveMap { */ private final RobotInfo[] initialBodies; // only contains Enlightenment Centers - private int[] rubbleArray; // factor to multiply cooldowns by - public LiveMap(int width, int height, MapLocation origin, @@ -90,7 +93,6 @@ public LiveMap(int width, // TODO: initialize with potentially hardcoded anomalies this.anomalySchedule = null; this.nextAnomalyIndex = 0; - } public LiveMap(int width, @@ -266,40 +268,18 @@ public MapLocation getOrigin() { return origin; } - public int[] getRubbleArray() { - return rubbleArray; - } - /** - * @param x to get lead at - * @param y to get lead at - * @return the amount of lead at this location + * @return the rubble array of the map */ - public int getLeadAtLocation(int x, int y) { - assert onTheMap(new MapLocation(x, y)); - return this.leadMap[x][y]; - } - - /** - * Changes the amount of lead to amount - * @param x to set lead at - * @param y to set lead at - * @param amount of lead to put at this location - */ - public void setLeadAtLocation(int x, int y, int amount) { - assert onTheMap(new MapLocation(x, y)); - this.leadMap[x][y] = amount; + public int[] getRubbleArray() { + return rubbleArray; } /** - * Adds the amount of lead to current amount at a given square - * @param x to set lead at - * @param y to set lead at - * @param amountToAdd + * @return the lead array of the map */ - public void addLeadAtLocation(int x, int y, int amountToAdd) { - assert onTheMap(new MapLocation(x, y)); - this.leadMap[x][y] += amountToAdd; + public int[] getLeadArray() { + return leadArray; } /** diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 7f079bb5..297092db 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -590,7 +590,7 @@ private void assertCanMineLead(MapLocation loc) throws GameActionException { throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); } - int leadAmount = gameWorld.getLeadCount(loc); + int leadAmount = gameWorld.getLead(loc); if (leadAmount < 0) { throw new GameActionException(CANT_DO_THAT, "Lead amount must be positive to be mined."); @@ -625,7 +625,7 @@ private void assertCanMineGold(MapLocation loc) throws GameActionException { throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); } - int goldAmount = gameWorld.getGoldCount(loc); + int goldAmount = gameWorld.getGold(loc); if (goldAmount < 0) { throw new GameActionException(CANT_DO_THAT, "Gold amount must be positive to be mined."); From b44552c929bde274961db090f341dfe315312b74 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 03:10:12 -0600 Subject: [PATCH 132/413] comment fix --- engine/src/main/battlecode/world/GameWorld.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index fe513d9c..f152a278 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -403,7 +403,7 @@ public void processEndOfRound() { // Add lead resources to the team teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); - // Process end of each robot's round (currently empty in InternalRobot) + // Process end of each robot's round objectInfo.eachRobot((robot) -> { robot.processEndOfRound(); return true; From 05b7a9e19d3c51fd5f2ba9f0ed7542101c2e4944 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 03:24:06 -0600 Subject: [PATCH 133/413] Fixed LiveMap/AnomalyScheduleEntry and some bugs in GameWorld regarding them --- .../world/AnomalyScheduleEntry.java | 11 +++++ .../src/main/battlecode/world/GameWorld.java | 5 ++- engine/src/main/battlecode/world/LiveMap.java | 42 ++++++++++++++----- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java index f8e05502..acd62fb9 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/world/AnomalyScheduleEntry.java @@ -17,4 +17,15 @@ public AnomalyScheduleEntry(int round, AnomalyType anomaly) { public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType) { return new AnomalyScheduleEntry(this.roundNumber, this.anomalyType); } + + /** + * Returns whether two AnomalyScheduleEntrys are equal. + * + * @param other the other anomaly schedule entry to compare to + * @return whether the two anomaly schedules entry are equivalent + */ + public boolean equals(AnomalyScheduleEntry other) { + if (this.roundNumber != other.roundNumber) return false; + return this.anomalyType == other.anomalyType; + } } \ No newline at end of file diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index f152a278..0112ceec 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -395,7 +395,7 @@ public boolean timeLimitReached() { public void processEndOfRound() { // Add lead resources to the map - if ((this.currentRound + 1) % GameConstants.ADD_LEAD_EVERY_ROUNDS == 0) // +1 so we don't add lead the first round + if (this.currentRound % GameConstants.ADD_LEAD_EVERY_ROUNDS == 0) for (int i = 0; i < this.lead.length) if (this.lead[i] > 0) this.lead[i] += GameConstants.ADD_LEAD; @@ -411,7 +411,8 @@ public void processEndOfRound() { // Trigger any anomalies // note: singularity is handled below in the "check for end of match" - if (this.gameMap.viewNextAnomaly().roundNumber == this.currentRound) { + AnomalyScheduleEntry nextAnomaly = this.gameMap.viewNextAnomaly(); + if (nextAnomaly != null && nextAnomaly.roundNumber == this.currentRound) { AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; if (anomaly == AnomalyType.ABYSS) causeAbyssGlobal(anomaly); if (anomaly == AnomalyType.CHARGE) causeChargeGlobal(anomaly); diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 0c4145e4..8b55873d 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -83,9 +83,8 @@ public LiveMap(int width, this.mapName = mapName; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); this.rubbleArray = new int[width * height]; - for (int i = 0; i < rubbleArray.length; i++) { - this.rubbleArray[i] = 1; // default cooldown factor is 1 - } + Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 + this.leadArray = new int[width * height]; // TODO: we guarantee there to be lead within vision range of archons // invariant: bodies is sorted by id Arrays.sort(this.initialBodies, (a, b) -> Integer.compare(a.getID(), b.getID())); @@ -102,7 +101,9 @@ public LiveMap(int width, int rounds, String mapName, RobotInfo[] initialBodies, - int[] rubbleArray) { + int[] rubbleArray, + int[] leadArray, + AnomalyScheduleEntry[] anomalySchedule) { this.width = width; this.height = height; this.origin = origin; @@ -114,6 +115,16 @@ public LiveMap(int width, for (int i = 0; i < rubbleArray.length; i++) { this.rubbleArray[i] = rubbleArray[i]; } + this.leadArray = new int[leadArray.length]; + for (int i = 0; i < leadArray.length; i++) { + this.leadArray[i] = leadArray[i]; + } + + this.anomalySchedule = new int[anomalySchedule.length]; + for (int i = 0; i < anomalySchedule.length; i++) { + this.anomalySchedule[i] = anomalySchedule[i]; + } + this.nextAnomalyIndex = 0; // invariant: bodies is sorted by id Arrays.sort(this.initialBodies, (a, b) -> Integer.compare(a.getID(), b.getID())); @@ -126,21 +137,20 @@ public LiveMap(int width, */ public LiveMap(LiveMap gm) { this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.initialBodies, - gm.rubbleArray); + gm.rubbleArray, gm.leadArray, gm.anomalySchedule); } @Override public boolean equals(Object o) { if (!(o instanceof LiveMap)) return false; - return this.equals((LiveMap) o); } /** * Returns whether two GameMaps are equal. * - * @param other the other map to compare to. - * @return whether the two maps are equivalent. + * @param other the other map to compare to + * @return whether the two maps are equivalent */ public boolean equals(LiveMap other) { if (this.rounds != other.rounds) return false; @@ -150,6 +160,8 @@ public boolean equals(LiveMap other) { if (!this.mapName.equals(other.mapName)) return false; if (!this.origin.equals(other.origin)) return false; if (!Arrays.equals(this.rubbleArray, other.rubbleArray)) return false; + if (!Arrays.equals(this.leadArray, other.leadArary)) return false; + if (!Arrays.equals(this.anomalySchedule, other.anomalySchedule)) return false; return Arrays.equals(this.initialBodies, other.initialBodies); } @@ -162,6 +174,8 @@ public int hashCode() { result = 31 * result + rounds; result = 31 * result + mapName.hashCode(); result = 31 * result + Arrays.hashCode(rubbleArray); + result = 31 * result + Arrays.hashCode(leadArray); + result = 31 * result + Arrays.hashCode(anomalySchedule); result = 31 * result + Arrays.hashCode(initialBodies); return result; } @@ -286,7 +300,9 @@ public int[] getLeadArray() { * @return a copy of the next Anomaly that hasn't happened yet. */ public AnomalyScheduleEntry viewNextAnomaly() { - return this.anomalySchedule[this.nextAnomalyIndex].copyEntry(); + if (this.nextAnomalyIndex < this.anomalySchedule.length) + return this.anomalySchedule[this.nextAnomalyIndex].copyEntry(); + return null; } /** @@ -294,7 +310,9 @@ public AnomalyScheduleEntry viewNextAnomaly() { * @return the next Anomaly. */ public AnomalyScheduleEntry takeNextAnomaly() { - return this.anomalySchedule[this.nextAnomalyIndex++].copyEntry(); + if (this.nextAnomalyIndex < this.anomalySchedule.length) + return this.anomalySchedule[this.nextAnomalyIndex++].copyEntry(); + return null; } /** @@ -330,7 +348,9 @@ public String toString() { ", rounds=" + rounds + ", mapName='" + mapName + '\'' + ", initialBodies=" + Arrays.toString(initialBodies) + - ", rubbleArray=:)" + Arrays.toString(rubbleArray) + + ", rubbleArray=" + Arrays.toString(rubbleArray) + + ", leadArray=" + Arrays.toString(leadArray) + + ", anomalySchedule=" + Arrays.toString(anomalySchedule) + "}"; } } From 35cb3029d4b20af584e530382737dd2a1aed583e Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 03:27:16 -0600 Subject: [PATCH 134/413] fix anomaly schedule in LiveMap --- engine/src/main/battlecode/world/LiveMap.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 8b55873d..c175846c 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -86,12 +86,12 @@ public LiveMap(int width, Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 this.leadArray = new int[width * height]; // TODO: we guarantee there to be lead within vision range of archons + this.anomalySchedule = new int[1]; + this.anomalySchedule[0] = new AnomalyScheduleEntry(GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, AnomalyType.SINGULARITY); + this.nextAnomalyIndex = 0; + // invariant: bodies is sorted by id Arrays.sort(this.initialBodies, (a, b) -> Integer.compare(a.getID(), b.getID())); - - // TODO: initialize with potentially hardcoded anomalies - this.anomalySchedule = null; - this.nextAnomalyIndex = 0; } public LiveMap(int width, From a37c1c6af7f87ea2ad2498bd09d9c89c0aa706e3 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 03:29:36 -0600 Subject: [PATCH 135/413] style fix --- engine/src/main/battlecode/world/LiveMap.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index c175846c..1c59ea73 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -338,8 +338,7 @@ public String toString() { ", initialBodies=" + Arrays.toString(initialBodies) + ", len=" + Integer.toString(rubbleArray.length) + "}"; - } - else { + } else { return "LiveMap{" + "width=" + width + ", height=" + height + From c55ef47841fc5e970280b683cfdfe3ab8e7e1a47 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Wed, 22 Dec 2021 11:04:03 -0500 Subject: [PATCH 136/413] fix minor typos with lead and gold rendering --- client/visualizer/src/gamearea/renderer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index 22a05021..29fef393 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -59,7 +59,6 @@ export default class Renderer { this.renderResources(world); this.renderBodies(world, curTime, nextStep, lerpAmount); - world.mapStats.goldVals this.renderIndicatorDotsLines(world); this.setMouseoverEvent(world); @@ -165,7 +164,7 @@ export default class Renderer { else this.ctx.drawImage(goldImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); } if(map.leadVals[idxVal] > 0){ - let size = sigmoid(map.goldVals[idxVal] / 50); + let size = sigmoid(map.leadVals[idxVal] / 50); if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1-size)/2, cy + (1-size)/2, scale * size, scale * size); else this.ctx.drawImage(leadImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); } From d0bcca81f406759060b0ee8135ba8c87355346ff Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Wed, 22 Dec 2021 11:22:39 -0500 Subject: [PATCH 137/413] Add actions for global anomalies --- schema/battlecode.fbs | 7 ++++++- schema/ts/battlecode_generated.ts | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1347def8..1ef7131e 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -98,7 +98,12 @@ enum Action : byte { LOCAL_CHARGE, /// Dies due to an uncaught exception. /// Target: none - DIE_EXCEPTION + DIE_EXCEPTION, + ABYSS, + CHARGE, + FURY, + VORTEX, + SINGULARITY } // Metadata diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 63d97fbf..0093e8f9 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -48,7 +48,12 @@ export enum Action{ * Dies due to an uncaught exception. * Target: none */ - DIE_EXCEPTION= 13 + DIE_EXCEPTION= 13, + ABYSS= 14, + CHARGE= 15, + FURY= 16, + VORTEX= 17, + SINGULARITY= 18 }}; /** From 0736c010903216a43fe81fb3d593e009e7ecb1e2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 12:37:57 -0600 Subject: [PATCH 138/413] added causeVortexGlobal --- .../src/main/battlecode/world/GameWorld.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 0112ceec..f91cd0cb 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -607,8 +607,26 @@ public void causeFuryGlobal() { /** * Mutates state to peform the global Vortex. + * Note that in this year's game, width == height (only square maps) + * Only mutates the rubble array in this class; doesn't change the LiveMap */ public void causeVortexGlobal() { - // TODO + int n = this.gameMap.getWidth(); + for (int x = 0; x < n / 2; x++) { + for (int y = 0; y < (n + 1) / 2; y++) { + int curX = x; + int curY = y; + int lastRubble = this.rubble[curX + curY * n]; + for (int i = 0; i < 4; i++) { + int tempX = curX; + curX = curY; + curY = (n - 1) - tempX; + int idx = curX + curY * n; + int tempRubble = this.rubble[idx]; + this.rubble[idx] = lastRubble; + lastRubble = tempRubble; + } + } + } } } From cccf3b8c5e0b8291e06e597d5561156a3e8d413e Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 14:06:57 -0600 Subject: [PATCH 139/413] MapBuilder --- .../main/battlecode/common/GameConstants.java | 12 ++ engine/src/main/battlecode/world/LiveMap.java | 2 +- .../src/main/battlecode/world/MapBuilder.java | 149 +++++++++--------- 3 files changed, 89 insertions(+), 74 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 2255e6b0..cb31e160 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -27,6 +27,18 @@ public class GameConstants { /** The maximum possible map width. */ public static final int MAP_MAX_WIDTH = 80; + /** The minimum number of starting Archons per team. */ + public static final int MIN_STARTING_ARCHONS = 1; + + /** The maximum number of starting Archons per team. */ + public static final int MAX_STARTING_ARCHONS = 4; + + /** The minimum amount of rubble per square. */ + public static final int MIN_RUBBLE = 100; + + /** The maximum amount of rubble per square. */ + public static final int MAX_RUBBLE = 100; + // ********************************* // ****** GAME PARAMETERS ********** // ********************************* diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 1c59ea73..ffd8ab39 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -160,7 +160,7 @@ public boolean equals(LiveMap other) { if (!this.mapName.equals(other.mapName)) return false; if (!this.origin.equals(other.origin)) return false; if (!Arrays.equals(this.rubbleArray, other.rubbleArray)) return false; - if (!Arrays.equals(this.leadArray, other.leadArary)) return false; + if (!Arrays.equals(this.leadArray, other.leadArray)) return false; if (!Arrays.equals(this.anomalySchedule, other.anomalySchedule)) return false; return Arrays.equals(this.initialBodies, other.initialBodies); } diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index e9f8af4c..02189268 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -20,6 +20,8 @@ public enum MapSymmetry {rotational, horizontal, vertical}; public int seed; private MapSymmetry symmetry; private int[] rubbleArray; + private int[] leadArray; + private ArrayList anomalySchedule; private int idCounter; private List bodies; @@ -35,10 +37,10 @@ public MapBuilder(String name, int width, int height, int originX, int originY, // default values this.symmetry = MapSymmetry.vertical; this.idCounter = 0; - this.rubbleArray = new int[width*height]; - for (int i = 0; i < rubbleArray.length; i++) { - rubbleArray[i] = 1; // default cooldown factor is 1 - } + this.rubbleArray = new int[width * height]; + Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 + this.leadArray = new int[width * height]; + this.anomalySchedule = new ArrayList<>(); } // ******************** @@ -55,7 +57,7 @@ private int locationToIndex(int x, int y) { return x + y * width; } - public void addEnlightenmentCenter(int id, Team team, int influence, MapLocation loc) { + public void addArchon(int id, Team team, MapLocation loc) { // check if something already exists here, if so shout for (RobotInfo r : bodies) { if (r.location.equals(loc)) { @@ -65,18 +67,17 @@ public void addEnlightenmentCenter(int id, Team team, int influence, MapLocation bodies.add(new RobotInfo( id, team, - RobotType.ENLIGHTENMENT_CENTER, - influence, - influence, // Enlightenment Centers conviction == influence + RobotType.ARCHON, + 1, + RobotType.ARCHON.health; loc )); } - public void addEnlightenmentCenter(int x, int y, Team team, int influence) { - addEnlightenmentCenter( + public void addArchon(int x, int y, Team team) { + addArchon( idCounter++, team, - influence, new MapLocation(x, y) ); } @@ -85,11 +86,18 @@ public void setRubble(int x, int y, int value) { this.rubbleArray[locationToIndex(x, y)] = value; } + public void setLead(int x, int y, int value) { + this.leadArray[locationToIndex(x, y)] = value; + } + + public void addAnomalyScheduleEntry(int round, AnomalyType anomaly) { + this.anomalySchedule.add(new AnomalyScheduleEntry(round, anomaly)); + } + public void setSymmetry(MapSymmetry symmetry) { this.symmetry = symmetry; } - // ******************** // SYMMETRY METHODS // ******************** @@ -101,6 +109,7 @@ public int symmetricY(int y) { public int symmetricX(int x) { return symmetricX(x, symmetry); } + public int symmetricY(int y, MapSymmetry symmetry) { switch (symmetry) { case vertical: @@ -132,14 +141,9 @@ public MapLocation symmetryLocation(MapLocation p) { * @param x x position * @param y y position */ - public void addSymmetricEnlightenmentCenter(int x, int y) { - addEnlightenmentCenter(x, y, Team.A, GameConstants.INITIAL_ENLIGHTENMENT_CENTER_INFLUENCE); - addEnlightenmentCenter(symmetricX(x), symmetricY(y), Team.B, GameConstants.INITIAL_ENLIGHTENMENT_CENTER_INFLUENCE); - } - - public void addSymmetricNeutralEnlightenmentCenter(int x, int y, int influence) { - addEnlightenmentCenter(x, y, Team.NEUTRAL, influence); - addEnlightenmentCenter(symmetricX(x), symmetricY(y), Team.NEUTRAL, influence); + public void addSymmetricArchon(int x, int y) { + addArchon(x, y, Team.A); + addArchon(symmetricX(x), symmetricY(y), Team.B); } public void setSymmetricRubble(int x, int y, int value) { @@ -147,13 +151,19 @@ public void setSymmetricRubble(int x, int y, int value) { this.rubbleArray[locationToIndex(symmetricX(x), symmetricY(y))] = value; } + public void setSymmetricLead(int x, int y, int value) { + this.leadArray[locationToIndex(x, y)] = value; + this.leadArray[locationToIndex(symmetricX(x), symmetricY(y))] = value; + } + // ******************** // BUILDING AND SAVING // ******************** public LiveMap build() { return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, - bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray); + bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray, leadArray, + anomalySchedule.toArray(new AnomalyScheduleEntry[anomalySchedule.size()])); } /** @@ -169,60 +179,51 @@ public void saveMap(String pathname) throws IOException { } /** - * Returns true if the map is valid. - * - * WARNING: DON'T TRUST THIS COMPLETELY. THIS DOES NOT VERIFY SYMMETRY. - * @return + * Throws a RuntimeException if the map is invalid. */ public void assertIsValid() { - System.out.println("Validating " + name + "..."); // get robots - RobotInfo[] robots = new RobotInfo[width*height]; + RobotInfo[] robots = new RobotInfo[width * height]; for (RobotInfo r : bodies) { - assert robots[locationToIndex(r.location.x, r.location.y)] == null; + if (robots[locationToIndex(r.location.x, r.location.y)] != null) + throw new RuntimeException("Two robots on the same square"); robots[locationToIndex(r.location.x, r.location.y)] = r; - if (r.influence < 50 || r.influence > 500) // this really should be a GameConstant, but oh well - throw new RuntimeException("Influence not in [50, 500]"); } + if (width < GameConstants.MAP_MIN_WIDTH || height < GameConstants.MAP_MIN_HEIGHT || + width > GameConstants.MAP_MAX_WIDTH || height > GameConstants.MAP_MAX_HEIGHT) + throw new RuntimeException("The map size must be between " + GameConstants.MAP_MIN_WIDTH + "x" + + GameConstants.MAP_MIN_HEIGHT + " and " + GameConstants.MAP_MAX_WIDTH + "x" + + GameConstants.MAP_MAX_HEIGHT + ", inclusive"); - if (width < 32 || height < 32 || width > 64 || height > 64) - throw new RuntimeException("The map size must be between 32x32 and 64x64, inclusive."); - - // checks at least one Enlightenment Center of each team - // only needs to check there's an Enlightenment Center of Team A, because symmetry is checked - boolean noTeamARobots = true; + // checks between 1 and 4 Archons of each team + // only needs to check the Archons of Team A, because symmetry is checked + int numTeamARobots = 0; for (RobotInfo r : bodies) { if (r.getTeam() == Team.A) { - noTeamARobots = false; - break; + numTeamARobots++; } } - if (noTeamARobots) { - throw new RuntimeException("Map must have starting robots of each team"); + if (numTeamARobots < GameConstants.MIN_STARTING_ARCHONS || + numTeamARobots > GameConstants.MAX_STARTING_ARCHONS) { + throw new RuntimeException("Map must have between " + GameConstants.MIN_STARTING_ARCHONS + + "and " + GameConstants.MAX_STARTING_ARCHONS + " starting Archons of each team"); } - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - MapLocation current = new MapLocation(x, y); - // This should also be a GameConstant, but I'm speed-coding this and we can fix this later - if (rubbleArray[locationToIndex(current.x, current.y)] <= 100 || rubbleArray[locationToIndex(current.x, current.y)] >= 0) { - throw new RuntimeException("Map rubble not between 0 and 100"); - } + for (int i = 0; i < rubbleArray.length; i++) { + if (rubbleArray[i] < GameConstants.MIN_RUBBLE || rubbleArray[i] > GameConstants.MAX_RUBBLE) { + throw new RuntimeException("Map rubble must be between " + GameConstants.MIN_RUBBLE + + " and " + GameConstants.MAX_RUBBLE); } } - // assert rubble and Enlightenment Center symmetry + // assert rubble, lead, and Archon symmetry ArrayList allMapSymmetries = getSymmetry(robots); System.out.println("This map has the following symmetries: " + allMapSymmetries); - boolean doesContain = false; - for (MapSymmetry sss : allMapSymmetries) { - if (sss == symmetry) doesContain = true; - } - if (!doesContain) { - throw new RuntimeException("Rubble and Enlightenment Centers must be symmetric according to the given symmetry; they are not currently."); + if (allMapSymmetries.isEmpty()) { + throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); } } @@ -235,8 +236,10 @@ public MapLocation indexToLocation(int idx) { idx / this.width); } + /** + * @return the list of symmetries, empty if map is invalid + */ private ArrayList getSymmetry(RobotInfo[] robots) { - ArrayList possible = new ArrayList(); possible.add(MapSymmetry.vertical); possible.add(MapSymmetry.horizontal); @@ -245,35 +248,35 @@ private ArrayList getSymmetry(RobotInfo[] robots) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MapLocation current = new MapLocation(x, y); + int curIdx = locationToIndex(current.x, current.y); RobotInfo cri = robots[locationToIndex(current.x, current.y)]; - for (int i = possible.size()-1; i >= 0; i--) { // iterating backwards so we can remove in the loop + for (int i = possible.size() - 1; i >= 0; i--) { // iterating backwards so we can remove in the loop MapSymmetry symmetry = possible.get(i); MapLocation symm = new MapLocation(symmetricX(x, symmetry), symmetricY(y, symmetry)); - if (rubbleArray[locationToIndex(current.x, current.y)] != rubbleArray[locationToIndex(symm.x, symm.y)]) possible.remove(symmetry); - RobotInfo sri = robots[locationToIndex(symm.x, symm.y)]; - if (!(cri == null) || !(sri == null)) { - if (cri == null || sri == null) { - possible.remove(symmetry); - } else if (cri.getType() != sri.getType()) { - possible.remove(symmetry); - } else if (!symmetricTeams(cri.getTeam(), sri.getTeam())) { - possible.remove(symmetry); + int symIdx = locationToIndex(symm.x, symm.y); + if (rubbleArray[curIdx] != rubbleArray[symIdx]) + possible.remove(symmetry); + else if (leadArray[curIdx] != leadArray[symIdx]) + possible.remove(symmetry); + else { + RobotInfo sri = robots[locationToIndex(symm.x, symm.y)]; + if (cri != null || sri != null) { + if (cri == null || sri == null) { + possible.remove(symmetry); + } else if (cri.getType() != sri.getType()) { + possible.remove(symmetry); + } else if (!symmetricTeams(cri.getTeam(), sri.getTeam())) { + possible.remove(symmetry); + } } } } - if (possible.size() <= 1) break; } - if (possible.size() <= 1) break; } - return possible; } private boolean symmetricTeams(Team a, Team b) { - switch (a) { - case A: return b == Team.B; - case B: return b == Team.A; - default: return b == Team.NEUTRAL; - } + return a != b; } } From 0ca6b25e34d73cbfc7a74fac236a212b38d08be2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 14:07:57 -0600 Subject: [PATCH 140/413] blank line at the end of LiveMap --- engine/src/main/battlecode/world/LiveMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index ffd8ab39..d72a5f38 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -353,4 +353,4 @@ public String toString() { "}"; } } -} \ No newline at end of file +} From 4a4923a4ccd49fb4413e1c6be7321382d7a012bf Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 14:18:25 -0600 Subject: [PATCH 141/413] TestMapBuilder --- .../main/battlecode/world/TestMapBuilder.java | 55 +++++-------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/engine/src/main/battlecode/world/TestMapBuilder.java b/engine/src/main/battlecode/world/TestMapBuilder.java index 2023612e..7e14bada 100644 --- a/engine/src/main/battlecode/world/TestMapBuilder.java +++ b/engine/src/main/battlecode/world/TestMapBuilder.java @@ -8,58 +8,33 @@ * Lets maps be built easily, for testing purposes. */ public class TestMapBuilder { - private String name; - private MapLocation origin; - private int width; - private int height; - private int seed; - private int rounds; - private int[] rubbleArray; + private MapBuilder mapBuilder; - private List bodies; - - public TestMapBuilder(String name, int oX, int oY, int width, int height, int seed, int rounds) { - this(name, new MapLocation(oX, oY), width, height, seed, rounds); - } - - public TestMapBuilder(String name, MapLocation origin, int width, int height, int seed, int rounds) { - this.name = name; - this.origin = origin; - this.width = width; - this.height = height; - this.seed = seed; - this.bodies = new ArrayList<>(); + public TestMapBuilder(String name, int oX, int oY, int width, int height, int seed) { + this.mapBuilder = new MapBuilder(name, width, height, oX, oY, seed) } - public TestMapBuilder addEnlightenmentCenter(int id, Team team, int influence, MapLocation loc) { - bodies.add(new RobotInfo( - id, - team, - RobotType.ENLIGHTENMENT_CENTER, - influence, - 0, - loc - )); - + public TestMapBuilder addArchon(int id, Team team, MapLocation loc) { + this.mapBuilder.addArchon(id, team, loc); return this; } - public TestMapBuilder setRubble() { - this.rubbleArray = new int[width * height]; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - this.rubbleArray[i + j * width] = (i * j + i + j) / (i * j + 1); - } - } + public TestMapBuilder setRubble(int x, int y, int value) { + this.mapBuilder.setRubble(x, y, value); + return this; + } + + public TestMapBuilder setLead(int x, int y, int value) { + this.mapBuilder.setLead(x, y, value); return this; } - public TestMapBuilder addBody(RobotInfo info) { - bodies.add(info); + public TestMapBuilder addAnomalyScheduleEntry(int round, AnomalyType anomaly) { + this.mapBuilder.addAnomalyScheduleEntry(round, anomaly); return this; } public LiveMap build() { - return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray); + return this.mapBuilder.build(); } } From 1818fb0fa183b183802a3416431b12be13c6fd5f Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 14:41:19 -0600 Subject: [PATCH 142/413] small changes --- engine/src/main/battlecode/world/GameMapIO.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index 01006912..977bf629 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -48,9 +48,7 @@ public final strictfp class GameMapIO { * @return LiveMap for map * @throws IOException if the map fails to load or can't be found. */ - public static LiveMap loadMap(String mapName, File mapDir) - throws IOException { - + public static LiveMap loadMap(String mapName, File mapDir) throws IOException { final LiveMap result; final File mapFile = new File(mapDir, mapName + MAP_EXTENSION); From e6a0341d68bb4ad35bc59acc6c15b42146deae7e Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 15:45:00 -0600 Subject: [PATCH 143/413] preliminary RobotController --- .../battlecode/common/RobotController.java | 103 +++++++++--------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 781407d6..0fb3cfbf 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -171,7 +171,7 @@ public strictfp interface RobotController { * vision range. * * @param id the ID of the robot to query - * @return true if the given robot is within this robot's vision range; + * @return true if the given robot is within this robot's vision range and exists; * false otherwise. * * @battlecode.doc.costlymethod @@ -295,8 +295,6 @@ public strictfp interface RobotController { */ MapLocation adjacentLocation(Direction dir); - - // *********************************** // ****** READINESS METHODS ********** // *********************************** @@ -377,9 +375,6 @@ public strictfp interface RobotController { // ****** BUILDING/SPAWNING ********** // *********************************** - - // TODO: is upgrade level a part of type or an extra parameter? - /** * Tests whether the robot can build a robot of the given type in the * given direction. Checks that the robot is of a type that can build, @@ -418,7 +413,7 @@ public strictfp interface RobotController { * * Checks that the robot is an attacking type unit and that the given location * is within the robot's reach (based on attack type). Also checks that an - * enemy unit exists in the given square. + * enemy unit exists in the given square, and there are no cooldown turns remaining. * * @param loc target location to attack * @return whether it is possible to attack the given location. @@ -431,6 +426,7 @@ public strictfp interface RobotController { * Attack a given location. * * @throws GameActionException if conditions for attacking are not satisfied + * * @battlecode.doc.costlymethod */ void attack(MapLocation loc) throws GameActionException; @@ -440,9 +436,9 @@ public strictfp interface RobotController { // ***************************** /** - * Tests whether this robot can use an anomaly centered at the robots location. + * Tests whether this robot can use an anomaly centered at the robot's location. * - * Checks that the robot is a sage. + * Checks that the robot is a sage, and there are no cooldown turns remaining. * * @return whether it is possible to use an anomaly centered at the robots location. * @@ -454,6 +450,7 @@ public strictfp interface RobotController { * Use anomaly centered at robots location. * * @throws GameActionException if conditions for using anomaly are not satisfied + * * @battlecode.doc.costlymethod */ void useAnomaly(AnomalyType anomaly) throws GameActionException; @@ -466,8 +463,8 @@ public strictfp interface RobotController { * Tests whether this robot can heal a droid at the given location. * * Checks that the robot is an archon unit and that the given location - * is within the robot's action radius. Also checks that a - * friendly droid robot exists in the given square. + * is within the robot's action radius. Also checks that a friendly droid + * exists in the given square, and there are no cooldown turns remaining. * * @param loc target location to heal at * @return whether it is possible to heal a droid robot at the given location. @@ -484,7 +481,6 @@ public strictfp interface RobotController { */ void healDroid(MapLocation loc) throws GameActionException; - // *********************** // **** MINER METHODS **** // *********************** @@ -495,7 +491,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * have positive lead amounts. + * have positive lead amounts. Also checks that no cooldown turns remain. * * @param loc target location to mine * @return whether it is possible to mine at the given location. @@ -508,7 +504,8 @@ public strictfp interface RobotController { * Mine lead at a given location. * * @throws GameActionException if conditions for mining are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void mineLead(MapLocation loc) throws GameActionException; @@ -518,7 +515,7 @@ public strictfp interface RobotController { * Checks that the robot is a Miner, that the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also - * have positive gold amounts. + * have positive gold amounts. Also checks that no cooldown turns remain. * * @param loc target location to mine * @return whether it is possible to mine at the given location. @@ -531,7 +528,8 @@ public strictfp interface RobotController { * Mine a gold at given location. * * @throws GameActionException if conditions for mining are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void mineGold(MapLocation loc) throws GameActionException; @@ -544,7 +542,8 @@ public strictfp interface RobotController { * * Checks that the robot is a Builder, that the given location is a valid * upgrade location. Valid upgrade locations must be adjacent to the current - * location and contain an upgradable building. The upgrade must also be affordable. + * location and contain an upgradable building. The upgrade must also be + * affordable, and there must be no cooldown turns remaining. * * @param loc target location to upgrade * @return whether it is possible to upgrade at the given location. @@ -557,16 +556,17 @@ public strictfp interface RobotController { * Upgrade a building at a given location. * * @throws GameActionException if conditions for upgrading are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void upgrade(MapLocation loc) throws GameActionException; /** * Tests whether this robot can repair a building at the given location. * - * Checks that the robot is a builder unit and that the given location - * is within the robot's action radius. Also checks that a - * friendly unit which is a building exists in the given square. + * Checks that the robot is a builder unit and that the given location is + * within the robot's action radius. Also checks that a friendly unit which + * is a building exists in the given square, and no cooldown turns remain. * * @param loc target location to repair building at * @return whether it is possible to repair a building at the given location. @@ -579,19 +579,20 @@ public strictfp interface RobotController { * Repairs building at a given location. * * @throws GameActionException if conditions for repairing building are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void repairBuilding(MapLocation loc) throws GameActionException; // ******************************* - // **** ALCHEMIST LAB METHODS **** + // **** ALCHEMIST LAB METHODS **** // ******************************* /** * Tests whether this robot can convert lead into gold. * * Checks that the robot is a lab and the player has sufficient lead to - * perform a conversion. + * perform a conversion. Also checks that no cooldown turns remain. * * @return whether it is possible to convert lead into gold * @@ -600,9 +601,9 @@ public strictfp interface RobotController { boolean canConvert(); /** - * Get lead to gold conversion rate. + * Get lead to gold conversion rate. Returns 0 if robot is not a lab. * - * @battlecode.doc.costlymethod + * @battlecode.doc.costlymethod */ public int getGoldExchangeRate(); @@ -610,7 +611,7 @@ public strictfp interface RobotController { * Convert lead into gold. * * @throws GameActionException if conditions for converting are not satisfied - * @battlecode.doc.costlymethod + * @battlecode.doc.costlymethod */ void convert() throws GameActionException; @@ -619,9 +620,10 @@ public strictfp interface RobotController { // ******************************* /** - * Tests whether this tower can transform. + * Tests whether this robot can transform. * - * Checks that the robot is a turret or portable + * Checks that the robot is a building and is not a prototype; also checks + * that there are no cooldown turns remaining. * * @return whether it is possible to transform * @@ -633,56 +635,57 @@ public strictfp interface RobotController { * Transform from turret into portable or vice versa. * * @throws GameActionException if conditions for transforming are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void transform() throws GameActionException; - // *********************************** // ****** COMMUNICATION METHODS ****** // *********************************** /** - * Checks whether the robot can set the flag to a specified integer. + * Checks whether the robot can set the team array's value at a specified index. * - * @return whether the robot can set the flag to the specified integer. + * @param index the index in the team's shared array + * @param value the value to set that index to + * @return whether the robot can set the team array's value at the given index */ - boolean canSetFlag(int flag); + boolean canSetTeamArray(int index, int value); /** - * Sets a robot's flag to an integer. + * Sets a team's array value at a specified index. * - * @param flag the flag value. - * @throws GameActionException if the specified integer is not a valid flag + * @param index the index in the team's shared array + * @param value the value to set that index to + * @throws GameActionException if the index or value is invalid * * @battlecode.doc.costlymethod */ - void setFlag(int flag) throws GameActionException; + void setTeamArray(int index, int value) throws GameActionException; /** - * Given a robot's ID, checks if a robot can get the flag of that robot. + * Given an index, checks if a robot can get the value at that index in the team array. * - * Checks that a robot exists, and that either (a) the robot is an Enlightenment - * Center or (b) the target robot is within sensor range. + * Checks that the index is valid. * - * @param id the target robot's ID - * @return whether it is possible to get the robot's flag + * @param index the index in the team's shared array + * @return whether it is possible to get the value at that index * * @battlecode.doc.costlymethod */ - boolean canGetFlag(int id); + boolean canGetTeamArray(int index); /** - * Given a robot's ID, returns the flag of the robot. + * Given an index, returns the value at that index in the team array. * - * @param id the target robot's ID - * @throws GameActionException if conditions for getting the flag are not satisfied - * @return the flag of the robot + * @param index the index in the team's shared array + * @throws GameActionException if conditions for getting the value are not satisfied + * @return the value at that index in the team's shared array * * @battlecode.doc.costlymethod */ - int getFlag(int id) throws GameActionException; - + int getTeamArray(int index) throws GameActionException; // *********************************** // ****** OTHER ACTION METHODS ******* From c87d1ac36a74d2978a278e2506db879b6e3e170a Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:14:49 -0600 Subject: [PATCH 144/413] Updated TeamInfo --- .../src/main/battlecode/world/TeamInfo.java | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 46fff191..d73392a6 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -12,23 +12,21 @@ public class TeamInfo { private GameWorld gameWorld; - private int archonCount; - private int leadCount; - private int goldCount; + private int[] archonCounts; + private int[] leadCounts; + private int[] goldCounts; /** * Create a new representation of TeamInfo * - * @param gameWorld the gameWorld the team exists in - * @param archonCount the number of remaining archons - * @param leadCount the amount of lead stored - * @param goldCount the amount of gold stored + * @param gameWorld the gameWorld the teams exist in */ - public TeamInfo(GameWorld gameWorld) { + public TeamInfo(GameWorld gameWorld, int numArchons) { this.gameWorld = gameWorld; - this.archonCount = 0; - this.leadCount = 0; - this.goldCount = 0; + this.archonCount = new int[2]; + Arrays.fill(this.archonCount, numArchons); + this.leadCount = new int[2]; + this.goldCount = new int[2]; } // ********************************* @@ -38,28 +36,31 @@ public TeamInfo(GameWorld gameWorld) { /** * Get the number of remaining Archons. * + * @param team the team to query * @return the number of archons remaining */ - public int getArchonCount() { - return this.archonCount; + public int getArchonCount(Team team) { + return this.archonCount[team.ordinal()]; } /** * Get the amount of lead. * + * @param team the team to query * @return the team's lead count */ - public int getLead() { - return this.leadCount; + public int getLead(Team team) { + return this.leadCount[team.ordinal()]; } /** * Get the amount of gold. * + * @param team the team to query * @return the team's gold count */ - public int getGold() { - return this.goldCount; + public int getGold(Team team) { + return this.goldCount[team.ordinal()]; } // ********************************* @@ -67,44 +68,43 @@ public int getGold() { // ********************************* /** - * Set the number of Archons. + * Decrease the number of Archons. * - * @param newArchonCount the new number of Archons - * - * @throws IllegalArgumentException if the newArchonCount is negative + * @param team the team to query + * @throws IllegalArgumentException if the new Archon count goes below 0 */ - public void setArchonCount(int newArchonCount) throws IllegalArgumentException { - if (newArchonCount < 0) { + public void decreaseArchonCount(Team team) throws IllegalArgumentException { + if (this.archonCount[team.ordinal()] == 0) { throw new IllegalArgumentException("Invalid archon count"); } - this.archonCount = newArchonCount; + this.archonCount[team.ordinal()]--; } /** * Add to the amount of lead. If leadChange is negative, subtract from lead instead. * + * @param team the team to query * @param leadChange the change in the lead count - * * @throws IllegalArgumentException if the resulting amount of lead is negative */ - public void changeLead(int leadChange) throws IllegalArgumentException { - if (leadCount + leadChange < 0) { + public void changeLead(Team team, int leadChange) throws IllegalArgumentException { + if (this.leadCount[team.ordinal()] + leadChange < 0) { throw new IllegalArgumentException("Invalid lead change"); } - this.leadCount += leadChange; + this.leadCount[team.ordinal()] += leadChange; } /** * Add to the amount of gold. If goldChange is negative, subtract from gold instead. * + * @param team the team to query * @param goldChange the change in the gold count - * * @throws IllegalArgumentException if the resulting amount of gold is negative */ - public void changeGold(int goldChange) throws IllegalArgumentException { - if (goldCount + goldChange < 0) { + public void changeGold(Team team, int goldChange) throws IllegalArgumentException { + if (this.goldCount[team.ordinal()] + goldChange < 0) { throw new IllegalArgumentException("Invalid gold change"); } - this.goldCount += goldChange; + this.goldCount[team.ordinal()] += goldChange; } } From c8017cf3adb5e08ba33e706a25756162420d1749 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:16:18 -0600 Subject: [PATCH 145/413] rename functions in TeamInfo --- .../src/main/battlecode/world/TeamInfo.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index d73392a6..c67efb69 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -81,30 +81,30 @@ public void decreaseArchonCount(Team team) throws IllegalArgumentException { } /** - * Add to the amount of lead. If leadChange is negative, subtract from lead instead. + * Add to the amount of lead. If amount is negative, subtract from lead instead. * * @param team the team to query - * @param leadChange the change in the lead count + * @param amount the change in the lead count * @throws IllegalArgumentException if the resulting amount of lead is negative */ - public void changeLead(Team team, int leadChange) throws IllegalArgumentException { - if (this.leadCount[team.ordinal()] + leadChange < 0) { + public void addLead(Team team, int amount) throws IllegalArgumentException { + if (this.leadCount[team.ordinal()] + amount < 0) { throw new IllegalArgumentException("Invalid lead change"); } - this.leadCount[team.ordinal()] += leadChange; + this.leadCount[team.ordinal()] += amount; } /** - * Add to the amount of gold. If goldChange is negative, subtract from gold instead. + * Add to the amount of gold. If amount is negative, subtract from gold instead. * * @param team the team to query - * @param goldChange the change in the gold count + * @param amount the change in the gold count * @throws IllegalArgumentException if the resulting amount of gold is negative */ - public void changeGold(Team team, int goldChange) throws IllegalArgumentException { - if (this.goldCount[team.ordinal()] + goldChange < 0) { + public void addGold(Team team, int amount) throws IllegalArgumentException { + if (this.goldCount[team.ordinal()] + amount < 0) { throw new IllegalArgumentException("Invalid gold change"); } - this.goldCount[team.ordinal()] += goldChange; + this.goldCount[team.ordinal()] += amount; } } From 2def911f033f9cb211cfbcad30cc6820137c2b00 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:28:34 -0600 Subject: [PATCH 146/413] remove archon counts from TeamInfo, update GameWorld win cons --- .../battlecode/world/DominationFactor.java | 2 +- .../src/main/battlecode/world/GameWorld.java | 46 ++++++++----------- .../src/main/battlecode/world/TeamInfo.java | 28 +---------- 3 files changed, 22 insertions(+), 54 deletions(-) diff --git a/engine/src/main/battlecode/world/DominationFactor.java b/engine/src/main/battlecode/world/DominationFactor.java index 995bd3ab..ac9999db 100644 --- a/engine/src/main/battlecode/world/DominationFactor.java +++ b/engine/src/main/battlecode/world/DominationFactor.java @@ -7,7 +7,7 @@ public enum DominationFactor { /** * Win by all enemy archons being destroyed (early end). */ - ANNIHILATED, + ANNIHILATION, /** * Win by having more Archons. */ diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index f91cd0cb..1c94038e 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -54,7 +54,6 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match this.gameMap = gm; this.objectInfo = new ObjectInfo(gm); - this.teamInfo = new TeamInfo(this); this.profilerCollections = new HashMap<>(); @@ -65,13 +64,17 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match controlProvider.matchStarted(this); // Add the robots contained in the LiveMap to this world. + int numArchons = 0; RobotInfo[] initialBodies = this.gameMap.getInitialBodies(); for (int i = 0; i < initialBodies.length; i++) { RobotInfo robot = initialBodies[i]; MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y); int newID = spawnRobot(robot.type, newLocation, robot.team); initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, 1, robot.health, newLocation); + if (robot.team == Team.A && robot.type == RobotType.ARCHON) + numArchons++; } + this.teamInfo = new TeamInfo(this, numArchons); // Write match header at beginning of match this.matchMaker.makeMatchHeader(this.gameMap); @@ -311,30 +314,12 @@ public void setWinner(Team t, DominationFactor d) { gameStats.setDominationFactor(d); } - /** - * Sets the winner if one of the teams has been annihilated. - * - * @return whether or not a winner was set - */ - public boolean setWinnerIfAnnihilated() { - int robotCountA = objectInfo.getRobotCount(Team.A); - int robotCountB = objectInfo.getRobotCount(Team.B); - if (robotCountA == 0) { - setWinner(Team.B, DominationFactor.ANNIHILATED); - return true; - } else if (robotCountB == 0) { - setWinner(Team.A, DominationFactor.ANNIHILATED); - return true; - } - return false; - } - /** * @return whether a team has more archons */ public boolean setWinnerIfMoreArchons() { - int archonCountA = objectInfo.getRobotTypeCount(Team.A, RobotType.ARCHON); - int archonCountB = objectInfo.getRobotTypeCount(Team.B, RobotType.ARCHON); + int archonCountA = this.objectInfo.getRobotTypeCount(Team.A, RobotType.ARCHON); + int archonCountB = this.objectInfo.getRobotTypeCount(Team.B, RobotType.ARCHON); if (archonCountA > archonCountB) { setWinner(Team.A, DominationFactor.MORE_ARCHONS); @@ -401,7 +386,8 @@ public void processEndOfRound() { this.lead[i] += GameConstants.ADD_LEAD; // Add lead resources to the team - teamInfo.changeLead(teamInfo.getLead() + GameConstants.PASSIVE_LEAD_INCREASE); + this.teamInfo.addLead(Team.A, GameConstants.PASSIVE_LEAD_INCREASE); + this.teamInfo.addLead(Team.B, GameConstants.PASSIVE_LEAD_INCREASE); // Process end of each robot's round objectInfo.eachRobot((robot) -> { @@ -421,7 +407,6 @@ public void processEndOfRound() { } // Check for end of match - setWinnerIfAnnihilated(); if (timeLimitReached() && gameStats.getWinner() == null) if (!setWinnerIfMoreArchons()) if (!setWinnerIfMoreGoldValue()) @@ -457,6 +442,8 @@ public int spawnRobot(RobotType type, MapLocation location, Team team) { public void destroyRobot(int id) { InternalRobot robot = objectInfo.getRobotByID(id); + RobotType type = robot.getType(); + Team team = robot.getTeam(); removeRobot(robot.getLocation()); int leadDropped = robot.getType().getLeadDropped(robot.getLevel()); @@ -468,6 +455,10 @@ public void destroyRobot(int id) { controlProvider.robotKilled(robot); objectInfo.destroyRobot(id); + // this happens here because both teams' Archons can die in the same round + if (type == RobotType.ARCHON && this.objectInfo.getRobotTypeCount(team, RobotType.ARCHON) == 0) + setWinner(1 - team, DominationFactor.ANNIHILATION); + matchMaker.addDied(id); } @@ -529,9 +520,12 @@ public void causeAbyssSage(InternalRobot robot) { */ public void causeAbyssGlobal() { this.causeAbyssGridUpdate(AnomalyType.ABYSS.globalPercentage, this.getAllLocations()); - // change team resources - teamInfo.changeLead((int) (-1 * AnomalyType.ABYSS.globalPercentage * teamInfo.getLead())); - teamInfo.changeGold((int) (-1 * AnomalyType.ABYSS.globalPercentage * teamInfo.getGold())); + + this.teamInfo.addLead(Team.A, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getLead(Team.A))); + this.teamInfo.addLead(Team.B, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getLead(Team.B))); + + this.teamInfo.addGold(Team.A, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.A))); + this.teamInfo.addGold(Team.B, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.B))); } /** diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index c67efb69..b32412a1 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -12,7 +12,6 @@ public class TeamInfo { private GameWorld gameWorld; - private int[] archonCounts; private int[] leadCounts; private int[] goldCounts; @@ -21,10 +20,8 @@ public class TeamInfo { * * @param gameWorld the gameWorld the teams exist in */ - public TeamInfo(GameWorld gameWorld, int numArchons) { + public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; - this.archonCount = new int[2]; - Arrays.fill(this.archonCount, numArchons); this.leadCount = new int[2]; this.goldCount = new int[2]; } @@ -33,16 +30,6 @@ public TeamInfo(GameWorld gameWorld, int numArchons) { // ***** GETTER METHODS ************ // ********************************* - /** - * Get the number of remaining Archons. - * - * @param team the team to query - * @return the number of archons remaining - */ - public int getArchonCount(Team team) { - return this.archonCount[team.ordinal()]; - } - /** * Get the amount of lead. * @@ -67,19 +54,6 @@ public int getGold(Team team) { // ***** UPDATE METHODS ************ // ********************************* - /** - * Decrease the number of Archons. - * - * @param team the team to query - * @throws IllegalArgumentException if the new Archon count goes below 0 - */ - public void decreaseArchonCount(Team team) throws IllegalArgumentException { - if (this.archonCount[team.ordinal()] == 0) { - throw new IllegalArgumentException("Invalid archon count"); - } - this.archonCount[team.ordinal()]--; - } - /** * Add to the amount of lead. If amount is negative, subtract from lead instead. * From 7d1a8f7989b3f619d9446807d2d62eddb736f498 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:30:00 -0600 Subject: [PATCH 147/413] updated win conditions on Server.java --- engine/src/main/battlecode/server/Server.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/engine/src/main/battlecode/server/Server.java b/engine/src/main/battlecode/server/Server.java index 2e1c6b22..b098bb42 100644 --- a/engine/src/main/battlecode/server/Server.java +++ b/engine/src/main/battlecode/server/Server.java @@ -360,17 +360,17 @@ public String getWinnerString(GameInfo game, Team winner, int roundNumber) { DominationFactor dom = stats.getDominationFactor(); switch (dom) { - case ANNIHILATED: - sb.append("The winning team won by annihilating the enemy team."); + case ANNIHILATION: + sb.append("The winning team won by annihilating the enemy team's Archons."); break; - case MORE_VOTES: - sb.append("The winning team won by having more votes."); + case MORE_ARCHONS: + sb.append("The winning team won by having more Archons."); break; - case MORE_ENLIGHTENMENT_CENTERS: - sb.append("The winning team won on tiebreakers (more Enlightenment Centers)."); + case MORE_GOLD_NET_WORTH: + sb.append("The winning team won on tiebreakers (more gold net worth)."); break; - case MORE_INFLUENCE: - sb.append("The winning team won on tiebreakers (more total unit influence)."); + case MORE_LEAD_NET_WORTH: + sb.append("The winning team won on tiebreakers (more lead net worth)."); break; case WON_BY_DUBIOUS_REASONS: sb.append("The winning team won arbitrarily (coin flip)."); From 070904278fae2f6ce3d5bf8fd9c17a4588a43407 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:32:02 -0600 Subject: [PATCH 148/413] update comment --- engine/src/main/battlecode/common/RobotController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 0fb3cfbf..c35e64d1 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -26,7 +26,7 @@ public strictfp interface RobotController { int getRoundNum(); /** - * Returns the number of robots on your team, including Centers of Enlightenment. + * Returns the number of robots on your team, including Archons. * If this number ever reaches zero, you immediately lose. * * @return the number of robots on your team From bb6361e4c8aac35c977fdc4d057938f7131b8547 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:32:40 -0600 Subject: [PATCH 149/413] remove TODO: getNetWorth? --- engine/src/main/battlecode/common/RobotController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index c35e64d1..4dc1545e 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -45,10 +45,6 @@ public strictfp interface RobotController { */ int getArchonCount(); - // TODO: getNetWorth() - // is this desired?? - - // ********************************* // ****** UNIT QUERY METHODS ******* // ********************************* From 25c001d01ec52797f7883738a55deb3247470189 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:46:21 -0600 Subject: [PATCH 150/413] added vision methods to InternalRobot --- .../main/battlecode/world/InternalRobot.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index a7f3a953..ff70c22e 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -187,10 +187,10 @@ public int getActionRadiusSquared() { /** * Returns whether this robot can perform actions on the given location. * - * @param toSense the MapLocation to act + * @param toAct the MapLocation to act */ - public boolean canActLocation(MapLocation toSense) { - return this.location.distanceSquaredTo(toSense) <= getActionRadiusSquared(); + public boolean canActLocation(MapLocation toAct) { + return this.location.distanceSquaredTo(toAct) <= getActionRadiusSquared(); } /** @@ -202,6 +202,31 @@ public boolean canActRadiusSquared(int radiusSquared) { return radiusSquared <= getActionRadiusSquared(); } + /** + * Returns the robot's vision radius squared. + */ + public int getVisionRadiusSquared() { + return this.type.visionRadiusSquared; + } + + /** + * Returns whether this robot can see the given location. + * + * @param toSee the MapLocation to see + */ + public boolean canSeeLocation(MapLocation toSee) { + return this.location.distanceSquaredTo(toSee) <= getVisionRadiusSquared(); + } + + /** + * Returns whether this robot can see a given radius away. + * + * @param radiusSquared the distance squared to act + */ + public boolean canSeeRadiusSquared(int radiusSquared) { + return radiusSquared <= getVisionRadiusSquared(); + } + // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** From 160a1c7f4228ecdda258172f14e9424e4a4d6608 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 16:54:06 -0600 Subject: [PATCH 151/413] style fixes --- .../battlecode/common/RobotController.java | 137 ++++++++++-------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 4dc1545e..205b7590 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -19,7 +19,7 @@ public strictfp interface RobotController { * match. * * @return the current round number, where round 1 is the first round of the - * match. + * match * * @battlecode.doc.costlymethod */ @@ -52,7 +52,7 @@ public strictfp interface RobotController { /** * Returns the ID of this robot. * - * @return the ID of this robot. + * @return the ID of this robot * * @battlecode.doc.costlymethod */ @@ -61,7 +61,7 @@ public strictfp interface RobotController { /** * Returns this robot's Team. * - * @return this robot's Team. + * @return this robot's Team * * @battlecode.doc.costlymethod */ @@ -70,7 +70,7 @@ public strictfp interface RobotController { /** * Returns this robot's type (MINER, ARCHON, BUILDER, etc.). * - * @return this robot's type. + * @return this robot's type * * @battlecode.doc.costlymethod */ @@ -79,7 +79,7 @@ public strictfp interface RobotController { /** * Returns this robot's current location. * - * @return this robot's current location. + * @return this robot's current location * * @battlecode.doc.costlymethod */ @@ -88,7 +88,7 @@ public strictfp interface RobotController { /** * Returns this robot's current health. * - * @return this robot's current health. + * @return this robot's current health * * @battlecode.doc.costlymethod */ @@ -97,11 +97,11 @@ public strictfp interface RobotController { /** * Returns this robot's current level. * - * @return this robot's current level. + * @return this robot's current level * * @battlecode.doc.costlymethod */ - int getUpgradeLevel(); + int getLevel(); // *********************************** // ****** GENERAL VISION METHODS ***** @@ -112,8 +112,8 @@ public strictfp interface RobotController { * the location is not within the vision range. * * @param loc the location to check - * @return true if the location is on the map; false otherwise. - * @throws GameActionException if the location is not within vision range. + * @return true if the location is on the map; false otherwise + * @throws GameActionException if the location is not within vision range * * @battlecode.doc.costlymethod */ @@ -123,7 +123,7 @@ public strictfp interface RobotController { * Checks whether the given location is within the robot's vision range, and if it is on the map. * * @param loc the location to check - * @return true if the given location is within the robot's vision range and is on the map; false otherwise. + * @return true if the given location is within the robot's vision range and is on the map; false otherwise * * @battlecode.doc.costlymethod */ @@ -133,7 +133,7 @@ public strictfp interface RobotController { * Checks whether a point at the given radius squared is within the robot's vision range. * * @param radiusSquared the radius to check - * @return true if the given radius is within the robot's vision range; false otherwise. + * @return true if the given radius is within the robot's vision range; false otherwise * * @battlecode.doc.costlymethod */ @@ -143,8 +143,8 @@ public strictfp interface RobotController { * Checks whether a robot is at a given location. Assumes the location is valid. * * @param loc the location to check - * @return true if a robot is at the location. - * @throws GameActionException if the location is not within vision range or on the map. + * @return true if a robot is at the location + * @throws GameActionException if the location is not within vision range or on the map * * @battlecode.doc.costlymethod */ @@ -155,8 +155,8 @@ public strictfp interface RobotController { * there. * * @param loc the location to check - * @return the robot at the given location. - * @throws GameActionException if the location is not within vision range. + * @return the robot at the given location + * @throws GameActionException if the location is not within vision range * * @battlecode.doc.costlymethod */ @@ -168,7 +168,7 @@ public strictfp interface RobotController { * * @param id the ID of the robot to query * @return true if the given robot is within this robot's vision range and exists; - * false otherwise. + * false otherwise * * @battlecode.doc.costlymethod */ @@ -178,9 +178,9 @@ public strictfp interface RobotController { * Sees information about a particular robot given its ID. * * @param id the ID of the robot to query - * @return a RobotInfo object for the seen robot. + * @return a RobotInfo object for the seen robot * @throws GameActionException if the robot cannot be seen (for example, - * if it doesn't exist or is out of vision range). + * if it doesn't exist or is out of vision range) * * @battlecode.doc.costlymethod */ @@ -191,7 +191,7 @@ public strictfp interface RobotController { * particular order. * * @return array of RobotInfo objects, which contain information about all - * the robots you saw. + * the robots you saw * * @battlecode.doc.costlymethod */ @@ -202,10 +202,10 @@ public strictfp interface RobotController { * robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within vision radius are returned. + * this robot; if -1 is passed, all robots within vision radius are returned; * if radiusSquared is larger than the robot's vision radius, the vision - * radius is used. - * @return array of RobotInfo objects of all the robots you saw. + * radius is used + * @return array of RobotInfo objects of all the robots you saw * * @battlecode.doc.costlymethod */ @@ -216,12 +216,12 @@ public strictfp interface RobotController { * distance of this robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within vision radius are returned. + * this robot; if -1 is passed, all robots within vision radius are returned; * if radiusSquared is larger than the robot's vision radius, the vision - * radius is used. - * @param team filter game objects by the given team. If null is passed, + * radius is used + * @param team filter game objects by the given team; if null is passed, * robots from any team are returned - * @return array of RobotInfo objects of all the robots you saw. + * @return array of RobotInfo objects of all the robots you saw * * @battlecode.doc.costlymethod */ @@ -234,12 +234,12 @@ public strictfp interface RobotController { * * @param center center of the given search radius * @param radiusSquared return robots this distance away from the center of - * this robot. If -1 is passed, all robots within vision radius are returned. + * this robot; if -1 is passed, all robots within vision radius are returned; * if radiusSquared is larger than the robot's vision radius, the vision - * radius is used. - * @param team filter game objects by the given team. If null is passed, + * radius is used + * @param team filter game objects by the given team; if null is passed, * objects from all teams are returned - * @return sorted array of RobotInfo objects of the robots you saw. + * @return sorted array of RobotInfo objects of the robots you saw * * @battlecode.doc.costlymethod */ @@ -252,7 +252,7 @@ public strictfp interface RobotController { * greater cooldowns for making actions. * * @param loc the given location - * @return the rubble of that location. + * @return the rubble of that location * @throws GameActionException if the robot cannot sense the given location * * @battlecode.doc.costlymethod @@ -263,7 +263,7 @@ public strictfp interface RobotController { * Given a location, returns the lead count of that location. * * @param loc the given location - * @return the amount of lead at that location. + * @return the amount of lead at that location * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod @@ -274,7 +274,7 @@ public strictfp interface RobotController { * Given a location, returns the gold count of that location. * * @param loc the given location - * @return the amount of gold at that location. + * @return the amount of gold at that location * @throws GameActionException if the robot cannot see the given location * * @battlecode.doc.costlymethod @@ -285,7 +285,7 @@ public strictfp interface RobotController { * Returns the location adjacent to current location in the given direction. * * @param dir the given direction - * @return the location adjacent to current location in the given direction. + * @return the location adjacent to current location in the given direction * * @battlecode.doc.costlymethod */ @@ -299,7 +299,7 @@ public strictfp interface RobotController { * Tests whether the robot can act. Returns * getCooldownTurns() < 1. * - * @return true if the robot can act. + * @return true if the robot can act * * @battlecode.doc.costlymethod */ @@ -310,7 +310,7 @@ public strictfp interface RobotController { * When this number is strictly less than 1, isActionReady() is true and the robot * can act again. * - * @return the number of action turns remaining before this unit can act again. + * @return the number of action turns remaining before this unit can act again * * @battlecode.doc.costlymethod */ @@ -320,7 +320,7 @@ public strictfp interface RobotController { * Tests whether the robot can move. Returns * getCooldownTurns() < 1. * - * @return true if the robot can move. + * @return true if the robot can move * * @battlecode.doc.costlymethod */ @@ -331,7 +331,7 @@ public strictfp interface RobotController { * When this number is strictly less than 1, isMovementReady() is true and the robot * can move again. * - * @return the number of cooldown turns remaining before this unit can move again. + * @return the number of cooldown turns remaining before this unit can move again * * @battlecode.doc.costlymethod */ @@ -361,7 +361,7 @@ public strictfp interface RobotController { * @throws GameActionException if the robot cannot move one step in this * direction, such as cooldown being >= 1, the target location being * off the map, or the target destination being occupied by - * another robot. + * another robot * * @battlecode.doc.costlymethod */ @@ -382,7 +382,7 @@ public strictfp interface RobotController { * @param type the type of robot to build * @param dir the direction to build in * @return whether it is possible to build a robot of the given type in the - * given direction. + * given direction * * @battlecode.doc.costlymethod */ @@ -394,7 +394,7 @@ public strictfp interface RobotController { * @param type the type of robot to build * @param dir the direction to spawn the unit * @throws GameActionException if the conditions of canBuildRobot - * are not all satisfied. + * are not all satisfied * * @battlecode.doc.costlymethod */ @@ -412,7 +412,7 @@ public strictfp interface RobotController { * enemy unit exists in the given square, and there are no cooldown turns remaining. * * @param loc target location to attack - * @return whether it is possible to attack the given location. + * @return whether it is possible to attack the given location * * @battlecode.doc.costlymethod */ @@ -423,7 +423,7 @@ public strictfp interface RobotController { * * @throws GameActionException if conditions for attacking are not satisfied * - * @battlecode.doc.costlymethod + * @battlecode.doc.costlymethod */ void attack(MapLocation loc) throws GameActionException; @@ -436,7 +436,7 @@ public strictfp interface RobotController { * * Checks that the robot is a sage, and there are no cooldown turns remaining. * - * @return whether it is possible to use an anomaly centered at the robots location. + * @return whether it is possible to use an anomaly centered at the robots location * * @battlecode.doc.costlymethod */ @@ -447,7 +447,7 @@ public strictfp interface RobotController { * * @throws GameActionException if conditions for using anomaly are not satisfied * - * @battlecode.doc.costlymethod + * @battlecode.doc.costlymethod */ void useAnomaly(AnomalyType anomaly) throws GameActionException; @@ -462,8 +462,8 @@ public strictfp interface RobotController { * is within the robot's action radius. Also checks that a friendly droid * exists in the given square, and there are no cooldown turns remaining. * - * @param loc target location to heal at - * @return whether it is possible to heal a droid robot at the given location. + * @param loc target location to heal at + * @return whether it is possible to heal a droid robot at the given location * * @battlecode.doc.costlymethod */ @@ -473,7 +473,8 @@ public strictfp interface RobotController { * Heals at a given location. * * @throws GameActionException if conditions for healing are not satisfied - * @battlecode.doc.costlymethod + * + * @battlecode.doc.costlymethod */ void healDroid(MapLocation loc) throws GameActionException; @@ -490,7 +491,7 @@ public strictfp interface RobotController { * have positive lead amounts. Also checks that no cooldown turns remain. * * @param loc target location to mine - * @return whether it is possible to mine at the given location. + * @return whether it is possible to mine at the given location * * @battlecode.doc.costlymethod */ @@ -514,7 +515,7 @@ public strictfp interface RobotController { * have positive gold amounts. Also checks that no cooldown turns remain. * * @param loc target location to mine - * @return whether it is possible to mine at the given location. + * @return whether it is possible to mine at the given location * * @battlecode.doc.costlymethod */ @@ -542,7 +543,7 @@ public strictfp interface RobotController { * affordable, and there must be no cooldown turns remaining. * * @param loc target location to upgrade - * @return whether it is possible to upgrade at the given location. + * @return whether it is possible to upgrade at the given location * * @battlecode.doc.costlymethod */ @@ -565,7 +566,7 @@ public strictfp interface RobotController { * is a building exists in the given square, and no cooldown turns remain. * * @param loc target location to repair building at - * @return whether it is possible to repair a building at the given location. + * @return whether it is possible to repair a building at the given location * * @battlecode.doc.costlymethod */ @@ -597,7 +598,9 @@ public strictfp interface RobotController { boolean canConvert(); /** - * Get lead to gold conversion rate. Returns 0 if robot is not a lab. + * Get lead to gold conversion rate. + * + * @return the lead to gold conversion rate, 0 if the robot is not a lab * * @battlecode.doc.costlymethod */ @@ -607,6 +610,7 @@ public strictfp interface RobotController { * Convert lead into gold. * * @throws GameActionException if conditions for converting are not satisfied + * * @battlecode.doc.costlymethod */ void convert() throws GameActionException; @@ -687,6 +691,13 @@ public strictfp interface RobotController { // ****** OTHER ACTION METHODS ******* // *********************************** + /** + * @return the anomaly schedule + * + * @battlecode.doc.costlymethod + */ + AnomalyScheduleEntry[] getAnomalySchedule(); + /** * Destroys the robot. * @@ -708,10 +719,10 @@ public strictfp interface RobotController { /** * Draw a dot on the game map for debugging purposes. * - * @param loc the location to draw the dot. - * @param red the red component of the dot's color. - * @param green the green component of the dot's color. - * @param blue the blue component of the dot's color. + * @param loc the location to draw the dot + * @param red the red component of the dot's color + * @param green the green component of the dot's color + * @param blue the blue component of the dot's color * * @battlecode.doc.costlymethod */ @@ -720,11 +731,11 @@ public strictfp interface RobotController { /** * Draw a line on the game map for debugging purposes. * - * @param startLoc the location to draw the line from. - * @param endLoc the location to draw the line to. - * @param red the red component of the line's color. - * @param green the green component of the line's color. - * @param blue the blue component of the line's color. + * @param startLoc the location to draw the line from + * @param endLoc the location to draw the line to + * @param red the red component of the line's color + * @param green the green component of the line's color + * @param blue the blue component of the line's color * * @battlecode.doc.costlymethod */ From c38990a8fe20d888c4b35fa2feac83cfd5f201ae Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 19:49:01 -0600 Subject: [PATCH 152/413] various changes, RobotControllerImpl up including mining --- .../battlecode/common/RobotController.java | 113 +++---- .../src/main/battlecode/common/RobotMode.java | 16 +- .../src/main/battlecode/common/RobotType.java | 36 +- .../main/battlecode/world/InternalRobot.java | 18 +- .../battlecode/world/RobotControllerImpl.java | 308 ++++++------------ 5 files changed, 204 insertions(+), 287 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 205b7590..c27e73a1 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -296,8 +296,7 @@ public strictfp interface RobotController { // *********************************** /** - * Tests whether the robot can act. Returns - * getCooldownTurns() < 1. + * Tests whether the robot can act. * * @return true if the robot can act * @@ -307,8 +306,9 @@ public strictfp interface RobotController { /** * Returns the number of action cooldown turns remaining before this unit can act again. - * When this number is strictly less than 1, isActionReady() is true and the robot - * can act again. + * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isActionReady() + * is true and the robot can act again. This number decreases by + * GameConstants.COOLDOWNS_PER_TURN every turn. * * @return the number of action turns remaining before this unit can act again * @@ -317,8 +317,7 @@ public strictfp interface RobotController { double getActionCooldownTurns(); /** - * Tests whether the robot can move. Returns - * getCooldownTurns() < 1. + * Tests whether the robot can move. * * @return true if the robot can move * @@ -328,8 +327,9 @@ public strictfp interface RobotController { /** * Returns the number of movement cooldown turns remaining before this unit can move again. - * When this number is strictly less than 1, isMovementReady() is true and the robot - * can move again. + * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isMovementReady() + * is true and the robot can move again. This number decreases by + * GameConstants.COOLDOWNS_PER_TURN every turn. * * @return the number of cooldown turns remaining before this unit can move again * @@ -337,15 +337,39 @@ public strictfp interface RobotController { */ double getMovementCooldownTurns(); + /** + * Tests whether the robot can transform. + * + * Checks if the robot's mode is TURRET or PORTABLE. Also checks action + * or movement cooldown turns, depending on the robot's current mode. + * + * @return true if the robot can transform + * + * @battlecode.doc.costlymethod + */ + boolean isTransformReady(); + + /** + * Returns the number of cooldown turns remaining before this unit can transform again. + * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isTransformReady() + * is true and the robot can transform again. This number decreases by + * GameConstants.COOLDOWNS_PER_TURN every turn. + * + * @return the number of cooldown turns remaining before this unit can transform again + * + * @battlecode.doc.costlymethod + */ + double getTransformCooldownTurns(); + // *********************************** // ****** MOVEMENT METHODS *********** // *********************************** /** * Checks whether this robot can move one step in the given direction. - * Returns false if the robot is a building, if the target location is not - * on the map, if the target location is occupied, or if there are cooldown - * turns remaining. + * Returns false if the robot is not in a mode that can move, if the target + * location is not on the map, if the target location is occupied, or if + * there are cooldown turns remaining. * * @param dir the direction to move in * @return true if it is possible to call move without an exception @@ -359,9 +383,8 @@ public strictfp interface RobotController { * * @param dir the direction to move in * @throws GameActionException if the robot cannot move one step in this - * direction, such as cooldown being >= 1, the target location being - * off the map, or the target destination being occupied by - * another robot + * direction, such as cooldown being too high, the target location being + * off the map, or the target destination being occupied by another robot * * @battlecode.doc.costlymethod */ @@ -432,51 +455,52 @@ public strictfp interface RobotController { // ***************************** /** - * Tests whether this robot can use an anomaly centered at the robot's location. + * Tests whether this robot can envision an anomaly centered at the robot's location. * * Checks that the robot is a sage, and there are no cooldown turns remaining. * - * @return whether it is possible to use an anomaly centered at the robots location + * @return whether it is possible to envision an anomaly centered at the robots location * * @battlecode.doc.costlymethod */ - boolean canUseAnomaly(AnomalyType anomaly); + boolean canEnvision(AnomalyType anomaly); /** - * Use anomaly centered at robots location. + * Envision an anomaly centered at the robot's location. * - * @throws GameActionException if conditions for using anomaly are not satisfied + * @throws GameActionException if conditions for envisioning are not satisfied * * @battlecode.doc.costlymethod */ - void useAnomaly(AnomalyType anomaly) throws GameActionException; + void envision(AnomalyType anomaly) throws GameActionException; // ***************************** - // ****** ARCHON METHODS ****** + // ****** REPAIR METHODS ****** // ***************************** /** - * Tests whether this robot can heal a droid at the given location. + * Tests whether this robot can repair a robot at the given location. * - * Checks that the robot is an archon unit and that the given location - * is within the robot's action radius. Also checks that a friendly droid - * exists in the given square, and there are no cooldown turns remaining. + * Checks that the robot can repair other units and that the given location + * is within the robot's action radius. Also checks that a friendly unit + * of a repairable type exists in the given square, and there are no + * cooldown turns remaining. * - * @param loc target location to heal at - * @return whether it is possible to heal a droid robot at the given location + * @param loc target location to repair at + * @return whether it is possible to repair a robot at the given location * * @battlecode.doc.costlymethod */ - boolean canHealDroid(MapLocation loc); + boolean canRepair(MapLocation loc); /** - * Heals at a given location. + * Repairs at a given location. * - * @throws GameActionException if conditions for healing are not satisfied + * @throws GameActionException if conditions for repairing are not satisfied * * @battlecode.doc.costlymethod */ - void healDroid(MapLocation loc) throws GameActionException; + void repair(MapLocation loc) throws GameActionException; // *********************** // **** MINER METHODS **** @@ -485,7 +509,7 @@ public strictfp interface RobotController { /** * Tests whether the robot can mine lead at a given location. * - * Checks that the robot is a Miner, that the given location is a valid + * Checks that the robot is a Miner, and the given location is a valid * mining location. Valid mining locations must be the current location * or adjacent to the current location. Valid mining locations must also * have positive lead amounts. Also checks that no cooldown turns remain. @@ -531,7 +555,7 @@ public strictfp interface RobotController { void mineGold(MapLocation loc) throws GameActionException; // ************************* - // **** BUILDER METHODS **** + // **** UPGRADE METHODS **** // ************************* /** @@ -558,29 +582,6 @@ public strictfp interface RobotController { */ void upgrade(MapLocation loc) throws GameActionException; - /** - * Tests whether this robot can repair a building at the given location. - * - * Checks that the robot is a builder unit and that the given location is - * within the robot's action radius. Also checks that a friendly unit which - * is a building exists in the given square, and no cooldown turns remain. - * - * @param loc target location to repair building at - * @return whether it is possible to repair a building at the given location - * - * @battlecode.doc.costlymethod - */ - boolean canRepairBuilding(MapLocation loc); - - /** - * Repairs building at a given location. - * - * @throws GameActionException if conditions for repairing building are not satisfied - * - * @battlecode.doc.costlymethod - */ - void repairBuilding(MapLocation loc) throws GameActionException; - // ******************************* // **** ALCHEMIST LAB METHODS **** // ******************************* diff --git a/engine/src/main/battlecode/common/RobotMode.java b/engine/src/main/battlecode/common/RobotMode.java index bc0f2870..198147d3 100644 --- a/engine/src/main/battlecode/common/RobotMode.java +++ b/engine/src/main/battlecode/common/RobotMode.java @@ -5,16 +5,18 @@ */ public enum RobotMode { - DROID (true, true), - PROTOTYPE (false, false), - TURRET (true, false), - PORTABLE (false, true); + DROID (true, true, false), + PROTOTYPE (false, false, false), + TURRET (true, false, true), + PORTABLE (false, true, true); public final boolean canAct; public final boolean canMove; + public final boolean canTransform; - RobotMode(boolean canAct, boolean canMove) { - this.canAct = canAct; - this.canMove = canMove; + RobotMode(boolean canAct, boolean canMove, boolean canTransform) { + this.canAct = canAct; + this.canMove = canMove; + this.canTransform = canTransform; } } \ No newline at end of file diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 7697a6f5..0cfb254a 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -46,14 +46,14 @@ public enum RobotType { /** * Ranged attacking robot. */ - SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), - // BCL BCG AC MC HP DMG AR VR BL + SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), + // BCL BCG AC MC HP DMG AR VR BL /** * Gold robot, causes Anomalies. */ - SAGE ( 0, 50,200, 25, 45, 100, 13, 20, 10000) - // BCL BCG AC MC HP DMG AR VR BL + SAGE ( 0, 50, 200, 25, 45, 100, 13, 20, 10000) + // BCL BCG AC MC HP DMG AR VR BL ; /** @@ -116,15 +116,6 @@ public int getVisionRadiusSquared(int level) { return this.visionRadiusSquared; } - /** - * @return whether this type can attack - */ - public boolean canAttack() { - return (this == WATCHTOWER - || this == SOLDIER - || this == SAGE); - } - /** * @param builtType type of robot being built * @return whether this type can build the given robot type @@ -138,10 +129,27 @@ public boolean canBuild(RobotType builtType) { builtType == WATCHTOWER)); } + /** + * @return whether this type can attack + */ + public boolean canAttack() { + return (this == WATCHTOWER + || this == SOLDIER); + } + + /** + * @param repairedType type of robot being repaired + * @return whether this type can repair the given robot type + */ + public boolean canRepair(RobotType repairedType) { + return (this == ARCHON && !builtType.isBuilding() || + this == BUILDER && builtType.isBuilding()); + } + /** * @return whether this type can anomalies */ - public boolean canUseAnomaly() { + public boolean canEnvision() { return this == SAGE; } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index ff70c22e..f35ee1f7 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -133,6 +133,14 @@ public int getMovementCooldownTurns() { return movementCooldownTurns; } + public int getTransformCooldownTurns() { + if (this.mode == RobotMode.TURRET) + return this.actionCooldownTurns; + if (this.mode == RobotMode.PORTABLE) + return this.movementCooldownTurns; + return -1; + } + public RobotInfo getRobotInfo() { if (cachedRobotInfo != null && cachedRobotInfo.ID == ID @@ -331,28 +339,20 @@ public void upgrade() { /** * Attacks another robot. Assumes bot is in range. - * Note: this is relatively inefficient(?), can possibly optimize - * by making better helper methods in GameWorld * * @param bot the robot to be attacked */ public void attack(InternalRobot bot) { - if (!this.canActLocation(bot.location)) - return; // TODO: throw exception? int dmg = this.type.getDamage(this.level); bot.addHealth(-dmg); } /** * Heals another robot. Assumes bot is in range. - * Note: this is relatively inefficient(?), can possibly optimize - * by making better helper methods in GameWorld * * @param bot the robot to be healed */ public void heal(InternalRobot bot) { - if (!this.canActLocation(bot.location)) - return; // TODO: throw exception? int healingAmount = this.type.getHealing(this.level); bot.addHealth(healingAmount); } @@ -416,7 +416,7 @@ public void die_exception() { * @return the number of friendly robots within sensor (vision) radius. */ public int updateNumVisibleFriendlyRobots() { - return this.numVisibleFriendlyRobots = this.controller.getNumVisibleFriendlyRobots(); + return this.numVisibleFriendlyRobots = this.controller.seeNearbyRobots(-1, getTeam()).length; } @Override diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 297092db..0c8cd0ea 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -65,7 +65,7 @@ private static void assertNotNull(Object o) { @Override public int hashCode() { - return robot.getID(); + return this.robot.getID(); } // ********************************* @@ -74,18 +74,17 @@ public int hashCode() { @Override public int getRoundNum() { - return gameWorld.getCurrentRound(); + return this.gameWorld.getCurrentRound(); } @Override public int getRobotCount() { - return gameWorld.getObjectInfo().getRobotCount(getTeam()); + return this.gameWorld.getObjectInfo().getRobotCount(getTeam()); } @Override public int getArchonCount() { - // TODO: Assumes getArchons() exists in TeamInfo - return gameWorld.getTeamInfo().getArchons(); + return this.gameWorld.getTeamInfo().getArchonCount(getTeam()); } // ********************************* @@ -118,8 +117,8 @@ public int getHealth() { } @Override - public int getUpgradeLevel() { - return this.robot.getUpgradeLevel(); + public int getLevel() { + return this.robot.getLevel(); } private InternalRobot getRobotByID(int id) { @@ -128,14 +127,6 @@ private InternalRobot getRobotByID(int id) { return this.gameWorld.getObjectInfo().getRobotByID(id); } - /** - * Returns a fully copied version of the anomaly schedule. - */ - public AnomalyScheduleEntry[] getAnomalySchedule() { - this.gameWorld.getAnomalySchedule(); - } - - // *********************************** // ****** GENERAL VISION METHODS ***** // *********************************** @@ -181,10 +172,8 @@ public boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException @Override public RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException { assertCanSeeLocation(loc); - InternalRobot bot = gameWorld.getRobot(loc); - if (bot != null) - return bot.getRobotInfo(getType().canTrueSense()); - return null; + InternalRobot bot = this.gameWorld.getRobot(loc); + return bot == null ? null : bot.getRobotInfo(); } @Override @@ -197,8 +186,8 @@ public boolean canSeeRobot(int id) { public RobotInfo seeRobot(int id) throws GameActionException { if (!canSeeRobot(id)) throw new GameActionException(CANT_SENSE_THAT, - "Can't see given robot; It may not exist anymore"); - return getRobotByID(id).getRobotInfo(getType().canTrueSense()); + "Can't see given robot; It may be out of vision range or not exist anymore"); + return getRobotByID(id).getRobotInfo(); } @Override @@ -232,24 +221,14 @@ public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team t // check if right team if (team != null && seenRobot.getTeam() != team) continue; - validSeenRobots.add(seenRobot.getRobotInfo(getType().canTrueSense())); + validSeenRobots.add(seenRobot.getRobotInfo()); } return validSeenRobots.toArray(new RobotInfo[validSeenRobots.size()]); } - /** - * @return the number of friendly robots within sensor (vision) radius. - */ - public int getNumVisibleFriendlyRobots() { - return this.seeNearbyRobots( - this.robot.getVisionRadiusSquared(), - this.robot.getTeam() - ).length; - } - @Override public int seeRubble(MapLocation loc) throws GameActionException { - assertCanSenseLocation(loc); + assertCanSeeLocation(loc); return this.gameWorld.getRubble(loc); } @@ -279,20 +258,14 @@ private boolean isLocationOccupied(MapLocation loc) throws GameActionException { } private void assertIsActionReady() throws GameActionException { - if (getActionCooldownTurns() >= 1) - throw new GameActionException(IS_NOT_READY, - "This robot's action cooldown has not expired."); - if (!robot.getMode().canAct) + if (!this.robot.getMode().canAct) throw new GameActionException(CANT_DO_THAT, "This robot is not in a mode that can act."); + if (!this.robot.canActCooldown()) + throw new GameActionException(IS_NOT_READY, + "This robot's action cooldown has not expired."); } - /** - * Check if the robot is ready to perform an action. Returns true if - * the current action cooldown counter is strictly less than 1. - * - * @return true if the robot can do an action, false otherwise - */ @Override public boolean isActionReady() { try { @@ -301,31 +274,20 @@ public boolean isActionReady() { } catch (GameActionException e) { return false; } } - /** - * Return the action cooldown turn counter of the robot. If this is < 1, the robot - * can perform an action; otherwise, it cannot. - * The counter is decreased by 1 at the start of every - * turn, and increased to varying degrees by different actions taken. - * - * @return the number of action cooldown turns as a float - */ @Override public double getActionCooldownTurns() { return this.robot.getActionCooldownTurns(); } private void assertIsMovementReady() throws GameActionException { - if (getMovementCooldownTurns() >= 1) + if (!this.robot.getMode().canMove) + throw new GameActionException(CANT_DO_THAT, + "This robot is not in a mode that can move."); + if (!this.robot.canMoveCooldown()) throw new GameActionException(IS_NOT_READY, "This robot's movement cooldown has not expired."); } - /** - * Check if the robot is ready to move. Returns true if - * the current movement cooldown counter is strictly less than 1. - * - * @return true if the robot can move, false otherwise - */ @Override public boolean isMovementReady() { try { @@ -334,19 +296,34 @@ public boolean isMovementReady() { } catch (GameActionException e) { return false; } } - /** - * Return the movement cooldown turn counter of the robot. If this is < 1, the robot - * can move; otherwise, it cannot. - * The counter is decreased by 1 at the start of every - * turn, and increased by moving. - * - * @return the number of cooldown movement turns as a float - */ @Override public double getMovementCooldownTurns() { return this.robot.getMovementCooldownTurns(); } + private void assertIsTransformReady() throws GameActionException { + if (!this.robot.getMode().canTransform) + throw new GameActionException(CANT_DO_THAT, + "This robot is not in a mode that can transform."); + if (!this.robot.canTransformCooldown()) + throw new GameActionException(IS_NOT_READY, + "This robot's transform cooldown (either action or movement + cooldown, depending on its current mode) has not expired."); + } + + @Override + public boolean isTransformReady() { + try { + assertIsTransformReady(); + return true; + } catch (GameActionException e) { return false; } + } + + @Override + public double getTransformCooldownTurns() { + return this.robot.getTransformCooldownTurns(); + } + // *********************************** // ****** MOVEMENT METHODS *********** // *********************************** @@ -354,9 +331,6 @@ public double getMovementCooldownTurns() { private void assertCanMove(Direction dir) throws GameActionException { assertNotNull(dir); assertIsMovementReady(); - if (robot.getMode().canMove) - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot move."); MapLocation loc = adjacentLocation(dir); if (!onTheMap(loc)) throw new GameActionException(OUT_OF_RANGE, @@ -364,9 +338,6 @@ private void assertCanMove(Direction dir) throws GameActionException { if (isLocationOccupied(loc)) throw new GameActionException(CANT_MOVE_THERE, "Cannot move to an occupied location; " + loc + " is occupied."); - if (!isMovementReady()) - throw new GameActionException(IS_NOT_READY, - "Robot is still cooling down! You need to wait before you can perform another action."); } @Override @@ -398,20 +369,17 @@ private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActio assertIsActionReady(); if (!getType().canBuild(type)) throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot build robots of type" + type + "."); + "Robot is of type " + getType() + " which cannot build robots of type " + type + "."); - // CHECK FUNCTION NAMES FOR GETTING LEAD/GOLD COSTS AND SUPPLIES int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); Team team = getTeam(); - if (gameWorld.getTeamInfo().getLead(team) < leadNeeded) { + if (this.gameWorld.getTeamInfo().getLead(team) < leadNeeded) throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of lead."); - } - if (gameWorld.getTeamInfo().getGold(team) < goldNeeded) { + if (this.gameWorld.getTeamInfo().getGold(team) < goldNeeded) throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of gold."); - } MapLocation spawnLoc = adjacentLocation(dir); if (!onTheMap(spawnLoc)) @@ -430,29 +398,17 @@ public boolean canBuildRobot(RobotType type, Direction dir) { } catch (GameActionException e) { return false; } } - // TODO: CHECK FUNCTION NAMES - // TODO: Change cooldown turns to build turn @Override public void buildRobot(RobotType type, Direction dir) throws GameActionException { assertCanBuildRobot(type, dir); - + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + Team team = getTeam(); int leadNeeded = type.getLeadCost(); int goldNeeded = type.getGoldCost(); - - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); - - Team robotTeam = this.robot.getTeam(); - robotTeam.addLead(-leadNeeded); - robotTeam.addGold(-goldNeeded); - - int robotID = gameWorld.spawnRobot(this.robot, type, adjacentLocation(dir), getTeam()); - - // Undo because setting cooldown is automatically done - // // set cooldown turns here, because not all new robots have cooldown (eg. switching teams) - // InternalRobot newBot = getRobotByID(robotID); - // newBot.setCooldownTurns(type.initialCooldown); - - gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); + this.gameWorld.getTeamInfo().addLead(team, -leadNeeded); + this.gameWorld.getTeamInfo().addGold(team, -goldNeeded); + this.gameWorld.spawnRobot(type, adjacentLocation(dir), team); + this.gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); } // ***************************** @@ -467,8 +423,11 @@ private void assertCanAttack(MapLocation loc) throws GameActionException { "Robot is of type " + getType() + " which cannot attack."); if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, - "Robot can't be attacked because it is out of range."); + "Location can't be attacked because it is out of range."); InternalRobot bot = getRobot(loc); + if (bot == null) + throw new GameActionException(CANT_DO_THAT, + "There is no robot to attack at the target location."); if (bot.getTeam() == getTeam()) throw new GameActionException(CANT_DO_THAT, "Robot is not on the enemy team."); @@ -486,94 +445,85 @@ public boolean canAttack(MapLocation loc) { public void attack(MapLocation loc) throws GameActionException { assertCanAttack(loc); this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); - InternalRobot bot = gameWorld.getRobot(loc); + InternalRobot bot = this.gameWorld.getRobot(loc); this.robot.attack(bot); - int attackedID = bot.getID(); - gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, attackedID); + this.gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, bot.getID()); } // ***************************** // ******** SAGE METHODS ******* // ***************************** - private void assertCanUseAnomaly(AnomalyType anomaly) throws GameActionException { + private void assertCanEnvision(AnomalyType anomaly) throws GameActionException { assertIsActionReady(); - if (!getType().canUseAnomaly()) { + if (!getType().canEnvision()) throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot use anomaly."); - } - if (!anomaly.isSageAnomaly) { + "Robot is of type " + getType() + " which cannot envision."); + if (!anomaly.isSageAnomaly) throw new GameActionException(CANT_DO_THAT, "Sage can not use anomaly of type " + anomaly.toString()); - } } @Override - public boolean canUseAnomaly(AnomalyType anomaly) { + public boolean canEnvision(AnomalyType anomaly) { try { - assertCanUseAnomaly(anomaly); + assertCanEnvision(anomaly); return true; } catch (GameActionException e) { return false; } } @Override - public void useAnomaly(AnomalyType anomaly) throws GameActionException { - assertCanUseAnomaly(anomaly); + public void envision(AnomalyType anomaly) throws GameActionException { + assertCanEnvision(anomaly); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); switch (anomaly) { case ABYSS: - gameWorld.causeAbyssSage(this.robot, anomaly); + this.gameWorld.causeAbyssSage(this.robot, anomaly); case CHARGE: - gameWorld.causeChargeSage(this.robot, anomaly); + this.gameWorld.causeChargeSage(this.robot, anomaly); case FURY: - gameWorld.causeFurySage(this.robot, anomaly); - default: - throw IllegalArgumentException("Anomaly is not of the right type, should not get here"); + this.gameWorld.causeFurySage(this.robot, anomaly); } - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); - gameWorld.getMatchMaker().addAction(getID(), Action.USE_ANOMALY, anomaly); + gameWorld.getMatchMaker().addAction(getID(), Action.ENVISION, anomaly); } // ***************************** - // ****** ARCHON METHODS ******* + // ****** REPAIR METHODS ******* // ***************************** - private void assertCanHealDroid(MapLocation loc) throws GameActionException { + private void assertCanRepair(MapLocation loc) throws GameActionException { assertNotNull(loc); assertIsActionReady(); - if (!getType().canHealDroid()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot heal droids."); - } else if (!this.robot.canActLocation(loc)) { + if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, - "This robot can't be healed because location is out of range."); - } - InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeHealed())) { - throw new GameActionException(CANT_DO_THAT, - "Robot is not of a type that can be healed."); - } - if (bot.getTeam() != getTeam()) { + "The target location is out of range."); + InternalRobot bot = this.gameWorld.getRobot(loc); + if (bot == null) throw new GameActionException(CANT_DO_THAT, - "Robot is not on your team so can't be healed."); - } + "There is no robot to repair at the target location."); + if (!getType().canRepair(bot.getType())) + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot repair robots of type " + bot.getType() + "."); + if (bot.getTeam() != getTeam()) + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be repaired."); } @Override - public boolean canHealDroid(MapLocation loc) { + public boolean canRepair(MapLocation loc) { try { - assertCanHealDroid(loc); + assertCanRepair(loc); return true; } catch (GameActionException e) { return false; } } @Override - public void healDroid(MapLocation loc) throws GameActionException { - assertCanHealDroid(loc); - this.robot.addActionCooldownTurns(GameConstants.HEAL_COOLDOWN); - InternalRobot bot = gameWorld.getRobot(loc); + public void repair(MapLocation loc) throws GameActionException { + assertCanRepair(loc); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + InternalRobot bot = this.gameWorld.getRobot(loc); this.robot.heal(bot); - int healedID = bot.getID(); - gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, healedID); + gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, bot.getID()); } // *********************** @@ -583,18 +533,15 @@ public void healDroid(MapLocation loc) throws GameActionException { private void assertCanMineLead(MapLocation loc) throws GameActionException { assertNotNull(loc); assertIsActionReady(); - if (!getType().canMine()) { + if (!getType().canMine()) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot mine."); - } else if (!this.robot.canActLocation(loc)) { + if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); - } - int leadAmount = gameWorld.getLead(loc); - if (leadAmount < 0) { + if (this.gameWorld.getLead(loc) < 1) throw new GameActionException(CANT_DO_THAT, "Lead amount must be positive to be mined."); - } } @Override @@ -608,28 +555,24 @@ public boolean canMineLead(MapLocation loc) { @Override public void mineLead(MapLocation loc) throws GameActionException { assertCanMineLead(loc); - this.robot.mineLead(loc); - Team robotTeam = this.robot.getTeam(); - robotTeam.addLead(1); this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.gameWorld.setLead(loc, this.gameWorld.getLead(loc) - 1); + this.gameWorld.getTeamInfo().addLead(this.robot.getTeam(), 1); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } private void assertCanMineGold(MapLocation loc) throws GameActionException { assertNotNull(loc); assertIsActionReady(); - if (!getType().canMine()) { + if (!getType().canMine()) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot mine."); - } else if (!this.robot.canActLocation(loc)) { + if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, "This location can't be mined because it is out of range."); - } - int goldAmount = gameWorld.getGold(loc); - if (goldAmount < 0) { + if (this.gameWorld.getGold(loc) < 1) throw new GameActionException(CANT_DO_THAT, "Gold amount must be positive to be mined."); - } } @Override @@ -643,15 +586,14 @@ public boolean canMineGold(MapLocation loc) { @Override public void mineGold(MapLocation loc) throws GameActionException { assertCanMineGold(loc); - this.robot.mineGold(loc); - Team robotTeam = this.robot.getTeam(); - robotTeam.addGold(1); this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.gameWorld.setGold(loc, this.gameWorld.getGold(loc) - 1); + this.gameWorld.getTeamInfo().addGold(this.robot.getTeam(), 1); gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } // ************************* - // **** BUILDER METHODS **** + // **** UPGRADE METHODS **** // ************************* private void assertCanUpgrade(MapLocation loc) throws GameActionException { @@ -713,47 +655,6 @@ public void upgrade(MapLocation loc) throws GameActionException { gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); } - private void assertCanRepairBuilding(MapLocation loc) throws GameActionException { - assertIsActionReady(); - if (!getType().canRepairBuilding()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot repair buildings."); - } else if (!this.robot.canActLocation(loc)) { - throw new GameActionException(OUT_OF_RANGE, - "Robot can't be repaired because it is out of range."); - } - InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeUpgraded())) { - throw new GameActionException(CANT_DO_THAT, - "Robot is not of a type that can be repair."); - } - if (bot.getTeam() != getTeam()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is not on your team so can't be repaired."); - } - } - - @Override - public boolean canRepairBuilding(MapLocation loc) { - try { - assertCanRepairBuilding(loc); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void repairBuilding(MapLocation loc) throws GameActionException { - assertCanRepairBuilding(loc); - InternalRobot bot = gameWorld.getRobot(loc); - - this.robot.heal(bot); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); - - InternalRobot bot = gameWorld.getRobot(loc); - int repairedID = bot.getID(); - gameWorld.getMatchMaker().addAction(getID(), Action.REPAIRED, repairedID); - } - // ******************************* // **** ALCHEMIST LAB METHODS **** // ******************************* @@ -889,6 +790,11 @@ public int getFlag(int id) throws GameActionException { // ****** OTHER ACTION METHODS ******* // *********************************** + @Override + public AnomalyScheduleEntry[] getAnomalySchedule() { + return this.gameWorld.getAnomalySchedule(); + } + @Override public void disintegrate() { throw new RobotDeathException(); From e4a3752e87088344834fe3133e30062f16cd9d95 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 20:05:45 -0600 Subject: [PATCH 153/413] mutate methods --- .../main/battlecode/common/GameConstants.java | 4 +- .../battlecode/common/RobotController.java | 20 ++--- .../src/main/battlecode/common/RobotType.java | 38 ++++++---- .../main/battlecode/world/InternalRobot.java | 28 +++++-- .../battlecode/world/RobotControllerImpl.java | 74 +++++++++---------- 5 files changed, 90 insertions(+), 74 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index cb31e160..9b8bf837 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -71,8 +71,8 @@ public class GameConstants { /** The number of cooldown turns per transformation. */ public static final int TRANSFORM_COOLDOWN = 100; - /** The number of cooldown turns per upgrade. */ - public static final int UPGRADE_COOLDOWN = 100; + /** The number of cooldown turns per mutation. */ + public static final int MUTATE_COOLDOWN = 100; // ********************************* // ****** GAME MECHANICS *********** diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index c27e73a1..a1d42cdd 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -555,32 +555,32 @@ public strictfp interface RobotController { void mineGold(MapLocation loc) throws GameActionException; // ************************* - // **** UPGRADE METHODS **** + // **** MUTATE METHODS **** // ************************* /** - * Tests whether this robot can upgrade the building at the given location. + * Tests whether this robot can mutate the building at the given location. * * Checks that the robot is a Builder, that the given location is a valid - * upgrade location. Valid upgrade locations must be adjacent to the current - * location and contain an upgradable building. The upgrade must also be + * mutate location. Valid mutate locations must be adjacent to the current + * location and contain a mutable building. The mutation must also be * affordable, and there must be no cooldown turns remaining. * - * @param loc target location to upgrade - * @return whether it is possible to upgrade at the given location + * @param loc target location to mutate + * @return whether it is possible to mutate at the given location * * @battlecode.doc.costlymethod */ - boolean canUpgrade(MapLocation loc); + boolean canMutate(MapLocation loc); /** - * Upgrade a building at a given location. + * Mutate a building at a given location. * - * @throws GameActionException if conditions for upgrading are not satisfied + * @throws GameActionException if conditions for mutating are not satisfied * * @battlecode.doc.costlymethod */ - void upgrade(MapLocation loc) throws GameActionException; + void mutate(MapLocation loc) throws GameActionException; // ******************************* // **** ALCHEMIST LAB METHODS **** diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 0cfb254a..2e60aaa4 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -137,6 +137,13 @@ public boolean canAttack() { || this == SOLDIER); } + /** + * @return whether this type can envision anomalies + */ + public boolean canEnvision() { + return this == SAGE; + } + /** * @param repairedType type of robot being repaired * @return whether this type can repair the given robot type @@ -147,24 +154,25 @@ public boolean canRepair(RobotType repairedType) { } /** - * @return whether this type can anomalies + * @return whether this type can mine */ - public boolean canEnvision() { - return this == SAGE; + public boolean canMine() { + return this == MINER; } /** - * @return whether this type can convert lead into gold + * @param mutatedType type of robot being mutated + * @return whether this type can mutate buildings */ - public boolean canConvert() { - return this == LABORATORY; + public boolean canMutate(RobotType mutatedType) { + return this == BUILDER && mutatedType.isBuilding(); } /** - * @return whether this type can mine + * @return whether this type can convert lead into gold */ - public boolean canMine() { - return this == MINER; + public boolean canConvert() { + return this == LABORATORY; } /** @@ -236,18 +244,18 @@ public int getHealing(int level) { // COST RELATED FUNCTIONS /** - * @param level the level to upgrade to - * @return lead component of cost to upgrade + * @param level the level to mutate to + * @return lead component of cost to mutate */ - public int getLeadUpgradeCost(int level) { + public int getLeadMutateCost(int level) { return level == 2 ? 600 : 0; } /** - * @param level the level to upgrade to - * @return gold component of cost to upgrade. + * @param level the level to mutate to + * @return gold component of cost to mutate. */ - public int getGoldUpgradeCost(int level) { + public int getGoldMutateCost(int level) { return level == 3 ? 100 : 0; } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index f35ee1f7..a334498a 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -141,6 +141,14 @@ public int getTransformCooldownTurns() { return -1; } + public int getLeadMutateCost() { + return this.type.getLeadMutateCost(this.level + 1); + } + + public int getGoldMutateCost() { + return this.type.getGoldMutateCost(this.level + 1); + } + public RobotInfo getRobotInfo() { if (cachedRobotInfo != null && cachedRobotInfo.ID == ID @@ -235,6 +243,17 @@ public boolean canSeeRadiusSquared(int radiusSquared) { return radiusSquared <= getVisionRadiusSquared(); } + /** + * @return whether this robot can mutate + */ + public boolean canMutate() { + if (this.mode == RobotMode.DROID || this.mode == RobotMode.PROTOTYPE) + return false; + if (this.level == GameConstants.MAX_LEVEL) + return false; + return true; + } + // ****************************************** // ****** UPDATE METHODS ******************** // ****************************************** @@ -326,13 +345,10 @@ public void transform() { } /** - * Upgrade a building. + * Mutate a building. */ - public void upgrade() { - if (this.mode == RobotMode.DROID || this.mode == RobotMode.PROTOTYPE) - return; - if (this.level == GameConstants.MAX_LEVEL) - return; + public void mutate() { + if (!canMutate()) return; this.level++; this.health += this.type.getMaxHealth(this.level) - this.type.getMaxHealth(this.level - 1); } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 0c8cd0ea..77d5aaa8 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -593,66 +593,58 @@ public void mineGold(MapLocation loc) throws GameActionException { } // ************************* - // **** UPGRADE METHODS **** + // **** MUTATE METHODS **** // ************************* - private void assertCanUpgrade(MapLocation loc) throws GameActionException { + private void assertCanMutate(MapLocation loc) throws GameActionException { assertNotNull(loc); assertIsActionReady(); - Team team = getTeam(); - if (!getType().canUpgrade()) { - throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot upgrade buildings."); - } else if (!this.robot.canActLocation(loc)) { + if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, - "Robot can't be upgraded because it is out of range."); - } + "Target location for mutation is out of range."); InternalRobot bot = gameWorld.getRobot(loc); - if (!(bot.getType().canBeUpgraded())) { - throw new GameActionException(CANT_DO_THAT, - "Robot is not of a type that can be upgraded."); - } - if (bot.getTeam() != getTeam()) { + if (bot == null) throw new GameActionException(CANT_DO_THAT, - "Robot is not on your team so can't be upgraded."); - } - if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadUpgradeCost()) { + "There is no robot to mutate at the target location."); + if (!getType().canMutate(bot.getType())) + throw new GameActionException(CANT_DO_THAT, + "Robot is of type " + getType() + " which cannot mutate robots of type " + bot.getType() + "."); + if (bot.getTeam() != getTeam()) + throw new GameActionException(CANT_DO_THAT, + "Robot is not on your team so can't be mutated."); + if (!bot.canMutate()) + throw new GameActionException(CANT_DO_THAT, + "Robot is either not in a mutable mode, or already at max level."); + if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadMutateCost()) throw new GameActionException(NOT_ENOUGH_RESOURCE, - "You don't have enough lead to upgrade this robot."); - } - if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldUpgradeCost()) { + "You don't have enough lead to mutate this robot."); + if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldMutateCost()) throw new GameActionException(NOT_ENOUGH_RESOURCE, - "You don't have enough gold to upgrade this robot."); - } + "You don't have enough gold to mutate this robot."); } @Override - public boolean canUpgrade(MapLocation loc) { + public boolean canMutate(MapLocation loc) { try { - assertCanUpgrade(loc); + assertCanMutate(loc); return true; } catch (GameActionException e) { return false; } } @Override - public void upgrade(MapLocation loc) throws GameActionException { - assertCanUpgrade(loc); - InternalRobot bot = gameWorld.getRobot(loc); - RobotType type = bot.getType(); - int upgradeLevel = bot.getUpgradeLevel(); - - int leadNeeded = type.getLeadUpgradeCost(upgradeLevel); - int goldNeeded = type.getGoldUpgradeCost(upgradeLevel); - - bot.upgrade(); - Team robotTeam = this.robot.getTeam(); - robotTeam.addGold(-goldNeeded); - robotTeam.addLead(-leadNeeded); + public void mutate(MapLocation loc) throws GameActionException { + assertCanMutate(loc); this.addActionCooldownTurns(this.robot.getType().actionCooldown); - bot.addActionCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - bot.addMovementCooldownTurns(GameConstants.UPGRADE_COOLDOWN); - int upgradedID = bot.getID(); - gameWorld.getMatchMaker().addAction(getID(), Action.UPGRADE, upgradedID); + Team team = this.robot.getTeam(); + InternalRobot bot = this.gameWorld.getRobot(loc); + int leadNeeded = bot.getLeadMutateCost(); + int goldNeeded = type.getGoldMutateCost(); + this.gameWorld.getTeamInfo().addLead(team, -leadNeeded); + this.gameWorld.getTeamInfo().addGold(team, -goldNeeded); + bot.mutate(); + bot.addActionCooldownTurns(GameConstants.MUTATE_COOLDOWN); + bot.addMovementCooldownTurns(GameConstants.MUTATE_COOLDOWN); + gameWorld.getMatchMaker().addAction(getID(), Action.MUTATE, bot.getID()); } // ******************************* From ca99cc5c8d7d3be126b11b38a2bd1c57b54e121c Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 20:29:24 -0600 Subject: [PATCH 154/413] transmute methods --- .../battlecode/common/RobotController.java | 34 ++++++------- .../src/main/battlecode/common/RobotType.java | 4 +- .../main/battlecode/world/InternalRobot.java | 5 ++ .../battlecode/world/RobotControllerImpl.java | 51 +++++++++---------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index a1d42cdd..4ab164bf 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -582,39 +582,39 @@ public strictfp interface RobotController { */ void mutate(MapLocation loc) throws GameActionException; - // ******************************* - // **** ALCHEMIST LAB METHODS **** - // ******************************* + // *************************** + // **** TRANSMUTE METHODS **** + // *************************** - /** - * Tests whether this robot can convert lead into gold. - * - * Checks that the robot is a lab and the player has sufficient lead to - * perform a conversion. Also checks that no cooldown turns remain. + /** + * Get lead to gold transmutation rate. * - * @return whether it is possible to convert lead into gold + * @return the lead to gold transmutation rate, 0 if the robot is not a lab * * @battlecode.doc.costlymethod */ - boolean canConvert(); + public int getTransmutationRate(); - /** - * Get lead to gold conversion rate. + /** + * Tests whether this robot can transmute lead into gold. + * + * Checks that the robot is a lab and the player has sufficient lead to + * perform a conversion. Also checks that no cooldown turns remain. * - * @return the lead to gold conversion rate, 0 if the robot is not a lab + * @return whether it is possible to transmute lead into gold * * @battlecode.doc.costlymethod */ - public int getGoldExchangeRate(); + boolean canTransmute(); /** - * Convert lead into gold. + * Transmute lead into gold. * - * @throws GameActionException if conditions for converting are not satisfied + * @throws GameActionException if conditions for transmuting are not satisfied * * @battlecode.doc.costlymethod */ - void convert() throws GameActionException; + void transmute() throws GameActionException; // ******************************* // **** GENERAL TOWER METHODS **** diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 2e60aaa4..2841def3 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -169,9 +169,9 @@ public boolean canMutate(RobotType mutatedType) { } /** - * @return whether this type can convert lead into gold + * @return whether this type can transmute lead into gold */ - public boolean canConvert() { + public boolean canTransmute() { return this == LABORATORY; } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index a334498a..74d864eb 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -141,6 +141,11 @@ public int getTransformCooldownTurns() { return -1; } + public int getNumVisibleFriendlyRobots() { + updateNumVisibleFriendlyRobots(); + return this.numVisibleFriendlyRobots; + } + public int getLeadMutateCost() { return this.type.getLeadMutateCost(this.level + 1); } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 77d5aaa8..b4bbd0f2 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -647,47 +647,42 @@ public void mutate(MapLocation loc) throws GameActionException { gameWorld.getMatchMaker().addAction(getID(), Action.MUTATE, bot.getID()); } - // ******************************* - // **** ALCHEMIST LAB METHODS **** - // ******************************* + // *************************** + // **** TRANSMUTE METHODS **** + // *************************** + + @Override + public int getTransmutationRate() { + return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * + Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * this.robot.getNumVisibleFriendlyRobots())); + } - private void assertCanConvert() throws GameActionException { + private void assertCanTransmute() throws GameActionException { assertIsActionReady(); - Team team = getTeam(); - if (!getType().canConvert()) { + if (!getType().canTransmute()) throw new GameActionException(CANT_DO_THAT, - "Robot is of type " + getType() + " which cannot convert lead to gold."); - } else if (GameConstants.LEAD_TO_GOLD_RATE > gameWorld.getTeamInfo().getLead(team)) { + "Robot is of type " + getType() + " which cannot transmute lead to gold."); + if (this.gameWorld.getTeamInfo().getLead(this.robot.getTeam()) < getTransmutationRate()) throw new GameActionException(CANT_DO_THAT, - "You don't have enough lead to be able to convert to gold."); - } + "You don't have enough lead to transmute to gold."); } @Override - public boolean canConvert() { + public boolean canTransmute() { try { - assertCanConvert(); + assertCanTransmute(); return true; } catch (GameActionException e) { return false; } } @Override - public int getGoldExchangeRate() { - return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * - Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * nearbyRobotCount)); - } - - @Override - public void convert() throws GameActionException { - assertCanConvert(); - RobotType type = this.robot.getType(); - this.robot.addActionCooldownTurns(type.actionCooldown); - Team robotTeam = this.robot.getTeam(); - int nearbyRobotCount = seeNearbyRobots(); - robotTeam.addLead(-GameConstants.LEAD_TO_GOLD_RATE * getGoldExchangeRate()); - robotTeam.addGold(1); - - gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY); + public void transmute() throws GameActionException { + assertCanTransmute(); + this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + Team team = this.robot.getTeam(); + this.gameWorld.getTeamInfo().addLead(team, -getTransmutationRate()); + this.gameWorld.getTeamInfo().addGold(team, 1); + gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY, -1); } // ******************************* From 04dfd4e6153084fd994c6c1b5cce716f2344eecb Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 20:37:00 -0600 Subject: [PATCH 155/413] transform methods + style fixes --- .../battlecode/common/RobotController.java | 11 ++--- .../main/battlecode/world/InternalRobot.java | 11 +++-- .../battlecode/world/RobotControllerImpl.java | 44 ++++++++----------- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 4ab164bf..123bcb35 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -616,15 +616,12 @@ public strictfp interface RobotController { */ void transmute() throws GameActionException; - // ******************************* - // **** GENERAL TOWER METHODS **** - // ******************************* + // *************************** + // **** TRANSFORM METHODS **** + // *************************** /** - * Tests whether this robot can transform. - * - * Checks that the robot is a building and is not a prototype; also checks - * that there are no cooldown turns remaining. + * Tests whether this robot can transform. Same effect as isTransformReady(). * * @return whether it is possible to transform * diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 74d864eb..04cd9299 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -338,14 +338,13 @@ public void addHealth(int healthAmount) { /** * Transform from turret to portable mode, or vice versa. + * Assumes that cooldown is sufficient. */ public void transform() { - if (this.canTransformCooldown()) { - if (this.mode == RobotMode.TURRET) { - this.mode = RobotMode.PORTABLE; - } else { - this.mode = RobotMode.TURRET; - } + if (this.mode == RobotMode.TURRET) { + this.mode = RobotMode.PORTABLE; + } else { + this.mode = RobotMode.TURRET; } } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index b4bbd0f2..e09a55a6 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -122,7 +122,7 @@ public int getLevel() { } private InternalRobot getRobotByID(int id) { - if (!gameWorld.getObjectInfo().existsRobot(id)) + if (!this.gameWorld.getObjectInfo().existsRobot(id)) return null; return this.gameWorld.getObjectInfo().getRobotByID(id); } @@ -137,7 +137,7 @@ public boolean onTheMap(MapLocation loc) throws GameActionException { if (!this.robot.canSeeLocation(loc)) throw new GameActionException(CANT_SEE_THAT, "Target location not within vision range"); - return gameWorld.getGameMap().onTheMap(loc); + return this.gameWorld.getGameMap().onTheMap(loc); } private void assertCanSeeLocation(MapLocation loc) throws GameActionException { @@ -145,7 +145,7 @@ private void assertCanSeeLocation(MapLocation loc) throws GameActionException { if (!this.robot.canSeeLocation(loc)) throw new GameActionException(CANT_SEE_THAT, "Target location not within vision range"); - if (!gameWorld.getGameMap().onTheMap(loc)) + if (!this.gameWorld.getGameMap().onTheMap(loc)) throw new GameActionException(CANT_SEE_THAT, "Target location is not on the map"); } @@ -355,8 +355,7 @@ public void move(Direction dir) throws GameActionException { this.robot.addMovementCooldownTurns(this.robot.getType().movementCooldown); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); - - gameWorld.getMatchMaker().addMoved(getID(), getLocation()); + this.gameWorld.getMatchMaker().addMoved(getID(), getLocation()); } // *********************************** @@ -484,7 +483,7 @@ public void envision(AnomalyType anomaly) throws GameActionException { case FURY: this.gameWorld.causeFurySage(this.robot, anomaly); } - gameWorld.getMatchMaker().addAction(getID(), Action.ENVISION, anomaly); + this.gameWorld.getMatchMaker().addAction(getID(), Action.ENVISION, anomaly); } // ***************************** @@ -523,7 +522,7 @@ public void repair(MapLocation loc) throws GameActionException { this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); InternalRobot bot = this.gameWorld.getRobot(loc); this.robot.heal(bot); - gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, bot.getID()); + this.gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, bot.getID()); } // *********************** @@ -558,7 +557,7 @@ public void mineLead(MapLocation loc) throws GameActionException { this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); this.gameWorld.setLead(loc, this.gameWorld.getLead(loc) - 1); this.gameWorld.getTeamInfo().addLead(this.robot.getTeam(), 1); - gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); + this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } private void assertCanMineGold(MapLocation loc) throws GameActionException { @@ -589,7 +588,7 @@ public void mineGold(MapLocation loc) throws GameActionException { this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); this.gameWorld.setGold(loc, this.gameWorld.getGold(loc) - 1); this.gameWorld.getTeamInfo().addGold(this.robot.getTeam(), 1); - gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); + this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } // ************************* @@ -644,7 +643,7 @@ public void mutate(MapLocation loc) throws GameActionException { bot.mutate(); bot.addActionCooldownTurns(GameConstants.MUTATE_COOLDOWN); bot.addMovementCooldownTurns(GameConstants.MUTATE_COOLDOWN); - gameWorld.getMatchMaker().addAction(getID(), Action.MUTATE, bot.getID()); + this.gameWorld.getMatchMaker().addAction(getID(), Action.MUTATE, bot.getID()); } // *************************** @@ -682,20 +681,15 @@ public void transmute() throws GameActionException { Team team = this.robot.getTeam(); this.gameWorld.getTeamInfo().addLead(team, -getTransmutationRate()); this.gameWorld.getTeamInfo().addGold(team, 1); - gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY, -1); + this.gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY, -1); } - // ******************************* - // **** GENERAL TOWER METHODS **** - // ******************************* + // *************************** + // **** TRANSFORM METHODS **** + // *************************** private void assertCanTransform() throws GameActionException { - assertIsActionReady(); - assertIsMovementReady(); - if (robot.getMode() != RobotMode.TURRET && robot.getMode() != RobotMode.PORTABLE) { - throw new GameActionException(CANT_DO_THAT, - "Robot is not transformable."); - } + assertIsTransformReady(); } @Override @@ -709,12 +703,12 @@ public boolean canTransform() { @Override public void transform() throws GameActionException { assertCanTransform(); - robot.transform(); - RobotMode mode = robot.getMode(); - if (mode == RobotMode.TURRET) - addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + this.robot.transform(); + if (this.robot.getMode() == RobotMode.TURRET) + this.robot.addActionCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); else - addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + this.robot.addMovementCooldownTurns(GameConstants.TRANSFORM_COOLDOWN); + this.gameWorld.getMatchMaker().addAction(getID(), Action.TRANSFORM, -1); } // *********************************** From 983723df210d8227fb1218b85b243b330ac5463a Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 20:38:38 -0600 Subject: [PATCH 156/413] misc RobotControllerImpl --- engine/src/main/battlecode/world/RobotControllerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index e09a55a6..9c62569a 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -783,8 +783,9 @@ public void disintegrate() { @Override public void resign() { + Team team = this.robot.getTeam(); gameWorld.getObjectInfo().eachRobot((robot) -> { - if (robot.getTeam() == getTeam()) { + if (robot.getTeam() == team) { gameWorld.destroyRobot(robot.getID()); } return true; @@ -798,14 +799,13 @@ public void resign() { @Override public void setIndicatorDot(MapLocation loc, int red, int green, int blue) { assertNotNull(loc); - gameWorld.getMatchMaker().addIndicatorDot(getID(), loc, red, green, blue); + this.gameWorld.getMatchMaker().addIndicatorDot(getID(), loc, red, green, blue); } @Override public void setIndicatorLine(MapLocation startLoc, MapLocation endLoc, int red, int green, int blue) { assertNotNull(startLoc); assertNotNull(endLoc); - gameWorld.getMatchMaker().addIndicatorLine(getID(), startLoc, endLoc, red, green, blue); + this.gameWorld.getMatchMaker().addIndicatorLine(getID(), startLoc, endLoc, red, green, blue); } - } From 24bd03a3233a0f977bc3a70ce81966d045361908 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 20:50:21 -0600 Subject: [PATCH 157/413] communication code --- .../main/battlecode/common/GameConstants.java | 6 ++ .../battlecode/common/RobotController.java | 42 ++++---------- .../battlecode/world/RobotControllerImpl.java | 57 ++++--------------- .../src/main/battlecode/world/TeamInfo.java | 24 ++++++++ 4 files changed, 52 insertions(+), 77 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 9b8bf837..aacee83b 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -46,6 +46,12 @@ public class GameConstants { /** The number of indicator strings that a player can associate with a robot. */ public static final int NUMBER_OF_INDICATOR_STRINGS = 3; + /** The length of each team's shared communication array. */ + public static final int SHARED_ARRAY_LENGTH = 64; + + /** The maximum value in shared communication arrays. */ + public static final int MAX_SHARED_ARRAY_VALUE = Short.MAX_VALUE; + /** The bytecode penalty that is imposed each time an exception is thrown. */ public static final int EXCEPTION_BYTECODE_PENALTY = 500; diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 123bcb35..c024cd5d 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -642,48 +642,28 @@ public strictfp interface RobotController { // ****** COMMUNICATION METHODS ****** // *********************************** - /** - * Checks whether the robot can set the team array's value at a specified index. - * - * @param index the index in the team's shared array - * @param value the value to set that index to - * @return whether the robot can set the team array's value at the given index - */ - boolean canSetTeamArray(int index, int value); - /** - * Sets a team's array value at a specified index. - * - * @param index the index in the team's shared array - * @param value the value to set that index to - * @throws GameActionException if the index or value is invalid - * - * @battlecode.doc.costlymethod - */ - void setTeamArray(int index, int value) throws GameActionException; - - /** - * Given an index, checks if a robot can get the value at that index in the team array. - * - * Checks that the index is valid. + * Given an index, returns the value at that index in the team array. * - * @param index the index in the team's shared array - * @return whether it is possible to get the value at that index + * @param index the index in the team's shared array, 0-indexed + * @return the value at that index in the team's shared array, + * or -1 if the index is invalid * * @battlecode.doc.costlymethod */ - boolean canGetTeamArray(int index); + int readSharedArray(int index); /** - * Given an index, returns the value at that index in the team array. + * Sets a team's array value at a specified index. + * No change occurs if the index or value is invalid. * - * @param index the index in the team's shared array - * @throws GameActionException if conditions for getting the value are not satisfied - * @return the value at that index in the team's shared array + * @param index the index in the team's shared array, 0-indexed + * @param value the value to set that index to + * @return whether the value was successfully written * * @battlecode.doc.costlymethod */ - int getTeamArray(int index) throws GameActionException; + boolean writeSharedArray(int index, int value); // *********************************** // ****** OTHER ACTION METHODS ******* diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9c62569a..8770c284 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -715,58 +715,23 @@ public void transform() throws GameActionException { // ****** COMMUNICATION METHODS ****** // *********************************** - //TODO: Communication needs to be fixed - - private void assertCanSetFlag(int flag) throws GameActionException { - if (flag < GameConstants.MIN_FLAG_VALUE || flag > GameConstants.MAX_FLAG_VALUE) { - throw new GameActionException(CANT_DO_THAT, "Flag value out of range"); - } - } - @Override - public boolean canSetFlag(int flag) { - try { - assertCanSetFlag(flag); - return true; - } catch (GameActionException e) { return false; } - } - - @Override - public void setFlag(int flag) throws GameActionException { - assertCanSetFlag(flag); - this.robot.setFlag(flag); - gameWorld.getMatchMaker().addAction(getID(), Action.SET_FLAG, flag); - } - - private void assertCanGetFlag(int id) throws GameActionException { - InternalRobot bot = getRobotByID(id); - if (bot == null) - throw new GameActionException(CANT_DO_THAT, - "Robot of given ID does not exist."); - if (getType() != RobotType.ENLIGHTENMENT_CENTER && - bot.getType() != RobotType.ENLIGHTENMENT_CENTER && - !canSeeLocation(bot.getLocation())) - throw new GameActionException(CANT_SENSE_THAT, - "Robot at location is out of sensor range and not an Enlightenment Center."); + public int readSharedArray(int index) { + if (index < 0 || index >= GameConstants.SHARED_ARRAY_LENGTH) + return -1; + return this.gameWorld.getTeamInfo().readSharedArray(this.robot.getTeam(), index); } @Override - public boolean canGetFlag(int id) { - try { - assertCanGetFlag(id); - return true; - } catch (GameActionException e) { return false; } + public boolean writeSharedArray(int index, int value) { + if (index < 0 || index >= GameConstants.SHARED_ARRAY_LENGTH) + return false; + if (value < 0 || value >= GameConstants.MAX_SHARED_ARRAY_VALUE) + return false; + this.gameWorld.getTeamInfo().writeSharedArray(this.robot.getTeam(), index, value); + return true; } - @Override - public int getFlag(int id) throws GameActionException { - assertCanGetFlag(id); - - return getRobotByID(id).getFlag(); - } - - //TODO: move this back to public? - // *********************************** // ****** OTHER ACTION METHODS ******* // *********************************** diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index b32412a1..8b8e3418 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -14,6 +14,7 @@ public class TeamInfo { private GameWorld gameWorld; private int[] leadCounts; private int[] goldCounts; + private int[][] sharedArrays; /** * Create a new representation of TeamInfo @@ -24,6 +25,7 @@ public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; this.leadCount = new int[2]; this.goldCount = new int[2]; + this.sharedArrays = new int[2][GameConstants.SHARED_ARRAY_LENGTH]; } // ********************************* @@ -50,6 +52,17 @@ public int getGold(Team team) { return this.goldCount[team.ordinal()]; } + /** + * Reads the shared array value. + * + * @param team the team to query + * @param index the index in the array + * @return the value at that index in the team's shared array + */ + public int readSharedArray(Team team, int index) { + return this.sharedArrays[team.ordinal()][index]; + } + // ********************************* // ***** UPDATE METHODS ************ // ********************************* @@ -81,4 +94,15 @@ public void addGold(Team team, int amount) throws IllegalArgumentException { } this.goldCount[team.ordinal()] += amount; } + + /** + * Sets an index in the team's shared array to a given value. + * + * @param team the team to query + * @param index the index in the shared array + * @param value the new value + */ + public void setSharedArray(Team team, int index, int value) { + this.sharedArrays[team.ordinal()][index] = value; + } } From 1249aef8c12b68e089d8ab5729a5f98f684ea9a6 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 21:50:00 -0600 Subject: [PATCH 158/413] fix compile issues --- .../AnomalyScheduleEntry.java | 5 +- .../main/battlecode/common/AnomalyType.java | 6 +- .../common/GameActionExceptionType.java | 6 +- .../src/main/battlecode/common/RobotType.java | 8 +- .../src/main/battlecode/world/GameWorld.java | 16 ++-- .../main/battlecode/world/InternalRobot.java | 4 +- engine/src/main/battlecode/world/LiveMap.java | 4 +- .../src/main/battlecode/world/MapBuilder.java | 2 +- .../battlecode/world/RobotControllerImpl.java | 80 +++++++++---------- .../src/main/battlecode/world/TeamInfo.java | 18 ++--- .../main/battlecode/world/TestMapBuilder.java | 2 +- 11 files changed, 73 insertions(+), 78 deletions(-) rename engine/src/main/battlecode/{world => common}/AnomalyScheduleEntry.java (86%) diff --git a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java similarity index 86% rename from engine/src/main/battlecode/world/AnomalyScheduleEntry.java rename to engine/src/main/battlecode/common/AnomalyScheduleEntry.java index acd62fb9..7530863e 100644 --- a/engine/src/main/battlecode/world/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java @@ -1,5 +1,4 @@ -package battlecode.world; -import battlecode.common.*; +package battlecode.common; public class AnomalyScheduleEntry { @@ -14,7 +13,7 @@ public AnomalyScheduleEntry(int round, AnomalyType anomaly) { /** * @return a copy of the entry */ - public AnomalyScheduleEntry copyEntry(AnomalyType anomalyType) { + public AnomalyScheduleEntry copyEntry() { return new AnomalyScheduleEntry(this.roundNumber, this.anomalyType); } diff --git a/engine/src/main/battlecode/common/AnomalyType.java b/engine/src/main/battlecode/common/AnomalyType.java index 6c027a0e..f09085be 100644 --- a/engine/src/main/battlecode/common/AnomalyType.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -4,9 +4,9 @@ * Holds the different anomalies in the game. */ public enum AnomalyType { - ABYSS (true, true, 0.1, 0.2), - CHARGE (true, true, 0.05, 0.1), - FURY (true, true, 0.05, 0.1), + ABYSS (true, true, 0.1f, 0.2f), + CHARGE (true, true, 0.05f, 0.1f), + FURY (true, true, 0.05f, 0.1f), VORTEX (true, false, 0, 0), SINGULARITY (true, false, 0, 0); diff --git a/engine/src/main/battlecode/common/GameActionExceptionType.java b/engine/src/main/battlecode/common/GameActionExceptionType.java index 0895f729..38b17abf 100644 --- a/engine/src/main/battlecode/common/GameActionExceptionType.java +++ b/engine/src/main/battlecode/common/GameActionExceptionType.java @@ -22,10 +22,10 @@ public enum GameActionExceptionType { */ IS_NOT_READY, /** - * Indicates when a robot tries to sense a robot that no longer exists or is no longer - * in this robot's sensor range. + * Indicates when a robot tries to see a robot that no longer exists or is no longer + * in this robot's vision range. */ - CANT_SENSE_THAT, + CANT_SEE_THAT, /** * Indicates when a robot tries to perform an action on a location that is outside * its range. diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 2841def3..e3d17f5a 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -149,8 +149,8 @@ public boolean canEnvision() { * @return whether this type can repair the given robot type */ public boolean canRepair(RobotType repairedType) { - return (this == ARCHON && !builtType.isBuilding() || - this == BUILDER && builtType.isBuilding()); + return (this == ARCHON && !repairedType.isBuilding() || + this == BUILDER && repairedType.isBuilding()); } /** @@ -266,7 +266,7 @@ public int getGoldMutateCost(int level) { public int getLeadWorth(int level) { int leadWorth = this.buildCostLead; for (int i = 2; i <= level; i++) { - leadWorth += this.getLeadUpgradeCost(i); + leadWorth += this.getLeadMutateCost(i); } return leadWorth; } @@ -278,7 +278,7 @@ public int getLeadWorth(int level) { public int getGoldWorth(int level) { int goldWorth = this.buildCostGold; for (int i = 2; i <= level; i++) { - goldWorth += this.getGoldUpgradeCost(i); + goldWorth += this.getGoldMutateCost(i); } return goldWorth; } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 1c94038e..a9c672da 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -74,7 +74,7 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match if (robot.team == Team.A && robot.type == RobotType.ARCHON) numArchons++; } - this.teamInfo = new TeamInfo(this, numArchons); + this.teamInfo = new TeamInfo(this); // Write match header at beginning of match this.matchMaker.makeMatchHeader(this.gameMap); @@ -381,7 +381,7 @@ public boolean timeLimitReached() { public void processEndOfRound() { // Add lead resources to the map if (this.currentRound % GameConstants.ADD_LEAD_EVERY_ROUNDS == 0) - for (int i = 0; i < this.lead.length) + for (int i = 0; i < this.lead.length; i++) if (this.lead[i] > 0) this.lead[i] += GameConstants.ADD_LEAD; @@ -400,10 +400,10 @@ public void processEndOfRound() { AnomalyScheduleEntry nextAnomaly = this.gameMap.viewNextAnomaly(); if (nextAnomaly != null && nextAnomaly.roundNumber == this.currentRound) { AnomalyType anomaly = this.gameMap.takeNextAnomaly().anomalyType; - if (anomaly == AnomalyType.ABYSS) causeAbyssGlobal(anomaly); - if (anomaly == AnomalyType.CHARGE) causeChargeGlobal(anomaly); - if (anomaly == AnomalyType.FURY) causeFuryGlobal(anomaly); - if (anomaly == AnomalyType.VORTEX) causeVortexGlobal(anomaly); + if (anomaly == AnomalyType.ABYSS) causeAbyssGlobal(); + if (anomaly == AnomalyType.CHARGE) causeChargeGlobal(); + if (anomaly == AnomalyType.FURY) causeFuryGlobal(); + if (anomaly == AnomalyType.VORTEX) causeVortexGlobal(); } // Check for end of match @@ -457,7 +457,7 @@ public void destroyRobot(int id) { // this happens here because both teams' Archons can die in the same round if (type == RobotType.ARCHON && this.objectInfo.getRobotTypeCount(team, RobotType.ARCHON) == 0) - setWinner(1 - team, DominationFactor.ANNIHILATION); + setWinner(team == Team.A ? Team.B : Team.A, DominationFactor.ANNIHILATION); matchMaker.addDied(id); } @@ -565,7 +565,7 @@ public void causeChargeGlobal() { /** Used to sort droids for charge */ class SortByFriends implements Comparator { public int compare(InternalRobot a, InternalRobot b) { - return a.numVisibleFriendlyRobots - b.numVisibleFriendlyRobots; + return a.getNumVisibleFriendlyRobots(false) - b.getNumVisibleFriendlyRobots(false); } } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 04cd9299..df798e30 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -141,8 +141,8 @@ public int getTransformCooldownTurns() { return -1; } - public int getNumVisibleFriendlyRobots() { - updateNumVisibleFriendlyRobots(); + public int getNumVisibleFriendlyRobots(boolean update) { + if (update) updateNumVisibleFriendlyRobots(); return this.numVisibleFriendlyRobots; } diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index d72a5f38..26102efe 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -86,7 +86,7 @@ public LiveMap(int width, Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 this.leadArray = new int[width * height]; // TODO: we guarantee there to be lead within vision range of archons - this.anomalySchedule = new int[1]; + this.anomalySchedule = new AnomalyScheduleEntry[1]; this.anomalySchedule[0] = new AnomalyScheduleEntry(GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, AnomalyType.SINGULARITY); this.nextAnomalyIndex = 0; @@ -120,7 +120,7 @@ public LiveMap(int width, this.leadArray[i] = leadArray[i]; } - this.anomalySchedule = new int[anomalySchedule.length]; + this.anomalySchedule = new AnomalyScheduleEntry[anomalySchedule.length]; for (int i = 0; i < anomalySchedule.length; i++) { this.anomalySchedule[i] = anomalySchedule[i]; } diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 02189268..5367f1a8 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -69,7 +69,7 @@ public void addArchon(int id, Team team, MapLocation loc) { team, RobotType.ARCHON, 1, - RobotType.ARCHON.health; + RobotType.ARCHON.health, loc )); } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 8770c284..7b0fd509 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -65,7 +65,7 @@ private static void assertNotNull(Object o) { @Override public int hashCode() { - return this.robot.getID(); + return getID(); } // ********************************* @@ -84,7 +84,7 @@ public int getRobotCount() { @Override public int getArchonCount() { - return this.gameWorld.getTeamInfo().getArchonCount(getTeam()); + return this.gameWorld.getObjectInfo().getRobotTypeCount(getTeam(), RobotType.ARCHON); } // ********************************* @@ -185,7 +185,7 @@ public boolean canSeeRobot(int id) { @Override public RobotInfo seeRobot(int id) throws GameActionException { if (!canSeeRobot(id)) - throw new GameActionException(CANT_SENSE_THAT, + throw new GameActionException(CANT_SEE_THAT, "Can't see given robot; It may be out of vision range or not exist anymore"); return getRobotByID(id).getRobotInfo(); } @@ -208,7 +208,7 @@ public RobotInfo[] seeNearbyRobots(int radiusSquared, Team team) { @Override public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team) { assertNotNull(center); - int actualRadiusSquared = radiusSquared == -1 ? getType().sensorRadiusSquared : Math.min(radiusSquared, getType().sensorRadiusSquared); + int actualRadiusSquared = radiusSquared == -1 ? getType().visionRadiusSquared : Math.min(radiusSquared, getType().visionRadiusSquared); InternalRobot[] allSeenRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); List validSeenRobots = new ArrayList<>(); for (InternalRobot seenRobot : allSeenRobots) { @@ -307,8 +307,8 @@ private void assertIsTransformReady() throws GameActionException { "This robot is not in a mode that can transform."); if (!this.robot.canTransformCooldown()) throw new GameActionException(IS_NOT_READY, - "This robot's transform cooldown (either action or movement - cooldown, depending on its current mode) has not expired."); + "This robot's transform cooldown (either action or movement" + + "cooldown, depending on its current mode) has not expired."); } @Override @@ -352,7 +352,7 @@ public boolean canMove(Direction dir) { public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - this.robot.addMovementCooldownTurns(this.robot.getType().movementCooldown); + this.robot.addMovementCooldownTurns(getType().movementCooldown); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); this.gameWorld.getMatchMaker().addMoved(getID(), getLocation()); @@ -370,13 +370,11 @@ private void assertCanBuildRobot(RobotType type, Direction dir) throws GameActio throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot build robots of type " + type + "."); - int leadNeeded = type.getLeadCost(); - int goldNeeded = type.getGoldCost(); Team team = getTeam(); - if (this.gameWorld.getTeamInfo().getLead(team) < leadNeeded) + if (this.gameWorld.getTeamInfo().getLead(team) < type.buildCostLead) throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of lead."); - if (this.gameWorld.getTeamInfo().getGold(team) < goldNeeded) + if (this.gameWorld.getTeamInfo().getGold(team) < type.buildCostGold) throw new GameActionException(NOT_ENOUGH_RESOURCE, "Insufficient amount of gold."); @@ -400,14 +398,12 @@ public boolean canBuildRobot(RobotType type, Direction dir) { @Override public void buildRobot(RobotType type, Direction dir) throws GameActionException { assertCanBuildRobot(type, dir); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); Team team = getTeam(); - int leadNeeded = type.getLeadCost(); - int goldNeeded = type.getGoldCost(); - this.gameWorld.getTeamInfo().addLead(team, -leadNeeded); - this.gameWorld.getTeamInfo().addGold(team, -goldNeeded); + this.gameWorld.getTeamInfo().addLead(team, -type.buildCostLead); + this.gameWorld.getTeamInfo().addGold(team, -type.buildCostGold); this.gameWorld.spawnRobot(type, adjacentLocation(dir), team); - this.gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, robotID); + this.gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, getID()); } // ***************************** @@ -423,7 +419,7 @@ private void assertCanAttack(MapLocation loc) throws GameActionException { if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, "Location can't be attacked because it is out of range."); - InternalRobot bot = getRobot(loc); + InternalRobot bot = this.gameWorld.getRobot(loc); if (bot == null) throw new GameActionException(CANT_DO_THAT, "There is no robot to attack at the target location."); @@ -443,7 +439,7 @@ public boolean canAttack(MapLocation loc) { @Override public void attack(MapLocation loc) throws GameActionException { assertCanAttack(loc); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); InternalRobot bot = this.gameWorld.getRobot(loc); this.robot.attack(bot); this.gameWorld.getMatchMaker().addAction(getID(), Action.ATTACK, bot.getID()); @@ -474,14 +470,14 @@ public boolean canEnvision(AnomalyType anomaly) { @Override public void envision(AnomalyType anomaly) throws GameActionException { assertCanEnvision(anomaly); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); switch (anomaly) { case ABYSS: - this.gameWorld.causeAbyssSage(this.robot, anomaly); + this.gameWorld.causeAbyssSage(this.robot); case CHARGE: - this.gameWorld.causeChargeSage(this.robot, anomaly); + this.gameWorld.causeChargeSage(this.robot); case FURY: - this.gameWorld.causeFurySage(this.robot, anomaly); + this.gameWorld.causeFurySage(this.robot); } this.gameWorld.getMatchMaker().addAction(getID(), Action.ENVISION, anomaly); } @@ -519,10 +515,10 @@ public boolean canRepair(MapLocation loc) { @Override public void repair(MapLocation loc) throws GameActionException { assertCanRepair(loc); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); InternalRobot bot = this.gameWorld.getRobot(loc); this.robot.heal(bot); - this.gameWorld.getMatchMaker().addAction(getID(), Action.HEAL_DROID, bot.getID()); + this.gameWorld.getMatchMaker().addAction(getID(), Action.REPAIR, bot.getID()); } // *********************** @@ -554,9 +550,9 @@ public boolean canMineLead(MapLocation loc) { @Override public void mineLead(MapLocation loc) throws GameActionException { assertCanMineLead(loc); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); this.gameWorld.setLead(loc, this.gameWorld.getLead(loc) - 1); - this.gameWorld.getTeamInfo().addLead(this.robot.getTeam(), 1); + this.gameWorld.getTeamInfo().addLead(getTeam(), 1); this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); } @@ -585,9 +581,9 @@ public boolean canMineGold(MapLocation loc) { @Override public void mineGold(MapLocation loc) throws GameActionException { assertCanMineGold(loc); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); + this.robot.addActionCooldownTurns(getType().actionCooldown); this.gameWorld.setGold(loc, this.gameWorld.getGold(loc) - 1); - this.gameWorld.getTeamInfo().addGold(this.robot.getTeam(), 1); + this.gameWorld.getTeamInfo().addGold(getTeam(), 1); this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); } @@ -601,7 +597,7 @@ private void assertCanMutate(MapLocation loc) throws GameActionException { if (!this.robot.canActLocation(loc)) throw new GameActionException(OUT_OF_RANGE, "Target location for mutation is out of range."); - InternalRobot bot = gameWorld.getRobot(loc); + InternalRobot bot = this.gameWorld.getRobot(loc); if (bot == null) throw new GameActionException(CANT_DO_THAT, "There is no robot to mutate at the target location."); @@ -614,10 +610,10 @@ private void assertCanMutate(MapLocation loc) throws GameActionException { if (!bot.canMutate()) throw new GameActionException(CANT_DO_THAT, "Robot is either not in a mutable mode, or already at max level."); - if (gameWorld.getTeamInfo().getLead(team) < bot.getLeadMutateCost()) + if (gameWorld.getTeamInfo().getLead(getTeam()) < bot.getLeadMutateCost()) throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough lead to mutate this robot."); - if (gameWorld.getTeamInfo().getGold(team) < bot.getGoldMutateCost()) + if (gameWorld.getTeamInfo().getGold(getTeam()) < bot.getGoldMutateCost()) throw new GameActionException(NOT_ENOUGH_RESOURCE, "You don't have enough gold to mutate this robot."); } @@ -633,11 +629,11 @@ public boolean canMutate(MapLocation loc) { @Override public void mutate(MapLocation loc) throws GameActionException { assertCanMutate(loc); - this.addActionCooldownTurns(this.robot.getType().actionCooldown); - Team team = this.robot.getTeam(); + this.robot.addActionCooldownTurns(getType().actionCooldown); + Team team = getTeam(); InternalRobot bot = this.gameWorld.getRobot(loc); int leadNeeded = bot.getLeadMutateCost(); - int goldNeeded = type.getGoldMutateCost(); + int goldNeeded = bot.getGoldMutateCost(); this.gameWorld.getTeamInfo().addLead(team, -leadNeeded); this.gameWorld.getTeamInfo().addGold(team, -goldNeeded); bot.mutate(); @@ -653,7 +649,7 @@ public void mutate(MapLocation loc) throws GameActionException { @Override public int getTransmutationRate() { return (int) (GameConstants.ALCHEMIST_LONELINESS_A - GameConstants.ALCHEMIST_LONELINESS_B * - Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * this.robot.getNumVisibleFriendlyRobots())); + Math.exp(-GameConstants.ALCHEMIST_LONELINESS_K * this.robot.getNumVisibleFriendlyRobots(true))); } private void assertCanTransmute() throws GameActionException { @@ -661,7 +657,7 @@ private void assertCanTransmute() throws GameActionException { if (!getType().canTransmute()) throw new GameActionException(CANT_DO_THAT, "Robot is of type " + getType() + " which cannot transmute lead to gold."); - if (this.gameWorld.getTeamInfo().getLead(this.robot.getTeam()) < getTransmutationRate()) + if (this.gameWorld.getTeamInfo().getLead(getTeam()) < getTransmutationRate()) throw new GameActionException(CANT_DO_THAT, "You don't have enough lead to transmute to gold."); } @@ -677,8 +673,8 @@ public boolean canTransmute() { @Override public void transmute() throws GameActionException { assertCanTransmute(); - this.robot.addActionCooldownTurns(this.robot.getType().actionCooldown); - Team team = this.robot.getTeam(); + this.robot.addActionCooldownTurns(getType().actionCooldown); + Team team = getTeam(); this.gameWorld.getTeamInfo().addLead(team, -getTransmutationRate()); this.gameWorld.getTeamInfo().addGold(team, 1); this.gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY, -1); @@ -719,7 +715,7 @@ public void transform() throws GameActionException { public int readSharedArray(int index) { if (index < 0 || index >= GameConstants.SHARED_ARRAY_LENGTH) return -1; - return this.gameWorld.getTeamInfo().readSharedArray(this.robot.getTeam(), index); + return this.gameWorld.getTeamInfo().readSharedArray(getTeam(), index); } @Override @@ -728,7 +724,7 @@ public boolean writeSharedArray(int index, int value) { return false; if (value < 0 || value >= GameConstants.MAX_SHARED_ARRAY_VALUE) return false; - this.gameWorld.getTeamInfo().writeSharedArray(this.robot.getTeam(), index, value); + this.gameWorld.getTeamInfo().writeSharedArray(getTeam(), index, value); return true; } @@ -748,7 +744,7 @@ public void disintegrate() { @Override public void resign() { - Team team = this.robot.getTeam(); + Team team = getTeam(); gameWorld.getObjectInfo().eachRobot((robot) -> { if (robot.getTeam() == team) { gameWorld.destroyRobot(robot.getID()); diff --git a/engine/src/main/battlecode/world/TeamInfo.java b/engine/src/main/battlecode/world/TeamInfo.java index 8b8e3418..6200de89 100644 --- a/engine/src/main/battlecode/world/TeamInfo.java +++ b/engine/src/main/battlecode/world/TeamInfo.java @@ -23,8 +23,8 @@ public class TeamInfo { */ public TeamInfo(GameWorld gameWorld) { this.gameWorld = gameWorld; - this.leadCount = new int[2]; - this.goldCount = new int[2]; + this.leadCounts = new int[2]; + this.goldCounts = new int[2]; this.sharedArrays = new int[2][GameConstants.SHARED_ARRAY_LENGTH]; } @@ -39,7 +39,7 @@ public TeamInfo(GameWorld gameWorld) { * @return the team's lead count */ public int getLead(Team team) { - return this.leadCount[team.ordinal()]; + return this.leadCounts[team.ordinal()]; } /** @@ -49,7 +49,7 @@ public int getLead(Team team) { * @return the team's gold count */ public int getGold(Team team) { - return this.goldCount[team.ordinal()]; + return this.goldCounts[team.ordinal()]; } /** @@ -75,10 +75,10 @@ public int readSharedArray(Team team, int index) { * @throws IllegalArgumentException if the resulting amount of lead is negative */ public void addLead(Team team, int amount) throws IllegalArgumentException { - if (this.leadCount[team.ordinal()] + amount < 0) { + if (this.leadCounts[team.ordinal()] + amount < 0) { throw new IllegalArgumentException("Invalid lead change"); } - this.leadCount[team.ordinal()] += amount; + this.leadCounts[team.ordinal()] += amount; } /** @@ -89,10 +89,10 @@ public void addLead(Team team, int amount) throws IllegalArgumentException { * @throws IllegalArgumentException if the resulting amount of gold is negative */ public void addGold(Team team, int amount) throws IllegalArgumentException { - if (this.goldCount[team.ordinal()] + amount < 0) { + if (this.goldCounts[team.ordinal()] + amount < 0) { throw new IllegalArgumentException("Invalid gold change"); } - this.goldCount[team.ordinal()] += amount; + this.goldCounts[team.ordinal()] += amount; } /** @@ -102,7 +102,7 @@ public void addGold(Team team, int amount) throws IllegalArgumentException { * @param index the index in the shared array * @param value the new value */ - public void setSharedArray(Team team, int index, int value) { + public void writeSharedArray(Team team, int index, int value) { this.sharedArrays[team.ordinal()][index] = value; } } diff --git a/engine/src/main/battlecode/world/TestMapBuilder.java b/engine/src/main/battlecode/world/TestMapBuilder.java index 7e14bada..4cf495fb 100644 --- a/engine/src/main/battlecode/world/TestMapBuilder.java +++ b/engine/src/main/battlecode/world/TestMapBuilder.java @@ -11,7 +11,7 @@ public class TestMapBuilder { private MapBuilder mapBuilder; public TestMapBuilder(String name, int oX, int oY, int width, int height, int seed) { - this.mapBuilder = new MapBuilder(name, width, height, oX, oY, seed) + this.mapBuilder = new MapBuilder(name, width, height, oX, oY, seed); } public TestMapBuilder addArchon(int id, Team team, MapLocation loc) { From 16300189c0db03c7f3cd9f3e953bff4d5a588382 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 22:16:33 -0600 Subject: [PATCH 159/413] small change --- engine/src/main/battlecode/world/RobotControllerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 7b0fd509..2c3ec427 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -456,7 +456,7 @@ private void assertCanEnvision(AnomalyType anomaly) throws GameActionException { "Robot is of type " + getType() + " which cannot envision."); if (!anomaly.isSageAnomaly) throw new GameActionException(CANT_DO_THAT, - "Sage can not use anomaly of type " + anomaly.toString()); + "Sage can not use anomaly of type " + anomaly); } @Override From 3a193204030d203ee005106fb529ca927a699efc Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Wed, 22 Dec 2021 22:19:44 -0600 Subject: [PATCH 160/413] remove robot freeze in GameWorld --- engine/src/main/battlecode/world/GameWorld.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index a9c672da..7f9fbbe7 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -141,8 +141,7 @@ private boolean updateRobot(InternalRobot robot) { // If the robot terminates but the death signal has not yet // been visited: if (this.controlProvider.getTerminated(robot) && objectInfo.getRobotByID(robot.getID()) != null) - //destroyRobot(robot.getID()); - ; // Freeze robot instead of destroying it + destroyRobot(robot.getID()); return true; } From 3fdd60b17f53c805da2658237926b81a389a8446 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 23 Dec 2021 02:02:55 -0600 Subject: [PATCH 161/413] map symmetry can now be accessed from gameWorld --- .../common/AnomalyScheduleEntry.java | 2 +- engine/src/main/battlecode/world/LiveMap.java | 39 +++++++++++++------ .../src/main/battlecode/world/MapBuilder.java | 29 +++++++------- .../main/battlecode/world/MapSymmetry.java | 10 +++++ 4 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 engine/src/main/battlecode/world/MapSymmetry.java diff --git a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java index 7530863e..eef5c249 100644 --- a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java @@ -27,4 +27,4 @@ public boolean equals(AnomalyScheduleEntry other) { if (this.roundNumber != other.roundNumber) return false; return this.anomalyType == other.anomalyType; } -} \ No newline at end of file +} diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index 26102efe..f48aba86 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -27,27 +27,32 @@ public strictfp class LiveMap { private final MapLocation origin; /** - * Factor to multiply cooldowns by + * The symmetry of the map. + */ + private final MapSymmetry symmetry; + + /** + * Factor to multiply cooldowns by. */ private int[] rubbleArray; /** - * How much lead is on each square + * How much lead is on each square. */ private final int[] leadArray; /** - * The random seed contained in the map file + * The random seed contained in the map file. */ private final int seed; /** - * The maximum number of rounds in the game + * The maximum number of rounds in the game. */ private final int rounds; /** - * The name of the map + * The name of the map. */ private final String mapName; @@ -57,7 +62,7 @@ public strictfp class LiveMap { private final AnomalyScheduleEntry[] anomalySchedule; /** - * Index of next anomaly to occur (excluding Singularity which always occurs) + * Index of next anomaly to occur (excluding Singularity which always occurs). */ private int nextAnomalyIndex; @@ -81,6 +86,7 @@ public LiveMap(int width, this.seed = seed; this.rounds = rounds; this.mapName = mapName; + this.symmetry = MapSymmetry.ROTATIONAL; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); this.rubbleArray = new int[width * height]; Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 @@ -100,6 +106,7 @@ public LiveMap(int width, int seed, int rounds, String mapName, + MapSymmetry symmetry, RobotInfo[] initialBodies, int[] rubbleArray, int[] leadArray, @@ -110,6 +117,7 @@ public LiveMap(int width, this.seed = seed; this.rounds = rounds; this.mapName = mapName; + this.symmetry = symmetry; this.initialBodies = Arrays.copyOf(initialBodies, initialBodies.length); this.rubbleArray = new int[rubbleArray.length]; for (int i = 0; i < rubbleArray.length; i++) { @@ -136,8 +144,8 @@ public LiveMap(int width, * @param gm the LiveMap to copy. */ public LiveMap(LiveMap gm) { - this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.initialBodies, - gm.rubbleArray, gm.leadArray, gm.anomalySchedule); + this(gm.width, gm.height, gm.origin, gm.seed, gm.rounds, gm.mapName, gm.symmetry, + gm.initialBodies, gm.rubbleArray, gm.leadArray, gm.anomalySchedule); } @Override @@ -190,9 +198,9 @@ public int getWidth() { } /** - * Returns the height of this map. + * Returns the height of the map. * - * @return the height of this map. + * @return the height of the map */ public int getHeight() { return height; @@ -201,12 +209,21 @@ public int getHeight() { /** * Returns the name of the map. * - * @return the name o the map. + * @return the name of the map */ public String getMapName() { return mapName; } + /** + * Returns the symmetry of the map. + * + * @return the symmetry of the map + */ + public MapSymmetry getSymmetry() { + return symmetry; + } + /** * Determines whether or not the location at the specified * coordinates is on the map. The coordinate should be a shifted one diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 5367f1a8..deeb1b8f 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -11,8 +11,6 @@ */ public class MapBuilder { - public enum MapSymmetry {rotational, horizontal, vertical}; - public String name; public int width; public int height; @@ -35,7 +33,7 @@ public MapBuilder(String name, int width, int height, int originX, int originY, this.bodies = new ArrayList<>(); // default values - this.symmetry = MapSymmetry.vertical; + this.symmetry = MapSymmetry.ROTATIONAL; this.idCounter = 0; this.rubbleArray = new int[width * height]; Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 @@ -112,10 +110,10 @@ public int symmetricX(int x) { public int symmetricY(int y, MapSymmetry symmetry) { switch (symmetry) { - case vertical: + case VERTICAL: return y; - case horizontal: - case rotational: + case HORIZONTAL: + case ROTATIONAL: default: return height - 1 - y; } @@ -123,10 +121,10 @@ public int symmetricY(int y, MapSymmetry symmetry) { public int symmetricX(int x, MapSymmetry symmetry) { switch (symmetry) { - case horizontal: + case HORIZONTAL: return x; - case vertical: - case rotational: + case VERTICAL: + case ROTATIONAL: default: return width - 1 - x; } @@ -162,7 +160,7 @@ public void setSymmetricLead(int x, int y, int value) { public LiveMap build() { return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, - bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray, leadArray, + symmetry, bodies.toArray(new RobotInfo[bodies.size()]), rubbleArray, leadArray, anomalySchedule.toArray(new AnomalyScheduleEntry[anomalySchedule.size()])); } @@ -222,9 +220,10 @@ public void assertIsValid() { // assert rubble, lead, and Archon symmetry ArrayList allMapSymmetries = getSymmetry(robots); System.out.println("This map has the following symmetries: " + allMapSymmetries); - if (allMapSymmetries.isEmpty()) { + if (allMapSymmetries.isEmpty()) throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); - } + if (!allMapSymmetries.contains(this.symmetry)) + throw new RuntimeException("This map is supposed to have " + this.symmetry + " symmetry, but it doesn't"); } public boolean onTheMap(MapLocation loc) { @@ -241,9 +240,9 @@ public MapLocation indexToLocation(int idx) { */ private ArrayList getSymmetry(RobotInfo[] robots) { ArrayList possible = new ArrayList(); - possible.add(MapSymmetry.vertical); - possible.add(MapSymmetry.horizontal); - possible.add(MapSymmetry.rotational); + possible.add(MapSymmetry.ROTATIONAL); + possible.add(MapSymmetry.HORIZONTAL); + possible.add(MapSymmetry.VERTICAL); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { diff --git a/engine/src/main/battlecode/world/MapSymmetry.java b/engine/src/main/battlecode/world/MapSymmetry.java new file mode 100644 index 00000000..3a9d1636 --- /dev/null +++ b/engine/src/main/battlecode/world/MapSymmetry.java @@ -0,0 +1,10 @@ +package battlecode.world; + +/** + * The different kinds of map symmetry. + */ +public enum MapSymmetry { + ROTATIONAL, + HORIZONTAL, + VERTICAL, +} From 03df0c1b12eb1d2ca2b2052a589e16ca6d5842aa Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 9 Oct 2021 12:36:42 -0400 Subject: [PATCH 162/413] added a draft schema --- draft_schema.fbs | 304 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 draft_schema.fbs diff --git a/draft_schema.fbs b/draft_schema.fbs new file mode 100644 index 00000000..24698fcd --- /dev/null +++ b/draft_schema.fbs @@ -0,0 +1,304 @@ +namespace battlecode.schema; + +/// A vector in two-dimensional space. Discrete space, of course. +/// Defaults to the 0 vector. +struct Vec { + x: int = 0; + y: int = 0; +} + +/// A table of vectors. +table VecTable { + xs: [int]; + ys: [int]; +} + + +/// A table of RGB values. +table RGBTable { + red: [int]; + green: [int]; + blue: [int]; +} + +/// The possible types of things that can exist. +/// Note that bullets are not treated as bodies. +enum BodyType : byte { + + // Core unit types + MINER, + ARCHON, + BUILDER, + LABORATORY, + + // Combat units + GUARD, + GUARD_TURRET, + ARCHER, + ARCHER_TURRET, + WIZARD, + WIZARD_TURRET +} + +/// A list of new bodies to be placed on the map. +table SpawnedBodyTable { + /// The numeric ID of the new bodies. + /// Will never be negative. + /// There will only be one body with a particular ID at a time. + /// So, there will never be two robots with the same ID, or a robot and + /// a building with the same ID. + robotIDs: [int]; + /// The teams of the new bodies. + teamIDs: [byte]; + /// The types of the new bodies. + types: [BodyType]; + /// The locations of the bodies. + locs: VecTable; + /// the amount of influence paid to create these bodies + /// for initial Enlightenment Centers, this is the amount of influence + /// needed to take over + influences: [int]; +} + +/// The map a round is played on. +table GameMap { + /// The name of a map. + name: string; + /// The bottom corner of the map. + minCorner: Vec; + /// The top corner of the map. + maxCorner: Vec; + /// The bodies on the map. + bodies: SpawnedBodyTable; + /// The random seed of the map. + randomSeed: int; + /// The factor to divide cooldowns by + passability: [double]; +} + +/// Actions that can be performed. +/// Purely aesthetic; have no actual effect on simulation. +/// (Although the simulation may want to track the 'parents' of +/// particular robots.) +/// Actions may have 'targets', which are the units on which +/// the actions were performed. +enum Action : byte { + ATTACK, // combat unit types + DAZZLE, // wizard + SPAWN_UNIT, //archon + UPGRADE, //buldings + MINE, // miner + BUILD, // builder + CONVERT_GOLD, // for alchemist laboratory +} + +// Metadata + +/// Metadata about all bodies of a particular type. +table BodyTypeMetadata { + type: BodyType; + spawnSource: BodyType; + actionCooldown: float; + actionRadiusSquared: int; + visionRadiusSquared: int; + moveCooldown: float; + bytecodeLimit: int; + level: int; + dps: int; + hp: int; +} + +/// Data relevant to a particular team. +table TeamData { + /// The name of the team. + name: string; + /// The java package the team uses. + packageName: string; + /// The ID of the team this data pertains to. + teamID: byte; +} + +// Profiler tables + +/// These tables are set-up so that they match closely with speedscope's file format documented at +/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. +/// The client uses speedscope to show the recorded data in an interactive interface. + +/// A single event in a profile. Represents either an open event (meaning a +/// method has been entered) or a close event (meaning the method was exited). +table ProfilerEvent { + /// Whether this is an open event (true) or a close event (false). + isOpen: bool; + /// The bytecode counter at the time the event occurred. + at: int; + /// The index of the method name in the ProfilerFile.frames array. + frame: int; +} + +/// A profile contains all events and is labeled with a name. +table ProfilerProfile { + /// The display-friendly name of the profile. + name: string; + /// The events that occurred in the profile. + events: [ProfilerEvent]; +} + +/// A profiler file is a collection of profiles. +/// When profiling is enabled there is one of these per team per match. +table ProfilerFile { + /// The method names that are referred to in the events. + frames: [string]; + /// The recorded profiles, one per robot. + profiles: [ProfilerProfile]; +} + +/// Events + +/// An Event is a single step that needs to be processed. +/// A saved game simply consists of a long list of Events. +/// Events can be divided by either being sent separately (e.g. as separate +/// websocket messages), or by being wrapped with a GameWrapper. +/// A game consists of a series of matches; a match consists of a series of +/// rounds, and is played on a single map. Each round is a single simulation +/// step. +union Event { + /// There should only be one GameHeader, at the start of the stream. + GameHeader, + /// There should be one MatchHeader at the start of each match. + MatchHeader, + /// A single simulation step. A round may be skipped if + /// nothing happens during its time. + Round, + /// There should be one MatchFooter at the end of each simulation step. + MatchFooter, + /// There should only be one GameFooter, at the end of the stream. + GameFooter +} + +/// The first event sent in the game. Contains all metadata about the game. +table GameHeader { + /// The version of the spec this game complies with. + specVersion: string; + /// The teams participating in the game. + teams: [TeamData]; + /// Information about all body types in the game. + bodyTypeMetadata: [BodyTypeMetadata]; +} + +/// The final event sent in the game. +table GameFooter { + /// The ID of the winning team of the game. + winner: byte; +} + +/// Sent to start a match. +table MatchHeader { + /// The map the match was played on. + map: GameMap; + /// The maximum number of rounds in this match. + maxRounds: int; +} + +/// Sent to end a match. +table MatchFooter { + /// The ID of the winning team. + winner: byte; + /// The number of rounds played. + totalRounds: int; + /// Profiler data for team A and B if profiling is enabled. + profilerFiles: [ProfilerFile]; +} + +/// A single time-step in a Game. +/// The bulk of the data in the file is stored in tables like this. +/// Note that a struct-of-arrays format is more space efficient than an array- +/// of-structs. +table Round { + /// The IDs of teams in the Game. + teamIDs: [int]; + + /// The IDs of bodies that moved. + movedIDs: [int]; + /// The new locations of bodies that have moved. + movedLocs: VecTable; + + /// New bodies. + spawnedBodies: SpawnedBodyTable; + + /// The IDs of bodies that died. + diedIDs: [int]; + + /// The IDs of robots that performed actions. + /// IDs may repeat. + actionIDs: [int]; + /// The actions performed. These actions allow us to track how much soup or dirt a body carries. + actions: [Action]; + /// The 'targets' of the performed actions. Actions without targets may have any value + actionTargets: [int]; + + /// The IDs of bodies that set indicator dots + indicatorDotIDs: [int]; + /// The location of the indicator dots + indicatorDotLocs: VecTable; + /// The RGB values of the indicator dots + indicatorDotRGBs: RGBTable; + + /// The IDs of bodies that set indicator lines + indicatorLineIDs: [int]; + /// The start location of the indicator lines + indicatorLineStartLocs: VecTable; + /// The end location of the indicator lines + indicatorLineEndLocs: VecTable; + /// The RGB values of the indicator lines + indicatorLineRGBs: RGBTable; + + /// All logs sent this round. + /// Messages from a particular robot in this round start on a new line, and + /// have a header: + /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' + /// $TEAM = 'A' | 'B' + /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' + /// $ID = a number + /// $ROUND = a number + /// The header is not necessarily followed by a newline. + /// This header should only be sent once per robot per round (although + /// players may forge it, so don't crash if you get strange input.) + /// + /// You should try to only read this value once, and cache it. Reading + /// strings from a flatbuffer is much less efficient than reading other + /// buffers, because they need to be copied into an environment-provided + /// buffer and validated. + /// + /// (haha i guess you can never really escape string parsing can you) + logs: string; // TODO: maybe split into more arrays + + /// The first sent Round in a match should have index 1. (The starting state, + /// created by the MatchHeader, can be thought to have index 0.) + /// It should increase by one for each following round. + roundID: int; + + /// The IDs of player bodies. + bytecodeIDs: [int]; + /// The bytecodes used by the player bodies. + bytecodesUsed: [int]; +} + +/// Necessary due to flatbuffers requiring unions to be wrapped in tables. +table EventWrapper { + e: Event; +} + +/// If events are not otherwise delimited, this wrapper structure +/// allows a game to be stored in a single buffer. +/// The first event will be a GameHeader; the last event will be a GameFooter. +/// matchHeaders[0] is the index of the 0th match header in the event stream, +/// corresponding to matchFooters[0]. These indices allow quick traversal of +/// the file. +table GameWrapper { + /// The series of events comprising the game. + events: [EventWrapper]; + /// The indices of the headers of the matches, in order. + matchHeaders: [int]; + /// The indices of the footers of the matches, in order. + matchFooters: [int]; +} From f2424ea442436815f48916a3b8ff6a281b94d090 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 23 Oct 2021 11:32:38 -0400 Subject: [PATCH 163/413] Move schema file --- draft_schema.fbs => schema/draft_schema.fbs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename draft_schema.fbs => schema/draft_schema.fbs (100%) diff --git a/draft_schema.fbs b/schema/draft_schema.fbs similarity index 100% rename from draft_schema.fbs rename to schema/draft_schema.fbs From fcaf1e5ca507e88d1159993f7e6ea42fa5c61efa Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 30 Oct 2021 00:38:09 -0400 Subject: [PATCH 164/413] Update schema --- schema/draft_schema.fbs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 24698fcd..b1b88241 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,10 +54,8 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the amount of influence paid to create these bodies - /// for initial Enlightenment Centers, this is the amount of influence - /// needed to take over - influences: [int]; + /// the level of the body + level: [int]; } /// The map a round is played on. @@ -89,7 +87,12 @@ enum Action : byte { UPGRADE, //buldings MINE, // miner BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory + CONVERT_GOLD, // for alchemist laboratory. + ATTACKED, // when a body is attacked + TRANSFORM_PORTABLE, + TRANSFORM_TURRET, + UPGRADE, // builder upgrades building, + REPAIR // builder repairs building } // Metadata @@ -103,9 +106,10 @@ table BodyTypeMetadata { visionRadiusSquared: int; moveCooldown: float; bytecodeLimit: int; - level: int; dps: int; hp: int; + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level } /// Data relevant to a particular team. @@ -217,6 +221,9 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; + teamLead: [int]; + teamGold: [int]; + /// The IDs of bodies that moved. movedIDs: [int]; /// The new locations of bodies that have moved. From 9be76978296b1f0e36653d83be4a09262fd8c69d Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Sat, 30 Oct 2021 12:30:03 -0400 Subject: [PATCH 165/413] Some schema changes --- schema/draft_schema.fbs | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b1b88241..23a8f802 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,8 +54,6 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the level of the body - level: [int]; } /// The map a round is played on. @@ -89,10 +87,10 @@ enum Action : byte { BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. ATTACKED, // when a body is attacked - TRANSFORM_PORTABLE, - TRANSFORM_TURRET, + TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, - REPAIR // builder repairs building + REPAIR, // builder repairs building + CHANGE_HP } // Metadata @@ -243,6 +241,11 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; + /// The IDs of the robots who changed their indicator strings + indicationStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicationStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots @@ -259,25 +262,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - /// All logs sent this round. - /// Messages from a particular robot in this round start on a new line, and - /// have a header: - /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - /// $TEAM = 'A' | 'B' - /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - /// $ID = a number - /// $ROUND = a number - /// The header is not necessarily followed by a newline. - /// This header should only be sent once per robot per round (although - /// players may forge it, so don't crash if you get strange input.) - /// - /// You should try to only read this value once, and cache it. Reading - /// strings from a flatbuffer is much less efficient than reading other - /// buffers, because they need to be copied into an environment-provided - /// buffer and validated. - /// - /// (haha i guess you can never really escape string parsing can you) - logs: string; // TODO: maybe split into more arrays + //logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) From 5ddac8bd834ebbc43e3a040881a45561599549b4 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 11:18:37 -0400 Subject: [PATCH 166/413] Add repaired action --- schema/draft_schema.fbs | 11 ++++++----- schema/package-lock.json | 19 ------------------- 2 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 schema/package-lock.json diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 23a8f802..01e8db8a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -82,7 +82,7 @@ enum Action : byte { ATTACK, // combat unit types DAZZLE, // wizard SPAWN_UNIT, //archon - UPGRADE, //buldings + UPGRADE, //buildings MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. @@ -90,7 +90,8 @@ enum Action : byte { TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, REPAIR, // builder repairs building - CHANGE_HP + CHANGE_HP, + REPAIRED // prototype becomes a turret } // Metadata @@ -102,10 +103,10 @@ table BodyTypeMetadata { actionCooldown: float; actionRadiusSquared: int; visionRadiusSquared: int; - moveCooldown: float; + movingCooldown: float; bytecodeLimit: int; - dps: int; - hp: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level } diff --git a/schema/package-lock.json b/schema/package-lock.json deleted file mode 100644 index 278729f5..00000000 --- a/schema/package-lock.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "battlecode-schema", - "version": "2021.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/flatbuffers": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", - "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", - "dev": true - }, - "flatbuffers": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", - "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" - } - } -} From 87a15066e35ab7b44c4545803e8391bf4e129ee1 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:30:21 -0400 Subject: [PATCH 167/413] added lead to map --- schema/draft_schema.fbs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 01e8db8a..d26f1681 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -70,6 +70,13 @@ table GameMap { randomSeed: int; /// The factor to divide cooldowns by passability: [double]; + + //lead locations + + // a vectable of lead cords + lead_locations: VecTable; + //inital lead amounts + initial_lead: [double]; } /// Actions that can be performed. From ba26eb53e504a16a8337d4c0812c9164bb4a47d2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 12:21:46 -0400 Subject: [PATCH 168/413] Change terminology --- client/playback/src/gameworld.ts | 14 +------------- schema/draft_schema.fbs | 2 +- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 84e63950..af0ab7f2 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -14,28 +14,16 @@ export type DeadBodiesSchema = { y: Int32Array, } -export type EmpowerSchema = { - id: Int32Array, - x: Int32Array, - y: Int32Array - team: Int8Array, - radius: Int32Array -} - export type BodiesSchema = { id: Int32Array, team: Int8Array, type: Int8Array, x: Int32Array, y: Int32Array, - influence: Int32Array; - conviction: Int32Array; flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? ability: Int8Array, - bid: Int32Array, - parent: Int32Array, - income: Int32Array + parent: Int32Array }; // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index d26f1681..b4bf9840 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -98,7 +98,7 @@ enum Action : byte { UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, - REPAIRED // prototype becomes a turret + FULLY_REPAIRED // prototype becomes a turret } // Metadata From bbb45163c71e0a2862145aad35198c6ed2d07e1f Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:51:46 -0400 Subject: [PATCH 169/413] added lead increase contants and upgrade costs --- schema/draft_schema.fbs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b4bf9840..f1b0b68a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -72,7 +72,7 @@ table GameMap { passability: [double]; //lead locations - + // a vectable of lead cords lead_locations: VecTable; //inital lead amounts @@ -116,6 +116,7 @@ table BodyTypeMetadata { hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -185,6 +186,14 @@ union Event { GameFooter } +table Constants{ + //amounts of resources added to each block per round + leadAdditiveIncease: double; + goldAdditiveIncease: double; + increase_period: int; +} + + /// The first event sent in the game. Contains all metadata about the game. table GameHeader { /// The version of the spec this game complies with. @@ -193,8 +202,14 @@ table GameHeader { teams: [TeamData]; /// Information about all body types in the game. bodyTypeMetadata: [BodyTypeMetadata]; + + //game constants + constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. From bc86886cf1992b07bffac48e4bf5a7f6afbdc712 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:18:27 -0500 Subject: [PATCH 170/413] Begin to update gameworld --- client/playback/src/gameworld.ts | 5 +- schema/battlecode.fbs | 150 +++++++-------- schema/draft_schema.fbs | 319 ------------------------------- 3 files changed, 68 insertions(+), 406 deletions(-) delete mode 100644 schema/draft_schema.fbs diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index af0ab7f2..00ad1187 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -23,7 +23,9 @@ export type BodiesSchema = { flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? ability: Int8Array, - parent: Int32Array + parent: Int32Array, + hp: Int32Array, + level: Int8Array }; // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data @@ -35,6 +37,7 @@ export type MapStats = { randomSeed: number, passability: Float64Array, // double + lead: Int32Array; getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 57a2963c..f1b0b68a 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -24,16 +24,20 @@ table RGBTable { /// The possible types of things that can exist. /// Note that bullets are not treated as bodies. enum BodyType : byte { - /// Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - ///can be neutral until captured - ENLIGHTENMENT_CENTER, - /// politicians use their influence to self destruct and capture other units - POLITICIAN, - /// slanderers generate passive influence for the enlightenment center that created them - /// they turn into politicians at some point, and can only be identified by slanderers. - SLANDERER, - /// have the ability to identify slanderers - MUCKRAKER, + + // Core unit types + MINER, + ARCHON, + BUILDER, + LABORATORY, + + // Combat units + GUARD, + GUARD_TURRET, + ARCHER, + ARCHER_TURRET, + WIZARD, + WIZARD_TURRET } /// A list of new bodies to be placed on the map. @@ -50,10 +54,6 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the amount of influence paid to create these bodies - /// for initial Enlightenment Centers, this is the amount of influence - /// needed to take over - influences: [int]; } /// The map a round is played on. @@ -70,6 +70,13 @@ table GameMap { randomSeed: int; /// The factor to divide cooldowns by passability: [double]; + + //lead locations + + // a vectable of lead cords + lead_locations: VecTable; + //inital lead amounts + initial_lead: [double]; } /// Actions that can be performed. @@ -79,63 +86,37 @@ table GameMap { /// Actions may have 'targets', which are the units on which /// the actions were performed. enum Action : byte { - /// Politicians self-destruct and affect nearby bodies. - /// Target: radius squared - EMPOWER, - /// Slanderers passively generate influence for the - /// Enlightenment Center that created them. - /// Target: parent ID - EMBEZZLE, - /// Slanderers turn into Politicians. - /// Target: none - CAMOUFLAGE, - /// Muckrakers can expose a slanderer. - /// Target: an enemy body - EXPOSE, - /// Units can change their flag. - /// Target: new flag value - SET_FLAG, - /// Builds a unit. - /// Target: spawned unit - SPAWN_UNIT, - /// Places a bid. - /// Target: bid value - PLACE_BID, - /// A robot can change team after being empowered, - /// or when a Enlightenment Center is taken over. - /// Target: new robotID - CHANGE_TEAM, - /// A robot's influence changes. - /// Target: delta value - CHANGE_INFLUENCE, - /// A robot's conviction changes. - /// Target: delta value, i.e. red 5 -> blue 3 is -2 - CHANGE_CONVICTION, - /// Dies due to an uncaught exception. - /// Target: none - DIE_EXCEPTION + ATTACK, // combat unit types + DAZZLE, // wizard + SPAWN_UNIT, //archon + UPGRADE, //buildings + MINE, // miner + BUILD, // builder + CONVERT_GOLD, // for alchemist laboratory. + ATTACKED, // when a body is attacked + TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state + UPGRADE, // builder upgrades building, + REPAIR, // builder repairs building + CHANGE_HP, + FULLY_REPAIRED // prototype becomes a turret } // Metadata /// Metadata about all bodies of a particular type. table BodyTypeMetadata { - /// The relevant type. type: BodyType; - /// The spawn source. spawnSource: BodyType; - /// the convictionRatio of this type - convictionRatio: float; - /// cooldown of this type actionCooldown: float; - /// action radius if this type actionRadiusSquared: int; - /// sensor radius squared for this type - sensorRadiusSquared: int; - /// detection radius of this type - detectionRadiusSquared: int; - /// bytecode limit for this type + visionRadiusSquared: int; + movingCooldown: float; bytecodeLimit: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -205,6 +186,14 @@ union Event { GameFooter } +table Constants{ + //amounts of resources added to each block per round + leadAdditiveIncease: double; + goldAdditiveIncease: double; + increase_period: int; +} + + /// The first event sent in the game. Contains all metadata about the game. table GameHeader { /// The version of the spec this game complies with. @@ -213,8 +202,14 @@ table GameHeader { teams: [TeamData]; /// Information about all body types in the game. bodyTypeMetadata: [BodyTypeMetadata]; + + //game constants + constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. @@ -246,10 +241,9 @@ table MatchFooter { table Round { /// The IDs of teams in the Game. teamIDs: [int]; - /// The number of votes the teams get, 0 or 1. - teamVotes: [int]; - /// The ID of the Enlightenment Center got the bid. - teamBidderIDs: [int]; + + teamLead: [int]; + teamGold: [int]; /// The IDs of bodies that moved. movedIDs: [int]; @@ -270,6 +264,11 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; + /// The IDs of the robots who changed their indicator strings + indicationStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicationStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots @@ -286,25 +285,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - /// All logs sent this round. - /// Messages from a particular robot in this round start on a new line, and - /// have a header: - /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - /// $TEAM = 'A' | 'B' - /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - /// $ID = a number - /// $ROUND = a number - /// The header is not necessarily followed by a newline. - /// This header should only be sent once per robot per round (although - /// players may forge it, so don't crash if you get strange input.) - /// - /// You should try to only read this value once, and cache it. Reading - /// strings from a flatbuffer is much less efficient than reading other - /// buffers, because they need to be copied into an environment-provided - /// buffer and validated. - /// - /// (haha i guess you can never really escape string parsing can you) - logs: string; + //logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) @@ -315,9 +296,6 @@ table Round { bytecodeIDs: [int]; /// The bytecodes used by the player bodies. bytecodesUsed: [int]; - - /// Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - teamNumBuffs: [int]; } /// Necessary due to flatbuffers requiring unions to be wrapped in tables. diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs deleted file mode 100644 index f1b0b68a..00000000 --- a/schema/draft_schema.fbs +++ /dev/null @@ -1,319 +0,0 @@ -namespace battlecode.schema; - -/// A vector in two-dimensional space. Discrete space, of course. -/// Defaults to the 0 vector. -struct Vec { - x: int = 0; - y: int = 0; -} - -/// A table of vectors. -table VecTable { - xs: [int]; - ys: [int]; -} - - -/// A table of RGB values. -table RGBTable { - red: [int]; - green: [int]; - blue: [int]; -} - -/// The possible types of things that can exist. -/// Note that bullets are not treated as bodies. -enum BodyType : byte { - - // Core unit types - MINER, - ARCHON, - BUILDER, - LABORATORY, - - // Combat units - GUARD, - GUARD_TURRET, - ARCHER, - ARCHER_TURRET, - WIZARD, - WIZARD_TURRET -} - -/// A list of new bodies to be placed on the map. -table SpawnedBodyTable { - /// The numeric ID of the new bodies. - /// Will never be negative. - /// There will only be one body with a particular ID at a time. - /// So, there will never be two robots with the same ID, or a robot and - /// a building with the same ID. - robotIDs: [int]; - /// The teams of the new bodies. - teamIDs: [byte]; - /// The types of the new bodies. - types: [BodyType]; - /// The locations of the bodies. - locs: VecTable; -} - -/// The map a round is played on. -table GameMap { - /// The name of a map. - name: string; - /// The bottom corner of the map. - minCorner: Vec; - /// The top corner of the map. - maxCorner: Vec; - /// The bodies on the map. - bodies: SpawnedBodyTable; - /// The random seed of the map. - randomSeed: int; - /// The factor to divide cooldowns by - passability: [double]; - - //lead locations - - // a vectable of lead cords - lead_locations: VecTable; - //inital lead amounts - initial_lead: [double]; -} - -/// Actions that can be performed. -/// Purely aesthetic; have no actual effect on simulation. -/// (Although the simulation may want to track the 'parents' of -/// particular robots.) -/// Actions may have 'targets', which are the units on which -/// the actions were performed. -enum Action : byte { - ATTACK, // combat unit types - DAZZLE, // wizard - SPAWN_UNIT, //archon - UPGRADE, //buildings - MINE, // miner - BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory. - ATTACKED, // when a body is attacked - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state - UPGRADE, // builder upgrades building, - REPAIR, // builder repairs building - CHANGE_HP, - FULLY_REPAIRED // prototype becomes a turret -} - -// Metadata - -/// Metadata about all bodies of a particular type. -table BodyTypeMetadata { - type: BodyType; - spawnSource: BodyType; - actionCooldown: float; - actionRadiusSquared: int; - visionRadiusSquared: int; - movingCooldown: float; - bytecodeLimit: int; - dps: int; // dps at lowest level - hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; -} - -/// Data relevant to a particular team. -table TeamData { - /// The name of the team. - name: string; - /// The java package the team uses. - packageName: string; - /// The ID of the team this data pertains to. - teamID: byte; -} - -// Profiler tables - -/// These tables are set-up so that they match closely with speedscope's file format documented at -/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. -/// The client uses speedscope to show the recorded data in an interactive interface. - -/// A single event in a profile. Represents either an open event (meaning a -/// method has been entered) or a close event (meaning the method was exited). -table ProfilerEvent { - /// Whether this is an open event (true) or a close event (false). - isOpen: bool; - /// The bytecode counter at the time the event occurred. - at: int; - /// The index of the method name in the ProfilerFile.frames array. - frame: int; -} - -/// A profile contains all events and is labeled with a name. -table ProfilerProfile { - /// The display-friendly name of the profile. - name: string; - /// The events that occurred in the profile. - events: [ProfilerEvent]; -} - -/// A profiler file is a collection of profiles. -/// When profiling is enabled there is one of these per team per match. -table ProfilerFile { - /// The method names that are referred to in the events. - frames: [string]; - /// The recorded profiles, one per robot. - profiles: [ProfilerProfile]; -} - -/// Events - -/// An Event is a single step that needs to be processed. -/// A saved game simply consists of a long list of Events. -/// Events can be divided by either being sent separately (e.g. as separate -/// websocket messages), or by being wrapped with a GameWrapper. -/// A game consists of a series of matches; a match consists of a series of -/// rounds, and is played on a single map. Each round is a single simulation -/// step. -union Event { - /// There should only be one GameHeader, at the start of the stream. - GameHeader, - /// There should be one MatchHeader at the start of each match. - MatchHeader, - /// A single simulation step. A round may be skipped if - /// nothing happens during its time. - Round, - /// There should be one MatchFooter at the end of each simulation step. - MatchFooter, - /// There should only be one GameFooter, at the end of the stream. - GameFooter -} - -table Constants{ - //amounts of resources added to each block per round - leadAdditiveIncease: double; - goldAdditiveIncease: double; - increase_period: int; -} - - -/// The first event sent in the game. Contains all metadata about the game. -table GameHeader { - /// The version of the spec this game complies with. - specVersion: string; - /// The teams participating in the game. - teams: [TeamData]; - /// Information about all body types in the game. - bodyTypeMetadata: [BodyTypeMetadata]; - - //game constants - constants: Constants; -} - - - - -/// The final event sent in the game. -table GameFooter { - /// The ID of the winning team of the game. - winner: byte; -} - -/// Sent to start a match. -table MatchHeader { - /// The map the match was played on. - map: GameMap; - /// The maximum number of rounds in this match. - maxRounds: int; -} - -/// Sent to end a match. -table MatchFooter { - /// The ID of the winning team. - winner: byte; - /// The number of rounds played. - totalRounds: int; - /// Profiler data for team A and B if profiling is enabled. - profilerFiles: [ProfilerFile]; -} - -/// A single time-step in a Game. -/// The bulk of the data in the file is stored in tables like this. -/// Note that a struct-of-arrays format is more space efficient than an array- -/// of-structs. -table Round { - /// The IDs of teams in the Game. - teamIDs: [int]; - - teamLead: [int]; - teamGold: [int]; - - /// The IDs of bodies that moved. - movedIDs: [int]; - /// The new locations of bodies that have moved. - movedLocs: VecTable; - - /// New bodies. - spawnedBodies: SpawnedBodyTable; - - /// The IDs of bodies that died. - diedIDs: [int]; - - /// The IDs of robots that performed actions. - /// IDs may repeat. - actionIDs: [int]; - /// The actions performed. These actions allow us to track how much soup or dirt a body carries. - actions: [Action]; - /// The 'targets' of the performed actions. Actions without targets may have any value - actionTargets: [int]; - - /// The IDs of the robots who changed their indicator strings - indicationStringIDs: [int]; - /// The messages of the robots who changed their indicator strings - indicationStrings: [string]; - - /// The IDs of bodies that set indicator dots - indicatorDotIDs: [int]; - /// The location of the indicator dots - indicatorDotLocs: VecTable; - /// The RGB values of the indicator dots - indicatorDotRGBs: RGBTable; - - /// The IDs of bodies that set indicator lines - indicatorLineIDs: [int]; - /// The start location of the indicator lines - indicatorLineStartLocs: VecTable; - /// The end location of the indicator lines - indicatorLineEndLocs: VecTable; - /// The RGB values of the indicator lines - indicatorLineRGBs: RGBTable; - - //logs have been replaced with indicator strings - - /// The first sent Round in a match should have index 1. (The starting state, - /// created by the MatchHeader, can be thought to have index 0.) - /// It should increase by one for each following round. - roundID: int; - - /// The IDs of player bodies. - bytecodeIDs: [int]; - /// The bytecodes used by the player bodies. - bytecodesUsed: [int]; -} - -/// Necessary due to flatbuffers requiring unions to be wrapped in tables. -table EventWrapper { - e: Event; -} - -/// If events are not otherwise delimited, this wrapper structure -/// allows a game to be stored in a single buffer. -/// The first event will be a GameHeader; the last event will be a GameFooter. -/// matchHeaders[0] is the index of the 0th match header in the event stream, -/// corresponding to matchFooters[0]. These indices allow quick traversal of -/// the file. -table GameWrapper { - /// The series of events comprising the game. - events: [EventWrapper]; - /// The indices of the headers of the matches, in order. - matchHeaders: [int]; - /// The indices of the footers of the matches, in order. - matchFooters: [int]; -} From 9bcfd888a17f200a4c7108e4e647d271d6fc6206 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:34:19 -0500 Subject: [PATCH 171/413] Compile typescript for current schema --- schema/battlecode.fbs | 1 - schema/ts/battlecode_generated.ts | 956 ++++++++++++++++++------------ 2 files changed, 561 insertions(+), 396 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index f1b0b68a..76f65df9 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -89,7 +89,6 @@ enum Action : byte { ATTACK, // combat unit types DAZZLE, // wizard SPAWN_UNIT, //archon - UPGRADE, //buildings MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 9e0b103f..d8474d3c 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -9,27 +9,16 @@ import { flatbuffers } from "flatbuffers" */ export namespace battlecode.schema{ export enum BodyType{ - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - ENLIGHTENMENT_CENTER= 0, - - /** - * politicians use their influence to self destruct and capture other units - */ - POLITICIAN= 1, - - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - SLANDERER= 2, - - /** - * have the ability to identify slanderers - */ - MUCKRAKER= 3 + MINER= 0, + ARCHON= 1, + BUILDER= 2, + LABORATORY= 3, + GUARD= 4, + GUARD_TURRET= 5, + ARCHER= 6, + ARCHER_TURRET= 7, + WIZARD= 8, + WIZARD_TURRET= 9 }}; /** @@ -44,73 +33,18 @@ export enum BodyType{ */ export namespace battlecode.schema{ export enum Action{ - /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared - */ - EMPOWER= 0, - - /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID - */ - EMBEZZLE= 1, - - /** - * Slanderers turn into Politicians. - * Target: none - */ - CAMOUFLAGE= 2, - - /** - * Muckrakers can expose a slanderer. - * Target: an enemy body - */ - EXPOSE= 3, - - /** - * Units can change their flag. - * Target: new flag value - */ - SET_FLAG= 4, - - /** - * Builds a unit. - * Target: spawned unit - */ - SPAWN_UNIT= 5, - - /** - * Places a bid. - * Target: bid value - */ - PLACE_BID= 6, - - /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID - */ - CHANGE_TEAM= 7, - - /** - * A robot's influence changes. - * Target: delta value - */ - CHANGE_INFLUENCE= 8, - - /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 - */ - CHANGE_CONVICTION= 9, - - /** - * Dies due to an uncaught exception. - * Target: none - */ - DIE_EXCEPTION= 10 + ATTACK= 0, + DAZZLE= 1, + SPAWN_UNIT= 2, + MINE= 3, + BUILD= 4, + CONVERT_GOLD= 5, + ATTACKED= 6, + TRANSFORM= 7, + UPGRADE= 8, + REPAIR= 9, + CHANGE_HP= 10, + FULLY_REPAIRED= 11 }}; /** @@ -712,40 +646,11 @@ locs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; -/** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - * - * @param number index - * @returns number - */ -influences(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -influencesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -influencesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - /** * @param flatbuffers.Builder builder */ static startSpawnedBodyTable(builder:flatbuffers.Builder) { - builder.startObject(5); + builder.startObject(4); }; /** @@ -843,35 +748,6 @@ static addLocs(builder:flatbuffers.Builder, locsOffset:flatbuffers.Offset) { builder.addFieldOffset(3, locsOffset, 0); }; -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset influencesOffset - */ -static addInfluences(builder:flatbuffers.Builder, influencesOffset:flatbuffers.Offset) { - builder.addFieldOffset(4, influencesOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createInfluencesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startInfluencesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -}; - /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -881,13 +757,12 @@ static endSpawnedBodyTable(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createSpawnedBodyTable(builder:flatbuffers.Builder, robotIDsOffset:flatbuffers.Offset, teamIDsOffset:flatbuffers.Offset, typesOffset:flatbuffers.Offset, locsOffset:flatbuffers.Offset, influencesOffset:flatbuffers.Offset):flatbuffers.Offset { +static createSpawnedBodyTable(builder:flatbuffers.Builder, robotIDsOffset:flatbuffers.Offset, teamIDsOffset:flatbuffers.Offset, typesOffset:flatbuffers.Offset, locsOffset:flatbuffers.Offset):flatbuffers.Offset { SpawnedBodyTable.startSpawnedBodyTable(builder); SpawnedBodyTable.addRobotIDs(builder, robotIDsOffset); SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); SpawnedBodyTable.addTypes(builder, typesOffset); SpawnedBodyTable.addLocs(builder, locsOffset); - SpawnedBodyTable.addInfluences(builder, influencesOffset); return SpawnedBodyTable.endSpawnedBodyTable(builder); } } @@ -1005,11 +880,45 @@ passabilityArray():Float64Array|null { return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 16); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +initialLead(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; +}; + +/** + * @returns number + */ +initialLeadLength():number { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Float64Array + */ +initialLeadArray():Float64Array|null { + var offset = this.bb!.__offset(this.bb_pos, 18); + return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startGameMap(builder:flatbuffers.Builder) { - builder.startObject(6); + builder.startObject(8); }; /** @@ -1081,6 +990,43 @@ static startPassabilityVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(8, numElems, 8); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadLocationsOffset + */ +static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(6, leadLocationsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset initialLeadOffset + */ +static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, initialLeadOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(8, data.length, 8); + for (var i = data.length - 1; i >= 0; i--) { + builder.addFloat64(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startInitialLeadVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(8, numElems, 8); +}; + /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -1090,7 +1036,7 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, initialLeadOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); @@ -1098,6 +1044,8 @@ static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, GameMap.addBodies(builder, bodiesOffset); GameMap.addRandomSeed(builder, randomSeed); GameMap.addPassability(builder, passabilityOffset); + GameMap.addLeadLocations(builder, leadLocationsOffset); + GameMap.addInitialLead(builder, initialLeadOffset); return GameMap.endGameMap(builder); } } @@ -1133,90 +1081,123 @@ static getRootAsBodyTypeMetadata(bb:flatbuffers.ByteBuffer, obj?:BodyTypeMetadat }; /** - * The relevant type. - * * @returns battlecode.schema.BodyType */ type():battlecode.schema.BodyType { var offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.ENLIGHTENMENT_CENTER; + return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.MINER; }; /** - * The spawn source. - * * @returns battlecode.schema.BodyType */ spawnSource():battlecode.schema.BodyType { var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.ENLIGHTENMENT_CENTER; + return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.MINER; }; /** - * the convictionRatio of this type - * * @returns number */ -convictionRatio():number { +actionCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** - * cooldown of this type - * * @returns number */ -actionCooldown():number { +actionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 10); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * action radius if this type - * * @returns number */ -actionRadiusSquared():number { +visionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 12); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * sensor radius squared for this type - * * @returns number */ -sensorRadiusSquared():number { +movingCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 14); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** - * detection radius of this type - * * @returns number */ -detectionRadiusSquared():number { +bytecodeLimit():number { var offset = this.bb!.__offset(this.bb_pos, 16); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * bytecode limit for this type - * * @returns number */ -bytecodeLimit():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; +/** + * @returns number + */ +hp():number { + var offset = this.bb!.__offset(this.bb_pos, 20); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @returns number + */ +dpsMul():number { + var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +}; + +/** + * @returns number + */ +hpMul():number { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +}; + +/** + * @param number index + * @returns number + */ +upgradeCosts(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +upgradeCostsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +upgradeCostsArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(8); + builder.startObject(12); }; /** @@ -1224,7 +1205,7 @@ static startBodyTypeMetadata(builder:flatbuffers.Builder) { * @param battlecode.schema.BodyType type */ static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { - builder.addFieldInt8(0, type, battlecode.schema.BodyType.ENLIGHTENMENT_CENTER); + builder.addFieldInt8(0, type, battlecode.schema.BodyType.MINER); }; /** @@ -1232,15 +1213,7 @@ static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { * @param battlecode.schema.BodyType spawnSource */ static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema.BodyType) { - builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.ENLIGHTENMENT_CENTER); -}; - -/** - * @param flatbuffers.Builder builder - * @param number convictionRatio - */ -static addConvictionRatio(builder:flatbuffers.Builder, convictionRatio:number) { - builder.addFieldFloat32(2, convictionRatio, 0.0); + builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.MINER); }; /** @@ -1248,7 +1221,7 @@ static addConvictionRatio(builder:flatbuffers.Builder, convictionRatio:number) { * @param number actionCooldown */ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(3, actionCooldown, 0.0); + builder.addFieldFloat32(2, actionCooldown, 0.0); }; /** @@ -1256,23 +1229,23 @@ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { * @param number actionRadiusSquared */ static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(4, actionRadiusSquared, 0); + builder.addFieldInt32(3, actionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number sensorRadiusSquared + * @param number visionRadiusSquared */ -static addSensorRadiusSquared(builder:flatbuffers.Builder, sensorRadiusSquared:number) { - builder.addFieldInt32(5, sensorRadiusSquared, 0); +static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { + builder.addFieldInt32(4, visionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number detectionRadiusSquared + * @param number movingCooldown */ -static addDetectionRadiusSquared(builder:flatbuffers.Builder, detectionRadiusSquared:number) { - builder.addFieldInt32(6, detectionRadiusSquared, 0); +static addMovingCooldown(builder:flatbuffers.Builder, movingCooldown:number) { + builder.addFieldFloat32(5, movingCooldown, 0.0); }; /** @@ -1280,7 +1253,68 @@ static addDetectionRadiusSquared(builder:flatbuffers.Builder, detectionRadiusSqu * @param number bytecodeLimit */ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { - builder.addFieldInt32(7, bytecodeLimit, 0); + builder.addFieldInt32(6, bytecodeLimit, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number dps + */ +static addDps(builder:flatbuffers.Builder, dps:number) { + builder.addFieldInt32(7, dps, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number hp + */ +static addHp(builder:flatbuffers.Builder, hp:number) { + builder.addFieldInt32(8, hp, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number dpsMul + */ +static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { + builder.addFieldFloat32(9, dpsMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number hpMul + */ +static addHpMul(builder:flatbuffers.Builder, hpMul:number) { + builder.addFieldFloat32(10, hpMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset upgradeCostsOffset + */ +static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, upgradeCostsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startUpgradeCostsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); }; /** @@ -1292,16 +1326,20 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, convictionRatio:number, actionCooldown:number, actionRadiusSquared:number, sensorRadiusSquared:number, detectionRadiusSquared:number, bytecodeLimit:number):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addDps(builder, dps); + BodyTypeMetadata.addHp(builder, hp); + BodyTypeMetadata.addDpsMul(builder, dpsMul); + BodyTypeMetadata.addHpMul(builder, hpMul); + BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } } @@ -1718,98 +1756,199 @@ framesLength():number { * @param battlecode.schema.ProfilerProfile= obj * @returns battlecode.schema.ProfilerProfile */ -profiles(index: number, obj?:battlecode.schema.ProfilerProfile):battlecode.schema.ProfilerProfile|null { - var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? (obj || new battlecode.schema.ProfilerProfile).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +profiles(index: number, obj?:battlecode.schema.ProfilerProfile):battlecode.schema.ProfilerProfile|null { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? (obj || new battlecode.schema.ProfilerProfile).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +}; + +/** + * @returns number + */ +profilesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @param flatbuffers.Builder builder + */ +static startProfilerFile(builder:flatbuffers.Builder) { + builder.startObject(2); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset framesOffset + */ +static addFrames(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, framesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createFramesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startFramesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset profilesOffset + */ +static addProfiles(builder:flatbuffers.Builder, profilesOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, profilesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createProfilesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startProfilesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { + var offset = builder.endObject(); + return offset; +}; + +static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { + ProfilerFile.startProfilerFile(builder); + ProfilerFile.addFrames(builder, framesOffset); + ProfilerFile.addProfiles(builder, profilesOffset); + return ProfilerFile.endProfilerFile(builder); +} +} +} +/** + * @constructor + */ +export namespace battlecode.schema{ +export class Constants { + bb: flatbuffers.ByteBuffer|null = null; + + bb_pos:number = 0; +/** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Constants + */ +__init(i:number, bb:flatbuffers.ByteBuffer):Constants { + this.bb_pos = i; + this.bb = bb; + return this; }; /** - * @returns number + * @param flatbuffers.ByteBuffer bb + * @param Constants= obj + * @returns Constants */ -profilesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +static getRootAsConstants(bb:flatbuffers.ByteBuffer, obj?:Constants):Constants { + return (obj || new Constants).__init(bb.readInt32(bb.position()) + bb.position(), bb); }; /** - * @param flatbuffers.Builder builder + * @returns number */ -static startProfilerFile(builder:flatbuffers.Builder) { - builder.startObject(2); +leadAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; }; /** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset framesOffset + * @returns number */ -static addFrames(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset) { - builder.addFieldOffset(0, framesOffset, 0); +goldAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; }; /** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @returns number */ -static createFramesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addOffset(data[i]); - } - return builder.endVector(); +increasePeriod():number { + var offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @param flatbuffers.Builder builder - * @param number numElems */ -static startFramesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); +static startConstants(builder:flatbuffers.Builder) { + builder.startObject(3); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset profilesOffset + * @param number leadAdditiveIncease */ -static addProfiles(builder:flatbuffers.Builder, profilesOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, profilesOffset, 0); +static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { + builder.addFieldFloat64(0, leadAdditiveIncease, 0.0); }; /** * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @param number goldAdditiveIncease */ -static createProfilesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addOffset(data[i]); - } - return builder.endVector(); +static addGoldAdditiveIncease(builder:flatbuffers.Builder, goldAdditiveIncease:number) { + builder.addFieldFloat64(1, goldAdditiveIncease, 0.0); }; /** * @param flatbuffers.Builder builder - * @param number numElems + * @param number increasePeriod */ -static startProfilesVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); +static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { + builder.addFieldInt32(2, increasePeriod, 0); }; /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset */ -static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { +static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { var offset = builder.endObject(); return offset; }; -static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { - ProfilerFile.startProfilerFile(builder); - ProfilerFile.addFrames(builder, framesOffset); - ProfilerFile.addProfiles(builder, profilesOffset); - return ProfilerFile.endProfilerFile(builder); +static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { + Constants.startConstants(builder); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); + Constants.addGoldAdditiveIncease(builder, goldAdditiveIncease); + Constants.addIncreasePeriod(builder, increasePeriod); + return Constants.endConstants(builder); } } } @@ -1896,11 +2035,20 @@ bodyTypeMetadataLength():number { return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; +/** + * @param battlecode.schema.Constants= obj + * @returns battlecode.schema.Constants|null + */ +constants(obj?:battlecode.schema.Constants):battlecode.schema.Constants|null { + var offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? (obj || new battlecode.schema.Constants).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + /** * @param flatbuffers.Builder builder */ static startGameHeader(builder:flatbuffers.Builder) { - builder.startObject(3); + builder.startObject(4); }; /** @@ -1969,6 +2117,14 @@ static startBodyTypeMetadataVector(builder:flatbuffers.Builder, numElems:number) builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset constantsOffset + */ +static addConstants(builder:flatbuffers.Builder, constantsOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, constantsOffset, 0); +}; + /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -1978,11 +2134,12 @@ static endGameHeader(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameHeader(builder:flatbuffers.Builder, specVersionOffset:flatbuffers.Offset, teamsOffset:flatbuffers.Offset, bodyTypeMetadataOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameHeader(builder:flatbuffers.Builder, specVersionOffset:flatbuffers.Offset, teamsOffset:flatbuffers.Offset, bodyTypeMetadataOffset:flatbuffers.Offset, constantsOffset:flatbuffers.Offset):flatbuffers.Offset { GameHeader.startGameHeader(builder); GameHeader.addSpecVersion(builder, specVersionOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); + GameHeader.addConstants(builder, constantsOffset); return GameHeader.endGameHeader(builder); } } @@ -2350,12 +2507,10 @@ teamIDsArray():Int32Array|null { }; /** - * The number of votes the teams get, 0 or 1. - * * @param number index * @returns number */ -teamVotes(index: number):number|null { +teamLead(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2363,7 +2518,7 @@ teamVotes(index: number):number|null { /** * @returns number */ -teamVotesLength():number { +teamLeadLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2371,18 +2526,16 @@ teamVotesLength():number { /** * @returns Int32Array */ -teamVotesArray():Int32Array|null { +teamLeadArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** - * The ID of the Enlightenment Center got the bid. - * * @param number index * @returns number */ -teamBidderIDs(index: number):number|null { +teamGold(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2390,7 +2543,7 @@ teamBidderIDs(index: number):number|null { /** * @returns number */ -teamBidderIDsLength():number { +teamGoldLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2398,7 +2551,7 @@ teamBidderIDsLength():number { /** * @returns Int32Array */ -teamBidderIDsArray():Int32Array|null { +teamGoldArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2561,6 +2714,55 @@ actionTargetsArray():Int32Array|null { return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * The IDs of the robots who changed their indicator strings + * + * @param number index + * @returns number + */ +indicationStringIDs(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +indicationStringIDsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +indicationStringIDsArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 24); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * The messages of the robots who changed their indicator strings + * + * @param number index + * @param flatbuffers.Encoding= optionalEncoding + * @returns string|Uint8Array + */ +indicationStrings(index: number):string +indicationStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array +indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; +}; + +/** + * @returns number + */ +indicationStringsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 26); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + /** * The IDs of bodies that set indicator dots * @@ -2568,7 +2770,7 @@ actionTargetsArray():Int32Array|null { * @returns number */ indicatorDotIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2576,7 +2778,7 @@ indicatorDotIDs(index: number):number|null { * @returns number */ indicatorDotIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2584,7 +2786,7 @@ indicatorDotIDsLength():number { * @returns Int32Array */ indicatorDotIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2595,7 +2797,7 @@ indicatorDotIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2606,7 +2808,7 @@ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|nul * @returns battlecode.schema.RGBTable|null */ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2617,7 +2819,7 @@ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nul * @returns number */ indicatorLineIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2625,7 +2827,7 @@ indicatorLineIDs(index: number):number|null { * @returns number */ indicatorLineIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2633,7 +2835,7 @@ indicatorLineIDsLength():number { * @returns Int32Array */ indicatorLineIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2644,7 +2846,7 @@ indicatorLineIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2655,7 +2857,7 @@ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTab * @returns battlecode.schema.VecTable|null */ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 38); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2666,40 +2868,10 @@ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable * @returns battlecode.schema.RGBTable|null */ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 36); + var offset = this.bb!.__offset(this.bb_pos, 40); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; -/** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - * - * @param flatbuffers.Encoding= optionalEncoding - * @returns string|Uint8Array|null - */ -logs():string|null -logs(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null -logs(optionalEncoding?:any):string|Uint8Array|null { - var offset = this.bb!.__offset(this.bb_pos, 38); - return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; -}; - /** * The first sent Round in a match should have index 1. (The starting state, * created by the MatchHeader, can be thought to have index 0.) @@ -2708,7 +2880,7 @@ logs(optionalEncoding?:any):string|Uint8Array|null { * @returns number */ roundID():number { - var offset = this.bb!.__offset(this.bb_pos, 40); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -2719,7 +2891,7 @@ roundID():number { * @returns number */ bytecodeIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2727,7 +2899,7 @@ bytecodeIDs(index: number):number|null { * @returns number */ bytecodeIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2735,7 +2907,7 @@ bytecodeIDsLength():number { * @returns Int32Array */ bytecodeIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2746,33 +2918,6 @@ bytecodeIDsArray():Int32Array|null { * @returns number */ bytecodesUsed(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -bytecodesUsedLength():number { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -bytecodesUsedArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 44); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - * - * @param number index - * @returns number - */ -teamNumBuffs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2780,7 +2925,7 @@ teamNumBuffs(index: number):number|null { /** * @returns number */ -teamNumBuffsLength():number { +bytecodesUsedLength():number { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2788,7 +2933,7 @@ teamNumBuffsLength():number { /** * @returns Int32Array */ -teamNumBuffsArray():Int32Array|null { +bytecodesUsedArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2831,10 +2976,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamVotesOffset + * @param flatbuffers.Offset teamLeadOffset */ -static addTeamVotes(builder:flatbuffers.Builder, teamVotesOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamVotesOffset, 0); +static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadOffset, 0); }; /** @@ -2842,7 +2987,7 @@ static addTeamVotes(builder:flatbuffers.Builder, teamVotesOffset:flatbuffers.Off * @param Array. data * @returns flatbuffers.Offset */ -static createTeamVotesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2854,16 +2999,16 @@ static createTeamVotesVector(builder:flatbuffers.Builder, data:number[] | Uint8A * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamVotesVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamBidderIDsOffset + * @param flatbuffers.Offset teamGoldOffset */ -static addTeamBidderIDs(builder:flatbuffers.Builder, teamBidderIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamBidderIDsOffset, 0); +static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldOffset, 0); }; /** @@ -2871,7 +3016,7 @@ static addTeamBidderIDs(builder:flatbuffers.Builder, teamBidderIDsOffset:flatbuf * @param Array. data * @returns flatbuffers.Offset */ -static createTeamBidderIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2883,7 +3028,7 @@ static createTeamBidderIDsVector(builder:flatbuffers.Builder, data:number[] | Ui * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamBidderIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3048,12 +3193,70 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset indicationStringIDsOffset + */ +static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicationStringIDsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startIndicationStringIDsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset indicationStringsOffset + */ +static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, indicationStringsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startIndicationStringsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + /** * @param flatbuffers.Builder builder * @param flatbuffers.Offset indicatorDotIDsOffset */ static addIndicatorDotIDs(builder:flatbuffers.Builder, indicatorDotIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicatorDotIDsOffset, 0); + builder.addFieldOffset(12, indicatorDotIDsOffset, 0); }; /** @@ -3082,7 +3285,7 @@ static startIndicatorDotIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorDotLocsOffset */ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, indicatorDotLocsOffset, 0); + builder.addFieldOffset(13, indicatorDotLocsOffset, 0); }; /** @@ -3090,7 +3293,7 @@ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:f * @param flatbuffers.Offset indicatorDotRGBsOffset */ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, indicatorDotRGBsOffset, 0); + builder.addFieldOffset(14, indicatorDotRGBsOffset, 0); }; /** @@ -3098,7 +3301,7 @@ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:f * @param flatbuffers.Offset indicatorLineIDsOffset */ static addIndicatorLineIDs(builder:flatbuffers.Builder, indicatorLineIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, indicatorLineIDsOffset, 0); + builder.addFieldOffset(15, indicatorLineIDsOffset, 0); }; /** @@ -3127,7 +3330,7 @@ static startIndicatorLineIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorLineStartLocsOffset */ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStartLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, indicatorLineStartLocsOffset, 0); + builder.addFieldOffset(16, indicatorLineStartLocsOffset, 0); }; /** @@ -3135,7 +3338,7 @@ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStart * @param flatbuffers.Offset indicatorLineEndLocsOffset */ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, indicatorLineEndLocsOffset, 0); + builder.addFieldOffset(17, indicatorLineEndLocsOffset, 0); }; /** @@ -3143,15 +3346,7 @@ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocs * @param flatbuffers.Offset indicatorLineRGBsOffset */ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(16, indicatorLineRGBsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset logsOffset - */ -static addLogs(builder:flatbuffers.Builder, logsOffset:flatbuffers.Offset) { - builder.addFieldOffset(17, logsOffset, 0); + builder.addFieldOffset(18, indicatorLineRGBsOffset, 0); }; /** @@ -3159,7 +3354,7 @@ static addLogs(builder:flatbuffers.Builder, logsOffset:flatbuffers.Offset) { * @param number roundID */ static addRoundID(builder:flatbuffers.Builder, roundID:number) { - builder.addFieldInt32(18, roundID, 0); + builder.addFieldInt32(19, roundID, 0); }; /** @@ -3167,7 +3362,7 @@ static addRoundID(builder:flatbuffers.Builder, roundID:number) { * @param flatbuffers.Offset bytecodeIDsOffset */ static addBytecodeIDs(builder:flatbuffers.Builder, bytecodeIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(19, bytecodeIDsOffset, 0); + builder.addFieldOffset(20, bytecodeIDsOffset, 0); }; /** @@ -3196,7 +3391,7 @@ static startBytecodeIDsVector(builder:flatbuffers.Builder, numElems:number) { * @param flatbuffers.Offset bytecodesUsedOffset */ static addBytecodesUsed(builder:flatbuffers.Builder, bytecodesUsedOffset:flatbuffers.Offset) { - builder.addFieldOffset(20, bytecodesUsedOffset, 0); + builder.addFieldOffset(21, bytecodesUsedOffset, 0); }; /** @@ -3220,35 +3415,6 @@ static startBytecodesUsedVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamNumBuffsOffset - */ -static addTeamNumBuffs(builder:flatbuffers.Builder, teamNumBuffsOffset:flatbuffers.Offset) { - builder.addFieldOffset(21, teamNumBuffsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createTeamNumBuffsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startTeamNumBuffsVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -}; - /** * @param flatbuffers.Builder builder * @returns flatbuffers.Offset @@ -3258,11 +3424,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamVotesOffset:flatbuffers.Offset, teamBidderIDsOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, logsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset, teamNumBuffsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadOffset:flatbuffers.Offset, teamGoldOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); + Round.addTeamLead(builder, teamLeadOffset); + Round.addTeamGold(builder, teamGoldOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); @@ -3270,6 +3436,8 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); + Round.addIndicationStringIDs(builder, indicationStringIDsOffset); + Round.addIndicationStrings(builder, indicationStringsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); @@ -3277,11 +3445,9 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); - Round.addLogs(builder, logsOffset); Round.addRoundID(builder, roundID); Round.addBytecodeIDs(builder, bytecodeIDsOffset); Round.addBytecodesUsed(builder, bytecodesUsedOffset); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); return Round.endRound(builder); } } From e449f3d4ce116e72d1006648ae4a727a2de0ba4b Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 11:25:34 -0500 Subject: [PATCH 172/413] tmp --- client/playback/src/gameworld.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 00ad1187..05ea2f0c 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -84,8 +84,6 @@ export type Log = { text: string }; - - /** * A frozen image of the game world. * @@ -478,9 +476,6 @@ export default class GameWorld { break; /// A robot can change team after being empowered /// Target: teamID - case schema.Action.CHANGE_TEAM: - // TODO remove the robot, don't alter it - break; /// A robot's influence changes. /// Target: delta value case schema.Action.CHANGE_INFLUENCE: From 7c508523aaabbf28296ec1b14ec26c853d332e88 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 11:55:47 -0500 Subject: [PATCH 173/413] Tweak schema --- schema/battlecode.fbs | 1 - 1 file changed, 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 76f65df9..af3fd031 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -92,7 +92,6 @@ enum Action : byte { MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. - ATTACKED, // when a body is attacked TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, REPAIR, // builder repairs building From 7f282e5743ec130ef550c4118e2f7a628b511061 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 12:46:40 -0500 Subject: [PATCH 174/413] New units and actions in schema --- schema/battlecode.fbs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index af3fd031..74f4879f 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -33,11 +33,8 @@ enum BodyType : byte { // Combat units GUARD, - GUARD_TURRET, - ARCHER, - ARCHER_TURRET, WIZARD, - WIZARD_TURRET + TURRET } /// A list of new bodies to be placed on the map. @@ -96,7 +93,10 @@ enum Action : byte { UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, - FULLY_REPAIRED // prototype becomes a turret + FULLY_REPAIRED, // prototype becomes a turret + LOCAL_ABYSS, + LOCAL_FURY, + LOCAL_VORTEX } // Metadata From 3471e8ee47f5485a747b21892fb1637510e9a653 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 20 Nov 2021 12:48:02 -0500 Subject: [PATCH 175/413] No local vortex --- schema/battlecode.fbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 74f4879f..702193f8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -96,7 +96,7 @@ enum Action : byte { FULLY_REPAIRED, // prototype becomes a turret LOCAL_ABYSS, LOCAL_FURY, - LOCAL_VORTEX + LOCAL_CHARGE } // Metadata From 4829dd699c8abab92c2eac13fcc17415a62cfbdd Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:22:21 -0500 Subject: [PATCH 176/413] Update schema --- schema/battlecode.fbs | 16 +++--- schema/ts/battlecode_generated.ts | 94 ++++++++++++++++--------------- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 702193f8..6191bfd8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -71,9 +71,9 @@ table GameMap { //lead locations // a vectable of lead cords - lead_locations: VecTable; + leadLocations: VecTable; //inital lead amounts - initial_lead: [double]; + leadAmounts: [double]; } /// Actions that can be performed. @@ -84,19 +84,21 @@ table GameMap { /// the actions were performed. enum Action : byte { ATTACK, // combat unit types - DAZZLE, // wizard SPAWN_UNIT, //archon MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state + TRANSFORM, // Swaps a building between portable and turret mode UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, FULLY_REPAIRED, // prototype becomes a turret LOCAL_ABYSS, LOCAL_FURY, - LOCAL_CHARGE + LOCAL_CHARGE, + /// Dies due to an uncaught exception. + /// Target: none + DIE_EXCEPTION } // Metadata @@ -240,8 +242,8 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLead: [int]; - teamGold: [int]; + teamLeadIncome: [int]; + teamGoldIncome: [int]; /// The IDs of bodies that moved. movedIDs: [int]; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index d8474d3c..c32f55e3 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -14,11 +14,8 @@ export enum BodyType{ BUILDER= 2, LABORATORY= 3, GUARD= 4, - GUARD_TURRET= 5, - ARCHER= 6, - ARCHER_TURRET= 7, - WIZARD= 8, - WIZARD_TURRET= 9 + WIZARD= 5, + TURRET= 6 }}; /** @@ -34,17 +31,24 @@ export enum BodyType{ export namespace battlecode.schema{ export enum Action{ ATTACK= 0, - DAZZLE= 1, - SPAWN_UNIT= 2, - MINE= 3, - BUILD= 4, - CONVERT_GOLD= 5, - ATTACKED= 6, - TRANSFORM= 7, - UPGRADE= 8, - REPAIR= 9, - CHANGE_HP= 10, - FULLY_REPAIRED= 11 + SPAWN_UNIT= 1, + MINE= 2, + BUILD= 3, + CONVERT_GOLD= 4, + TRANSFORM= 5, + UPGRADE= 6, + REPAIR= 7, + CHANGE_HP= 8, + FULLY_REPAIRED= 9, + LOCAL_ABYSS= 10, + LOCAL_FURY= 11, + LOCAL_CHARGE= 12, + + /** + * Dies due to an uncaught exception. + * Target: none + */ + DIE_EXCEPTION= 13 }}; /** @@ -893,7 +897,7 @@ leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -initialLead(index: number):number|null { +leadAmounts(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; }; @@ -901,7 +905,7 @@ initialLead(index: number):number|null { /** * @returns number */ -initialLeadLength():number { +leadAmountsLength():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -909,7 +913,7 @@ initialLeadLength():number { /** * @returns Float64Array */ -initialLeadArray():Float64Array|null { +leadAmountsArray():Float64Array|null { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -1000,10 +1004,10 @@ static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuf /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset initialLeadOffset + * @param flatbuffers.Offset leadAmountsOffset */ -static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(7, initialLeadOffset, 0); +static addLeadAmounts(builder:flatbuffers.Builder, leadAmountsOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, leadAmountsOffset, 0); }; /** @@ -1011,7 +1015,7 @@ static addInitialLead(builder:flatbuffers.Builder, initialLeadOffset:flatbuffers * @param Array. data * @returns flatbuffers.Offset */ -static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadAmountsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(8, data.length, 8); for (var i = data.length - 1; i >= 0; i--) { builder.addFloat64(data[i]); @@ -1023,7 +1027,7 @@ static createInitialLeadVector(builder:flatbuffers.Builder, data:number[] | Uint * @param flatbuffers.Builder builder * @param number numElems */ -static startInitialLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadAmountsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(8, numElems, 8); }; @@ -1036,7 +1040,7 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, initialLeadOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, leadAmountsOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); @@ -1045,7 +1049,7 @@ static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, GameMap.addRandomSeed(builder, randomSeed); GameMap.addPassability(builder, passabilityOffset); GameMap.addLeadLocations(builder, leadLocationsOffset); - GameMap.addInitialLead(builder, initialLeadOffset); + GameMap.addLeadAmounts(builder, leadAmountsOffset); return GameMap.endGameMap(builder); } } @@ -2510,7 +2514,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -teamLead(index: number):number|null { +teamLeadIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2518,7 +2522,7 @@ teamLead(index: number):number|null { /** * @returns number */ -teamLeadLength():number { +teamLeadIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2526,7 +2530,7 @@ teamLeadLength():number { /** * @returns Int32Array */ -teamLeadArray():Int32Array|null { +teamLeadIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2535,7 +2539,7 @@ teamLeadArray():Int32Array|null { * @param number index * @returns number */ -teamGold(index: number):number|null { +teamGoldIncome(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2543,7 +2547,7 @@ teamGold(index: number):number|null { /** * @returns number */ -teamGoldLength():number { +teamGoldIncomeLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2551,7 +2555,7 @@ teamGoldLength():number { /** * @returns Int32Array */ -teamGoldArray():Int32Array|null { +teamGoldIncomeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2976,10 +2980,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadOffset + * @param flatbuffers.Offset teamLeadIncomeOffset */ -static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadOffset, 0); +static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadIncomeOffset, 0); }; /** @@ -2987,7 +2991,7 @@ static addTeamLead(builder:flatbuffers.Builder, teamLeadOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -2999,16 +3003,16 @@ static createTeamLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldOffset + * @param flatbuffers.Offset teamGoldIncomeOffset */ -static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldOffset, 0); +static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldIncomeOffset, 0); }; /** @@ -3016,7 +3020,7 @@ static addTeamGold(builder:flatbuffers.Builder, teamGoldOffset:flatbuffers.Offse * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3028,7 +3032,7 @@ static createTeamGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Ar * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3424,11 +3428,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadOffset:flatbuffers.Offset, teamGoldOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLead(builder, teamLeadOffset); - Round.addTeamGold(builder, teamGoldOffset); + Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); + Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); From 52a71547f81bb7a0cf35c008276494278bfb5d15 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:41:56 -0500 Subject: [PATCH 177/413] Add build cost to schema --- schema/battlecode.fbs | 7 ++--- schema/ts/battlecode_generated.ts | 45 +++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 6191bfd8..cb0c68c0 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -112,11 +112,12 @@ table BodyTypeMetadata { visionRadiusSquared: int; movingCooldown: float; bytecodeLimit: int; + buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; + dpsMul: float; // dps multiplier for level + hpMul: float; // hp multiplier per level + upgradeCosts: [int]; } /// Data relevant to a particular team. diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index c32f55e3..2c71e46b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1143,7 +1143,7 @@ bytecodeLimit():number { /** * @returns number */ -dps():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1151,7 +1151,7 @@ dps():number { /** * @returns number */ -hp():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1159,8 +1159,16 @@ hp():number { /** * @returns number */ -dpsMul():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @returns number + */ +dpsMul():number { + var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1168,7 +1176,7 @@ dpsMul():number { * @returns number */ hpMul():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1177,7 +1185,7 @@ hpMul():number { * @returns number */ upgradeCosts(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -1185,7 +1193,7 @@ upgradeCosts(index: number):number|null { * @returns number */ upgradeCostsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -1193,7 +1201,7 @@ upgradeCostsLength():number { * @returns Int32Array */ upgradeCostsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -1201,7 +1209,7 @@ upgradeCostsArray():Int32Array|null { * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(12); + builder.startObject(13); }; /** @@ -1260,12 +1268,20 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(7, buildCost, 0); +}; + /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(7, dps, 0); + builder.addFieldInt32(8, dps, 0); }; /** @@ -1273,7 +1289,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(8, hp, 0); + builder.addFieldInt32(9, hp, 0); }; /** @@ -1281,7 +1297,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(9, dpsMul, 0.0); + builder.addFieldFloat32(10, dpsMul, 0.0); }; /** @@ -1289,7 +1305,7 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(10, hpMul, 0.0); + builder.addFieldFloat32(11, hpMul, 0.0); }; /** @@ -1297,7 +1313,7 @@ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { * @param flatbuffers.Offset upgradeCostsOffset */ static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, upgradeCostsOffset, 0); + builder.addFieldOffset(12, upgradeCostsOffset, 0); }; /** @@ -1330,7 +1346,7 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, buildCost:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); @@ -1339,6 +1355,7 @@ static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schem BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); From 5c8d1e272a11c99165e5c8be75ff53d4e4bfb361 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:47:33 -0500 Subject: [PATCH 178/413] More schema tweaks --- schema/battlecode.fbs | 11 +++----- schema/ts/battlecode_generated.ts | 42 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index cb0c68c0..1b23ecfe 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -187,11 +187,11 @@ union Event { GameFooter } -table Constants{ +table Constants { //amounts of resources added to each block per round leadAdditiveIncease: double; goldAdditiveIncease: double; - increase_period: int; + increasePeriod: int; } @@ -208,9 +208,6 @@ table GameHeader { constants: Constants; } - - - /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. @@ -266,9 +263,9 @@ table Round { actionTargets: [int]; /// The IDs of the robots who changed their indicator strings - indicationStringIDs: [int]; + indicaortStringIDs: [int]; /// The messages of the robots who changed their indicator strings - indicationStrings: [string]; + indicatorStrings: [string]; /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2c71e46b..2ba18c03 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -2741,7 +2741,7 @@ actionTargetsArray():Int32Array|null { * @param number index * @returns number */ -indicationStringIDs(index: number):number|null { +indicaortStringIDs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2749,7 +2749,7 @@ indicationStringIDs(index: number):number|null { /** * @returns number */ -indicationStringIDsLength():number { +indicaortStringIDsLength():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2757,7 +2757,7 @@ indicationStringIDsLength():number { /** * @returns Int32Array */ -indicationStringIDsArray():Int32Array|null { +indicaortStringIDsArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2769,9 +2769,9 @@ indicationStringIDsArray():Int32Array|null { * @param flatbuffers.Encoding= optionalEncoding * @returns string|Uint8Array */ -indicationStrings(index: number):string -indicationStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array -indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { +indicatorStrings(index: number):string +indicatorStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array +indicatorStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; }; @@ -2779,7 +2779,7 @@ indicationStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { /** * @returns number */ -indicationStringsLength():number { +indicatorStringsLength():number { var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3216,10 +3216,10 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicationStringIDsOffset + * @param flatbuffers.Offset indicaortStringIDsOffset */ -static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicationStringIDsOffset, 0); +static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicaortStringIDsOffset, 0); }; /** @@ -3227,7 +3227,7 @@ static addIndicationStringIDs(builder:flatbuffers.Builder, indicationStringIDsOf * @param Array. data * @returns flatbuffers.Offset */ -static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3239,16 +3239,16 @@ static createIndicationStringIDsVector(builder:flatbuffers.Builder, data:number[ * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicationStringIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicaortStringIDsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicationStringsOffset + * @param flatbuffers.Offset indicatorStringsOffset */ -static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, indicationStringsOffset, 0); +static addIndicatorStrings(builder:flatbuffers.Builder, indicatorStringsOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, indicatorStringsOffset, 0); }; /** @@ -3256,7 +3256,7 @@ static addIndicationStrings(builder:flatbuffers.Builder, indicationStringsOffset * @param Array. data * @returns flatbuffers.Offset */ -static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { +static createIndicatorStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); @@ -3268,7 +3268,7 @@ static createIndicationStringsVector(builder:flatbuffers.Builder, data:flatbuffe * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicationStringsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3445,7 +3445,7 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicaortStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); @@ -3457,8 +3457,8 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); - Round.addIndicationStringIDs(builder, indicationStringIDsOffset); - Round.addIndicationStrings(builder, indicationStringsOffset); + Round.addIndicaortStringIDs(builder, indicaortStringIDsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From da1c97349a430166ae89676cf014f954634fcbe9 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:07:48 -0500 Subject: [PATCH 179/413] Minor schema changes --- schema/battlecode.fbs | 4 +- schema/ts/battlecode_generated.ts | 72 +++++++++++++++---------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1b23ecfe..0d432ce8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -107,16 +107,16 @@ enum Action : byte { table BodyTypeMetadata { type: BodyType; spawnSource: BodyType; - actionCooldown: float; actionRadiusSquared: int; visionRadiusSquared: int; + actionCooldown: float; movingCooldown: float; bytecodeLimit: int; - buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level + buildCost: int; upgradeCosts: [int]; } diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2ba18c03..44e7be78 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1103,15 +1103,15 @@ spawnSource():battlecode.schema.BodyType { /** * @returns number */ -actionCooldown():number { +actionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 8); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -actionRadiusSquared():number { +visionRadiusSquared():number { var offset = this.bb!.__offset(this.bb_pos, 10); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1119,9 +1119,9 @@ actionRadiusSquared():number { /** * @returns number */ -visionRadiusSquared():number { +actionCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** @@ -1143,7 +1143,7 @@ bytecodeLimit():number { /** * @returns number */ -buildCost():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1151,7 +1151,7 @@ buildCost():number { /** * @returns number */ -dps():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1159,15 +1159,15 @@ dps():number { /** * @returns number */ -hp():number { +dpsMul():number { var offset = this.bb!.__offset(this.bb_pos, 22); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** * @returns number */ -dpsMul():number { +hpMul():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1175,9 +1175,9 @@ dpsMul():number { /** * @returns number */ -hpMul():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** @@ -1230,26 +1230,26 @@ static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema /** * @param flatbuffers.Builder builder - * @param number actionCooldown + * @param number actionRadiusSquared */ -static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(2, actionCooldown, 0.0); +static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { + builder.addFieldInt32(2, actionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number actionRadiusSquared + * @param number visionRadiusSquared */ -static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(3, actionRadiusSquared, 0); +static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { + builder.addFieldInt32(3, visionRadiusSquared, 0); }; /** * @param flatbuffers.Builder builder - * @param number visionRadiusSquared + * @param number actionCooldown */ -static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { - builder.addFieldInt32(4, visionRadiusSquared, 0); +static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { + builder.addFieldFloat32(4, actionCooldown, 0.0); }; /** @@ -1268,20 +1268,12 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(7, buildCost, 0); -}; - /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(8, dps, 0); + builder.addFieldInt32(7, dps, 0); }; /** @@ -1289,7 +1281,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(9, hp, 0); + builder.addFieldInt32(8, hp, 0); }; /** @@ -1297,7 +1289,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(10, dpsMul, 0.0); + builder.addFieldFloat32(9, dpsMul, 0.0); }; /** @@ -1305,7 +1297,15 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(11, hpMul, 0.0); + builder.addFieldFloat32(10, hpMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(11, buildCost, 0); }; /** @@ -1346,20 +1346,20 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionCooldown:number, actionRadiusSquared:number, visionRadiusSquared:number, movingCooldown:number, bytecodeLimit:number, buildCost:number, dps:number, hp:number, dpsMul:number, hpMul:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); BodyTypeMetadata.addHpMul(builder, hpMul); + BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } From b3940dfe0cb8d87a2015f7fd4e86737242808e90 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:10 -0500 Subject: [PATCH 180/413] Schema body types and resource drops --- schema/battlecode.fbs | 22 ++- schema/ts/battlecode_generated.ts | 236 ++++++++++++++++++++++++------ 2 files changed, 205 insertions(+), 53 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 0d432ce8..55dbb14d 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -25,16 +25,16 @@ table RGBTable { /// Note that bullets are not treated as bodies. enum BodyType : byte { - // Core unit types + // robots MINER, - ARCHON, - BUILDER, - LABORATORY, - - // Combat units GUARD, WIZARD, - TURRET + BUILDER, + + // buildings + ARCHON, + LABORATORY, + WATCHTOWER } /// A list of new bodies to be placed on the map. @@ -263,10 +263,16 @@ table Round { actionTargets: [int]; /// The IDs of the robots who changed their indicator strings - indicaortStringIDs: [int]; + indicatorStringIDs: [int]; /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; + leadDrops: VecTable; + leadDropsValues: [int]; + + goldDrops: VecTable; + goldDropsValues: [int]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 44e7be78..2bf2620b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,12 +10,12 @@ import { flatbuffers } from "./flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, - ARCHON= 1, - BUILDER= 2, - LABORATORY= 3, - GUARD= 4, - WIZARD= 5, - TURRET= 6 + GUARD= 1, + WIZARD= 2, + BUILDER= 3, + ARCHON= 4, + LABORATORY= 5, + WATCHTOWER= 6 }}; /** @@ -2741,7 +2741,7 @@ actionTargetsArray():Int32Array|null { * @param number index * @returns number */ -indicaortStringIDs(index: number):number|null { +indicatorStringIDs(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2749,7 +2749,7 @@ indicaortStringIDs(index: number):number|null { /** * @returns number */ -indicaortStringIDsLength():number { +indicatorStringIDsLength():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2757,7 +2757,7 @@ indicaortStringIDsLength():number { /** * @returns Int32Array */ -indicaortStringIDsArray():Int32Array|null { +indicatorStringIDsArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2784,6 +2784,74 @@ indicatorStringsLength():number { return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 28); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +leadDropsValues(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +leadDropsValuesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +leadDropsValuesArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * @param battlecode.schema.VecTable= obj + * @returns battlecode.schema.VecTable|null + */ +goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { + var offset = this.bb!.__offset(this.bb_pos, 32); + return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +}; + +/** + * @param number index + * @returns number + */ +goldDropsValues(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +goldDropsValuesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +goldDropsValuesArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * The IDs of bodies that set indicator dots * @@ -2791,7 +2859,7 @@ indicatorStringsLength():number { * @returns number */ indicatorDotIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2799,7 +2867,7 @@ indicatorDotIDs(index: number):number|null { * @returns number */ indicatorDotIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2807,7 +2875,7 @@ indicatorDotIDsLength():number { * @returns Int32Array */ indicatorDotIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 36); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2818,7 +2886,7 @@ indicatorDotIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 38); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2829,7 +2897,7 @@ indicatorDotLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|nul * @returns battlecode.schema.RGBTable|null */ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); + var offset = this.bb!.__offset(this.bb_pos, 40); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2840,7 +2908,7 @@ indicatorDotRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nul * @returns number */ indicatorLineIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2848,7 +2916,7 @@ indicatorLineIDs(index: number):number|null { * @returns number */ indicatorLineIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2856,7 +2924,7 @@ indicatorLineIDsLength():number { * @returns Int32Array */ indicatorLineIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 42); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2867,7 +2935,7 @@ indicatorLineIDsArray():Int32Array|null { * @returns battlecode.schema.VecTable|null */ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 36); + var offset = this.bb!.__offset(this.bb_pos, 44); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2878,7 +2946,7 @@ indicatorLineStartLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTab * @returns battlecode.schema.VecTable|null */ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 38); + var offset = this.bb!.__offset(this.bb_pos, 46); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2889,7 +2957,7 @@ indicatorLineEndLocs(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable * @returns battlecode.schema.RGBTable|null */ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|null { - var offset = this.bb!.__offset(this.bb_pos, 40); + var offset = this.bb!.__offset(this.bb_pos, 48); return offset ? (obj || new battlecode.schema.RGBTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2901,7 +2969,7 @@ indicatorLineRGBs(obj?:battlecode.schema.RGBTable):battlecode.schema.RGBTable|nu * @returns number */ roundID():number { - var offset = this.bb!.__offset(this.bb_pos, 42); + var offset = this.bb!.__offset(this.bb_pos, 50); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -2912,7 +2980,7 @@ roundID():number { * @returns number */ bytecodeIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2920,7 +2988,7 @@ bytecodeIDs(index: number):number|null { * @returns number */ bytecodeIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2928,7 +2996,7 @@ bytecodeIDsLength():number { * @returns Int32Array */ bytecodeIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 44); + var offset = this.bb!.__offset(this.bb_pos, 52); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2939,7 +3007,7 @@ bytecodeIDsArray():Int32Array|null { * @returns number */ bytecodesUsed(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2947,7 +3015,7 @@ bytecodesUsed(index: number):number|null { * @returns number */ bytecodesUsedLength():number { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2955,7 +3023,7 @@ bytecodesUsedLength():number { * @returns Int32Array */ bytecodesUsedArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 46); + var offset = this.bb!.__offset(this.bb_pos, 54); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2963,7 +3031,7 @@ bytecodesUsedArray():Int32Array|null { * @param flatbuffers.Builder builder */ static startRound(builder:flatbuffers.Builder) { - builder.startObject(22); + builder.startObject(26); }; /** @@ -3216,10 +3284,10 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicaortStringIDsOffset + * @param flatbuffers.Offset indicatorStringIDsOffset */ -static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicaortStringIDsOffset, 0); +static addIndicatorStringIDs(builder:flatbuffers.Builder, indicatorStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, indicatorStringIDsOffset, 0); }; /** @@ -3227,7 +3295,7 @@ static addIndicaortStringIDs(builder:flatbuffers.Builder, indicaortStringIDsOffs * @param Array. data * @returns flatbuffers.Offset */ -static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicatorStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3239,7 +3307,7 @@ static createIndicaortStringIDsVector(builder:flatbuffers.Builder, data:number[] * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicaortStringIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringIDsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3272,12 +3340,86 @@ static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) builder.startVector(4, numElems, 4); }; +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadDropsOffset + */ +static addLeadDrops(builder:flatbuffers.Builder, leadDropsOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, leadDropsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadDropsValuesOffset + */ +static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, leadDropsValuesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startLeadDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset goldDropsOffset + */ +static addGoldDrops(builder:flatbuffers.Builder, goldDropsOffset:flatbuffers.Offset) { + builder.addFieldOffset(14, goldDropsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset goldDropsValuesOffset + */ +static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(15, goldDropsValuesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startGoldDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + /** * @param flatbuffers.Builder builder * @param flatbuffers.Offset indicatorDotIDsOffset */ static addIndicatorDotIDs(builder:flatbuffers.Builder, indicatorDotIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, indicatorDotIDsOffset, 0); + builder.addFieldOffset(16, indicatorDotIDsOffset, 0); }; /** @@ -3306,7 +3448,7 @@ static startIndicatorDotIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorDotLocsOffset */ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, indicatorDotLocsOffset, 0); + builder.addFieldOffset(17, indicatorDotLocsOffset, 0); }; /** @@ -3314,7 +3456,7 @@ static addIndicatorDotLocs(builder:flatbuffers.Builder, indicatorDotLocsOffset:f * @param flatbuffers.Offset indicatorDotRGBsOffset */ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, indicatorDotRGBsOffset, 0); + builder.addFieldOffset(18, indicatorDotRGBsOffset, 0); }; /** @@ -3322,7 +3464,7 @@ static addIndicatorDotRGBs(builder:flatbuffers.Builder, indicatorDotRGBsOffset:f * @param flatbuffers.Offset indicatorLineIDsOffset */ static addIndicatorLineIDs(builder:flatbuffers.Builder, indicatorLineIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, indicatorLineIDsOffset, 0); + builder.addFieldOffset(19, indicatorLineIDsOffset, 0); }; /** @@ -3351,7 +3493,7 @@ static startIndicatorLineIDsVector(builder:flatbuffers.Builder, numElems:number) * @param flatbuffers.Offset indicatorLineStartLocsOffset */ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStartLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(16, indicatorLineStartLocsOffset, 0); + builder.addFieldOffset(20, indicatorLineStartLocsOffset, 0); }; /** @@ -3359,7 +3501,7 @@ static addIndicatorLineStartLocs(builder:flatbuffers.Builder, indicatorLineStart * @param flatbuffers.Offset indicatorLineEndLocsOffset */ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocsOffset:flatbuffers.Offset) { - builder.addFieldOffset(17, indicatorLineEndLocsOffset, 0); + builder.addFieldOffset(21, indicatorLineEndLocsOffset, 0); }; /** @@ -3367,7 +3509,7 @@ static addIndicatorLineEndLocs(builder:flatbuffers.Builder, indicatorLineEndLocs * @param flatbuffers.Offset indicatorLineRGBsOffset */ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset:flatbuffers.Offset) { - builder.addFieldOffset(18, indicatorLineRGBsOffset, 0); + builder.addFieldOffset(22, indicatorLineRGBsOffset, 0); }; /** @@ -3375,7 +3517,7 @@ static addIndicatorLineRGBs(builder:flatbuffers.Builder, indicatorLineRGBsOffset * @param number roundID */ static addRoundID(builder:flatbuffers.Builder, roundID:number) { - builder.addFieldInt32(19, roundID, 0); + builder.addFieldInt32(23, roundID, 0); }; /** @@ -3383,7 +3525,7 @@ static addRoundID(builder:flatbuffers.Builder, roundID:number) { * @param flatbuffers.Offset bytecodeIDsOffset */ static addBytecodeIDs(builder:flatbuffers.Builder, bytecodeIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(20, bytecodeIDsOffset, 0); + builder.addFieldOffset(24, bytecodeIDsOffset, 0); }; /** @@ -3412,7 +3554,7 @@ static startBytecodeIDsVector(builder:flatbuffers.Builder, numElems:number) { * @param flatbuffers.Offset bytecodesUsedOffset */ static addBytecodesUsed(builder:flatbuffers.Builder, bytecodesUsedOffset:flatbuffers.Offset) { - builder.addFieldOffset(21, bytecodesUsedOffset, 0); + builder.addFieldOffset(25, bytecodesUsedOffset, 0); }; /** @@ -3445,7 +3587,7 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicaortStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropsOffset:flatbuffers.Offset, leadDropsValuesOffset:flatbuffers.Offset, goldDropsOffset:flatbuffers.Offset, goldDropsValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); @@ -3457,8 +3599,12 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); - Round.addIndicaortStringIDs(builder, indicaortStringIDsOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); Round.addIndicatorStrings(builder, indicatorStringsOffset); + Round.addLeadDrops(builder, leadDropsOffset); + Round.addLeadDropsValues(builder, leadDropsValuesOffset); + Round.addGoldDrops(builder, goldDropsOffset); + Round.addGoldDropsValues(builder, goldDropsValuesOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From 388669e20a4cb7dec15fcf00faad975f80b3a094 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:55 -0500 Subject: [PATCH 181/413] whoops --- schema/ts/battlecode_generated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 2bf2620b..9eb1644b 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. From baa0d78c61fc9fd7adcdea42b31f43d4bbd5e290 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:06 -0500 Subject: [PATCH 182/413] preliminary engine feedback --- schema/battlecode.fbs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 55dbb14d..1347def8 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -25,11 +25,11 @@ table RGBTable { /// Note that bullets are not treated as bodies. enum BodyType : byte { - // robots + // droids MINER, - GUARD, - WIZARD, BUILDER, + SOLDIER, + SAGE, // buildings ARCHON, @@ -68,11 +68,11 @@ table GameMap { /// The factor to divide cooldowns by passability: [double]; - //lead locations + // lead locations // a vectable of lead cords leadLocations: VecTable; - //inital lead amounts + // inital lead amounts leadAmounts: [double]; } @@ -110,14 +110,15 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; actionCooldown: float; - movingCooldown: float; + movementCooldown: float; bytecodeLimit: int; dps: int; // dps at lowest level hp: int; // hp at lowest level dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level buildCost: int; - upgradeCosts: [int]; + upgradeCostLead: [int]; + upgradeCostGold: [int]; } /// Data relevant to a particular team. @@ -240,8 +241,8 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLeadIncome: [int]; - teamGoldIncome: [int]; + teamLeadChange: [int]; + teamGoldChange: [int]; /// The IDs of bodies that moved. movedIDs: [int]; @@ -267,11 +268,11 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; - leadDrops: VecTable; - leadDropsValues: [int]; + leadDropLocations: VecTable; + leadDropValues: [int]; - goldDrops: VecTable; - goldDropsValues: [int]; + goldDropLocations: VecTable; + goldDropValues: [int]; /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; From c3b2d665a5791a3b55b2694d078529b661f1766f Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:49 -0500 Subject: [PATCH 183/413] regenerate ts file --- schema/ts/battlecode_generated.ts | 187 +++++++++++++++++++----------- 1 file changed, 121 insertions(+), 66 deletions(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 9eb1644b..63d97fbf 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,9 +10,9 @@ import { flatbuffers } from "flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, - GUARD= 1, - WIZARD= 2, - BUILDER= 3, + BUILDER= 1, + SOLDIER= 2, + SAGE= 3, ARCHON= 4, LABORATORY= 5, WATCHTOWER= 6 @@ -1127,7 +1127,7 @@ actionCooldown():number { /** * @returns number */ -movingCooldown():number { +movementCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 14); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1184,7 +1184,7 @@ buildCost():number { * @param number index * @returns number */ -upgradeCosts(index: number):number|null { +upgradeCostLead(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -1192,7 +1192,7 @@ upgradeCosts(index: number):number|null { /** * @returns number */ -upgradeCostsLength():number { +upgradeCostLeadLength():number { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -1200,16 +1200,41 @@ upgradeCostsLength():number { /** * @returns Int32Array */ -upgradeCostsArray():Int32Array|null { +upgradeCostLeadArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; +/** + * @param number index + * @returns number + */ +upgradeCostGold(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +upgradeCostGoldLength():number { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +upgradeCostGoldArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + /** * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(13); + builder.startObject(14); }; /** @@ -1254,10 +1279,10 @@ static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { /** * @param flatbuffers.Builder builder - * @param number movingCooldown + * @param number movementCooldown */ -static addMovingCooldown(builder:flatbuffers.Builder, movingCooldown:number) { - builder.addFieldFloat32(5, movingCooldown, 0.0); +static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) { + builder.addFieldFloat32(5, movementCooldown, 0.0); }; /** @@ -1310,10 +1335,39 @@ static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostsOffset + * @param flatbuffers.Offset upgradeCostLeadOffset + */ +static addUpgradeCostLead(builder:flatbuffers.Builder, upgradeCostLeadOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, upgradeCostLeadOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createUpgradeCostLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startUpgradeCostLeadVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset upgradeCostGoldOffset */ -static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, upgradeCostsOffset, 0); +static addUpgradeCostGold(builder:flatbuffers.Builder, upgradeCostGoldOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, upgradeCostGoldOffset, 0); }; /** @@ -1321,7 +1375,7 @@ static addUpgradeCosts(builder:flatbuffers.Builder, upgradeCostsOffset:flatbuffe * @param Array. data * @returns flatbuffers.Offset */ -static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createUpgradeCostGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -1333,7 +1387,7 @@ static createUpgradeCostsVector(builder:flatbuffers.Builder, data:number[] | Uin * @param flatbuffers.Builder builder * @param number numElems */ -static startUpgradeCostsVector(builder:flatbuffers.Builder, numElems:number) { +static startUpgradeCostGoldVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -1346,21 +1400,22 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addMovingCooldown(builder, movingCooldown); + BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); BodyTypeMetadata.addHpMul(builder, hpMul); BodyTypeMetadata.addBuildCost(builder, buildCost); - BodyTypeMetadata.addUpgradeCosts(builder, upgradeCostsOffset); + BodyTypeMetadata.addUpgradeCostLead(builder, upgradeCostLeadOffset); + BodyTypeMetadata.addUpgradeCostGold(builder, upgradeCostGoldOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } } @@ -2531,7 +2586,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -teamLeadIncome(index: number):number|null { +teamLeadChange(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2539,7 +2594,7 @@ teamLeadIncome(index: number):number|null { /** * @returns number */ -teamLeadIncomeLength():number { +teamLeadChangeLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2547,7 +2602,7 @@ teamLeadIncomeLength():number { /** * @returns Int32Array */ -teamLeadIncomeArray():Int32Array|null { +teamLeadChangeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2556,7 +2611,7 @@ teamLeadIncomeArray():Int32Array|null { * @param number index * @returns number */ -teamGoldIncome(index: number):number|null { +teamGoldChange(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2564,7 +2619,7 @@ teamGoldIncome(index: number):number|null { /** * @returns number */ -teamGoldIncomeLength():number { +teamGoldChangeLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2572,7 +2627,7 @@ teamGoldIncomeLength():number { /** * @returns Int32Array */ -teamGoldIncomeArray():Int32Array|null { +teamGoldChangeArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2788,7 +2843,7 @@ indicatorStringsLength():number { * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ -leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { +leadDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2797,7 +2852,7 @@ leadDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -leadDropsValues(index: number):number|null { +leadDropValues(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2805,7 +2860,7 @@ leadDropsValues(index: number):number|null { /** * @returns number */ -leadDropsValuesLength():number { +leadDropValuesLength():number { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2813,7 +2868,7 @@ leadDropsValuesLength():number { /** * @returns Int32Array */ -leadDropsValuesArray():Int32Array|null { +leadDropValuesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2822,7 +2877,7 @@ leadDropsValuesArray():Int32Array|null { * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ -goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { +goldDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -2831,7 +2886,7 @@ goldDrops(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { * @param number index * @returns number */ -goldDropsValues(index: number):number|null { +goldDropValues(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2839,7 +2894,7 @@ goldDropsValues(index: number):number|null { /** * @returns number */ -goldDropsValuesLength():number { +goldDropValuesLength():number { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2847,7 +2902,7 @@ goldDropsValuesLength():number { /** * @returns Int32Array */ -goldDropsValuesArray():Int32Array|null { +goldDropValuesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3065,10 +3120,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadIncomeOffset + * @param flatbuffers.Offset teamLeadChangeOffset */ -static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadIncomeOffset, 0); +static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadChangeOffset, 0); }; /** @@ -3076,7 +3131,7 @@ static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3088,16 +3143,16 @@ static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadChangeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldIncomeOffset + * @param flatbuffers.Offset teamGoldChangeOffset */ -static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldIncomeOffset, 0); +static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldChangeOffset, 0); }; /** @@ -3105,7 +3160,7 @@ static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3117,7 +3172,7 @@ static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldChangeVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3342,18 +3397,18 @@ static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropsOffset + * @param flatbuffers.Offset leadDropLocationsOffset */ -static addLeadDrops(builder:flatbuffers.Builder, leadDropsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, leadDropsOffset, 0); +static addLeadDropLocations(builder:flatbuffers.Builder, leadDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, leadDropLocationsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropsValuesOffset + * @param flatbuffers.Offset leadDropValuesOffset */ -static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, leadDropsValuesOffset, 0); +static addLeadDropValues(builder:flatbuffers.Builder, leadDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, leadDropValuesOffset, 0); }; /** @@ -3361,7 +3416,7 @@ static addLeadDropsValues(builder:flatbuffers.Builder, leadDropsValuesOffset:fla * @param Array. data * @returns flatbuffers.Offset */ -static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3373,24 +3428,24 @@ static createLeadDropsValuesVector(builder:flatbuffers.Builder, data:number[] | * @param flatbuffers.Builder builder * @param number numElems */ -static startLeadDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropsOffset + * @param flatbuffers.Offset goldDropLocationsOffset */ -static addGoldDrops(builder:flatbuffers.Builder, goldDropsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, goldDropsOffset, 0); +static addGoldDropLocations(builder:flatbuffers.Builder, goldDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(14, goldDropLocationsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropsValuesOffset + * @param flatbuffers.Offset goldDropValuesOffset */ -static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, goldDropsValuesOffset, 0); +static addGoldDropValues(builder:flatbuffers.Builder, goldDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(15, goldDropValuesOffset, 0); }; /** @@ -3398,7 +3453,7 @@ static addGoldDropsValues(builder:flatbuffers.Builder, goldDropsValuesOffset:fla * @param Array. data * @returns flatbuffers.Offset */ -static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createGoldDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3410,7 +3465,7 @@ static createGoldDropsValuesVector(builder:flatbuffers.Builder, data:number[] | * @param flatbuffers.Builder builder * @param number numElems */ -static startGoldDropsValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startGoldDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3587,11 +3642,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropsOffset:flatbuffers.Offset, leadDropsValuesOffset:flatbuffers.Offset, goldDropsOffset:flatbuffers.Offset, goldDropsValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangeOffset:flatbuffers.Offset, teamGoldChangeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); - Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); + Round.addTeamLeadChange(builder, teamLeadChangeOffset); + Round.addTeamGoldChange(builder, teamGoldChangeOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); @@ -3601,10 +3656,10 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionTargets(builder, actionTargetsOffset); Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); Round.addIndicatorStrings(builder, indicatorStringsOffset); - Round.addLeadDrops(builder, leadDropsOffset); - Round.addLeadDropsValues(builder, leadDropsValuesOffset); - Round.addGoldDrops(builder, goldDropsOffset); - Round.addGoldDropsValues(builder, goldDropsValuesOffset); + Round.addLeadDropLocations(builder, leadDropLocationsOffset); + Round.addLeadDropValues(builder, leadDropValuesOffset); + Round.addGoldDropLocations(builder, goldDropLocationsOffset); + Round.addGoldDropValues(builder, goldDropValuesOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From 65f814fc983380273acc1f5501c8972b22c08f8b Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Wed, 22 Dec 2021 11:22:39 -0500 Subject: [PATCH 184/413] Add actions for global anomalies --- schema/battlecode.fbs | 7 ++++++- schema/ts/battlecode_generated.ts | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1347def8..1ef7131e 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -98,7 +98,12 @@ enum Action : byte { LOCAL_CHARGE, /// Dies due to an uncaught exception. /// Target: none - DIE_EXCEPTION + DIE_EXCEPTION, + ABYSS, + CHARGE, + FURY, + VORTEX, + SINGULARITY } // Metadata diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 63d97fbf..0093e8f9 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -48,7 +48,12 @@ export enum Action{ * Dies due to an uncaught exception. * Target: none */ - DIE_EXCEPTION= 13 + DIE_EXCEPTION= 13, + ABYSS= 14, + CHARGE= 15, + FURY= 16, + VORTEX= 17, + SINGULARITY= 18 }}; /** From fad46028b355cf292ca2cc9b77019696693e262e Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 23 Dec 2021 01:38:28 -0600 Subject: [PATCH 185/413] schema updates from engine --- .../main/battlecode/world/InternalRobot.java | 8 +- .../battlecode/world/RobotControllerImpl.java | 2 +- schema/battlecode.fbs | 85 +++++++++++-------- 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index df798e30..65ca3301 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -318,16 +318,14 @@ public void addHealth(int healthAmount) { int maxHealth = this.type.getMaxHealth(this.level); if (this.health > maxHealth) { this.health = maxHealth; - if (this.mode == RobotMode.PROTOTYPE) + if (this.mode == RobotMode.PROTOTYPE) { this.mode = RobotMode.TURRET; + this.gameWorld.getMatchMaker().addAction(getID(), Action.FULLY_REPAIRED, -1); + } } if (this.health <= 0) { - int leadDrop = this.type.getLeadDropped(this.level); - int goldDrop = this.type.getGoldDropped(this.level); - // TODO: drop resources at this location (interact with GameWorld) this.gameWorld.destroyRobot(this.ID); } else if (this.health != oldHealth) { - // TODO: double check this this.gameWorld.getMatchMaker().addAction(getID(), Action.CHANGE_HEALTH, this.health - oldHealth); } } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 2c3ec427..7983ab7a 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -677,7 +677,7 @@ public void transmute() throws GameActionException { Team team = getTeam(); this.gameWorld.getTeamInfo().addLead(team, -getTransmutationRate()); this.gameWorld.getTeamInfo().addGold(team, 1); - this.gameWorld.getMatchMaker().addAction(getID(), Action.CONVERT_CURRENCY, -1); + this.gameWorld.getMatchMaker().addAction(getID(), Action.TRANSMUTE, -1); } // *************************** diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 1ef7131e..25d96afb 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -13,7 +13,6 @@ table VecTable { ys: [int]; } - /// A table of RGB values. table RGBTable { red: [int]; @@ -65,15 +64,10 @@ table GameMap { bodies: SpawnedBodyTable; /// The random seed of the map. randomSeed: int; - /// The factor to divide cooldowns by - passability: [double]; - - // lead locations - - // a vectable of lead cords - leadLocations: VecTable; - // inital lead amounts - leadAmounts: [double]; + /// The rubble on the map. + rubble: [int]; + /// The lead on the map. + lead: [int]; } /// Actions that can be performed. @@ -83,27 +77,44 @@ table GameMap { /// Actions may have 'targets', which are the units on which /// the actions were performed. enum Action : byte { - ATTACK, // combat unit types - SPAWN_UNIT, //archon - MINE, // miner - BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory. - TRANSFORM, // Swaps a building between portable and turret mode - UPGRADE, // builder upgrades building, - REPAIR, // builder repairs building - CHANGE_HP, - FULLY_REPAIRED, // prototype becomes a turret + /// Target: ID of robot attacked + ATTACK, + /// Target: ID of robot spawned + SPAWN_UNIT, + /// Target: location mined, x + y * width + MINE_LEAD, + /// Target: location mined, x + y * width + MINE_GOLD, + /// Target: none + TRANSMUTE, + /// Target: none + TRANSFORM, + /// Target: ID of robot mutated + MUTATE, + /// Target: ID of robot repaired + REPAIR, + /// Target: change in health (can be negative) + CHANGE_HEALTH, + /// When a PROTOTYPE building upgrades to TURRET + /// Target: none + FULLY_REPAIRED, + /// Target: Sage location, x + y * width LOCAL_ABYSS, + /// Target: Sage location, x + y * width LOCAL_FURY, + /// Target: Sage location, x + y * width LOCAL_CHARGE, - /// Dies due to an uncaught exception. /// Target: none - DIE_EXCEPTION, ABYSS, + /// Target: none CHARGE, + /// Target: none FURY, + /// Target: 0 if horizontal, 1 if vertical, 2 if 90 degrees clockwise VORTEX, - SINGULARITY + /// Dies due to an uncaught exception. + /// Target: none + DIE_EXCEPTION } // Metadata @@ -111,19 +122,15 @@ enum Action : byte { /// Metadata about all bodies of a particular type. table BodyTypeMetadata { type: BodyType; - spawnSource: BodyType; + buildCostLead: [int]; // array of length 3, build cost and upgrade costs + buildCostGold: [int]; // array of length 3, build cost and upgrade costs + actionCooldown: int; + movementCooldown: int; + health: int; + damage: int; actionRadiusSquared: int; visionRadiusSquared: int; - actionCooldown: float; - movementCooldown: float; bytecodeLimit: int; - dps: int; // dps at lowest level - hp: int; // hp at lowest level - dpsMul: float; // dps multiplier for level - hpMul: float; // hp multiplier per level - buildCost: int; - upgradeCostLead: [int]; - upgradeCostGold: [int]; } /// Data relevant to a particular team. @@ -246,8 +253,10 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; - teamLeadChange: [int]; - teamGoldChange: [int]; + /// The total amount of lead change of this team, this round + teamLeadChanges: [int]; + /// The total amount of gold change of this team, this round + teamGoldChanges: [int]; /// The IDs of bodies that moved. movedIDs: [int]; @@ -273,10 +282,14 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; + /// The locations of lead drops leadDropLocations: VecTable; + /// The amount of lead dropped at each location leadDropValues: [int]; + /// The locations of gold drops goldDropLocations: VecTable; + /// The amount of gold dropped at each location goldDropValues: [int]; /// The IDs of bodies that set indicator dots @@ -295,7 +308,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - //logs have been replaced with indicator strings + // logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) From f2c4217aa417149a2c9643adcfac8b80e5eec53d Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 9 Oct 2021 12:36:42 -0400 Subject: [PATCH 186/413] added a draft schema --- draft_schema.fbs | 304 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 draft_schema.fbs diff --git a/draft_schema.fbs b/draft_schema.fbs new file mode 100644 index 00000000..24698fcd --- /dev/null +++ b/draft_schema.fbs @@ -0,0 +1,304 @@ +namespace battlecode.schema; + +/// A vector in two-dimensional space. Discrete space, of course. +/// Defaults to the 0 vector. +struct Vec { + x: int = 0; + y: int = 0; +} + +/// A table of vectors. +table VecTable { + xs: [int]; + ys: [int]; +} + + +/// A table of RGB values. +table RGBTable { + red: [int]; + green: [int]; + blue: [int]; +} + +/// The possible types of things that can exist. +/// Note that bullets are not treated as bodies. +enum BodyType : byte { + + // Core unit types + MINER, + ARCHON, + BUILDER, + LABORATORY, + + // Combat units + GUARD, + GUARD_TURRET, + ARCHER, + ARCHER_TURRET, + WIZARD, + WIZARD_TURRET +} + +/// A list of new bodies to be placed on the map. +table SpawnedBodyTable { + /// The numeric ID of the new bodies. + /// Will never be negative. + /// There will only be one body with a particular ID at a time. + /// So, there will never be two robots with the same ID, or a robot and + /// a building with the same ID. + robotIDs: [int]; + /// The teams of the new bodies. + teamIDs: [byte]; + /// The types of the new bodies. + types: [BodyType]; + /// The locations of the bodies. + locs: VecTable; + /// the amount of influence paid to create these bodies + /// for initial Enlightenment Centers, this is the amount of influence + /// needed to take over + influences: [int]; +} + +/// The map a round is played on. +table GameMap { + /// The name of a map. + name: string; + /// The bottom corner of the map. + minCorner: Vec; + /// The top corner of the map. + maxCorner: Vec; + /// The bodies on the map. + bodies: SpawnedBodyTable; + /// The random seed of the map. + randomSeed: int; + /// The factor to divide cooldowns by + passability: [double]; +} + +/// Actions that can be performed. +/// Purely aesthetic; have no actual effect on simulation. +/// (Although the simulation may want to track the 'parents' of +/// particular robots.) +/// Actions may have 'targets', which are the units on which +/// the actions were performed. +enum Action : byte { + ATTACK, // combat unit types + DAZZLE, // wizard + SPAWN_UNIT, //archon + UPGRADE, //buldings + MINE, // miner + BUILD, // builder + CONVERT_GOLD, // for alchemist laboratory +} + +// Metadata + +/// Metadata about all bodies of a particular type. +table BodyTypeMetadata { + type: BodyType; + spawnSource: BodyType; + actionCooldown: float; + actionRadiusSquared: int; + visionRadiusSquared: int; + moveCooldown: float; + bytecodeLimit: int; + level: int; + dps: int; + hp: int; +} + +/// Data relevant to a particular team. +table TeamData { + /// The name of the team. + name: string; + /// The java package the team uses. + packageName: string; + /// The ID of the team this data pertains to. + teamID: byte; +} + +// Profiler tables + +/// These tables are set-up so that they match closely with speedscope's file format documented at +/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. +/// The client uses speedscope to show the recorded data in an interactive interface. + +/// A single event in a profile. Represents either an open event (meaning a +/// method has been entered) or a close event (meaning the method was exited). +table ProfilerEvent { + /// Whether this is an open event (true) or a close event (false). + isOpen: bool; + /// The bytecode counter at the time the event occurred. + at: int; + /// The index of the method name in the ProfilerFile.frames array. + frame: int; +} + +/// A profile contains all events and is labeled with a name. +table ProfilerProfile { + /// The display-friendly name of the profile. + name: string; + /// The events that occurred in the profile. + events: [ProfilerEvent]; +} + +/// A profiler file is a collection of profiles. +/// When profiling is enabled there is one of these per team per match. +table ProfilerFile { + /// The method names that are referred to in the events. + frames: [string]; + /// The recorded profiles, one per robot. + profiles: [ProfilerProfile]; +} + +/// Events + +/// An Event is a single step that needs to be processed. +/// A saved game simply consists of a long list of Events. +/// Events can be divided by either being sent separately (e.g. as separate +/// websocket messages), or by being wrapped with a GameWrapper. +/// A game consists of a series of matches; a match consists of a series of +/// rounds, and is played on a single map. Each round is a single simulation +/// step. +union Event { + /// There should only be one GameHeader, at the start of the stream. + GameHeader, + /// There should be one MatchHeader at the start of each match. + MatchHeader, + /// A single simulation step. A round may be skipped if + /// nothing happens during its time. + Round, + /// There should be one MatchFooter at the end of each simulation step. + MatchFooter, + /// There should only be one GameFooter, at the end of the stream. + GameFooter +} + +/// The first event sent in the game. Contains all metadata about the game. +table GameHeader { + /// The version of the spec this game complies with. + specVersion: string; + /// The teams participating in the game. + teams: [TeamData]; + /// Information about all body types in the game. + bodyTypeMetadata: [BodyTypeMetadata]; +} + +/// The final event sent in the game. +table GameFooter { + /// The ID of the winning team of the game. + winner: byte; +} + +/// Sent to start a match. +table MatchHeader { + /// The map the match was played on. + map: GameMap; + /// The maximum number of rounds in this match. + maxRounds: int; +} + +/// Sent to end a match. +table MatchFooter { + /// The ID of the winning team. + winner: byte; + /// The number of rounds played. + totalRounds: int; + /// Profiler data for team A and B if profiling is enabled. + profilerFiles: [ProfilerFile]; +} + +/// A single time-step in a Game. +/// The bulk of the data in the file is stored in tables like this. +/// Note that a struct-of-arrays format is more space efficient than an array- +/// of-structs. +table Round { + /// The IDs of teams in the Game. + teamIDs: [int]; + + /// The IDs of bodies that moved. + movedIDs: [int]; + /// The new locations of bodies that have moved. + movedLocs: VecTable; + + /// New bodies. + spawnedBodies: SpawnedBodyTable; + + /// The IDs of bodies that died. + diedIDs: [int]; + + /// The IDs of robots that performed actions. + /// IDs may repeat. + actionIDs: [int]; + /// The actions performed. These actions allow us to track how much soup or dirt a body carries. + actions: [Action]; + /// The 'targets' of the performed actions. Actions without targets may have any value + actionTargets: [int]; + + /// The IDs of bodies that set indicator dots + indicatorDotIDs: [int]; + /// The location of the indicator dots + indicatorDotLocs: VecTable; + /// The RGB values of the indicator dots + indicatorDotRGBs: RGBTable; + + /// The IDs of bodies that set indicator lines + indicatorLineIDs: [int]; + /// The start location of the indicator lines + indicatorLineStartLocs: VecTable; + /// The end location of the indicator lines + indicatorLineEndLocs: VecTable; + /// The RGB values of the indicator lines + indicatorLineRGBs: RGBTable; + + /// All logs sent this round. + /// Messages from a particular robot in this round start on a new line, and + /// have a header: + /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' + /// $TEAM = 'A' | 'B' + /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' + /// $ID = a number + /// $ROUND = a number + /// The header is not necessarily followed by a newline. + /// This header should only be sent once per robot per round (although + /// players may forge it, so don't crash if you get strange input.) + /// + /// You should try to only read this value once, and cache it. Reading + /// strings from a flatbuffer is much less efficient than reading other + /// buffers, because they need to be copied into an environment-provided + /// buffer and validated. + /// + /// (haha i guess you can never really escape string parsing can you) + logs: string; // TODO: maybe split into more arrays + + /// The first sent Round in a match should have index 1. (The starting state, + /// created by the MatchHeader, can be thought to have index 0.) + /// It should increase by one for each following round. + roundID: int; + + /// The IDs of player bodies. + bytecodeIDs: [int]; + /// The bytecodes used by the player bodies. + bytecodesUsed: [int]; +} + +/// Necessary due to flatbuffers requiring unions to be wrapped in tables. +table EventWrapper { + e: Event; +} + +/// If events are not otherwise delimited, this wrapper structure +/// allows a game to be stored in a single buffer. +/// The first event will be a GameHeader; the last event will be a GameFooter. +/// matchHeaders[0] is the index of the 0th match header in the event stream, +/// corresponding to matchFooters[0]. These indices allow quick traversal of +/// the file. +table GameWrapper { + /// The series of events comprising the game. + events: [EventWrapper]; + /// The indices of the headers of the matches, in order. + matchHeaders: [int]; + /// The indices of the footers of the matches, in order. + matchFooters: [int]; +} From 18df48201edde4022b966e7bc6ef648e58d7b7fb Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 23 Oct 2021 11:32:38 -0400 Subject: [PATCH 187/413] Move schema file --- draft_schema.fbs => schema/draft_schema.fbs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename draft_schema.fbs => schema/draft_schema.fbs (100%) diff --git a/draft_schema.fbs b/schema/draft_schema.fbs similarity index 100% rename from draft_schema.fbs rename to schema/draft_schema.fbs From 66db8f65a36c26cc52bbb28c6091477211cde9e9 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 30 Oct 2021 00:38:09 -0400 Subject: [PATCH 188/413] Update schema --- schema/draft_schema.fbs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 24698fcd..b1b88241 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,10 +54,8 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the amount of influence paid to create these bodies - /// for initial Enlightenment Centers, this is the amount of influence - /// needed to take over - influences: [int]; + /// the level of the body + level: [int]; } /// The map a round is played on. @@ -89,7 +87,12 @@ enum Action : byte { UPGRADE, //buldings MINE, // miner BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory + CONVERT_GOLD, // for alchemist laboratory. + ATTACKED, // when a body is attacked + TRANSFORM_PORTABLE, + TRANSFORM_TURRET, + UPGRADE, // builder upgrades building, + REPAIR // builder repairs building } // Metadata @@ -103,9 +106,10 @@ table BodyTypeMetadata { visionRadiusSquared: int; moveCooldown: float; bytecodeLimit: int; - level: int; dps: int; hp: int; + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level } /// Data relevant to a particular team. @@ -217,6 +221,9 @@ table Round { /// The IDs of teams in the Game. teamIDs: [int]; + teamLead: [int]; + teamGold: [int]; + /// The IDs of bodies that moved. movedIDs: [int]; /// The new locations of bodies that have moved. From d043f74b6aefd0f66d6b4b2033e6e3efd7289452 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Sat, 30 Oct 2021 12:30:03 -0400 Subject: [PATCH 189/413] Some schema changes --- schema/draft_schema.fbs | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b1b88241..23a8f802 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -54,8 +54,6 @@ table SpawnedBodyTable { types: [BodyType]; /// The locations of the bodies. locs: VecTable; - /// the level of the body - level: [int]; } /// The map a round is played on. @@ -89,10 +87,10 @@ enum Action : byte { BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. ATTACKED, // when a body is attacked - TRANSFORM_PORTABLE, - TRANSFORM_TURRET, + TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, - REPAIR // builder repairs building + REPAIR, // builder repairs building + CHANGE_HP } // Metadata @@ -243,6 +241,11 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; + /// The IDs of the robots who changed their indicator strings + indicationStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicationStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots @@ -259,25 +262,7 @@ table Round { /// The RGB values of the indicator lines indicatorLineRGBs: RGBTable; - /// All logs sent this round. - /// Messages from a particular robot in this round start on a new line, and - /// have a header: - /// '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - /// $TEAM = 'A' | 'B' - /// $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - /// $ID = a number - /// $ROUND = a number - /// The header is not necessarily followed by a newline. - /// This header should only be sent once per robot per round (although - /// players may forge it, so don't crash if you get strange input.) - /// - /// You should try to only read this value once, and cache it. Reading - /// strings from a flatbuffer is much less efficient than reading other - /// buffers, because they need to be copied into an environment-provided - /// buffer and validated. - /// - /// (haha i guess you can never really escape string parsing can you) - logs: string; // TODO: maybe split into more arrays + //logs have been replaced with indicator strings /// The first sent Round in a match should have index 1. (The starting state, /// created by the MatchHeader, can be thought to have index 0.) From 4bac96957e3a4e30412f3ee2c53e8206840f6cbf Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 11:18:37 -0400 Subject: [PATCH 190/413] Add repaired action --- schema/draft_schema.fbs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 23a8f802..01e8db8a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -82,7 +82,7 @@ enum Action : byte { ATTACK, // combat unit types DAZZLE, // wizard SPAWN_UNIT, //archon - UPGRADE, //buldings + UPGRADE, //buildings MINE, // miner BUILD, // builder CONVERT_GOLD, // for alchemist laboratory. @@ -90,7 +90,8 @@ enum Action : byte { TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state UPGRADE, // builder upgrades building, REPAIR, // builder repairs building - CHANGE_HP + CHANGE_HP, + REPAIRED // prototype becomes a turret } // Metadata @@ -102,10 +103,10 @@ table BodyTypeMetadata { actionCooldown: float; actionRadiusSquared: int; visionRadiusSquared: int; - moveCooldown: float; + movingCooldown: float; bytecodeLimit: int; - dps: int; - hp: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level } From 0198edb72919c3ba77efbc7c8691c00a2fc3459d Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:30:21 -0400 Subject: [PATCH 191/413] added lead to map --- schema/draft_schema.fbs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index 01e8db8a..d26f1681 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -70,6 +70,13 @@ table GameMap { randomSeed: int; /// The factor to divide cooldowns by passability: [double]; + + //lead locations + + // a vectable of lead cords + lead_locations: VecTable; + //inital lead amounts + initial_lead: [double]; } /// Actions that can be performed. From 2ba1f3bac226d880d33ab882499ae7598bd021df Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 6 Nov 2021 12:21:46 -0400 Subject: [PATCH 192/413] Change terminology --- schema/draft_schema.fbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index d26f1681..b4bf9840 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -98,7 +98,7 @@ enum Action : byte { UPGRADE, // builder upgrades building, REPAIR, // builder repairs building CHANGE_HP, - REPAIRED // prototype becomes a turret + FULLY_REPAIRED // prototype becomes a turret } // Metadata From cb3c84f98f3530f07d265e4ce73350c41c327d9c Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Sat, 6 Nov 2021 12:51:46 -0400 Subject: [PATCH 193/413] added lead increase contants and upgrade costs --- schema/draft_schema.fbs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs index b4bf9840..f1b0b68a 100644 --- a/schema/draft_schema.fbs +++ b/schema/draft_schema.fbs @@ -72,7 +72,7 @@ table GameMap { passability: [double]; //lead locations - + // a vectable of lead cords lead_locations: VecTable; //inital lead amounts @@ -116,6 +116,7 @@ table BodyTypeMetadata { hp: int; // hp at lowest level dps_mul: float; // dps multiplier for level hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -185,6 +186,14 @@ union Event { GameFooter } +table Constants{ + //amounts of resources added to each block per round + leadAdditiveIncease: double; + goldAdditiveIncease: double; + increase_period: int; +} + + /// The first event sent in the game. Contains all metadata about the game. table GameHeader { /// The version of the spec this game complies with. @@ -193,8 +202,14 @@ table GameHeader { teams: [TeamData]; /// Information about all body types in the game. bodyTypeMetadata: [BodyTypeMetadata]; + + //game constants + constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. From 8db347c4132b898fbc0d8562a88d92d898171434 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:18:27 -0500 Subject: [PATCH 194/413] Begin to update gameworld --- schema/battlecode.fbs | 9 +- schema/draft_schema.fbs | 319 ---------------------------------------- 2 files changed, 8 insertions(+), 320 deletions(-) delete mode 100644 schema/draft_schema.fbs diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 25d96afb..76f4143b 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -23,7 +23,6 @@ table RGBTable { /// The possible types of things that can exist. /// Note that bullets are not treated as bodies. enum BodyType : byte { - // droids MINER, BUILDER, @@ -131,6 +130,11 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; bytecodeLimit: int; + dps: int; // dps at lowest level + hp: int; // hp at lowest level + dps_mul: float; // dps multiplier for level + hp_mul: float; // hp multiplier per level + upgrade_costs: [int]; } /// Data relevant to a particular team. @@ -221,6 +225,9 @@ table GameHeader { constants: Constants; } + + + /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. diff --git a/schema/draft_schema.fbs b/schema/draft_schema.fbs deleted file mode 100644 index f1b0b68a..00000000 --- a/schema/draft_schema.fbs +++ /dev/null @@ -1,319 +0,0 @@ -namespace battlecode.schema; - -/// A vector in two-dimensional space. Discrete space, of course. -/// Defaults to the 0 vector. -struct Vec { - x: int = 0; - y: int = 0; -} - -/// A table of vectors. -table VecTable { - xs: [int]; - ys: [int]; -} - - -/// A table of RGB values. -table RGBTable { - red: [int]; - green: [int]; - blue: [int]; -} - -/// The possible types of things that can exist. -/// Note that bullets are not treated as bodies. -enum BodyType : byte { - - // Core unit types - MINER, - ARCHON, - BUILDER, - LABORATORY, - - // Combat units - GUARD, - GUARD_TURRET, - ARCHER, - ARCHER_TURRET, - WIZARD, - WIZARD_TURRET -} - -/// A list of new bodies to be placed on the map. -table SpawnedBodyTable { - /// The numeric ID of the new bodies. - /// Will never be negative. - /// There will only be one body with a particular ID at a time. - /// So, there will never be two robots with the same ID, or a robot and - /// a building with the same ID. - robotIDs: [int]; - /// The teams of the new bodies. - teamIDs: [byte]; - /// The types of the new bodies. - types: [BodyType]; - /// The locations of the bodies. - locs: VecTable; -} - -/// The map a round is played on. -table GameMap { - /// The name of a map. - name: string; - /// The bottom corner of the map. - minCorner: Vec; - /// The top corner of the map. - maxCorner: Vec; - /// The bodies on the map. - bodies: SpawnedBodyTable; - /// The random seed of the map. - randomSeed: int; - /// The factor to divide cooldowns by - passability: [double]; - - //lead locations - - // a vectable of lead cords - lead_locations: VecTable; - //inital lead amounts - initial_lead: [double]; -} - -/// Actions that can be performed. -/// Purely aesthetic; have no actual effect on simulation. -/// (Although the simulation may want to track the 'parents' of -/// particular robots.) -/// Actions may have 'targets', which are the units on which -/// the actions were performed. -enum Action : byte { - ATTACK, // combat unit types - DAZZLE, // wizard - SPAWN_UNIT, //archon - UPGRADE, //buildings - MINE, // miner - BUILD, // builder - CONVERT_GOLD, // for alchemist laboratory. - ATTACKED, // when a body is attacked - TRANSFORM, //Swaps a building from portable to turret or frorm turret to portable depending on current state - UPGRADE, // builder upgrades building, - REPAIR, // builder repairs building - CHANGE_HP, - FULLY_REPAIRED // prototype becomes a turret -} - -// Metadata - -/// Metadata about all bodies of a particular type. -table BodyTypeMetadata { - type: BodyType; - spawnSource: BodyType; - actionCooldown: float; - actionRadiusSquared: int; - visionRadiusSquared: int; - movingCooldown: float; - bytecodeLimit: int; - dps: int; // dps at lowest level - hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; -} - -/// Data relevant to a particular team. -table TeamData { - /// The name of the team. - name: string; - /// The java package the team uses. - packageName: string; - /// The ID of the team this data pertains to. - teamID: byte; -} - -// Profiler tables - -/// These tables are set-up so that they match closely with speedscope's file format documented at -/// https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. -/// The client uses speedscope to show the recorded data in an interactive interface. - -/// A single event in a profile. Represents either an open event (meaning a -/// method has been entered) or a close event (meaning the method was exited). -table ProfilerEvent { - /// Whether this is an open event (true) or a close event (false). - isOpen: bool; - /// The bytecode counter at the time the event occurred. - at: int; - /// The index of the method name in the ProfilerFile.frames array. - frame: int; -} - -/// A profile contains all events and is labeled with a name. -table ProfilerProfile { - /// The display-friendly name of the profile. - name: string; - /// The events that occurred in the profile. - events: [ProfilerEvent]; -} - -/// A profiler file is a collection of profiles. -/// When profiling is enabled there is one of these per team per match. -table ProfilerFile { - /// The method names that are referred to in the events. - frames: [string]; - /// The recorded profiles, one per robot. - profiles: [ProfilerProfile]; -} - -/// Events - -/// An Event is a single step that needs to be processed. -/// A saved game simply consists of a long list of Events. -/// Events can be divided by either being sent separately (e.g. as separate -/// websocket messages), or by being wrapped with a GameWrapper. -/// A game consists of a series of matches; a match consists of a series of -/// rounds, and is played on a single map. Each round is a single simulation -/// step. -union Event { - /// There should only be one GameHeader, at the start of the stream. - GameHeader, - /// There should be one MatchHeader at the start of each match. - MatchHeader, - /// A single simulation step. A round may be skipped if - /// nothing happens during its time. - Round, - /// There should be one MatchFooter at the end of each simulation step. - MatchFooter, - /// There should only be one GameFooter, at the end of the stream. - GameFooter -} - -table Constants{ - //amounts of resources added to each block per round - leadAdditiveIncease: double; - goldAdditiveIncease: double; - increase_period: int; -} - - -/// The first event sent in the game. Contains all metadata about the game. -table GameHeader { - /// The version of the spec this game complies with. - specVersion: string; - /// The teams participating in the game. - teams: [TeamData]; - /// Information about all body types in the game. - bodyTypeMetadata: [BodyTypeMetadata]; - - //game constants - constants: Constants; -} - - - - -/// The final event sent in the game. -table GameFooter { - /// The ID of the winning team of the game. - winner: byte; -} - -/// Sent to start a match. -table MatchHeader { - /// The map the match was played on. - map: GameMap; - /// The maximum number of rounds in this match. - maxRounds: int; -} - -/// Sent to end a match. -table MatchFooter { - /// The ID of the winning team. - winner: byte; - /// The number of rounds played. - totalRounds: int; - /// Profiler data for team A and B if profiling is enabled. - profilerFiles: [ProfilerFile]; -} - -/// A single time-step in a Game. -/// The bulk of the data in the file is stored in tables like this. -/// Note that a struct-of-arrays format is more space efficient than an array- -/// of-structs. -table Round { - /// The IDs of teams in the Game. - teamIDs: [int]; - - teamLead: [int]; - teamGold: [int]; - - /// The IDs of bodies that moved. - movedIDs: [int]; - /// The new locations of bodies that have moved. - movedLocs: VecTable; - - /// New bodies. - spawnedBodies: SpawnedBodyTable; - - /// The IDs of bodies that died. - diedIDs: [int]; - - /// The IDs of robots that performed actions. - /// IDs may repeat. - actionIDs: [int]; - /// The actions performed. These actions allow us to track how much soup or dirt a body carries. - actions: [Action]; - /// The 'targets' of the performed actions. Actions without targets may have any value - actionTargets: [int]; - - /// The IDs of the robots who changed their indicator strings - indicationStringIDs: [int]; - /// The messages of the robots who changed their indicator strings - indicationStrings: [string]; - - /// The IDs of bodies that set indicator dots - indicatorDotIDs: [int]; - /// The location of the indicator dots - indicatorDotLocs: VecTable; - /// The RGB values of the indicator dots - indicatorDotRGBs: RGBTable; - - /// The IDs of bodies that set indicator lines - indicatorLineIDs: [int]; - /// The start location of the indicator lines - indicatorLineStartLocs: VecTable; - /// The end location of the indicator lines - indicatorLineEndLocs: VecTable; - /// The RGB values of the indicator lines - indicatorLineRGBs: RGBTable; - - //logs have been replaced with indicator strings - - /// The first sent Round in a match should have index 1. (The starting state, - /// created by the MatchHeader, can be thought to have index 0.) - /// It should increase by one for each following round. - roundID: int; - - /// The IDs of player bodies. - bytecodeIDs: [int]; - /// The bytecodes used by the player bodies. - bytecodesUsed: [int]; -} - -/// Necessary due to flatbuffers requiring unions to be wrapped in tables. -table EventWrapper { - e: Event; -} - -/// If events are not otherwise delimited, this wrapper structure -/// allows a game to be stored in a single buffer. -/// The first event will be a GameHeader; the last event will be a GameFooter. -/// matchHeaders[0] is the index of the 0th match header in the event stream, -/// corresponding to matchFooters[0]. These indices allow quick traversal of -/// the file. -table GameWrapper { - /// The series of events comprising the game. - events: [EventWrapper]; - /// The indices of the headers of the matches, in order. - matchHeaders: [int]; - /// The indices of the footers of the matches, in order. - matchFooters: [int]; -} From a98aa1bb8072f92bdbcfadda724c65c345d08a77 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 13 Nov 2021 10:34:19 -0500 Subject: [PATCH 195/413] Compile typescript for current schema --- schema/ts/battlecode_generated.ts | 101 ++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 0093e8f9..6607707a 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -2024,6 +2024,107 @@ static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; +static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { + Constants.startConstants(builder); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); + Constants.addGoldAdditiveIncease(builder, goldAdditiveIncease); + Constants.addIncreasePeriod(builder, increasePeriod); + return Constants.endConstants(builder); +} +} +} +/** + * @constructor + */ +export namespace battlecode.schema{ +export class Constants { + bb: flatbuffers.ByteBuffer|null = null; + + bb_pos:number = 0; +/** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Constants + */ +__init(i:number, bb:flatbuffers.ByteBuffer):Constants { + this.bb_pos = i; + this.bb = bb; + return this; +}; + +/** + * @param flatbuffers.ByteBuffer bb + * @param Constants= obj + * @returns Constants + */ +static getRootAsConstants(bb:flatbuffers.ByteBuffer, obj?:Constants):Constants { + return (obj || new Constants).__init(bb.readInt32(bb.position()) + bb.position(), bb); +}; + +/** + * @returns number + */ +leadAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; +}; + +/** + * @returns number + */ +goldAdditiveIncease():number { + var offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; +}; + +/** + * @returns number + */ +increasePeriod():number { + var offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @param flatbuffers.Builder builder + */ +static startConstants(builder:flatbuffers.Builder) { + builder.startObject(3); +}; + +/** + * @param flatbuffers.Builder builder + * @param number leadAdditiveIncease + */ +static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { + builder.addFieldFloat64(0, leadAdditiveIncease, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number goldAdditiveIncease + */ +static addGoldAdditiveIncease(builder:flatbuffers.Builder, goldAdditiveIncease:number) { + builder.addFieldFloat64(1, goldAdditiveIncease, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number increasePeriod + */ +static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { + builder.addFieldInt32(2, increasePeriod, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { + var offset = builder.endObject(); + return offset; +}; + static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { Constants.startConstants(builder); Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); From de5c8837bab1dde08754829d57161ebda20c359e Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:22:21 -0500 Subject: [PATCH 196/413] Update schema --- schema/ts/battlecode_generated.ts | 75 +++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 6607707a..a27bc9ed 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,12 +10,21 @@ import { flatbuffers } from "./flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, +<<<<<<< HEAD BUILDER= 1, SOLDIER= 2, SAGE= 3, ARCHON= 4, LABORATORY= 5, WATCHTOWER= 6 +======= + ARCHON= 1, + BUILDER= 2, + LABORATORY= 3, + GUARD= 4, + WIZARD= 5, + TURRET= 6 +>>>>>>> Update schema }}; /** @@ -48,12 +57,16 @@ export enum Action{ * Dies due to an uncaught exception. * Target: none */ +<<<<<<< HEAD DIE_EXCEPTION= 13, ABYSS= 14, CHARGE= 15, FURY= 16, VORTEX= 17, SINGULARITY= 18 +======= + DIE_EXCEPTION= 13 +>>>>>>> Update schema }}; /** @@ -2692,7 +2705,11 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ +<<<<<<< HEAD teamLeadChange(index: number):number|null { +======= +teamLeadIncome(index: number):number|null { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2700,7 +2717,11 @@ teamLeadChange(index: number):number|null { /** * @returns number */ +<<<<<<< HEAD teamLeadChangeLength():number { +======= +teamLeadIncomeLength():number { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2708,7 +2729,11 @@ teamLeadChangeLength():number { /** * @returns Int32Array */ +<<<<<<< HEAD teamLeadChangeArray():Int32Array|null { +======= +teamLeadIncomeArray():Int32Array|null { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2717,7 +2742,11 @@ teamLeadChangeArray():Int32Array|null { * @param number index * @returns number */ +<<<<<<< HEAD teamGoldChange(index: number):number|null { +======= +teamGoldIncome(index: number):number|null { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2725,7 +2754,11 @@ teamGoldChange(index: number):number|null { /** * @returns number */ +<<<<<<< HEAD teamGoldChangeLength():number { +======= +teamGoldIncomeLength():number { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2733,7 +2766,11 @@ teamGoldChangeLength():number { /** * @returns Int32Array */ +<<<<<<< HEAD teamGoldChangeArray():Int32Array|null { +======= +teamGoldIncomeArray():Int32Array|null { +>>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3226,10 +3263,17 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder +<<<<<<< HEAD * @param flatbuffers.Offset teamLeadChangeOffset */ static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatbuffers.Offset) { builder.addFieldOffset(1, teamLeadChangeOffset, 0); +======= + * @param flatbuffers.Offset teamLeadIncomeOffset + */ +static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadIncomeOffset, 0); +>>>>>>> Update schema }; /** @@ -3237,7 +3281,11 @@ static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ +<<<<<<< HEAD static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +======= +static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +>>>>>>> Update schema builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3249,16 +3297,27 @@ static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ +<<<<<<< HEAD static startTeamLeadChangeVector(builder:flatbuffers.Builder, numElems:number) { +======= +static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { +>>>>>>> Update schema builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder +<<<<<<< HEAD * @param flatbuffers.Offset teamGoldChangeOffset */ static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatbuffers.Offset) { builder.addFieldOffset(2, teamGoldChangeOffset, 0); +======= + * @param flatbuffers.Offset teamGoldIncomeOffset + */ +static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldIncomeOffset, 0); +>>>>>>> Update schema }; /** @@ -3266,7 +3325,11 @@ static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ +<<<<<<< HEAD static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +======= +static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +>>>>>>> Update schema builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3278,7 +3341,11 @@ static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ +<<<<<<< HEAD static startTeamGoldChangeVector(builder:flatbuffers.Builder, numElems:number) { +======= +static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { +>>>>>>> Update schema builder.startVector(4, numElems, 4); }; @@ -3748,11 +3815,19 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; +<<<<<<< HEAD static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangeOffset:flatbuffers.Offset, teamGoldChangeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadChange(builder, teamLeadChangeOffset); Round.addTeamGoldChange(builder, teamGoldChangeOffset); +======= +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { + Round.startRound(builder); + Round.addTeamIDs(builder, teamIDsOffset); + Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); + Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); +>>>>>>> Update schema Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); From 31bb614e2047e4e20a3a5d2b8bc51a9d7e309fba Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:41:56 -0500 Subject: [PATCH 197/413] Add build cost to schema --- schema/battlecode.fbs | 7 +- schema/ts/battlecode_generated.ts | 108 +++++++----------------------- 2 files changed, 29 insertions(+), 86 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 76f4143b..e3207623 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -130,11 +130,12 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; bytecodeLimit: int; + buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level - dps_mul: float; // dps multiplier for level - hp_mul: float; // hp multiplier per level - upgrade_costs: [int]; + dpsMul: float; // dps multiplier for level + hpMul: float; // hp multiplier per level + upgradeCosts: [int]; } /// Data relevant to a particular team. diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index a27bc9ed..39c88c6c 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -10,21 +10,12 @@ import { flatbuffers } from "./flatbuffers" export namespace battlecode.schema{ export enum BodyType{ MINER= 0, -<<<<<<< HEAD BUILDER= 1, SOLDIER= 2, SAGE= 3, ARCHON= 4, LABORATORY= 5, WATCHTOWER= 6 -======= - ARCHON= 1, - BUILDER= 2, - LABORATORY= 3, - GUARD= 4, - WIZARD= 5, - TURRET= 6 ->>>>>>> Update schema }}; /** @@ -57,16 +48,12 @@ export enum Action{ * Dies due to an uncaught exception. * Target: none */ -<<<<<<< HEAD DIE_EXCEPTION= 13, ABYSS= 14, CHARGE= 15, FURY= 16, VORTEX= 17, SINGULARITY= 18 -======= - DIE_EXCEPTION= 13 ->>>>>>> Update schema }}; /** @@ -1161,7 +1148,7 @@ bytecodeLimit():number { /** * @returns number */ -dps():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1169,7 +1156,7 @@ dps():number { /** * @returns number */ -hp():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1177,8 +1164,16 @@ hp():number { /** * @returns number */ -dpsMul():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + +/** + * @returns number + */ +dpsMul():number { + var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1186,7 +1181,7 @@ dpsMul():number { * @returns number */ hpMul():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1311,12 +1306,20 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(7, buildCost, 0); +}; + /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(7, dps, 0); + builder.addFieldInt32(8, dps, 0); }; /** @@ -1324,7 +1327,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(8, hp, 0); + builder.addFieldInt32(9, hp, 0); }; /** @@ -1332,7 +1335,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(9, dpsMul, 0.0); + builder.addFieldFloat32(10, dpsMul, 0.0); }; /** @@ -1340,7 +1343,7 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(10, hpMul, 0.0); + builder.addFieldFloat32(11, hpMul, 0.0); }; /** @@ -1427,6 +1430,7 @@ static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schem BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); @@ -2705,11 +2709,7 @@ teamIDsArray():Int32Array|null { * @param number index * @returns number */ -<<<<<<< HEAD teamLeadChange(index: number):number|null { -======= -teamLeadIncome(index: number):number|null { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2717,11 +2717,7 @@ teamLeadIncome(index: number):number|null { /** * @returns number */ -<<<<<<< HEAD teamLeadChangeLength():number { -======= -teamLeadIncomeLength():number { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2729,11 +2725,7 @@ teamLeadIncomeLength():number { /** * @returns Int32Array */ -<<<<<<< HEAD teamLeadChangeArray():Int32Array|null { -======= -teamLeadIncomeArray():Int32Array|null { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -2742,11 +2734,7 @@ teamLeadIncomeArray():Int32Array|null { * @param number index * @returns number */ -<<<<<<< HEAD teamGoldChange(index: number):number|null { -======= -teamGoldIncome(index: number):number|null { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2754,11 +2742,7 @@ teamGoldIncome(index: number):number|null { /** * @returns number */ -<<<<<<< HEAD teamGoldChangeLength():number { -======= -teamGoldIncomeLength():number { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2766,11 +2750,7 @@ teamGoldIncomeLength():number { /** * @returns Int32Array */ -<<<<<<< HEAD teamGoldChangeArray():Int32Array|null { -======= -teamGoldIncomeArray():Int32Array|null { ->>>>>>> Update schema var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3263,17 +3243,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder -<<<<<<< HEAD * @param flatbuffers.Offset teamLeadChangeOffset */ static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatbuffers.Offset) { builder.addFieldOffset(1, teamLeadChangeOffset, 0); -======= - * @param flatbuffers.Offset teamLeadIncomeOffset - */ -static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadIncomeOffset, 0); ->>>>>>> Update schema }; /** @@ -3281,11 +3254,7 @@ static addTeamLeadIncome(builder:flatbuffers.Builder, teamLeadIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -<<<<<<< HEAD static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { -======= -static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { ->>>>>>> Update schema builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3297,27 +3266,16 @@ static createTeamLeadIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -<<<<<<< HEAD static startTeamLeadChangeVector(builder:flatbuffers.Builder, numElems:number) { -======= -static startTeamLeadIncomeVector(builder:flatbuffers.Builder, numElems:number) { ->>>>>>> Update schema builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder -<<<<<<< HEAD * @param flatbuffers.Offset teamGoldChangeOffset */ static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatbuffers.Offset) { builder.addFieldOffset(2, teamGoldChangeOffset, 0); -======= - * @param flatbuffers.Offset teamGoldIncomeOffset - */ -static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldIncomeOffset, 0); ->>>>>>> Update schema }; /** @@ -3325,11 +3283,7 @@ static addTeamGoldIncome(builder:flatbuffers.Builder, teamGoldIncomeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -<<<<<<< HEAD static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { -======= -static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { ->>>>>>> Update schema builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3341,11 +3295,7 @@ static createTeamGoldIncomeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -<<<<<<< HEAD static startTeamGoldChangeVector(builder:flatbuffers.Builder, numElems:number) { -======= -static startTeamGoldIncomeVector(builder:flatbuffers.Builder, numElems:number) { ->>>>>>> Update schema builder.startVector(4, numElems, 4); }; @@ -3815,19 +3765,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -<<<<<<< HEAD static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangeOffset:flatbuffers.Offset, teamGoldChangeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); Round.addTeamLeadChange(builder, teamLeadChangeOffset); Round.addTeamGoldChange(builder, teamGoldChangeOffset); -======= -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadIncomeOffset:flatbuffers.Offset, teamGoldIncomeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicationStringIDsOffset:flatbuffers.Offset, indicationStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { - Round.startRound(builder); - Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLeadIncome(builder, teamLeadIncomeOffset); - Round.addTeamGoldIncome(builder, teamGoldIncomeOffset); ->>>>>>> Update schema Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); From 20a9c7a3b8cb6143ebcf1a816c65333a6c6b9faa Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 11:47:33 -0500 Subject: [PATCH 198/413] More schema tweaks --- schema/battlecode.fbs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index e3207623..8c9fe108 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -226,9 +226,6 @@ table GameHeader { constants: Constants; } - - - /// The final event sent in the game. table GameFooter { /// The ID of the winning team of the game. @@ -285,11 +282,6 @@ table Round { /// The 'targets' of the performed actions. Actions without targets may have any value actionTargets: [int]; - /// The IDs of the robots who changed their indicator strings - indicatorStringIDs: [int]; - /// The messages of the robots who changed their indicator strings - indicatorStrings: [string]; - /// The locations of lead drops leadDropLocations: VecTable; /// The amount of lead dropped at each location @@ -300,6 +292,11 @@ table Round { /// The amount of gold dropped at each location goldDropValues: [int]; + /// The IDs of the robots who changed their indicator strings + indicatorStringIDs: [int]; + /// The messages of the robots who changed their indicator strings + indicatorStrings: [string]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots From 8960250fd51a85e57f452626a22ace8d3875c120 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:07:48 -0500 Subject: [PATCH 199/413] Minor schema changes --- schema/battlecode.fbs | 2 +- schema/ts/battlecode_generated.ts | 41 +++++++++++++++---------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 8c9fe108..7c03c342 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -130,11 +130,11 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; bytecodeLimit: int; - buildCost: int; dps: int; // dps at lowest level hp: int; // hp at lowest level dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level + buildCost: int; upgradeCosts: [int]; } diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 39c88c6c..4c058728 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1148,7 +1148,7 @@ bytecodeLimit():number { /** * @returns number */ -buildCost():number { +dps():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1156,7 +1156,7 @@ buildCost():number { /** * @returns number */ -dps():number { +hp():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1164,15 +1164,15 @@ dps():number { /** * @returns number */ -hp():number { +dpsMul():number { var offset = this.bb!.__offset(this.bb_pos, 22); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; /** * @returns number */ -dpsMul():number { +hpMul():number { var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; }; @@ -1180,9 +1180,9 @@ dpsMul():number { /** * @returns number */ -hpMul():number { +buildCost():number { var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** @@ -1306,20 +1306,12 @@ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { builder.addFieldInt32(6, bytecodeLimit, 0); }; -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(7, buildCost, 0); -}; - /** * @param flatbuffers.Builder builder * @param number dps */ static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(8, dps, 0); + builder.addFieldInt32(7, dps, 0); }; /** @@ -1327,7 +1319,7 @@ static addDps(builder:flatbuffers.Builder, dps:number) { * @param number hp */ static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(9, hp, 0); + builder.addFieldInt32(8, hp, 0); }; /** @@ -1335,7 +1327,7 @@ static addHp(builder:flatbuffers.Builder, hp:number) { * @param number dpsMul */ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(10, dpsMul, 0.0); + builder.addFieldFloat32(9, dpsMul, 0.0); }; /** @@ -1343,7 +1335,15 @@ static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { * @param number hpMul */ static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(11, hpMul, 0.0); + builder.addFieldFloat32(10, hpMul, 0.0); +}; + +/** + * @param flatbuffers.Builder builder + * @param number buildCost + */ +static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { + builder.addFieldInt32(11, buildCost, 0); }; /** @@ -1421,7 +1421,7 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); @@ -1430,7 +1430,6 @@ static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schem BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addBuildCost(builder, buildCost); BodyTypeMetadata.addDps(builder, dps); BodyTypeMetadata.addHp(builder, hp); BodyTypeMetadata.addDpsMul(builder, dpsMul); From 2e22107381dbc879fa032ee755098f2174081a31 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:10 -0500 Subject: [PATCH 200/413] Schema body types and resource drops --- schema/battlecode.fbs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 7c03c342..f49e26f0 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -297,6 +297,12 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; + leadDrops: VecTable; + leadDropsValues: [int]; + + goldDrops: VecTable; + goldDropsValues: [int]; + /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots From de137678adb40130046abce8cec931cda91f03bb Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 4 Dec 2021 12:43:55 -0500 Subject: [PATCH 201/413] whoops --- schema/ts/battlecode_generated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 4c058728..66777e57 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. From 6d600fd971216a8654cf8f56919cb285128e2400 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:06 -0500 Subject: [PATCH 202/413] preliminary engine feedback --- schema/battlecode.fbs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index f49e26f0..52a7bf4f 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -135,7 +135,8 @@ table BodyTypeMetadata { dpsMul: float; // dps multiplier for level hpMul: float; // hp multiplier per level buildCost: int; - upgradeCosts: [int]; + upgradeCostLead: [int]; + upgradeCostGold: [int]; } /// Data relevant to a particular team. @@ -297,11 +298,11 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; - leadDrops: VecTable; - leadDropsValues: [int]; + leadDropLocations: VecTable; + leadDropValues: [int]; - goldDrops: VecTable; - goldDropsValues: [int]; + goldDropLocations: VecTable; + goldDropValues: [int]; /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; From 7886c9c70834849c6a5758c2206e72ae28494558 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 4 Dec 2021 13:38:49 -0500 Subject: [PATCH 203/413] regenerate ts file --- schema/ts/battlecode_generated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 66777e57..e2099c20 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1421,7 +1421,7 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movingCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); BodyTypeMetadata.addSpawnSource(builder, spawnSource); From b6fcc0bcb9f031d7c2dcbd43b54228a8c580f39a Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Wed, 22 Dec 2021 11:22:39 -0500 Subject: [PATCH 204/413] Add actions for global anomalies --- schema/battlecode.fbs | 7 ++++++- schema/ts/battlecode_generated.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 52a7bf4f..ae149f93 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -113,7 +113,12 @@ enum Action : byte { VORTEX, /// Dies due to an uncaught exception. /// Target: none - DIE_EXCEPTION + DIE_EXCEPTION, + ABYSS, + CHARGE, + FURY, + VORTEX, + SINGULARITY } // Metadata diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index e2099c20..3ffa4e02 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "flatbuffers" +import { flatbuffers } from "./flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. From edea0547cb72239f3100c745c17b30478086aac5 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 23 Dec 2021 01:41:03 -0600 Subject: [PATCH 205/413] schema constants --- schema/battlecode.fbs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index ae149f93..c3f03945 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -212,10 +212,10 @@ union Event { } table Constants { - //amounts of resources added to each block per round - leadAdditiveIncease: double; - goldAdditiveIncease: double; + // number of rounds for passive lead increase increasePeriod: int; + // amounts of lead added every increasePeriod rounds + leadAdditiveIncease: int; } From 8310722f0739c6b9ee299fb4a64c52a470347415 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 23 Dec 2021 01:50:09 -0600 Subject: [PATCH 206/413] reorder vortex targets --- schema/battlecode.fbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index c3f03945..9202d028 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -109,7 +109,7 @@ enum Action : byte { CHARGE, /// Target: none FURY, - /// Target: 0 if horizontal, 1 if vertical, 2 if 90 degrees clockwise + /// Target: 0 if 90 degrees clockwise, 1 if horizontal, 2 if vertical VORTEX, /// Dies due to an uncaught exception. /// Target: none From a62e9860396f47824ef1b5559906f20543918407 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 17:34:28 -0600 Subject: [PATCH 207/413] tweak schema after rebase --- schema/battlecode.fbs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 9202d028..9295822a 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -100,9 +100,9 @@ enum Action : byte { /// Target: Sage location, x + y * width LOCAL_ABYSS, /// Target: Sage location, x + y * width - LOCAL_FURY, - /// Target: Sage location, x + y * width LOCAL_CHARGE, + /// Target: Sage location, x + y * width + LOCAL_FURY, /// Target: none ABYSS, /// Target: none @@ -114,11 +114,6 @@ enum Action : byte { /// Dies due to an uncaught exception. /// Target: none DIE_EXCEPTION, - ABYSS, - CHARGE, - FURY, - VORTEX, - SINGULARITY } // Metadata @@ -135,13 +130,6 @@ table BodyTypeMetadata { actionRadiusSquared: int; visionRadiusSquared: int; bytecodeLimit: int; - dps: int; // dps at lowest level - hp: int; // hp at lowest level - dpsMul: float; // dps multiplier for level - hpMul: float; // hp multiplier per level - buildCost: int; - upgradeCostLead: [int]; - upgradeCostGold: [int]; } /// Data relevant to a particular team. @@ -303,12 +291,6 @@ table Round { /// The messages of the robots who changed their indicator strings indicatorStrings: [string]; - leadDropLocations: VecTable; - leadDropValues: [int]; - - goldDropLocations: VecTable; - goldDropValues: [int]; - /// The IDs of bodies that set indicator dots indicatorDotIDs: [int]; /// The location of the indicator dots From 3ed6722809302a6df699d135e89a82b9650d1d57 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 17:43:20 -0600 Subject: [PATCH 208/413] compiled schema files --- .../main/battlecode/schema-old/Action.java | 77 +++++ .../main/battlecode/schema-old/BodyType.java | 34 +++ .../schema-old/BodyTypeMetadata.java | 88 ++++++ .../src/main/battlecode/schema-old/Event.java | 44 +++ .../battlecode/schema-old/EventWrapper.java | 40 +++ .../battlecode/schema-old/GameFooter.java | 39 +++ .../battlecode/schema-old/GameHeader.java | 63 ++++ .../main/battlecode/schema-old/GameMap.java | 67 +++++ .../battlecode/schema-old/GameWrapper.java | 72 +++++ .../battlecode/schema-old/MatchFooter.java | 57 ++++ .../battlecode/schema-old/MatchHeader.java | 47 +++ .../battlecode/schema-old/ProfilerEvent.java | 57 ++++ .../battlecode/schema-old/ProfilerFile.java | 54 ++++ .../schema-old/ProfilerProfile.java | 52 ++++ .../main/battlecode/schema-old/RGBTable.java | 59 ++++ .../src/main/battlecode/schema-old/Round.java | 283 ++++++++++++++++++ .../schema-old/SpawnedBodyTable.java | 94 ++++++ .../main/battlecode/schema-old/TeamData.java | 57 ++++ .../src/main/battlecode/schema-old/Vec.java | 29 ++ .../main/battlecode/schema-old/VecTable.java | 50 ++++ engine/src/main/battlecode/schema/Action.java | 83 +++-- .../src/main/battlecode/schema/BodyType.java | 27 +- .../battlecode/schema/BodyTypeMetadata.java | 92 +++--- .../src/main/battlecode/schema/Constants.java | 37 +++ .../main/battlecode/schema/GameHeader.java | 11 +- .../src/main/battlecode/schema/GameMap.java | 28 +- engine/src/main/battlecode/schema/Round.java | 210 +++++++------ .../battlecode/schema/SpawnedBodyTable.java | 20 +- schema/java/battlecode/schema/Action.java | 83 +++-- schema/java/battlecode/schema/BodyType.java | 27 +- .../battlecode/schema/BodyTypeMetadata.java | 92 +++--- schema/java/battlecode/schema/Constants.java | 37 +++ schema/java/battlecode/schema/GameHeader.java | 11 +- schema/java/battlecode/schema/GameMap.java | 28 +- schema/java/battlecode/schema/Round.java | 210 +++++++------ .../battlecode/schema/SpawnedBodyTable.java | 20 +- 36 files changed, 1933 insertions(+), 446 deletions(-) create mode 100644 engine/src/main/battlecode/schema-old/Action.java create mode 100644 engine/src/main/battlecode/schema-old/BodyType.java create mode 100644 engine/src/main/battlecode/schema-old/BodyTypeMetadata.java create mode 100644 engine/src/main/battlecode/schema-old/Event.java create mode 100644 engine/src/main/battlecode/schema-old/EventWrapper.java create mode 100644 engine/src/main/battlecode/schema-old/GameFooter.java create mode 100644 engine/src/main/battlecode/schema-old/GameHeader.java create mode 100644 engine/src/main/battlecode/schema-old/GameMap.java create mode 100644 engine/src/main/battlecode/schema-old/GameWrapper.java create mode 100644 engine/src/main/battlecode/schema-old/MatchFooter.java create mode 100644 engine/src/main/battlecode/schema-old/MatchHeader.java create mode 100644 engine/src/main/battlecode/schema-old/ProfilerEvent.java create mode 100644 engine/src/main/battlecode/schema-old/ProfilerFile.java create mode 100644 engine/src/main/battlecode/schema-old/ProfilerProfile.java create mode 100644 engine/src/main/battlecode/schema-old/RGBTable.java create mode 100644 engine/src/main/battlecode/schema-old/Round.java create mode 100644 engine/src/main/battlecode/schema-old/SpawnedBodyTable.java create mode 100644 engine/src/main/battlecode/schema-old/TeamData.java create mode 100644 engine/src/main/battlecode/schema-old/Vec.java create mode 100644 engine/src/main/battlecode/schema-old/VecTable.java create mode 100644 engine/src/main/battlecode/schema/Constants.java create mode 100644 schema/java/battlecode/schema/Constants.java diff --git a/engine/src/main/battlecode/schema-old/Action.java b/engine/src/main/battlecode/schema-old/Action.java new file mode 100644 index 00000000..a21287a3 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/Action.java @@ -0,0 +1,77 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +/** + * Actions that can be performed. + * Purely aesthetic; have no actual effect on simulation. + * (Although the simulation may want to track the 'parents' of + * particular robots.) + * Actions may have 'targets', which are the units on which + * the actions were performed. + */ +public final class Action { + private Action() { } + /** + * Politicians self-destruct and affect nearby bodies. + * Target: radius squared + */ + public static final byte EMPOWER = 0; + /** + * Slanderers passively generate influence for the + * Enlightenment Center that created them. + * Target: parent ID + */ + public static final byte EMBEZZLE = 1; + /** + * Slanderers turn into Politicians. + * Target: none + */ + public static final byte CAMOUFLAGE = 2; + /** + * Muckrakers can expose a slanderer. + * Target: an enemy body + */ + public static final byte EXPOSE = 3; + /** + * Units can change their flag. + * Target: new flag value + */ + public static final byte SET_FLAG = 4; + /** + * Builds a unit. + * Target: spawned unit + */ + public static final byte SPAWN_UNIT = 5; + /** + * Places a bid. + * Target: bid value + */ + public static final byte PLACE_BID = 6; + /** + * A robot can change team after being empowered, + * or when a Enlightenment Center is taken over. + * Target: new robotID + */ + public static final byte CHANGE_TEAM = 7; + /** + * A robot's influence changes. + * Target: delta value + */ + public static final byte CHANGE_INFLUENCE = 8; + /** + * A robot's conviction changes. + * Target: delta value, i.e. red 5 -> blue 3 is -2 + */ + public static final byte CHANGE_CONVICTION = 9; + /** + * Dies due to an uncaught exception. + * Target: none + */ + public static final byte DIE_EXCEPTION = 10; + + public static final String[] names = { "EMPOWER", "EMBEZZLE", "CAMOUFLAGE", "EXPOSE", "SET_FLAG", "SPAWN_UNIT", "PLACE_BID", "CHANGE_TEAM", "CHANGE_INFLUENCE", "CHANGE_CONVICTION", "DIE_EXCEPTION", }; + + public static String name(int e) { return names[e]; } +} + diff --git a/engine/src/main/battlecode/schema-old/BodyType.java b/engine/src/main/battlecode/schema-old/BodyType.java new file mode 100644 index 00000000..ee34e38d --- /dev/null +++ b/engine/src/main/battlecode/schema-old/BodyType.java @@ -0,0 +1,34 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +/** + * The possible types of things that can exist. + * Note that bullets are not treated as bodies. + */ +public final class BodyType { + private BodyType() { } + /** + * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids + *can be neutral until captured + */ + public static final byte ENLIGHTENMENT_CENTER = 0; + /** + * politicians use their influence to self destruct and capture other units + */ + public static final byte POLITICIAN = 1; + /** + * slanderers generate passive influence for the enlightenment center that created them + * they turn into politicians at some point, and can only be identified by slanderers. + */ + public static final byte SLANDERER = 2; + /** + * have the ability to identify slanderers + */ + public static final byte MUCKRAKER = 3; + + public static final String[] names = { "ENLIGHTENMENT_CENTER", "POLITICIAN", "SLANDERER", "MUCKRAKER", }; + + public static String name(int e) { return names[e]; } +} + diff --git a/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java b/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java new file mode 100644 index 00000000..8b7e63ba --- /dev/null +++ b/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * Metadata about all bodies of a particular type. + */ +public final class BodyTypeMetadata extends Table { + public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb) { return getRootAsBodyTypeMetadata(_bb, new BodyTypeMetadata()); } + public static BodyTypeMetadata getRootAsBodyTypeMetadata(ByteBuffer _bb, BodyTypeMetadata obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The relevant type. + */ + public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } + /** + * The spawn source. + */ + public byte spawnSource() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; } + /** + * the convictionRatio of this type + */ + public float convictionRatio() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + /** + * cooldown of this type + */ + public float actionCooldown() { int o = __offset(10); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } + /** + * action radius if this type + */ + public int actionRadiusSquared() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * sensor radius squared for this type + */ + public int sensorRadiusSquared() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * detection radius of this type + */ + public int detectionRadiusSquared() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * bytecode limit for this type + */ + public int bytecodeLimit() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + + public static int createBodyTypeMetadata(FlatBufferBuilder builder, + byte type, + byte spawnSource, + float convictionRatio, + float actionCooldown, + int actionRadiusSquared, + int sensorRadiusSquared, + int detectionRadiusSquared, + int bytecodeLimit) { + builder.startObject(8); + BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); + BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); + BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); + BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addActionCooldown(builder, actionCooldown); + BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); + BodyTypeMetadata.addSpawnSource(builder, spawnSource); + BodyTypeMetadata.addType(builder, type); + return BodyTypeMetadata.endBodyTypeMetadata(builder); + } + + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(8); } + public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } + public static void addSpawnSource(FlatBufferBuilder builder, byte spawnSource) { builder.addByte(1, spawnSource, 0); } + public static void addConvictionRatio(FlatBufferBuilder builder, float convictionRatio) { builder.addFloat(2, convictionRatio, 0.0f); } + public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(3, actionCooldown, 0.0f); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(4, actionRadiusSquared, 0); } + public static void addSensorRadiusSquared(FlatBufferBuilder builder, int sensorRadiusSquared) { builder.addInt(5, sensorRadiusSquared, 0); } + public static void addDetectionRadiusSquared(FlatBufferBuilder builder, int detectionRadiusSquared) { builder.addInt(6, detectionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(7, bytecodeLimit, 0); } + public static int endBodyTypeMetadata(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/Event.java b/engine/src/main/battlecode/schema-old/Event.java new file mode 100644 index 00000000..15d257e3 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/Event.java @@ -0,0 +1,44 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +/** + * Events + * An Event is a single step that needs to be processed. + * A saved game simply consists of a long list of Events. + * Events can be divided by either being sent separately (e.g. as separate + * websocket messages), or by being wrapped with a GameWrapper. + * A game consists of a series of matches; a match consists of a series of + * rounds, and is played on a single map. Each round is a single simulation + * step. + */ +public final class Event { + private Event() { } + public static final byte NONE = 0; + /** + * There should only be one GameHeader, at the start of the stream. + */ + public static final byte GameHeader = 1; + /** + * There should be one MatchHeader at the start of each match. + */ + public static final byte MatchHeader = 2; + /** + * A single simulation step. A round may be skipped if + * nothing happens during its time. + */ + public static final byte Round = 3; + /** + * There should be one MatchFooter at the end of each simulation step. + */ + public static final byte MatchFooter = 4; + /** + * There should only be one GameFooter, at the end of the stream. + */ + public static final byte GameFooter = 5; + + public static final String[] names = { "NONE", "GameHeader", "MatchHeader", "Round", "MatchFooter", "GameFooter", }; + + public static String name(int e) { return names[e]; } +} + diff --git a/engine/src/main/battlecode/schema-old/EventWrapper.java b/engine/src/main/battlecode/schema-old/EventWrapper.java new file mode 100644 index 00000000..3eb73a91 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/EventWrapper.java @@ -0,0 +1,40 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * Necessary due to flatbuffers requiring unions to be wrapped in tables. + */ +public final class EventWrapper extends Table { + public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb) { return getRootAsEventWrapper(_bb, new EventWrapper()); } + public static EventWrapper getRootAsEventWrapper(ByteBuffer _bb, EventWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public EventWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public byte eType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } + public Table e(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; } + + public static int createEventWrapper(FlatBufferBuilder builder, + byte e_type, + int eOffset) { + builder.startObject(2); + EventWrapper.addE(builder, eOffset); + EventWrapper.addEType(builder, e_type); + return EventWrapper.endEventWrapper(builder); + } + + public static void startEventWrapper(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addEType(FlatBufferBuilder builder, byte eType) { builder.addByte(0, eType, 0); } + public static void addE(FlatBufferBuilder builder, int eOffset) { builder.addOffset(1, eOffset, 0); } + public static int endEventWrapper(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/GameFooter.java b/engine/src/main/battlecode/schema-old/GameFooter.java new file mode 100644 index 00000000..b5512bb5 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/GameFooter.java @@ -0,0 +1,39 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * The final event sent in the game. + */ +public final class GameFooter extends Table { + public static GameFooter getRootAsGameFooter(ByteBuffer _bb) { return getRootAsGameFooter(_bb, new GameFooter()); } + public static GameFooter getRootAsGameFooter(ByteBuffer _bb, GameFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public GameFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The ID of the winning team of the game. + */ + public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } + + public static int createGameFooter(FlatBufferBuilder builder, + byte winner) { + builder.startObject(1); + GameFooter.addWinner(builder, winner); + return GameFooter.endGameFooter(builder); + } + + public static void startGameFooter(FlatBufferBuilder builder) { builder.startObject(1); } + public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } + public static int endGameFooter(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/GameHeader.java b/engine/src/main/battlecode/schema-old/GameHeader.java new file mode 100644 index 00000000..77363711 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/GameHeader.java @@ -0,0 +1,63 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * The first event sent in the game. Contains all metadata about the game. + */ +public final class GameHeader extends Table { + public static GameHeader getRootAsGameHeader(ByteBuffer _bb) { return getRootAsGameHeader(_bb, new GameHeader()); } + public static GameHeader getRootAsGameHeader(ByteBuffer _bb, GameHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public GameHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The version of the spec this game complies with. + */ + public String specVersion() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer specVersionAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } + public ByteBuffer specVersionInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } + /** + * The teams participating in the game. + */ + public TeamData teams(int j) { return teams(new TeamData(), j); } + public TeamData teams(TeamData obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int teamsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + /** + * Information about all body types in the game. + */ + public BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new BodyTypeMetadata(), j); } + public BodyTypeMetadata bodyTypeMetadata(BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int bodyTypeMetadataLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + + public static int createGameHeader(FlatBufferBuilder builder, + int specVersionOffset, + int teamsOffset, + int bodyTypeMetadataOffset) { + builder.startObject(3); + GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); + GameHeader.addTeams(builder, teamsOffset); + GameHeader.addSpecVersion(builder, specVersionOffset); + return GameHeader.endGameHeader(builder); + } + + public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addSpecVersion(FlatBufferBuilder builder, int specVersionOffset) { builder.addOffset(0, specVersionOffset, 0); } + public static void addTeams(FlatBufferBuilder builder, int teamsOffset) { builder.addOffset(1, teamsOffset, 0); } + public static int createTeamsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startTeamsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addBodyTypeMetadata(FlatBufferBuilder builder, int bodyTypeMetadataOffset) { builder.addOffset(2, bodyTypeMetadataOffset, 0); } + public static int createBodyTypeMetadataVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startBodyTypeMetadataVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endGameHeader(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/GameMap.java b/engine/src/main/battlecode/schema-old/GameMap.java new file mode 100644 index 00000000..09b78818 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/GameMap.java @@ -0,0 +1,67 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * The map a round is played on. + */ +public final class GameMap extends Table { + public static GameMap getRootAsGameMap(ByteBuffer _bb) { return getRootAsGameMap(_bb, new GameMap()); } + public static GameMap getRootAsGameMap(ByteBuffer _bb, GameMap obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public GameMap __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The name of a map. + */ + public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } + public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } + /** + * The bottom corner of the map. + */ + public Vec minCorner() { return minCorner(new Vec()); } + public Vec minCorner(Vec obj) { int o = __offset(6); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + /** + * The top corner of the map. + */ + public Vec maxCorner() { return maxCorner(new Vec()); } + public Vec maxCorner(Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + /** + * The bodies on the map. + */ + public SpawnedBodyTable bodies() { return bodies(new SpawnedBodyTable()); } + public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The random seed of the map. + */ + public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * The factor to divide cooldowns by + */ + public double passability(int j) { int o = __offset(14); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } + public int passabilityLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer passabilityAsByteBuffer() { return __vector_as_bytebuffer(14, 8); } + public ByteBuffer passabilityInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 8); } + + public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(6); } + public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } + public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } + public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } + public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } + public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } + public static void addPassability(FlatBufferBuilder builder, int passabilityOffset) { builder.addOffset(5, passabilityOffset, 0); } + public static int createPassabilityVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } + public static void startPassabilityVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } + public static int endGameMap(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/GameWrapper.java b/engine/src/main/battlecode/schema-old/GameWrapper.java new file mode 100644 index 00000000..25a0c03e --- /dev/null +++ b/engine/src/main/battlecode/schema-old/GameWrapper.java @@ -0,0 +1,72 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * If events are not otherwise delimited, this wrapper structure + * allows a game to be stored in a single buffer. + * The first event will be a GameHeader; the last event will be a GameFooter. + * matchHeaders[0] is the index of the 0th match header in the event stream, + * corresponding to matchFooters[0]. These indices allow quick traversal of + * the file. + */ +public final class GameWrapper extends Table { + public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb) { return getRootAsGameWrapper(_bb, new GameWrapper()); } + public static GameWrapper getRootAsGameWrapper(ByteBuffer _bb, GameWrapper obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public GameWrapper __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The series of events comprising the game. + */ + public EventWrapper events(int j) { return events(new EventWrapper(), j); } + public EventWrapper events(EventWrapper obj, int j) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int eventsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + /** + * The indices of the headers of the matches, in order. + */ + public int matchHeaders(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int matchHeadersLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer matchHeadersAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer matchHeadersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + /** + * The indices of the footers of the matches, in order. + */ + public int matchFooters(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int matchFootersLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer matchFootersAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer matchFootersInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + + public static int createGameWrapper(FlatBufferBuilder builder, + int eventsOffset, + int matchHeadersOffset, + int matchFootersOffset) { + builder.startObject(3); + GameWrapper.addMatchFooters(builder, matchFootersOffset); + GameWrapper.addMatchHeaders(builder, matchHeadersOffset); + GameWrapper.addEvents(builder, eventsOffset); + return GameWrapper.endGameWrapper(builder); + } + + public static void startGameWrapper(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(0, eventsOffset, 0); } + public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addMatchHeaders(FlatBufferBuilder builder, int matchHeadersOffset) { builder.addOffset(1, matchHeadersOffset, 0); } + public static int createMatchHeadersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startMatchHeadersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addMatchFooters(FlatBufferBuilder builder, int matchFootersOffset) { builder.addOffset(2, matchFootersOffset, 0); } + public static int createMatchFootersVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startMatchFootersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endGameWrapper(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/MatchFooter.java b/engine/src/main/battlecode/schema-old/MatchFooter.java new file mode 100644 index 00000000..8777c9ea --- /dev/null +++ b/engine/src/main/battlecode/schema-old/MatchFooter.java @@ -0,0 +1,57 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * Sent to end a match. + */ +public final class MatchFooter extends Table { + public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb) { return getRootAsMatchFooter(_bb, new MatchFooter()); } + public static MatchFooter getRootAsMatchFooter(ByteBuffer _bb, MatchFooter obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public MatchFooter __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The ID of the winning team. + */ + public byte winner() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } + /** + * The number of rounds played. + */ + public int totalRounds() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * Profiler data for team A and B if profiling is enabled. + */ + public ProfilerFile profilerFiles(int j) { return profilerFiles(new ProfilerFile(), j); } + public ProfilerFile profilerFiles(ProfilerFile obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int profilerFilesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + + public static int createMatchFooter(FlatBufferBuilder builder, + byte winner, + int totalRounds, + int profilerFilesOffset) { + builder.startObject(3); + MatchFooter.addProfilerFiles(builder, profilerFilesOffset); + MatchFooter.addTotalRounds(builder, totalRounds); + MatchFooter.addWinner(builder, winner); + return MatchFooter.endMatchFooter(builder); + } + + public static void startMatchFooter(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addWinner(FlatBufferBuilder builder, byte winner) { builder.addByte(0, winner, 0); } + public static void addTotalRounds(FlatBufferBuilder builder, int totalRounds) { builder.addInt(1, totalRounds, 0); } + public static void addProfilerFiles(FlatBufferBuilder builder, int profilerFilesOffset) { builder.addOffset(2, profilerFilesOffset, 0); } + public static int createProfilerFilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startProfilerFilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endMatchFooter(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/MatchHeader.java b/engine/src/main/battlecode/schema-old/MatchHeader.java new file mode 100644 index 00000000..b167ea98 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/MatchHeader.java @@ -0,0 +1,47 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * Sent to start a match. + */ +public final class MatchHeader extends Table { + public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb) { return getRootAsMatchHeader(_bb, new MatchHeader()); } + public static MatchHeader getRootAsMatchHeader(ByteBuffer _bb, MatchHeader obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public MatchHeader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The map the match was played on. + */ + public GameMap map() { return map(new GameMap()); } + public GameMap map(GameMap obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The maximum number of rounds in this match. + */ + public int maxRounds() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + + public static int createMatchHeader(FlatBufferBuilder builder, + int mapOffset, + int maxRounds) { + builder.startObject(2); + MatchHeader.addMaxRounds(builder, maxRounds); + MatchHeader.addMap(builder, mapOffset); + return MatchHeader.endMatchHeader(builder); + } + + public static void startMatchHeader(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addMap(FlatBufferBuilder builder, int mapOffset) { builder.addOffset(0, mapOffset, 0); } + public static void addMaxRounds(FlatBufferBuilder builder, int maxRounds) { builder.addInt(1, maxRounds, 0); } + public static int endMatchHeader(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/ProfilerEvent.java b/engine/src/main/battlecode/schema-old/ProfilerEvent.java new file mode 100644 index 00000000..58c47f12 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/ProfilerEvent.java @@ -0,0 +1,57 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * These tables are set-up so that they match closely with speedscope's file format documented at + * https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources. + * The client uses speedscope to show the recorded data in an interactive interface. + * A single event in a profile. Represents either an open event (meaning a + * method has been entered) or a close event (meaning the method was exited). + */ +public final class ProfilerEvent extends Table { + public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb) { return getRootAsProfilerEvent(_bb, new ProfilerEvent()); } + public static ProfilerEvent getRootAsProfilerEvent(ByteBuffer _bb, ProfilerEvent obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public ProfilerEvent __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * Whether this is an open event (true) or a close event (false). + */ + public boolean isOpen() { int o = __offset(4); return o != 0 ? 0!=bb.get(o + bb_pos) : false; } + /** + * The bytecode counter at the time the event occurred. + */ + public int at() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * The index of the method name in the ProfilerFile.frames array. + */ + public int frame() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + + public static int createProfilerEvent(FlatBufferBuilder builder, + boolean isOpen, + int at, + int frame) { + builder.startObject(3); + ProfilerEvent.addFrame(builder, frame); + ProfilerEvent.addAt(builder, at); + ProfilerEvent.addIsOpen(builder, isOpen); + return ProfilerEvent.endProfilerEvent(builder); + } + + public static void startProfilerEvent(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addIsOpen(FlatBufferBuilder builder, boolean isOpen) { builder.addBoolean(0, isOpen, false); } + public static void addAt(FlatBufferBuilder builder, int at) { builder.addInt(1, at, 0); } + public static void addFrame(FlatBufferBuilder builder, int frame) { builder.addInt(2, frame, 0); } + public static int endProfilerEvent(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/ProfilerFile.java b/engine/src/main/battlecode/schema-old/ProfilerFile.java new file mode 100644 index 00000000..c101925d --- /dev/null +++ b/engine/src/main/battlecode/schema-old/ProfilerFile.java @@ -0,0 +1,54 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A profiler file is a collection of profiles. + * When profiling is enabled there is one of these per team per match. + */ +public final class ProfilerFile extends Table { + public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb) { return getRootAsProfilerFile(_bb, new ProfilerFile()); } + public static ProfilerFile getRootAsProfilerFile(ByteBuffer _bb, ProfilerFile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public ProfilerFile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The method names that are referred to in the events. + */ + public String frames(int j) { int o = __offset(4); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int framesLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + /** + * The recorded profiles, one per robot. + */ + public ProfilerProfile profiles(int j) { return profiles(new ProfilerProfile(), j); } + public ProfilerProfile profiles(ProfilerProfile obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int profilesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + + public static int createProfilerFile(FlatBufferBuilder builder, + int framesOffset, + int profilesOffset) { + builder.startObject(2); + ProfilerFile.addProfiles(builder, profilesOffset); + ProfilerFile.addFrames(builder, framesOffset); + return ProfilerFile.endProfilerFile(builder); + } + + public static void startProfilerFile(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addFrames(FlatBufferBuilder builder, int framesOffset) { builder.addOffset(0, framesOffset, 0); } + public static int createFramesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startFramesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addProfiles(FlatBufferBuilder builder, int profilesOffset) { builder.addOffset(1, profilesOffset, 0); } + public static int createProfilesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startProfilesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endProfilerFile(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/ProfilerProfile.java b/engine/src/main/battlecode/schema-old/ProfilerProfile.java new file mode 100644 index 00000000..15312ead --- /dev/null +++ b/engine/src/main/battlecode/schema-old/ProfilerProfile.java @@ -0,0 +1,52 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A profile contains all events and is labeled with a name. + */ +public final class ProfilerProfile extends Table { + public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb) { return getRootAsProfilerProfile(_bb, new ProfilerProfile()); } + public static ProfilerProfile getRootAsProfilerProfile(ByteBuffer _bb, ProfilerProfile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public ProfilerProfile __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The display-friendly name of the profile. + */ + public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } + public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } + /** + * The events that occurred in the profile. + */ + public ProfilerEvent events(int j) { return events(new ProfilerEvent(), j); } + public ProfilerEvent events(ProfilerEvent obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int eventsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + + public static int createProfilerProfile(FlatBufferBuilder builder, + int nameOffset, + int eventsOffset) { + builder.startObject(2); + ProfilerProfile.addEvents(builder, eventsOffset); + ProfilerProfile.addName(builder, nameOffset); + return ProfilerProfile.endProfilerProfile(builder); + } + + public static void startProfilerProfile(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } + public static void addEvents(FlatBufferBuilder builder, int eventsOffset) { builder.addOffset(1, eventsOffset, 0); } + public static int createEventsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startEventsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endProfilerProfile(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/RGBTable.java b/engine/src/main/battlecode/schema-old/RGBTable.java new file mode 100644 index 00000000..6164af79 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/RGBTable.java @@ -0,0 +1,59 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A table of RGB values. + */ +public final class RGBTable extends Table { + public static RGBTable getRootAsRGBTable(ByteBuffer _bb) { return getRootAsRGBTable(_bb, new RGBTable()); } + public static RGBTable getRootAsRGBTable(ByteBuffer _bb, RGBTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public RGBTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public int red(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int redLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer redAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } + public ByteBuffer redInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } + public int green(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int greenLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer greenAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer greenInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int blue(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int blueLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer blueAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer blueInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + + public static int createRGBTable(FlatBufferBuilder builder, + int redOffset, + int greenOffset, + int blueOffset) { + builder.startObject(3); + RGBTable.addBlue(builder, blueOffset); + RGBTable.addGreen(builder, greenOffset); + RGBTable.addRed(builder, redOffset); + return RGBTable.endRGBTable(builder); + } + + public static void startRGBTable(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addRed(FlatBufferBuilder builder, int redOffset) { builder.addOffset(0, redOffset, 0); } + public static int createRedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startRedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addGreen(FlatBufferBuilder builder, int greenOffset) { builder.addOffset(1, greenOffset, 0); } + public static int createGreenVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startGreenVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addBlue(FlatBufferBuilder builder, int blueOffset) { builder.addOffset(2, blueOffset, 0); } + public static int createBlueVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBlueVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endRGBTable(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/Round.java b/engine/src/main/battlecode/schema-old/Round.java new file mode 100644 index 00000000..c36316ae --- /dev/null +++ b/engine/src/main/battlecode/schema-old/Round.java @@ -0,0 +1,283 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A single time-step in a Game. + * The bulk of the data in the file is stored in tables like this. + * Note that a struct-of-arrays format is more space efficient than an array- + * of-structs. + */ +public final class Round extends Table { + public static Round getRootAsRound(ByteBuffer _bb) { return getRootAsRound(_bb, new Round()); } + public static Round getRootAsRound(ByteBuffer _bb, Round obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public Round __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The IDs of teams in the Game. + */ + public int teamIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } + public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } + /** + * The number of votes the teams get, 0 or 1. + */ + public int teamVotes(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamVotesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamVotesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer teamVotesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + /** + * The ID of the Enlightenment Center got the bid. + */ + public int teamBidderIDs(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamBidderIDsLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamBidderIDsAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer teamBidderIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + /** + * The IDs of bodies that moved. + */ + public int movedIDs(int j) { int o = __offset(10); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int movedIDsLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer movedIDsAsByteBuffer() { return __vector_as_bytebuffer(10, 4); } + public ByteBuffer movedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 4); } + /** + * The new locations of bodies that have moved. + */ + public VecTable movedLocs() { return movedLocs(new VecTable()); } + public VecTable movedLocs(VecTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * New bodies. + */ + public SpawnedBodyTable spawnedBodies() { return spawnedBodies(new SpawnedBodyTable()); } + public SpawnedBodyTable spawnedBodies(SpawnedBodyTable obj) { int o = __offset(14); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The IDs of bodies that died. + */ + public int diedIDs(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int diedIDsLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer diedIDsAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } + public ByteBuffer diedIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } + /** + * The IDs of robots that performed actions. + * IDs may repeat. + */ + public int actionIDs(int j) { int o = __offset(18); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int actionIDsLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer actionIDsAsByteBuffer() { return __vector_as_bytebuffer(18, 4); } + public ByteBuffer actionIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 4); } + /** + * The actions performed. These actions allow us to track how much soup or dirt a body carries. + */ + public byte actions(int j) { int o = __offset(20); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } + public int actionsLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer actionsAsByteBuffer() { return __vector_as_bytebuffer(20, 1); } + public ByteBuffer actionsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 1); } + /** + * The 'targets' of the performed actions. Actions without targets may have any value + */ + public int actionTargets(int j) { int o = __offset(22); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int actionTargetsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer actionTargetsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } + public ByteBuffer actionTargetsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } + /** + * The IDs of bodies that set indicator dots + */ + public int indicatorDotIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorDotIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } + public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } + /** + * The location of the indicator dots + */ + public VecTable indicatorDotLocs() { return indicatorDotLocs(new VecTable()); } + public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The RGB values of the indicator dots + */ + public RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new RGBTable()); } + public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The IDs of bodies that set indicator lines + */ + public int indicatorLineIDs(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorLineIDsLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } + public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + /** + * The start location of the indicator lines + */ + public VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new VecTable()); } + public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The end location of the indicator lines + */ + public VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new VecTable()); } + public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(34); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The RGB values of the indicator lines + */ + public RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new RGBTable()); } + public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(36); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * All logs sent this round. + * Messages from a particular robot in this round start on a new line, and + * have a header: + * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' + * $TEAM = 'A' | 'B' + * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' + * $ID = a number + * $ROUND = a number + * The header is not necessarily followed by a newline. + * This header should only be sent once per robot per round (although + * players may forge it, so don't crash if you get strange input.) + * + * You should try to only read this value once, and cache it. Reading + * strings from a flatbuffer is much less efficient than reading other + * buffers, because they need to be copied into an environment-provided + * buffer and validated. + * + * (haha i guess you can never really escape string parsing can you) + */ + public String logs() { int o = __offset(38); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer logsAsByteBuffer() { return __vector_as_bytebuffer(38, 1); } + public ByteBuffer logsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 38, 1); } + /** + * The first sent Round in a match should have index 1. (The starting state, + * created by the MatchHeader, can be thought to have index 0.) + * It should increase by one for each following round. + */ + public int roundID() { int o = __offset(40); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + /** + * The IDs of player bodies. + */ + public int bytecodeIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodeIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } + public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } + /** + * The bytecodes used by the player bodies. + */ + public int bytecodesUsed(int j) { int o = __offset(44); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodesUsedLength() { int o = __offset(44); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(44, 4); } + public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 44, 4); } + /** + * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. + */ + public int teamNumBuffs(int j) { int o = __offset(46); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamNumBuffsLength() { int o = __offset(46); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamNumBuffsAsByteBuffer() { return __vector_as_bytebuffer(46, 4); } + public ByteBuffer teamNumBuffsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 46, 4); } + + public static int createRound(FlatBufferBuilder builder, + int teamIDsOffset, + int teamVotesOffset, + int teamBidderIDsOffset, + int movedIDsOffset, + int movedLocsOffset, + int spawnedBodiesOffset, + int diedIDsOffset, + int actionIDsOffset, + int actionsOffset, + int actionTargetsOffset, + int indicatorDotIDsOffset, + int indicatorDotLocsOffset, + int indicatorDotRGBsOffset, + int indicatorLineIDsOffset, + int indicatorLineStartLocsOffset, + int indicatorLineEndLocsOffset, + int indicatorLineRGBsOffset, + int logsOffset, + int roundID, + int bytecodeIDsOffset, + int bytecodesUsedOffset, + int teamNumBuffsOffset) { + builder.startObject(22); + Round.addTeamNumBuffs(builder, teamNumBuffsOffset); + Round.addBytecodesUsed(builder, bytecodesUsedOffset); + Round.addBytecodeIDs(builder, bytecodeIDsOffset); + Round.addRoundID(builder, roundID); + Round.addLogs(builder, logsOffset); + Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); + Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); + Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); + Round.addIndicatorLineIDs(builder, indicatorLineIDsOffset); + Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); + Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); + Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); + Round.addActionTargets(builder, actionTargetsOffset); + Round.addActions(builder, actionsOffset); + Round.addActionIDs(builder, actionIDsOffset); + Round.addDiedIDs(builder, diedIDsOffset); + Round.addSpawnedBodies(builder, spawnedBodiesOffset); + Round.addMovedLocs(builder, movedLocsOffset); + Round.addMovedIDs(builder, movedIDsOffset); + Round.addTeamBidderIDs(builder, teamBidderIDsOffset); + Round.addTeamVotes(builder, teamVotesOffset); + Round.addTeamIDs(builder, teamIDsOffset); + return Round.endRound(builder); + } + + public static void startRound(FlatBufferBuilder builder) { builder.startObject(22); } + public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(0, teamIDsOffset, 0); } + public static int createTeamIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamVotes(FlatBufferBuilder builder, int teamVotesOffset) { builder.addOffset(1, teamVotesOffset, 0); } + public static int createTeamVotesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamVotesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamBidderIDs(FlatBufferBuilder builder, int teamBidderIDsOffset) { builder.addOffset(2, teamBidderIDsOffset, 0); } + public static int createTeamBidderIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamBidderIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addMovedIDs(FlatBufferBuilder builder, int movedIDsOffset) { builder.addOffset(3, movedIDsOffset, 0); } + public static int createMovedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startMovedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addMovedLocs(FlatBufferBuilder builder, int movedLocsOffset) { builder.addOffset(4, movedLocsOffset, 0); } + public static void addSpawnedBodies(FlatBufferBuilder builder, int spawnedBodiesOffset) { builder.addOffset(5, spawnedBodiesOffset, 0); } + public static void addDiedIDs(FlatBufferBuilder builder, int diedIDsOffset) { builder.addOffset(6, diedIDsOffset, 0); } + public static int createDiedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startDiedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addActionIDs(FlatBufferBuilder builder, int actionIDsOffset) { builder.addOffset(7, actionIDsOffset, 0); } + public static int createActionIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startActionIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addActions(FlatBufferBuilder builder, int actionsOffset) { builder.addOffset(8, actionsOffset, 0); } + public static int createActionsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static void startActionsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } + public static void addActionTargets(FlatBufferBuilder builder, int actionTargetsOffset) { builder.addOffset(9, actionTargetsOffset, 0); } + public static int createActionTargetsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startActionTargetsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(10, indicatorDotIDsOffset, 0); } + public static int createIndicatorDotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startIndicatorDotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(11, indicatorDotLocsOffset, 0); } + public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(12, indicatorDotRGBsOffset, 0); } + public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(13, indicatorLineIDsOffset, 0); } + public static int createIndicatorLineIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startIndicatorLineIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(14, indicatorLineStartLocsOffset, 0); } + public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(15, indicatorLineEndLocsOffset, 0); } + public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(16, indicatorLineRGBsOffset, 0); } + public static void addLogs(FlatBufferBuilder builder, int logsOffset) { builder.addOffset(17, logsOffset, 0); } + public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(18, roundID, 0); } + public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(19, bytecodeIDsOffset, 0); } + public static int createBytecodeIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBytecodeIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(20, bytecodesUsedOffset, 0); } + public static int createBytecodesUsedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBytecodesUsedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamNumBuffs(FlatBufferBuilder builder, int teamNumBuffsOffset) { builder.addOffset(21, teamNumBuffsOffset, 0); } + public static int createTeamNumBuffsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamNumBuffsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endRound(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java b/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java new file mode 100644 index 00000000..3616e911 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java @@ -0,0 +1,94 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A list of new bodies to be placed on the map. + */ +public final class SpawnedBodyTable extends Table { + public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb) { return getRootAsSpawnedBodyTable(_bb, new SpawnedBodyTable()); } + public static SpawnedBodyTable getRootAsSpawnedBodyTable(ByteBuffer _bb, SpawnedBodyTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public SpawnedBodyTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The numeric ID of the new bodies. + * Will never be negative. + * There will only be one body with a particular ID at a time. + * So, there will never be two robots with the same ID, or a robot and + * a building with the same ID. + */ + public int robotIDs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int robotIDsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer robotIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } + public ByteBuffer robotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } + /** + * The teams of the new bodies. + */ + public byte teamIDs(int j) { int o = __offset(6); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } + public int teamIDsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } + public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } + /** + * The types of the new bodies. + */ + public byte types(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; } + public int typesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer typesAsByteBuffer() { return __vector_as_bytebuffer(8, 1); } + public ByteBuffer typesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); } + /** + * The locations of the bodies. + */ + public VecTable locs() { return locs(new VecTable()); } + public VecTable locs(VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * the amount of influence paid to create these bodies + * for initial Enlightenment Centers, this is the amount of influence + * needed to take over + */ + public int influences(int j) { int o = __offset(12); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int influencesLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer influencesAsByteBuffer() { return __vector_as_bytebuffer(12, 4); } + public ByteBuffer influencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 4); } + + public static int createSpawnedBodyTable(FlatBufferBuilder builder, + int robotIDsOffset, + int teamIDsOffset, + int typesOffset, + int locsOffset, + int influencesOffset) { + builder.startObject(5); + SpawnedBodyTable.addInfluences(builder, influencesOffset); + SpawnedBodyTable.addLocs(builder, locsOffset); + SpawnedBodyTable.addTypes(builder, typesOffset); + SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); + SpawnedBodyTable.addRobotIDs(builder, robotIDsOffset); + return SpawnedBodyTable.endSpawnedBodyTable(builder); + } + + public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(5); } + public static void addRobotIDs(FlatBufferBuilder builder, int robotIDsOffset) { builder.addOffset(0, robotIDsOffset, 0); } + public static int createRobotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startRobotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(1, teamIDsOffset, 0); } + public static int createTeamIDsVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } + public static void addTypes(FlatBufferBuilder builder, int typesOffset) { builder.addOffset(2, typesOffset, 0); } + public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } + public static void startTypesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } + public static void addLocs(FlatBufferBuilder builder, int locsOffset) { builder.addOffset(3, locsOffset, 0); } + public static void addInfluences(FlatBufferBuilder builder, int influencesOffset) { builder.addOffset(4, influencesOffset, 0); } + public static int createInfluencesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startInfluencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endSpawnedBodyTable(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/TeamData.java b/engine/src/main/battlecode/schema-old/TeamData.java new file mode 100644 index 00000000..57e3e4db --- /dev/null +++ b/engine/src/main/battlecode/schema-old/TeamData.java @@ -0,0 +1,57 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * Data relevant to a particular team. + */ +public final class TeamData extends Table { + public static TeamData getRootAsTeamData(ByteBuffer _bb) { return getRootAsTeamData(_bb, new TeamData()); } + public static TeamData getRootAsTeamData(ByteBuffer _bb, TeamData obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public TeamData __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + /** + * The name of the team. + */ + public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); } + public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); } + /** + * The java package the team uses. + */ + public String packageName() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer packageNameAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } + public ByteBuffer packageNameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } + /** + * The ID of the team this data pertains to. + */ + public byte teamID() { int o = __offset(8); return o != 0 ? bb.get(o + bb_pos) : 0; } + + public static int createTeamData(FlatBufferBuilder builder, + int nameOffset, + int packageNameOffset, + byte teamID) { + builder.startObject(3); + TeamData.addPackageName(builder, packageNameOffset); + TeamData.addName(builder, nameOffset); + TeamData.addTeamID(builder, teamID); + return TeamData.endTeamData(builder); + } + + public static void startTeamData(FlatBufferBuilder builder) { builder.startObject(3); } + public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } + public static void addPackageName(FlatBufferBuilder builder, int packageNameOffset) { builder.addOffset(1, packageNameOffset, 0); } + public static void addTeamID(FlatBufferBuilder builder, byte teamID) { builder.addByte(2, teamID, 0); } + public static int endTeamData(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema-old/Vec.java b/engine/src/main/battlecode/schema-old/Vec.java new file mode 100644 index 00000000..a9cdcb68 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/Vec.java @@ -0,0 +1,29 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A vector in two-dimensional space. Discrete space, of course. + * Defaults to the 0 vector. + */ +public final class Vec extends Struct { + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; } + public Vec __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public int x() { return bb.getInt(bb_pos + 0); } + public int y() { return bb.getInt(bb_pos + 4); } + + public static int createVec(FlatBufferBuilder builder, int x, int y) { + builder.prep(4, 8); + builder.putInt(y); + builder.putInt(x); + return builder.offset(); + } +} + diff --git a/engine/src/main/battlecode/schema-old/VecTable.java b/engine/src/main/battlecode/schema-old/VecTable.java new file mode 100644 index 00000000..82da91e7 --- /dev/null +++ b/engine/src/main/battlecode/schema-old/VecTable.java @@ -0,0 +1,50 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +/** + * A table of vectors. + */ +public final class VecTable extends Table { + public static VecTable getRootAsVecTable(ByteBuffer _bb) { return getRootAsVecTable(_bb, new VecTable()); } + public static VecTable getRootAsVecTable(ByteBuffer _bb, VecTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public VecTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public int xs(int j) { int o = __offset(4); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int xsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer xsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } + public ByteBuffer xsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } + public int ys(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int ysLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer ysAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer ysInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + + public static int createVecTable(FlatBufferBuilder builder, + int xsOffset, + int ysOffset) { + builder.startObject(2); + VecTable.addYs(builder, ysOffset); + VecTable.addXs(builder, xsOffset); + return VecTable.endVecTable(builder); + } + + public static void startVecTable(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addXs(FlatBufferBuilder builder, int xsOffset) { builder.addOffset(0, xsOffset, 0); } + public static int createXsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startXsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addYs(FlatBufferBuilder builder, int ysOffset) { builder.addOffset(1, ysOffset, 0); } + public static int createYsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startYsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endVecTable(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema/Action.java b/engine/src/main/battlecode/schema/Action.java index a21287a3..3062d6f7 100644 --- a/engine/src/main/battlecode/schema/Action.java +++ b/engine/src/main/battlecode/schema/Action.java @@ -13,64 +13,81 @@ public final class Action { private Action() { } /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared + * Target: ID of robot attacked */ - public static final byte EMPOWER = 0; + public static final byte ATTACK = 0; /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID + * Target: ID of robot spawned */ - public static final byte EMBEZZLE = 1; + public static final byte SPAWN_UNIT = 1; + /** + * Target: location mined, x + y * width + */ + public static final byte MINE_LEAD = 2; + /** + * Target: location mined, x + y * width + */ + public static final byte MINE_GOLD = 3; + /** + * Target: none + */ + public static final byte TRANSMUTE = 4; /** - * Slanderers turn into Politicians. * Target: none */ - public static final byte CAMOUFLAGE = 2; + public static final byte TRANSFORM = 5; /** - * Muckrakers can expose a slanderer. - * Target: an enemy body + * Target: ID of robot mutated */ - public static final byte EXPOSE = 3; + public static final byte MUTATE = 6; /** - * Units can change their flag. - * Target: new flag value + * Target: ID of robot repaired */ - public static final byte SET_FLAG = 4; + public static final byte REPAIR = 7; /** - * Builds a unit. - * Target: spawned unit + * Target: change in health (can be negative) + */ + public static final byte CHANGE_HEALTH = 8; + /** + * When a PROTOTYPE building upgrades to TURRET + * Target: none */ - public static final byte SPAWN_UNIT = 5; + public static final byte FULLY_REPAIRED = 9; /** - * Places a bid. - * Target: bid value + * Target: Sage location, x + y * width */ - public static final byte PLACE_BID = 6; + public static final byte LOCAL_ABYSS = 10; /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID + * Target: Sage location, x + y * width */ - public static final byte CHANGE_TEAM = 7; + public static final byte LOCAL_CHARGE = 11; /** - * A robot's influence changes. - * Target: delta value + * Target: Sage location, x + y * width + */ + public static final byte LOCAL_FURY = 12; + /** + * Target: none + */ + public static final byte ABYSS = 13; + /** + * Target: none + */ + public static final byte CHARGE = 14; + /** + * Target: none */ - public static final byte CHANGE_INFLUENCE = 8; + public static final byte FURY = 15; /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 + * Target: 0 if 90 degrees clockwise, 1 if horizontal, 2 if vertical */ - public static final byte CHANGE_CONVICTION = 9; + public static final byte VORTEX = 16; /** * Dies due to an uncaught exception. * Target: none */ - public static final byte DIE_EXCEPTION = 10; + public static final byte DIE_EXCEPTION = 17; - public static final String[] names = { "EMPOWER", "EMBEZZLE", "CAMOUFLAGE", "EXPOSE", "SET_FLAG", "SPAWN_UNIT", "PLACE_BID", "CHANGE_TEAM", "CHANGE_INFLUENCE", "CHANGE_CONVICTION", "DIE_EXCEPTION", }; + public static final String[] names = { "ATTACK", "SPAWN_UNIT", "MINE_LEAD", "MINE_GOLD", "TRANSMUTE", "TRANSFORM", "MUTATE", "REPAIR", "CHANGE_HEALTH", "FULLY_REPAIRED", "LOCAL_ABYSS", "LOCAL_CHARGE", "LOCAL_FURY", "ABYSS", "CHARGE", "FURY", "VORTEX", "DIE_EXCEPTION", }; public static String name(int e) { return names[e]; } } diff --git a/engine/src/main/battlecode/schema/BodyType.java b/engine/src/main/battlecode/schema/BodyType.java index ee34e38d..aa900424 100644 --- a/engine/src/main/battlecode/schema/BodyType.java +++ b/engine/src/main/battlecode/schema/BodyType.java @@ -8,26 +8,15 @@ */ public final class BodyType { private BodyType() { } - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - public static final byte ENLIGHTENMENT_CENTER = 0; - /** - * politicians use their influence to self destruct and capture other units - */ - public static final byte POLITICIAN = 1; - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - public static final byte SLANDERER = 2; - /** - * have the ability to identify slanderers - */ - public static final byte MUCKRAKER = 3; + public static final byte MINER = 0; + public static final byte BUILDER = 1; + public static final byte SOLDIER = 2; + public static final byte SAGE = 3; + public static final byte ARCHON = 4; + public static final byte LABORATORY = 5; + public static final byte WATCHTOWER = 6; - public static final String[] names = { "ENLIGHTENMENT_CENTER", "POLITICIAN", "SLANDERER", "MUCKRAKER", }; + public static final String[] names = { "MINER", "BUILDER", "SOLDIER", "SAGE", "ARCHON", "LABORATORY", "WATCHTOWER", }; public static String name(int e) { return names[e]; } } diff --git a/engine/src/main/battlecode/schema/BodyTypeMetadata.java b/engine/src/main/battlecode/schema/BodyTypeMetadata.java index 8b7e63ba..70480529 100644 --- a/engine/src/main/battlecode/schema/BodyTypeMetadata.java +++ b/engine/src/main/battlecode/schema/BodyTypeMetadata.java @@ -17,69 +17,63 @@ public final class BodyTypeMetadata extends Table { public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - /** - * The relevant type. - */ public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * The spawn source. - */ - public byte spawnSource() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * the convictionRatio of this type - */ - public float convictionRatio() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * cooldown of this type - */ - public float actionCooldown() { int o = __offset(10); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * action radius if this type - */ - public int actionRadiusSquared() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * sensor radius squared for this type - */ - public int sensorRadiusSquared() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * detection radius of this type - */ - public int detectionRadiusSquared() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * bytecode limit for this type - */ - public int bytecodeLimit() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int buildCostLead(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int buildCostLeadLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer buildCostLeadAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer buildCostLeadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int buildCostGold(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int buildCostGoldLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer buildCostGoldAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer buildCostGoldInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + public int actionCooldown() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int movementCooldown() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int health() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int damage() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int bytecodeLimit() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, - byte spawnSource, - float convictionRatio, - float actionCooldown, + int buildCostLeadOffset, + int buildCostGoldOffset, + int actionCooldown, + int movementCooldown, + int health, + int damage, int actionRadiusSquared, - int sensorRadiusSquared, - int detectionRadiusSquared, + int visionRadiusSquared, int bytecodeLimit) { - builder.startObject(8); + builder.startObject(10); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addDamage(builder, damage); + BodyTypeMetadata.addHealth(builder, health); + BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); - BodyTypeMetadata.addSpawnSource(builder, spawnSource); + BodyTypeMetadata.addBuildCostGold(builder, buildCostGoldOffset); + BodyTypeMetadata.addBuildCostLead(builder, buildCostLeadOffset); BodyTypeMetadata.addType(builder, type); return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(8); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(10); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } - public static void addSpawnSource(FlatBufferBuilder builder, byte spawnSource) { builder.addByte(1, spawnSource, 0); } - public static void addConvictionRatio(FlatBufferBuilder builder, float convictionRatio) { builder.addFloat(2, convictionRatio, 0.0f); } - public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(3, actionCooldown, 0.0f); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(4, actionRadiusSquared, 0); } - public static void addSensorRadiusSquared(FlatBufferBuilder builder, int sensorRadiusSquared) { builder.addInt(5, sensorRadiusSquared, 0); } - public static void addDetectionRadiusSquared(FlatBufferBuilder builder, int detectionRadiusSquared) { builder.addInt(6, detectionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(7, bytecodeLimit, 0); } + public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLeadOffset) { builder.addOffset(1, buildCostLeadOffset, 0); } + public static int createBuildCostLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBuildCostLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGoldOffset) { builder.addOffset(2, buildCostGoldOffset, 0); } + public static int createBuildCostGoldVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBuildCostGoldVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(3, actionCooldown, 0); } + public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(4, movementCooldown, 0); } + public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(5, health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(6, damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(7, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(8, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(9, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/schema/Constants.java b/engine/src/main/battlecode/schema/Constants.java new file mode 100644 index 00000000..f82a5a1f --- /dev/null +++ b/engine/src/main/battlecode/schema/Constants.java @@ -0,0 +1,37 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +public final class Constants extends Table { + public static Constants getRootAsConstants(ByteBuffer _bb) { return getRootAsConstants(_bb, new Constants()); } + public static Constants getRootAsConstants(ByteBuffer _bb, Constants obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public Constants __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public int increasePeriod() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int leadAdditiveIncease() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + + public static int createConstants(FlatBufferBuilder builder, + int increasePeriod, + int leadAdditiveIncease) { + builder.startObject(2); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); + Constants.addIncreasePeriod(builder, increasePeriod); + return Constants.endConstants(builder); + } + + public static void startConstants(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addIncreasePeriod(FlatBufferBuilder builder, int increasePeriod) { builder.addInt(0, increasePeriod, 0); } + public static void addLeadAdditiveIncease(FlatBufferBuilder builder, int leadAdditiveIncease) { builder.addInt(1, leadAdditiveIncease, 0); } + public static int endConstants(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/engine/src/main/battlecode/schema/GameHeader.java b/engine/src/main/battlecode/schema/GameHeader.java index 77363711..4c93ff54 100644 --- a/engine/src/main/battlecode/schema/GameHeader.java +++ b/engine/src/main/battlecode/schema/GameHeader.java @@ -35,19 +35,23 @@ public final class GameHeader extends Table { public BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new BodyTypeMetadata(), j); } public BodyTypeMetadata bodyTypeMetadata(BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int bodyTypeMetadataLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public Constants constants() { return constants(new Constants()); } + public Constants constants(Constants obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } public static int createGameHeader(FlatBufferBuilder builder, int specVersionOffset, int teamsOffset, - int bodyTypeMetadataOffset) { - builder.startObject(3); + int bodyTypeMetadataOffset, + int constantsOffset) { + builder.startObject(4); + GameHeader.addConstants(builder, constantsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addSpecVersion(builder, specVersionOffset); return GameHeader.endGameHeader(builder); } - public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(4); } public static void addSpecVersion(FlatBufferBuilder builder, int specVersionOffset) { builder.addOffset(0, specVersionOffset, 0); } public static void addTeams(FlatBufferBuilder builder, int teamsOffset) { builder.addOffset(1, teamsOffset, 0); } public static int createTeamsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } @@ -55,6 +59,7 @@ public static int createGameHeader(FlatBufferBuilder builder, public static void addBodyTypeMetadata(FlatBufferBuilder builder, int bodyTypeMetadataOffset) { builder.addOffset(2, bodyTypeMetadataOffset, 0); } public static int createBodyTypeMetadataVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startBodyTypeMetadataVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addConstants(FlatBufferBuilder builder, int constantsOffset) { builder.addOffset(3, constantsOffset, 0); } public static int endGameHeader(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/schema/GameMap.java b/engine/src/main/battlecode/schema/GameMap.java index 09b78818..42d7163f 100644 --- a/engine/src/main/battlecode/schema/GameMap.java +++ b/engine/src/main/battlecode/schema/GameMap.java @@ -43,22 +43,32 @@ public final class GameMap extends Table { */ public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** - * The factor to divide cooldowns by + * The rubble on the map. */ - public double passability(int j) { int o = __offset(14); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } - public int passabilityLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer passabilityAsByteBuffer() { return __vector_as_bytebuffer(14, 8); } - public ByteBuffer passabilityInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 8); } + public int rubble(int j) { int o = __offset(14); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int rubbleLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(14, 4); } + public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 4); } + /** + * The lead on the map. + */ + public int lead(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } + public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(6); } + public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(7); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } - public static void addPassability(FlatBufferBuilder builder, int passabilityOffset) { builder.addOffset(5, passabilityOffset, 0); } - public static int createPassabilityVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } - public static void startPassabilityVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } + public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(5, rubbleOffset, 0); } + public static int createRubbleVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startRubbleVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(6, leadOffset, 0); } + public static int createLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endGameMap(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/schema/Round.java b/engine/src/main/battlecode/schema/Round.java index c36316ae..b7295a4e 100644 --- a/engine/src/main/battlecode/schema/Round.java +++ b/engine/src/main/battlecode/schema/Round.java @@ -28,19 +28,19 @@ public final class Round extends Table { public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } /** - * The number of votes the teams get, 0 or 1. + * The total amount of lead change of this team, this round */ - public int teamVotes(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamVotesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamVotesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer teamVotesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int teamLeadChanges(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamLeadChangesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamLeadChangesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer teamLeadChangesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } /** - * The ID of the Enlightenment Center got the bid. + * The total amount of gold change of this team, this round */ - public int teamBidderIDs(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamBidderIDsLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamBidderIDsAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer teamBidderIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + public int teamGoldChanges(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamGoldChangesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamGoldChangesAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer teamGoldChangesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } /** * The IDs of bodies that moved. */ @@ -87,100 +87,106 @@ public final class Round extends Table { public int actionTargetsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } public ByteBuffer actionTargetsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } public ByteBuffer actionTargetsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } + /** + * The locations of lead drops + */ + public VecTable leadDropLocations() { return leadDropLocations(new VecTable()); } + public VecTable leadDropLocations(VecTable obj) { int o = __offset(24); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The amount of lead dropped at each location + */ + public int leadDropValues(int j) { int o = __offset(26); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadDropValuesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadDropValuesAsByteBuffer() { return __vector_as_bytebuffer(26, 4); } + public ByteBuffer leadDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 4); } + /** + * The locations of gold drops + */ + public VecTable goldDropLocations() { return goldDropLocations(new VecTable()); } + public VecTable goldDropLocations(VecTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The amount of gold dropped at each location + */ + public int goldDropValues(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int goldDropValuesLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer goldDropValuesAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } + public ByteBuffer goldDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + /** + * The IDs of the robots who changed their indicator strings + */ + public int indicatorStringIDs(int j) { int o = __offset(32); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorStringIDsLength() { int o = __offset(32); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorStringIDsAsByteBuffer() { return __vector_as_bytebuffer(32, 4); } + public ByteBuffer indicatorStringIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 32, 4); } + /** + * The messages of the robots who changed their indicator strings + */ + public String indicatorStrings(int j) { int o = __offset(34); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int indicatorStringsLength() { int o = __offset(34); return o != 0 ? __vector_len(o) : 0; } /** * The IDs of bodies that set indicator dots */ - public int indicatorDotIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorDotIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } - public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } + public int indicatorDotIDs(int j) { int o = __offset(36); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorDotIDsLength() { int o = __offset(36); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(36, 4); } + public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 36, 4); } /** * The location of the indicator dots */ public VecTable indicatorDotLocs() { return indicatorDotLocs(new VecTable()); } - public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(38); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator dots */ public RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new RGBTable()); } - public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(40); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The IDs of bodies that set indicator lines */ - public int indicatorLineIDs(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorLineIDsLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } - public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + public int indicatorLineIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorLineIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } + public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } /** * The start location of the indicator lines */ public VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new VecTable()); } - public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(44); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The end location of the indicator lines */ public VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new VecTable()); } - public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(34); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(46); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator lines */ public RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new RGBTable()); } - public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(36); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - */ - public String logs() { int o = __offset(38); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer logsAsByteBuffer() { return __vector_as_bytebuffer(38, 1); } - public ByteBuffer logsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 38, 1); } + public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(48); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The first sent Round in a match should have index 1. (The starting state, * created by the MatchHeader, can be thought to have index 0.) * It should increase by one for each following round. */ - public int roundID() { int o = __offset(40); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int roundID() { int o = __offset(50); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The IDs of player bodies. */ - public int bytecodeIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodeIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } - public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } + public int bytecodeIDs(int j) { int o = __offset(52); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodeIDsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(52, 4); } + public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 4); } /** * The bytecodes used by the player bodies. */ - public int bytecodesUsed(int j) { int o = __offset(44); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodesUsedLength() { int o = __offset(44); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(44, 4); } - public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 44, 4); } - /** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - */ - public int teamNumBuffs(int j) { int o = __offset(46); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamNumBuffsLength() { int o = __offset(46); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamNumBuffsAsByteBuffer() { return __vector_as_bytebuffer(46, 4); } - public ByteBuffer teamNumBuffsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 46, 4); } + public int bytecodesUsed(int j) { int o = __offset(54); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodesUsedLength() { int o = __offset(54); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(54, 4); } + public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 54, 4); } public static int createRound(FlatBufferBuilder builder, int teamIDsOffset, - int teamVotesOffset, - int teamBidderIDsOffset, + int teamLeadChangesOffset, + int teamGoldChangesOffset, int movedIDsOffset, int movedLocsOffset, int spawnedBodiesOffset, @@ -188,6 +194,12 @@ public static int createRound(FlatBufferBuilder builder, int actionIDsOffset, int actionsOffset, int actionTargetsOffset, + int leadDropLocationsOffset, + int leadDropValuesOffset, + int goldDropLocationsOffset, + int goldDropValuesOffset, + int indicatorStringIDsOffset, + int indicatorStringsOffset, int indicatorDotIDsOffset, int indicatorDotLocsOffset, int indicatorDotRGBsOffset, @@ -195,17 +207,13 @@ public static int createRound(FlatBufferBuilder builder, int indicatorLineStartLocsOffset, int indicatorLineEndLocsOffset, int indicatorLineRGBsOffset, - int logsOffset, int roundID, int bytecodeIDsOffset, - int bytecodesUsedOffset, - int teamNumBuffsOffset) { - builder.startObject(22); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); + int bytecodesUsedOffset) { + builder.startObject(26); Round.addBytecodesUsed(builder, bytecodesUsedOffset); Round.addBytecodeIDs(builder, bytecodeIDsOffset); Round.addRoundID(builder, roundID); - Round.addLogs(builder, logsOffset); Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); @@ -213,6 +221,12 @@ public static int createRound(FlatBufferBuilder builder, Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); + Round.addGoldDropValues(builder, goldDropValuesOffset); + Round.addGoldDropLocations(builder, goldDropLocationsOffset); + Round.addLeadDropValues(builder, leadDropValuesOffset); + Round.addLeadDropLocations(builder, leadDropLocationsOffset); Round.addActionTargets(builder, actionTargetsOffset); Round.addActions(builder, actionsOffset); Round.addActionIDs(builder, actionIDsOffset); @@ -220,22 +234,22 @@ public static int createRound(FlatBufferBuilder builder, Round.addSpawnedBodies(builder, spawnedBodiesOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addMovedIDs(builder, movedIDsOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); + Round.addTeamGoldChanges(builder, teamGoldChangesOffset); + Round.addTeamLeadChanges(builder, teamLeadChangesOffset); Round.addTeamIDs(builder, teamIDsOffset); return Round.endRound(builder); } - public static void startRound(FlatBufferBuilder builder) { builder.startObject(22); } + public static void startRound(FlatBufferBuilder builder) { builder.startObject(26); } public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(0, teamIDsOffset, 0); } public static int createTeamIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamVotes(FlatBufferBuilder builder, int teamVotesOffset) { builder.addOffset(1, teamVotesOffset, 0); } - public static int createTeamVotesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamVotesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamBidderIDs(FlatBufferBuilder builder, int teamBidderIDsOffset) { builder.addOffset(2, teamBidderIDsOffset, 0); } - public static int createTeamBidderIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamBidderIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamLeadChanges(FlatBufferBuilder builder, int teamLeadChangesOffset) { builder.addOffset(1, teamLeadChangesOffset, 0); } + public static int createTeamLeadChangesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamLeadChangesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamGoldChanges(FlatBufferBuilder builder, int teamGoldChangesOffset) { builder.addOffset(2, teamGoldChangesOffset, 0); } + public static int createTeamGoldChangesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamGoldChangesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addMovedIDs(FlatBufferBuilder builder, int movedIDsOffset) { builder.addOffset(3, movedIDsOffset, 0); } public static int createMovedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startMovedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -253,28 +267,38 @@ public static int createRound(FlatBufferBuilder builder, public static void addActionTargets(FlatBufferBuilder builder, int actionTargetsOffset) { builder.addOffset(9, actionTargetsOffset, 0); } public static int createActionTargetsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startActionTargetsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(10, indicatorDotIDsOffset, 0); } + public static void addLeadDropLocations(FlatBufferBuilder builder, int leadDropLocationsOffset) { builder.addOffset(10, leadDropLocationsOffset, 0); } + public static void addLeadDropValues(FlatBufferBuilder builder, int leadDropValuesOffset) { builder.addOffset(11, leadDropValuesOffset, 0); } + public static int createLeadDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startLeadDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addGoldDropLocations(FlatBufferBuilder builder, int goldDropLocationsOffset) { builder.addOffset(12, goldDropLocationsOffset, 0); } + public static void addGoldDropValues(FlatBufferBuilder builder, int goldDropValuesOffset) { builder.addOffset(13, goldDropValuesOffset, 0); } + public static int createGoldDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startGoldDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorStringIDs(FlatBufferBuilder builder, int indicatorStringIDsOffset) { builder.addOffset(14, indicatorStringIDsOffset, 0); } + public static int createIndicatorStringIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startIndicatorStringIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorStrings(FlatBufferBuilder builder, int indicatorStringsOffset) { builder.addOffset(15, indicatorStringsOffset, 0); } + public static int createIndicatorStringsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startIndicatorStringsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(16, indicatorDotIDsOffset, 0); } public static int createIndicatorDotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorDotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(11, indicatorDotLocsOffset, 0); } - public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(12, indicatorDotRGBsOffset, 0); } - public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(13, indicatorLineIDsOffset, 0); } + public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(17, indicatorDotLocsOffset, 0); } + public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(18, indicatorDotRGBsOffset, 0); } + public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(19, indicatorLineIDsOffset, 0); } public static int createIndicatorLineIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorLineIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(14, indicatorLineStartLocsOffset, 0); } - public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(15, indicatorLineEndLocsOffset, 0); } - public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(16, indicatorLineRGBsOffset, 0); } - public static void addLogs(FlatBufferBuilder builder, int logsOffset) { builder.addOffset(17, logsOffset, 0); } - public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(18, roundID, 0); } - public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(19, bytecodeIDsOffset, 0); } + public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(20, indicatorLineStartLocsOffset, 0); } + public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(21, indicatorLineEndLocsOffset, 0); } + public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(22, indicatorLineRGBsOffset, 0); } + public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(23, roundID, 0); } + public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(24, bytecodeIDsOffset, 0); } public static int createBytecodeIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodeIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(20, bytecodesUsedOffset, 0); } + public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(25, bytecodesUsedOffset, 0); } public static int createBytecodesUsedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodesUsedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamNumBuffs(FlatBufferBuilder builder, int teamNumBuffsOffset) { builder.addOffset(21, teamNumBuffsOffset, 0); } - public static int createTeamNumBuffsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamNumBuffsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endRound(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/schema/SpawnedBodyTable.java b/engine/src/main/battlecode/schema/SpawnedBodyTable.java index 3616e911..71bf66ec 100644 --- a/engine/src/main/battlecode/schema/SpawnedBodyTable.java +++ b/engine/src/main/battlecode/schema/SpawnedBodyTable.java @@ -47,24 +47,13 @@ public final class SpawnedBodyTable extends Table { */ public VecTable locs() { return locs(new VecTable()); } public VecTable locs(VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - */ - public int influences(int j) { int o = __offset(12); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int influencesLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer influencesAsByteBuffer() { return __vector_as_bytebuffer(12, 4); } - public ByteBuffer influencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 4); } public static int createSpawnedBodyTable(FlatBufferBuilder builder, int robotIDsOffset, int teamIDsOffset, int typesOffset, - int locsOffset, - int influencesOffset) { - builder.startObject(5); - SpawnedBodyTable.addInfluences(builder, influencesOffset); + int locsOffset) { + builder.startObject(4); SpawnedBodyTable.addLocs(builder, locsOffset); SpawnedBodyTable.addTypes(builder, typesOffset); SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); @@ -72,7 +61,7 @@ public static int createSpawnedBodyTable(FlatBufferBuilder builder, return SpawnedBodyTable.endSpawnedBodyTable(builder); } - public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(5); } + public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(4); } public static void addRobotIDs(FlatBufferBuilder builder, int robotIDsOffset) { builder.addOffset(0, robotIDsOffset, 0); } public static int createRobotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRobotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -83,9 +72,6 @@ public static int createSpawnedBodyTable(FlatBufferBuilder builder, public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } public static void startTypesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } public static void addLocs(FlatBufferBuilder builder, int locsOffset) { builder.addOffset(3, locsOffset, 0); } - public static void addInfluences(FlatBufferBuilder builder, int influencesOffset) { builder.addOffset(4, influencesOffset, 0); } - public static int createInfluencesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startInfluencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endSpawnedBodyTable(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/schema/java/battlecode/schema/Action.java b/schema/java/battlecode/schema/Action.java index a21287a3..3062d6f7 100644 --- a/schema/java/battlecode/schema/Action.java +++ b/schema/java/battlecode/schema/Action.java @@ -13,64 +13,81 @@ public final class Action { private Action() { } /** - * Politicians self-destruct and affect nearby bodies. - * Target: radius squared + * Target: ID of robot attacked */ - public static final byte EMPOWER = 0; + public static final byte ATTACK = 0; /** - * Slanderers passively generate influence for the - * Enlightenment Center that created them. - * Target: parent ID + * Target: ID of robot spawned */ - public static final byte EMBEZZLE = 1; + public static final byte SPAWN_UNIT = 1; + /** + * Target: location mined, x + y * width + */ + public static final byte MINE_LEAD = 2; + /** + * Target: location mined, x + y * width + */ + public static final byte MINE_GOLD = 3; + /** + * Target: none + */ + public static final byte TRANSMUTE = 4; /** - * Slanderers turn into Politicians. * Target: none */ - public static final byte CAMOUFLAGE = 2; + public static final byte TRANSFORM = 5; /** - * Muckrakers can expose a slanderer. - * Target: an enemy body + * Target: ID of robot mutated */ - public static final byte EXPOSE = 3; + public static final byte MUTATE = 6; /** - * Units can change their flag. - * Target: new flag value + * Target: ID of robot repaired */ - public static final byte SET_FLAG = 4; + public static final byte REPAIR = 7; /** - * Builds a unit. - * Target: spawned unit + * Target: change in health (can be negative) + */ + public static final byte CHANGE_HEALTH = 8; + /** + * When a PROTOTYPE building upgrades to TURRET + * Target: none */ - public static final byte SPAWN_UNIT = 5; + public static final byte FULLY_REPAIRED = 9; /** - * Places a bid. - * Target: bid value + * Target: Sage location, x + y * width */ - public static final byte PLACE_BID = 6; + public static final byte LOCAL_ABYSS = 10; /** - * A robot can change team after being empowered, - * or when a Enlightenment Center is taken over. - * Target: new robotID + * Target: Sage location, x + y * width */ - public static final byte CHANGE_TEAM = 7; + public static final byte LOCAL_CHARGE = 11; /** - * A robot's influence changes. - * Target: delta value + * Target: Sage location, x + y * width + */ + public static final byte LOCAL_FURY = 12; + /** + * Target: none + */ + public static final byte ABYSS = 13; + /** + * Target: none + */ + public static final byte CHARGE = 14; + /** + * Target: none */ - public static final byte CHANGE_INFLUENCE = 8; + public static final byte FURY = 15; /** - * A robot's conviction changes. - * Target: delta value, i.e. red 5 -> blue 3 is -2 + * Target: 0 if 90 degrees clockwise, 1 if horizontal, 2 if vertical */ - public static final byte CHANGE_CONVICTION = 9; + public static final byte VORTEX = 16; /** * Dies due to an uncaught exception. * Target: none */ - public static final byte DIE_EXCEPTION = 10; + public static final byte DIE_EXCEPTION = 17; - public static final String[] names = { "EMPOWER", "EMBEZZLE", "CAMOUFLAGE", "EXPOSE", "SET_FLAG", "SPAWN_UNIT", "PLACE_BID", "CHANGE_TEAM", "CHANGE_INFLUENCE", "CHANGE_CONVICTION", "DIE_EXCEPTION", }; + public static final String[] names = { "ATTACK", "SPAWN_UNIT", "MINE_LEAD", "MINE_GOLD", "TRANSMUTE", "TRANSFORM", "MUTATE", "REPAIR", "CHANGE_HEALTH", "FULLY_REPAIRED", "LOCAL_ABYSS", "LOCAL_CHARGE", "LOCAL_FURY", "ABYSS", "CHARGE", "FURY", "VORTEX", "DIE_EXCEPTION", }; public static String name(int e) { return names[e]; } } diff --git a/schema/java/battlecode/schema/BodyType.java b/schema/java/battlecode/schema/BodyType.java index ee34e38d..aa900424 100644 --- a/schema/java/battlecode/schema/BodyType.java +++ b/schema/java/battlecode/schema/BodyType.java @@ -8,26 +8,15 @@ */ public final class BodyType { private BodyType() { } - /** - * Enlightenment centers produce politicians, Muckrakers and slanderers and place bids - *can be neutral until captured - */ - public static final byte ENLIGHTENMENT_CENTER = 0; - /** - * politicians use their influence to self destruct and capture other units - */ - public static final byte POLITICIAN = 1; - /** - * slanderers generate passive influence for the enlightenment center that created them - * they turn into politicians at some point, and can only be identified by slanderers. - */ - public static final byte SLANDERER = 2; - /** - * have the ability to identify slanderers - */ - public static final byte MUCKRAKER = 3; + public static final byte MINER = 0; + public static final byte BUILDER = 1; + public static final byte SOLDIER = 2; + public static final byte SAGE = 3; + public static final byte ARCHON = 4; + public static final byte LABORATORY = 5; + public static final byte WATCHTOWER = 6; - public static final String[] names = { "ENLIGHTENMENT_CENTER", "POLITICIAN", "SLANDERER", "MUCKRAKER", }; + public static final String[] names = { "MINER", "BUILDER", "SOLDIER", "SAGE", "ARCHON", "LABORATORY", "WATCHTOWER", }; public static String name(int e) { return names[e]; } } diff --git a/schema/java/battlecode/schema/BodyTypeMetadata.java b/schema/java/battlecode/schema/BodyTypeMetadata.java index 8b7e63ba..70480529 100644 --- a/schema/java/battlecode/schema/BodyTypeMetadata.java +++ b/schema/java/battlecode/schema/BodyTypeMetadata.java @@ -17,69 +17,63 @@ public final class BodyTypeMetadata extends Table { public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - /** - * The relevant type. - */ public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * The spawn source. - */ - public byte spawnSource() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; } - /** - * the convictionRatio of this type - */ - public float convictionRatio() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * cooldown of this type - */ - public float actionCooldown() { int o = __offset(10); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; } - /** - * action radius if this type - */ - public int actionRadiusSquared() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * sensor radius squared for this type - */ - public int sensorRadiusSquared() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * detection radius of this type - */ - public int detectionRadiusSquared() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - /** - * bytecode limit for this type - */ - public int bytecodeLimit() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int buildCostLead(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int buildCostLeadLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer buildCostLeadAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer buildCostLeadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int buildCostGold(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int buildCostGoldLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer buildCostGoldAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer buildCostGoldInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + public int actionCooldown() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int movementCooldown() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int health() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int damage() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int bytecodeLimit() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, - byte spawnSource, - float convictionRatio, - float actionCooldown, + int buildCostLeadOffset, + int buildCostGoldOffset, + int actionCooldown, + int movementCooldown, + int health, + int damage, int actionRadiusSquared, - int sensorRadiusSquared, - int detectionRadiusSquared, + int visionRadiusSquared, int bytecodeLimit) { - builder.startObject(8); + builder.startObject(10); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDetectionRadiusSquared(builder, detectionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, sensorRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addDamage(builder, damage); + BodyTypeMetadata.addHealth(builder, health); + BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addConvictionRatio(builder, convictionRatio); - BodyTypeMetadata.addSpawnSource(builder, spawnSource); + BodyTypeMetadata.addBuildCostGold(builder, buildCostGoldOffset); + BodyTypeMetadata.addBuildCostLead(builder, buildCostLeadOffset); BodyTypeMetadata.addType(builder, type); return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(8); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(10); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } - public static void addSpawnSource(FlatBufferBuilder builder, byte spawnSource) { builder.addByte(1, spawnSource, 0); } - public static void addConvictionRatio(FlatBufferBuilder builder, float convictionRatio) { builder.addFloat(2, convictionRatio, 0.0f); } - public static void addActionCooldown(FlatBufferBuilder builder, float actionCooldown) { builder.addFloat(3, actionCooldown, 0.0f); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(4, actionRadiusSquared, 0); } - public static void addSensorRadiusSquared(FlatBufferBuilder builder, int sensorRadiusSquared) { builder.addInt(5, sensorRadiusSquared, 0); } - public static void addDetectionRadiusSquared(FlatBufferBuilder builder, int detectionRadiusSquared) { builder.addInt(6, detectionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(7, bytecodeLimit, 0); } + public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLeadOffset) { builder.addOffset(1, buildCostLeadOffset, 0); } + public static int createBuildCostLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBuildCostLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGoldOffset) { builder.addOffset(2, buildCostGoldOffset, 0); } + public static int createBuildCostGoldVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startBuildCostGoldVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(3, actionCooldown, 0); } + public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(4, movementCooldown, 0); } + public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(5, health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(6, damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(7, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(8, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(9, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/schema/java/battlecode/schema/Constants.java b/schema/java/battlecode/schema/Constants.java new file mode 100644 index 00000000..f82a5a1f --- /dev/null +++ b/schema/java/battlecode/schema/Constants.java @@ -0,0 +1,37 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package battlecode.schema; + +import java.nio.*; +import java.lang.*; +import java.util.*; +import com.google.flatbuffers.*; + +@SuppressWarnings("unused") +public final class Constants extends Table { + public static Constants getRootAsConstants(ByteBuffer _bb) { return getRootAsConstants(_bb, new Constants()); } + public static Constants getRootAsConstants(ByteBuffer _bb, Constants obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); } + public Constants __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public int increasePeriod() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int leadAdditiveIncease() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + + public static int createConstants(FlatBufferBuilder builder, + int increasePeriod, + int leadAdditiveIncease) { + builder.startObject(2); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); + Constants.addIncreasePeriod(builder, increasePeriod); + return Constants.endConstants(builder); + } + + public static void startConstants(FlatBufferBuilder builder) { builder.startObject(2); } + public static void addIncreasePeriod(FlatBufferBuilder builder, int increasePeriod) { builder.addInt(0, increasePeriod, 0); } + public static void addLeadAdditiveIncease(FlatBufferBuilder builder, int leadAdditiveIncease) { builder.addInt(1, leadAdditiveIncease, 0); } + public static int endConstants(FlatBufferBuilder builder) { + int o = builder.endObject(); + return o; + } +} + diff --git a/schema/java/battlecode/schema/GameHeader.java b/schema/java/battlecode/schema/GameHeader.java index 77363711..4c93ff54 100644 --- a/schema/java/battlecode/schema/GameHeader.java +++ b/schema/java/battlecode/schema/GameHeader.java @@ -35,19 +35,23 @@ public final class GameHeader extends Table { public BodyTypeMetadata bodyTypeMetadata(int j) { return bodyTypeMetadata(new BodyTypeMetadata(), j); } public BodyTypeMetadata bodyTypeMetadata(BodyTypeMetadata obj, int j) { int o = __offset(8); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } public int bodyTypeMetadataLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public Constants constants() { return constants(new Constants()); } + public Constants constants(Constants obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } public static int createGameHeader(FlatBufferBuilder builder, int specVersionOffset, int teamsOffset, - int bodyTypeMetadataOffset) { - builder.startObject(3); + int bodyTypeMetadataOffset, + int constantsOffset) { + builder.startObject(4); + GameHeader.addConstants(builder, constantsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addSpecVersion(builder, specVersionOffset); return GameHeader.endGameHeader(builder); } - public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(3); } + public static void startGameHeader(FlatBufferBuilder builder) { builder.startObject(4); } public static void addSpecVersion(FlatBufferBuilder builder, int specVersionOffset) { builder.addOffset(0, specVersionOffset, 0); } public static void addTeams(FlatBufferBuilder builder, int teamsOffset) { builder.addOffset(1, teamsOffset, 0); } public static int createTeamsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } @@ -55,6 +59,7 @@ public static int createGameHeader(FlatBufferBuilder builder, public static void addBodyTypeMetadata(FlatBufferBuilder builder, int bodyTypeMetadataOffset) { builder.addOffset(2, bodyTypeMetadataOffset, 0); } public static int createBodyTypeMetadataVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } public static void startBodyTypeMetadataVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addConstants(FlatBufferBuilder builder, int constantsOffset) { builder.addOffset(3, constantsOffset, 0); } public static int endGameHeader(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/schema/java/battlecode/schema/GameMap.java b/schema/java/battlecode/schema/GameMap.java index 09b78818..42d7163f 100644 --- a/schema/java/battlecode/schema/GameMap.java +++ b/schema/java/battlecode/schema/GameMap.java @@ -43,22 +43,32 @@ public final class GameMap extends Table { */ public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** - * The factor to divide cooldowns by + * The rubble on the map. */ - public double passability(int j) { int o = __offset(14); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } - public int passabilityLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer passabilityAsByteBuffer() { return __vector_as_bytebuffer(14, 8); } - public ByteBuffer passabilityInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 8); } + public int rubble(int j) { int o = __offset(14); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int rubbleLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(14, 4); } + public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 4); } + /** + * The lead on the map. + */ + public int lead(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } + public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(6); } + public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(7); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } - public static void addPassability(FlatBufferBuilder builder, int passabilityOffset) { builder.addOffset(5, passabilityOffset, 0); } - public static int createPassabilityVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } - public static void startPassabilityVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } + public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(5, rubbleOffset, 0); } + public static int createRubbleVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startRubbleVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(6, leadOffset, 0); } + public static int createLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endGameMap(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/schema/java/battlecode/schema/Round.java b/schema/java/battlecode/schema/Round.java index c36316ae..b7295a4e 100644 --- a/schema/java/battlecode/schema/Round.java +++ b/schema/java/battlecode/schema/Round.java @@ -28,19 +28,19 @@ public final class Round extends Table { public ByteBuffer teamIDsAsByteBuffer() { return __vector_as_bytebuffer(4, 4); } public ByteBuffer teamIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 4); } /** - * The number of votes the teams get, 0 or 1. + * The total amount of lead change of this team, this round */ - public int teamVotes(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamVotesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamVotesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer teamVotesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } + public int teamLeadChanges(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamLeadChangesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamLeadChangesAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } + public ByteBuffer teamLeadChangesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } /** - * The ID of the Enlightenment Center got the bid. + * The total amount of gold change of this team, this round */ - public int teamBidderIDs(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamBidderIDsLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamBidderIDsAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer teamBidderIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } + public int teamGoldChanges(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int teamGoldChangesLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer teamGoldChangesAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } + public ByteBuffer teamGoldChangesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } /** * The IDs of bodies that moved. */ @@ -87,100 +87,106 @@ public final class Round extends Table { public int actionTargetsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } public ByteBuffer actionTargetsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } public ByteBuffer actionTargetsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } + /** + * The locations of lead drops + */ + public VecTable leadDropLocations() { return leadDropLocations(new VecTable()); } + public VecTable leadDropLocations(VecTable obj) { int o = __offset(24); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The amount of lead dropped at each location + */ + public int leadDropValues(int j) { int o = __offset(26); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadDropValuesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadDropValuesAsByteBuffer() { return __vector_as_bytebuffer(26, 4); } + public ByteBuffer leadDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 4); } + /** + * The locations of gold drops + */ + public VecTable goldDropLocations() { return goldDropLocations(new VecTable()); } + public VecTable goldDropLocations(VecTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + /** + * The amount of gold dropped at each location + */ + public int goldDropValues(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int goldDropValuesLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer goldDropValuesAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } + public ByteBuffer goldDropValuesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + /** + * The IDs of the robots who changed their indicator strings + */ + public int indicatorStringIDs(int j) { int o = __offset(32); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorStringIDsLength() { int o = __offset(32); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorStringIDsAsByteBuffer() { return __vector_as_bytebuffer(32, 4); } + public ByteBuffer indicatorStringIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 32, 4); } + /** + * The messages of the robots who changed their indicator strings + */ + public String indicatorStrings(int j) { int o = __offset(34); return o != 0 ? __string(__vector(o) + j * 4) : null; } + public int indicatorStringsLength() { int o = __offset(34); return o != 0 ? __vector_len(o) : 0; } /** * The IDs of bodies that set indicator dots */ - public int indicatorDotIDs(int j) { int o = __offset(24); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorDotIDsLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(24, 4); } - public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 4); } + public int indicatorDotIDs(int j) { int o = __offset(36); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorDotIDsLength() { int o = __offset(36); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorDotIDsAsByteBuffer() { return __vector_as_bytebuffer(36, 4); } + public ByteBuffer indicatorDotIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 36, 4); } /** * The location of the indicator dots */ public VecTable indicatorDotLocs() { return indicatorDotLocs(new VecTable()); } - public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorDotLocs(VecTable obj) { int o = __offset(38); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator dots */ public RGBTable indicatorDotRGBs() { return indicatorDotRGBs(new RGBTable()); } - public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public RGBTable indicatorDotRGBs(RGBTable obj) { int o = __offset(40); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The IDs of bodies that set indicator lines */ - public int indicatorLineIDs(int j) { int o = __offset(30); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int indicatorLineIDsLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(30, 4); } - public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 4); } + public int indicatorLineIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int indicatorLineIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer indicatorLineIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } + public ByteBuffer indicatorLineIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } /** * The start location of the indicator lines */ public VecTable indicatorLineStartLocs() { return indicatorLineStartLocs(new VecTable()); } - public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorLineStartLocs(VecTable obj) { int o = __offset(44); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The end location of the indicator lines */ public VecTable indicatorLineEndLocs() { return indicatorLineEndLocs(new VecTable()); } - public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(34); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public VecTable indicatorLineEndLocs(VecTable obj) { int o = __offset(46); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The RGB values of the indicator lines */ public RGBTable indicatorLineRGBs() { return indicatorLineRGBs(new RGBTable()); } - public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(36); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * All logs sent this round. - * Messages from a particular robot in this round start on a new line, and - * have a header: - * '[' $TEAM ':' $ROBOTTYPE '#' $ID '@' $ROUND '] ' - * $TEAM = 'A' | 'B' - * $ROBOTTYPE = 'ENLIGHTENMENT_CENTER' | 'POLITICIAN' | 'SLANDERER' | 'MUCKRAKER' - * $ID = a number - * $ROUND = a number - * The header is not necessarily followed by a newline. - * This header should only be sent once per robot per round (although - * players may forge it, so don't crash if you get strange input.) - * - * You should try to only read this value once, and cache it. Reading - * strings from a flatbuffer is much less efficient than reading other - * buffers, because they need to be copied into an environment-provided - * buffer and validated. - * - * (haha i guess you can never really escape string parsing can you) - */ - public String logs() { int o = __offset(38); return o != 0 ? __string(o + bb_pos) : null; } - public ByteBuffer logsAsByteBuffer() { return __vector_as_bytebuffer(38, 1); } - public ByteBuffer logsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 38, 1); } + public RGBTable indicatorLineRGBs(RGBTable obj) { int o = __offset(48); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The first sent Round in a match should have index 1. (The starting state, * created by the MatchHeader, can be thought to have index 0.) * It should increase by one for each following round. */ - public int roundID() { int o = __offset(40); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int roundID() { int o = __offset(50); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The IDs of player bodies. */ - public int bytecodeIDs(int j) { int o = __offset(42); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodeIDsLength() { int o = __offset(42); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(42, 4); } - public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 42, 4); } + public int bytecodeIDs(int j) { int o = __offset(52); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodeIDsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodeIDsAsByteBuffer() { return __vector_as_bytebuffer(52, 4); } + public ByteBuffer bytecodeIDsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 4); } /** * The bytecodes used by the player bodies. */ - public int bytecodesUsed(int j) { int o = __offset(44); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int bytecodesUsedLength() { int o = __offset(44); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(44, 4); } - public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 44, 4); } - /** - * Amount of influence contributing to the teams' buffs. Added at end for backwards compatability. - */ - public int teamNumBuffs(int j) { int o = __offset(46); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int teamNumBuffsLength() { int o = __offset(46); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer teamNumBuffsAsByteBuffer() { return __vector_as_bytebuffer(46, 4); } - public ByteBuffer teamNumBuffsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 46, 4); } + public int bytecodesUsed(int j) { int o = __offset(54); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int bytecodesUsedLength() { int o = __offset(54); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer bytecodesUsedAsByteBuffer() { return __vector_as_bytebuffer(54, 4); } + public ByteBuffer bytecodesUsedInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 54, 4); } public static int createRound(FlatBufferBuilder builder, int teamIDsOffset, - int teamVotesOffset, - int teamBidderIDsOffset, + int teamLeadChangesOffset, + int teamGoldChangesOffset, int movedIDsOffset, int movedLocsOffset, int spawnedBodiesOffset, @@ -188,6 +194,12 @@ public static int createRound(FlatBufferBuilder builder, int actionIDsOffset, int actionsOffset, int actionTargetsOffset, + int leadDropLocationsOffset, + int leadDropValuesOffset, + int goldDropLocationsOffset, + int goldDropValuesOffset, + int indicatorStringIDsOffset, + int indicatorStringsOffset, int indicatorDotIDsOffset, int indicatorDotLocsOffset, int indicatorDotRGBsOffset, @@ -195,17 +207,13 @@ public static int createRound(FlatBufferBuilder builder, int indicatorLineStartLocsOffset, int indicatorLineEndLocsOffset, int indicatorLineRGBsOffset, - int logsOffset, int roundID, int bytecodeIDsOffset, - int bytecodesUsedOffset, - int teamNumBuffsOffset) { - builder.startObject(22); - Round.addTeamNumBuffs(builder, teamNumBuffsOffset); + int bytecodesUsedOffset) { + builder.startObject(26); Round.addBytecodesUsed(builder, bytecodesUsedOffset); Round.addBytecodeIDs(builder, bytecodeIDsOffset); Round.addRoundID(builder, roundID); - Round.addLogs(builder, logsOffset); Round.addIndicatorLineRGBs(builder, indicatorLineRGBsOffset); Round.addIndicatorLineEndLocs(builder, indicatorLineEndLocsOffset); Round.addIndicatorLineStartLocs(builder, indicatorLineStartLocsOffset); @@ -213,6 +221,12 @@ public static int createRound(FlatBufferBuilder builder, Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); + Round.addGoldDropValues(builder, goldDropValuesOffset); + Round.addGoldDropLocations(builder, goldDropLocationsOffset); + Round.addLeadDropValues(builder, leadDropValuesOffset); + Round.addLeadDropLocations(builder, leadDropLocationsOffset); Round.addActionTargets(builder, actionTargetsOffset); Round.addActions(builder, actionsOffset); Round.addActionIDs(builder, actionIDsOffset); @@ -220,22 +234,22 @@ public static int createRound(FlatBufferBuilder builder, Round.addSpawnedBodies(builder, spawnedBodiesOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addMovedIDs(builder, movedIDsOffset); - Round.addTeamBidderIDs(builder, teamBidderIDsOffset); - Round.addTeamVotes(builder, teamVotesOffset); + Round.addTeamGoldChanges(builder, teamGoldChangesOffset); + Round.addTeamLeadChanges(builder, teamLeadChangesOffset); Round.addTeamIDs(builder, teamIDsOffset); return Round.endRound(builder); } - public static void startRound(FlatBufferBuilder builder) { builder.startObject(22); } + public static void startRound(FlatBufferBuilder builder) { builder.startObject(26); } public static void addTeamIDs(FlatBufferBuilder builder, int teamIDsOffset) { builder.addOffset(0, teamIDsOffset, 0); } public static int createTeamIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startTeamIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamVotes(FlatBufferBuilder builder, int teamVotesOffset) { builder.addOffset(1, teamVotesOffset, 0); } - public static int createTeamVotesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamVotesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamBidderIDs(FlatBufferBuilder builder, int teamBidderIDsOffset) { builder.addOffset(2, teamBidderIDsOffset, 0); } - public static int createTeamBidderIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamBidderIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamLeadChanges(FlatBufferBuilder builder, int teamLeadChangesOffset) { builder.addOffset(1, teamLeadChangesOffset, 0); } + public static int createTeamLeadChangesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamLeadChangesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addTeamGoldChanges(FlatBufferBuilder builder, int teamGoldChangesOffset) { builder.addOffset(2, teamGoldChangesOffset, 0); } + public static int createTeamGoldChangesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startTeamGoldChangesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addMovedIDs(FlatBufferBuilder builder, int movedIDsOffset) { builder.addOffset(3, movedIDsOffset, 0); } public static int createMovedIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startMovedIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -253,28 +267,38 @@ public static int createRound(FlatBufferBuilder builder, public static void addActionTargets(FlatBufferBuilder builder, int actionTargetsOffset) { builder.addOffset(9, actionTargetsOffset, 0); } public static int createActionTargetsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startActionTargetsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(10, indicatorDotIDsOffset, 0); } + public static void addLeadDropLocations(FlatBufferBuilder builder, int leadDropLocationsOffset) { builder.addOffset(10, leadDropLocationsOffset, 0); } + public static void addLeadDropValues(FlatBufferBuilder builder, int leadDropValuesOffset) { builder.addOffset(11, leadDropValuesOffset, 0); } + public static int createLeadDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startLeadDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addGoldDropLocations(FlatBufferBuilder builder, int goldDropLocationsOffset) { builder.addOffset(12, goldDropLocationsOffset, 0); } + public static void addGoldDropValues(FlatBufferBuilder builder, int goldDropValuesOffset) { builder.addOffset(13, goldDropValuesOffset, 0); } + public static int createGoldDropValuesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startGoldDropValuesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorStringIDs(FlatBufferBuilder builder, int indicatorStringIDsOffset) { builder.addOffset(14, indicatorStringIDsOffset, 0); } + public static int createIndicatorStringIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startIndicatorStringIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorStrings(FlatBufferBuilder builder, int indicatorStringsOffset) { builder.addOffset(15, indicatorStringsOffset, 0); } + public static int createIndicatorStringsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startIndicatorStringsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addIndicatorDotIDs(FlatBufferBuilder builder, int indicatorDotIDsOffset) { builder.addOffset(16, indicatorDotIDsOffset, 0); } public static int createIndicatorDotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorDotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(11, indicatorDotLocsOffset, 0); } - public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(12, indicatorDotRGBsOffset, 0); } - public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(13, indicatorLineIDsOffset, 0); } + public static void addIndicatorDotLocs(FlatBufferBuilder builder, int indicatorDotLocsOffset) { builder.addOffset(17, indicatorDotLocsOffset, 0); } + public static void addIndicatorDotRGBs(FlatBufferBuilder builder, int indicatorDotRGBsOffset) { builder.addOffset(18, indicatorDotRGBsOffset, 0); } + public static void addIndicatorLineIDs(FlatBufferBuilder builder, int indicatorLineIDsOffset) { builder.addOffset(19, indicatorLineIDsOffset, 0); } public static int createIndicatorLineIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startIndicatorLineIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(14, indicatorLineStartLocsOffset, 0); } - public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(15, indicatorLineEndLocsOffset, 0); } - public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(16, indicatorLineRGBsOffset, 0); } - public static void addLogs(FlatBufferBuilder builder, int logsOffset) { builder.addOffset(17, logsOffset, 0); } - public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(18, roundID, 0); } - public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(19, bytecodeIDsOffset, 0); } + public static void addIndicatorLineStartLocs(FlatBufferBuilder builder, int indicatorLineStartLocsOffset) { builder.addOffset(20, indicatorLineStartLocsOffset, 0); } + public static void addIndicatorLineEndLocs(FlatBufferBuilder builder, int indicatorLineEndLocsOffset) { builder.addOffset(21, indicatorLineEndLocsOffset, 0); } + public static void addIndicatorLineRGBs(FlatBufferBuilder builder, int indicatorLineRGBsOffset) { builder.addOffset(22, indicatorLineRGBsOffset, 0); } + public static void addRoundID(FlatBufferBuilder builder, int roundID) { builder.addInt(23, roundID, 0); } + public static void addBytecodeIDs(FlatBufferBuilder builder, int bytecodeIDsOffset) { builder.addOffset(24, bytecodeIDsOffset, 0); } public static int createBytecodeIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodeIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(20, bytecodesUsedOffset, 0); } + public static void addBytecodesUsed(FlatBufferBuilder builder, int bytecodesUsedOffset) { builder.addOffset(25, bytecodesUsedOffset, 0); } public static int createBytecodesUsedVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startBytecodesUsedVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addTeamNumBuffs(FlatBufferBuilder builder, int teamNumBuffsOffset) { builder.addOffset(21, teamNumBuffsOffset, 0); } - public static int createTeamNumBuffsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startTeamNumBuffsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endRound(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/schema/java/battlecode/schema/SpawnedBodyTable.java b/schema/java/battlecode/schema/SpawnedBodyTable.java index 3616e911..71bf66ec 100644 --- a/schema/java/battlecode/schema/SpawnedBodyTable.java +++ b/schema/java/battlecode/schema/SpawnedBodyTable.java @@ -47,24 +47,13 @@ public final class SpawnedBodyTable extends Table { */ public VecTable locs() { return locs(new VecTable()); } public VecTable locs(VecTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } - /** - * the amount of influence paid to create these bodies - * for initial Enlightenment Centers, this is the amount of influence - * needed to take over - */ - public int influences(int j) { int o = __offset(12); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int influencesLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer influencesAsByteBuffer() { return __vector_as_bytebuffer(12, 4); } - public ByteBuffer influencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 4); } public static int createSpawnedBodyTable(FlatBufferBuilder builder, int robotIDsOffset, int teamIDsOffset, int typesOffset, - int locsOffset, - int influencesOffset) { - builder.startObject(5); - SpawnedBodyTable.addInfluences(builder, influencesOffset); + int locsOffset) { + builder.startObject(4); SpawnedBodyTable.addLocs(builder, locsOffset); SpawnedBodyTable.addTypes(builder, typesOffset); SpawnedBodyTable.addTeamIDs(builder, teamIDsOffset); @@ -72,7 +61,7 @@ public static int createSpawnedBodyTable(FlatBufferBuilder builder, return SpawnedBodyTable.endSpawnedBodyTable(builder); } - public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(5); } + public static void startSpawnedBodyTable(FlatBufferBuilder builder) { builder.startObject(4); } public static void addRobotIDs(FlatBufferBuilder builder, int robotIDsOffset) { builder.addOffset(0, robotIDsOffset, 0); } public static int createRobotIDsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRobotIDsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } @@ -83,9 +72,6 @@ public static int createSpawnedBodyTable(FlatBufferBuilder builder, public static int createTypesVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); } public static void startTypesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); } public static void addLocs(FlatBufferBuilder builder, int locsOffset) { builder.addOffset(3, locsOffset, 0); } - public static void addInfluences(FlatBufferBuilder builder, int influencesOffset) { builder.addOffset(4, influencesOffset, 0); } - public static int createInfluencesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startInfluencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endSpawnedBodyTable(FlatBufferBuilder builder) { int o = builder.endObject(); return o; From f46c9e718cd0faeec1e3ee82ed0aa3adbdc7d33d Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 18:06:24 -0600 Subject: [PATCH 209/413] edit GameMap in schema --- .../src/main/battlecode/schema/GameMap.java | 55 ++++++++++++++----- .../src/main/battlecode/world/GameMapIO.java | 1 - schema/battlecode.fbs | 6 ++ schema/java/battlecode/schema/GameMap.java | 55 ++++++++++++++----- 4 files changed, 86 insertions(+), 31 deletions(-) diff --git a/engine/src/main/battlecode/schema/GameMap.java b/engine/src/main/battlecode/schema/GameMap.java index 42d7163f..bae5c860 100644 --- a/engine/src/main/battlecode/schema/GameMap.java +++ b/engine/src/main/battlecode/schema/GameMap.java @@ -33,42 +33,67 @@ public final class GameMap extends Table { */ public Vec maxCorner() { return maxCorner(new Vec()); } public Vec maxCorner(Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + /** + * The map symmetry: 0 for rotation, 1 for horizontal, 2 for vertical. + */ + public int symmetry() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The bodies on the map. */ public SpawnedBodyTable bodies() { return bodies(new SpawnedBodyTable()); } - public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The random seed of the map. */ - public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int randomSeed() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The rubble on the map. */ - public int rubble(int j) { int o = __offset(14); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int rubbleLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(14, 4); } - public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 4); } + public int rubble(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int rubbleLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } + public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } /** * The lead on the map. */ - public int lead(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int leadLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } - public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } + public int lead(int j) { int o = __offset(18); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(18, 4); } + public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 4); } + /** + * The anomalies scheduled: 0/1/2/3 abyss/charge/fury/vortex. + */ + public int anomalies(int j) { int o = __offset(20); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int anomaliesLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer anomaliesAsByteBuffer() { return __vector_as_bytebuffer(20, 4); } + public ByteBuffer anomaliesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 4); } + /** + * The rounds the anomalies are scheduled for. + */ + public int anomalyRounds(int j) { int o = __offset(22); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int anomalyRoundsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer anomalyRoundsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } + public ByteBuffer anomalyRoundsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(7); } + public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(10); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } - public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } - public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } - public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(5, rubbleOffset, 0); } + public static void addSymmetry(FlatBufferBuilder builder, int symmetry) { builder.addInt(3, symmetry, 0); } + public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(4, bodiesOffset, 0); } + public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(5, randomSeed, 0); } + public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(6, rubbleOffset, 0); } public static int createRubbleVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRubbleVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(6, leadOffset, 0); } + public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(7, leadOffset, 0); } public static int createLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addAnomalies(FlatBufferBuilder builder, int anomaliesOffset) { builder.addOffset(8, anomaliesOffset, 0); } + public static int createAnomaliesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startAnomaliesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addAnomalyRounds(FlatBufferBuilder builder, int anomalyRoundsOffset) { builder.addOffset(9, anomalyRoundsOffset, 0); } + public static int createAnomalyRoundsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startAnomalyRoundsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endGameMap(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index 977bf629..170909f6 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -228,7 +228,6 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final String mapName = raw.name(); int[] rubbleArray = new int[width * height]; int[] leadArray = new int[width * height]; - int[] goldArray = new int[width * height]; for (int i = 0; i < width * height; i++) { rubbleArray[i] = raw.rubble(i); leadArray[i] = raw.lead(i); diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 9295822a..dba30970 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -59,6 +59,8 @@ table GameMap { minCorner: Vec; /// The top corner of the map. maxCorner: Vec; + /// The map symmetry: 0 for rotation, 1 for horizontal, 2 for vertical. + symmetry: int; /// The bodies on the map. bodies: SpawnedBodyTable; /// The random seed of the map. @@ -67,6 +69,10 @@ table GameMap { rubble: [int]; /// The lead on the map. lead: [int]; + /// The anomalies scheduled: 0/1/2/3 abyss/charge/fury/vortex. + anomalies: [int]; + /// The rounds the anomalies are scheduled for. + anomalyRounds: [int]; } /// Actions that can be performed. diff --git a/schema/java/battlecode/schema/GameMap.java b/schema/java/battlecode/schema/GameMap.java index 42d7163f..bae5c860 100644 --- a/schema/java/battlecode/schema/GameMap.java +++ b/schema/java/battlecode/schema/GameMap.java @@ -33,42 +33,67 @@ public final class GameMap extends Table { */ public Vec maxCorner() { return maxCorner(new Vec()); } public Vec maxCorner(Vec obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; } + /** + * The map symmetry: 0 for rotation, 1 for horizontal, 2 for vertical. + */ + public int symmetry() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The bodies on the map. */ public SpawnedBodyTable bodies() { return bodies(new SpawnedBodyTable()); } - public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(10); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } + public SpawnedBodyTable bodies(SpawnedBodyTable obj) { int o = __offset(12); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; } /** * The random seed of the map. */ - public int randomSeed() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int randomSeed() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } /** * The rubble on the map. */ - public int rubble(int j) { int o = __offset(14); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int rubbleLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(14, 4); } - public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 4); } + public int rubble(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int rubbleLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer rubbleAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } + public ByteBuffer rubbleInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } /** * The lead on the map. */ - public int lead(int j) { int o = __offset(16); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int leadLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } - public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } + public int lead(int j) { int o = __offset(18); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int leadLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer leadAsByteBuffer() { return __vector_as_bytebuffer(18, 4); } + public ByteBuffer leadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 4); } + /** + * The anomalies scheduled: 0/1/2/3 abyss/charge/fury/vortex. + */ + public int anomalies(int j) { int o = __offset(20); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int anomaliesLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer anomaliesAsByteBuffer() { return __vector_as_bytebuffer(20, 4); } + public ByteBuffer anomaliesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 4); } + /** + * The rounds the anomalies are scheduled for. + */ + public int anomalyRounds(int j) { int o = __offset(22); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } + public int anomalyRoundsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } + public ByteBuffer anomalyRoundsAsByteBuffer() { return __vector_as_bytebuffer(22, 4); } + public ByteBuffer anomalyRoundsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); } - public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(7); } + public static void startGameMap(FlatBufferBuilder builder) { builder.startObject(10); } public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); } public static void addMinCorner(FlatBufferBuilder builder, int minCornerOffset) { builder.addStruct(1, minCornerOffset, 0); } public static void addMaxCorner(FlatBufferBuilder builder, int maxCornerOffset) { builder.addStruct(2, maxCornerOffset, 0); } - public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(3, bodiesOffset, 0); } - public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(4, randomSeed, 0); } - public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(5, rubbleOffset, 0); } + public static void addSymmetry(FlatBufferBuilder builder, int symmetry) { builder.addInt(3, symmetry, 0); } + public static void addBodies(FlatBufferBuilder builder, int bodiesOffset) { builder.addOffset(4, bodiesOffset, 0); } + public static void addRandomSeed(FlatBufferBuilder builder, int randomSeed) { builder.addInt(5, randomSeed, 0); } + public static void addRubble(FlatBufferBuilder builder, int rubbleOffset) { builder.addOffset(6, rubbleOffset, 0); } public static int createRubbleVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startRubbleVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(6, leadOffset, 0); } + public static void addLead(FlatBufferBuilder builder, int leadOffset) { builder.addOffset(7, leadOffset, 0); } public static int createLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } public static void startLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addAnomalies(FlatBufferBuilder builder, int anomaliesOffset) { builder.addOffset(8, anomaliesOffset, 0); } + public static int createAnomaliesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startAnomaliesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static void addAnomalyRounds(FlatBufferBuilder builder, int anomalyRoundsOffset) { builder.addOffset(9, anomalyRoundsOffset, 0); } + public static int createAnomalyRoundsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } + public static void startAnomalyRoundsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static int endGameMap(FlatBufferBuilder builder) { int o = builder.endObject(); return o; From 34b74cd02a8ea1c0d59e8ba697d5e8180513126c Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 18:27:42 -0600 Subject: [PATCH 210/413] remove duplicates --- engine/src/main/battlecode/schema-old/Action.java | 2 +- engine/src/main/battlecode/schema-old/BodyType.java | 2 +- engine/src/main/battlecode/schema-old/BodyTypeMetadata.java | 2 +- engine/src/main/battlecode/schema-old/Event.java | 2 +- engine/src/main/battlecode/schema-old/EventWrapper.java | 2 +- engine/src/main/battlecode/schema-old/GameFooter.java | 2 +- engine/src/main/battlecode/schema-old/GameHeader.java | 2 +- engine/src/main/battlecode/schema-old/GameMap.java | 2 +- engine/src/main/battlecode/schema-old/GameWrapper.java | 2 +- engine/src/main/battlecode/schema-old/MatchFooter.java | 2 +- engine/src/main/battlecode/schema-old/MatchHeader.java | 2 +- engine/src/main/battlecode/schema-old/ProfilerEvent.java | 2 +- engine/src/main/battlecode/schema-old/ProfilerFile.java | 2 +- engine/src/main/battlecode/schema-old/ProfilerProfile.java | 2 +- engine/src/main/battlecode/schema-old/RGBTable.java | 2 +- engine/src/main/battlecode/schema-old/Round.java | 2 +- engine/src/main/battlecode/schema-old/SpawnedBodyTable.java | 2 +- engine/src/main/battlecode/schema-old/TeamData.java | 2 +- engine/src/main/battlecode/schema-old/Vec.java | 2 +- engine/src/main/battlecode/schema-old/VecTable.java | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/engine/src/main/battlecode/schema-old/Action.java b/engine/src/main/battlecode/schema-old/Action.java index a21287a3..ffd303b8 100644 --- a/engine/src/main/battlecode/schema-old/Action.java +++ b/engine/src/main/battlecode/schema-old/Action.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; /** * Actions that can be performed. diff --git a/engine/src/main/battlecode/schema-old/BodyType.java b/engine/src/main/battlecode/schema-old/BodyType.java index ee34e38d..2d4ae7ab 100644 --- a/engine/src/main/battlecode/schema-old/BodyType.java +++ b/engine/src/main/battlecode/schema-old/BodyType.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; /** * The possible types of things that can exist. diff --git a/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java b/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java index 8b7e63ba..a2825c7c 100644 --- a/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java +++ b/engine/src/main/battlecode/schema-old/BodyTypeMetadata.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/Event.java b/engine/src/main/battlecode/schema-old/Event.java index 15d257e3..ccfb7cd9 100644 --- a/engine/src/main/battlecode/schema-old/Event.java +++ b/engine/src/main/battlecode/schema-old/Event.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; /** * Events diff --git a/engine/src/main/battlecode/schema-old/EventWrapper.java b/engine/src/main/battlecode/schema-old/EventWrapper.java index 3eb73a91..d3377ac7 100644 --- a/engine/src/main/battlecode/schema-old/EventWrapper.java +++ b/engine/src/main/battlecode/schema-old/EventWrapper.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/GameFooter.java b/engine/src/main/battlecode/schema-old/GameFooter.java index b5512bb5..70bab946 100644 --- a/engine/src/main/battlecode/schema-old/GameFooter.java +++ b/engine/src/main/battlecode/schema-old/GameFooter.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/GameHeader.java b/engine/src/main/battlecode/schema-old/GameHeader.java index 77363711..53b7e653 100644 --- a/engine/src/main/battlecode/schema-old/GameHeader.java +++ b/engine/src/main/battlecode/schema-old/GameHeader.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/GameMap.java b/engine/src/main/battlecode/schema-old/GameMap.java index 09b78818..34475b23 100644 --- a/engine/src/main/battlecode/schema-old/GameMap.java +++ b/engine/src/main/battlecode/schema-old/GameMap.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/GameWrapper.java b/engine/src/main/battlecode/schema-old/GameWrapper.java index 25a0c03e..ecf4634c 100644 --- a/engine/src/main/battlecode/schema-old/GameWrapper.java +++ b/engine/src/main/battlecode/schema-old/GameWrapper.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/MatchFooter.java b/engine/src/main/battlecode/schema-old/MatchFooter.java index 8777c9ea..74fa1fd1 100644 --- a/engine/src/main/battlecode/schema-old/MatchFooter.java +++ b/engine/src/main/battlecode/schema-old/MatchFooter.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/MatchHeader.java b/engine/src/main/battlecode/schema-old/MatchHeader.java index b167ea98..ec5a46d0 100644 --- a/engine/src/main/battlecode/schema-old/MatchHeader.java +++ b/engine/src/main/battlecode/schema-old/MatchHeader.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/ProfilerEvent.java b/engine/src/main/battlecode/schema-old/ProfilerEvent.java index 58c47f12..0fbcd553 100644 --- a/engine/src/main/battlecode/schema-old/ProfilerEvent.java +++ b/engine/src/main/battlecode/schema-old/ProfilerEvent.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/ProfilerFile.java b/engine/src/main/battlecode/schema-old/ProfilerFile.java index c101925d..ffbd5e0d 100644 --- a/engine/src/main/battlecode/schema-old/ProfilerFile.java +++ b/engine/src/main/battlecode/schema-old/ProfilerFile.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/ProfilerProfile.java b/engine/src/main/battlecode/schema-old/ProfilerProfile.java index 15312ead..34a12924 100644 --- a/engine/src/main/battlecode/schema-old/ProfilerProfile.java +++ b/engine/src/main/battlecode/schema-old/ProfilerProfile.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/RGBTable.java b/engine/src/main/battlecode/schema-old/RGBTable.java index 6164af79..96fdeb9c 100644 --- a/engine/src/main/battlecode/schema-old/RGBTable.java +++ b/engine/src/main/battlecode/schema-old/RGBTable.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/Round.java b/engine/src/main/battlecode/schema-old/Round.java index c36316ae..c45ebc4e 100644 --- a/engine/src/main/battlecode/schema-old/Round.java +++ b/engine/src/main/battlecode/schema-old/Round.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java b/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java index 3616e911..b82bff1b 100644 --- a/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java +++ b/engine/src/main/battlecode/schema-old/SpawnedBodyTable.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/TeamData.java b/engine/src/main/battlecode/schema-old/TeamData.java index 57e3e4db..32b840b1 100644 --- a/engine/src/main/battlecode/schema-old/TeamData.java +++ b/engine/src/main/battlecode/schema-old/TeamData.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/Vec.java b/engine/src/main/battlecode/schema-old/Vec.java index a9cdcb68..880323bb 100644 --- a/engine/src/main/battlecode/schema-old/Vec.java +++ b/engine/src/main/battlecode/schema-old/Vec.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; diff --git a/engine/src/main/battlecode/schema-old/VecTable.java b/engine/src/main/battlecode/schema-old/VecTable.java index 82da91e7..318ab618 100644 --- a/engine/src/main/battlecode/schema-old/VecTable.java +++ b/engine/src/main/battlecode/schema-old/VecTable.java @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -package battlecode.schema; +// package battlecode.schema; import java.nio.*; import java.lang.*; From b7bcee273350ee3de5d2bb6429b5414608b1d5e2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 18:25:03 -0600 Subject: [PATCH 211/413] initial GameMapIO --- .../src/main/battlecode/world/GameMapIO.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index 170909f6..2796dd81 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -223,15 +223,19 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int width = (int) (raw.maxCorner().x() - raw.minCorner().x()); final int height = (int) (raw.maxCorner().y() - raw.minCorner().y()); final MapLocation origin = new MapLocation((int) raw.minCorner().x(), (int) raw.minCorner().y()); + final MapSymmetry symmetry = MaySymmetry.values()[raw.symmetry()]; final int seed = raw.randomSeed(); final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); int[] rubbleArray = new int[width * height]; int[] leadArray = new int[width * height]; - for (int i = 0; i < width * height; i++) { + for (int i = 0; i < rubbleArray.length; i++) { rubbleArray[i] = raw.rubble(i); leadArray[i] = raw.lead(i); - goldArray[i] = raw.gold(i); + } + AnomalyScheduleEntry[] anomalySchedule = new AnomalyScheduleEntry[raw.anomaliesLength()]; + for (int i = 0; i < anomalySchedule.length; i++) { + anomalySchedule[i] = new AnomalyScheduleEntry(raw.anomalyRounds(i), AnomalyType.values()[raw.anomalies(i)]); } ArrayList initBodies = new ArrayList<>(); SpawnedBodyTable bodyTable = raw.bodies(); @@ -240,7 +244,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { RobotInfo[] initialBodies = initBodies.toArray(new RobotInfo[initBodies.size()]); return new LiveMap( - width, height, origin, seed, rounds, mapName, initialBodies, rubbleArray, leadArray, goldArray + width, height, origin, seed, rounds, mapName, symmetry, initialBodies, rubbleArray, leadArray, anomalySchedule ); } @@ -257,7 +261,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int randomSeed = gameMap.getSeed(); int[] rubbleArray = gameMap.getRubbleArray(); int[] leadArray = gameMap.getLeadArray(); - int[] goldArray = gameMap.getGoldArray(); + AnomalyScheduleEntry[] anomalySchedule = gameMap.getAnomalySchedule(); // Make body tables ArrayList bodyIDs = new ArrayList<>(); ArrayList bodyTeamIDs = new ArrayList<>(); @@ -266,12 +270,17 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { ArrayList bodyLocsYs = new ArrayList<>(); ArrayList rubbleArrayList = new ArrayList<>(); ArrayList leadArrayList = new ArrayList<>(); - ArrayList goldArrayList = new ArrayList<>(); + ArrayList anomaliesArrayList = new ArrayList<>(); + ArrayList anomalyRoundsArrayList = new ArrayList<>(); + + for (int i = 0; i < anomalySchedule.length; i++) { + anomaliesArrayList.add(anomalySchedule[i].anomalyType.ordinal()); + anomalyRoundsArrayList.add(anomalySchedule[i].roundNumber); + } for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) { rubbleArrayList.add(rubbleArray[i]); leadArrayList.add(leadArray[i]); - goldArrayList.add(goldArray[i]); } for (RobotInfo robot : gameMap.getInitialBodies()) { @@ -296,18 +305,21 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) { int bodies = SpawnedBodyTable.endSpawnedBodyTable(builder); int rubbleArrayInt = battlecode.schema.GameMap.createRubbleVector(builder, ArrayUtils.toPrimitive(rubbleArrayList.toArray(new Integer[rubbleArrayList.size()]))); int leadArrayInt = battlecode.schema.GameMap.createLeadVector(builder, ArrayUtils.toPrimitive(leadArrayList.toArray(new Integer[leadArrayList.size()]))); - int goldArrayInt = battlecode.schema.GameMap.createGoldVector(builder, ArrayUtils.toPrimitive(goldArrayList.toArray(new Integer[goldArrayList.size()]))); + int anomaliesArrayInt = battlecode.schema.GameMap.createAnomaliesVector(builder, ArrayUtils.toPrimitive(anomaliesArrayList.toArray(new Integer[anomaliesArrayList.size()]))); + int anomalyRoundsArrayInt = battlecode.schema.GameMap.createAnomalyRoundsVector(builder, ArrayUtils.toPrimitive(anomalyRoundsArrayList.toArray(new Integer[anomalyRoundsArrayList.size()]))); // Build LiveMap for flatbuffer battlecode.schema.GameMap.startGameMap(builder); battlecode.schema.GameMap.addName(builder, name); battlecode.schema.GameMap.addMinCorner(builder, Vec.createVec(builder, gameMap.getOrigin().x, gameMap.getOrigin().y)); battlecode.schema.GameMap.addMaxCorner(builder, Vec.createVec(builder, gameMap.getOrigin().x + gameMap.getWidth(), gameMap.getOrigin().y + gameMap.getHeight())); + battlecode.schema.GameMap.addSymmetry(builder, gameMap.getSymmetry().ordinal()); battlecode.schema.GameMap.addBodies(builder, bodies); battlecode.schema.GameMap.addRandomSeed(builder, randomSeed); battlecode.schema.GameMap.addRubble(builder, rubbleArrayInt); battlecode.schema.GameMap.addLead(builder, leadArrayInt); - battlecode.schema.GameMap.addGold(builder, goldArrayInt); + battlecode.schema.GameMap.addAnomalies(builder, anomaliesArrayInt); + battlecode.schema.GameMap.addAnomalyRounds(builder, anomalyRoundsArrayInt); return battlecode.schema.GameMap.endGameMap(builder); } @@ -325,7 +337,7 @@ private static void initInitialBodiesFromSchemaBodyTable(SpawnedBodyTable bodyTa int bodyY = locs.ys(i); Team bodyTeam = TeamMapping.team(bodyTable.teamIDs(i)); if (bodyType == RobotType.ARCHON) - initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, new MapLocation(bodyX, bodyY))); + initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, 1, RobotType.ARCHON.health, new MapLocation(bodyX, bodyY))); // ignore robots that are not archons, TODO throw error? } } From 3ad0abfd1bbbbdbd1053301d3e92e7e6f428571c Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 18:31:04 -0600 Subject: [PATCH 212/413] fix typo --- engine/src/main/battlecode/world/GameMapIO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index 2796dd81..a7865545 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -223,7 +223,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw) { final int width = (int) (raw.maxCorner().x() - raw.minCorner().x()); final int height = (int) (raw.maxCorner().y() - raw.minCorner().y()); final MapLocation origin = new MapLocation((int) raw.minCorner().x(), (int) raw.minCorner().y()); - final MapSymmetry symmetry = MaySymmetry.values()[raw.symmetry()]; + final MapSymmetry symmetry = MapSymmetry.values()[raw.symmetry()]; final int seed = raw.randomSeed(); final int rounds = GameConstants.GAME_MAX_NUMBER_OF_ROUNDS; final String mapName = raw.name(); From e3fbd5efd9980155e70c0675cb37dc3ad49256e4 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 20:04:20 -0600 Subject: [PATCH 213/413] GameMaker --- .../src/main/battlecode/server/GameMaker.java | 182 ++++++++++++------ 1 file changed, 123 insertions(+), 59 deletions(-) diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index bcd12599..b7d6b6e9 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -17,6 +17,7 @@ import gnu.trove.list.array.TIntArrayList; import gnu.trove.list.array.TCharArrayList; import java.util.List; +import java.util.ArrayList; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -263,10 +264,16 @@ public void makeGameHeader() { int teamsOffset = GameHeader.createTeamsVector(builder, teamsVec); int bodyTypeMetadataOffset = makeBodyTypeMetadata(builder); + Constants.startConstants(builder); + Constants.addIncreasePeriod(builder, GameConstants.ADD_LEAD_EVERY_ROUNDS); + Constants.addLeadAdditiveIncease(builder, GameConstants.ADD_LEAD); + int constantsOffset = Constants.endConstants(builder); + GameHeader.startGameHeader(builder); GameHeader.addSpecVersion(builder, specVersionOffset); GameHeader.addTeams(builder, teamsOffset); GameHeader.addBodyTypeMetadata(builder, bodyTypeMetadataOffset); + GameHeader.addConstants(builder, constantsOffset); int gameHeaderOffset = GameHeader.endGameHeader(builder); return EventWrapper.createEventWrapper(builder, Event.GameHeader, gameHeaderOffset); @@ -280,12 +287,18 @@ public int makeBodyTypeMetadata(FlatBufferBuilder builder) { for (RobotType type : RobotType.values()) { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, robotTypeToBodyType(type)); - BodyTypeMetadata.addSpawnSource(builder, robotTypeToBodyType(type.spawnSource)); - BodyTypeMetadata.addConvictionRatio(builder, type.convictionRatio); + int[] buildCostLeadArray = {type.buildCostLead, type.getLeadMutateCost(2), type.getLeadMutateCost(3)}; + int buildCostLeadOffset = BodyTypeMetadata.createBuildCostLeadVector(builder, buildCostLeadArray); + int[] buildCostGoldArray = {type.buildCostGold, type.getGoldMutateCost(2), type.getGoldMutateCost(3)}; + int buildCostGoldOffset = BodyTypeMetadata.createBuildCostGoldVector(builder, buildCostGoldArray); + BodyTypeMetadata.addBuildCostLead(builder, buildCostLeadOffset); + BodyTypeMetadata.addBuildCostGold(builder, buildCostGoldOffset); BodyTypeMetadata.addActionCooldown(builder, type.actionCooldown); + BodyTypeMetadata.addMovementCooldown(builder, type.movementCooldown); + BodyTypeMetadata.addHealth(builder, type.health); + BodyTypeMetadata.addDamage(builder, type.damage); BodyTypeMetadata.addActionRadiusSquared(builder, type.actionRadiusSquared); - BodyTypeMetadata.addSensorRadiusSquared(builder, type.sensorRadiusSquared); - BodyTypeMetadata.addDetectionRadiusSquared(builder, type.detectionRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, type.visionRadiusSquared); BodyTypeMetadata.addBytecodeLimit(builder, type.bytecodeLimit); bodyTypeMetadataOffsets.add(BodyTypeMetadata.endBodyTypeMetadata(builder)); } @@ -295,10 +308,13 @@ public int makeBodyTypeMetadata(FlatBufferBuilder builder) { } private byte robotTypeToBodyType(RobotType type) { - if (type == RobotType.ENLIGHTENMENT_CENTER) return BodyType.ENLIGHTENMENT_CENTER; - if (type == RobotType.POLITICIAN) return BodyType.POLITICIAN; - if (type == RobotType.SLANDERER) return BodyType.SLANDERER; - if (type == RobotType.MUCKRAKER) return BodyType.MUCKRAKER; + if (type == RobotType.ARCHON) return BodyType.ARCHON; + if (type == RobotType.LABORATORY) return BodyType.LABORATORY; + if (type == RobotType.WATCHTOWER) return BodyType.WATCHTOWER; + if (type == RobotType.MINER) return BodyType.MINER; + if (type == RobotType.BUILDER) return BodyType.BUILDER; + if (type == RobotType.SOLDIER) return BodyType.SOLDIER; + if (type == RobotType.SAGE) return BodyType.SAGE; return Byte.MIN_VALUE; } @@ -320,8 +336,8 @@ public void makeGameFooter(Team winner) { public class MatchMaker { private TIntArrayList movedIDs; // ints // VecTable for movedLocs in Round - private TIntArrayList movedLocsXs; - private TIntArrayList movedLocsYs; + private TIntArrayList movedLocsX; + private TIntArrayList movedLocsY; // SpawnedBodyTable for spawnedBodies private TIntArrayList spawnedBodiesRobotIDs; @@ -329,7 +345,6 @@ public class MatchMaker { private TByteArrayList spawnedBodiesTypes; private TIntArrayList spawnedBodiesLocsXs; //For locs private TIntArrayList spawnedBodiesLocsYs; //For locs - private TIntArrayList spawnedBodiesInfluences; private TIntArrayList diedIDs; // ints @@ -337,11 +352,21 @@ public class MatchMaker { private TByteArrayList actions; // Actions private TIntArrayList actionTargets; // ints (IDs) + private TIntArrayList leadDropLocsX; + private TIntArrayList leadDropLocsY; + private TIntArrayList leadDropValues; + + private TIntArrayList goldDropLocsX; + private TIntArrayList goldDropLocsY; + private TIntArrayList goldDropValues; + // Round statistics private TIntArrayList teamIDs; - private TIntArrayList teamVotes; - private TIntArrayList teamBidderIDs; - private TIntArrayList teamNumBuffs; + private TIntArrayList teamLeadChanges; + private TIntArrayList teamGoldChanges; + + private TIntArrayList indicatorStringIDs; + private ArrayList indicatorStrings; // Indicator dots with locations and RGB values private TIntArrayList indicatorDotIDs; @@ -365,27 +390,30 @@ public class MatchMaker { private TIntArrayList bytecodeIDs; private TIntArrayList bytecodesUsed; - // Used to write logs. - private final ByteArrayOutputStream logger; - public MatchMaker() { this.movedIDs = new TIntArrayList(); - this.movedLocsXs = new TIntArrayList(); - this.movedLocsYs = new TIntArrayList(); + this.movedLocsX = new TIntArrayList(); + this.movedLocsY = new TIntArrayList(); this.spawnedBodiesRobotIDs = new TIntArrayList(); this.spawnedBodiesTeamIDs = new TByteArrayList(); this.spawnedBodiesTypes = new TByteArrayList(); this.spawnedBodiesLocsXs = new TIntArrayList(); this.spawnedBodiesLocsYs = new TIntArrayList(); - this.spawnedBodiesInfluences = new TIntArrayList(); this.diedIDs = new TIntArrayList(); this.actionIDs = new TIntArrayList(); this.actions = new TByteArrayList(); this.actionTargets = new TIntArrayList(); + this.leadDropLocsX = new TIntArrayList(); + this.leadDropLocsY = new TIntArrayList(); + this.leadDropValues = new TIntArrayList(); + this.goldDropLocsX = new TIntArrayList(); + this.goldDropLocsY = new TIntArrayList(); + this.goldDropValues = new TIntArrayList(); this.teamIDs = new TIntArrayList(); - this.teamVotes = new TIntArrayList(); - this.teamBidderIDs = new TIntArrayList(); - this.teamNumBuffs = new TIntArrayList(); + this.teamLeadChanges = new TIntArrayList(); + this.teamGoldChanges = new TIntArrayList(); + this.indicatorStringIDs = new TIntArrayList(); + this.indicatorStrings = new ArrayList<>(); this.indicatorDotIDs = new TIntArrayList(); this.indicatorDotLocsX = new TIntArrayList(); this.indicatorDotLocsY = new TIntArrayList(); @@ -402,7 +430,6 @@ public MatchMaker() { this.indicatorLineRGBsGreen = new TIntArrayList(); this.bytecodeIDs = new TIntArrayList(); this.bytecodesUsed = new TIntArrayList(); - this.logger = new ByteArrayOutputStream(); } public void makeMatchHeader(LiveMap gameMap) { @@ -472,13 +499,13 @@ public void makeMatchFooter(Team winTeam, int totalRounds, List { // The bodies that spawned @@ -486,24 +513,21 @@ public void makeRound(int roundNum) { int spawnedBodiesRobotIDsP = SpawnedBodyTable.createRobotIDsVector(builder, spawnedBodiesRobotIDs.toArray()); int spawnedBodiesTeamIDsP = SpawnedBodyTable.createTeamIDsVector(builder, spawnedBodiesTeamIDs.toArray()); int spawnedBodiesTypesP = SpawnedBodyTable.createTypesVector(builder, spawnedBodiesTypes.toArray()); - int spawnedBodiesInfluencesP = SpawnedBodyTable.createInfluencesVector(builder, spawnedBodiesInfluences.toArray()); SpawnedBodyTable.startSpawnedBodyTable(builder); SpawnedBodyTable.addLocs(builder, spawnedBodiesLocsP); SpawnedBodyTable.addRobotIDs(builder, spawnedBodiesRobotIDsP); SpawnedBodyTable.addTeamIDs(builder, spawnedBodiesTeamIDsP); SpawnedBodyTable.addTypes(builder, spawnedBodiesTypesP); - SpawnedBodyTable.addInfluences(builder, spawnedBodiesInfluencesP); int spawnedBodiesP = SpawnedBodyTable.endSpawnedBodyTable(builder); // Round statistics int teamIDsP = Round.createTeamIDsVector(builder, teamIDs.toArray()); - int teamVotesP = Round.createTeamVotesVector(builder, teamVotes.toArray()); - int teamBidderIDsP = Round.createTeamBidderIDsVector(builder, teamBidderIDs.toArray()); - int teamNumBuffsP = Round.createTeamNumBuffsVector(builder, teamNumBuffs.toArray()); + int teamLeadChangesP = Round.createTeamLeadChangesVector(builder, teamLeadChanges.toArray()); + int teamGoldChangesP = Round.createTeamGoldChangesVector(builder, teamGoldChanges.toArray()); // The bodies that moved int movedIDsP = Round.createMovedIDsVector(builder, movedIDs.toArray()); - int movedLocsP = createVecTable(builder, movedLocsXs, movedLocsYs); + int movedLocsP = createVecTable(builder, movedLocsX, movedLocsY); // The bodies that died int diedIDsP = Round.createDiedIDsVector(builder, diedIDs.toArray()); @@ -513,6 +537,20 @@ public void makeRound(int roundNum) { int actionsP = Round.createActionsVector(builder, actions.toArray()); int actionTargetsP = Round.createActionTargetsVector(builder, actionTargets.toArray()); + // The lead and gold dropped + int leadDropLocsP = createVecTable(builder, leadDropLocsX, leadDropLocsY); + int leadDropValuesP = Round.createLeadDropValuesVector(builder, leadDropValues.toArray()); + int goldDropLocsP = createVecTable(builder, goldDropLocsX, goldDropLocsY); + int goldDropValuesP = Round.createGoldDropValuesVector(builder, goldDropValues.toArray()); + + // The indicator strings that were set + int indicatorStringIDsP = Round.createIndicatorStringIDsVector(builder, indicatorStringIDs.toArray()); + TIntArrayList indicatorStringsIntList = new TIntArrayList(); + for (String s : indicatorStrings) { + indicatorStringsIntList.add(builder.createString(s)); + } + int indicatorStringsP = Round.createIndicatorStringsVector(builder, indicatorStringsIntList.toArray()); + // The indicator dots that were set int indicatorDotIDsP = Round.createIndicatorDotIDsVector(builder, indicatorDotIDs.toArray()); int indicatorDotLocsP = createVecTable(builder, indicatorDotLocsX, indicatorDotLocsY); @@ -528,13 +566,10 @@ public void makeRound(int roundNum) { int bytecodeIDsP = Round.createBytecodeIDsVector(builder, bytecodeIDs.toArray()); int bytecodesUsedP = Round.createBytecodesUsedVector(builder, bytecodesUsed.toArray()); - int logsP = builder.createString(ByteBuffer.wrap(logs)); - Round.startRound(builder); Round.addTeamIDs(builder, teamIDsP); - Round.addTeamVotes(builder, teamVotesP); - Round.addTeamBidderIDs(builder, teamBidderIDsP); - Round.addTeamNumBuffs(builder, teamNumBuffsP); + Round.addTeamLeadChanges(builder, teamLeadChangesP); + Round.addTeamGoldChanges(builder, teamGoldChangesP); Round.addMovedIDs(builder, movedIDsP); Round.addMovedLocs(builder, movedLocsP); Round.addSpawnedBodies(builder, spawnedBodiesP); @@ -542,6 +577,12 @@ public void makeRound(int roundNum) { Round.addActionIDs(builder, actionIDsP); Round.addActions(builder, actionsP); Round.addActionTargets(builder, actionTargetsP); + Round.addLeadDropLocations(builder, leadDropLocsP); + Round.addLeadDropValues(builder, leadDropValuesP); + Round.addGoldDropLocations(builder, goldDropLocsP); + Round.addGoldDropValues(builder, goldDropValuesP); + Round.addIndicatorStringIDs(builder, indicatorStringIDsP); + Round.addIndicatorStrings(builder, indicatorStringsP); Round.addIndicatorDotIDs(builder, indicatorDotIDsP); Round.addIndicatorDotLocs(builder, indicatorDotLocsP); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsP); @@ -552,7 +593,6 @@ public void makeRound(int roundNum) { Round.addRoundID(builder, roundNum); Round.addBytecodeIDs(builder, bytecodeIDsP); Round.addBytecodesUsed(builder, bytecodesUsedP); - Round.addLogs(builder, logsP); int round = Round.endRound(builder); return EventWrapper.createEventWrapper(builder, Event.Round, round); }); @@ -563,14 +603,14 @@ public void makeRound(int roundNum) { /** * @return an outputstream that will be baked into the output file */ - public OutputStream getOut() { - return logger; - } + // public OutputStream getOut() { + // return logger; + // } public void addMoved(int id, MapLocation newLocation) { movedIDs.add(id); - movedLocsXs.add(newLocation.x); - movedLocsYs.add(newLocation.y); + movedLocsX.add(newLocation.x); + movedLocsY.add(newLocation.y); } public void addDied(int id) { @@ -583,11 +623,30 @@ public void addAction(int userID, byte action, int targetID) { actionTargets.add(targetID); } - public void addTeamInfo(Team team, int vote, int bidderID, int numBuffs) { + public void addLeadDrop(MapLocation location, int value) { + leadDropLocsX.add(location.x); + leadDropLocsY.add(location.y); + leadDropValues.add(value); + } + + public void addGoldDrop(MapLocation location, int value) { + goldDropLocsX.add(location.x); + goldDropLocsY.add(location.y); + goldDropValues.add(value); + } + + public void addTeamInfo(Team team, int leadChange, int goldChange) { teamIDs.add(TeamMapping.id(team)); - teamVotes.add(vote); - teamBidderIDs.add(bidderID); - teamNumBuffs.add(numBuffs); + teamLeadChanges.add(leadChange); + teamGoldChanges.add(goldChange); + } + + public void addIndicatorString(int id, String string) { + if (!showIndicators) { + return; + } + indicatorStringIDs.add(id); + indicatorStrings.add(string); } public void addIndicatorDot(int id, MapLocation loc, int red, int green, int blue) { @@ -627,27 +686,32 @@ public void addSpawnedRobot(InternalRobot robot) { spawnedBodiesLocsYs.add(robot.getLocation().y); spawnedBodiesTeamIDs.add(TeamMapping.id(robot.getTeam())); spawnedBodiesTypes.add(FlatHelpers.getBodyTypeFromRobotType(robot.getType())); - spawnedBodiesInfluences.add(robot.getInfluence()); } private void clearData() { movedIDs.clear(); - movedLocsXs.clear(); - movedLocsYs.clear(); + movedLocsX.clear(); + movedLocsY.clear(); spawnedBodiesRobotIDs.clear(); spawnedBodiesTeamIDs.clear(); spawnedBodiesTypes.clear(); spawnedBodiesLocsXs.clear(); spawnedBodiesLocsYs.clear(); - spawnedBodiesInfluences.clear(); diedIDs.clear(); actionIDs.clear(); actions.clear(); actionTargets.clear(); + leadDropLocsX.clear(); + leadDropLocsY.clear(); + leadDropValues.clear(); + goldDropLocsX.clear(); + goldDropLocsY.clear(); + goldDropValues.clear(); teamIDs.clear(); - teamVotes.clear(); - teamBidderIDs.clear(); - teamNumBuffs.clear(); + teamLeadChanges.clear(); + teamGoldChanges.clear(); + indicatorStringIDs.clear(); + indicatorStrings.clear(); indicatorDotIDs.clear(); indicatorDotLocsX.clear(); indicatorDotLocsY.clear(); From a15935ed347748b7f0a67e3b1bee73ccb0c8c102 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 21:00:12 -0600 Subject: [PATCH 214/413] brought logs back, but not to client --- .../src/main/battlecode/server/GameMaker.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index b7d6b6e9..f9414bec 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -390,6 +390,9 @@ public class MatchMaker { private TIntArrayList bytecodeIDs; private TIntArrayList bytecodesUsed; + // Used to write logs. + private final ByteArrayOutputStream logger; + public MatchMaker() { this.movedIDs = new TIntArrayList(); this.movedLocsX = new TIntArrayList(); @@ -430,6 +433,7 @@ public MatchMaker() { this.indicatorLineRGBsGreen = new TIntArrayList(); this.bytecodeIDs = new TIntArrayList(); this.bytecodesUsed = new TIntArrayList(); + this.logger = new ByteArrayOutputStream(); } public void makeMatchHeader(LiveMap gameMap) { @@ -499,13 +503,13 @@ public void makeMatchFooter(Team winTeam, int totalRounds, List { // The bodies that spawned @@ -603,9 +607,9 @@ public void makeRound(int roundNum) { /** * @return an outputstream that will be baked into the output file */ - // public OutputStream getOut() { - // return logger; - // } + public OutputStream getOut() { + return logger; + } public void addMoved(int id, MapLocation newLocation) { movedIDs.add(id); From 1fac313245f8a62a32bb0ca5f20a2ada7b4a78b2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 21:29:39 -0600 Subject: [PATCH 215/413] RobotTypeTaglet --- .../main/battlecode/doc/RobotTypeTaglet.java | 20 +++++++++---------- .../battlecode/world/RobotControllerImpl.java | 15 +++++++++++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/engine/src/main/battlecode/doc/RobotTypeTaglet.java b/engine/src/main/battlecode/doc/RobotTypeTaglet.java index 00dd0cd6..2cdb93c5 100644 --- a/engine/src/main/battlecode/doc/RobotTypeTaglet.java +++ b/engine/src/main/battlecode/doc/RobotTypeTaglet.java @@ -177,21 +177,21 @@ public String docFor(String variant) { StringBuilder builder = new StringBuilder(); try { - appendField(builder, rt, "convictionRatio"); + appendField(builder, rt, "buildCostLead"); + builder.append("
"); + appendField(builder, rt, "buildCostGold"); builder.append("
"); appendField(builder, rt, "actionCooldown"); builder.append("
"); - appendField(builder, rt, "actionRadiusSquared"); + appendField(builder, rt, "movementCooldown"); builder.append("
"); - appendField(builder, rt, "sensorRadiusSquared"); + appendField(builder, rt, "health"); builder.append("
"); - appendField(builder, rt, "detectionRadiusSquared"); - - if (rt.spawnSource != null) { - builder.append("
"); - appendField(builder, rt, "spawnSource"); - // appendField(builder, rt, "cost"); Cost is variable in 2021 - } + appendField(builder, rt, "damage"); + builder.append("
"); + appendField(builder, rt, "actionRadiusSquared"); + builder.append("
"); + appendField(builder, rt, "visionRadiusSquared"); if (rt.bytecodeLimit != 0) { builder.append("
"); diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 7983ab7a..1d90bde7 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -127,6 +127,10 @@ private InternalRobot getRobotByID(int id) { return this.gameWorld.getObjectInfo().getRobotByID(id); } + private int locationToInt(MapLocation loc) { + return loc.x + loc.y * this.gameWorld.getGameMap().getWidth(); + } + // *********************************** // ****** GENERAL VISION METHODS ***** // *********************************** @@ -474,12 +478,17 @@ public void envision(AnomalyType anomaly) throws GameActionException { switch (anomaly) { case ABYSS: this.gameWorld.causeAbyssSage(this.robot); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_ABYSS, locationToInt(this.robot.getLocation())); + break; case CHARGE: this.gameWorld.causeChargeSage(this.robot); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_CHARGE, locationToInt(this.robot.getLocation())); + break; case FURY: this.gameWorld.causeFurySage(this.robot); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_FURY, locationToInt(this.robot.getLocation())); + break; } - this.gameWorld.getMatchMaker().addAction(getID(), Action.ENVISION, anomaly); } // ***************************** @@ -553,7 +562,7 @@ public void mineLead(MapLocation loc) throws GameActionException { this.robot.addActionCooldownTurns(getType().actionCooldown); this.gameWorld.setLead(loc, this.gameWorld.getLead(loc) - 1); this.gameWorld.getTeamInfo().addLead(getTeam(), 1); - this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, loc); + this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, locationToInt(loc)); } private void assertCanMineGold(MapLocation loc) throws GameActionException { @@ -584,7 +593,7 @@ public void mineGold(MapLocation loc) throws GameActionException { this.robot.addActionCooldownTurns(getType().actionCooldown); this.gameWorld.setGold(loc, this.gameWorld.getGold(loc) - 1); this.gameWorld.getTeamInfo().addGold(getTeam(), 1); - this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, loc); + this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, locationToInt(loc)); } // ************************* From f6451abf0d1fc99e34e5d99d7beec57cd82c03ad Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 21:38:19 -0600 Subject: [PATCH 216/413] FlatHelpers and maps --- .../src/main/battlecode/util/FlatHelpers.java | 44 ++++++++++++------- .../main/battlecode/world/maps/Circle.java | 9 ++-- .../battlecode/world/maps/MapTestSmall.java | 4 +- .../main/battlecode/world/maps/Quadrants.java | 16 +++---- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/engine/src/main/battlecode/util/FlatHelpers.java b/engine/src/main/battlecode/util/FlatHelpers.java index 983c714d..ed1f44b9 100644 --- a/engine/src/main/battlecode/util/FlatHelpers.java +++ b/engine/src/main/battlecode/util/FlatHelpers.java @@ -23,14 +23,20 @@ public class FlatHelpers { public static RobotType getRobotTypeFromBodyType(byte bodyType) { switch (bodyType) { - case BodyType.ENLIGHTENMENT_CENTER: - return RobotType.ENLIGHTENMENT_CENTER; - case BodyType.POLITICIAN: - return RobotType.POLITICIAN; - case BodyType.SLANDERER: - return RobotType.SLANDERER; - case BodyType.MUCKRAKER: - return RobotType.MUCKRAKER; + case BodyType.ARCHON: + return RobotType.ARCHON; + case BodyType.LABORATORY: + return RobotType.LABORATORY; + case BodyType.WATCHTOWER: + return RobotType.WATCHTOWER; + case BodyType.MINER: + return RobotType.MINER; + case BodyType.BUILDER: + return RobotType.BUILDER; + case BodyType.SOLDIER: + return RobotType.SOLDIER; + case BodyType.SAGE: + return RobotType.SAGE; default: throw new RuntimeException("No robot type for: " + bodyType); } @@ -38,14 +44,20 @@ public static RobotType getRobotTypeFromBodyType(byte bodyType) { public static byte getBodyTypeFromRobotType(RobotType type) { switch (type) { - case ENLIGHTENMENT_CENTER: - return BodyType.ENLIGHTENMENT_CENTER; - case POLITICIAN: - return BodyType.POLITICIAN; - case SLANDERER: - return BodyType.SLANDERER; - case MUCKRAKER: - return BodyType.MUCKRAKER; + case ARCHON: + return BodyType.ARCHON; + case LABORATORY: + return BodyType.LABORATORY; + case WATCHTOWER: + return BodyType.WATCHTOWER; + case MINER: + return BodyType.MINER; + case BUILDER: + return BodyType.BUILDER; + case SOLDIER: + return BodyType.SOLDIER; + case SAGE: + return BodyType.SAGE; default: throw new RuntimeException("No body type for: " + type); } diff --git a/engine/src/main/battlecode/world/maps/Circle.java b/engine/src/main/battlecode/world/maps/Circle.java index a0abf931..6699635f 100644 --- a/engine/src/main/battlecode/world/maps/Circle.java +++ b/engine/src/main/battlecode/world/maps/Circle.java @@ -41,16 +41,13 @@ public static void makeCircle() throws IOException { final int half = 31; final MapLocation center = new MapLocation(half, half); MapBuilder mapBuilder = new MapBuilder(mapName, 2*half+1, 2*half+1, 25016, 12865, 116896); - mapBuilder.addSymmetricEnlightenmentCenter(20, 20); - mapBuilder.addSymmetricEnlightenmentCenter(20, 2*half-20); - mapBuilder.addSymmetricNeutralEnlightenmentCenter(0, 0, 300); - mapBuilder.addSymmetricNeutralEnlightenmentCenter(0, 2*half, 300); + mapBuilder.addSymmetricArchon(20, 20); + mapBuilder.addSymmetricArchon(20, 2*half-20); for (int i = 0; i <= half; i++) { for (int j = 0; j <= 2*half; j++) { int d = new MapLocation(i, j).distanceSquaredTo(center); - mapBuilder.setSymmetricPassability(i, j, - 1.0 - 0.5 * Math.exp(-0.0002 * (d - 500) * (d - 500))); + mapBuilder.setSymmetricLead(i, j, d); } } diff --git a/engine/src/main/battlecode/world/maps/MapTestSmall.java b/engine/src/main/battlecode/world/maps/MapTestSmall.java index 4cf150bb..a89299b9 100644 --- a/engine/src/main/battlecode/world/maps/MapTestSmall.java +++ b/engine/src/main/battlecode/world/maps/MapTestSmall.java @@ -39,12 +39,12 @@ public static void main(String[] args) { public static void makeSimple() throws IOException { MapBuilder mapBuilder = new MapBuilder(mapName, 32, 32, 10000, 23921, 30); - mapBuilder.addSymmetricEnlightenmentCenter(5, 5); + mapBuilder.addSymmetricArchon(5, 5); Random random = new Random(6147); for (int i = 0; i < mapBuilder.width / 2; i++) { for (int j = 0; j < mapBuilder.height; j++) { - mapBuilder.setSymmetricPassability(i, j, random.nextDouble()*0.9+0.1); + mapBuilder.setSymmetricLead(i, j, random.nextInt(100)); } } diff --git a/engine/src/main/battlecode/world/maps/Quadrants.java b/engine/src/main/battlecode/world/maps/Quadrants.java index a041ee0c..25db0fa2 100644 --- a/engine/src/main/battlecode/world/maps/Quadrants.java +++ b/engine/src/main/battlecode/world/maps/Quadrants.java @@ -6,6 +6,7 @@ import battlecode.world.GameMapIO; import battlecode.world.LiveMap; import battlecode.world.MapBuilder; +import battlecode.world.MapSymmetry; import battlecode.world.TestMapBuilder; import battlecode.common.GameConstants; @@ -39,16 +40,15 @@ public static void main(String[] args) { public static void makeQuadrants() throws IOException { MapBuilder mapBuilder = new MapBuilder(mapName, 40, 40, 13265, 17387, 215957); - mapBuilder.setSymmetry(MapBuilder.MapSymmetry.rotational); - mapBuilder.addSymmetricEnlightenmentCenter(5, 5); - mapBuilder.addSymmetricEnlightenmentCenter(10, 30); - mapBuilder.addSymmetricNeutralEnlightenmentCenter(18, 19, 500); + mapBuilder.setSymmetry(MapSymmetry.ROTATIONAL); + mapBuilder.addSymmetricArchon(5, 5); + mapBuilder.addSymmetricArchon(10, 30); for (int i = 5; i <= 15; i++) { - mapBuilder.setSymmetricPassability(i, 15, 0.1); - mapBuilder.setSymmetricPassability(i, 25, 0.1); - mapBuilder.setSymmetricPassability(15, i, 0.1); - mapBuilder.setSymmetricPassability(25, i, 0.1); + mapBuilder.setSymmetricLead(i, 15, 10); + mapBuilder.setSymmetricLead(i, 25, 10); + mapBuilder.setSymmetricLead(15, i, 10); + mapBuilder.setSymmetricLead(25, i, 10); } mapBuilder.saveMap(outputDirectory); From a95f14b6ba31a9343898ebbb8b7472178d4ea122 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 21:39:14 -0600 Subject: [PATCH 217/413] GameWorld bugfix --- engine/src/main/battlecode/world/GameWorld.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 7f9fbbe7..da7b7cf6 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -200,7 +200,7 @@ public int getLead(MapLocation loc) { return this.lead[locationToIndex(loc)]; } - public int setLead(MapLocation loc, int amount) { + public void setLead(MapLocation loc, int amount) { this.lead[locationToIndex(loc)] = amount; } @@ -208,7 +208,7 @@ public int getGold(MapLocation loc) { return this.gold[locationToIndex(loc)]; } - public int setGold(MapLocation loc, int amount) { + public void setGold(MapLocation loc, int amount) { this.gold[locationToIndex(loc)] = amount; } From 96c80e7d60a4dc85098f171f88f0518f4b2f3ba2 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 21:47:16 -0600 Subject: [PATCH 218/413] engine compiles now? fix misc errors --- .../sample/testplayeractions/RobotPlayer.java | 2 +- .../test/battlecode/server/GameMakerTest.java | 12 ++-- .../test/battlecode/world/GenerateMaps.java | 8 +-- .../src/test/battlecode/world/TestGame.java | 5 +- .../test/battlecode/world/TestMapBuilder.java | 55 +++++-------------- 5 files changed, 27 insertions(+), 55 deletions(-) diff --git a/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java b/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java index 297b0481..28a5331b 100644 --- a/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java +++ b/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java @@ -11,7 +11,7 @@ public class RobotPlayer { public static void run(RobotController rc) throws GameActionException { rc.resign(); - rc.senseNearbyRobots(); + rc.seeNearbyRobots(); System.out.println("I shouldn't overflow!"); } diff --git a/engine/src/test/battlecode/server/GameMakerTest.java b/engine/src/test/battlecode/server/GameMakerTest.java index 6cf73e5e..8b20a219 100644 --- a/engine/src/test/battlecode/server/GameMakerTest.java +++ b/engine/src/test/battlecode/server/GameMakerTest.java @@ -44,12 +44,12 @@ public void testStateExceptions() { gm.makeGameFooter(Team.A); } - @Test(expected=RuntimeException.class) - public void testMatchStateExceptions() { - GameMaker gm = new GameMaker(info, null, true); - gm.makeGameHeader(); - gm.getMatchMaker().makeMatchFooter(Team.A, 23, new ArrayList<>()); - } + // @Test(expected=RuntimeException.class) + // public void testMatchStateExceptions() { + // GameMaker gm = new GameMaker(info, null, true); + // gm.makeGameHeader(); + // gm.getMatchMaker().makeMatchFooter(Team.A, 23, new ArrayList<>()); + // } // @Test // public void fullReasonableGame() throws Exception { diff --git a/engine/src/test/battlecode/world/GenerateMaps.java b/engine/src/test/battlecode/world/GenerateMaps.java index a55779fd..0d340cb6 100644 --- a/engine/src/test/battlecode/world/GenerateMaps.java +++ b/engine/src/test/battlecode/world/GenerateMaps.java @@ -21,20 +21,18 @@ public class GenerateMaps { @Test public void makeSimple() throws IOException { - LiveMap map = new TestMapBuilder("maptest", 0, 0, 100, 100, 30, 3000) - .addEnlightenmentCenter( + LiveMap map = new TestMapBuilder("maptest", 0, 0, 100, 100, 30) + .addArchon( 0, Team.A, - GameConstants.INITIAL_ENLIGHTENMENT_CENTER_INFLUENCE, new MapLocation( 1, 1 ) ) - .addEnlightenmentCenter( + .addArchon( 1, Team.B, - GameConstants.INITIAL_ENLIGHTENMENT_CENTER_INFLUENCE, new MapLocation( 99, 99 diff --git a/engine/src/test/battlecode/world/TestGame.java b/engine/src/test/battlecode/world/TestGame.java index 8092aecb..b83ccc61 100644 --- a/engine/src/test/battlecode/world/TestGame.java +++ b/engine/src/test/battlecode/world/TestGame.java @@ -67,10 +67,9 @@ public int getOriginY() { * @param y y coordinate for the spawn * @param type type of the robot to spawn * @param team team of the robot to spawn - * @param influence influence of the robot to spawn */ - public int spawn(int x, int y, RobotType type, Team team, int influence) { - return world.spawnRobot(null, type, new MapLocation(x, y), team, influence); + public int spawn(int x, int y, RobotType type, Team team) { + return world.spawnRobot(type, new MapLocation(x, y), team); } /** diff --git a/engine/src/test/battlecode/world/TestMapBuilder.java b/engine/src/test/battlecode/world/TestMapBuilder.java index 6a84b76e..4cf495fb 100644 --- a/engine/src/test/battlecode/world/TestMapBuilder.java +++ b/engine/src/test/battlecode/world/TestMapBuilder.java @@ -8,58 +8,33 @@ * Lets maps be built easily, for testing purposes. */ public class TestMapBuilder { - private String name; - private MapLocation origin; - private int width; - private int height; - private int seed; - private int rounds; - private double[] passabilityArray; + private MapBuilder mapBuilder; - private List bodies; - - public TestMapBuilder(String name, int oX, int oY, int width, int height, int seed, int rounds) { - this(name, new MapLocation(oX, oY), width, height, seed, rounds); - } - - public TestMapBuilder(String name, MapLocation origin, int width, int height, int seed, int rounds) { - this.name = name; - this.origin = origin; - this.width = width; - this.height = height; - this.seed = seed; - this.bodies = new ArrayList<>(); + public TestMapBuilder(String name, int oX, int oY, int width, int height, int seed) { + this.mapBuilder = new MapBuilder(name, width, height, oX, oY, seed); } - public TestMapBuilder addEnlightenmentCenter(int id, Team team, int influence, MapLocation loc) { - bodies.add(new RobotInfo( - id, - team, - RobotType.ENLIGHTENMENT_CENTER, - influence, - 0, - loc - )); - + public TestMapBuilder addArchon(int id, Team team, MapLocation loc) { + this.mapBuilder.addArchon(id, team, loc); return this; } - public TestMapBuilder setPassability() { - this.passabilityArray = new double[width * height]; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - this.passabilityArray[i + j * width] = (i * j + i + j) / (i * j + 1); - } - } + public TestMapBuilder setRubble(int x, int y, int value) { + this.mapBuilder.setRubble(x, y, value); + return this; + } + + public TestMapBuilder setLead(int x, int y, int value) { + this.mapBuilder.setLead(x, y, value); return this; } - public TestMapBuilder addBody(RobotInfo info) { - bodies.add(info); + public TestMapBuilder addAnomalyScheduleEntry(int round, AnomalyType anomaly) { + this.mapBuilder.addAnomalyScheduleEntry(round, anomaly); return this; } public LiveMap build() { - return new LiveMap(width, height, origin, seed, GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, name, bodies.toArray(new RobotInfo[bodies.size()]), passabilityArray); + return this.mapBuilder.build(); } } From 3f5635fd31a56545e91cb633802b6fe43040556f Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 22:12:26 -0600 Subject: [PATCH 219/413] misc, edited RobotPlayer, remove old maps --- .../battlecode/schema/BodyTypeMetadata.java | 74 ++++++++------- .../src/main/battlecode/server/GameMaker.java | 12 +-- .../battlecode/world/resources/AmidstWe.map21 | Bin 33048 -> 0 bytes .../world/resources/Andromeda.map21 | Bin 32568 -> 0 bytes .../battlecode/world/resources/Arena.map21 | Bin 8496 -> 0 bytes .../world/resources/BadSnowflake.map21 | Bin 20312 -> 0 bytes .../world/resources/BattleCode.map21 | Bin 23640 -> 0 bytes .../world/resources/BattleCodeToo.map21 | Bin 23640 -> 0 bytes .../world/resources/BlobWithLegs.map21 | Bin 33080 -> 0 bytes .../battlecode/world/resources/Blotches.map21 | Bin 16664 -> 0 bytes .../main/battlecode/world/resources/Bog.map21 | Bin 8464 -> 0 bytes .../battlecode/world/resources/Branches.map21 | Bin 33080 -> 0 bytes .../world/resources/ButtonsAndBows.map21 | Bin 32976 -> 0 bytes .../battlecode/world/resources/CToE.map21 | Bin 16616 -> 0 bytes .../battlecode/world/resources/Chevron.map21 | Bin 16728 -> 0 bytes .../battlecode/world/resources/Circles.map21 | Bin 16656 -> 0 bytes .../battlecode/world/resources/Corridor.map21 | Bin 10872 -> 0 bytes .../main/battlecode/world/resources/Cow.map21 | Bin 32344 -> 0 bytes .../world/resources/CowTwister.map21 | Bin 16624 -> 0 bytes .../world/resources/CringyAsF.map21 | Bin 19224 -> 0 bytes .../world/resources/CrossStitch.map21 | Bin 33048 -> 0 bytes .../world/resources/CrownJewels.map21 | Bin 16696 -> 0 bytes .../world/resources/EggCarton.map21 | Bin 15904 -> 0 bytes .../world/resources/ExesAndOhs.map21 | Bin 21816 -> 0 bytes .../world/resources/Extensions.map21 | Bin 33080 -> 0 bytes .../world/resources/FindYourWay.map21 | Bin 16664 -> 0 bytes .../world/resources/FiveOfHearts.map21 | Bin 33080 -> 0 bytes .../battlecode/world/resources/Flawars.map21 | Bin 18736 -> 0 bytes .../world/resources/FrogOrBath.map21 | Bin 8504 -> 0 bytes .../world/resources/GetShrekt.map21 | Bin 33080 -> 0 bytes .../battlecode/world/resources/Goldfish.map21 | Bin 18960 -> 0 bytes .../battlecode/world/resources/Gridlock.map21 | Bin 33080 -> 0 bytes .../world/resources/HappyBoba.map21 | Bin 10592 -> 0 bytes .../world/resources/HexesAndOhms.map21 | Bin 24856 -> 0 bytes .../world/resources/Hourglass.map21 | Bin 18712 -> 0 bytes .../battlecode/world/resources/Illusion.map21 | Bin 10360 -> 0 bytes .../resources/InaccurateBritishFlag.map21 | Bin 18752 -> 0 bytes .../world/resources/JerryIsEvil.map21 | Bin 25912 -> 0 bytes .../battlecode/world/resources/Legends.map21 | Bin 20304 -> 0 bytes .../battlecode/world/resources/Licc.map21 | Bin 28944 -> 0 bytes .../world/resources/MainCampus.map21 | Bin 19224 -> 0 bytes .../battlecode/world/resources/Mario.map21 | Bin 15184 -> 0 bytes .../battlecode/world/resources/Maze.map21 | Bin 16504 -> 0 bytes .../world/resources/Misdirection.map21 | Bin 20312 -> 0 bytes .../world/resources/Networking.map21 | Bin 16664 -> 0 bytes .../world/resources/NextHouse.map21 | Bin 16592 -> 0 bytes .../world/resources/NoInternet.map21 | Bin 12568 -> 0 bytes .../world/resources/NotAPuzzle.map21 | Bin 33080 -> 0 bytes .../world/resources/OneCallAway.map21 | Bin 13112 -> 0 bytes .../world/resources/PaperWindmill.map21 | Bin 18784 -> 0 bytes .../world/resources/Punctuation.map21 | Bin 24856 -> 0 bytes .../battlecode/world/resources/Radial.map21 | Bin 11224 -> 0 bytes .../battlecode/world/resources/Rainbow.map21 | Bin 13032 -> 0 bytes .../world/resources/Randomized.map21 | Bin 20352 -> 0 bytes .../battlecode/world/resources/Saturn.map21 | Bin 17152 -> 0 bytes .../battlecode/world/resources/SeaFloor.map21 | Bin 11832 -> 0 bytes .../battlecode/world/resources/Sediment.map21 | Bin 19480 -> 0 bytes .../world/resources/SlowMusic.map21 | Bin 24888 -> 0 bytes .../battlecode/world/resources/Smile.map21 | Bin 8424 -> 0 bytes .../world/resources/Snowflake.map21 | Bin 10320 -> 0 bytes .../world/resources/SpaceInvaders.map21 | Bin 12568 -> 0 bytes .../battlecode/world/resources/Star.map21 | Bin 10072 -> 0 bytes .../battlecode/world/resources/Stonks.map21 | Bin 25944 -> 0 bytes .../world/resources/Superposition.map21 | Bin 20312 -> 0 bytes .../world/resources/Surprised.map21 | Bin 33048 -> 0 bytes ...MapEditorIsSuperiorToGoogleSheetsEom.map21 | Bin 19440 -> 0 bytes .../resources/TheSnackThatSmilesBack.map21 | Bin 33056 -> 0 bytes .../world/resources/TicTacTie.map21 | Bin 33080 -> 0 bytes .../battlecode/world/resources/Tiger.map21 | Bin 33144 -> 0 bytes .../world/resources/UnbrandedWordGame.map21 | Bin 33088 -> 0 bytes .../world/resources/VideoGames.map21 | Bin 24888 -> 0 bytes .../world/resources/WhatISeeInMyDreams.map21 | Bin 13160 -> 0 bytes .../battlecode/world/resources/Yoda.map21 | Bin 33072 -> 0 bytes .../main/battlecode/world/resources/Z.map21 | Bin 33040 -> 0 bytes .../battlecode/world/resources/Zodiac.map21 | Bin 24880 -> 0 bytes .../battlecode/world/resources/circle.map21 | Bin 32056 -> 0 bytes .../world/resources/maptestsmall.map21 | Bin 8400 -> 0 bytes .../world/resources/quadrants.map21 | Bin 13080 -> 0 bytes .../main/examplefuncsplayer/RobotPlayer.java | 89 +++++++++--------- schema/battlecode.fbs | 8 +- .../battlecode/schema/BodyTypeMetadata.java | 74 ++++++++------- 81 files changed, 135 insertions(+), 122 deletions(-) delete mode 100644 engine/src/main/battlecode/world/resources/AmidstWe.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Andromeda.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Arena.map21 delete mode 100644 engine/src/main/battlecode/world/resources/BadSnowflake.map21 delete mode 100644 engine/src/main/battlecode/world/resources/BattleCode.map21 delete mode 100644 engine/src/main/battlecode/world/resources/BattleCodeToo.map21 delete mode 100644 engine/src/main/battlecode/world/resources/BlobWithLegs.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Blotches.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Bog.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Branches.map21 delete mode 100644 engine/src/main/battlecode/world/resources/ButtonsAndBows.map21 delete mode 100644 engine/src/main/battlecode/world/resources/CToE.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Chevron.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Circles.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Corridor.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Cow.map21 delete mode 100644 engine/src/main/battlecode/world/resources/CowTwister.map21 delete mode 100644 engine/src/main/battlecode/world/resources/CringyAsF.map21 delete mode 100644 engine/src/main/battlecode/world/resources/CrossStitch.map21 delete mode 100644 engine/src/main/battlecode/world/resources/CrownJewels.map21 delete mode 100644 engine/src/main/battlecode/world/resources/EggCarton.map21 delete mode 100644 engine/src/main/battlecode/world/resources/ExesAndOhs.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Extensions.map21 delete mode 100644 engine/src/main/battlecode/world/resources/FindYourWay.map21 delete mode 100644 engine/src/main/battlecode/world/resources/FiveOfHearts.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Flawars.map21 delete mode 100644 engine/src/main/battlecode/world/resources/FrogOrBath.map21 delete mode 100644 engine/src/main/battlecode/world/resources/GetShrekt.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Goldfish.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Gridlock.map21 delete mode 100644 engine/src/main/battlecode/world/resources/HappyBoba.map21 delete mode 100644 engine/src/main/battlecode/world/resources/HexesAndOhms.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Hourglass.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Illusion.map21 delete mode 100644 engine/src/main/battlecode/world/resources/InaccurateBritishFlag.map21 delete mode 100644 engine/src/main/battlecode/world/resources/JerryIsEvil.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Legends.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Licc.map21 delete mode 100644 engine/src/main/battlecode/world/resources/MainCampus.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Mario.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Maze.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Misdirection.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Networking.map21 delete mode 100644 engine/src/main/battlecode/world/resources/NextHouse.map21 delete mode 100644 engine/src/main/battlecode/world/resources/NoInternet.map21 delete mode 100644 engine/src/main/battlecode/world/resources/NotAPuzzle.map21 delete mode 100644 engine/src/main/battlecode/world/resources/OneCallAway.map21 delete mode 100644 engine/src/main/battlecode/world/resources/PaperWindmill.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Punctuation.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Radial.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Rainbow.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Randomized.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Saturn.map21 delete mode 100644 engine/src/main/battlecode/world/resources/SeaFloor.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Sediment.map21 delete mode 100644 engine/src/main/battlecode/world/resources/SlowMusic.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Smile.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Snowflake.map21 delete mode 100644 engine/src/main/battlecode/world/resources/SpaceInvaders.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Star.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Stonks.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Superposition.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Surprised.map21 delete mode 100644 engine/src/main/battlecode/world/resources/TheClientMapEditorIsSuperiorToGoogleSheetsEom.map21 delete mode 100644 engine/src/main/battlecode/world/resources/TheSnackThatSmilesBack.map21 delete mode 100644 engine/src/main/battlecode/world/resources/TicTacTie.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Tiger.map21 delete mode 100644 engine/src/main/battlecode/world/resources/UnbrandedWordGame.map21 delete mode 100644 engine/src/main/battlecode/world/resources/VideoGames.map21 delete mode 100644 engine/src/main/battlecode/world/resources/WhatISeeInMyDreams.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Yoda.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Z.map21 delete mode 100644 engine/src/main/battlecode/world/resources/Zodiac.map21 delete mode 100644 engine/src/main/battlecode/world/resources/circle.map21 delete mode 100644 engine/src/main/battlecode/world/resources/maptestsmall.map21 delete mode 100644 engine/src/main/battlecode/world/resources/quadrants.map21 diff --git a/engine/src/main/battlecode/schema/BodyTypeMetadata.java b/engine/src/main/battlecode/schema/BodyTypeMetadata.java index 70480529..62c03006 100644 --- a/engine/src/main/battlecode/schema/BodyTypeMetadata.java +++ b/engine/src/main/battlecode/schema/BodyTypeMetadata.java @@ -18,26 +18,28 @@ public final class BodyTypeMetadata extends Table { public BodyTypeMetadata __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public byte type() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; } - public int buildCostLead(int j) { int o = __offset(6); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int buildCostLeadLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer buildCostLeadAsByteBuffer() { return __vector_as_bytebuffer(6, 4); } - public ByteBuffer buildCostLeadInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 4); } - public int buildCostGold(int j) { int o = __offset(8); return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0; } - public int buildCostGoldLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; } - public ByteBuffer buildCostGoldAsByteBuffer() { return __vector_as_bytebuffer(8, 4); } - public ByteBuffer buildCostGoldInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 4); } - public int actionCooldown() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int movementCooldown() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int health() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int damage() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int actionRadiusSquared() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int visionRadiusSquared() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int bytecodeLimit() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int buildCostLead() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int buildCostGold() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2CostLead() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2CostGold() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3CostLead() { int o = __offset(14); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3CostGold() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionCooldown() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int movementCooldown() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int health() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int damage() { int o = __offset(24); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(28); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int bytecodeLimit() { int o = __offset(30); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, - int buildCostLeadOffset, - int buildCostGoldOffset, + int buildCostLead, + int buildCostGold, + int level2CostLead, + int level2CostGold, + int level3CostLead, + int level3CostGold, int actionCooldown, int movementCooldown, int health, @@ -45,7 +47,7 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { - builder.startObject(10); + builder.startObject(14); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); @@ -53,27 +55,31 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, BodyTypeMetadata.addHealth(builder, health); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addBuildCostGold(builder, buildCostGoldOffset); - BodyTypeMetadata.addBuildCostLead(builder, buildCostLeadOffset); + BodyTypeMetadata.addLevel3CostGold(builder, level3CostGold); + BodyTypeMetadata.addLevel3CostLead(builder, level3CostLead); + BodyTypeMetadata.addLevel2CostGold(builder, level2CostGold); + BodyTypeMetadata.addLevel2CostLead(builder, level2CostLead); + BodyTypeMetadata.addBuildCostGold(builder, buildCostGold); + BodyTypeMetadata.addBuildCostLead(builder, buildCostLead); BodyTypeMetadata.addType(builder, type); return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(10); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(14); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } - public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLeadOffset) { builder.addOffset(1, buildCostLeadOffset, 0); } - public static int createBuildCostLeadVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBuildCostLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGoldOffset) { builder.addOffset(2, buildCostGoldOffset, 0); } - public static int createBuildCostGoldVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBuildCostGoldVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(3, actionCooldown, 0); } - public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(4, movementCooldown, 0); } - public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(5, health, 0); } - public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(6, damage, 0); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(7, actionRadiusSquared, 0); } - public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(8, visionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(9, bytecodeLimit, 0); } + public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLead) { builder.addInt(1, buildCostLead, 0); } + public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGold) { builder.addInt(2, buildCostGold, 0); } + public static void addLevel2CostLead(FlatBufferBuilder builder, int level2CostLead) { builder.addInt(3, level2CostLead, 0); } + public static void addLevel2CostGold(FlatBufferBuilder builder, int level2CostGold) { builder.addInt(4, level2CostGold, 0); } + public static void addLevel3CostLead(FlatBufferBuilder builder, int level3CostLead) { builder.addInt(5, level3CostLead, 0); } + public static void addLevel3CostGold(FlatBufferBuilder builder, int level3CostGold) { builder.addInt(6, level3CostGold, 0); } + public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(7, actionCooldown, 0); } + public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(8, movementCooldown, 0); } + public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(9, health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(10, damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(11, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(12, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(13, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index f9414bec..da803cee 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -287,12 +287,12 @@ public int makeBodyTypeMetadata(FlatBufferBuilder builder) { for (RobotType type : RobotType.values()) { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, robotTypeToBodyType(type)); - int[] buildCostLeadArray = {type.buildCostLead, type.getLeadMutateCost(2), type.getLeadMutateCost(3)}; - int buildCostLeadOffset = BodyTypeMetadata.createBuildCostLeadVector(builder, buildCostLeadArray); - int[] buildCostGoldArray = {type.buildCostGold, type.getGoldMutateCost(2), type.getGoldMutateCost(3)}; - int buildCostGoldOffset = BodyTypeMetadata.createBuildCostGoldVector(builder, buildCostGoldArray); - BodyTypeMetadata.addBuildCostLead(builder, buildCostLeadOffset); - BodyTypeMetadata.addBuildCostGold(builder, buildCostGoldOffset); + BodyTypeMetadata.addBuildCostLead(builder, type.buildCostLead); + BodyTypeMetadata.addBuildCostGold(builder, type.buildCostGold); + BodyTypeMetadata.addLevel2CostLead(builder, type.getLeadMutateCost(2)); + BodyTypeMetadata.addLevel2CostGold(builder, type.getGoldMutateCost(2)); + BodyTypeMetadata.addLevel3CostLead(builder, type.getLeadMutateCost(3)); + BodyTypeMetadata.addLevel3CostGold(builder, type.getGoldMutateCost(3)); BodyTypeMetadata.addActionCooldown(builder, type.actionCooldown); BodyTypeMetadata.addMovementCooldown(builder, type.movementCooldown); BodyTypeMetadata.addHealth(builder, type.health); diff --git a/engine/src/main/battlecode/world/resources/AmidstWe.map21 b/engine/src/main/battlecode/world/resources/AmidstWe.map21 deleted file mode 100644 index 39397b347ebb7219bddeae7e1afd74a7de82d78e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33048 zcmeI4y>4Aq5QTSw2^NYX7m4I52~ud%fCv;+4o^WzLkfhbNJ&A#Gaw~T6nC`LRPJ~L z_VM-S$P0~T_C9ldtZYkL%WHnttUc%68%wrwS`J?)P0C}Dt=z^uNu27s!+|wkf#`|G>4vf!%q|br3Z>F#FGsUg` zy}<|bl@nhZ@u9f3kF0sz!_xEeR$p&i=Xtz$PHUg~(0(tk^;>iNDq6m%v+`MSZ;qGG z@_`QX6v-=6r}4dT%ioL3uYayT|J5&jidvV&nS-8k;!B}5Z*O~Qy+8Nj9*X2uSL4dH zelAyi<#YADe&*?Z;N(?DSfpW`k@b8 z$`{WyiueJueD&(l2WI)n(&_cp+ZXkXKF=MlNFF2~ofEB7UAUs^k=OWMc&|VD6tnJy zuJv3sZ`Eb{L67+s_u}ODf_k5*uim~aeddEv-QGHH4tcP5&Q^W+j^b86$J}WH)-!!ACNx9rS8WZ^pz7| z3U%Ir?{817_vc;*_L$};_&F)rR(s6zbI-SJj-vdp7ts4^@mP$Kh$X-yw^u| zAAax~MeT!U`RmowKIOgs(24GcI_-n^`pE9X4}POaAGnmSR$csnt^HO#deQw*M;~bE zZxzQEexpd=QodCmuBh|LYkV$8m;JyM$%EwQ&R?n@fB20eeTrE=(M8YWRvq!V$b9w# zM;A^WBu?F45uf;uB7IBU%hM+hF69GVZw`5ozT1NMj^b^(*YG)QApiG7W3OYc<8?LO zS0BpfK=j{5>TcU!@C{o2y}Z@e8fOk@^?P}%FB(Tb`g1XL^hM`vRfkV}gT(O#xAN4@ zMdqlE#yzh6tsH$t?jJ?^Tj#G;k3YQ+aYgEgXZy5ti7PUnI6NEC=l)ToFWb*tJ$!-D z`%p*UTp#qK2NI8BZ=a`+F3A0(NS`-ntvr74ubjAt^v(6HI?AK^y?vHGdh9_taS!RU z=BypZ55AQX_mIB1{#8eLRKK^+(npUyC@1bAeb$_{R z-2+^adJECr8u5pJ| z;y&QbI_`0C{k+M0^Rn_fPkGiHbkJ91Kj6*$_ItvA6!Fh}6v-<__2dBxT_Th-&6`zVrM+n>($_|pEEuls?MU)sk~`uJB|YF<MI4@m=<-}a;)zL1TR!-bQ`c%J{tDf?x zZf{>yzqL;ND39v(_NhKPJYVI+J)}?dd%5Z*cM!*0?u^ykhH|t?Kb@&G+(F-`u#)_4wR* zUcb)QdM~f_d*k?5+}bC8@S&XeTF89GwdRjG(*~CRz0cV5*z6nl9F+&v+{1dluIF_gxPiaXRm=&T;KMs@=zxKda}co~izMJ&)@7 zte(g9d|S^HpUz1=U)1xoo+tHuQ_rXMOgX*|-`}}AapHIC_fz1bdZsxa*E7xi?w6l_ M{Pp$suj;quKgM^UC;$Ke diff --git a/engine/src/main/battlecode/world/resources/Andromeda.map21 b/engine/src/main/battlecode/world/resources/Andromeda.map21 deleted file mode 100644 index f0d8d31343b448b364ba5d5e344df05b68127845..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32568 zcmeI5y^b736ouQ^fRVsBu#htdAV4AjArT;?6_3CpAlYPq!~^gI1Ox~P#EUrN0U&a~ z1FQ%v5fG4&QSI`#v50NI&-V;J?H*(_w3B?qXkB4W9>epMR#;e`ShrjZu zjbAHjy!HWG{aX2t?WcKDPsZ~nb60#gxgWIFp?Yeoe%^m{_WN(+qA4}QeK14i*%?V}HpANls`5(f{wy*&66?@)D|AAG$C zA3D_6%R?MI@PfU3bN$f+$%p(LFR!O=pLqD-cmA#G@bqFUzw<+ndZ^F&&+QL7j(4qf zbimfSB7OP-AN*hx@AirBMaLJds}A*0Uli~5iHA>hT-@60s!Kjgb=Im+^HZCAbzSY& zdNdAx>S^V1e(MZ5ED)G#l ze6U;RuYIZK%zO)8&R_P4S6=edb^OT}e*D#D{dq<0hqLJ?{nfr>vyZ>yqu*|yc=+H~ zWFLRW=k!=V6^#0m_a9w+|J&Lx`djx~@6*%!Yb!tf$A2q5>Q{d48~HqIsCCryI=}dw zl)C75WY_&F_va|S)-UJFR(hJxsn44}f?LfWe(kT?%vmdH*-)d(*KX>@HM(T?2P^qfB3nR_fn+3rKow(&x~d6=(P41|C;Y%_vdBk zDG&VYx7yL%=?8pE5x%u?ZeE&4-Pd^DoEKnk|9kUpM0xAHoE_zbj>c1O9nX1Re*cvC2(`bFUH6gC zJ^JS#>9DVQdEL*Oe%1Xc`6(a%^l2-5t$e88@zJ-nQ2VvDzSC=+Pt+IXKlHqri{{Z< z-?97Ot6$g2eb*uPvH1FS{W{kCdv#s@(fR25AN85@PO*-g_Mbe#K7C#vJi-UR*3Y^_ z_3xd7#<$wNI^?hXtUFYH`c>=u{?_x=>n@(R<`wC)A0fP2AM35C@pWIy>weDXf&6_& z`_F&9yyUO>vEGUrAN7^}I^S}Bu-~e$e#9%PpR=_d=hwQfe0AMr{&}7A|GfG8-lcr4 zbvQq*&-t;gbHQf+)X>c**M0cw{nYw@t1n9c|O2;r^y zxNa1SPVHaT;X_yJW8IyRLVdSKddz{e2t#cKW@#5ue+4{jckyzJkm{v5uSe-{~pOTszWt{iZ*? zeUJF&?)T-iDog^u!3ZynEl_;BCD>Rck5dU{cL>p4<)>-^WBx7MTca<7Bp!Q|+2>|2-@1cdPB@w{#u-dQRoK*Lg-ZJn(|7 zYrN*qKK{gmtP_WSWaoJQ`&GoRjpW^nYv-YSC*mbv5K+Fy9!Rb=1sv9EF1?7MiE zZ;n6w+{uUhBgB7eBoF$TvCO@((7#Z$6pd&mDdAw#H-Wq02nBnzzmeJ@ggXr|%lS)XsWWXa3Z= z6}tW|oj37{(R`S%BK5m?)xmcDj_=gxf0%jm`Hf=#`+GM(=BwvPZTIV)`usWX9lCzw z&%X9w&nxVu^Ek8~bw001zo{QPnm7K;9n|^PJmvb-_1d1kA86GhfBe;E{aHo&3@)vM z{AdR$!VI(+bht?^6!&;!Y5X??`Q2R}GBZ{mA#Ej{X?zPY@_!>9GkG?Gq0lI?lg!9iCon<#&GQQ4jSw|GE7^$MLScjvm-rpUZ>3zyq)IkJgEI zs5;Is(sBFnp+kMn->nk|54@m@+j<>+ko?Fu(#MZDc)%!L_la|ePNb{xsuS57uewou zlwTBosQtNhy83$aR(-X#?|DD|+*Eny=B4_M$Mu6eT->qO$q&?e>$=MODEz_JI`DU> z`q^*)ze273?e)_+)cx;&pX~HiM{O4utt*e(QM~SJ{8s%?-DBBWud|otr@Tw~h+msm z`J9dZj$;S5`#ZqBzk7f8^J~ApPWwJ^EB)vAI~V^u{#GjXPC7nG$9L)YAsxS@<7PVk zxt5O~)AOef)^Dc&KYt^6j=t}u<3>8h=O3lxm2|wDjyKXVa$ipe>!Z(WPmVVeK7D+U t?C}_Vc<}t%3uQf}HYD>g@2LA?I$lc0%jp=kKmF?7H(!5w|K8{6`G1yJ3_<_^ diff --git a/engine/src/main/battlecode/world/resources/Arena.map21 b/engine/src/main/battlecode/world/resources/Arena.map21 deleted file mode 100644 index 1d5d2309256c9b20ed6a1957205017a567c0a6af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8496 zcmeHNu}T9$5FIsY5D69vX#^3=bT$@3uo3(QD?wWeTYte)1jWDbH?+zpq!KJr_yNu) zc~17_mfOY4ZG>AG-_7pq?0Y+VcLuI2leQyAav)vVk!@*9OHtGpIXr1ePcQB-L3vtL3 zLd5055HIwDS4iiipU>L05sHqP|tt~amW)W443XHETa z&YJswIsfnR-+!^swb(d2|4sdy`iqSE{2t2X@bl=sjKg1)~zARS%{O_M! zIz#(jtRK8%pYMpnJVWFMhIr)K7w`i5&jHgh>4(k`+ItT9fXk*Ee1PD|=o>g^4X5>MM&!eqXQEVbWj5x9V|T-}a+SPwIHF{;Ku-HD9A2b&9WVN52}_ z{rzsBqZ4=4PSqaN9@Spe+G5wR7!v*4A$iTKd<;_SD?x1@3xZZB=bgZEFV6 v?_%7z^D&Ot*%%!jHy6L+CTMflt|_H)jx|NM?z-BB+UE57?C$3FO0Rzau)&G< diff --git a/engine/src/main/battlecode/world/resources/BadSnowflake.map21 b/engine/src/main/battlecode/world/resources/BadSnowflake.map21 deleted file mode 100644 index 60e9b68c9d52aea8c277f6b90811741e473b9380..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20312 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 diff --git a/engine/src/main/battlecode/world/resources/BlobWithLegs.map21 b/engine/src/main/battlecode/world/resources/BlobWithLegs.map21 deleted file mode 100644 index 961cc076389ac4be351ca15c0b8ff1a3115de128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33080 zcmeI5v5H<*6oqdjYSa)?M2UqU62!tnP%JbuD3-QjFNg|)g+71}U@3xP;cNH~YUvBu zT3B0oZ!%x=!D8=o@A)$!nSsNawfEXua|$%jMR`8^VRznYKKqR7XV=>g z&Rp!gV{;e)cmz>QB9W6Gxvg)e#@9 zOM2q?8p)p;-Pe3?fBTs4^{wjMC-LNy^u%Y^CBG`pJPE6M=V$rgoBW8QI~CHWLiZol zck8Vi<<(ry&+?z;!+e#W|D0l8)jLn$gh%z=dh5D8&0WR2{^*h)`3h6LyOkN4Z<-OoXH&aRHRLGK+--kADSar^A$v-%{T?p)nHC*AD*cjvZ_ zeH*QVr+0H4{VcS9;@y5n>(gGl@r&L+_xIl6en<2bx^9$L{wY7JPuFL3&)t2yKl?CR zH_FpH635Sd&8?@dLh6oU)hFds-=ueZbpNjJa=$mcTc334{*KcxVe%(#zgZmry_n|c z`tkFeJ_qExeo0rod+J}s)BUL$^qY-UU-GFh z`}O-1Pni7dGmE=l*O&Vz9NjzmK~&o0^@j$ei8JyRV2gx+(-?UUZq^K{=Q`K5Swo>X7O@vn5`(eK5_egEnHyf5hY zC4MTTU*(U^nCj4_JaOK|KUeAJ6&?NwQ+2jg>y- ziSv%ev?t=81CDP(>W$rc=EQ&Y{+Yu_zb;ZgOOKy1`J+pD;=HHP`$?QWAifFhLmimv zh%+bLNFL<#VVybsLFf1KuHUGx(pP!khxamiUlq5nIra2mPSAQddXTu0Jm`GlRsU31 z#k;NsSkND=^SSc$B**azW9M@KJITE)l<*jDjfCa z9`xzfCmnuZ(m6h=cYWfseenZRU*6L=s;9o%dzHt>SlxqpT}RxAALxAINlzS1^(jsr zm~`DZK47Zrz8Ce@n^*g-^7b=lj)Yx3?*b;jZX6%5TZfK1kT{s)y`f8pu0nhhCV%48F(+{&dC+m>IsHNJ(Ry?0 zK-VYEd`A15)5mc*c_VovI>!?q)#F2*kv!;spMbOf3i07x;R%^1?J3m}r{0+Sh%=uN z--Pt3^60>>KItA*oP8Usy_4Vjp6sQIylX<{NPgr&?pwVx{gRHnG3kk;ho1`R1G*3I zU}V1)@}8jm;q(X7o>H8;g!J#C?`xj=bmQE+Li{S-XdYj1w7%LqdB1n+!yI7RbBa@! z&~sGW`%XOdCb8k3J#uBusU);;C;pp5{nA&R~#Q>RX4il zi{8KQmw0vW(R}LTc=ApAPx{fg=YUr}kJ|pL`*!oZ-zX;kz57r7-KVQ_-O>Hqui|^> z#P?`DJ_(b56;FP|AJ+Xd-`>vw^%Wj{Km3yq`B6-M-FUZO@~i5*bxG%V)i3>iPw~pn z{S&Wz$RDk*e3CzL>PL}!W94JLx$B)bx4z*r;Mf;kc+Mj+$`=omO6Q(-isg5{0ka$9L6{h+Wul&fT`V^<`C?xx&eYv(=U2d$wTkE;Ip6}Q5!+L&M&$adZxSs#k^ZJ$h-=CdF>ppuK3n^UOYeVuK3(~UOhjX_U-k&vYsvefTw;rs3=S`zKa@ YW&3{fe`-D3_s_0ptABbuo5$w&KhO#3tpET3 diff --git a/engine/src/main/battlecode/world/resources/Blotches.map21 b/engine/src/main/battlecode/world/resources/Blotches.map21 deleted file mode 100644 index 5e1f052f7f3a0540a1b79feeae7e1075c4d1b1f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16664 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 JF7rOg`#+5m!d?IX diff --git a/engine/src/main/battlecode/world/resources/Bog.map21 b/engine/src/main/battlecode/world/resources/Bog.map21 deleted file mode 100644 index 589610584d7b112cd0ef881a46a59a63861e72e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8464 zcmds-!DR3-zLNk;S)td8IEd zPDS3o6ggG@LjBM6q6VzT-|ENrH2ze%=dah}s@Zo{eOQlQ)z>d+{C4|do%p)%RYkoh zPc&{o-%uDjy$`nLOZ``tc&IH|`R@9`6F_p|e8oXwkS?(xF~ zr}eDk>wen%KiXe3ZdW>4emLM7^2Fn*7wy;TYUj~9H`S4T@o)AwAyA>vey@*Gy5#0B#p&suo8RlB zlrFjXOL2O-=jQkND5Xno{!*Nt?z#EBK1%75o4*vNr~6cXc)Fi^c;CGJ`N!*nI=R>T z`RN;uv7Y?)eLwq@;`DT-FZ{I6fwza-o&)^&AszbH{qyes`51d&@qNee|L48)w%m3O zKR(JyJf6CiyS~2Kd~Xw-_t(j%16=s1zVvN5hyFj!y3M0rbpJYkex0Iq=@$;T@aSnh z>v;0J_2%b_>Kcvf_M88Es^~dId8mgU${XVM^0^=W_w&Cgzn2$1m#O*nJ_q{bz|rQ} zfdjpGr1nPbLhVxRliEGCv&KHFPxh{{r9OAC&?gU;IzLfcsHOPFYWLNis_m&gQA;st nEzQ&Q2WpSho~fmg))@8cy*p{n^^}(`?5m}H?l!OAo_~~oQ8^N9 diff --git a/engine/src/main/battlecode/world/resources/Branches.map21 b/engine/src/main/battlecode/world/resources/Branches.map21 deleted file mode 100644 index d96140e7fe797b5c80c200f4a8a60604a5ea2264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33080 zcmeI4J&0XZ6oqf%s8fV6MUWI0K_m#KP=ke_UQA(UZ(-pth=PTJXlEyaV55RRt&Lb% zh`m3B0S#(Ie63M*Kp|pM3ZCnkFPB*}d(PSCoO|azc@HjY_C9N`wa?k_Z{ED*WEXE+ z-L2iJ?qs*s9qTr`jeuQ$YeXvu~k2+LtnXh<(0uv_0a>>&livLM{h1n^+_KoUg|DkTp0Ua&!6*7&9QVn zS0CP7sPiw~pSRAtKd*i+U;D_d^YYXu6?^sT`0XD5xqYPeuj{$GUfyB(sISJk`_MXX z9DUl&zs!H{?}@6DdmdiiviWE~Q^)K14<|f+-r>FfsonE`ng9Cvzx3Sn{_BmSZ@c-Y{B!rII=OXT-m?2>f34&7{D%`=p4Wf9|F)jD z>goK|zc$|AZ}0QH`e>auRy`|LU5lrAt@FmJXT_>(@#^yR&;OQxY5!X1jjet(ue!Q! z#aic$EnUs4uC5a+FE@_$%RhhiX`$}d;%R=ax~Y9sKR1r&G0tDl$BI=ym#1|aqhsY+ zSM>6!pR3OD(R?bVZ$+)s^@HPa{;HE3Tl%^6@X#R!$y*2yw0N3_59+!V!v`%Md3d0e zXWc^T6fJ%#A9d>IpYmZn)i>+#LGl*D11+BB;e)zv#qdFkM;;!S%3JHyx5DT%&L7{o zFn1rRepDyLXML_Z^|505nit3UTYa_4>%MYzwN7Kz(RC}Ht4@8aSo^eit@6=tdFHSC z&yDpwmbFg%O7*Slt>f6wIDhT0Rh-*5ez|;$hfWH$KE-EU>%6g72mUnJZvNhLfUo-^ zUy7<{#j0=dG_Q5uxRsvjl*NnwwFe&k_1jy1tNz}9>Kw}Y^M78P>!bZnU6-p5Py1^f zGxz9M|NVdZo(kFjH(w98UwTE>bN%6i-a7Rs_Uh&ODi5DhjCzay!B7AG=ZBZRtA6}z zf5dhDjgNoT;k-fC@l7FoFvVvbKE5D%5I#uWi_|N6b(GKCqb~0Q#`9Lc(pY_Kb{ov!xQ`Z``kJ{MRA9DxS^VjqDooD*|R8ReCW7R)6Ui23qdVK5QdwzGn zZXK*^pF`>X@H_k8?P8ycrGC`q`oN=4>b*$47rj2rJ^IY|`tR)%zV|%fQ(ubccyZbN z;(iwWr4Qcw^3=yaSO0$<-t$TEOV5uw^ohY%dGvA--(|twbN4^~bN78%JkDADTjf=E z)#7*#i~dUZ^l$t0XYSYkx%bQ5Qkd$CdgWPpiwECAty{L3xySx_{}0;l->m&EOFnhZ z^r<{6Z}H%-CNk#{b)TyqGZ)=QtGw#2S{%<|J%8rryuBLJ#ba`VfF2urf35^~7K*&w4GYpQQ&c7cHHG^W*$;eM)%;_c4BdC&lxwYroWc^VHQMz9}7eQ(^R9 z^ha-h^`^yzOOw6+d;3qFi+5f9srTlot3~xq#g<>HF160wqdw0A?LYTR^`Yz5eoOO~ zzBga$uXXC1inYFNyy(Lp|3CTa#S4@D{g3^X_Dy{&qz~1z^2+nZ=z0+!Z(S~b_uQv{ z{O9(iJkFsNqOW>ZUU}XaT`%I}t@H86zyISm75e&W_d2Bep$~7Ky17vMYaP%1_y4)h zO?~v-Soh|sn+vtS)^Xei&--Bdai@LEbsnWYR=?hSssGe<);{ulnLF5S{@Pb}{z_xZCzV$}_})Bqxv2WJvE^H;tKa`A z)oIQfujr|MXF<#}UtTcfuRssGBR=@q@^tta} z$NRiR|HakY9(m*QKPUV9FaE91NA>W@#n$zzR~x7HQLE3~qfh_(zH|H6`f2~(nAiVUcf32Zu zhU-|k?hDt^aNQrSU~vrx4mW;25{TD+4vRzGb>SL(uMgMYb7Qy$&bj9wd+v#+pL!wu G*!>H?#j{TU diff --git a/engine/src/main/battlecode/world/resources/ButtonsAndBows.map21 b/engine/src/main/battlecode/world/resources/ButtonsAndBows.map21 deleted file mode 100644 index 46d00d5651294b8dbf3ee41973c5217e59e4e1c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32976 zcmeI5F^*hC6h#X&!35SY!2}KoyZ}oqV1(s>fPj>Mj10*RY(&Zuh>##6X9aA6gblC+ zFM;3o9JT)Ge!Qyc|9{V)`IcIj``*2`-m7XGOMtm4rCgWi<@54vz^CP+Tn<>u-%m<; zG2pA8OZoG=QhxcilphBCX26S~el>hv{`l_Qo7Zo@eEt2)H$S}{3WM>F-*!L#y4`TQ zhwXc?{XBSRzYYw)$_+o>-}d4|yN}1RPw#t2zQ=NJ4`t8j9ee8!k`shLG zpnd1&%w=SLBf4mA`u4%;8?(Gj?>@XWmpP5KdG^8a8>9J_t}_?Μw&kACE*jxNff zj?PFQbRSMXLUha(A-cJ9qWq=m>^avxkYBqGdZYdB!>x-r`unnXH0M(F*86DH*X}{C z(SG;g)@2-D?f0NnpPhfMK6^yy`#{IM@JL7Bh(AK>;nq_(T4!#(d9)8X=p!9{BmQ$E zb9sJq>)^}}$7fF6h>jd1ePgc}5o$)j#g9dzFuoe`b)rfxh{=kv`ukGeT^(0y}sMs%&% zyMN^KT;`t7eR!?Tdd~%S9-KZ%-ALbvjyWPk2cD|KPoC#8M`!HS;UkZEBDBujKKIS7 zhofUYkh+mR=sui2NS$*dw9ec<_sy+`qhmfJePgc7Ci}*6E%|k~X^MTZj^g;LG z^g-&JTZ{NItj$A59`hOL8+&z;k9i{GeETDgKFXtxF3Uj&T2I|*9UL8VM2HSwhUlX_ z>ga0o(1Z3-H(D2Q`^+O>R(FnhuirlB!mTq$7oqjFJj$bfYL5Nn8m(I!_dam%LEUKG z+PL?Ddk^YH>(<7-58QiDH(Iwg?tS3igSyeWwQ=tQ_a4-Z)~$_uAGr6RZnSP~-21@2 z2X&)$YvbMr?meg*ty>HC9_HS|eRJ#A!o3IF^HVokw-)X_;Mx4>jG6Dg_Pqz(^HMij z*UOz7@!ovgIK0o47zUz^{weDQFbEq4wYvttC`dal-E;+_XPu+Sr{a$R%Y1Kz_ zkz=&peYkbC+8Ip$%-ir8*&T$`ZUB>N$w<71@gV!QH zW9GLWp84Fj58jI8;)B;BKBN8a!>!A>eQ*$e#G^XCS|rDq`K^a%KKJc|gXkk3)$!FL zIY#^4hg+9%`{1p}Ir!kUh|ie$t%qkm_w9qXBDwhBwTRDXzx#0OGHxFn#2@jjPQMp9 zKf>PJ$j3SEyKau&b$Bh3W3=CWxOEw~58jHLgAX3z@4Nr}bb&v|to9tw4R1yE#RsoN zd`A1-hg(<6?T2SbK05eX(R;u%WM6dfR>W^~j{9)yT6t?utG;!fbLm_6YSl-3kz=&p zeYkbKoV*Ns^Vj0b_NPD9KI9pl?>^kRjW6^2jH&LKcQiWReYkZS-`;%vuVC( z{5&@Le%*ªG-WvP4Q9gRNUeYkZQ$7jrZ^zDPwUkfs~v37p@;I)2q_>A;H_u=$2 zL_fxV@BZ9n@O}8_%x6CO*&OHYGv^rDA6)Jp#&hid9BkiHtqxzL|5#^FWAEPN?C0lv z<~bKK$8ltC<8t?Ke6GXuYjwWovCn&&AD&CzR5|1=jZ@7(RSx@)^Y%Y~=!3O7^v1E@ z?+!op{bRr9ITycg_b{GkzW3+8$LI0x#{E0C>N)4WW9we6`r7@+xzoRYls~TbzW;vS zao+y>Q+p3{>pb6azWhBLpX2cUYIWS>Sns{ec}ME|^N;6PkI%TzVXmd|`23y|?!ET& zAJ4I#9OFL6`;T+UJJd(I|F3(FjPK8%I@f#8&Bya+d%Hj1J&fmy&uP6M{=J8BzV|Zc zeCp=ZLHEtk84thDt^2j=@9RDAPOba2>ihQ3-jhD)cQ#-C-F;7w?H>B}<=wJ(b>EyE z&b$cp4*SvG(PPI2V z<2et%$LLyduH4o+YV~u?J6CS)UYl-R|Ga;DukF3Ie?M#c|9IE_I`HxDFIVMRxhdD> zX}K&H!2=hg7}YWRFTe4Y%SU++GbciPK=?>^VVXV>3(cAwo}e>Qwx-2L?c OA8MZrja~24JN_Ra95{#o diff --git a/engine/src/main/battlecode/world/resources/CToE.map21 b/engine/src/main/battlecode/world/resources/CToE.map21 deleted file mode 100644 index 93ad69597d611af57af04eb6195d37ad46a67a35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16616 zcmeI4!D>(h62M>ZifCnLhh*u9DJ$T5$n{OhX1bq|V!mBqQA&+2p zc0a~crv0ZoC5-Z`mb)z;b7`EB3qZU0mEz5Ma{e{Fvs=&AZW zqnF3|`S$+2`o8P+>7A20R&AZX&)=JKnB#K2-Z^y!f1JzfGX3-GG9S)#9q(i4bG&}f z@14`n;E!{O`*%9t$I$2hJwLC5Rds!AyxsFYzk2_Vzut;B_?zoF{r(xh{zJWJKfU}O z*W16XPrg0x?R$On;^#W|a;MHUHI6yFeUKMbFL&x(Q{(90+Xs13^>U}qMO;s9-`+lK z{&n{~Zm)07ugmM@_4??=&vl-~wf$%Hk;Pr+Z?C}c^F8Z2WO0}4zg++2{lDD*d=6xN z4rOtf8_nt?i_6?-Rv%eh=0>yn$l@|Ln$<@Zm$}ibKC-yXjb`( zWO11r&FUkI%iL&IA6Z=HMzi|J;%?^tvHkz9(&6tUUay!c9{${1TMv#>n-|?H9)6Ug z^5G~|b-cdf;d|?PZL}hp*~HeK<;^9GkCr_%?6uJshR`!nJd#x$$jYbWdHS zQI5)2e0){M>r+>$x2`u{@$tQNRXlZ-syb0$@$sV^n@?S(HgE2|;^XfN*UrIwN^M?r zuXy-Tj>?ClRMqkNiihv5>y3w_)LU1@D;~b86ZPRJjdEq2|W7 zdC@&}l}0%#U-9u(9j{MarQW*Uc*V!})>ZM;RjTSleZ|L*a%?_zmD;?y_ll3dFI+nZ z^C`7?(Y@l~M>#4Vj#5>}>nk3ss!r60qcqB~`HF{c^XA^eQF>Fj z$Mq=!>x<_I9MvZT9M^x+tm}GO*Sosj*L7A`dv?GVvySSs2U<>hlt5c2b+x$m{j)!` cowfC#uKRVZw)-j<=d0DhLGy3bb-OP7-#29t`2YX_ diff --git a/engine/src/main/battlecode/world/resources/Chevron.map21 b/engine/src/main/battlecode/world/resources/Chevron.map21 deleted file mode 100644 index 4bddf3bbb3f9a8207e2eb8c933628eb21a8ad41a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16728 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 diff --git a/engine/src/main/battlecode/world/resources/Corridor.map21 b/engine/src/main/battlecode/world/resources/Corridor.map21 deleted file mode 100644 index a0826128fe447f2b4e1db9d68e0a4edaa6602d7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10872 zcmeI2ze)o^5XMK18c>3Tg@uBJf{I1JR!HG9_y#sskvxZ;A}BtDf{&qZG^L>^>Wh5b&dbTR$lamH zQ(NRr@kX(|BeFFs@^J5t*G@mmTc>QFykOb+tIkK=KCGG_`7Oeiai7n4S@;_tu3Lm3 z<5l_O^IdTGd6O@c_qf(S5AUN9j&2;#!AJ7T(&HuR{V(}eUoJXEt*wjS$S9qe`d)ODav>M81{u0v@3tWRBsqWe$%tWRABTTf9xbsgBxqV=;r zbsa+MXMO5Au%FaZ)US1L%DoMLr~lXA)uZ-F-4As?xch;Asr#Yshq@oK`@wa?Bz#{` zC&=f4_5bVV19ke)>XEt*wjS$S9qe`d)ODav>M81{r325=v*(kc^|StG9mp5!IVp%aKcBCqZ(c4B-@R-pxn;F|wNtfowQIGe+WS=Bj`ZBw z#lRSE>ie4wo$2Q8sx{Qy`KH>m+N#>ZH=l7gXJ%mT-Oul~roJ;bhlBGe4LUs6i!O(Y ZpMx9`5^)IvB!~z&03k?RfLmCcz(=6l z>+&$=DZTFLp50mYS!xyUSMSr$En|W9C@j7X!jo_uj>19M3p-&qVhBIBLez%v>O%;B z-h^=WHiVB6A4c4X`djgwzIz|OK8Sy~{JJ=COcU@q_#Uiw559a(U%yYLLcibD-tXM! zKh@rWckcareXITcz@AKne!r`|-?`6!s=Wj6-23QiyhTk&pB6WH9}Ltsx7TKl2mpts`Po+jY?hkaqR_JjRdw&LBMCgA(Wdjr|p z5BMpx;@zGm;QOccr&jO#wb}b+-GA+VS@BkWw{P}-TKiLL_x;-J{j%=AcE7B6E5F-) zKR5a3U*CV6TcK6I%45aB&hgL#VTTMi;T>pLubpcTyxkVbX~3UTYP2pVXo)b?-$}37kNAX zzPx_>$NjO~?+<m1J8`CE4I<@&)t7r_h6jVtvliMsjPU1^1T|fBxJlen15B$K=c=*@GgGZs_haR|y$6PyvUEy$Cx36pmkE(a9zR!EJ z{yy(bJK`C+e#paq-G0H|&)eB+^{x0@@u+?*{=U7t7tDDa-rPUr0jhe(>cI;{-F+GN zU*G32FZj9tPCvFkj^|6)*3Y9+$l*^6_%LJYL>k9xhjd%ks;EW%+FI z*|TN&`sK2`82o7P^TCJ1e{VeBymn&U25gbS`t_-FUqIeoA-LFXz7Le7Tpum6=oN%)RfggMG<7 zm-DATtIcu2fQV;|b15BVMSqkbCs$j@`AAEkVh zSLyWi&(eI-JfFtOSKmr`Xr9LO>7$g7@=|xc`c~S5=INyRS(Go2#`Nih!ZtS2W)-?^)?C$2q#b zteZo18Y^EtslQ`&-}Jj2b-!Oa55J@SS<1_P{w(vJm7dMZKIcoH&N{u7^0uvZ0;(p^qhpFMwdZ~0YD*6IHWo!fcniuyWM^Zai9uIqUYdMmqg z&gOMFXVvpOa``k?{%k$_p^-mJbC`2{R8P%6 zil_wM%T@A|rW-m}tOPF0`1fA-1a z)5)%${i&<_rk``2b}rOU&(d5+d0W3P@}8CM_NzNb$Ev^c)jQhX^;P#xzspg#w_?@D zNAs!ES5NB0tkZeVO6#v^59;f*zKZ56R&(i_Prte^Kl@Y5MRgj}r?*mG#VSvKRp0B& zMLBd*eJ`uL%C|?IK1z9*dFiLl{;gVGQVze;{JoTqa%fDSK1%sXx%^7=_p-{b{Jnds zIeU`&D_?yt<>q|)G-m%^oq06MrICM>RbKjZa_{~shcA~#{#o?I`hq?e_y)# zIyhG{`<*lUX0`eME8R2CU-{X0(U9KYlbmN#M!NX9--5PYQT6 z%qQbnKTF`d@jM^T_v2YVL*UnVuEysNtTW@I1a6+|+rCwQI-ak_^Wm-c?%)UGS$ozU XYu@@=`PTB_hT|g)Zus`#JLCBWg#(p$ diff --git a/engine/src/main/battlecode/world/resources/CringyAsF.map21 b/engine/src/main/battlecode/world/resources/CringyAsF.map21 deleted file mode 100644 index d29fa78b9a59c320054d844d2830feb44718fd8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19224 zcmeI4O=?s@6oo4qHG+f)83dd-$O2RxIf+4W;6}uW19c)e(=`aX0>Krygv^||4VPd& zDxV=IIo9oZ^}1h@ZYWOQbMHO(r~5sj4R0@%*G}3`_tRe5Nq5p#+RT`;ozm|gx6^}{ zDSbao>GP|UK4pBK@mJ=a-Y&T*{W&P_*0|oouz~5m2j9L9ub&5??i(Id|FUfAgIX6J zRDY}O^x#3&hc9?E+4YP*_5R<-&oh0vJk_b$tvZ@l?0)-FJ*`)p3x8`K`HE4!T3qp; z?2CBN)y1#*E?#-H(Nn&c?erb*>biJ%Q1cxhjf>{1UaL(#a8aFQ&SAME`ZV!&vzM^)o{^<+U`tYFo$J*$EWA$7<`k= z?pT|n)nA+2>DKaA-y4hmeD}5N{@6FD`-TVAzbu>jpw@*4)!%A6J$O*{9j|e{Y*!B+)OwEB zxSHLn)0$W7NByPFk^LP}FMj#?Zxp|ZGX`{MB^^o{#xg5&AX`kbMwN3I-lb;?y}j;4eEUGp!%)!aB!DyeYbC1jOzXwM9UNp|_#qsF3&PhHP)p7ke9{sTx)z`RU*RQWd`*XTl z-|0r^Eh7PdfBcXJgD^?uW?ZuJy7%DLG>@oraq{3 z;X(CJWtV#W??1izow`5v4Qk(0*VlSuZPzdJfzdiHUio6r_j{!CYQH)U@s5xB7mXu+ zZdls`{c4=r#MQ7huckYdzqMcTK#vU@u+OK_6Vy zukmUZ-TwFOTEE&yt36f!uAg4@+hc|DGMSorm4c=W#yo^ZA(1=X`GF^XT||$v7PBt^C}n&HUu4t<3G`vzgBj z|0JIq`8>>L(8V5nw~o)z>% diff --git a/engine/src/main/battlecode/world/resources/CrossStitch.map21 b/engine/src/main/battlecode/world/resources/CrossStitch.map21 deleted file mode 100644 index 70ee7e04ad251e313e98ed2bd43e6120b0278139..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33048 zcmeI3v5p-z6owtLpp^(=K`FLDLQzVJ6m&>zkp^lW0SQ5cM7E@$$TJ|3hshIwgy`}D zNGnlLQy@G$`^EB^>wCsy`;6x@SF-;2`1tt$&+oardv|l`#@B^=;y!kl?!rBA=kCm- z^K<{Y|DJpLlXD+_>D<51ocrSo=U#dI-N%Ncm%j|J*H^vbH@B}ptMl{f{p;^5u(tkI zyleC9wO;G~;XBx>53P07;eAv6`C7`$re8O2p8MGUc73qXmHR$^bM@P=!|Sg*|J&); z?t@K#f?j+Ft@>c2Q@aP#K3M6O_rRtfQ@!{u(W(zNy5&8X_5r>0f%)iDyY~Yd{kmSM zTh33t59m8B-_!RVz4#0gx9Y=qUf^l{JfJt`vGwOY^fT5)Jm|xBFwPHoahy8s(CQvo z>9Wz2?+3nvR{fZJPOp7C75?}R&edg|x3zoFJ74@xp|!tr&+EOfz4OEGvES*>f8xCS zuPbx?T$^IyZejpU|oH4bx8fp=kA~8 z)z(qBUidtg&)GnpvsU+)y6C}okT`j5v3(y(^_1?9`xo@mZ;4j-0A2EY;xX^(^HsKP z--ldXx%tQYG1ZID67hrhShxKBQ1U|`=Yhm!ex3RHebDr2>t%fi`o}ubS8cuCbBIoS z2Z@*I)Ocz-wRNq&zAkmjd29X0>&ttg>p5O;x*xsx4ie9;w=7@NsjW|S9h@eN<`9VAX3 zn2NK$V_)|n-kTVN&8%VTL?+}HAZC3(dC(fyYB@B^tY^OnZhSBABH4}B`*HNTGRZ|!rJ z`UNj=X`R}7s0T0RJI0?Y$$rfBk39Md5~r@5YjM_hJnmEL{%F3jj_)9GQ1VR0W!^qt z*MIt-@{2gWgT&bnrsAyc*oWUKAEbZG@f{>i9XThyW8Z$K{J~EU-$CMFs?HwYrvLbc zzxWOkCvV4X`<(I*pYa_ep4xY+@pX0A|6EA(3BC9Z64&;(SzoUY=&{w0UWxNRSAusg zq7&ai;<@$8@}+*}?fRhU)YeP&^7{vgV_iG__zt$!E&U9?kF)ASuD;y-jrW%aeM@7j7=H@@K~_YA%g$phs&bLx=CIc2En)Yhkc zi1|*}%lJ;~S)Z57KlUs99SXcz2Z@8@dHw(XJ?1<0DYtLA`D>rA@x@>KgfDTBIC;di z`fIJneC>Ugx_jdz`Ne*Q=QZQt^L-jF_Pb6Y*y_e1Hg|C)~0>$ZI=|GXi$AGZ4BJqUW`^WXY&N3Bn`eVO*b zTL0R5rT@(TZ+$@TY3fhkbM%7NeOUYcqj!8?3VmX(yudjgV0@nBm;V2K+P-<~K_9+@@&1q($ESSfuD8A4xxDJ@o7;!Ed9C|}@8Dcs zxp}R1r;)%ADRUw`ZV17wD1`~Uy| diff --git a/engine/src/main/battlecode/world/resources/CrownJewels.map21 b/engine/src/main/battlecode/world/resources/CrownJewels.map21 deleted file mode 100644 index b521c9f85841e6be399417882a84a383f5bbf218..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16696 zcmeI)&x%|{6bA5$8BP4d5G0G)nT1OQK{tXhg1fwcFW_V)3dtfb;ZhXEwfHKoUAY?w zxSoZ3tvh#qY5O#1s&3!gLq={x@y$8s`@VCk>UNJYp-;;AdQjdkkIG4TP~Iu`%TdKr z<5GV6^|*ZWc_}}BQp$U0rF>cOpRY=}sJTkKdR?53KdiW(!*BxYbFe-K>vOQa5Ax4} zpMM%&f1ch}jPLK;x({>5{TwRR@5$xsuhZL#@qBLUKFsZ2;=Y!S_0e}}|J83ef&6nf zo{xKQFR{K<%wNByd~e#vK4RZ2A9=58>|PGF55D>w>Ks14eEqTbpGVE#n!A_R@`?3B z?Mol`a;W+F>Z9*m9M9#&X*{3p_O;jqRhw@8xAa<}`Q4Q^(JEQ}ga=nSE^je8+d{JQ?5qvwF-= zua&3g7y0sdu|75C!#C>X@nXFU%nUV_+&bD{EQd#`1G;fis|^Y`0Dud@)6bXW4#sA@yYn= z_!&G?&SJYKBF7>`a} ztS-MV^5L8LsN-k6EKkQLEYpYeM0eE8Cd)#Wq9qr;1_{9J7Lw(70^ z*?uyeesmeHmFJW3TJ=oV%12*u?|$&;pnR+U)H?r6*Q#ead2{#r;L-7!ihMF%tDfmv zd2{oJ@-4kO-5BTp{|$dG>KAdYFTMTqmxuCr@^g`I#JRqG`tz6nKC6#^(cmxt95@%} z9#Oq_{>bCk>w`xZ{d(i*!w;(W`c32Q-cxVC>v_Ar)8^Xzy)vDC&P86VF5ioD_4@MZ z?TeS``KjYCi@W#K+wXebuJ7Er^>Z!})%Weguh$2UZr{GqhaXhm*Z+Fm?mbQIx6R-6 zyT1SK`@F^1FJepATW_7azIeU9Egs*9E!{Hp>A(M%={x=YZ>n#0zghmK=34s-%&499TaG{(qkX$Mu^79=`nUfa7|_59|7@uJ7vlzOG;D8on;z?>pnF zUm;M2^~2Q?->=_4a8#KC_k+5Q>KcB2>uQ};9M+pxOFVEstn1zX;HUNHH|iSZxLeo2 p@$&PX*Eab&TB+eBcj)_iU4#B!U2oU*#nW$}fAje4`PtXc%D-nCRMh|g diff --git a/engine/src/main/battlecode/world/resources/EggCarton.map21 b/engine/src/main/battlecode/world/resources/EggCarton.map21 deleted file mode 100644 index ff30301ba75d7cc1e2ccd4ebb1771ce20f7dfe0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15904 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 diff --git a/engine/src/main/battlecode/world/resources/ExesAndOhs.map21 b/engine/src/main/battlecode/world/resources/ExesAndOhs.map21 deleted file mode 100644 index 5c356f6004669ea84b78548c0399da0f95a80322..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21816 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 BspJ3v diff --git a/engine/src/main/battlecode/world/resources/FindYourWay.map21 b/engine/src/main/battlecode/world/resources/FindYourWay.map21 deleted file mode 100644 index 5f57d0b6220ba795ef46f3cc6be62bb04531ac45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16664 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 diff --git a/engine/src/main/battlecode/world/resources/Flawars.map21 b/engine/src/main/battlecode/world/resources/Flawars.map21 deleted file mode 100644 index b3363dc45c27e6166e86f54ad356e3611424d637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18736 zcmdtq&x#yX7zOZ3j5>k@l`O=CC@N&F;3|-v_!@C1xDZ|V5-vrExb_`p;R9stYF@y# z3m?F$srlt{Pu1<}o~f?xIB+?h?|%PJ)y!a$e$;i{JKd+`Z~ODO zKTp2yy1&2ax<9|~x<7h+-s6Mb{$_u^`tI3J&wlu^>)z_g_18a7Uv>QA`s=TkbKos} z)#ug!Z_kIX7f)-vy5Y+x&$%M~^oPT=+XFk^@@I$Q&K1owkIQ=y(J^)1m*;#rKd%0gKR zbPwjW2e`ZMoWq_A$}10^s9qvJ@gvHwK7JKH@7eja=T_%Xtotf;cH8y2HJ1KzPJ7q4 zdwfLuJQPdaI$v9l>?h+6>!prG=^jG^|uJ(IgT|ehN7v9>-RQJ}t+3R`bOND%L{ElU>=R6mkTYVf)fBU5etoKvukM_3i;^b+ex?7>XYHaO$YrFSr zid*f6PFb(sm;UIFPv7@ezRbTipYONyIo@xruX@=>d9T*q!=d@;1?^EDJkh;4$i5Y3 zUnBRNCeq_rc)mKf^q?E$hubeZ?w);X)JKh}YwC}u-(C6k@3Z|U-c|>B#M^7~^mBh~ z)XzLF=|}g(rMT98dC!kMcjnLinG=z@%wV|iTlQ{97`F-u!t{V&*TpuQk`9dFWst;&J!vIAlLpG{-!q9&7W| zA3vS$bc1x8-%t6y!@W2t{?w?yd0bo9ee)Hav#+i9m3raX*T|QjQ}J8PG2dtIcVAtO z?N|ERYCr1GrG@i*q<2C2(m(U^I~LaUkFDEX^Ox_J$J$5cwI90VJ?@_Wh(+(+ygbk1 z<%8<1jp~hfSAEuwFMBz3ZhM1=#`DkkdSB)LpVs!4?)H=S<++xpRiFJ(ly@HWbuL); zvG1HMoy6xo4*9i^9~}2cN6#sqn0w88@dfpv9)2j+dS@T!!l!eab7_9}u%37Ne)5wa zvcr}=^Vd9eZS6Pxrt|9q>L;K4@3+Gy@Xb?kqB@2$NQJu(lj9uCSHU+J(yqpk<%6C{OqvIlljz3tm`f7%wHaL;F8_FJaCN9`PSxTKk9CcIX`ZH^GM$% zoX#h|Ig_(P_xivgd-~&$pE&m9?4$o$dY3)u1FCl_%=we+vqrkN-%s<%2U~XcOL*IO zar@#p?``#;>b-B>Q~9;_t{?ZF19sd!I}X#1pDW%@|DyZ3&UI*C^lPDf?(zQzKI}h5 z=+X7(2wn7_67;Yi>QR55^ylaP{L-J_`*YEsUvJL8_qy)$8Gg}!7SWJn@Ey+M8yr4r z==J`**Pl=N^Fe<;?9aRX8NLSJ!H0dYec7MS`txyrhF@?8A78_N-|Kt0e}A;U*7G6% T@cBkVp5A=@c}H*bIQaet-No_8 diff --git a/engine/src/main/battlecode/world/resources/FrogOrBath.map21 b/engine/src/main/battlecode/world/resources/FrogOrBath.map21 deleted file mode 100644 index 83d70e552c5c617fb0358293230b25c64a956468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8504 zcmeHNyGjF55FHcIs38ibh+vVz!otp0h*;R#Sl9*y?Sx?AM_7uW_(RrKc7m0ipWxi= z9s;wB_px&~AXywv=5^-G-7ON?0TtI4?a`11v_)N7rVb;~nC*b=ct~`APSn04x?ude zB(5P^XFHwTUY|`)#&%Tj zl{eR(KHgNlR((Ew)_E)4xp=Jim3+B$Tk%T0R=$!>?U9{3OFP_-_ z=cTi$x!QT;ny<|ZjW?w$bWW)5dDYe3L-yC*qu~3l{JumSDCcN#S?BW$9{u~euV2gi z^dWyZz1~MajSq3u0l|a3L|UETTM0fG;{MC50P`|CUZusS&p zKIXv(B3>84r(u;p?s=Z|hxKVX5TEh+&OI&#SxTpx4*t9)_$+4tkQ*7iai zbxr9l=6+PZpIOiM?T5WlXFXr?VQ-1D?!WnRU(L_8w>A&)dCkRqiFNfzKKPOsafz}n z)|Y(J*Z4x~w0;@)@%i$S&*xk5S@A%x^6R!Va<+iW|fxjt8e%Y9zrzZOx;eRla(wl%g5HjYoZT+Y4s@C$}d{J#JI diff --git a/engine/src/main/battlecode/world/resources/GetShrekt.map21 b/engine/src/main/battlecode/world/resources/GetShrekt.map21 deleted file mode 100644 index f6677ff20469030df8779dd673779ee546812292..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33080 zcmeI3zm8i)6vii;1r`!TTSRCDLP97MNEApw1(M6q^8i#qNOULb7tmVucM5m(YNQ{cm7>ZVr%y*mDgpum)=fS=`!6;7wJ4> z%5qA#E^np}zD?<`FH-vMvy^_#ct7KltlK(e$kJ*H1IHZ3^Dy2I;~p6Iz_Ur~kby`!4%> z{Pcdbaq4gPhhG#={dxKMr_F1<^6=FA(E4;g-gAJz@*q#`{m&7+$41@rm)qChD-Si! ztGm|U<7>5R9onbbtvu{s{gJJ>x%K2z^zz`Z{kO{SXM^y$G*|UR@ebUEcnQ!+&msKU%-#x0K$hPxZ*X^MMD9 z_GS5_xA4^VPo4CQY$1LgYJAk+^TQ7RT>FPNisY|F_78gTz5Qvtmrw0F5A3Q(w(ORk zI17nW)V^wE_^iB^UgMApK6?83XD(ds^VGENT^_6NW9zA}cCS%?_~+^izCV87y#86u zh46w}FZyWTmLELIe{7jLK&#$fJ^WyApYY7JcjfWwBY*2$h}S&m3-9Cb=X?A?<@Mxg zUi*8r-hRnrp;ssNY5ZLGzw+4kH2HhyK|kP>_jvn1oPWOOfWGv7rZRriqljJO=8}~k z*{Wmi{abld-z!tM^3X4cUn{~>yC32dYk6w@$w!>d2N}QKxxl9gzv`EkH7{~+pUg9g zC9mGcz8vLOKl)U?&KtkpdB9`wTXxG|^}RCr6>Iw@Ugzq`CC=Zs<>&FM-KrBkSlhq) z!{hA-KSkouBQJ#|kM3a|{=F6IWZujJ*}`ewb@S(Zi(mCxCwBB8^|vBC>`P_zr-Ia1 zkmsO%|IF3HX+H9T_0K~r-+J$R1p05?x5mN8epN=_ixw~SSo|8t+|YyYc!)ndtyp+; z|MBO*%WKt%-s>}JhmZLqD`NLh<5aGVkIt#KUys+bm%gn1^BnY}*10UfN zc17huZuQgtRfgB=6FdIOQ!B$me@h{G6zQiI;a#f!T3+gD-G?`iR(|RszP7JkfAT7N z{d#ug>#eglo_d&f6p4%W8|B3h{@(t2RhuXZ2m4-fr#h`;ivj2}qdir7K5BV)G^KM+4;5WUxD)DEB5KYsJ# zqrK0$T8Af7PjA1P2VRi*TZo^9R-Ed+chx)nb`u4AVvj_CZ zip*2>UYzwNK3eN-;-yS+x` zC_jGG8SP*Fh-V%uqhA`myx6t=s7$=oht3muDWo37+I+-E=V1B41L~ZJQ+=;&iXZfS|>bLB~Yd`3xSbuMq zcrPyg|Lkc!YxD2Rt$us;@Jr>|guw-gm9`)_H1u@PNI0w&LLjwT@%U)M3>d z)x)FpqX%2}Y{kK=d0S=pqJ7u;!QWcn+;P;SSlbu=%JcuScdyslcmEEMw{~8{(N8PF zqu5%H#=)z4WXp~|imm-yab8~jjurI$Ejx3FB0N^zQ9V4hc|Cu4LC+sM{uZjA%F(`S z{j7S>NB2*?Ao0i^;t$sLq5klYS7lF+eJP|K(8_~d`iI;$ksftgYYbk*Z zH7~NYf9k*w)H$ICi90ruAN2C$2WnrIj6dk*xi0&3uebL)Qx>Nfu&f=N+ z@AF;PJiNT@(?gHvy6wzAieA0&6hC|a*r)!_&;GqRyl8gzSc@;(oJPN!35@socn-#M zFy05_9vJt)xCh2PFz$hI4~%fF4OIFk9+`Fxzut$aSp=be1s%4fsFi=S_t-8g&pb2gskb2Fa}*Gu`loX;!yyqeGb Q2M<60>YE2&Kg>V>3oSEQ%m4rY diff --git a/engine/src/main/battlecode/world/resources/Goldfish.map21 b/engine/src/main/battlecode/world/resources/Goldfish.map21 deleted file mode 100644 index 116a291d85b2d38847d61b8e4a8157ee62619004..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18960 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 H;xEJhV@{M@ diff --git a/engine/src/main/battlecode/world/resources/HappyBoba.map21 b/engine/src/main/battlecode/world/resources/HappyBoba.map21 deleted file mode 100644 index 9ebb2dd4df083c7b7455e29b215b79f469442af8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10592 zcmeHNv2GMG5OtCRju1kSqUh)-K%$^P;sXvv6#N855K5c06#NDPYCeE=B??+tqau40g9k~Oya7&F?|0^KE@&1@lw~}-};%Kg?8TlxK{fJ%j zsq}aAHtVMShxQBgJkfm}ubz){{&jq-U-R}mr&b(me0cm&{b};Ibfq63T8CNxxcBy{ z)o*tv6$9o=x>gKw*`l+)^UthnjIGafC zzui1>>lBZV`xuIruIE?n=bC8wr5YzM(c%f!&2?5>@)DbVJio-T`^h-O&2`=V{52nS zgkn=y9oIizRC)a}zOQtx*Ym}7oKmNbtNq*kP~BYT*V*PN{l@3pIlVVK9+7h zUe_UPeY|*~y16b+{#sAIK6QlRtl$4VkbjS+g4R9_-S?^JNtK6Hk5qh9jjQW0)jU(> zrS-EPn~!mcb<6o^dqLuhdjA(sQz4e<>Hz3%k#8-?pc>y`>-t@>a=iMdFA4@ zbaOmc9y5@n;m>>F$!_Mx)3K$>rCiF=6> zYY9KGXE0fR0+VZpk705jQRaMO;(H5r2PXO4tZ)UC-0s63R4BfGH|g)};A0mTBGIJ3 V2NPb2cNcaKCbJ8e%pbsn=MUx33B~{b diff --git a/engine/src/main/battlecode/world/resources/HexesAndOhms.map21 b/engine/src/main/battlecode/world/resources/HexesAndOhms.map21 deleted file mode 100644 index 6616991ff680f1fbdd525e20e5031c8b19af0960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24856 zcmeI5zmC*56onnapDhpqX$ueV6rzpYnK_(%(O(be#2V*6X=`JCEnDe|!Dz`?s%N{QS$iJgvpeFFu`aBu$+h z3W51JP>+N6f0eKE)2OOGvt9_qA7_@g$FJ4z^;_%uo6Xn1r%IPPH#}SWkwaVaYxTq1 zJ73i2^%>)!(lg-yZr>#of>L@?@ z_4e`j(O;>`w{ng8;jYeO>-bT-&b*gjZ;pN8hf-IH4^=+u)%QWZ4)NCMgL)kCS&inR zJfl8)4mF1-YJJpEyY9_vZuh*;+{@YZD96zpe3jb%(YeP@t*biwdh7T`75=E#4-p+A&$jPF#ntQEyAC&W z-+kcTx=(M8eJpqCp7!RvzO0XOrw^+7jq;;^Zyz|)r&UMuYCpwG`MtXB*UQV>r?u}W zztOz9kL9I&(Yor_%1iCn+h>&DXkOiiI^0m|p5jM6e=on@oIOuH=b3yzcGPe4t#de{ zD$hEqe5wx5sH#4yUeBdDvyRe-IZ7Q>b=EztdHsGodC%vqNBiJgTBDq-&(7_+ymjlh z^O}#pzOs4dOZB1O(h8@jvVW_e+|)u~J?|q$zmKE7*6(|LzHk5U=Uy&)j?w$BEg!u% z{G$F=U$p<)_>G>&fXIRn`5r_QFU^o_g!0_ds+23;K$dh zm9CB7=y}vVsYkisZ`IcRqxW4~KFSMDOKWt0e23!4ep3s9^}H{^_api^X!X;V z+@ZAYdwJeh^f=jdJ6BwzK9%pS*L^R~`|64lbrc@VQR-H`b?awde=hic4+S5&sMd4s zet)Q3)Ti>j^;T}Jes!*1p3z({&)%H6r>c)~?9E5{sdH0Tec*?0RG03@d3yQv<`pmc z^{VZ=G_R%manD2ZXJ5;UdaJ5FOY>T~ANPbmO5IcZsOMMfil6dR_j2`I{?A+bDP5|M z>Q5bxtxA4W;ThHFexv-zNB5h)Lg3=-T{yPt@fC`t$bO{dc|Wd3tlU&%WnyMZNv- zp`L$q9geDxT32=Yc}kv8};>a zY|T{;`u%-x9bWK6sVl{YDxX)6^0a-t92`-bSM#X9-dl6G{gr=|UvJ*yXV0(ZULSb2 zs@l)i6<2(*_4DxmcSK*bmp^%rA3m$SIooHcIh?I}{YUwY<~d)KXVgdEwJZG4*7Nq} z)IRW4s&bdT4oB3x4?fiM&-FrJ_qtH=fM--ypII*ieBP7ORpfLhf11GY=JN!O@}~vd z$q0_~c$&wrdHkNoA9>u&<4-Y;@+S``7X<0Oyb|2mHcc|6PGejbnVxRpm)`zDWv m+h3R3y*$3%&a-U3itme*@~0cr%$HejV+CfrE_z diff --git a/engine/src/main/battlecode/world/resources/Hourglass.map21 b/engine/src/main/battlecode/world/resources/Hourglass.map21 deleted file mode 100644 index ec2d0cf81ea9775443ecf97e94edf9bdbb42766c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18712 zcmeI4xo#9e5QfXJ;N_6zz!DA#oFEbcBtlZZ0wEDXvV?>oBZGvH1PR_~Gg2ObjDQEA znwcMVeo^WyI&1oQ+xOALoV2d{``mc2fO|}G(F_f_;);V?+fhrRQyxL&&`SR zp|7PnHFwmPD-Uy8I!67ebS^HjJj^N9ujSA7rDN2=abUOfSpOIoEB;)&m2Ygl$UD}b z{bFOpXU*$)p2snNiv!2;9+%3?Jb3KgXDnVR4ydbC{{Nl37ysNGz4DdXci_%?ZarQ+ zxE^b~G~e7lt$Mue-t|r8HPwG?|K5F#%{$l6tKO+Rr~1eG^Xem(C)NB~>tAc#)_Fuf z(3W2*JL-ZiRY$J8=o30uUgSYuXxQt~!{4=2*98tS9jha@9`ms{^XKz&n_uVOe>Vpo zOULqA>)0NP^RLe@<*}pZKT~-v%|A6?Y5%ePGFR`h#bIoH*7{oQ=*y~aNBcPU*s3d5 zx3#VoyH$T~zEkrtKdTS+t7UA}JC#Fef97fR#eSv6R(+*8F3rz8tv=Z=*Vw9OY2UT2 zXP#Ey?3a4Xb=1bqyB_f5zG2U$Ilp(GwZ{Wz<^X$Y&3S9*eO#`W;|XWYMg4q2byvOc``L4AB`J#WM3+TQ1( z#cOl^4?K21bl)#W`sSdM-|r4OQsarrLzP!5Z&co?Tvz$n%Z~$*ec9@J zhc^1=p{>rJscck&|NUMLRR_7#OPC9Ow^Z(_z!&S(^y>)rgDZbNhfkVXg6XPC@V};_ TuQHPJ7q4GFyLftesh@uWLw9cG diff --git a/engine/src/main/battlecode/world/resources/Illusion.map21 b/engine/src/main/battlecode/world/resources/Illusion.map21 deleted file mode 100644 index 51344ee0845f644ddd446b26501e30fb30af26df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10360 zcmeI2y=qiZ6oq%{E+{rJZF!2!^0`R^kI#`C`69Dhq2X_nDb5 z!ji?FdzdhPxp4Sq?X%Z9KMa8h_b6u1K^(`UIEsU~ALAG$BXz{&?S6cJ8u8{b;_K^( z=gD`;7tbPojb`46-=}BO=j!xi`uyBkJ-d;A_i=kK?FO#?`#$hJfxC83oEvg}NA24- zU7efrI^t)3(>3RC;tmDiu6}p zG>1O&R;5{2$-XM8&*?>T=p$!Unst@ztD^dx9-2cxc{iETec<_lJ7`gMd#OgZ;txNr9M=v4?kqyk-mz~ul3#>^^r?`s8%0- z$h;$c6`fz}y*cV5mpWR1-|IXY;!`s3sQpemzt)|fy7r@)hgu)1H3vUr-jTkF&ad^} z9QBb)eW+F+e#pEdeaoU-hq_ybc}QQcRv&qgc}MyxI=|L?bJRyJ^`TmQ_#yL-^i_0z zt@q}rk6h~L+rPW*M*9D+&OLIkO6DE4-)ZO9y7N=lel+t?>qE8X;D^jR(pS;>wceY9 zkGy4Tav}MS^i_0zt@q~OBX8N7Tu8nneHEQw>qB$sC+DWMuETmt`YNi==|ywsBWG2b zb(QR^qWYX(G>1NNR;5{2$-XM8&uN!KKlAIR*%xGg73r_2IrLLscdh$mzmD`*#82O* zYtG@w`6}Y4Z__pBaO8ZB_?X`|&AF7EQ%N87ZP%O=a$czQUDMpdqQCFy-}ZarK4zTc zn|X)V@8(Uic$nj5j!!wh-t{GR=Sg;t#da=TldxZ`R9-CFFxeQ_zNQ_Q_uha diff --git a/engine/src/main/battlecode/world/resources/InaccurateBritishFlag.map21 b/engine/src/main/battlecode/world/resources/InaccurateBritishFlag.map21 deleted file mode 100644 index 5471ebac46fa46b554d7767bbf4cb00e3ce6d16f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18752 zcmeHP&59H;5UyQU9Z?n!BY5y2=)t=e55j_oD0=k)hDCHiJgnZ;Vwm-^CynSsoS=r%p1`*fG(EjpqZOQPooL{C`0c}ev8 zEzzH+L^oOfWO>B)J3L-}TAZGKIbU47dv<vu ze^+{~^78-sWSy2A+xlfaxbB!;{AAvjwe5p_<6qxj;Sr_Jr|mEC;kcpihq3ct%Adv~ zzruS=qJN_gZ9j~Sf8{I2i`c{bXuQuC+Shf-8XNc`P@ER`E)+E55&G1Jo)&geya3w=GM#gFYTYk z`?$rPi^uYpytcIZ-4|X92hRJrtbXLqYu~Ug>OKyQYq#g(DfLgq)%83p$A^8jbicpl z^(9|k-PFF8;@fn5D(=4agIx!C5xyFk+aFy&=0)AFqjBx_Ts*t>PhFSIQ@AhI`s}>z zyx92#7v@1-{PLt#zqa|l_rs?7SNzB?>Ulg%-rD#q#VhN!CH5EfSijNF(!1t~#kJc@ z`!}|Ddml(YQ+c%fa6UJ`_@~LC@s-~1wDk=yAM$JIwXQQ4x7CMf-gQ9#AD{X$^<&x( z)B7-;1JgM$odeT3Fr5R_IZ*RCko$e1R{z}hwAOWY!(H$15f-n~56chdQ{%)hPY$i$ zyT+6LdlB-4dW;A3v-GZcVsY*EUH8B5`rGCk*E9Y9)9gR&OJ925eB-({&Hs9SdB3}! zD-s`;Sa0b1uKC9PY@7e}dcxy=?1!Q8z0QZl1I`P7jl_Jpy7mX_pzhbzxORIko>Ko* zT=shxURNnTjJI*L^MLtEb?qP4MLpafjStV4;=_2Wp3WnF)ce7^jvsMYx{nj{ZCWqw zpT_&R#h!~-;%u4MN6D9qr__IF@4vMk>648+%(upe=VSG)xUP6&_4=~gxN#r*ed`Nn ztd8=6I8pa;Yh2ha_2Pb*ANBUUl7H8-cK)${$`|s1dYB)LkIiEq(Zl|TZ)p11_{aV# zpTZN$FmGMsu>R2XvGb4pPv76W<0*H#xIs`pg!ZfiChln>&By%e8AFu+4bKS^`q=Kufz diff --git a/engine/src/main/battlecode/world/resources/JerryIsEvil.map21 b/engine/src/main/battlecode/world/resources/JerryIsEvil.map21 deleted file mode 100644 index 6c51af4652c32c05ae696248c751b160a7d28e40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25912 zcmeI5F^?QY5QWEY11;YJzy30O`o|94eRJ{ZcjxEwYkg&98O-s298(X1=GLBVRt>ng{vL?d!Dj z^Yek%+;}SQx_F+y<#mev(FgZXk$q72)n1;@-18@Y)J=J-UD9iPo$C0Mc))voKFnz@ ztkWy&F~(ynuCG@epKbo!r#iiub4j;t{^)vBaN7L22VlM*Yx6$NhdveQ+u{26xwW2A zAM|ki@$dG3PIO3~_4PW=&-INTo(``MzjNS7XiacxkBu@D{yBGbI=UF@ds7LNo{n2*3(Ww@5z1n`yjf*^L`y|fs z?(Mu|z2*5jz35B#@sFr{;i-PL(W@5c*Cq0*?Ta|&r*^-e|DoUMtNx|zs6*C0`jv;; zjxTZOR*Sihxpav9YWpG%UW&b$`(YfsVjuJKrY=Z*Y(@4*JmhiQuW{&Bi}ULcdDZqs zobpq#-pRdLtW@Q_CwuzB#&au>-xg4e4I^ReqZ~*rXTFNuvCZr5giZwCBDR= zqeJpIB+pcIdGYV|&#l8!UGkLU++5M!?brHU9{ixo$Nq>VKJ3@>pQ&N z)9!)l)ymF#jD2a|(!R#eZLc@CbLXz-*SQCIo>%vCsB`R>Jaf;R{D=K$|2Nf+y2AHd zWIh>N>l6FVbw>ZW{d4}=ox9HCxSr@xi|gwZdDQkzT)s!D&$DJno#4GQe{NzQBo2H1 zx$Atc=9l{(M^<(RK?B(7Mb#u>sjq&hu2tP&ga1LAJmgCR;iaKaN^jYrvG=0eHa6TO( zUsvDx(ZM0VKmIMxO~1D}=i`{mQW*7cedWH1AAi14p2RtHx;lURdqDpqy1LHqc;R>Y z_1pX}|J}UP)%n++KXX%L-imqtS3e&ZOJSVz>HXHteP`xOJ-^>thsf909piML`O!CaD{Oz?OZr7UTJa!{ z>ZE$IuYTNf75r3ynDpHNZ&^?Jr5 F{sZ5N4F~`L diff --git a/engine/src/main/battlecode/world/resources/Legends.map21 b/engine/src/main/battlecode/world/resources/Legends.map21 deleted file mode 100644 index d83ae96b62d7bb7231e7251c9385299c92e8589b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20304 zcmeI)&#EO?702;X0=6K*L959?h{S;);y`dD^b3ejkj#wEocJ0JC8+ok4xKv^9pwcY z1fjt}KY~@a{B(JK=lrs(&Ywsm2a0d6-&%XEwb!n?_uQMC^L(17uTS5d-kaW;`L*e- z>DkO_`qP)D>3cIj_}Mgl_~U8%>&)-Z{N2pAX8kMk_0x}j`O&X_{_E*4U!9Go*XtLJ zfB60K`tyq~c-tI)^z{12i$?Qp=kRE~^|e=T{q0?U?>O^J9<9^%b*sMi@yVO#?y}wQ zm!tdmU&pt3Wna!Kb#}}1DE;q$TVDUF&#k^bouAye{iy#B_0O~S33L=cqIk^s>@)pow|PBE&-&Rfd#!){ z^B_;wGdJXCC;2h`kG9ptbzd*9{<_)ba+<%t@3sC~s*`i0BY)PRH(HM^jxG-ANq$`W zdikICDd*h#{MetoN&b5?>)5Y4{B&%7deS=i_A>LZbN#BH&;PRididP5I_mOY%l36m ze)GbtLr3e7j&!7B)A^IxkM*m*{~YA89!JlOIF#pBI+r!?tF!wg=g@3@H9uV((v$p+ zm-oH*9K^jodw-(dwdY};m-`!ke_89FpF{SePi*r`z1gEY{Oi8V@8#M2(tpgp|9Koe z2m8dF`^dHq&AZvx>Z7^JJBqvP-|ka+l1Jy@9M*OH{cYA^nIC%>AaF>+A>p9L>&n^BFPgp4#WX_mEFrq$l~2Kl@$%k3R?XQ6H!KKL7oK zI2^^xKcaleQU3Jj`cd8H&ph`!m&`k=pZiNY^QAxSR*#Ry zuICkx?(=AT_My+zn?0(Re)*Fvf5zQ<4y_K|+#7R0X=lIbPdnrFf&6TwBOSBO$ZmP$ z!+rDjzNmj+k*`rd=sd*J_wMW3c=b>ocCz{Dqkhvbzx8My`_7}EgM8|s{QStDO14u;=QQf0Fb}pWu*Khh& zf7I{DFAt9PAr439F{;lmkGzfIM;z^=`A6rXFa7F+&c2qJr}aq}kNV}4~%bV-i{CnBf(J|*a>a+Rf!`3H1W}N#B z`CB}H>q{Q%vBlHn70VpK`m;^>vhc`_*5gzV_y8eae${T0A}D_x91^C@z|NOs?s?+w-bbVQmO&|HK!&a9r4(W~J^kLp~I!)(qb?D-d z-k9f*_1W@a&h@A*5319cacpe+Yr1u)E*t5MEk9izq&JFd_4x7V+*`bS*y@jT>#^;# z>DDDjb@^Lfdgi4!ikBbh*yehxE^)mxnX?xlY4@;tWZxB0EdQGIdA)BJs&?VK*>+w!E}9FddPnIcI!}ql;&cnCG&t_xH)$Jdd77#_J2SZrb87^PSGQ zpG#XmnhU@6Y@{O{=}5=i4;`(`xV+EPzt@&OX?>nY+TvFB`SZ6rr+LnQ|B>s`Hm}UX z=C>~Ok>5JB{@#>7sZP$n*=u}1kIZlX$-Qyb9gVjy+?z)o>mEgQlIpejkMwo@`0r-S z<5A3gwL0R`Pe*gPmh0U5_ZxL^H0OK!)osjuXWVFh8P6WA;}@TOJjzzD%{l9~xc^tZ z{T!WhY4$po{ygNmb{=%J?(;eK{(Fzner`Pvb34k`m-9$}%b#(dciTSKeQfu6+T!lT zqjPgk$)kDh72oD?YyOt^(Ym>g`WN>FZ~I)bedqc1{3&zKpFU^q+59PTZ_kUK&(}}p z>o@cD+xhzAd_9}5j|bPY`LpVl982tSEuU4laLKoPKHdBC_2v2c_I&+dzLr`)oUi|m vS^P_!n8m-uEiqnC|6T&;&%;~({f+th)_lD?U*DOprQSE^>z(;}Z@&Hw^)FBb diff --git a/engine/src/main/battlecode/world/resources/Licc.map21 b/engine/src/main/battlecode/world/resources/Licc.map21 deleted file mode 100644 index 9c4e687bb3a8393f26ded5ed3e9a768d2b88c80d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28944 zcmeI5J&qkk6otz$pb>wv1i^$xvXGD*A#x{>u>oQ`AwVK<=nU3?1nXcEmRN+-$-D%r zb?0-dPxqOse$}tvdrXbgI==t6?y2f}V-L(tim%7%X?l`w(&O}5x=vRaQZ`P$RQu_O^;p@%wj(raG`{1_kmj`)nly{Z;d*o8zqxm+- zUvHl~jCI|p(699;uH!HP&n(S1rD)lX$T?<%|Vk00p#x_&zEH*((A&qsMx znR-r-Jy7{mS^HDF%Ie?c>AXAtI*((^aSq;{&F9;?bLr2G#;eRc(K`&k^8K%VF$GV=Zg-M+(KLKnZiKGrwqS=Wi5>Q5!t@#5#D@hY<} zr^g-$pT6GIU;SF+HQ!v0bN>EiUgfR*H2+#T z`gwcs=MjxpnSRiNp&##i^liwwoZm-vd5L#e%1hkdex-W*+u~ETe&B0Ft%INHRX&xU_TgmLU+DKc|IwfFq%!bIAd_n+HmoLfbAe(_Vg)2p9*->mnG{lr}TdBsoX;^bQYR=Qm-$3w~P;+&p* zpz}lD>KF0*@lQR)SdYK&)nDbq;(2fD{fAyr{kE319&)M9)_$dWWjp(G9oC=Ub$RFK zKK74)|Cj8C)-T1aty}WP4wmYx{m?kgvn(s$Dv!J^$Jg6ghhl5qQ^&I&?E}4{`Z<|6 z>?)(*29L+P_IKQM)bB^_Ypu*WKo?)KyEyc%@#N{)_VeGt1NScXz2f1Y<2pZW{Omoy z+H+a!=lXArcX_*h-~9%UpqoE-(D`-!zWi-HZ}?T*x=zn`+54pP*ZHge@Amfl{-^KD zwtcDZedIpZwz;0`{NNXKePRclU)P^@pVabG>*x4vjdyvwe%<~F9{#U?|I`2eckOxL zT!JpXWOs4sTjR;IjLN&p+kKv79g53+ZCCf$`B{(FL9eKOP9_e!%ILSnjrd`)iKj-+%stc~5aZujxGbcc88ON_on5$G_^Qa_jl8 zk7vHq`r~^aJ6Q5__O*KIfu;CXzlcBl-wichW%_q|?18oX;a9?u&uN|ZpZ|^ZaPCIb zI)}>SFU7a|)$vlAetRcyfA+dy<*9JsDEu<=NI~sKkcI= zYrM+DqX$Fp@B6j(l0S8)$hj@uXRUt3D;~S9=BK{ux0m4^WbW{U9t^wwJZ9-Ut6k;! zxxc^O+<&>R^?u|5>BHe#Km0+>d%u3a^B;XFPbxECr^gQB2cq}r=21JhbMbS1us+3Q z|5Ni1Pw)q#uf_T}oeT2veDu9E@5jX-JD=uvvg)};# zy1x4JuW`qc9bdKeG+t%$pm!L4mv)>LM>A=b7`V zGI~($D&u!P$UazJ|Nec}@#6c^c$HbF(_;_3mH!W&%G!t8RaXBlPv^~jwBPrCT7N1l ze=0lv@B^J+*H7oYKmWW36r->5{jYJz8jrr?FoFF)XXrkwllAKY!jmFEb9$cX!Wq{+)wY z`L_;UXZdML!JSD`sKxo4Cz0^A)aFZ diff --git a/engine/src/main/battlecode/world/resources/MainCampus.map21 b/engine/src/main/battlecode/world/resources/MainCampus.map21 deleted file mode 100644 index 83cc69179170fcecc8b34922a51bb3f8c4cb4056..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19224 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 diff --git a/engine/src/main/battlecode/world/resources/Maze.map21 b/engine/src/main/battlecode/world/resources/Maze.map21 deleted file mode 100644 index 98abcdfad73a7ca5994f8999b2a221fc08701325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16504 zcmd6vF^-R27{%`}n1aa^Q%p&s5~V^RVFRYK0EHc>lnRwnB*aGS#1?c43vl1zCvxKC zJomnL#6NkzpL3q`oab&}zO(l8chc^*+wH8Kw43dy9d@>^Tl@0nR(tulwe$1VUO#N@ zPUo}E2Txl2dZPy}e&2dx`+0u+u>C&AT(;n?dL-M2A?cpo6pSkmyuOfF=llRe!hU(91_8j#dIrW{!-%Gu_ zx{rQH|7uNd;^^IKpX4Cfl4b?~gE2eiahrA1&sQFcz9;ok7U$y2{kLGpXY3)^= z_Q*T3&wN(12VGzCnJ4Opz0_09lN%-X*+V;y=Ey^O z(Mslfsl85fhk4SPBVQ%^j`T2Bjjts4zf<3>n)lRdaC3-u)61Rt9o2N{^%X@O4mm&&B;0HJ~`(zuX41fn%A6aeIN5g_FPWq zs&$XKBYEcNS*9MHt9ExaSJmXI|)YqOg*E~9rUUIAS-X7kQnC`fJ-E%p7&7+km zKRQqS%=h-vlbG&|?vr=D_%P+Gb8?V=C3DC;X>y~~-c|eBi&k zG}q?ep(eCX!*iLQq|o#Q9!-YT7X(!0`J`%}I; z*IuWS&s@nn@Mm?}qkk2-cUk0}+VA{oPWP)i<@Ekut@rl!v9G;os5yM4=2Vk+zMGSW z3c^_3!6Ej_*-V1Z<_hvGJSmU+wuq7LjUjf@9o#0 bbkT9ObGv)3f7koB{jUNx{q*^(7ai>fvO8&Z diff --git a/engine/src/main/battlecode/world/resources/Misdirection.map21 b/engine/src/main/battlecode/world/resources/Misdirection.map21 deleted file mode 100644 index a42e9982819466bda309f304cc72bffe00803a42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20312 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 diff --git a/engine/src/main/battlecode/world/resources/Networking.map21 b/engine/src/main/battlecode/world/resources/Networking.map21 deleted file mode 100644 index 56b6b022a8770f6bb6cfe4291f4bf701821718be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16664 zcmd6vzlxnz6vdAkWTFyM1PMVTf_9dI-6XAzk69zg}K{KI`Ii&DUSg5_WUCy5C;j z4}4X<-TR?S_d0t{-+zUx&$D~a)gJV#efZA8)&5m|bm-MUil%M7)pZ5hH zyh8Lw_c+J;quhPwNAvMJ*Bo7i_U-bjhkcdL`-2{y(0S-QhqEXDY@{dQS$!#=IX&jg zLH4^y4!E0RU&><++E;OWM*F-sx4z4rv&&N-dAs}M^PC>g`!2_S6j%GYdcH4=T|c^` z&u2fmV70dnzKisA{pc&~=Am;Qb7NO$pSeE=aO>O$w+_y}Li9#_o||`d_L+Bc(1Ff5 zi<4hr>cf}zX^yYLNeF<0d(5F1l(HnWb zgw`kSK6CQzXO7U2PYSukv)j-EF^ao>GyrRyzB4kR_|{; zJ)rmI)pL?#bPhb_v3E|zQ(l_W(?$2E+%(5u?a{3w&yn&yC*Sif$Dc6ebnlsR(>(R< z&bg(dUkXDe-H+Z? zOnJL=KR5T;&BI47$ejEx;v)xSzKiZZE7$jNPnSFAY|cG+ZunU}zJ;?tPM0XU)2g!qX5g+$6c5}Kq`np)IGaQ4QOk1wHf%$@7~Do^)dP9HpBS6BI0?~k7T zvyfac-J5;tO};cI4@|l2&%$&c`qQ3ySBKt+pXc$OIl6@QB~D(#g|VDIqX4vAoH`3+%Eca0Pp&__o^P>E_VB@bD#IC zoV?`g?$PaH>aXTipZ!U1UB#VaJ$ui0IeFl24nA^>-oq2xzsplT^WEIaSAAckJ@bV0 zvgbJxqOUOdSLam^`zjaRQG8WB+>`eObU!*H`U>%(b3Pnh7x5j%)VG?Oa=P z=ktCfv_J8#-~Hw(Kh5nwi_^E8hkq5jeXF_XyZPwwRaoiSS6KCUU*#R$yU+Y+e&u)H zQC{_VzuV`WE?@2I=H8WV^}f6MySjfjH{ILc``x^*F7-0+=AgUvJ(#~F@aX2Z1g_>U z1w5F;NAr9#&x?6}oag6x-kj%`dH#Ow_Wb+rtNA+w7w`N@ft&Mm;zj@7Ja5c%|0Q1d syYpOjPv*Jk-=F8Bc|M)zgLy7HUYEb;&l=3e+c{Zp-_CFRm)|w`2bKj2K>z>% diff --git a/engine/src/main/battlecode/world/resources/NextHouse.map21 b/engine/src/main/battlecode/world/resources/NextHouse.map21 deleted file mode 100644 index 8ba4153bbb73ee5bdd551156db303d401e7d7e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16592 zcmeI4ziL!L6voFGFhU3^QlzvRAUelbKlU4qXHLt%HlLLzs;3?pjl*v&|LnoT z)^k9gt@vi~_&u|5?EbVb@_=gZEw|RG<-gQBoz>#lbI@yF7VoOJ>apiqwDL`@haay_ zlz;NIV(mHb`uFV0uP1x?JiDF`&%d`_`LXgJE*`(Gp2rq1nhzO&20N%xAs+qQ?(Juldn~_=D)9sB_iI*86~$hkg~k zxK-PA|0-Maqh~&k5BwChp4wIR>ZrYSpUkP~<<+@7*~_PPFJIKIbJfc5qkC5wKSk|R z?J8^Dn9TQ6t3&PEl6C%Cxt6b1f9;RCVmz$h_rrJ9H+$24w(?UOuk~wX=J2rWd3Ddf zoAu)7&YMH`WBGgMinv<7)L;7koU-I7F=R(Xy-zuY5gl7xYKPpH0!;gMJ^d905M*Thh z$>+^m{H}SA%CWru|Eos(wCY*BqqpKby~l&vnFCb2CF2iTe(3Rw@{fPPv%&vs7X6Ta zZ$DA{&HATT-}|Dk%QJjmf@ce(`PGkoTS))^M!pZL#o>OmKK0-qIf^=`$|cWm&*~SI zd*#zS7T@Tj{aJpxcT0}$UH!PmoPXw1{?Si`@HrNveKA+mKkCyev%JbjPx5HCTH}LNsK7E{?FNeL{^!>%XHa&l-dCpb8JL~h~ zu$TIl+AHdshcW-Z`p%Ov`#jW-J~v&Y&&O6=KBIGG`BvN>sGg7F>ynOrQG8w9tdB0L z<6|o>zbVGO)}2cy(!Hbnx^uEVx~Ptit+@P2p>w-`6mOk#)w)>ENAvh7-b;Ph+qZO` zeIng^q`J75xcZonzIxQhM}2%0&lv0YnDuQs9{1t9kBsUt*0s)|Z(a84tBZ4DoWE__ zGu~&fufO*k>U%j#myWsoZPPxz_pMIf-2Lg`Ts{5tFvj`Eh4ys68P$#2n;tHuOCLwg z8LeYK^f~aCo;OP0zBo#EX`Q$)A4kupi=*`E;kI?{f!RJ;K8t5My>YtO+t;e2hpqZn zo{rxKD4zApt4DEtd~C(#QQs+7`+M{0eVvT^@^cUwKVSJ)+|Mbh*B>db9>rt*sy-cD zwLhz;hgsda@k}?1neQ%x~_V%^v=wYjV)jVC)AARxTO8erdJ?Y^nT{?8* z?*nml$Bp*OIBMUhKU&wlXEcA*+)+AlFFuZ*GfJ0EcHdcC->7rV)rtG?GxpBQ`m^|| zy4n4<;^z0xTe>dp!$QJ7K?uC!) zGseDHM@L?)>A@AJ4a`z08gG z-tzTrYR{$TI1es8FY24y%h-SFPdD)G=>Mzt>YD@mf8QP0tKZD~)$Uh&TkT!7_tom_ z0_DSzJv~#(WIvB=x4w6=f>a--V0Y6sOWR-1BD?VV~<&9!QG ot4;CAJk!@_&i?VlC%q{&=}mLaSG!d0(d!4V-adQt>RDa-7wM}CCjbBd diff --git a/engine/src/main/battlecode/world/resources/NotAPuzzle.map21 b/engine/src/main/battlecode/world/resources/NotAPuzzle.map21 deleted file mode 100644 index a169143d427f8b44071f4f512bc78766e5fa4780..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33080 zcmeHPyKWs-6g_baF%TjvN@0nD6e&SGMTK-ljfD6JLPI1PXj1V36ch+4h=ypb?%IoF;mZ7uKj-e=9++_4>>r0wfC-Ai}VNjgq9(@{D! zOs1#w)uV&-?sqBu^&q8xKTYXZ!`}=~%{B#n`Rw&{v*L6D>p9GI9sK-gdOg_y(FeMR zt#PgSJlDR~!`!{F*EwQe?$7#VkHdbs$mhd4>ad-4FRs*{TQ@h(>+j_wUZI!YYH!U~ zbF-iOv5t7Qv+l)}+H>pX#(Dj{e8emC@>}h#`D$+Ew@-`qI^B$pYL8O?==);6(!EOK z(Pwll-Al!fzAxred$jt|XLM}clk-R47xVGl(K`B!j(_|-&}90J?8Ec#XsuIJ#TJ(<||tF=GZ=$K0f=t zu8&^+i}pXyo-Y;FKZk<1D8&4DK8MaYw?CS1uE+a$I<5!L-)6^kQOBp5!926B z@;Dwk(937OqIIt?+qZK*p6UBU<@|%MDCB)TUGc?v9ItfFkLH`}aX(LQ;~)Gg^zVP1 zTNHYGDm(hCIQUh(@-tu2I_6ZkowN4-2k$<=dHtXNoEhgjaJM?cTcb``Ju(R_0~ zp4Zd2bFTa=zWDr9yz(<&(K^rT=`sA{eZWKi{Q>6`h2EaZj{YhReig6$(R_0~%sD!K z@a*;Xh7srIA;&`>eP7JSd`0W%GdeQA;F0Z0N8afBV!mj;xgPrDB0q2C=C#IwH^yAP zIj?n|rSh4tXgzli=AHH2I<;}&Pw~xuFRylvrSqcs=6Y%$=2_{gUacQIGBV$+b3F9g zIhM|2zM^%tkK&vCs$Q+1d2Q8e=U6%~ns2Vh{Ee!6eB*v*zh_6>Tzi&YA8HQfD_U3m zNAZI=dL2lpZ`=zC zQv2|AP}-OIiq=c#=@k#&qOjK`^ooz-9d&x`QQDXJiq=c#=@k#&q7d)P zz4poN8_l<>mpfOlIPeyA9iUFHeM&TctKZ{sG&^{U!nyVmA zXhSQ^jIO|7~&*KRv_&*yh{J-iR@ z&%gi78+2gazE95oj*!Z0<(c!t0-~9eE0Q4%U&MYmbgwx^F-X1rtavB~!)Kbrhva%A$~nf!1qrAfXpeUhKfL|Rlh3~X=9ACAefaRf{gnO(HUeii diff --git a/engine/src/main/battlecode/world/resources/OneCallAway.map21 b/engine/src/main/battlecode/world/resources/OneCallAway.map21 deleted file mode 100644 index 3af0bf051116e494869f4c4d0ca6c0aa720f855a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13112 zcmeI3%W4!s6oxBtqT_`SFpJqJ3R$SQ(ycHNA3%MCEOZszitpf31jQHe5wf0@J3$b9 z3r|hYM>Bu->FS#9o=ZqW@#jBvF8?{zxiQov6wgsO2@k>~9ECe!6vl=jJlPB3sp09f z5DwmkaPlaG*_#kXh9k4zw)OhMyH{uD=Py5=eF~@7LwG)aX45N-6S$g#_a3~TKYyo+ zp1)_;c(~`k?RNW?vgh}7DAfK_^GfZLFXiX$57j4m(YGp+$HVX6;&U?dbB*>l3>dhn>2)NW6#CFYwpmJUqNeet)Sxof8~Xf93dr>?_Ca^@)Ax ze$n9}Iux6A{al<2sORIKi>JezUtf0WYM=0R_lq7y^eEQrWBwj;F8Sx7y5PCzL7a!$ zCwyD_MUP^=KIX0GfgQXo=RrT~>zDUP&ja3kF6agG&w=+JM2~Xpis}ak)gMlOibMBH z{S>M$<;yy&e`l$`a;>lPf`jUx;>3aYE61+-l=s~)b#qa5b>*r0Ixpp^c=k0;Iev;= z`_p*M-<50rt~^&y+c|39RpYw$r}3(*Z?5%HJhwh`1asrnpFE)Mr+BJA-B0D~Yd^Pc zu0J|gog48U=H|`SpX=}G9Liq&{`Yw`sprU*7(@b$dEe z_I2ybt(VfDyT4rjPfwrElzDRXr2LolZtimwPp7BP^T%EvSI)86SMK$%e#&R=&(UT* zeq6nNPhbCbbc1d6;1AZvRp;03Jm|lg7ad@|9^y;HA8Z@fw;%Pve)Cu7Rpj^V<$UUO zcyXRRm9M(b9Kd=V)wsU=s0((>%UnR!?b+2Y#l1Y(!Bn2=K63!O&7+#%%SSy$&%c{} z_4zc{?LV*11KzBo{oK7g)bY@ZYiDOpV0XREb*Tg9*YoCpy}5pVJzJJQQzbDJ}`pTy|OP=bV{b6*K{ZYrm`ub%b#lG?~e|`L>_Eo2H|Nju? zv#x%q2iDiE>fi12;Jv8!#T>x;c@V#Dtm@sZbI^J1T0iIo+xDY=+s;${dHdVa*S70h zbxzyf7y1-e?RQt=v|sqH=)cmL`aNHKzIbRiNsi}tNyc_l0f5VK3~G-VR$~L^_0T8zDR) zeef!T!{;HKya?eL>6fIp$bX0A_1ll{PTm}SIDCI}d`xz@$$$9zJ*m2KsP{pA9n|MQ zeGb&;K>wZtPp8+}BvxOw*K@dLC3S zm$#LV=3Td6^VW9P{aGAy$G?8z>$J7!s+X7MjBIbc(s8+*QNHjOUAk|p9^#DrR=u{z z5yw=&aM!wym8I^e%=!At>1MV;u-4~-bm-JOE{+L z-1*zikL9i75qIs6T}LW!ofkXry5cog%hr6owzWRZFV(i@>Fc<~UBP;m&(E7uE$g7`F~zt`J%q^xeE`?*RmzAj7ID0tG^s~&98E2B52>2 zxu?CaE!Szd&);8H??e3iuHN6qM(gXZA90TLujX<7_jAqaebDN?)yYK`ai z+ctmMpWHs%%D4EU@zVXEeGq=7bm_iR>mja|KXpED-c{KLi?bg0@+%dm_o3-0{{I!M zyi)zf*3o>C9b30_yzGO;F?YOl-&Q@uTl`l3y2f)kTlrnBOE_!Y)%>OAv3RDAm+BAI z89H~gF7c;w*LhN}v=;uQ>-N2#=IgclzOLFI6Byp_4Rzn@zSaA-zHaMtpyYF4hfWh3 zPtOw?(P=?DRC-KuK=PgB2gxszTO^;Ae4=xQR{2JBHWAkvQ9KKuO~m<+NcKq{kUS)L zOv2|E-6q*3xlh996>%*4IG%kRf0u-FIi7PlevgD>|Gn7WpuWQ9=G4vhHIf@7eB=?= R<@1nu^g0Rm$1&R^e*kdo&7uGR diff --git a/engine/src/main/battlecode/world/resources/Punctuation.map21 b/engine/src/main/battlecode/world/resources/Punctuation.map21 deleted file mode 100644 index 8c88dcc010060e07ca86f44759b62ea3ab9d550a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24856 zcmeI5F^(if5Jd}EU?gC*pf$z;t$_p*Sb&K%903!P)mnhGII|umXF!6Rz%@9+UH}6N zi>z&)!C!qvL}pf1k7im*{f@{V|3^mER7)ex^yPATJyf2@c=KE#&=Z9taxZxiS@3s6}ZGHXh>67bckFUS`@#)e^|9ky)b$WA$cXL=L zaCaY!-Upw*cs;)YNA+%6J?94Z?jK)pZ~vqHI5)UeKPUY^Z~W)SZ@;du->)2QHNSJy z<$eKOf1}sk&AFO){q^QKHyG)R&O!C@1$DnSuFkc}@9j(LI5(*K8lQOkKYy~m)j5vx zbv|3i**VPaBk~=c<7oZt^PZcYn}6@z-1&O-sB^ko^}DL-OHyspKM>stNJKk z^<1oV8dIlv7sGex>SpJie>LCRSJo%eM*e2PWPP0O zX#S@7kM_CO{OQwOm)<^{p609fKlSuIis)rA^2_SLLyuVTT<1@p^j}5ls~Gu=>SgO^ z_0fC(XZy_ZvVF`txAx_9l}B9VQ@=<@;=MOsQI)t}1;=i>|q)#6Xqx$N;^U-`& zx5~$_S~r_d9}f5S(>`YVkLu0-eAV-69QCVwVpqq06`fvh9{+0nxy+ybLC!%8l2>HE zimKBa$DGzojyFbU(KUe#j20;)lc_(-IGd zKSHf@vFbS9)_LtiWBg~&AKfZye;QZyj^=Cs8gJDfK2G0VZ|WR6y{+@wPu5TCTwK+Q z`1m;9O_@LEaOlpbc~|f9THhO^pRI@Q(CN7A>G;_^eJJ1Ml}8M}iqwyy`Z_)3Y3%B@ zoGgMY=vJ|+=lJ9!e|Wt(I{#kZY+ZDI-OuV~d8)5*R%a_7{cNR= zE$pM`t-Rr{vDYF#fMKZjY})6aeU_fgJ=eAe%19{om`?Q@n+;4=TP|?XYYTltHxV>zE;l--}TQv=y>GeIfUo%w$5MY<>nLRRY&8fey{n@ z?nBS1apcE-Z=I_j)ywLt4>9#stlkIsImAEv+(U=DEK=t%s{_yJRP*R%@utl`I}grZ zy$`bb5fA^_82Pe4+ZR3bBZPnM^RM3joGW{N_zux=`{dz82)~MvZg#)w+slvo$?BpL z@!>@n=|uaHzT1y;)j?E1*&U4Pkn<*8opb5(WDJ=Qtw z9lQA)HUFc0&t>jhkE7<0^*!-k{=W(I--}ychu*%lZmaVjJ%7$Q>pGxU#b^#&&A-~` z-u&pg?A_07zv#M;`rX$1hPfSm{-gbw!%=wK&wte1?|jz@+_wLJe!qQ_z{3~cC2-Nc zDd2vaz{9q_XzRMIpW6DltvA~GrLE7}`ummtzrSc-Ca~6Cw7qpbYHQ`c)7EQkUADE> zec9GWZLNDBw6%UO!Fz4J+tw#-z2DZl$7_AxtlBplobv0NwPww)y05qOW?TOPRRz)8 diff --git a/engine/src/main/battlecode/world/resources/Radial.map21 b/engine/src/main/battlecode/world/resources/Radial.map21 deleted file mode 100644 index 277f066dd451e6fa01acce5c0a6335f4b56693b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11224 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 ARsaA1 diff --git a/engine/src/main/battlecode/world/resources/Rainbow.map21 b/engine/src/main/battlecode/world/resources/Rainbow.map21 deleted file mode 100644 index adcd26fd725c47bd4d05f041494fc1f7fac7bbe8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13032 zcmeHOu}%U(5FL={#TbHyg2I9r6B{c10E}N?tS!`-7#l796BDg1{Q*CLnx4>J$0s=J z@gTe0a=Yg(cfedSJa%q&=FQISoM*TWB}a=+sY@Md(E&x&U?d(B4M!36&WT31L|0El z-;5`WU#z>_CHnkON8A^bb&%^o_JQ;P=>yg21A`5{FI7D+lOM)5jMuDAwmhImKIRzu z@Obfe4Ew;OFN04u>hr?$b-i!syt4B^-k1k;jaQVN9@pgkGrj(SIFB)KVAQj`x}@g= zoVCuLqsIeJf7Jbi z=WV;*bRPbBlzUx)Z*24%=(ADJKd#LEUFVgZ$MQO0e)#-!-f=(KzvEeb%rSUFZ@W&b zqStxO?{m;2e~iH!dW_3L@G>#sGnmy2=gZ>h8W%i)wmkIn;rD?nf7pSaFJgXK=*t)O zW$|^53!Zt=HBM1>d3j=9Q9M@V2fTeTG(TTHun)~Ew14E`i`&X8bl&jqTMwH({JEmd zkFVY}-n!W>Ux&%U-(kz`#|zIbS@!AY?Qz#_ee?27Uzf3WJwo}(o7bky3$?DUem7+u zi_XJ!{fe?Hn*X-=`|tX1%Q~$(Pv5$%nxDjz-%C{I_Y&3n|DEg)*&nh$WM4`jkUk)N zK>C36fok;uq9(sJ(w@CH(&PuOHcO9%UlpM{mPeKb%k@;=8I?r*u1SMGBmREOqHL5L pO-1RIC|#H3kmZbJpGE1^kzlQkagB9#mK~NomYe(MmxtFk`URpc<7xl^ diff --git a/engine/src/main/battlecode/world/resources/Randomized.map21 b/engine/src/main/battlecode/world/resources/Randomized.map21 deleted file mode 100644 index 85fff6eac206c686f30c8bc15214db481736cc10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20352 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 F{|`|1%aZ^A diff --git a/engine/src/main/battlecode/world/resources/Saturn.map21 b/engine/src/main/battlecode/world/resources/Saturn.map21 deleted file mode 100644 index b7e2a4b23eb1ac8bdeab2296b679627f59470868..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17152 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 diff --git a/engine/src/main/battlecode/world/resources/SlowMusic.map21 b/engine/src/main/battlecode/world/resources/SlowMusic.map21 deleted file mode 100644 index 59c1e6931c49367367e8d0bb2fb6339db782f887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24888 zcmeI5!HQf(6ozYb)Dbjh5i!dkf+8+NSBfxC;K~;egoq-z5DEAUE=4f7^(A})1%-gC ztRn$8G7BHTb94I3W&WW!r*7SQyQjMwD*v3Sb52#Aud1h~r^(zd{!+-lN%j&;GOiyY82*7k<8jl58KYqmZD*5KpT77E$KJR+` z;R`2S7vtI=+2ljB^@Ly6zvf4tNNe$P^+$Emai4d2{#mYBKivo1(QG~8mG!Urktfnx z{9OH7m&o>cm**d?gYhH(zV|JuV^(*Sf9pBm-lN(3#C^^BFXiXF9&dgQ8?|-5EO-1o z|L)y?_@k`1rf^5Ib=x+7-_PUC?=2o&QD5Jq^!rn_`qcX2kJkLA_GkH#AOD)-rwVtp zl|Sd8H9k9!`uX}t?mCXmda~z0>k`>M&%@368a0Z`j>9qQj~{V0#Sf)UDD{g}xnoCh zQ^$S1F?Y@H`+D&7`-6^SQ;)1(K35}u&)5Hb0e;!_s2}mF>IZj}dPE9u;!ygd_^IQ* z{`egDdSdRZL+g^YJ^m_x`m=e|FXE>DH9N`!HZjbW)vwo9ZrOU_2WQPgKYmN8?|*#VkKH<7ZykyEdB<}=f2+c~ zrmgvE{>rVjZurBSeAtZdy4LEm?fx2n`g_+0FSM5v+|k~AYsL50ap`z?tM<+dcXX|K z_s#SB=I5?R^Pgkvt>aqpNB+b6yb*WC_mBVF=Zt%g_T9^Tz5C{YZ>0J4M0NG`M)Sqv z(L8I9!yWD8lCO8$JaJufe0tZnE9>ap#~2THbnWvO&6ndEbIHv!)+Kj7<9Ty=TIZe5 zAMR*Wr+pot#_7mk&%@lWPc{Ei_L2Ya3~vvD;) zp7+t-dcwP=z4@1luhnPQ`r!^Q?5XP{4?0(UYy9b-I*;$O|NV8HzqNiI-~W4u)_LI# zFO>e)e8i(#mtGs*s#EhSf9$FGh|AW^{pb6=V|HHr;0!NS#_^9-LMZ{%L{_j=|(cTmd{^}|{D(I3S#uJKwo<%X?(S-Ur$d3^m>&w=m%QS<9q z>Y?iM#oRS+TjyXc{!=+ljf1;t?Hs6IWGg?lIak~l9miga`{nsA&f$(S9x3}lYjuKK zO>1%5PrUZ`+P=^6`JgplR42wSpM&x9Mr(6tJ*rFbr=IXrWjs>iBEPBQUXS+AUuqpA z+t;`L>;Gt7OY?^d98vlsZS{}x>G)dwBMv$amq<0P)h2&7j^}+;>lxXtJX`&v`E}g) zz5M;p))zmxM2i1ZC4V*^?x@x?va>w#L!-P?$9>;N{@doyc~ahLPvu;T+ZF!Y!(PpD z#EfI-+wstYQ#^+nNRy`Hr&zHdczZ~#Yf|{xYmB( z=l1#6>b-RTw)iV2c%wSLlzrqsoPhlQ%g4P(Te&D-wOjM``g8tU^DKQY*UHcSv-80n zZLJ%;(bo7~@z2(4-~8Z?w(_{{+}ZEGan0@r?kM#*G|kp)-~8Z?9vXM{>-)c9e>vdR z)4v^X!#ZzS`^eh&)_$<|v$Zp8zirx&rbByg)BZatWoT#iM+Hvp-@*4CYp2$RuV1$I zy0teq_8rq#tkFOCyk+e*Yj0b7)!GNvp11a)wdbr2K0N&ElV=8-ew)4w9nV@D<{e^& X_!q3bXzi1)zP|VIx8Hp6nSK2~EazCP diff --git a/engine/src/main/battlecode/world/resources/Smile.map21 b/engine/src/main/battlecode/world/resources/Smile.map21 deleted file mode 100644 index 9edc9464eada7d4938cc845abcce7559d80e4c18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8424 zcmeHNu}TCn5PhDCi^yTI!XXw{SXfwSFWfhXt%Zda2j^c{S_}Fo{*|?rZvuxfune0? zvK-99<1tBQ=4Ea+>_K_}r?|ut3-SpL(2;?+8E{3uTLSO*!1*n(A^+ZhYk))I;dQ-v zA*TUh{HziM7q7$Dr##=QT;7%6C3kr^-K7-l00S z($gx>&_1p4+WLm#Te@1$m)2Q2UaNYP(yimP(qAf%SHIW4)IM_Kc=dbzb9I;U+jae= z>JV|H0`dPY`XKrs-h(&?;v9%`z;h1h?<#HA?k}BB+mXL+f9rZ{JL(_x_na?Q|LA_x zw&m}g*ZH*Vjc@tueA>4Bz4JPsw!QH!f1OX;mVeAk1>!q6`XKt?|2>%V7D1ox5p=v1 zFlT9c;+l9Qo``2c?hkw@bi8{YJ{`ve3qsZ%DVDK);+VJ~&IlQkM|cmj#Js+cSk}s2 Fg+Hl+ncx5b diff --git a/engine/src/main/battlecode/world/resources/Snowflake.map21 b/engine/src/main/battlecode/world/resources/Snowflake.map21 deleted file mode 100644 index c17a14a9a85d4a2521e44224eff0601814b869dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10320 zcmeI2ziJdw7{zbm7HgD{B1Hs?6oMAPMyvzAf~|#uu~CxJ*RT@wIeZL#2f<26;Ujn_ zn_prM9?s64*@?IrxSaj|opZjMB`Gp{W%2Bk2W7wPm7Q|8%*(7|sc|V^4(^l>4@)^Z zDdq9gQl3@ZsyKgC%IU0>&!4*I=ivh%CmrXHecZl|mwx88&*^F3(73NYz7xU=F6)ziFzHZN zes_QHYQKwJzw$dDeR;>~S3l|(9k(C#gl--^^^y3fJKkmM^eN&8e_Btv+Mi;_hmSO` zb@)K)#31=)(fMiRTUJ;3osU*NPP*e)0fxvJAQm5gcrnLLi)j^LtS~De|WWj>^SK=-_8g9&cD-hd{gJ0KerG2 zI-joY_?*7uUv=L3!9VDH=>8h(9DJbGogeMHuGsm;kNVg9&^mKq;-~Ll!Q?mXt9zvW zq^EqVit&+9_0xXZud$m?KBz0-R5AMC|E`<%(|gc3%@3`sp2kD@`_7|(6)*p9-j}bn z-|3TYk;yo?Cxlm%Clhz4Oz3?sDC; cz>Q7fjhfr6rCg%+-)(1!@c7la3 zAUKEQ%XQ{Bp8uN!b77dBb7sDo@66nru;d=o;yR=gxuKhRNcC#-R{`xWF)8^}^IuBjH zTlpbw(Uzco1r}JOnhd8z$#rExp{^8DTEKGA)& z{H*n|_|iVMjtl2P@{HxHjgR5?-mk5{HoiB%7`|KG2eR*2?;Rh*Z?z9TTDQWtaCAP{ zmVdAH;s2Gg&%N>icU^grAKDpnj{RPG?7U;=D?PVfbq>$tapyeu9D3E+>s)jB#r(&v z)5?eSSiQOXz_oNPUakKyZ}`62_x>0=U+jFwu4n9g;O~sjxmZ1RoSc(%Kg=0)8V-1r z>X0Y$Z>pB(Qpy`~{|kSYJm;I*chn{OZ}CEZp|`Kk;G3%DxqvtHj(_SoT7HZ3#d!|e z^0(Go;b{Ec{YTyM_dfI0?|^hYmfZ?RDqYU=Hle~ zBaha#IJNPpCl|*B&-Z`N3-V}Pi&GnqdRpNCPiqTb`?a>$l~?l^=BsQ@G+wH`uDrTF zXWTE^ueIGSFVO+NHE^_gZ{UExxE`@QV0q2*mgOA_zbZhVm-3$VpEBil4krB8!Iale zSSBpqe{U&wS$ny;6u)C>~v NFW#I!JA3(x?cZ#bVE_OC diff --git a/engine/src/main/battlecode/world/resources/Star.map21 b/engine/src/main/battlecode/world/resources/Star.map21 deleted file mode 100644 index 6a5bdb150d8f9d4ada19f93054d14dca72b3000d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10072 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 shsPN|yvv>QBjlg=pFe(a$6L;Q2XsSF7XSbN diff --git a/engine/src/main/battlecode/world/resources/TicTacTie.map21 b/engine/src/main/battlecode/world/resources/TicTacTie.map21 deleted file mode 100644 index 73c51f30723fce812e196321d076f67d4b5f1ad8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33080 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 diff --git a/engine/src/main/battlecode/world/resources/Yoda.map21 b/engine/src/main/battlecode/world/resources/Yoda.map21 deleted file mode 100644 index a095fd59109b52e45bf9bac376dcce7a0e66c373..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33072 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 wjrbnLhfnvu4Td*jSpWb4 diff --git a/engine/src/main/battlecode/world/resources/circle.map21 b/engine/src/main/battlecode/world/resources/circle.map21 deleted file mode 100644 index 0840c4e9e4bd19153fe78ec2aeea81d7475fd0f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32056 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%0D2# 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 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBuildCostLeadVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGoldOffset) { builder.addOffset(2, buildCostGoldOffset, 0); } - public static int createBuildCostGoldVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); } - public static void startBuildCostGoldVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } - public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(3, actionCooldown, 0); } - public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(4, movementCooldown, 0); } - public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(5, health, 0); } - public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(6, damage, 0); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(7, actionRadiusSquared, 0); } - public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(8, visionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(9, bytecodeLimit, 0); } + public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLead) { builder.addInt(1, buildCostLead, 0); } + public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGold) { builder.addInt(2, buildCostGold, 0); } + public static void addLevel2CostLead(FlatBufferBuilder builder, int level2CostLead) { builder.addInt(3, level2CostLead, 0); } + public static void addLevel2CostGold(FlatBufferBuilder builder, int level2CostGold) { builder.addInt(4, level2CostGold, 0); } + public static void addLevel3CostLead(FlatBufferBuilder builder, int level3CostLead) { builder.addInt(5, level3CostLead, 0); } + public static void addLevel3CostGold(FlatBufferBuilder builder, int level3CostGold) { builder.addInt(6, level3CostGold, 0); } + public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(7, actionCooldown, 0); } + public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(8, movementCooldown, 0); } + public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(9, health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(10, damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(11, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(12, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(13, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; From a19d043b7dcb151efe4743ec3595e9bbfed4d2d0 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 22:19:50 -0600 Subject: [PATCH 220/413] added lvl2 health and dmg to schema --- .../src/main/battlecode/common/RobotType.java | 9 ----- .../battlecode/schema/BodyTypeMetadata.java | 36 +++++++++++++------ .../src/main/battlecode/server/GameMaker.java | 4 +++ schema/battlecode.fbs | 4 +++ .../battlecode/schema/BodyTypeMetadata.java | 36 +++++++++++++------ 5 files changed, 60 insertions(+), 29 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index e3d17f5a..e0d7bca0 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -203,15 +203,6 @@ public int getMaxHealth(int level) { } } - /** - * Returns the starting health of a robot by level. - * @param level of the robot - * @return the starting health of a robot by level - */ - public int getStartingHealth(int level) { - return (int) (this.health * (this.isBuilding() ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1)); - } - /** * Returns the damage of a robot by level. * @param level diff --git a/engine/src/main/battlecode/schema/BodyTypeMetadata.java b/engine/src/main/battlecode/schema/BodyTypeMetadata.java index 62c03006..4d68dbd4 100644 --- a/engine/src/main/battlecode/schema/BodyTypeMetadata.java +++ b/engine/src/main/battlecode/schema/BodyTypeMetadata.java @@ -27,10 +27,14 @@ public final class BodyTypeMetadata extends Table { public int actionCooldown() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public int movementCooldown() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public int health() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int damage() { int o = __offset(24); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int actionRadiusSquared() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int visionRadiusSquared() { int o = __offset(28); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int bytecodeLimit() { int o = __offset(30); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2Health() { int o = __offset(24); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3Health() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int damage() { int o = __offset(28); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2Damage() { int o = __offset(30); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3Damage() { int o = __offset(32); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(34); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int bytecodeLimit() { int o = __offset(38); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, @@ -43,15 +47,23 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, int actionCooldown, int movementCooldown, int health, + int level2Health, + int level3Health, int damage, + int level2Damage, + int level3Damage, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { - builder.startObject(14); + builder.startObject(18); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addLevel3Damage(builder, level3Damage); + BodyTypeMetadata.addLevel2Damage(builder, level2Damage); BodyTypeMetadata.addDamage(builder, damage); + BodyTypeMetadata.addLevel3Health(builder, level3Health); + BodyTypeMetadata.addLevel2Health(builder, level2Health); BodyTypeMetadata.addHealth(builder, health); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); @@ -65,7 +77,7 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(14); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(18); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLead) { builder.addInt(1, buildCostLead, 0); } public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGold) { builder.addInt(2, buildCostGold, 0); } @@ -76,10 +88,14 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(7, actionCooldown, 0); } public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(8, movementCooldown, 0); } public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(9, health, 0); } - public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(10, damage, 0); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(11, actionRadiusSquared, 0); } - public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(12, visionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(13, bytecodeLimit, 0); } + public static void addLevel2Health(FlatBufferBuilder builder, int level2Health) { builder.addInt(10, level2Health, 0); } + public static void addLevel3Health(FlatBufferBuilder builder, int level3Health) { builder.addInt(11, level3Health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(12, damage, 0); } + public static void addLevel2Damage(FlatBufferBuilder builder, int level2Damage) { builder.addInt(13, level2Damage, 0); } + public static void addLevel3Damage(FlatBufferBuilder builder, int level3Damage) { builder.addInt(14, level3Damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(15, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(16, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(17, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index da803cee..9032b68a 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -296,7 +296,11 @@ public int makeBodyTypeMetadata(FlatBufferBuilder builder) { BodyTypeMetadata.addActionCooldown(builder, type.actionCooldown); BodyTypeMetadata.addMovementCooldown(builder, type.movementCooldown); BodyTypeMetadata.addHealth(builder, type.health); + BodyTypeMetadata.addLevel2Health(builder, type.getMaxHealth(2)); + BodyTypeMetadata.addLevel3Health(builder, type.getMaxHealth(3)); BodyTypeMetadata.addDamage(builder, type.damage); + BodyTypeMetadata.addLevel2Damage(builder, type.getDamage(2)); + BodyTypeMetadata.addLevel3Damage(builder, type.getDamage(3)); BodyTypeMetadata.addActionRadiusSquared(builder, type.actionRadiusSquared); BodyTypeMetadata.addVisionRadiusSquared(builder, type.visionRadiusSquared); BodyTypeMetadata.addBytecodeLimit(builder, type.bytecodeLimit); diff --git a/schema/battlecode.fbs b/schema/battlecode.fbs index 02390c31..50515275 100644 --- a/schema/battlecode.fbs +++ b/schema/battlecode.fbs @@ -136,7 +136,11 @@ table BodyTypeMetadata { actionCooldown: int; movementCooldown: int; health: int; + level2Health: int; + level3Health: int; damage: int; + level2Damage: int; + level3Damage: int; actionRadiusSquared: int; visionRadiusSquared: int; bytecodeLimit: int; diff --git a/schema/java/battlecode/schema/BodyTypeMetadata.java b/schema/java/battlecode/schema/BodyTypeMetadata.java index 62c03006..4d68dbd4 100644 --- a/schema/java/battlecode/schema/BodyTypeMetadata.java +++ b/schema/java/battlecode/schema/BodyTypeMetadata.java @@ -27,10 +27,14 @@ public final class BodyTypeMetadata extends Table { public int actionCooldown() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public int movementCooldown() { int o = __offset(20); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public int health() { int o = __offset(22); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int damage() { int o = __offset(24); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int actionRadiusSquared() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int visionRadiusSquared() { int o = __offset(28); return o != 0 ? bb.getInt(o + bb_pos) : 0; } - public int bytecodeLimit() { int o = __offset(30); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2Health() { int o = __offset(24); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3Health() { int o = __offset(26); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int damage() { int o = __offset(28); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level2Damage() { int o = __offset(30); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int level3Damage() { int o = __offset(32); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int actionRadiusSquared() { int o = __offset(34); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int visionRadiusSquared() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public int bytecodeLimit() { int o = __offset(38); return o != 0 ? bb.getInt(o + bb_pos) : 0; } public static int createBodyTypeMetadata(FlatBufferBuilder builder, byte type, @@ -43,15 +47,23 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, int actionCooldown, int movementCooldown, int health, + int level2Health, + int level3Health, int damage, + int level2Damage, + int level3Damage, int actionRadiusSquared, int visionRadiusSquared, int bytecodeLimit) { - builder.startObject(14); + builder.startObject(18); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addLevel3Damage(builder, level3Damage); + BodyTypeMetadata.addLevel2Damage(builder, level2Damage); BodyTypeMetadata.addDamage(builder, damage); + BodyTypeMetadata.addLevel3Health(builder, level3Health); + BodyTypeMetadata.addLevel2Health(builder, level2Health); BodyTypeMetadata.addHealth(builder, health); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); @@ -65,7 +77,7 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, return BodyTypeMetadata.endBodyTypeMetadata(builder); } - public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(14); } + public static void startBodyTypeMetadata(FlatBufferBuilder builder) { builder.startObject(18); } public static void addType(FlatBufferBuilder builder, byte type) { builder.addByte(0, type, 0); } public static void addBuildCostLead(FlatBufferBuilder builder, int buildCostLead) { builder.addInt(1, buildCostLead, 0); } public static void addBuildCostGold(FlatBufferBuilder builder, int buildCostGold) { builder.addInt(2, buildCostGold, 0); } @@ -76,10 +88,14 @@ public static int createBodyTypeMetadata(FlatBufferBuilder builder, public static void addActionCooldown(FlatBufferBuilder builder, int actionCooldown) { builder.addInt(7, actionCooldown, 0); } public static void addMovementCooldown(FlatBufferBuilder builder, int movementCooldown) { builder.addInt(8, movementCooldown, 0); } public static void addHealth(FlatBufferBuilder builder, int health) { builder.addInt(9, health, 0); } - public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(10, damage, 0); } - public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(11, actionRadiusSquared, 0); } - public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(12, visionRadiusSquared, 0); } - public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(13, bytecodeLimit, 0); } + public static void addLevel2Health(FlatBufferBuilder builder, int level2Health) { builder.addInt(10, level2Health, 0); } + public static void addLevel3Health(FlatBufferBuilder builder, int level3Health) { builder.addInt(11, level3Health, 0); } + public static void addDamage(FlatBufferBuilder builder, int damage) { builder.addInt(12, damage, 0); } + public static void addLevel2Damage(FlatBufferBuilder builder, int level2Damage) { builder.addInt(13, level2Damage, 0); } + public static void addLevel3Damage(FlatBufferBuilder builder, int level3Damage) { builder.addInt(14, level3Damage, 0); } + public static void addActionRadiusSquared(FlatBufferBuilder builder, int actionRadiusSquared) { builder.addInt(15, actionRadiusSquared, 0); } + public static void addVisionRadiusSquared(FlatBufferBuilder builder, int visionRadiusSquared) { builder.addInt(16, visionRadiusSquared, 0); } + public static void addBytecodeLimit(FlatBufferBuilder builder, int bytecodeLimit) { builder.addInt(17, bytecodeLimit, 0); } public static int endBodyTypeMetadata(FlatBufferBuilder builder) { int o = builder.endObject(); return o; From 28eac1942dec4f97112cb2a69722456dd3b3096b Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Sat, 25 Dec 2021 22:25:51 -0600 Subject: [PATCH 221/413] fix Constant bug --- .../main/battlecode/common/GameConstants.java | 2 +- .../battlecode/world/resources/circle.map22 | Bin 0 -> 31984 bytes .../world/resources/maptestsmall.map22 | Bin 0 -> 8408 bytes .../battlecode/world/resources/quadrants.map22 | Bin 0 -> 13036 bytes 4 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 engine/src/main/battlecode/world/resources/circle.map22 create mode 100644 engine/src/main/battlecode/world/resources/maptestsmall.map22 create mode 100644 engine/src/main/battlecode/world/resources/quadrants.map22 diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index aacee83b..7a011411 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -34,7 +34,7 @@ public class GameConstants { public static final int MAX_STARTING_ARCHONS = 4; /** The minimum amount of rubble per square. */ - public static final int MIN_RUBBLE = 100; + public static final int MIN_RUBBLE = 0; /** The maximum amount of rubble per square. */ public static final int MAX_RUBBLE = 100; diff --git a/engine/src/main/battlecode/world/resources/circle.map22 b/engine/src/main/battlecode/world/resources/circle.map22 new file mode 100644 index 0000000000000000000000000000000000000000..fecd7ef217e5c53411924c244bdaffd22324f24f GIT binary patch literal 31984 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 Dvtq3v literal 0 HcmV?d00001 diff --git a/engine/src/main/battlecode/world/resources/maptestsmall.map22 b/engine/src/main/battlecode/world/resources/maptestsmall.map22 new file mode 100644 index 0000000000000000000000000000000000000000..955ce9e3c1b7550e3f59389ee87468a3ae7232d6 GIT binary patch literal 8408 zcmeI&>v9xT6o%mr1_X(SiXsv*AptoBP*BdNLJ&~m0U-z;I#T}ADlPr#O?bz?4>e<1 zUV=4K_0m1N_g?E;-&&m?Q!Ea{@YZm8I5Dgai_h=(47-PgVf!%O`q28n*gXsf`hIq4 z7*4-841aw$47td>?Pb)_60<_&f^v{JC6rV&CNYde_Tw zF+PjqaWlS+wHV{wI1?)&$J2N_UXBa#EaX2Ha>;)%4uw3PeG~GIVgL2`A>?$A^>AJd z?*wf}LjI$Z@9ww6>ST?sdvPf~40-5y9P-)glU2h@An%|CFE3>J-gzI z;N8^_`*w&0d#vjn-(CoNcr2cLdtwYa);7(=7d&x%;I`9zR%;Dhn=COD`B4K)_1l17kEIbg<91_j~rs&40X{gws_Xfq^oyP9{043A?A&s_jZ^$ z`Rt*APJYT`pC0giZ_vOOb0oI>YSb&e6i=^Chjr)7zBQhTwG_*7DD2_I#dt0D#dLkX zdvmA<)12$w(`hc{yAVs^x%$eUw{d+@Pdii@ftn}nM}1v?@#X!XS3ce! z4EgBPCmMbCT#Y>46@0uO(|MG0Da3cB+Zp?B#cDi>JHaz~X;TNUr*Y49@9fG1&%7ga z@!)QVV@(Ws4}^XDgAelA|5})HzRd;i^m7b7IU3^doFD#fs`Yqmgt@fF3x3kQ8CSwA zs+Ardh~X^VY7(1AW2o)D$-Vq^nNzr*YO=@PF`N}cEHTBFL$13aHx0DVL>rB?(oDM= z)Z(l)HHx8Tv3W3t{Jh~2uig#1cz7##%G(!$*F5LFIC?>k-q>%=KANGI=fcdW%`-LW zy%=8uronIKBxw$FN6F#FNV& zdXL4@a%G!Q_tn) znRT%~4*JD5i;M9}IDbA4$42meCHQDAX*?9SLZ8HSeplGfFS=c)dk=K4K7H}bK0c{k z9J*IS-lst?zm89?U7pVlE%eiB&YgWTmO`(2Dkd%KL9gfh&{ws+9`y5VI*(`nwZ7c_ zQqW7wxi}X3;jDMWn%d;!ul1YpVoY;>-u>QiPOKZDXP3f^@}JI!@llAUUi&_XG1O_# z))3phx?K;4`me?OE<5)V`|}nbF`_SR?pQ$)0vRZ zm9PAsdSec0AA?SP@!eT_#@G|)NWHxEo~no6C*o@GWPZZ!uJ%}0qZ-s^kGk|u&Eh?X zjWBbk!XCNh6VHbZ+8&457n|q2z8C6pW;N_JlX6&de`NCgov!+>H|ueI0`K(E_h&JN zeDauweQ_ub2EUxA!!!FYgu3*?JeiY~piBNS) zMfug>x%>~qyT~lw&6s&Gn}OL3%w}LV1G5>J&A@C1W-~CGf!PeqW?(i0vl;k*&%i>z z)J*>`!9u?U_#NSV_>JLuZ12~w`TpJBz29{FzOp6!uHd(e|K88H!P;E^xcZnOv47e8 R^^c!^|Ks;xHh=!v`rkOW(y#yk literal 0 HcmV?d00001 diff --git a/engine/src/main/battlecode/world/resources/quadrants.map22 b/engine/src/main/battlecode/world/resources/quadrants.map22 new file mode 100644 index 0000000000000000000000000000000000000000..04fd272bbf2415e6a8264ee1ac7035978fd13192 GIT binary patch literal 13036 zcmeI3F-inM5JmsYjxx#wf(8n^24ZL+>H!1|1P#2xg0bMLH_?N64o_famF%Jj4Uc9b z{SCFJsSbmokaDRGVzG>JsSbmo zkaDRGVzG>JsSbmokaDRGVzG>HQ$vG->3Jl-WKtc?&pKDY6>tSyfpP`tH+SrBeP%S~ zne=~@D^a&Xxl~t|MR^zHQeBx;w?es8SC>V37v)l2nN+tzxl~t|MR^zHQeBx;w?es8 zSC>V37v)l2nN+tzxl~t|g?G6E|GNTt2hv0d9Ik;qU=P>>_JBQL57-0tfIVOj*aP-} zJzx*m1NMMDU=P>>_JBQL5Bwz$4ElacGQ?d-z9+egxQV!p=;NJ97r%Xs^X*BujJ4 Date: Sat, 25 Dec 2021 22:33:36 -0600 Subject: [PATCH 222/413] maps with origin 0,0 and fix null error in InternalRobot --- .../main/battlecode/world/InternalRobot.java | 3 ++- .../main/battlecode/world/maps/Circle.java | 2 +- .../battlecode/world/maps/MapTestSmall.java | 2 +- .../main/battlecode/world/maps/Quadrants.java | 2 +- .../battlecode/world/resources/circle.map22 | Bin 31984 -> 31984 bytes .../world/resources/maptestsmall.map22 | Bin 8408 -> 8408 bytes .../world/resources/quadrants.map22 | Bin 13036 -> 13036 bytes 7 files changed, 5 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 65ca3301..b67811ba 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -50,6 +50,8 @@ public strictfp class InternalRobot implements Comparable { */ @SuppressWarnings("unchecked") public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team team) { + this.gameWorld = gw; + this.ID = id; this.team = team; this.type = type; @@ -69,7 +71,6 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.numVisibleFriendlyRobots = 0; - this.gameWorld = gw; this.controller = new RobotControllerImpl(gameWorld, this); } diff --git a/engine/src/main/battlecode/world/maps/Circle.java b/engine/src/main/battlecode/world/maps/Circle.java index 6699635f..a18f85bc 100644 --- a/engine/src/main/battlecode/world/maps/Circle.java +++ b/engine/src/main/battlecode/world/maps/Circle.java @@ -40,7 +40,7 @@ public static void main(String[] args) { public static void makeCircle() throws IOException { final int half = 31; final MapLocation center = new MapLocation(half, half); - MapBuilder mapBuilder = new MapBuilder(mapName, 2*half+1, 2*half+1, 25016, 12865, 116896); + MapBuilder mapBuilder = new MapBuilder(mapName, 2*half+1, 2*half+1, 0, 0, 116896); mapBuilder.addSymmetricArchon(20, 20); mapBuilder.addSymmetricArchon(20, 2*half-20); diff --git a/engine/src/main/battlecode/world/maps/MapTestSmall.java b/engine/src/main/battlecode/world/maps/MapTestSmall.java index a89299b9..dedbf2ac 100644 --- a/engine/src/main/battlecode/world/maps/MapTestSmall.java +++ b/engine/src/main/battlecode/world/maps/MapTestSmall.java @@ -38,7 +38,7 @@ public static void main(String[] args) { } public static void makeSimple() throws IOException { - MapBuilder mapBuilder = new MapBuilder(mapName, 32, 32, 10000, 23921, 30); + MapBuilder mapBuilder = new MapBuilder(mapName, 32, 32, 0, 0, 30); mapBuilder.addSymmetricArchon(5, 5); Random random = new Random(6147); diff --git a/engine/src/main/battlecode/world/maps/Quadrants.java b/engine/src/main/battlecode/world/maps/Quadrants.java index 25db0fa2..ad9bc86c 100644 --- a/engine/src/main/battlecode/world/maps/Quadrants.java +++ b/engine/src/main/battlecode/world/maps/Quadrants.java @@ -39,7 +39,7 @@ public static void main(String[] args) { } public static void makeQuadrants() throws IOException { - MapBuilder mapBuilder = new MapBuilder(mapName, 40, 40, 13265, 17387, 215957); + MapBuilder mapBuilder = new MapBuilder(mapName, 40, 40, 0, 0, 215957); mapBuilder.setSymmetry(MapSymmetry.ROTATIONAL); mapBuilder.addSymmetricArchon(5, 5); mapBuilder.addSymmetricArchon(10, 30); diff --git a/engine/src/main/battlecode/world/resources/circle.map22 b/engine/src/main/battlecode/world/resources/circle.map22 index fecd7ef217e5c53411924c244bdaffd22324f24f..15adfd6a180796fe0563b53ba281efd711cf4e6f 100644 GIT binary patch delta 27 ccmezHlkvk(#t9aD_6!URAPfN;-B#5A0DeOUMgRZ+ delta 27 hcmezHlkvk(#t9aD-xC=a8jKhib^vKdqm6E>Y5=6w3SIyJ diff --git a/engine/src/main/battlecode/world/resources/maptestsmall.map22 b/engine/src/main/battlecode/world/resources/maptestsmall.map22 index 955ce9e3c1b7550e3f59389ee87468a3ae7232d6..c5df3490a2c263bb8fc3bc3a649d24f120612657 100644 GIT binary patch delta 25 ZcmccNc*Ajm1)l-~0|N*{z(%)83II-91o8j? delta 25 fcmccNc*Ajm1)qUB1H;5v1_l8jT^PI3ZIS{2V{Zoh diff --git a/engine/src/main/battlecode/world/resources/quadrants.map22 b/engine/src/main/battlecode/world/resources/quadrants.map22 index 04fd272bbf2415e6a8264ee1ac7035978fd13192..6c4e19ca7aa02502fb94b279359aef44a497d86f 100644 GIT binary patch delta 25 ZcmaEp`X+UP1)l~30|N*{z(%)aMgUpO1(*N; delta 25 fcmaEp`X+UP1>a9&1_ogl28N43`nB^$w`E2Ee)b6c From e2cbc56aecd883f9234159b69e31e68439721cf6 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 26 Dec 2021 11:05:49 -0600 Subject: [PATCH 223/413] Added additional flips for vortex --- .../src/main/battlecode/world/GameWorld.java | 68 +++++++++++++++++-- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index da7b7cf6..12226719 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -598,12 +598,7 @@ public void causeFuryGlobal() { this.causeFuryUpdate(AnomalyType.FURY.globalPercentage, this.getAllLocations()); } - /** - * Mutates state to peform the global Vortex. - * Note that in this year's game, width == height (only square maps) - * Only mutates the rubble array in this class; doesn't change the LiveMap - */ - public void causeVortexGlobal() { + private void rotatePassability() { int n = this.gameMap.getWidth(); for (int x = 0; x < n / 2; x++) { for (int y = 0; y < (n + 1) / 2; y++) { @@ -622,4 +617,63 @@ public void causeVortexGlobal() { } } } -} + + private void flipPassabilityHorizontally() { + int n = this.gameMap.getWidth(); + for (int x = 0; x < n / 2; x++) { + for (int y = 0; y < this.gameMap.getHeight(); y++) { + int idx = x + y * n; + int newX = n - x; + int newIdx = newX + y * n; + int prevRubble = this.rubble[idx]; + this.rubble[idx] = this.rubble[newIdx]; + this.rubble[newIdx] = prevRubble; + } + } + } + + private void flipPassabilityVertically() { + int n = this.gameMap.getHeight(); + for (int y = 0; y < n / 2; y++) { + for (int x = 0; x < this.gameMap.getWidth(); x++) { + int idx = x + y * n; + int newY = n - y; + int newIdx = x + newY * n; + int prevRubble = this.rubble[idx]; + this.rubble[idx] = this.rubble[newIdx]; + this.rubble[newIdx] = prevRubble; + } + } + } + + /** + * Mutates state to peform the global Vortex. + * Note that in this year's game, width == height (only square maps) + * Only mutates the rubble array in this class; doesn't change the LiveMap + */ + public void causeVortexGlobal() { + switch (this.gameMap.getSymmetry()) { + case HORIZONTAL: + flipPassabilityHorizontally(); + break; + case VERTICAL: + flipPassabilityVertically(); + break; + case ROTATIONAL: + // generate random choice of how rotation will occur + // 0 indicates horiztonal + // 1 indicates vertical + // 2 indicates rotation + horizontal + // 3 indicates rotation + vertical + int randomNumber = this.rand.nextInt(4); + if (randomNumber > 1) { + rotatePassability(); + } + if (randomNumber % 2 == 0) { + flipPassabilityHorizontally(); + } else { + flipPassabilityVertically(); + } + break; + } + } From ce2f3585f5d9bcffc856b49043d54e494dc5ca0a Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 26 Dec 2021 11:33:47 -0600 Subject: [PATCH 224/413] Added global anomalies to match maker actions --- .../src/main/battlecode/world/GameWorld.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 12226719..0f9e822f 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -525,6 +525,7 @@ public void causeAbyssGlobal() { this.teamInfo.addGold(Team.A, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.A))); this.teamInfo.addGold(Team.B, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.B))); + getMatchMaker().addAction(-1, ABYSS, -1); } /** @@ -559,6 +560,7 @@ public void causeChargeGlobal() { for (int i = 0; i < affectedDroidsLimit; i++) { this.destroyRobot(droids.get(i).getID()); } + getMatchMaker().addAction(-1, CHARGE, -1); } /** Used to sort droids for charge */ @@ -596,6 +598,7 @@ public void causeFurySage(InternalRobot robot) { */ public void causeFuryGlobal() { this.causeFuryUpdate(AnomalyType.FURY.globalPercentage, this.getAllLocations()); + getMatchMaker().addAction(-1, FURY, -1); } private void rotatePassability() { @@ -652,28 +655,31 @@ private void flipPassabilityVertically() { * Only mutates the rubble array in this class; doesn't change the LiveMap */ public void causeVortexGlobal() { + int changeIdx = 0; switch (this.gameMap.getSymmetry()) { case HORIZONTAL: flipPassabilityHorizontally(); + changeIdx = 1; break; case VERTICAL: flipPassabilityVertically(); + changeIdx = 2; break; case ROTATIONAL: // generate random choice of how rotation will occur - // 0 indicates horiztonal - // 1 indicates vertical - // 2 indicates rotation + horizontal - // 3 indicates rotation + vertical - int randomNumber = this.rand.nextInt(4); - if (randomNumber > 1) { + // 0 indicates rotational (clockwise) + // 1 indicates horizontal + // 2 indicates vertical + int randomNumber = this.rand.nextInt(3); + if (randomNumber == 0) { rotatePassability(); - } - if (randomNumber % 2 == 0) { + } else if (randomNumber == 1) { flipPassabilityHorizontally(); - } else { + } else if (randomNumber == 2) { flipPassabilityVertically(); } + changeIdx = randomNumber; break; } + getMatchMaker().addAction(-1, VORTEX, changeIdx); } From 13810dcc37390aad615d1302a7e104c4df32a7cb Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 26 Dec 2021 11:37:56 -0600 Subject: [PATCH 225/413] Small changes to actions passed into match maker --- .../src/main/battlecode/world/RobotControllerImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 1d90bde7..2cdc4b2e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -406,8 +406,8 @@ public void buildRobot(RobotType type, Direction dir) throws GameActionException Team team = getTeam(); this.gameWorld.getTeamInfo().addLead(team, -type.buildCostLead); this.gameWorld.getTeamInfo().addGold(team, -type.buildCostGold); - this.gameWorld.spawnRobot(type, adjacentLocation(dir), team); - this.gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, getID()); + int newId = this.gameWorld.spawnRobot(type, adjacentLocation(dir), team); + this.gameWorld.getMatchMaker().addAction(getID(), Action.SPAWN_UNIT, newId); } // ***************************** @@ -478,15 +478,15 @@ public void envision(AnomalyType anomaly) throws GameActionException { switch (anomaly) { case ABYSS: this.gameWorld.causeAbyssSage(this.robot); - this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_ABYSS, locationToInt(this.robot.getLocation())); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_ABYSS, locationToInt(getLocation())); break; case CHARGE: this.gameWorld.causeChargeSage(this.robot); - this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_CHARGE, locationToInt(this.robot.getLocation())); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_CHARGE, locationToInt(getLocation())); break; case FURY: this.gameWorld.causeFurySage(this.robot); - this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_FURY, locationToInt(this.robot.getLocation())); + this.gameWorld.getMatchMaker().addAction(getID(), Action.LOCAL_FURY, locationToInt(getLocation())); break; } } From 456d6cc0acfaad6361cb4730e980ecb2c591e1ff Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Mon, 27 Dec 2021 03:09:46 -0600 Subject: [PATCH 226/413] minor changes --- .../src/main/battlecode/world/GameWorld.java | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 0f9e822f..a6f6fd42 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -525,7 +525,7 @@ public void causeAbyssGlobal() { this.teamInfo.addGold(Team.A, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.A))); this.teamInfo.addGold(Team.B, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.B))); - getMatchMaker().addAction(-1, ABYSS, -1); + this.matchMaker.addAction(-1, ABYSS, -1); } /** @@ -560,7 +560,7 @@ public void causeChargeGlobal() { for (int i = 0; i < affectedDroidsLimit; i++) { this.destroyRobot(droids.get(i).getID()); } - getMatchMaker().addAction(-1, CHARGE, -1); + this.matchMaker.addAction(-1, CHARGE, -1); } /** Used to sort droids for charge */ @@ -598,10 +598,10 @@ public void causeFurySage(InternalRobot robot) { */ public void causeFuryGlobal() { this.causeFuryUpdate(AnomalyType.FURY.globalPercentage, this.getAllLocations()); - getMatchMaker().addAction(-1, FURY, -1); + this.matchMaker.addAction(-1, FURY, -1); } - private void rotatePassability() { + private void rotateRubble() { int n = this.gameMap.getWidth(); for (int x = 0; x < n / 2; x++) { for (int y = 0; y < (n + 1) / 2; y++) { @@ -621,13 +621,14 @@ private void rotatePassability() { } } - private void flipPassabilityHorizontally() { - int n = this.gameMap.getWidth(); - for (int x = 0; x < n / 2; x++) { - for (int y = 0; y < this.gameMap.getHeight(); y++) { - int idx = x + y * n; - int newX = n - x; - int newIdx = newX + y * n; + private void flipRubbleHorizontally() { + int w = this.gameMap.getWidth(); + int h = this.gameMap.getHeight(); + for (int x = 0; x < w / 2; x++) { + for (int y = 0; y < h; y++) { + int idx = x + y * w; + int newX = w - 1 - x; + int newIdx = newX + y * w; int prevRubble = this.rubble[idx]; this.rubble[idx] = this.rubble[newIdx]; this.rubble[newIdx] = prevRubble; @@ -635,13 +636,14 @@ private void flipPassabilityHorizontally() { } } - private void flipPassabilityVertically() { - int n = this.gameMap.getHeight(); - for (int y = 0; y < n / 2; y++) { - for (int x = 0; x < this.gameMap.getWidth(); x++) { - int idx = x + y * n; - int newY = n - y; - int newIdx = x + newY * n; + private void flipRubbleVertically() { + int w = this.gameMap.getWidth(); + int h = this.gameMap.getHeight(); + for (int y = 0; y < h / 2; y++) { + for (int x = 0; x < w; x++) { + int idx = x + y * w; + int newY = h - 1 - y; + int newIdx = x + newY * w; int prevRubble = this.rubble[idx]; this.rubble[idx] = this.rubble[newIdx]; this.rubble[newIdx] = prevRubble; @@ -651,35 +653,37 @@ private void flipPassabilityVertically() { /** * Mutates state to peform the global Vortex. - * Note that in this year's game, width == height (only square maps) * Only mutates the rubble array in this class; doesn't change the LiveMap */ public void causeVortexGlobal() { int changeIdx = 0; switch (this.gameMap.getSymmetry()) { case HORIZONTAL: - flipPassabilityHorizontally(); - changeIdx = 1; + flipRubbleVertically(); + changeIdx = 2; break; case VERTICAL: - flipPassabilityVertically(); - changeIdx = 2; + flipRubbleHorizontally(); + changeIdx = 1; break; case ROTATIONAL: // generate random choice of how rotation will occur - // 0 indicates rotational (clockwise) - // 1 indicates horizontal - // 2 indicates vertical - int randomNumber = this.rand.nextInt(3); + // can only rotate if it's a square map + boolean squareMap = this.gameMap.getWidth() == this.gameMap.getHeight(); + int randomNumber = this.rand.nextInt(squareMap ? 3 : 2); + if (!squareMap) { + randomNumber++; + } if (randomNumber == 0) { - rotatePassability(); + rotateRubble(); } else if (randomNumber == 1) { - flipPassabilityHorizontally(); + flipRubbleHorizontally(); } else if (randomNumber == 2) { - flipPassabilityVertically(); + flipRubbleVertically(); } changeIdx = randomNumber; break; } - getMatchMaker().addAction(-1, VORTEX, changeIdx); + this.matchMaker.addAction(-1, VORTEX, changeIdx); } +} From 6a736bfacf63e684cae3a7fc150f3a2be8e18329 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Mon, 27 Dec 2021 03:12:36 -0600 Subject: [PATCH 227/413] typo --- engine/src/main/battlecode/world/GameWorld.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index a6f6fd42..1e5a0a19 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -525,7 +525,7 @@ public void causeAbyssGlobal() { this.teamInfo.addGold(Team.A, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.A))); this.teamInfo.addGold(Team.B, (int) (-1 * AnomalyType.ABYSS.globalPercentage * this.teamInfo.getGold(Team.B))); - this.matchMaker.addAction(-1, ABYSS, -1); + this.matchMaker.addAction(-1, Action.ABYSS, -1); } /** @@ -560,7 +560,7 @@ public void causeChargeGlobal() { for (int i = 0; i < affectedDroidsLimit; i++) { this.destroyRobot(droids.get(i).getID()); } - this.matchMaker.addAction(-1, CHARGE, -1); + this.matchMaker.addAction(-1, Action.CHARGE, -1); } /** Used to sort droids for charge */ @@ -598,7 +598,7 @@ public void causeFurySage(InternalRobot robot) { */ public void causeFuryGlobal() { this.causeFuryUpdate(AnomalyType.FURY.globalPercentage, this.getAllLocations()); - this.matchMaker.addAction(-1, FURY, -1); + this.matchMaker.addAction(-1, Action.FURY, -1); } private void rotateRubble() { @@ -684,6 +684,6 @@ public void causeVortexGlobal() { changeIdx = randomNumber; break; } - this.matchMaker.addAction(-1, VORTEX, changeIdx); + this.matchMaker.addAction(-1, Action.VORTEX, changeIdx); } } From e78a12fd500e39b9b6e382a90e4348b6472c8b42 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 25 Dec 2021 14:30:30 -0800 Subject: [PATCH 228/413] Fixed constants according to spec --- engine/src/main/battlecode/common/GameConstants.java | 7 ++----- engine/src/main/battlecode/common/RobotType.java | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 7a011411..ddb5acb9 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -84,11 +84,8 @@ public class GameConstants { // ****** GAME MECHANICS *********** // ********************************* - /** A prototype building's starting health, as a multiplier of max health. */ - public static final float PROTOTYPE_STARTING_HEALTH_MULTIPLIER = 0.1f; - - /** The amount of health a prototype building has as a multiplier. */ - public static final float PROTOTYPE_HP_PERCENTAGE = 0.1f; + /** A blueprint building's health, as a multiplier of max health. */ + public static final float PROTOTYPE_HP_PERCENTAGE = 0.9f; /** The multiplier for reclaiming a building's cost. */ public static final float RECLAIM_COST_MULTIPLIER = 0.2f; diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index e0d7bca0..349d7816 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -21,7 +21,7 @@ public enum RobotType { * Converts lead into gold * * @battlecode.doc.robot */ - LABORATORY (800, 0, 10, 24, 130, 5, 20, 34, 10000), + LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), // BCL BCG AC MC HP DMG AR VR BL /** @@ -46,7 +46,7 @@ public enum RobotType { /** * Ranged attacking robot. */ - SOLDIER ( 75, 0, 10, 16, 3, 50, 13, 20, 10000), + SOLDIER ( 75, 0, 10, 16, 50, 3, 13, 20, 10000), // BCL BCG AC MC HP DMG AR VR BL /** From f75349ddfb68e476b0160a9fabe1e064c44d4c24 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 14:10:01 -0500 Subject: [PATCH 229/413] Changes to make the ranges of Archon and map size inclusive --- engine/src/main/battlecode/world/MapBuilder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index deeb1b8f..49fbb4ba 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -190,13 +190,13 @@ public void assertIsValid() { robots[locationToIndex(r.location.x, r.location.y)] = r; } - if (width < GameConstants.MAP_MIN_WIDTH || height < GameConstants.MAP_MIN_HEIGHT || - width > GameConstants.MAP_MAX_WIDTH || height > GameConstants.MAP_MAX_HEIGHT) + if (width <= GameConstants.MAP_MIN_WIDTH || height <= GameConstants.MAP_MIN_HEIGHT || + width >= GameConstants.MAP_MAX_WIDTH || height >= GameConstants.MAP_MAX_HEIGHT) throw new RuntimeException("The map size must be between " + GameConstants.MAP_MIN_WIDTH + "x" + GameConstants.MAP_MIN_HEIGHT + " and " + GameConstants.MAP_MAX_WIDTH + "x" + GameConstants.MAP_MAX_HEIGHT + ", inclusive"); - // checks between 1 and 4 Archons of each team + // checks between 1 and 4 Archons inclusive of each team // only needs to check the Archons of Team A, because symmetry is checked int numTeamARobots = 0; for (RobotInfo r : bodies) { @@ -204,8 +204,8 @@ public void assertIsValid() { numTeamARobots++; } } - if (numTeamARobots < GameConstants.MIN_STARTING_ARCHONS || - numTeamARobots > GameConstants.MAX_STARTING_ARCHONS) { + if (numTeamARobots <= GameConstants.MIN_STARTING_ARCHONS || + numTeamARobots >= GameConstants.MAX_STARTING_ARCHONS) { throw new RuntimeException("Map must have between " + GameConstants.MIN_STARTING_ARCHONS + "and " + GameConstants.MAX_STARTING_ARCHONS + " starting Archons of each team"); } From f9c06ddbb85ef7bc161efd91ebe1d100b517efb1 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 14:17:30 -0500 Subject: [PATCH 230/413] Corrected per team passive lead increase --- engine/src/main/battlecode/common/GameConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index ddb5acb9..91883798 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -56,7 +56,7 @@ public class GameConstants { public static final int EXCEPTION_BYTECODE_PENALTY = 500; /** The amount of lead each team gains per turn. */ - public static final int PASSIVE_LEAD_INCREASE = 5; + public static final int PASSIVE_LEAD_INCREASE = 2; /** The number of rounds between adding lead resources to the map. */ public static final int ADD_LEAD_EVERY_ROUNDS = 20; From 11262c0bb8ae2af4d592f207b7bc03bca66d79bf Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 14:21:03 -0500 Subject: [PATCH 231/413] correcting archon to heal not damage --- engine/src/main/battlecode/common/RobotType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 349d7816..b2a5efc3 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -212,7 +212,7 @@ public int getDamage(int level) { if (!this.isBuilding() || level == 1) { return this.damage; } else if (this == RobotType.ARCHON) { - return level == 2 ? 3 : 4; + return level == 2 ? -3 : -4; } else if (this == RobotType.LABORATORY) { return 0; } else { From 3a55fa02445b6c3cb06f8c601dcd6aad2c82de33 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 14:38:32 -0500 Subject: [PATCH 232/413] Corrected damage and healing --- .../src/main/battlecode/common/RobotType.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index b2a5efc3..7659a13f 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -206,30 +206,39 @@ public int getMaxHealth(int level) { /** * Returns the damage of a robot by level. * @param level - * @return the damage for a robot by level + * @return the damage for a robot by level. + * 0 if it's a non-damaging robot. */ public int getDamage(int level) { - if (!this.isBuilding() || level == 1) { - return this.damage; - } else if (this == RobotType.ARCHON) { - return level == 2 ? -3 : -4; - } else if (this == RobotType.LABORATORY) { + + // Robots that heal or don't do damage. + // Note, damage is negative in the enum if healing, so cannot directly use damage. + if (this == RobotType.ARCHON || this == RobotType.LABORATORY || this == RobotType.BUILDER) return 0; - } else { + + if(this == RobotType.WATCHTOWER){ + if(this.getLevel() == 1) return this.damage; return level == 2 ? 6 : 7; } + + // Non-healing droids only. + return this.damage; } /** * @param level - * @return the healing per turn for a robot by level + * @return the healing per turn for a robot by level as a positive amount. + * 0 if robot doesn't heal. */ public int getHealing(int level) { - if (this == ARCHON || this == BUILDER) { + if(this == BUILDER || (this == ARCHON && level == 1)) return (int) (-1 * this.getDamage(level)); - } else { - return 0; + else{ + if(this == ARCHON && level != 1) + return level == 2 ? 3 : 4; } + + return 0; } // COST RELATED FUNCTIONS From 7abee782a61ff8847863e2af2a486aca47f6f2d2 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 14:57:14 -0500 Subject: [PATCH 233/413] Add considering team reserves in singularity --- engine/src/main/battlecode/world/GameWorld.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 1e5a0a19..0dd09d1e 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -335,6 +335,12 @@ public boolean setWinnerIfMoreArchons() { */ public boolean setWinnerIfMoreGoldValue() { int[] totalGoldValues = new int[2]; + + // consider team reserves + totalGoldValues[Team.A] += this.teamInfo.getGold(Team.A); + totalGoldValues[Team.B] += this.teamInfo.getGold(Team.B); + + // sum live robots worth for (InternalRobot robot : objectInfo.robotsArray()) { totalGoldValues[robot.getTeam().ordinal()] += robot.getType().getGoldWorth(robot.getLevel()); } @@ -353,6 +359,12 @@ public boolean setWinnerIfMoreGoldValue() { */ public boolean setWinnerIfMoreLeadValue() { int[] totalLeadValues = new int[2]; + + // consider team reserves + totalGoldValues[Team.A] += this.teamInfo.getLead(Team.A); + totalGoldValues[Team.B] += this.teamInfo.getLead(Team.B); + + // sum live robot worth for (InternalRobot robot : objectInfo.robotsArray()) { totalLeadValues[robot.getTeam().ordinal()] += robot.getType().getLeadWorth(robot.getLevel()); } From 128feeb3051028934f74ec6e62b788be05bc9ba0 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 15:38:33 -0500 Subject: [PATCH 234/413] correct Sage hp vs dmg amount --- engine/src/main/battlecode/common/RobotType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 7659a13f..a87ff61a 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -21,7 +21,7 @@ public enum RobotType { * Converts lead into gold * * @battlecode.doc.robot */ - LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), + LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), // BCL BCG AC MC HP DMG AR VR BL /** @@ -52,7 +52,7 @@ public enum RobotType { /** * Gold robot, causes Anomalies. */ - SAGE ( 0, 50, 200, 25, 45, 100, 13, 20, 10000) + SAGE ( 0, 50, 200, 25, 100, 45, 13, 20, 10000) // BCL BCG AC MC HP DMG AR VR BL ; From ea001284b6e6a7dc8b3946ca3538a830eee761d0 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 16:41:57 -0500 Subject: [PATCH 235/413] update protoype initial health name --- engine/src/main/battlecode/common/RobotType.java | 11 ++--------- engine/src/main/battlecode/world/InternalRobot.java | 2 +- engine/src/main/battlecode/world/MapBuilder.java | 7 ++++--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index a87ff61a..dc34a0bd 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -283,19 +283,12 @@ public int getGoldWorth(int level) { return goldWorth; } - /** - * @return Reclaim cost percentage for when robot is destroyed. - */ - public float getReclaimCostPercentage() { - return (this.isBuilding()) ? 0.2f : 0; - } - /** * @param level the robot's current level * @return the amount of lead dropped */ public int getLeadDropped(int level) { - return this.isBuilding() ? (int) (this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER) : 0; + return this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER; } /** @@ -303,7 +296,7 @@ public int getLeadDropped(int level) { * @return the amount of gold dropped */ public int getGoldDropped(int level) { - return this.isBuilding() ? (int) (this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER) : 0; + return this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER; } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int movementCooldown, diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index b67811ba..9c8a1b2c 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -58,7 +58,7 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.location = loc; this.level = 1; this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.DROID; - this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_STARTING_HEALTH_MULTIPLIER : 1) * this.type.getMaxHealth(this.level)); + this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1) * this.type.getMaxHealth(this.level)); this.controlBits = 0; this.currentBytecodeLimit = type.bytecodeLimit; diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 49fbb4ba..26e81d11 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -220,10 +220,11 @@ public void assertIsValid() { // assert rubble, lead, and Archon symmetry ArrayList allMapSymmetries = getSymmetry(robots); System.out.println("This map has the following symmetries: " + allMapSymmetries); - if (allMapSymmetries.isEmpty()) - throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); if (!allMapSymmetries.contains(this.symmetry)) - throw new RuntimeException("This map is supposed to have " + this.symmetry + " symmetry, but it doesn't"); + throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); + } + + // TODO: assert that at least one lead deposit inside vision range of at least one Archon } public boolean onTheMap(MapLocation loc) { From 45eb7a04a241140808b8cb09eefd40ad29e332f7 Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 17:06:05 -0500 Subject: [PATCH 236/413] Adding archon/lead guarantee --- .../src/main/battlecode/world/GameWorld.java | 2 +- .../src/main/battlecode/world/MapBuilder.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 0dd09d1e..fdbe02ed 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -260,7 +260,7 @@ public InternalRobot[] getAllRobotsWithinRadiusSquared(MapLocation center, int r return returnRobots.toArray(new InternalRobot[returnRobots.size()]); } - public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int radiusSquared) { + public static MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int radiusSquared) { ArrayList returnLocations = new ArrayList(); int ceiledRadius = (int) Math.ceil(Math.sqrt(radiusSquared)) + 1; // add +1 just to be safe int minX = Math.max(center.x - ceiledRadius, this.gameMap.getOrigin().x); diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 26e81d11..038212e6 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -224,7 +224,27 @@ public void assertIsValid() { throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); } - // TODO: assert that at least one lead deposit inside vision range of at least one Archon + // assert that at least one lead deposit inside vision range of at least one Archon + + boolean[] hasVisibleLead = {false, false}; + + for (RobotInfo r : bodies) { + if (r.getType() != RobotType.ARCHON) continue; + if (hasVisibleLead[r.getTeam().ordinal()]) continue; + + MapLocation[] visibleLocations = GameWorld.getAllLocationsWithinRadiusSquared( + r.getLocation(), + r.getVisionRadiusSquared() + ); + + for (MapLocation location : visibleLocations) + if (this.leadArray[locationToIndex(location.x, location.y)] > 0) + hasVisibleLead[r.getTeam().ordinal()] = true; + } + + if (!(hasVisibleLead[0] && hasVisibleLead[1])) { + throw new RuntimeException("Teams must have at least one lead deposit visible to an Archon."); + } } public boolean onTheMap(MapLocation loc) { From ebbaf88445fefe88b817c79820753722f568e92a Mon Sep 17 00:00:00 2001 From: Nicole Wong Date: Tue, 28 Dec 2021 17:29:21 -0500 Subject: [PATCH 237/413] Fixed compilation errors related to these revisions --- .../src/main/battlecode/common/RobotType.java | 6 ++-- .../src/main/battlecode/world/GameWorld.java | 29 +++++++++++++------ .../src/main/battlecode/world/MapBuilder.java | 7 +++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index dc34a0bd..a30ac63c 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -217,7 +217,7 @@ public int getDamage(int level) { return 0; if(this == RobotType.WATCHTOWER){ - if(this.getLevel() == 1) return this.damage; + if(level == 1) return this.damage; return level == 2 ? 6 : 7; } @@ -288,7 +288,7 @@ public int getGoldWorth(int level) { * @return the amount of lead dropped */ public int getLeadDropped(int level) { - return this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER; + return (int) (this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER); } /** @@ -296,7 +296,7 @@ public int getLeadDropped(int level) { * @return the amount of gold dropped */ public int getGoldDropped(int level) { - return this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER; + return (int) (this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER); } RobotType(int buildCostLead, int buildCostGold, int actionCooldown, int movementCooldown, diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index fdbe02ed..5e4c84fe 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -260,13 +260,24 @@ public InternalRobot[] getAllRobotsWithinRadiusSquared(MapLocation center, int r return returnRobots.toArray(new InternalRobot[returnRobots.size()]); } - public static MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int radiusSquared) { + public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int radiusSquared) { + return getAllLocationsWithinRadiusSquaredWithoutMap( + this.gameMap.getOrigin(), + this.gameMap.getWidth(), + this.gameMap.getHeight(), + center, radiusSquared + ); + } + + public static MapLocation[] getAllLocationsWithinRadiusSquaredWithoutMap(MapLocation origin, + int width, int height, + MapLocation center, int radiusSquared){ ArrayList returnLocations = new ArrayList(); int ceiledRadius = (int) Math.ceil(Math.sqrt(radiusSquared)) + 1; // add +1 just to be safe - int minX = Math.max(center.x - ceiledRadius, this.gameMap.getOrigin().x); - int minY = Math.max(center.y - ceiledRadius, this.gameMap.getOrigin().y); - int maxX = Math.min(center.x + ceiledRadius, this.gameMap.getOrigin().x + this.gameMap.getWidth() - 1); - int maxY = Math.min(center.y + ceiledRadius, this.gameMap.getOrigin().y + this.gameMap.getHeight() - 1); + int minX = Math.max(center.x - ceiledRadius, origin.x); + int minY = Math.max(center.y - ceiledRadius, origin.y); + int maxX = Math.min(center.x + ceiledRadius, origin.x + width - 1); + int maxY = Math.min(center.y + ceiledRadius, origin.y + height - 1); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { MapLocation newLocation = new MapLocation(x, y); @@ -337,8 +348,8 @@ public boolean setWinnerIfMoreGoldValue() { int[] totalGoldValues = new int[2]; // consider team reserves - totalGoldValues[Team.A] += this.teamInfo.getGold(Team.A); - totalGoldValues[Team.B] += this.teamInfo.getGold(Team.B); + totalGoldValues[Team.A.ordinal()] += this.teamInfo.getGold(Team.A); + totalGoldValues[Team.B.ordinal()] += this.teamInfo.getGold(Team.B); // sum live robots worth for (InternalRobot robot : objectInfo.robotsArray()) { @@ -361,8 +372,8 @@ public boolean setWinnerIfMoreLeadValue() { int[] totalLeadValues = new int[2]; // consider team reserves - totalGoldValues[Team.A] += this.teamInfo.getLead(Team.A); - totalGoldValues[Team.B] += this.teamInfo.getLead(Team.B); + totalLeadValues[Team.A.ordinal()] += this.teamInfo.getLead(Team.A); + totalLeadValues[Team.B.ordinal()] += this.teamInfo.getLead(Team.B); // sum live robot worth for (InternalRobot robot : objectInfo.robotsArray()) { diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 038212e6..332836c7 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -232,9 +232,12 @@ public void assertIsValid() { if (r.getType() != RobotType.ARCHON) continue; if (hasVisibleLead[r.getTeam().ordinal()]) continue; - MapLocation[] visibleLocations = GameWorld.getAllLocationsWithinRadiusSquared( + MapLocation[] visibleLocations = GameWorld.getAllLocationsWithinRadiusSquaredWithoutMap( + this.origin, + this.width, + this.height, r.getLocation(), - r.getVisionRadiusSquared() + r.getType().getVisionRadiusSquared(1) ); for (MapLocation location : visibleLocations) From ed9f3b6286951a494018f59e36a700947eed81cc Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 13:09:46 -0500 Subject: [PATCH 238/413] Fixes --- client/playback/src/gen/create.ts | 43 ++++++++++++++++--------------- schema/ts/battlecode_generated.ts | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 57ec5b8b..cb67f28a 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -543,34 +543,34 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = for (let j = 0; j < unitCount; j++) { let action: number | null = null; let actionTarget: number | null = null; - let actions = [] + let possible_actions = [] switch (bodies.types[j]) { case schema.BodyType.MINER: action = schema.Action.MINE; break; case schema.BodyType.ARCHON: - actions = [schema.Action.SPAWN_UNIT, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; // got rid of spawn unit for now because it causes problems + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.SOLDIER: - actions = [schema.Action.ATTACK]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.ATTACK]; + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.BUILDER: - actions = [schema.Action.BUILD, schema.Action.REPAIR, schema.Action.UPGRADE]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.BUILD, schema.Action.REPAIR, schema.Action.UPGRADE]; + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.LABORATORY: - actions = [schema.Action.CONVERT_GOLD, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.CONVERT_GOLD, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.SAGE: - actions = [schema.Action.ATTACK, schema.Action.LOCAL_ABYSS, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.ATTACK, schema.Action.LOCAL_ABYSS, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.WATCHTOWER: - actions = [schema.Action.ATTACK, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; - action = actions[Math.floor(Math.random() * actions.length)]; + possible_actions = [schema.Action.ATTACK, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; default: break; @@ -582,6 +582,7 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = } actionIDs.push(bodies.robotIDs[j]); actions.push(action); + actionTargets.push(actionTarget); } } @@ -725,20 +726,20 @@ function createSoupGame(turns: number) { function main(){ const games = [ - { name: "blank", game: createBlankGame(512)}, - { name: "stand", game: createStandGame(4000) }, + //{ name: "blank", game: createBlankGame(512)}, + //{ name: "stand", game: createStandGame(4000) }, //{ name: "pick", game: createPickGame(1024) }, - { name: "random-map", game: createBlankGame(512, true) }, - { name: "wander", game: createWanderGame(2048, 32) }, + //{ name: "random-map", game: createBlankGame(512, true) }, + //{ name: "wander", game: createWanderGame(2048, 32) }, { name: "wander-actions", game: createWanderGame(2048, 32, true) }, - { name: "wander-actions-random-map", game: createWanderGame(2048, 32, true, true)}, - { name: "life", game: createLifeGame(512) }, - { name: "votes", game: createVotesGame(512) } + //{ name: "wander-actions-random-map", game: createWanderGame(2048, 32, true, true)}, + //{ name: "life", game: createLifeGame(512) }, + //{ name: "votes", game: createVotesGame(512) } //{ name: "soup", game: createSoupGame(512) }, //{ name: "viewOptions", game: createViewOptionGame(512) } ]; SIZE = 64; - games.push({ name: "big-wander", game: createWanderGame(2048, 128) }); + //games.push({ name: "big-wander", game: createWanderGame(2048, 128) }); const prefix = "../examples/"; diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index 0093e8f9..faeea6b8 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. From 8e2049e6ff643b2401fc51a7fb1af465cafee3e2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 13:29:06 -0500 Subject: [PATCH 239/413] Add blue miner and portable building images --- .../static/img/robots/blue_lab_portable.png | Bin 0 -> 612 bytes .../src/static/img/robots/blue_miner.png | Bin 3103 -> 2220 bytes .../img/robots/blue_watchtower_portable.png | Bin 0 -> 474 bytes .../static/img/robots/red_lab_portable.png | Bin 0 -> 584 bytes .../img/robots/red_watchtower_portable.png | Bin 0 -> 476 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 client/visualizer/src/static/img/robots/blue_lab_portable.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_portable.png diff --git a/client/visualizer/src/static/img/robots/blue_lab_portable.png b/client/visualizer/src/static/img/robots/blue_lab_portable.png new file mode 100644 index 0000000000000000000000000000000000000000..f0d5ee8d713b81a94b0b2e1cbc2c2473029f2e87 GIT binary patch literal 612 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBsPB=d zi(^Oz>)nHndD5v83>Usz#wQ+S^*GA3@ZOvF^R~NYe~sa7Y`GQJz^k#%eu>mcN$Z)N zGmn^lj*IHtB9y6m=`{y?;{my+U6-B;MJHFEZfU)=hxc2b+#GIwalTU*)$d5}cDB?o zzO=`_;Qb40n;-8_?fibs?1tp+1vbjQ+BpI1vil9fZY;1-JgdEZv5oRs?c_wAfVlhb zZ#+=1F;qUwo&5BUb`gu7^s*>b<%@IVqU^w9bw}B!G+P^A>Y2atzRXwW%G|#Jet#})y|LS2 z);eQ%({gBY#fN5Uq7s#KQnzP}1%a{L~zW0E`qxV(R4wqewvE0jlEws6|)j;)b zL!E~A(y1QW6T_6&x~GF2{M#$w}QGLQ{c)oj}t{b!`-TS~OoCP3kTH`cZ7PN|~6)>DJ|~ r8+pHJq#p`;`F6_2x#m+K_SG}IY^aK1EpD6+Oa=^|u6{1-oD!M};470Ukr000SaNLh0L04^f{ z04^f|c%?sf0006HlM(??12rx*lVt&e5nOl>pMi79zX8`Z6u8LLp3Hgb6IzKXRc}!9{vaY%pZ@^5aTbFfJ5b)scNmZz_ zK$w~CZ~8Jl0Pz1&dIpq(Xo(0*_xzbUG~K>Me`!7K|7T&)(=}oUg7JFyYdf8|YRjk_ zTTN@H8%4tz5Gp{he>-u@!FS!Nwc;ve-_l>Pj-Clek7&_3(^)|b&a@weCic!AUUB1A zAn5A0iG~4>pDhA`pf>BRHc{BRLieLC*;0<0mHVSq!&To0Xc6N-ZLqFYQJ(CIis0DGef)3GZjn z)QzXImZ{t#Z`!LqV!ZHQcv^L7Ah8SvcN)B~7%b;B2;x;7Y(e+$I^BMhg%GE8w#n~i4JQHm2` z_U`gCKTzwQnDVRJ2E#SINkEbJg*G45fNLa%e3ZWcUbzb zf5`R98O#rXv{Z+dqrZ*>W&M%BZUs#U_m();F1?dok*T{ukKOE`x47IkrTw)a=s|;4 z{F0$aOh{n!?7}kJol;cW-3mjBYYg*FlC`I~1_bZXv(fmG=c!ot{vM)O<8!3Q;qpZD zQX@xt5-7jb)h%%B++Q$6R;(U0k-bERf8B}8R)Kh*)kBLyR~-CQZ$0cwESbEtm&K)K zsg1RGIhKu4J_M41AzR`lCB+s}|F}^Y?xgNhaud(x7Y1>`HLw1hhd&?WSf;e#;^d)2 z0onYh z^Q91ibq3N_jp%hWE%c#A0=vZ!f4_l|YVk`fk=W+cZ;bYz(4cpEKWYDdmST?Im>Wyx z7TM`tPSJ}~i+B*+^Y^dhHBI_35)*zfj2S|z*s4=(y3m}vry$0FY3j)^y5uR{hY?L^ zQ)KgzBfh%FSuW(X(c3Kj#nC=PaoOQLjO>Qi;!Z_M@#-|q87T|ot(#usP58MkE4sLo z!yj&Vk9}&z91&mtc&9Leo@xKtI_OF)#J?9F V9$Dyz)6M_@002ovPDHLkV1hXx69@nR delta 2476 zcmZ{mc{tQ-AI5*P*t2gZOO`A#mLXag##WYQF!rr7hG8_xOe2H%F=We{oGdvA;UGs@ zv*m=W5tTL4W~rH8J0Y*mbq>s;^q{P8@W>;8W4`~LT-6wLoAO#y`a8e@$CpeB`P z7taO&fGokn4hsOGN&pZU0|4I+q{syT2toqDk|zM@WdVSA;N8bK)WIOl$HkI}#R94a z%n7hV*a6r9K>+B%CG;ml4p;*Ck$gaa6GZYqd;xL{fQkHNh$8{;KbMH<*A3xiRQ}TR zHgPCSEPc!tc0vQ0p$aJ$QBz9;sVSeqfa+y9K+zeq zkOk-$c}p1U*|4-G}UAM!M`1aP@~r7m3pRpM!rI zO|OuzQ0)Wp1fL&0e^?GAgTJ(YuK&^F`u}?V9Awl$PlNOQxN!jB7_&4pcJO2CawCx) z97Vpfa!X3oYuSt;mvu%)%H;*ryr#L|i3L-NMYZC25-AB1xO**jFW8{Ur7lq`*}<7Uclzz3%)Z0Eh;CoTbl2NJ>Ojj_*%GkNWZ2Zv36WBHGm14<4ap)YrXWTf|I5D1SDmyV;i&7ic z<&hEJBX=t}<%`{XGP1RFJjX8?UA7QaxKJW%&9Lnf@IVi~F%Ol{*I=YnY&8q;_tv&W z(ZOFf0GyESywa1J*t#_TZdHa@FPF6PIwj|x_9&L_5N=k}EZieNa5qC5pSuM#YTPSz?nL*JcM@LbEgo zg=7iGNZzK=K+8+g0e%x)H0gfD_?tMlt8F(H_Y^3FtbEZ{d3vSfMeE06A2V28L{Qbg z%Azq@qMf^amttBH9{*}C;&|$ivK@a!MPT9P6|0m8N=sfH6+Fsb)K>U64 z+gj|ehnGW87gCQqj1hsg|X*09buR`w$c2 zAGmJ&yZUAYrfC$-!H0N z8+@O9%rX}^cMQo=dyVO383vzly>{OGViSBONBDXdQI^K49O%zRsFyfc)i?QJQXu?N ze3`5`(Xc4`X6VAS4{F>1#M^x#bGkm++{sQ?W5OQ#fqJ#WQrwMlcJZy3DeSWy&z~_K zuRaH!(6_03+?)!%@r&vqpUswypSh23h!h&9DBab>O#C*R46vXSx38<}iE zCL!kDXy3E3q8i-}ao4_+wm9W|sw#C6iE@0I!sIWUHCBxb@+- z`1zJt(j5MUAV+@rKu16)6Qs$cB|u!iNcQs7otdt%!3AcGb`@I4kd8uHpryEh+-C9K zQU7a;-fNE!$!!iM;&vO3@xLl5Jlvq&sWHDx37=G06ZxG3TNzXO8&vfDZq^E2J(JL< z=@3Bth?K?}=wLu_Yiw&~B2#fP=>~1d_t>!n=F4!&p$c5MqM?2;VO(BqTA%NH$Bv4r zVy+Y4D=Xh+_u##t#JQ~-(+177ug|r1d|@GJZ?Yejg^19C z;4U~g2AfGU#qFHjdwOb3U~^ zVwnxP9+V}2R;Wzu$7g-Ui ziBpGaheFyJ`X7$CRqUuG9I0bv42;xH?7k7Iej6AX>s%-Z4@W=*62~YidE3cBJ(s=< z^X-et@`8woJrp?TkJ3vkYVHoy&$E76qh8vWEj|u0fA ztBF{Cl(}qbTX$9HNni72K~V!}2Zw+^!e%!-w>xgUXU*sI>%7%m#h@y|@<+tCLT~TS zQU{zTo5Q$|_ERldMOtNiE0O&3-{A=<=e4&A%@@OdFe{0eUzfqjJ-{LK6Fs7=Az=&zsW zR6x$5d~4Z9?M2Vb?}lx4$ZUJh=1nOp-QRh?Pi*W`ZUrYSlCX?Np=u*aFw8s5EDVlj z>GK8zMVKYJ#Z33dtRSwtG@@0{C$fh{R%()O%$40w;zd0%nLe_FR&d<%ar}){s_)IL zZ{Eft`)~zqx-j>-z!f<9wBoLjgE-f7utn#T8>6hpSy%lw zoxMDKw2H-xd1VgvJF^VW^*f3C$abP(^mPBU*Zi3Q622^)XEDwhKltT&d=35*A9uTH zpZB*xbn8z=ZOW`Mm;IYVhH<#WYQj!(1{Xu`EqHX5tm;m?5OVMr0xZv1n>~P;cryMC D4#`)8 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_portable.png b/client/visualizer/src/static/img/robots/blue_watchtower_portable.png new file mode 100644 index 0000000000000000000000000000000000000000..03388193edc2873dc7c00541eef02ddbb1444b08 GIT binary patch literal 474 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBs4v3P z#W5s<_3lB#yxR^Ut`~o=y}rzQ?wUT+>qcMK=&ifEwC8|0BTvGSd5VeA%ANmZCboDu zsVHvawD>H+WFWif{2T6DXZAg?-K?J>kb8fJ#?>!pf;TJ;xoqt3=)ZDV`n)E&i{EB9 z3&tngosXFq!J1&VAmnr8(plNU+QkKrD&{q`njiT%gKcBtye9S(DVO*STnU<2?;N&a z6<1G4Y`&5HEbh|KPl!v!E9AIx#aP9$5dWTBv(~M}e)PasHhd5)arv zoXPEEoL8CJ!C*W?;&=?pc11Rgt9NFB96L$CvqQy2NQo2T_HV503g2cjBLr`hKl;Zq z=cdB8nf1>!cPzGF)5Lf2iSUt~A)h^-Y4Wh}F48==be4PYs+r3T1oi+;ll?3r)0t7t zbmo84)R)`}4GF1nk_PeOCLLy<=iN*{(32|VB2>?4xW#`{!c@5_z`$qlboFyt=akR{ E0Q0T0asU7T literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_lab_portable.png b/client/visualizer/src/static/img/robots/red_lab_portable.png new file mode 100644 index 0000000000000000000000000000000000000000..ea1d0afafb43fd2e09327adfd0cfcf1c79153cf1 GIT binary patch literal 584 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBsPCAk zi(^Oz>)nHldD5W*3>VDLiM(@Ap0MM^3weg% zX?ONe5uhV5Wtg8w%_rzIbxW|9Ec}4b?WAub+fBVk&?K|B3 ze_iY@^R0&`uav#TeQD1zzPHJ51(!)#Z%JR0`nGI~_>$CIEg#lfw}10m|LIsSwj?!i zRqU@8_vuWzk-J6u_8p&}wxlvXmMgftVvFC5@6%Z`@9|HwRjf${I^;Ju`&-$iQ)h8} zyT+-#^z~NZM!CaMfmiif7h7{*YMTEtUiPcRy{P_&F(F&Em$2^dc^Lh|a88$2@uj8} zMg97GRXp;Ft74RO!Gh1Lc(Prl7TdN32d4V%3Ib`0Tzq^(SQWEv8~>)m_lz(7KYfq; zlG~DA4|6S`uDcB@ie9OIk??b!YWb4wi^MfA>4|1axh|kEdg*pI{O94nt0r_G?spj{~1QBNS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBs4vRX z#W5s<_3lCMJYh!>h67a}Z*NRx6_VL{^?HiCNZC%tgZ&lnX5+`Kh>54)9SGk{rjfdEt6UQ z=I6tTO!a_!3#-c4yt=z`>D;2nm)`C?d~IGy^{JK;hb_;zrgCP+-QdhwT|Ql4ZRNIu z*BCP+ckWrsnkkUUdU2NO)!o5fuQ`RgIJWuetbJf?FYn8Jit7@W+|PGsE^+O9c&~D) z=$-07mw>Qo*MjG@e)iB_ac^$4lnW+|63cUl3d?gq$V6=`tn5^0Uvl`A{l!__zjD>j zcnEj-ehAsSTkT?$qK}7g)ACn$x30YBn%%lVomc5>$F)0?Oy2T6-MS(887oub@;w?; q`niQKZTS=y8K&`COZbw)Kc)x!{d2qCbo~PcKZB>MpUXO@geCxu=e-92 literal 0 HcmV?d00001 From 4d6880a6fac0cdbc60e326dddccd7bc3b36e9bcd Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Thu, 30 Dec 2021 13:44:07 -0500 Subject: [PATCH 240/413] Lead and gold icons and map display changes --- client/package-lock.json | 10 +- client/playback/package-lock.json | 1110 +---------------- client/visualizer/src/constants.ts | 124 +- client/visualizer/src/gamearea/renderer.ts | 465 +++---- client/visualizer/src/imageloader.ts | 315 ++--- .../src/static/img/resources/gold.png | Bin 0 -> 547 bytes .../src/static/img/resources/lead.png | Bin 0 -> 563 bytes .../src/static/img/tiles/terrain2.png | Bin 0 -> 3016 bytes .../src/static/img/tiles/terrain3.png | Bin 0 -> 2473 bytes 9 files changed, 497 insertions(+), 1527 deletions(-) create mode 100644 client/visualizer/src/static/img/resources/gold.png create mode 100644 client/visualizer/src/static/img/resources/lead.png create mode 100644 client/visualizer/src/static/img/tiles/terrain2.png create mode 100644 client/visualizer/src/static/img/tiles/terrain3.png diff --git a/client/package-lock.json b/client/package-lock.json index 1068690b..9c5f0fde 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,13 +1,5 @@ { "name": "battlecode-client", "version": "2022.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "battlecode-client", - "version": "2022.0.0", - "license": "GPL-3.0" - } - } + "lockfileVersion": 1 } diff --git a/client/playback/package-lock.json b/client/playback/package-lock.json index a1afa9bb..384eed44 100644 --- a/client/playback/package-lock.json +++ b/client/playback/package-lock.json @@ -1,1097 +1,7 @@ { "name": "battlecode-playback", - "lockfileVersion": 2, "requires": true, - "packages": { - "": { - "name": "battlecode-playback", - "license": "GPL-3.0", - "dependencies": { - "battlecode-schema": "file:../../schema", - "core-js": "^3.3.6", - "deepcopy": "^2.0.0", - "pako": "^1.0.10", - "victor": "^1.1.0" - }, - "devDependencies": { - "@types/blue-tape": "^0.1.33", - "@types/core-js": "^2.5.2", - "@types/node": "^12.12.5", - "@types/pako": "^1.0.1", - "@types/victor": "^1.1.0", - "blue-tape": "^1.0.0", - "npm-force-resolutions": "0.0.3", - "stream": "0.0.2", - "tap-dot": "^2.0.0", - "ts-node": "^8.4.1", - "tslint": "^5.20.0", - "typescript": "^3.6.4" - } - }, - "../../schema": { - "name": "battlecode-schema", - "version": "2022.0.0", - "license": "GPL-3.0", - "dependencies": { - "@types/flatbuffers": "^1.9.1", - "flatbuffers": "^1.11.0" - } - }, - "../../schema/node_modules/@types/flatbuffers": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", - "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==" - }, - "../../schema/node_modules/flatbuffers": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", - "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" - }, - "node_modules/@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.0.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "dependencies": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@types/blue-tape": { - "version": "0.1.33", - "resolved": "https://registry.npmjs.org/@types/blue-tape/-/blue-tape-0.1.33.tgz", - "integrity": "sha512-l5cQcLM3aPh55bBQ4geWQ8hZ4Ew+s4RvyhMaBpgW3aJ2HUfRgwd8ENKrk/utC4Hz1dJAiehyIa4vN6emxBMaog==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/tape": "*" - } - }, - "node_modules/@types/core-js": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.2.tgz", - "integrity": "sha512-+NPqjXgyA02xTHKJDeDca9u8Zr42ts6jhdND4C3PrPeQ35RJa0dmfAedXW7a9K4N1QcBbuWI1nSfGK4r1eVFCQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "12.12.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", - "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", - "dev": true - }, - "node_modules/@types/pako": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz", - "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==", - "dev": true - }, - "node_modules/@types/tape": { - "version": "4.2.33", - "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", - "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/victor": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/victor/-/victor-1.1.0.tgz", - "integrity": "sha512-37o+SnbGRoWqb2+6GQ3NoFX8Ff5zCvm0XsXFulNvO89t2zKluqb4twVORheAnmQ+iEd0rKzAcBGC2//3XBoU1A==", - "dev": true - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arg": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", - "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/battlecode-schema": { - "resolved": "../../schema", - "link": true - }, - "node_modules/blue-tape": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/blue-tape/-/blue-tape-1.0.0.tgz", - "integrity": "sha1-dYHQTAc5XJXEJrLtbR7bRUp2uSs=", - "dev": true, - "dependencies": { - "tape": ">=2.0.0 <5.0.0" - }, - "bin": { - "blue-tape": "bin/blue-tape.js" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/core-js": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.6.tgz", - "integrity": "sha512-u4oM8SHwmDuh5mWZdDg9UwNVq5s1uqq6ZDLLIs07VY+VJU91i3h4f3K/pgFvtUQPGdeStrZ+odKyfyt4EnKHfA==", - "hasInstallScript": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "node_modules/deepcopy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.0.0.tgz", - "integrity": "sha512-d5ZK7pJw7F3k6M5vqDjGiiUS9xliIyWkdzBjnPhnSeRGjkYOGZMCFkdKVwV/WiHOe0NwzB8q+iDo7afvSf0arA==", - "dependencies": { - "type-detect": "^4.0.8" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/emitter-component": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", - "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=", - "dev": true - }, - "node_modules/es-abstract": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", - "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", - "dev": true, - "dependencies": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "dependencies": { - "has": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-format": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz", - "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww=", - "dev": true - }, - "node_modules/make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/npm-force-resolutions": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.3.tgz", - "integrity": "sha512-xbIPAGzD3nrJHDLtnRFt/O83teTA8ju5pWTf8W6OKL4D0XD9EjdRNJhzg4bSXWuucE+l1HGdTpOJR/l1Mi1Ycg==", - "dev": true, - "dependencies": { - "json-format": "^1.0.1", - "source-map-support": "^0.5.5" - }, - "bin": { - "npm-force-resolutions": "index.js" - } - }, - "node_modules/object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/re-emitter": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz", - "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, - "node_modules/resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "dependencies": { - "through": "~2.3.4" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/stream": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", - "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=", - "dev": true, - "dependencies": { - "emitter-component": "^1.1.1" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tap-dot": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tap-dot/-/tap-dot-2.0.0.tgz", - "integrity": "sha512-7N1yPcRDgdfHCUbG6lZ0hXo53NyXhKIjJNhqKBixl9HVEG4QasG16Nlvr8wRnqr2ZRYVWmbmxwF3NOBbTLtQLQ==", - "dev": true, - "dependencies": { - "chalk": "^1.1.1", - "tap-out": "^1.3.2", - "through2": "^2.0.0" - }, - "bin": { - "tap-dot": "bin/dot" - } - }, - "node_modules/tap-out": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz", - "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=", - "dev": true, - "dependencies": { - "re-emitter": "^1.0.0", - "readable-stream": "^2.0.0", - "split": "^1.0.0", - "trim": "0.0.1" - }, - "bin": { - "tap-out": "bin/cmd.js" - } - }, - "node_modules/tape": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz", - "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==", - "dev": true, - "dependencies": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.4", - "has": "~1.0.3", - "inherits": "~2.0.4", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.11.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "bin": { - "tape": "bin/tape" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, - "node_modules/ts-node": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", - "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - }, - "peerDependencies": { - "typescript": ">=2.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "node_modules/tslint": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", - "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" - } - }, - "node_modules/tslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/typescript": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", - "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "node_modules/victor": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/victor/-/victor-1.1.0.tgz", - "integrity": "sha1-3jzHexVYmxsMeyLD2tKXA0qwAro=" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - }, + "lockfileVersion": 1, "dependencies": { "@babel/code-frame": { "version": "7.5.5", @@ -1733,15 +643,6 @@ "emitter-component": "^1.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", @@ -1773,6 +674,15 @@ "function-bind": "^1.1.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 40de2e26..55c70706 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -1,21 +1,29 @@ -import { schema } from 'battlecode-playback'; -import { Symmetry } from './mapeditor/index'; +import { schema } from 'battlecode-playback' +import { Symmetry } from './mapeditor/index' // Body types -export const ARCHON = schema.BodyType.ARCHON; -export const BUILDER = schema.BodyType.BUILDER; -export const LABORATORY = schema.BodyType.LABORATORY; -export const MINER = schema.BodyType.MINER; -export const SAGE = schema.BodyType.SAGE; -export const SOLDIER = schema.BodyType.SOLDIER; -export const WATCHTOWER = schema.BodyType.WATCHTOWER; - -export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER]; -export const initialBodyTypeList: number[] = [ARCHON]; - -export const bodyTypePriority: number[] = []; // for guns, drones, etc. that should be drawn over other robots - -export const TILE_COLORS: Array[] = [[119, 228, 88], [144, 230, 83], [166, 231, 79], [187, 232, 76], [206, 233, 76], [231, 207, 66], [245, 182, 72], [249, 158, 86], [219, 115, 109], [163, 90, 118], [99, 73, 103], [51, 52, 65]]; +export const ARCHON = schema.BodyType.ARCHON +export const BUILDER = schema.BodyType.BUILDER +export const LABORATORY = schema.BodyType.LABORATORY +export const MINER = schema.BodyType.MINER +export const SAGE = schema.BodyType.SAGE +export const SOLDIER = schema.BodyType.SOLDIER +export const WATCHTOWER = schema.BodyType.WATCHTOWER + +export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER] +export const initialBodyTypeList: number[] = [ARCHON] + +export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots + +export const TILE_COLORS: Array[] = [ + [168, 137, 97], + [147, 117, 77], + [88, 129, 87], + [58, 90, 64], + [52, 78, 65], + [11, 32, 39], + [8, 20, 20] +] // flashy colors // [0, 147, 83], // turquoise // [29, 201, 2], // green @@ -26,45 +34,45 @@ export const TILE_COLORS: Array[] = [[119, 228, 88], [144, 230, 83], [16 // Given passability, get index of tile to use. export const getLevel = (x: number): number => { - const nLev = TILE_COLORS.length; - const floatLevel = ((1 - x) - 0.1) / 0.9 * nLev; + const nLev = TILE_COLORS.length + const floatLevel = ((1 - x) - 0.1) / 0.9 * nLev const level = Math.floor(floatLevel) - return Math.min(nLev - 1, Math.max(0, level)); + return Math.min(nLev - 1, Math.max(0, level)) } export const passiveInfluenceRate = (round: number): number => { //return Math.floor((1/50 + 0.03 * Math.exp(-0.001 * x)) * x); this one's for slanderers - return Math.ceil(0.2 * Math.sqrt(round)); + return Math.ceil(0.2 * Math.sqrt(round)) } export const buffFactor = (numBuffs: number): number => { - return 1 + 0.001 * numBuffs; + return 1 + 0.001 * numBuffs } -export const ACTION_RADIUS_COLOR = "#46ff00"; -export const VISION_RADIUS_COLOR = "#0000ff"; +export const ACTION_RADIUS_COLOR = "#46ff00" +export const VISION_RADIUS_COLOR = "#0000ff" // Expected bot image size -export const IMAGE_SIZE = 50; +export const IMAGE_SIZE = 50 // Game canvas rendering sizes -export const INDICATOR_DOT_SIZE = .3; -export const INDICATOR_LINE_WIDTH = .3; +export const INDICATOR_DOT_SIZE = .3 +export const INDICATOR_LINE_WIDTH = .3 export const SIGHT_RADIUS_LINE_WIDTH = .15 // Game canvas rendering parameters -export const EFFECT_STEP = 200; //time change between effect animations +export const EFFECT_STEP = 200 //time change between effect animations // Map editor canvas parameters -export const DELTA = .0001; -export const MIN_DIMENSION = 15; -export const MAX_DIMENSION = 100; +export const DELTA = .0001 +export const MIN_DIMENSION = 15 +export const MAX_DIMENSION = 100 // Initial influence of enlightenment center, for map editor -export const INITIAL_INFLUENCE = 150; +export const INITIAL_INFLUENCE = 150 // Server settings -export const NUMBER_OF_TEAMS = 2; +export const NUMBER_OF_TEAMS = 2 // export const VICTORY_POINT_THRESH = 1000; // Other constants @@ -84,12 +92,12 @@ export enum MapType { // Map types to filter in runner export const mapTypes: MapType[] = [MapType.DEFAULT, - MapType.SPRINT_1, - MapType.SPRINT_2, - MapType.QUALIFYING, - MapType.HS_NEWBIE, - MapType.FINAL, - MapType.CUSTOM]; +MapType.SPRINT_1, +MapType.SPRINT_2, +MapType.QUALIFYING, +MapType.HS_NEWBIE, +MapType.FINAL, +MapType.CUSTOM] export const SERVER_MAPS: Map = new Map([ ["maptestsmall", MapType.DEFAULT], @@ -168,57 +176,57 @@ export const SERVER_MAPS: Map = new Map([ ["Stonks", MapType.FINAL], ["TheClientMapEditorIsSuperiorToGoogleSheetsEom", MapType.FINAL], ["TheSnackThatSmilesBack", MapType.FINAL] -]); +]) export function bodyTypeToString(bodyType: schema.BodyType) { switch (bodyType) { case ARCHON: - return "archon"; + return "archon" case WATCHTOWER: - return "watchtower"; + return "watchtower" case BUILDER: - return "builder"; + return "builder" case MINER: - return "miner"; + return "miner" case SAGE: - return "sage"; + return "sage" case SOLDIER: - return "soldier"; + return "soldier" case LABORATORY: - return "laboratory"; - default: throw new Error("invalid body type"); + return "laboratory" + default: throw new Error("invalid body type") } } export function symmetryToString(symmetry: Symmetry) { switch (symmetry) { - case Symmetry.ROTATIONAL: return "Rotational"; - case Symmetry.HORIZONTAL: return "Horizontal"; - case Symmetry.VERTICAL: return "Vertical"; - default: throw new Error("invalid symmetry"); + case Symmetry.ROTATIONAL: return "Rotational" + case Symmetry.HORIZONTAL: return "Horizontal" + case Symmetry.VERTICAL: return "Vertical" + default: throw new Error("invalid symmetry") } } export function abilityToEffectString(effect: number): string | null { switch (effect) { case 1: - return "empower"; + return "empower" case 2: - return "expose"; + return "expose" case 3: - return "embezzle"; + return "embezzle" case 4: - return "camouflage_red"; + return "camouflage_red" case 5: - return "camouflage_blue"; + return "camouflage_blue" default: - return null; + return null } } // TODO: fix radius (is this vision that can be toggled in sidebar?) export function radiusFromBodyType(bodyType: schema.BodyType) { - return -1; + return -1 // switch(bodyType) { // case MINER: // case LANDSCAPER: diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index 29fef393..be9f8665 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -1,11 +1,11 @@ -import * as config from '../config'; -import * as cst from '../constants'; -import NextStep from './nextstep'; +import * as config from '../config' +import * as cst from '../constants' +import NextStep from './nextstep' -import {GameWorld, Metadata, schema, Game} from 'battlecode-playback'; -import {AllImages} from '../imageloader'; -import Victor = require('victor'); -import { constants } from 'buffer'; +import { GameWorld, Metadata, schema, Game } from 'battlecode-playback' +import { AllImages } from '../imageloader' +import Victor = require('victor') +import { constants } from 'buffer' /** * Renders the world. @@ -14,25 +14,25 @@ import { constants } from 'buffer'; */ export default class Renderer { - readonly ctx: CanvasRenderingContext2D; + readonly ctx: CanvasRenderingContext2D // For rendering robot information on click - private lastSelectedID: number; + private lastSelectedID: number // position of mouse cursor hovering - private hoverPos: {x: number, y: number} | null = null; + private hoverPos: { x: number, y: number } | null = null; constructor(readonly canvas: HTMLCanvasElement, readonly imgs: AllImages, private conf: config.Config, readonly metadata: Metadata, readonly onRobotSelected: (id: number) => void, readonly onMouseover: (x: number, y: number, xrel: number, yrel: number, passability: number) => void) { - let ctx = canvas.getContext("2d"); + let ctx = canvas.getContext("2d") if (ctx === null) { - throw new Error("Couldn't load canvas2d context"); + throw new Error("Couldn't load canvas2d context") } else { - this.ctx = ctx; + this.ctx = ctx } - this.ctx['imageSmoothingEnabled'] = false; + this.ctx['imageSmoothingEnabled'] = false } @@ -48,22 +48,24 @@ export default class Renderer { // setup correct rendering const viewWidth = viewMax.x - viewMin.x const viewHeight = viewMax.y - viewMin.y - const scale = this.canvas.width / (!this.conf.doingRotate ? viewWidth : viewHeight); + const scale = this.canvas.width / (!this.conf.doingRotate ? viewWidth : viewHeight) - this.ctx.save(); - this.ctx.scale(scale, scale); - if (!this.conf.doingRotate) this.ctx.translate(-viewMin.x, -viewMin.y); - else this.ctx.translate(-viewMin.y, -viewMin.x); + this.ctx.save() + this.ctx.scale(scale, scale) + if (!this.conf.doingRotate) this.ctx.translate(-viewMin.x, -viewMin.y) + else this.ctx.translate(-viewMin.y, -viewMin.x) - this.renderBackground(world); - this.renderResources(world); + this.renderBackground(world) + this.renderResources(world) - this.renderBodies(world, curTime, nextStep, lerpAmount); - this.renderIndicatorDotsLines(world); - this.setMouseoverEvent(world); + this.renderBodies(world, curTime, nextStep, lerpAmount) + this.renderHoverBox(world) + + this.renderIndicatorDotsLines(world) + this.setMouseoverEvent(world) // restore default rendering - this.ctx.restore(); + this.ctx.restore() } /** @@ -74,123 +76,154 @@ export default class Renderer { } private renderBackground(world: GameWorld) { - this.ctx.save(); - this.ctx.fillStyle = "white"; - this.ctx.globalAlpha = 1; + this.ctx.save() + this.ctx.fillStyle = "white" + this.ctx.globalAlpha = 1 - let minX = world.minCorner.x; - let minY = world.minCorner.y; - let width = world.maxCorner.x - world.minCorner.x; - let height = world.maxCorner.y - world.minCorner.y; + let minX = world.minCorner.x + let minY = world.minCorner.y + let width = world.maxCorner.x - world.minCorner.x + let height = world.maxCorner.y - world.minCorner.y - const scale = 20; + const scale = 20 - this.ctx.scale(1/scale, 1/scale); + this.ctx.scale(1 / scale, 1 / scale) // scale the background pattern - if (!this.conf.doingRotate) this.ctx.fillRect(minX*scale, minY*scale, width*scale, height*scale); - else this.ctx.fillRect(minY*scale, minX*scale, height*scale, width*scale); + if (!this.conf.doingRotate) this.ctx.fillRect(minX * scale, minY * scale, width * scale, height * scale) + else this.ctx.fillRect(minY * scale, minX * scale, height * scale, width * scale) - const map = world.mapStats; + const map = world.mapStats - for (let i = 0; i < width; i++) for (let j = 0; j < height; j++){ - let idxVal = map.getIdx(i,j); - let plotJ = height-j-1; + for (let i = 0; i < width; i++) for (let j = 0; j < height; j++) { + let idxVal = map.getIdx(i, j) + let plotJ = height - j - 1 - const cx = (minX+i)*scale, cy = (minY+plotJ)*scale; + const cx = (minX + i) * scale, cy = (minY + plotJ) * scale - this.ctx.globalAlpha = 1; + this.ctx.globalAlpha = 1 // Fetch and draw tile image - const swampLevel = cst.getLevel(map.passability[idxVal]); - const tileImg = this.imgs.tiles[swampLevel]; - if (!this.conf.doingRotate) this.ctx.drawImage(tileImg, cx, cy, scale, scale); - else this.ctx.drawImage(tileImg, cy, cx, scale, scale); + const swampLevel = cst.getLevel(map.passability[idxVal]) + const tileImg = this.imgs.tiles[swampLevel] + + //since tiles arent completely opaque + if (!this.conf.doingRotate) this.ctx.clearRect(cx, cy, scale + .5, scale + .5) + else this.ctx.clearRect(cx, cy, scale + .5, scale + .5) + + //+1 is so that there arent gaps in the map + if (!this.conf.doingRotate) this.ctx.drawImage(tileImg, cx, cy, scale + .5, scale + .5) + else this.ctx.drawImage(tileImg, cy, cx, scale + .5, scale + .5) // Draw grid if (this.conf.showGrid) { - this.ctx.strokeStyle = 'gray'; - this.ctx.globalAlpha = 1; - if (!this.conf.doingRotate) this.ctx.strokeRect(cx, cy, scale, scale); - else this.ctx.strokeRect(cy, cx, scale, scale); + this.ctx.strokeStyle = 'gray' + this.ctx.globalAlpha = 1 + if (!this.conf.doingRotate) this.ctx.strokeRect(cx, cy, scale, scale) + else this.ctx.strokeRect(cy, cx, scale, scale) } } - // draw hover box last + this.ctx.restore() + } + + private renderHoverBox(world: GameWorld) { if (this.hoverPos != null) { - const {x, y} = this.hoverPos; - const cx = (minX+x)*scale, cy = (minY+(height-y-1))*scale; - this.ctx.strokeStyle = 'purple'; - this.ctx.lineWidth *= 2; - this.ctx.globalAlpha = 1; - if (!this.conf.doingRotate) this.ctx.strokeRect(cx, cy, scale, scale); - else this.ctx.strokeRect(cy, cx, scale, scale); + this.ctx.save() + this.ctx.fillStyle = "white" + this.ctx.globalAlpha = 1 + + let minX = world.minCorner.x + let minY = world.minCorner.y + let width = world.maxCorner.x - world.minCorner.x + let height = world.maxCorner.y - world.minCorner.y + + const scale = 20 + + this.ctx.scale(1 / scale, 1 / scale) + const { x, y } = this.hoverPos + const cx = (minX + x) * scale, cy = (minY + (height - y - 1)) * scale + this.ctx.strokeStyle = 'purple' + this.ctx.lineWidth *= 2 + this.ctx.globalAlpha = 1 + if (!this.conf.doingRotate) this.ctx.strokeRect(cx, cy, scale, scale) + else this.ctx.strokeRect(cy, cx, scale, scale) + this.ctx.restore() } - - this.ctx.restore(); } private renderResources(world: GameWorld) { - this.ctx.save(); - this.ctx.globalAlpha = 1; + this.ctx.save() + this.ctx.globalAlpha = 1 - let minX = world.minCorner.x; - let minY = world.minCorner.y; - let width = world.maxCorner.x - world.minCorner.x; - let height = world.maxCorner.y - world.minCorner.y; + let minX = world.minCorner.x + let minY = world.minCorner.y + let width = world.maxCorner.x - world.minCorner.x + let height = world.maxCorner.y - world.minCorner.y - const leadImg = this.imgs.resources.lead; - const goldImg = this.imgs.resources.gold; + const leadImg = this.imgs.resources.lead + const goldImg = this.imgs.resources.gold - const map = world.mapStats; - const scale = 1; + const map = world.mapStats + const scale = 1 const sigmoid = (x) => { - return 1 / (1 + Math.exp(-x)) + return 1 / (1 + Math.exp(-x)) } - for (let i = 0; i < width; i++) for (let j = 0; j < height; j++){ - let idxVal = map.getIdx(i,j); - let plotJ = height-j-1; + for (let i = 0; i < width; i++) for (let j = 0; j < height; j++) { + let idxVal = map.getIdx(i, j) + let plotJ = height - j - 1 - this.ctx.globalAlpha = 1; - const cx = (minX+i)*scale, cy = (minY+plotJ)*scale; + this.ctx.globalAlpha = 1 + const cx = (minX + i) * scale, cy = (minY + plotJ) * scale - if(map.goldVals[idxVal] > 0){ - let size = sigmoid(map.goldVals[idxVal] / 50); - if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1-size)/2, cy + (1-size)/2, scale * size, scale * size); - else this.ctx.drawImage(goldImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); + if (map.goldVals[idxVal] > 0) { + let size = sigmoid(map.goldVals[idxVal] / 50) + if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) + else this.ctx.drawImage(goldImg, cy + (1 - size) / 2, cx + (1 - size) / 2, scale * size, scale * size) + + + this.ctx.strokeStyle = 'gold' + this.ctx.lineWidth = 1 / 30 + if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) } - if(map.leadVals[idxVal] > 0){ - let size = sigmoid(map.leadVals[idxVal] / 50); - if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1-size)/2, cy + (1-size)/2, scale * size, scale * size); - else this.ctx.drawImage(leadImg, cy + (1-size)/2, cx + (1-size)/2, scale * size, scale * size); + if (map.leadVals[idxVal] > 0) { + let size = sigmoid(map.leadVals[idxVal] / 50) + if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) + else this.ctx.drawImage(leadImg, cy + (1 - size) / 2, cx + (1 - size) / 2, scale * size, scale * size) + + this.ctx.strokeStyle = '#59727d' + this.ctx.lineWidth = 1 / 30 + if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) } } - this.ctx.restore(); + this.ctx.restore() } private renderBodies(world: GameWorld, curTime: number, nextStep?: NextStep, lerpAmount?: number) { - const bodies = world.bodies; - const length = bodies.length; - const types = bodies.arrays.type; - const teams = bodies.arrays.team; - const hps = bodies.arrays.hp; - const ids = bodies.arrays.id; - const xs = bodies.arrays.x; - const ys = bodies.arrays.y; - const abilities = bodies.arrays.ability; - const minY = world.minCorner.y; - const maxY = world.maxCorner.y -1; - - let nextXs: Int32Array, nextYs: Int32Array, realXs: Float32Array, realYs: Float32Array; + const bodies = world.bodies + const length = bodies.length + const types = bodies.arrays.type + const teams = bodies.arrays.team + const hps = bodies.arrays.hp + const ids = bodies.arrays.id + const xs = bodies.arrays.x + const ys = bodies.arrays.y + const abilities = bodies.arrays.ability + const minY = world.minCorner.y + const maxY = world.maxCorner.y - 1 + + let nextXs: Int32Array, nextYs: Int32Array, realXs: Float32Array, realYs: Float32Array if (nextStep && lerpAmount) { - nextXs = nextStep.bodies.arrays.x; - nextYs = nextStep.bodies.arrays.y; - lerpAmount = lerpAmount || 0; + nextXs = nextStep.bodies.arrays.x + nextYs = nextStep.bodies.arrays.y + lerpAmount = lerpAmount || 0 } // Calculate the real xs and ys @@ -200,13 +233,13 @@ export default class Renderer { if (nextStep && lerpAmount) { // Interpolated // @ts-ignore - realXs[i] = xs[i] + (nextXs[i] - xs[i]) * lerpAmount; + realXs[i] = xs[i] + (nextXs[i] - xs[i]) * lerpAmount // @ts-ignore - realYs[i] = this.flip(ys[i] + (nextYs[i] - ys[i]) * lerpAmount, minY, maxY); + realYs[i] = this.flip(ys[i] + (nextYs[i] - ys[i]) * lerpAmount, minY, maxY) } else { // Not interpolated - realXs[i] = xs[i]; - realYs[i] = this.flip(ys[i], minY, maxY); + realXs[i] = xs[i] + realYs[i] = this.flip(ys[i], minY, maxY) } } @@ -214,17 +247,17 @@ export default class Renderer { // render images with priority last to have them be on top of other units. const drawEffect = (effect: string, x: number, y: number) => { - const effectImgs: HTMLImageElement[] = this.imgs.effects[effect]; - const whichImg = (Math.floor(curTime / cst.EFFECT_STEP) % effectImgs.length); - const effectImg = effectImgs[whichImg]; - this.drawBot(effectImg, x, y, 0); + const effectImgs: HTMLImageElement[] = this.imgs.effects[effect] + const whichImg = (Math.floor(curTime / cst.EFFECT_STEP) % effectImgs.length) + const effectImg = effectImgs[whichImg] + this.drawBot(effectImg, x, y, 0) } const renderBot = (i: number) => { - const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][teams[i]]; - this.drawBot(img, realXs[i], realYs[i], hps[i]); + const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][teams[i]] + this.drawBot(img, realXs[i], realYs[i], hps[i]) // TODO: draw bot - this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID); + this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID) // draw effect // TODO: handle abilities/actions @@ -232,17 +265,17 @@ export default class Renderer { // if (effect !== null) drawEffect(effect, realXs[i], realYs[i]); } - let priorityIndices: number[] = []; + let priorityIndices: number[] = [] for (let i = 0; i < length; i++) { - if(cst.bodyTypePriority.includes(types[i])){ - priorityIndices.push(i); - continue; + if (cst.bodyTypePriority.includes(types[i])) { + priorityIndices.push(i) + continue } - renderBot(i); + renderBot(i) } - priorityIndices.forEach((i) => renderBot(i)); + priorityIndices.forEach((i) => renderBot(i)) // Render empowered bodies // TODO: something similar for lead and gold @@ -256,7 +289,7 @@ export default class Renderer { // drawEffect(empowered_team[i] == 1 ? "empower_red" : "empower_blue", empowered_x[i], this.flip(empowered_y[i], minY, maxY)); // } - this.setInfoStringEvent(world, xs, ys); + this.setInfoStringEvent(world, xs, ys) } /** @@ -267,19 +300,19 @@ export default class Renderer { * yMax coordinate of the maximum edge */ private flip(y: number, yMin: number, yMax: number) { - return yMin + yMax - y; + return yMin + yMax - y } /** * Draws a cirlce centered at (x,y) with given squared radius and color. */ private drawBotRadius(x: number, y: number, radiusSquared: number, color: string) { - if (this.conf.doingRotate) [x,y] = [y,x]; - this.ctx.beginPath(); - this.ctx.arc(x+0.5, y+0.5, Math.sqrt(radiusSquared), 0, 2 * Math.PI); - this.ctx.strokeStyle = color; - this.ctx.lineWidth = cst.SIGHT_RADIUS_LINE_WIDTH; - this.ctx.stroke(); + if (this.conf.doingRotate) [x, y] = [y, x] + this.ctx.beginPath() + this.ctx.arc(x + 0.5, y + 0.5, Math.sqrt(radiusSquared), 0, 2 * Math.PI) + this.ctx.strokeStyle = color + this.ctx.lineWidth = cst.SIGHT_RADIUS_LINE_WIDTH + this.ctx.stroke() } /** @@ -288,11 +321,11 @@ export default class Renderer { private drawSightRadii(x: number, y: number, type: schema.BodyType, single?: Boolean) { // handle bots with no radius here, if necessary if (this.conf.seeActionRadius || single) { - this.drawBotRadius(x, y, this.metadata.types[type].actionRadiusSquared, cst.ACTION_RADIUS_COLOR); + this.drawBotRadius(x, y, this.metadata.types[type].actionRadiusSquared, cst.ACTION_RADIUS_COLOR) } if (this.conf.seeVisionRadius || single) { - this.drawBotRadius(x, y, this.metadata.types[type].visionRadiusSquared, cst.VISION_RADIUS_COLOR); + this.drawBotRadius(x, y, this.metadata.types[type].visionRadiusSquared, cst.VISION_RADIUS_COLOR) } } @@ -300,63 +333,63 @@ export default class Renderer { * Draws an image centered at (x, y) with the given radius */ private drawImage(img: HTMLImageElement, x: number, y: number, radius: number) { - if (this.conf.doingRotate) [x,y] = [y,x]; - this.ctx.drawImage(img, x-radius, y-radius, radius*2, radius*2); + if (this.conf.doingRotate) [x, y] = [y, x] + this.ctx.drawImage(img, x - radius, y - radius, radius * 2, radius * 2) } /** * Draws an image centered at (x, y), such that an image with default size covers a 1x1 cell */ private drawBot(img: HTMLImageElement, x: number, y: number, c: number) { - if (this.conf.doingRotate) [x,y] = [y,x]; - let realWidth = img.naturalWidth/cst.IMAGE_SIZE; - let realHeight = img.naturalHeight/cst.IMAGE_SIZE; + if (this.conf.doingRotate) [x, y] = [y, x] + let realWidth = img.naturalWidth / cst.IMAGE_SIZE + let realHeight = img.naturalHeight / cst.IMAGE_SIZE const sigmoid = (x) => { - return 1 / (1 + Math.exp(-x)) + return 1 / (1 + Math.exp(-x)) } //this.ctx.filter = `brightness(${sigmoid(c - 100) * 30 + 90}%)`; - let size = sigmoid(c / 100) * 1 + 0.3; - this.ctx.drawImage(img, x+(1-realWidth * size)/2, y+(1-realHeight * size)/2, realWidth * size, realHeight * size); + let size = sigmoid(c / 100) * 1 + 0.3 + this.ctx.drawImage(img, x + (1 - realWidth * size) / 2, y + (1 - realHeight * size) / 2, realWidth * size, realHeight * size) } private setInfoStringEvent(world: GameWorld, xs: Int32Array, ys: Int32Array) { // world information - const width = world.maxCorner.x - world.minCorner.x; - const height = world.maxCorner.y - world.minCorner.y; - const ids: Int32Array = world.bodies.arrays.id; + const width = world.maxCorner.x - world.minCorner.x + const height = world.maxCorner.y - world.minCorner.y + const ids: Int32Array = world.bodies.arrays.id // TODO: why is this Int8Array and not Int32Array? - const types: Int8Array = world.bodies.arrays.type; + const types: Int8Array = world.bodies.arrays.type // const radii: Float32Array = world.bodies.arrays.radius; - const onRobotSelected = this.onRobotSelected; + const onRobotSelected = this.onRobotSelected this.canvas.onmousedown = (event: MouseEvent) => { - const {x, y} = this.getIntegerLocation(event, world); + const { x, y } = this.getIntegerLocation(event, world) // Get the ID of the selected robot - let selectedRobotID; - let possiblePriorityID: number | undefined = undefined; + let selectedRobotID + let possiblePriorityID: number | undefined = undefined for (let i in ids) { if (xs[i] == x && ys[i] == y) { - selectedRobotID = ids[i]; - if(cst.bodyTypePriority.includes(types[i])) - possiblePriorityID = ids[i]; + selectedRobotID = ids[i] + if (cst.bodyTypePriority.includes(types[i])) + possiblePriorityID = ids[i] } } // if there are two robots in same cell, choose the one with priority - if(possiblePriorityID != undefined) selectedRobotID = possiblePriorityID; + if (possiblePriorityID != undefined) selectedRobotID = possiblePriorityID // Set the info string even if the robot is undefined - this.lastSelectedID = selectedRobotID; - onRobotSelected(selectedRobotID); - }; + this.lastSelectedID = selectedRobotID + onRobotSelected(selectedRobotID) + } } private setMouseoverEvent(world: GameWorld) { // world information // const width = world.maxCorner.x - world.minCorner.x; // const height = world.maxCorner.y - world.minCorner.y; - const onMouseover = this.onMouseover; + const onMouseover = this.onMouseover // const minY = world.minCorner.y; // const maxY = world.maxCorner.y - 1; @@ -366,99 +399,99 @@ export default class Renderer { // const y = this.flip(_y, minY, maxY) // Set the location of the mouseover - const {x,y} = this.getIntegerLocation(event, world); - const xrel = x - world.minCorner.x; - const yrel = y - world.minCorner.y; - const idx = world.mapStats.getIdx(xrel, yrel); - onMouseover(x, y, xrel, yrel, world.mapStats.passability[idx]); - this.hoverPos = {x: xrel, y: yrel}; - }; + const { x, y } = this.getIntegerLocation(event, world) + const xrel = x - world.minCorner.x + const yrel = y - world.minCorner.y + const idx = world.mapStats.getIdx(xrel, yrel) + onMouseover(x, y, xrel, yrel, world.mapStats.passability[idx]) + this.hoverPos = { x: xrel, y: yrel } + } this.canvas.onmouseout = (event) => { - this.hoverPos = null; - }; + this.hoverPos = null + } } private getIntegerLocation(event: MouseEvent, world: GameWorld) { - const width = world.maxCorner.x - world.minCorner.x; - const height = world.maxCorner.y - world.minCorner.y; - const minY = world.minCorner.y; - const maxY = world.maxCorner.y - 1; - var _x: number; - var _y: number; + const width = world.maxCorner.x - world.minCorner.x + const height = world.maxCorner.y - world.minCorner.y + const minY = world.minCorner.y + const maxY = world.maxCorner.y - 1 + var _x: number + var _y: number if (!this.conf.doingRotate) { - _x = width * event.offsetX / this.canvas.offsetWidth + world.minCorner.x; - _y = height * event.offsetY / this.canvas.offsetHeight + world.minCorner.y; + _x = width * event.offsetX / this.canvas.offsetWidth + world.minCorner.x + _y = height * event.offsetY / this.canvas.offsetHeight + world.minCorner.y _y = this.flip(_y, minY, maxY) } else { - _y = (world.maxCorner.y - world.minCorner.y - 1) - height * event.offsetX / this.canvas.offsetWidth + world.minCorner.y; - _x = width * event.offsetY / this.canvas.offsetHeight + world.minCorner.x; + _y = (world.maxCorner.y - world.minCorner.y - 1) - height * event.offsetX / this.canvas.offsetWidth + world.minCorner.y + _x = width * event.offsetY / this.canvas.offsetHeight + world.minCorner.x } - return {x: Math.floor(_x), y: Math.floor(_y+1)}; + return { x: Math.floor(_x), y: Math.floor(_y + 1) } } private renderIndicatorDotsLines(world: GameWorld) { if (!this.conf.indicators && !this.conf.allIndicators) { - return; + return } - const dots = world.indicatorDots; - const lines = world.indicatorLines; + const dots = world.indicatorDots + const lines = world.indicatorLines // Render the indicator dots - const dotsID = dots.arrays.id; - const dotsX = dots.arrays.x; - const dotsY = dots.arrays.y; - const dotsRed = dots.arrays.red; - const dotsGreen = dots.arrays.green; - const dotsBlue = dots.arrays.blue; - const minY = world.minCorner.y; - const maxY = world.maxCorner.y - 1; + const dotsID = dots.arrays.id + const dotsX = dots.arrays.x + const dotsY = dots.arrays.y + const dotsRed = dots.arrays.red + const dotsGreen = dots.arrays.green + const dotsBlue = dots.arrays.blue + const minY = world.minCorner.y + const maxY = world.maxCorner.y - 1 - console.log(dots.length); + console.log(dots.length) for (let i = 0; i < dots.length; i++) { if (dotsID[i] === this.lastSelectedID || this.conf.allIndicators) { - const red = dotsRed[i]; - const green = dotsGreen[i]; - const blue = dotsBlue[i]; - const x = dotsX[i]; - const y = this.flip(dotsY[i], minY, maxY); - - this.ctx.beginPath(); - this.ctx.arc(x+0.5, y+0.5, cst.INDICATOR_DOT_SIZE, 0, 2 * Math.PI, false); - this.ctx.fillStyle = `rgb(${red}, ${green}, ${blue})`; - this.ctx.fill(); + const red = dotsRed[i] + const green = dotsGreen[i] + const blue = dotsBlue[i] + const x = dotsX[i] + const y = this.flip(dotsY[i], minY, maxY) + + this.ctx.beginPath() + this.ctx.arc(x + 0.5, y + 0.5, cst.INDICATOR_DOT_SIZE, 0, 2 * Math.PI, false) + this.ctx.fillStyle = `rgb(${red}, ${green}, ${blue})` + this.ctx.fill() } } // Render the indicator lines - const linesID = lines.arrays.id; - const linesStartX = lines.arrays.startX; - const linesStartY = lines.arrays.startY; - const linesEndX = lines.arrays.endX; - const linesEndY = lines.arrays.endY; - const linesRed = lines.arrays.red; - const linesGreen = lines.arrays.green; - const linesBlue = lines.arrays.blue; - this.ctx.lineWidth = cst.INDICATOR_LINE_WIDTH; + const linesID = lines.arrays.id + const linesStartX = lines.arrays.startX + const linesStartY = lines.arrays.startY + const linesEndX = lines.arrays.endX + const linesEndY = lines.arrays.endY + const linesRed = lines.arrays.red + const linesGreen = lines.arrays.green + const linesBlue = lines.arrays.blue + this.ctx.lineWidth = cst.INDICATOR_LINE_WIDTH for (let i = 0; i < lines.length; i++) { if (linesID[i] === this.lastSelectedID || this.conf.allIndicators) { - const red = linesRed[i]; - const green = linesGreen[i]; - const blue = linesBlue[i]; - const startX = linesStartX[i]+0.5; - const startY = this.flip(linesStartY[i], minY, maxY)+0.5; - const endX = linesEndX[i]+0.5; - const endY = this.flip(linesEndY[i], minY, maxY)+0.5; - - this.ctx.beginPath(); - this.ctx.moveTo(startX, startY); - this.ctx.lineTo(endX, endY); - this.ctx.strokeStyle = `rgb(${red}, ${green}, ${blue})`; - this.ctx.stroke(); + const red = linesRed[i] + const green = linesGreen[i] + const blue = linesBlue[i] + const startX = linesStartX[i] + 0.5 + const startY = this.flip(linesStartY[i], minY, maxY) + 0.5 + const endX = linesEndX[i] + 0.5 + const endY = this.flip(linesEndY[i], minY, maxY) + 0.5 + + this.ctx.beginPath() + this.ctx.moveTo(startX, startY) + this.ctx.lineTo(endX, endY) + this.ctx.strokeStyle = `rgb(${red}, ${green}, ${blue})` + this.ctx.stroke() } } } diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index 0463b629..847efa0c 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -1,7 +1,7 @@ -import { basename } from 'path'; -import {Config} from './config'; -import * as cst from "./constants"; -type Image = HTMLImageElement; +import { basename } from 'path' +import { Config } from './config' +import * as cst from "./constants" +type Image = HTMLImageElement export type AllImages = { star: Image, @@ -15,8 +15,8 @@ export type AllImages = { watchtower: Array, }, resources: { - lead: Image, - gold: Image + lead: Image, + gold: Image } effects: { // TODO }, @@ -33,49 +33,49 @@ export type AllImages = { halveUPS: Image, goEnd: Image } -}; +} export function loadAll(config: Config, callback: (arg0: AllImages) => void) { - const dirname = "./static/img/"; + const dirname = "./static/img/" - const NEUTRAL: number = 0; - const RED: number = 1; - const BLU: number = 2; + const NEUTRAL: number = 0 + const RED: number = 1 + const BLU: number = 2 - function loadImage(obj, slot, path, src?) : void { - const f = loadImage; - f.expected++; - const image = new Image(); + function loadImage(obj, slot, path, src?): void { + const f = loadImage + f.expected++ + const image = new Image() - function onFinish(){ - if(f.requestedAll && f.expected == f.success + f.failure){ - console.log(`Total ${f.expected} images loaded: ${f.success} successful, ${f.failure} failed.`); - callback((Object.freeze(result) as unknown) as AllImages); + function onFinish() { + if (f.requestedAll && f.expected == f.success + f.failure) { + console.log(`Total ${f.expected} images loaded: ${f.success} successful, ${f.failure} failed.`) + callback((Object.freeze(result) as unknown) as AllImages) } } image.onload = () => { - obj[slot] = image; - f.success++; - onFinish(); - }; + obj[slot] = image + f.success++ + onFinish() + } image.onerror = () => { - obj[slot] = image; - f.failure++; - console.error(`CANNOT LOAD IMAGE: ${slot}, ${path}, ${image}`); - if(src) console.error(`Source: ${src}`); - onFinish(); + obj[slot] = image + f.failure++ + console.error(`CANNOT LOAD IMAGE: ${slot}, ${path}, ${image}`) + if (src) console.error(`Source: ${src}`) + onFinish() } // might want to use path library // webpack url loader triggers on require(".png"), so .png should be explicit - image.src = (src ? src : require(dirname + path + '.png').default); + image.src = (src ? src : require(dirname + path + '.png').default) } - loadImage.expected = 0; - loadImage.success = 0; - loadImage.failure = 0; - loadImage.requestedAll = false; + loadImage.expected = 0 + loadImage.success = 0 + loadImage.failure = 0 + loadImage.requestedAll = false const result = { tiles: [], @@ -114,79 +114,106 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { halveUPS: null, goEnd: null } - }; + } // helper function to manipulate images const htmlToData = (ele: HTMLImageElement): ImageData => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - if(!context) throw new Error("Error while converting a tile image"); - canvas.width = ele.width; - canvas.height = ele.height; - context.drawImage(ele, 0, 0); - return context.getImageData(0, 0, ele.width, ele.height); - }; + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + if (!context) throw new Error("Error while converting a tile image") + canvas.width = ele.width + canvas.height = ele.height + context.drawImage(ele, 0, 0) + return context.getImageData(0, 0, ele.width, ele.height) + } const dataToSrc = (data: ImageData): String => { - var canvas = document.createElement("canvas"); - canvas.width = data.width; - canvas.height = data.height; - var context = canvas.getContext("2d"); - if(!context) throw new Error("Error while converting a tile images"); - context.putImageData(data, 0, 0); - - return canvas.toDataURL(`edited.png`); - }; + var canvas = document.createElement("canvas") + canvas.width = data.width + canvas.height = data.height + var context = canvas.getContext("2d") + if (!context) throw new Error("Error while converting a tile images") + context.putImageData(data, 0, 0) + + return canvas.toDataURL(`edited.png`) + } - loadImage(result, 'star', 'star'); + loadImage(result, 'star', 'star') // terrain tiles { - const tintData = (data: ImageData, colors: Uint8Array): ImageData => { - const arr = new Uint8ClampedArray(data.data.length); - for(let i=0; i 128; - const factor = rock ? 1.5 : 1; - arr[i + 0] = colors[0] / factor; - arr[i + 1] = colors[1] / factor; - arr[i + 2] = colors[2] / factor; - arr[i + 3] = 240; + // const tintData = (data: ImageData, colors: Uint8Array): ImageData => { + // const arr = new Uint8ClampedArray(data.data.length) + // for (let i = 0; i < arr.length; i += 4) { + // const rock = data.data[i] > 128; + // const factor = rock ? 1.5 : 1; + // arr[i + 0] = colors[0] / factor; + // arr[i + 1] = colors[1] / factor; + // arr[i + 2] = colors[2] / factor; + // arr[i + 3] = 240 + // } + // const result = new ImageData(arr, data.height) + // return result + // } + + const randomTile = (dim: number, colors: Uint8Array, level: number): ImageData => { + var seed = level + 1 //avoid 0 + function srand() { + var x = Math.sin(seed++) * 10000 + return x - Math.floor(x) } - const result = new ImageData(arr, data.height); - return result; - } - - const baseTile: Image = new Image(); - baseTile.src = require(dirname + 'tiles/terrain.png').default; - const nLev = cst.TILE_COLORS.length; - baseTile.onload = () => { - for(let i=0; icst.TILE_COLORS[i]); - const path: String = dataToSrc(tinted); - loadImage(result.tiles, i, "", path.slice(0, path.length-4)); + const arr = new Uint8ClampedArray(dim ** 2 * 4) + for (let i = 0; i < arr.length; i += 4) { + var scale = 8 * (2 + level) / 255 + var shade = srand() * scale + 1 - scale; + arr[i + 0] = colors[level][0] * shade + arr[i + 1] = colors[level][1] * shade + arr[i + 2] = colors[level][2] * shade + arr[i + 3] = 255 } + const result = new ImageData(arr, dim) + return result + + } + + // const baseTile: Image = new Image() + // baseTile.src = require(dirname + 'tiles/terrain3.png').default + + const nLev = cst.TILE_COLORS.length + // baseTile.onload = () => { + // for (let i = 0; i < nLev; i++) { + // const data: ImageData = htmlToData(baseTile) + // const tinted: ImageData = randomTile(25, cst.TILE_COLORS, i) + // const path: String = dataToSrc(tinted) + // loadImage(result.tiles, i, "", path.slice(0, path.length - 4)) + // } + // } + + for (let i = 0; i < nLev; i++) { + const tinted: ImageData = randomTile(25, cst.TILE_COLORS, i) + const path: String = dataToSrc(tinted) + loadImage(result.tiles, i, "", path.slice(0, path.length - 4)) } } // robot sprites - loadImage(result.robots.archon, RED, 'robots/red_archon_portable'); - loadImage(result.robots.watchtower, RED, 'robots/red_watchtower'); - loadImage(result.robots.builder, RED, 'robots/red_builder'); - loadImage(result.robots.miner, RED, 'robots/red_miner'); - loadImage(result.robots.sage, RED, 'robots/red_sage'); - loadImage(result.robots.soldier, RED, 'robots/red_soldier'); - loadImage(result.robots.laboratory, RED, 'robots/red_lab'); - - loadImage(result.robots.archon, BLU, 'robots/blue_archon_portable'); - loadImage(result.robots.watchtower, BLU, 'robots/blue_watchtower'); - loadImage(result.robots.builder, BLU, 'robots/blue_builder'); - loadImage(result.robots.miner, BLU, 'robots/blue_miner'); - loadImage(result.robots.sage, BLU, 'robots/blue_sage'); - loadImage(result.robots.soldier, BLU, 'robots/blue_soldier'); - loadImage(result.robots.laboratory, BLU, 'robots/blue_lab'); - - loadImage(result.resources, 'lead', 'star'); - loadImage(result.resources, 'gold', 'star'); + loadImage(result.robots.archon, RED, 'robots/red_archon_portable') + loadImage(result.robots.watchtower, RED, 'robots/red_watchtower') + loadImage(result.robots.builder, RED, 'robots/red_builder') + loadImage(result.robots.miner, RED, 'robots/red_miner') + loadImage(result.robots.sage, RED, 'robots/red_sage') + loadImage(result.robots.soldier, RED, 'robots/red_soldier') + loadImage(result.robots.laboratory, RED, 'robots/red_lab') + + loadImage(result.robots.archon, BLU, 'robots/blue_archon_portable') + loadImage(result.robots.watchtower, BLU, 'robots/blue_watchtower') + loadImage(result.robots.builder, BLU, 'robots/blue_builder') + loadImage(result.robots.miner, BLU, 'robots/blue_miner') + loadImage(result.robots.sage, BLU, 'robots/blue_sage') + loadImage(result.robots.soldier, BLU, 'robots/blue_soldier') + loadImage(result.robots.laboratory, BLU, 'robots/blue_lab') + + loadImage(result.resources, 'lead', 'resources/lead') + loadImage(result.resources, 'gold', 'resources/gold') // loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); @@ -199,79 +226,79 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { { const makeTransparent = (data: ImageData): ImageData => { - const arr = new Uint8ClampedArray(data.data.length); - for(let i=0; i { - const arr = new Uint8ClampedArray(data.data.length); - for(let i=0; i { - const arr = new Uint8ClampedArray(data.data.length); - for(let i=0; i { - const data: ImageData = htmlToData(base); - const trans: ImageData = makeTransparent(data); - const red: ImageData = makeRed(trans); - const blue: ImageData = makeBlue(trans); - const path_red: String = dataToSrc(red); - const path_blue: String = dataToSrc(blue); - loadImage(result.effects.empower_red, i, "", path_red.slice(0, path_red.length-4)); - loadImage(result.effects.empower_blue, i, "", path_blue.slice(0, path_blue.length-4)); + const data: ImageData = htmlToData(base) + const trans: ImageData = makeTransparent(data) + const red: ImageData = makeRed(trans) + const blue: ImageData = makeBlue(trans) + const path_red: String = dataToSrc(red) + const path_blue: String = dataToSrc(blue) + loadImage(result.effects.empower_red, i, "", path_red.slice(0, path_red.length - 4)) + loadImage(result.effects.empower_blue, i, "", path_blue.slice(0, path_blue.length - 4)) } } } - loadImage(result.effects.expose, 0, 'effects/expose/expose_empty'); + loadImage(result.effects.expose, 0, 'effects/expose/expose_empty') - loadImage(result.effects.camouflage_red, 0, 'effects/camouflage/camo_red'); - loadImage(result.effects.camouflage_blue, 0, 'effects/camouflage/camo_blue'); + loadImage(result.effects.camouflage_red, 0, 'effects/camouflage/camo_red') + loadImage(result.effects.camouflage_blue, 0, 'effects/camouflage/camo_blue') // buttons are from https://material.io/resources/icons - loadImage(result.controls, 'goNext', 'controls/go-next'); - loadImage(result.controls, 'goPrevious', 'controls/go-previous'); - loadImage(result.controls, 'playbackPause', 'controls/playback-pause'); - loadImage(result.controls, 'playbackStart', 'controls/playback-start'); - loadImage(result.controls, 'playbackStop', 'controls/playback-stop'); - loadImage(result.controls, 'reverseUPS', 'controls/reverse'); - loadImage(result.controls, 'doubleUPS', 'controls/skip-forward'); - loadImage(result.controls, 'halveUPS', 'controls/skip-backward'); - loadImage(result.controls, 'goEnd', 'controls/go-end'); - - loadImage(result.controls, 'matchBackward', 'controls/green-previous'); - loadImage(result.controls, 'matchForward', 'controls/green-next'); - + loadImage(result.controls, 'goNext', 'controls/go-next') + loadImage(result.controls, 'goPrevious', 'controls/go-previous') + loadImage(result.controls, 'playbackPause', 'controls/playback-pause') + loadImage(result.controls, 'playbackStart', 'controls/playback-start') + loadImage(result.controls, 'playbackStop', 'controls/playback-stop') + loadImage(result.controls, 'reverseUPS', 'controls/reverse') + loadImage(result.controls, 'doubleUPS', 'controls/skip-forward') + loadImage(result.controls, 'halveUPS', 'controls/skip-backward') + loadImage(result.controls, 'goEnd', 'controls/go-end') + + loadImage(result.controls, 'matchBackward', 'controls/green-previous') + loadImage(result.controls, 'matchForward', 'controls/green-next') + // mark as finished - loadImage.requestedAll = true; + loadImage.requestedAll = true } diff --git a/client/visualizer/src/static/img/resources/gold.png b/client/visualizer/src/static/img/resources/gold.png new file mode 100644 index 0000000000000000000000000000000000000000..ed786d2563bd5fccb3339a7cb7cd303e3f071941 GIT binary patch literal 547 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~yTEL88gA|sYUcVZstk=`UF(iZa z?R3Y!!wNjEol}y}E}A|g_?+sl8Ofnu*=oy?A<{sweRA5wT zV41)mP&b-O z>$?oo_Ohos6M0Qe9$mZW#H#pAqrEO>4{R3{yIIb>W^BY`qpo7Fe|MsH!b6}-v2V2{NT?0!n?|kzs{*>ztZj&4%?@tVTaOs+m z;rUa`4=nXKY4-cS>YvHgq94Qrcd7q5S=HiJ17Jp!Rg@2y3Vl@W=@cHYv_Jpadr3aIJ-LvJ@3L_PxsD?)2 z`#rmNZGG`BP{{Pbkzl!5C*HBGediUq;P?*KIqO$W}QS&oez&GQBOc-}{nwx%LBHr4s*tCwBE_Kly33!wnRa fkZ?WF#PW~Pd3v4r$2DIqKoREY>gTe~DWM4f|8(Hv literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/tiles/terrain2.png b/client/visualizer/src/static/img/tiles/terrain2.png new file mode 100644 index 0000000000000000000000000000000000000000..c20a1cf74389990dda60d412e602da0792c11daa GIT binary patch literal 3016 zcmV;(3pezMP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jBCGD$>1RA>dQ+1H9xTM!1|-R+nY z;tL6iIR_BDaL^mQ^hxwWOo-@>2<9A~$$&XKXMg4V?V_ihqhP`Am8$-VYwgg3_3PKq zeE+MfFTS(Gcz+I18buH2@mHO$=L*B;lhR8vSrJ< z6)RSB@7}$uc>zj5V55JbcL<09=>7Zm)qef@wVaD0lMIN%9BbFCbHsXh7|THP;lqdG z=a_XZ`j>jk5r(CFD4^)`=g-~k+qVt7hYufCJO0CA29w3lFxgKY%pFXWMJdDH_GRH_xCCW+^wqRJl ze*Jottuj+?N)1_aMXw;hfu{INZiy(UPfU9>+NP^5x5J&6+iH^pYp%LL6q7@&D-^CK3cw_uIE`?{3|?)ur9P ze}5S&DvV*Yve16|^r__95@GD!yLY>N`}S3P;J|?jianE{$yj7ou3SldWelD&wax)L z{zUIofPr#^@csMuyRBQdR(WX=2ShBXXDt30Lzy{>l_e)`+_=$g+_; zb7G1QI=%PxF^`#ZgZ4I4Jh#7L1zU*z0Z0GJo?WF}zA zigBX);K74Y24sd)yLRoW)?R@hxwmiMj`06aZw?N7FXi6q9qp0Ui9~}FhycQ)&&jOG zK-NVpdt%$RZ5^kS7iTz?gMrZ~L5dSKIXkZ(+{io11;u=;mwcUbaYCdppqv`|nTr$V zQ0ovUL@JSU6SX&-elkI}#dm@kGoqbu^`;C3ffES|z4V~Smm`#jj!DEZmm@ZmIf`7I zb4&t7BE=a8MIy)v&Lt3ZtX{pk1jV70mv+mRErn+tCSzgH0bg*8V>q6a5*d6b51!#8Clm0M zuS%%ODDM7;V4T4mQeJVw9EEt}5E*^O+vvb^sssnWjh+CJX^n&WcAarih9`YITA&d z1Y66dWCS*6WqYWTNa3em0|-xy50H5Vu3fvfTJwxG$8jn`*IdS4dIi>EcF<4MsaFK}O zb)mm`|0sd}hb-(tzw>|Qy`N-+i(wZoT)P83pR~7B5H5%gC!& zuPQJCb>+&H%9JdlM4E&6ktlo5hp*rA(8~rbTE2XF@eC6&0t^8r^3&7P6*&<%hpz1{RMA zBmx8|1jvcJK(#&lWReg@)b?MW|L7B97*~m6?@Li}vJPF7m zW`J76fB;cqESi*s5)6)Ip7Y5>_+q4JI<4q|hnGJ6=+<{Y96x@%=3!V1vA@R|*2Xd! z!{TiVWX^qRi%&5tOJpv4S5b7#c%nqdAh%i4!&1|HL6^dMhi-C;KDP{ zX--&IZh4s^3)3Z7(LEdorvOvtF^UZEoLay+B~p~Ru{mbR2|!CSgsj6>g7CcQWzWTU zxb!Gnd&-z|J~YHxE&139m(J1Gc#9&5^j(N?qC5%QH)5ZBY)TIM!k#u|mCU&5S;Oml zS57?{PLPxgKP zmX_0WqZXTP#IZrY!DeD)&CdQXE;+%v zWt?-$#%YyPF=do!2d8c6&pxD!Q&X~$n$r(4A{(mBMnJTT$ET!PXUzdOuUwr%?l+0F zGD~KZ7blV#<(ELx(FQN}n2)V=pwTB&ibWH%MQM~B1_B!g4}i5~5^w7?tVGg(in%{H zjbcby(f`0pbh8#LYl4GfpN!y3iA}X$rk^OZ;8_Enb>JLUT3Vp^D9~ERpHnJFDTDCh zi?MOS8VZ&^oCMSu?;Ke`DBkI3Za#4D(7+)&KpQzY zZBQaZ5B-s?2Py+ZX=r>df>L_s%$fQ$BT}wp%e}*C6<*FE#veR*aCFCx979~FovVrd zC#O>I@aUuH%y`h>cxD)l2?bccozu@6hg)#GXdK))iX5%k$UnJ%{RVejACB?0Us6AN zbO=~E5@jvZIDm1h2ye!bv+0p?1D!i)d_ literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/tiles/terrain3.png b/client/visualizer/src/static/img/tiles/terrain3.png new file mode 100644 index 0000000000000000000000000000000000000000..3a31974a353047e9e59acd1efe65faa203b5a1f9 GIT binary patch literal 2473 zcmV;a30C%rP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91DWC%Y1ONa40RR91DF6Tf0Kg!GUjP6J6G=otR9Fd3*jZB)K@bGs-eHkL zkV_Fn4doU7|IhH1Ae4}hLvBToOJLovB9fpZ#@Xra%F4{D9(L`0{rYtARMfiluO`u#vdv@W_ zaY-TzoaB%TS!)0!5S&9HnP+765`lYrd(~e*fBvlf^Yimn9ppKq4SxLiQ3hxuqKQNT z8Dx!vgM;EDhbkL=!3ZHE8HbRQ90?^rngb5N?(S|SB+Q({C8=0(@RV?Wf4};WI}*Yp z(*E=@0SGb(S%*k|`#j4{bZ@9`kdjKuA&%yd09ajJE!ElrfHixpDK+p9A3i*ZB)}e` z900E_f<41`w~nx!4AR4Jw15GddFFaUdk37N2mzCT1nMyYT!58A8SR%?`OJ&4Uz~Za zx)2~j*DXx~nF)(Xxg#Z*Ywi*eV{qu>$B#u0xWrLq-5M?Gu;M;*p$rJ$4e>fB-iE8&n9E+@C$`X#)uy41|`sMelu=>? zkm5EG2*XlJ@nQ+LP6%T1z_N$C_LYf4;DH0-#cBcxgebc&6LOiyflxS1V4C=jvb-MHYqQ~=60jeT9{iw2OVJg0z0cqvjFIVE|&m03s3f)&=SlBOui;LtrAsamV*a#9hja zkTSzVLOT(H1RVIv@0p88$&(h7uQ#myzy`MFbzwmOg_QXoD3KCSFPQ|^T;7@7IA0Kl_ciaLh0Z_wdfruc4m_ToZ}% zIq#Vf_8A;hVg!s-fVdbSh9Ksc?If;-ol+r#xoUta>vppOr@F6Cl z)>X)w-qach$Vpss$rpDCGGFgz%qaoPNgMSHr+}J6)Ch=^ju4lTO%;&$nM+9d>;xl% zXv!xaGI{+VB#(I&a3N<-PxgHXv zB273lNWk+|jwr6lZ?BesDaPJmzV68>YB`fH0F(*<5_R^wkVX_aPWz2xzhs0(tT+cs z3>@!K#yE85#2bVmW@r_!Joxt3-)=y9L^4V#w3r}wFKi_OiXeq?k!yt62gil5N|=M^ z4j(aQ5aWWweV@(Cfe#*tyE^{>P59*U6yXbm|-QhN~MnrDKD5hIVi z_84-Qlh2Pb&v3yb(4VXXh|wXz1s5=ioIHbTfVgX&0|5Nq_Sqa40COoKtcfMomA$HF zo**%*;1$GaqI?_Yru{Br2MlY%(suLBS&k)~p0Wu-`2=UjS|<4WQ3IRvds z031=o%pqXp?SWuUv_0Wq4`GI!dbj?Yg(DW&iySAMWF*a5cX!$h;Di7mD#RoP%oQ(x zYw7bGKA1Upu;e2uj*B-3lOQ?j=R?XPDCKf@#R=t=AdVpJIlYPmk_Z^~6Q&io?H!yG zixgZW@_afzPy8h1D#iS;CqP>f{xFFnbSM9keYu||G? nnacqaUxbE4IqWAjJ`DR0Z~A=K_flv-00000NkvXXu0mjf> Date: Thu, 30 Dec 2021 13:53:46 -0500 Subject: [PATCH 241/413] sidebar changes --- client/visualizer/src/main/looper.ts | 15 +++ client/visualizer/src/sidebar/stats.ts | 166 +++++-------------------- 2 files changed, 44 insertions(+), 137 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index c7fd377c..1a3c0fa0 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -15,6 +15,7 @@ import WebSocketListener from '../main/websocket'; import { TeamStats } from 'battlecode-playback/out/gameworld'; import { Tournament, readTournament } from '../main/tournament'; +import { ARCHON } from '../constants'; /* Responsible for a single match in the visualizer. @@ -334,10 +335,17 @@ export default class Looper { let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); // Update each robot count + console.log(teamStats); this.stats.robots.forEach((type: schema.BodyType) => { this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b), teamHP); // TODO: differentiate levels, maybe }); + /*const hps = world.bodies.arrays.hp; + const types = world.bodies.arrays.type; + for(var i = 0; i < hps.length; i++){ + this.stats.setRobotCount(teamID, types[i], hps[i]); // TODO: show number of robots per level + this.stats.setRobotHP(teamID, types[i], hps[i], teamHP); // TODO: differentiate levels, maybe + }*/ // Set votes // this.stats.setVotes(teamID, teamStats.votes); @@ -347,6 +355,13 @@ export default class Looper { this.stats.setIncome(teamID, teamStats.leadChange, teamStats.goldChange, world.turn); // this.stats.setIncome(teamID, 3 + teamID, 5 + teamID, world.turn); } + this.stats.resetECs(); + const hps = world.bodies.arrays.hp; + const teams = world.bodies.arrays.team; + const types = world.bodies.arrays.type; + for(var i = 0; i < hps.length; i++){ + if(types[i] == ARCHON) this.stats.addEC(teams[i], hps[i]); + } if (this.match.winner && this.match.current.turn == this.match.lastTurn) { this.stats.setWinner(this.match.winner, teamNames, teamIDs); diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 4f8bb401..7432efb1 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -4,16 +4,17 @@ import { AllImages } from '../imageloader'; import { schema } from 'battlecode-playback'; import Runner from '../runner'; import Chart = require('chart.js'); +import { ARCHON } from '../constants'; const hex: Object = { 1: "#db3627", 2: "#4f7ee6" }; -type VoteBar = { +type ArchonBar = { bar: HTMLDivElement, - vote: HTMLSpanElement, - bid: HTMLSpanElement + archon: HTMLSpanElement, + //bid: HTMLSpanElement }; type BuffDisplay = { @@ -47,7 +48,7 @@ export default class Stats { private robotImages: Map> = new Map(); // the robot image elements in the unit statistics display private robotTds: Map>> = new Map(); - private voteBars: VoteBar[]; + private archonBars: ArchonBar[]; private maxVotes: number; private incomeDisplays: IncomeDisplay[]; @@ -167,83 +168,12 @@ export default class Stats { return table; } - private initVoteBars(teamIDs: Array) { - const voteBars: VoteBar[] = []; - teamIDs.forEach((teamID: number) => { - let votes = document.createElement("div"); - votes.className = "stat-bar"; - votes.style.backgroundColor = hex[teamID]; - let votesSpan = document.createElement("span"); - let bidSpan = document.createElement("span"); - votesSpan.innerHTML = "0"; - bidSpan.innerHTML = "0"; - // Store the stat bars - voteBars[teamID] = { - bar: votes, - vote: votesSpan, - bid: bidSpan - }; - }); - return voteBars; - } - - private getVoteBarElement(teamIDs: Array): HTMLElement { - const votesDiv = document.createElement('div'); - - const box = document.createElement('div'); - box.className = "votes-box"; - - const title = document.createElement('div'); - title.className = "stats-header"; - - const bars = document.createElement('div'); - bars.id = "vote-bars"; - bars.appendChild(document.createElement('div')); - - const votes = document.createElement('div'); - votes.className = "votes-info"; - const bids = document.createElement('div'); - bids.className = "votes-info"; - - title.innerHTML = "Voting"; - - const votesTitle = document.createElement('div'); - votesTitle.innerHTML = "Votes"; - votes.appendChild(votesTitle); - - const bidsTitle = document.createElement('div'); - bidsTitle.innerHTML = "Bid"; - bids.appendChild(bidsTitle); - - // build table - - teamIDs.forEach((id: number) => { - - const vote = document.createElement('div'); - vote.appendChild(this.voteBars[id].vote); - votes.appendChild(vote); - - const bid = document.createElement('div'); - bid.appendChild(this.voteBars[id].bid); - bids.appendChild(bid); - - bars.appendChild(this.voteBars[id].bar); - }); - - votesDiv.appendChild(title); - box.appendChild(bids); - box.appendChild(votes); - box.appendChild(bars); - votesDiv.appendChild(box); - return votesDiv; - } - private initRelativeBars(teamIDs: Array) { const relativeBars: HTMLDivElement[] = []; teamIDs.forEach((id: number) => { const bar = document.createElement("div"); bar.style.backgroundColor = hex[id]; - bar.style.width = `50%`; + bar.style.width = `100%`; bar.className = "influence-bar"; bar.innerText = "0"; @@ -259,10 +189,10 @@ export default class Stats { const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'Total Influence'; + label.innerText = 'Ideas'; const frame = document.createElement("div"); - frame.style.width = "90%"; + frame.style.width = "100%"; teamIDs.forEach((id: number) => { frame.appendChild(this.relativeBars[id]); @@ -273,20 +203,11 @@ export default class Stats { return div; } - private initBuffDisplays(teamIDs: Array) { - const buffDisplays: BuffDisplay[] = []; - teamIDs.forEach((id: number) => { - const numBuffs = document.createElement("sup"); - const buff = document.createElement("span"); - numBuffs.style.color = hex[id]; - buff.style.color = hex[id]; - buff.style.fontWeight = "bold"; - numBuffs.textContent = "0"; - buff.textContent = "1.000"; - buffDisplays[id] = {numBuffs: numBuffs, buff: buff}; - }); - return buffDisplays; + private updateRelBars(teamID: number, newval: number){ + console.log(this.div); + this.relativeBars[teamID].innerHTML = (newval === undefined) ? "0" : newval.toString(); } + private initIncomeDisplays(teamIDs: Array) { const incomeDisplays: IncomeDisplay[] = []; teamIDs.forEach((id: number) => { @@ -303,28 +224,6 @@ export default class Stats { return incomeDisplays; } - private getBuffDisplaysElement(teamIDs: Array): HTMLElement { - const div = document.createElement("div"); - div.id = "buffs"; - - const label = document.createElement('div'); - label.className = "stats-header"; - label.innerText = 'Buffs'; - div.appendChild(label); - - teamIDs.forEach((id: number) => { - const buffDiv = document.createElement("div"); - buffDiv.className = "buff-div"; - // cell.appendChild(document.createTextNode("1.001")); - // cell.appendChild(this.buffDisplays[id].numBuffs); - // cell.appendChild(document.createTextNode(" = ")); - buffDiv.appendChild(this.buffDisplays[id].buff); - div.appendChild(buffDiv); - }); - - return div; - } - private getIncomeDisplaysElement(teamIDs: Array): HTMLElement { const table = document.createElement("table"); table.id = "income-table"; @@ -365,7 +264,7 @@ export default class Stats { const div = document.createElement('div'); const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'EC Control'; + label.innerText = 'Archon Control'; div.appendChild(label); div.appendChild(this.ECs); return div; @@ -426,7 +325,6 @@ export default class Stats { while (this.div.firstChild) { this.div.removeChild(this.div.firstChild); } - this.voteBars = []; this.relativeBars = []; this.maxVotes = 750; this.teamMapToTurnsIncomeSet = new Map(); @@ -488,18 +386,15 @@ export default class Stats { this.div.appendChild(document.createElement("hr")); // Add stats table - this.voteBars = this.initVoteBars(teamIDs); - const voteBarsElement = this.getVoteBarElement(teamIDs); - this.div.appendChild(voteBarsElement); - + /*let archonnums: Array = [1, 2]; + teamIDs.forEach((id: number) => { + archonnums[id] = (this.robotTds[id]["count"][ARCHON].inner == undefined) ? 0 : this.robotTds[id]["count"][ARCHON].inner; + console.log(archonnums[id]); + });*/ this.relativeBars = this.initRelativeBars(teamIDs); const relativeBarsElement = this.getRelativeBarsElement(teamIDs); this.div.appendChild(relativeBarsElement); - this.buffDisplays = this.initBuffDisplays(teamIDs); - const buffDivsElement = this.getBuffDisplaysElement(teamIDs); - this.div.appendChild(buffDivsElement); - this.incomeDisplays = this.initIncomeDisplays(teamIDs); const incomeElement = this.getIncomeDisplaysElement(teamIDs); this.div.appendChild(incomeElement); @@ -581,6 +476,8 @@ export default class Stats { */ setRobotCount(teamID: number, robotType: schema.BodyType, count: number) { let td: HTMLTableCellElement = this.robotTds[teamID]["count"][robotType]; + console.log(teamID, count, "fsdfsdf"); + if(robotType === ARCHON) this.updateRelBars(teamID, count); console.log(count, robotType); td.innerHTML = String(count); } @@ -613,8 +510,8 @@ export default class Stats { */ setVotes(teamID: number, count: number) { // TODO: figure out if statbars.get(id) can actually be null?? - const statBar: VoteBar = this.voteBars[teamID]; - statBar.vote.innerText = String(count); + const statBar: ArchonBar = this.archonBars[teamID]; + statBar.archon.innerText = String(count); this.maxVotes = Math.max(this.maxVotes, count); statBar.bar.style.width = `${Math.min(100 * count / this.maxVotes, 100)}%`; @@ -635,12 +532,6 @@ export default class Stats { else relBar.style.width = String(Math.round(influence * 100 / totalInfluence)) + "%"; }*/ - setBuffs(teamID: number, numBuffs: number) { - //this.buffDisplays[teamID].numBuffs.textContent = String(numBuffs); - this.buffDisplays[teamID].buff.textContent = String(cst.buffFactor(numBuffs).toFixed(3)); - this.buffDisplays[teamID].buff.style.fontSize = 14 * Math.sqrt(Math.min(9, cst.buffFactor(numBuffs))) + "px"; - } - setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number) { // incomes this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later this.incomeDisplays[teamID].goldIncome.textContent = String(goldIncome); @@ -667,7 +558,7 @@ export default class Stats { this.teamNameNodes[teamID].innerHTML = "" + name + " " + `🌟`; } - setBid(teamID: number, bid: number) { + /*setBid(teamID: number, bid: number) { // TODO: figure out if statbars.get(id) can actually be null?? const statBar: VoteBar = this.voteBars[teamID]; statBar.bid.innerText = String(bid); @@ -679,7 +570,7 @@ export default class Stats { // if (this.images.star.parentNode === statBar.bar) { // this.images.star.remove(); // } - } + }*/ setExtraInfo(info: string) { this.extraInfo.innerHTML = info; @@ -696,11 +587,12 @@ export default class Stats { this.ECs.innerHTML = ""; } - addEC(teamID: number) { + addEC(teamID: number, health: number/*, img: HTMLImageElement */) { const div = document.createElement("div"); - div.style.width = "35px"; - div.style.height = "35px"; - const img = this.images.robots["enlightenmentCenter"][teamID].cloneNode() as HTMLImageElement; + let size = 1.0/(1 + Math.exp(-(health/100))) + 0.3; + div.style.width = (35*size).toString() + "px"; + div.style.height = (35*size).toString() + "px"; + const img = /* img */this.images.robots.archon[teamID].cloneNode() as HTMLImageElement; img.style.width = "64px"; img.style.height = "64px"; // update dynamically later div.appendChild(img); From aba3dad9917b3efb4a42c117e11ec7818cec1411 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 30 Dec 2021 14:30:19 -0500 Subject: [PATCH 242/413] added gold and lead back in --- client/visualizer/src/imageloader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index e9d60393..d36eace1 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -244,8 +244,8 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { loadImage(result.robots.soldier, BLU, 'robots/blue_soldier'); - loadImage(result.resources, 'lead', 'star'); - loadImage(result.resources, 'gold', 'star'); + loadImage(result.resources, 'lead', 'resources/lead'); + loadImage(result.resources, 'gold', 'resources/gold'); From fe766a8d7d508228c32afab1461960fbc106c6a3 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 30 Dec 2021 14:33:24 -0500 Subject: [PATCH 243/413] fixed transform always portable bug --- client/playback/src/gameworld.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index f0eefd5a..12d18276 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -467,7 +467,7 @@ export default class GameWorld { case schema.Action.TRANSFORM: setAction(); - this.bodies.alter({ id: robotID, portable: 1}); + this.bodies.alter({ id: robotID, portable: 1 - body.portable}); break; case schema.Action.UPGRADE: From 130cdb1f9d51aa9ed11e2d7d289715937575ceb2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 15:29:24 -0500 Subject: [PATCH 244/413] Regenerate ts file --- schema/ts/battlecode_generated.ts | 1230 +++++++++++------------------ 1 file changed, 454 insertions(+), 776 deletions(-) diff --git a/schema/ts/battlecode_generated.ts b/schema/ts/battlecode_generated.ts index ad2f7d3f..1aaf24df 100644 --- a/schema/ts/battlecode_generated.ts +++ b/schema/ts/battlecode_generated.ts @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify -import { flatbuffers } from "./flatbuffers" +import { flatbuffers } from "flatbuffers" /** * The possible types of things that can exist. * Note that bullets are not treated as bodies. @@ -30,30 +30,97 @@ export enum BodyType{ */ export namespace battlecode.schema{ export enum Action{ + /** + * Target: ID of robot attacked + */ ATTACK= 0, + + /** + * Target: ID of robot spawned + */ SPAWN_UNIT= 1, - MINE= 2, - BUILD= 3, - CONVERT_GOLD= 4, + + /** + * Target: location mined, x + y * width + */ + MINE_LEAD= 2, + + /** + * Target: location mined, x + y * width + */ + MINE_GOLD= 3, + + /** + * Target: none + */ + TRANSMUTE= 4, + + /** + * Target: none + */ TRANSFORM= 5, - UPGRADE= 6, + + /** + * Target: ID of robot mutated + */ + MUTATE= 6, + + /** + * Target: ID of robot repaired + */ REPAIR= 7, - CHANGE_HP= 8, + + /** + * Target: change in health (can be negative) + */ + CHANGE_HEALTH= 8, + + /** + * When a PROTOTYPE building upgrades to TURRET + * Target: none + */ FULLY_REPAIRED= 9, + + /** + * Target: Sage location, x + y * width + */ LOCAL_ABYSS= 10, - LOCAL_FURY= 11, - LOCAL_CHARGE= 12, + + /** + * Target: Sage location, x + y * width + */ + LOCAL_CHARGE= 11, + + /** + * Target: Sage location, x + y * width + */ + LOCAL_FURY= 12, + + /** + * Target: none + */ + ABYSS= 13, + + /** + * Target: none + */ + CHARGE= 14, + + /** + * Target: none + */ + FURY= 15, + + /** + * Target: 0 if 90 degrees clockwise, 1 if horizontal, 2 if vertical + */ + VORTEX= 16, /** * Dies due to an uncaught exception. * Target: none */ - DIE_EXCEPTION= 13, - ABYSS= 14, - CHARGE= 15, - FURY= 16, - VORTEX= 17, - SINGULARITY= 18 + DIE_EXCEPTION= 17 }}; /** @@ -841,6 +908,16 @@ maxCorner(obj?:battlecode.schema.Vec):battlecode.schema.Vec|null { return offset ? (obj || new battlecode.schema.Vec).__init(this.bb_pos + offset, this.bb!) : null; }; +/** + * The map symmetry: 0 for rotation, 1 for horizontal, 2 for vertical. + * + * @returns number + */ +symmetry():number { + var offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +}; + /** * The bodies on the map. * @@ -848,7 +925,7 @@ maxCorner(obj?:battlecode.schema.Vec):battlecode.schema.Vec|null { * @returns battlecode.schema.SpawnedBodyTable|null */ bodies(obj?:battlecode.schema.SpawnedBodyTable):battlecode.schema.SpawnedBodyTable|null { - var offset = this.bb!.__offset(this.bb_pos, 10); + var offset = this.bb!.__offset(this.bb_pos, 12); return offset ? (obj || new battlecode.schema.SpawnedBodyTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; @@ -858,76 +935,123 @@ bodies(obj?:battlecode.schema.SpawnedBodyTable):battlecode.schema.SpawnedBodyTab * @returns number */ randomSeed():number { - var offset = this.bb!.__offset(this.bb_pos, 12); + var offset = this.bb!.__offset(this.bb_pos, 14); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * The factor to divide cooldowns by + * The rubble on the map. * * @param number index * @returns number */ -passability(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 14); - return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; +rubble(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 16); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; /** * @returns number */ -passabilityLength():number { - var offset = this.bb!.__offset(this.bb_pos, 14); +rubbleLength():number { + var offset = this.bb!.__offset(this.bb_pos, 16); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; /** - * @returns Float64Array - */ -passabilityArray():Float64Array|null { - var offset = this.bb!.__offset(this.bb_pos, 14); - return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * @param battlecode.schema.VecTable= obj - * @returns battlecode.schema.VecTable|null + * @returns Int32Array */ -leadLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { +rubbleArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 16); - return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** + * The lead on the map. + * * @param number index * @returns number */ -leadAmounts(index: number):number|null { +lead(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 18); - return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0; + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; /** * @returns number */ -leadAmountsLength():number { +leadLength():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; /** - * @returns Float64Array + * @returns Int32Array */ -leadAmountsArray():Float64Array|null { +leadArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 18); - return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * The anomalies scheduled: 0/1/2/3 abyss/charge/fury/vortex. + * + * @param number index + * @returns number + */ +anomalies(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 20); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +anomaliesLength():number { + var offset = this.bb!.__offset(this.bb_pos, 20); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +anomaliesArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 20); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +}; + +/** + * The rounds the anomalies are scheduled for. + * + * @param number index + * @returns number + */ +anomalyRounds(index: number):number|null { + var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +}; + +/** + * @returns number + */ +anomalyRoundsLength():number { + var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +}; + +/** + * @returns Int32Array + */ +anomalyRoundsArray():Int32Array|null { + var offset = this.bb!.__offset(this.bb_pos, 22); + return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** * @param flatbuffers.Builder builder */ static startGameMap(builder:flatbuffers.Builder) { - builder.startObject(8); + builder.startObject(10); }; /** @@ -954,12 +1078,20 @@ static addMaxCorner(builder:flatbuffers.Builder, maxCornerOffset:flatbuffers.Off builder.addFieldStruct(2, maxCornerOffset, 0); }; +/** + * @param flatbuffers.Builder builder + * @param number symmetry + */ +static addSymmetry(builder:flatbuffers.Builder, symmetry:number) { + builder.addFieldInt32(3, symmetry, 0); +}; + /** * @param flatbuffers.Builder builder * @param flatbuffers.Offset bodiesOffset */ static addBodies(builder:flatbuffers.Builder, bodiesOffset:flatbuffers.Offset) { - builder.addFieldOffset(3, bodiesOffset, 0); + builder.addFieldOffset(4, bodiesOffset, 0); }; /** @@ -967,15 +1099,44 @@ static addBodies(builder:flatbuffers.Builder, bodiesOffset:flatbuffers.Offset) { * @param number randomSeed */ static addRandomSeed(builder:flatbuffers.Builder, randomSeed:number) { - builder.addFieldInt32(4, randomSeed, 0); + builder.addFieldInt32(5, randomSeed, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset rubbleOffset + */ +static addRubble(builder:flatbuffers.Builder, rubbleOffset:flatbuffers.Offset) { + builder.addFieldOffset(6, rubbleOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createRubbleVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); +}; + +/** + * @param flatbuffers.Builder builder + * @param number numElems + */ +static startRubbleVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset passabilityOffset + * @param flatbuffers.Offset leadOffset */ -static addPassability(builder:flatbuffers.Builder, passabilityOffset:flatbuffers.Offset) { - builder.addFieldOffset(5, passabilityOffset, 0); +static addLead(builder:flatbuffers.Builder, leadOffset:flatbuffers.Offset) { + builder.addFieldOffset(7, leadOffset, 0); }; /** @@ -983,10 +1144,10 @@ static addPassability(builder:flatbuffers.Builder, passabilityOffset:flatbuffers * @param Array. data * @returns flatbuffers.Offset */ -static createPassabilityVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(8, data.length, 8); +static createLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { - builder.addFloat64(data[i]); + builder.addInt32(data[i]); } return builder.endVector(); }; @@ -995,24 +1156,45 @@ static createPassabilityVector(builder:flatbuffers.Builder, data:number[] | Uint * @param flatbuffers.Builder builder * @param number numElems */ -static startPassabilityVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(8, numElems, 8); +static startLeadVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset anomaliesOffset + */ +static addAnomalies(builder:flatbuffers.Builder, anomaliesOffset:flatbuffers.Offset) { + builder.addFieldOffset(8, anomaliesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ +static createAnomaliesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (var i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadLocationsOffset + * @param number numElems */ -static addLeadLocations(builder:flatbuffers.Builder, leadLocationsOffset:flatbuffers.Offset) { - builder.addFieldOffset(6, leadLocationsOffset, 0); +static startAnomaliesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadAmountsOffset + * @param flatbuffers.Offset anomalyRoundsOffset */ -static addLeadAmounts(builder:flatbuffers.Builder, leadAmountsOffset:flatbuffers.Offset) { - builder.addFieldOffset(7, leadAmountsOffset, 0); +static addAnomalyRounds(builder:flatbuffers.Builder, anomalyRoundsOffset:flatbuffers.Offset) { + builder.addFieldOffset(9, anomalyRoundsOffset, 0); }; /** @@ -1020,10 +1202,10 @@ static addLeadAmounts(builder:flatbuffers.Builder, leadAmountsOffset:flatbuffers * @param Array. data * @returns flatbuffers.Offset */ -static createLeadAmountsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(8, data.length, 8); +static createAnomalyRoundsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { + builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { - builder.addFloat64(data[i]); + builder.addInt32(data[i]); } return builder.endVector(); }; @@ -1032,8 +1214,8 @@ static createLeadAmountsVector(builder:flatbuffers.Builder, data:number[] | Uint * @param flatbuffers.Builder builder * @param number numElems */ -static startLeadAmountsVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(8, numElems, 8); +static startAnomalyRoundsVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); }; /** @@ -1045,16 +1227,18 @@ static endGameMap(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, bodiesOffset:flatbuffers.Offset, randomSeed:number, passabilityOffset:flatbuffers.Offset, leadLocationsOffset:flatbuffers.Offset, leadAmountsOffset:flatbuffers.Offset):flatbuffers.Offset { +static createGameMap(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, minCornerOffset:flatbuffers.Offset, maxCornerOffset:flatbuffers.Offset, symmetry:number, bodiesOffset:flatbuffers.Offset, randomSeed:number, rubbleOffset:flatbuffers.Offset, leadOffset:flatbuffers.Offset, anomaliesOffset:flatbuffers.Offset, anomalyRoundsOffset:flatbuffers.Offset):flatbuffers.Offset { GameMap.startGameMap(builder); GameMap.addName(builder, nameOffset); GameMap.addMinCorner(builder, minCornerOffset); GameMap.addMaxCorner(builder, maxCornerOffset); + GameMap.addSymmetry(builder, symmetry); GameMap.addBodies(builder, bodiesOffset); GameMap.addRandomSeed(builder, randomSeed); - GameMap.addPassability(builder, passabilityOffset); - GameMap.addLeadLocations(builder, leadLocationsOffset); - GameMap.addLeadAmounts(builder, leadAmountsOffset); + GameMap.addRubble(builder, rubbleOffset); + GameMap.addLead(builder, leadOffset); + GameMap.addAnomalies(builder, anomaliesOffset); + GameMap.addAnomalyRounds(builder, anomalyRoundsOffset); return GameMap.endGameMap(builder); } } @@ -1098,17 +1282,17 @@ type():battlecode.schema.BodyType { }; /** - * @returns battlecode.schema.BodyType + * @returns number */ -spawnSource():battlecode.schema.BodyType { +buildCostLead():number { var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : battlecode.schema.BodyType.MINER; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -actionRadiusSquared():number { +buildCostGold():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1116,7 +1300,7 @@ actionRadiusSquared():number { /** * @returns number */ -visionRadiusSquared():number { +level2CostLead():number { var offset = this.bb!.__offset(this.bb_pos, 10); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1124,23 +1308,23 @@ visionRadiusSquared():number { /** * @returns number */ -actionCooldown():number { +level2CostGold():number { var offset = this.bb!.__offset(this.bb_pos, 12); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -movementCooldown():number { +level3CostLead():number { var offset = this.bb!.__offset(this.bb_pos, 14); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -bytecodeLimit():number { +level3CostGold():number { var offset = this.bb!.__offset(this.bb_pos, 16); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1148,16 +1332,15 @@ bytecodeLimit():number { /** * @returns number */ -dps():number { +actionCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 18); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number -<<<<<<< HEAD */ -hp():number { +movementCooldown():number { var offset = this.bb!.__offset(this.bb_pos, 20); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -1165,361 +1348,200 @@ hp():number { /** * @returns number */ -dpsMul():number { +health():number { var offset = this.bb!.__offset(this.bb_pos, 22); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -hpMul():number { +level2Health():number { var offset = this.bb!.__offset(this.bb_pos, 24); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -buildCost():number { +level3Health():number { var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * @param number index * @returns number */ -upgradeCostLead(index: number):number|null { +damage():number { var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -upgradeCostLeadLength():number { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +level2Damage():number { + var offset = this.bb!.__offset(this.bb_pos, 30); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * @returns Int32Array + * @returns number */ -upgradeCostLeadArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +level3Damage():number { + var offset = this.bb!.__offset(this.bb_pos, 32); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * @param number index * @returns number */ -upgradeCostGold(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; +actionRadiusSquared():number { + var offset = this.bb!.__offset(this.bb_pos, 34); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -upgradeCostGoldLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +visionRadiusSquared():number { + var offset = this.bb!.__offset(this.bb_pos, 36); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** - * @returns Int32Array + * @returns number */ -upgradeCostGoldArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +bytecodeLimit():number { + var offset = this.bb!.__offset(this.bb_pos, 38); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @param flatbuffers.Builder builder */ static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(14); -======= - */ -hp():number { - var offset = this.bb!.__offset(this.bb_pos, 20); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; ->>>>>>> engine + builder.startObject(18); }; /** - * @returns number + * @param flatbuffers.Builder builder + * @param battlecode.schema.BodyType type */ -<<<<<<< HEAD static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { builder.addFieldInt8(0, type, battlecode.schema.BodyType.MINER); -======= -dpsMul():number { - var offset = this.bb!.__offset(this.bb_pos, 22); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; ->>>>>>> engine }; /** - * @returns number + * @param flatbuffers.Builder builder + * @param number buildCostLead */ -<<<<<<< HEAD -static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema.BodyType) { - builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.MINER); +static addBuildCostLead(builder:flatbuffers.Builder, buildCostLead:number) { + builder.addFieldInt32(1, buildCostLead, 0); }; /** * @param flatbuffers.Builder builder - * @param number actionRadiusSquared + * @param number buildCostGold */ -static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(2, actionRadiusSquared, 0); +static addBuildCostGold(builder:flatbuffers.Builder, buildCostGold:number) { + builder.addFieldInt32(2, buildCostGold, 0); }; /** * @param flatbuffers.Builder builder - * @param number visionRadiusSquared + * @param number level2CostLead */ -static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { - builder.addFieldInt32(3, visionRadiusSquared, 0); -======= -hpMul():number { - var offset = this.bb!.__offset(this.bb_pos, 24); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +static addLevel2CostLead(builder:flatbuffers.Builder, level2CostLead:number) { + builder.addFieldInt32(3, level2CostLead, 0); }; /** - * @returns number + * @param flatbuffers.Builder builder + * @param number level2CostGold */ -buildCost():number { - var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; ->>>>>>> engine +static addLevel2CostGold(builder:flatbuffers.Builder, level2CostGold:number) { + builder.addFieldInt32(4, level2CostGold, 0); }; /** - * @returns number + * @param flatbuffers.Builder builder + * @param number level3CostLead */ -<<<<<<< HEAD -static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(4, actionCooldown, 0.0); +static addLevel3CostLead(builder:flatbuffers.Builder, level3CostLead:number) { + builder.addFieldInt32(5, level3CostLead, 0); }; /** * @param flatbuffers.Builder builder - * @param number movementCooldown + * @param number level3CostGold */ -static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) { - builder.addFieldFloat32(5, movementCooldown, 0.0); +static addLevel3CostGold(builder:flatbuffers.Builder, level3CostGold:number) { + builder.addFieldInt32(6, level3CostGold, 0); }; /** * @param flatbuffers.Builder builder - * @param number bytecodeLimit - */ -static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { - builder.addFieldInt32(6, bytecodeLimit, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number dps - */ -static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(7, dps, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number hp - */ -static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(8, hp, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number dpsMul - */ -static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(9, dpsMul, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number hpMul - */ -static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(10, hpMul, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(11, buildCost, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostLeadOffset - */ -static addUpgradeCostLead(builder:flatbuffers.Builder, upgradeCostLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, upgradeCostLeadOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @param number actionCooldown */ -static createUpgradeCostLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); +static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { + builder.addFieldInt32(7, actionCooldown, 0); }; /** * @param flatbuffers.Builder builder - * @param number numElems + * @param number movementCooldown */ -static startUpgradeCostLeadVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); +static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) { + builder.addFieldInt32(8, movementCooldown, 0); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostGoldOffset + * @param number health */ -static addUpgradeCostGold(builder:flatbuffers.Builder, upgradeCostGoldOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, upgradeCostGoldOffset, 0); +static addHealth(builder:flatbuffers.Builder, health:number) { + builder.addFieldInt32(9, health, 0); }; /** * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset + * @param number level2Health */ -static createUpgradeCostGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); +static addLevel2Health(builder:flatbuffers.Builder, level2Health:number) { + builder.addFieldInt32(10, level2Health, 0); }; /** * @param flatbuffers.Builder builder - * @param number numElems - */ -static startUpgradeCostGoldVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -======= -buildCost():number { - var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; -}; - -/** - * @param number index - * @returns number - */ -upgradeCostLead(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -upgradeCostLeadLength():number { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -upgradeCostLeadArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * @param number index - * @returns number - */ -upgradeCostGold(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; ->>>>>>> engine -}; - -/** - * @returns number + * @param number level3Health */ -upgradeCostGoldLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -<<<<<<< HEAD -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { - BodyTypeMetadata.startBodyTypeMetadata(builder); - BodyTypeMetadata.addType(builder, type); - BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); - BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); - BodyTypeMetadata.addActionCooldown(builder, actionCooldown); - BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); - BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDps(builder, dps); - BodyTypeMetadata.addHp(builder, hp); - BodyTypeMetadata.addDpsMul(builder, dpsMul); - BodyTypeMetadata.addHpMul(builder, hpMul); - BodyTypeMetadata.addBuildCost(builder, buildCost); - BodyTypeMetadata.addUpgradeCostLead(builder, upgradeCostLeadOffset); - BodyTypeMetadata.addUpgradeCostGold(builder, upgradeCostGoldOffset); - return BodyTypeMetadata.endBodyTypeMetadata(builder); -} -} -} -======= ->>>>>>> engine -/** - * @returns Int32Array - */ -upgradeCostGoldArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; +static addLevel3Health(builder:flatbuffers.Builder, level3Health:number) { + builder.addFieldInt32(11, level3Health, 0); }; /** * @param flatbuffers.Builder builder + * @param number damage */ -static startBodyTypeMetadata(builder:flatbuffers.Builder) { - builder.startObject(14); +static addDamage(builder:flatbuffers.Builder, damage:number) { + builder.addFieldInt32(12, damage, 0); }; /** * @param flatbuffers.Builder builder - * @param battlecode.schema.BodyType type + * @param number level2Damage */ -static addType(builder:flatbuffers.Builder, type:battlecode.schema.BodyType) { - builder.addFieldInt8(0, type, battlecode.schema.BodyType.MINER); +static addLevel2Damage(builder:flatbuffers.Builder, level2Damage:number) { + builder.addFieldInt32(13, level2Damage, 0); }; /** * @param flatbuffers.Builder builder - * @param battlecode.schema.BodyType spawnSource + * @param number level3Damage */ -static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema.BodyType) { - builder.addFieldInt8(1, spawnSource, battlecode.schema.BodyType.MINER); +static addLevel3Damage(builder:flatbuffers.Builder, level3Damage:number) { + builder.addFieldInt32(14, level3Damage, 0); }; /** @@ -1527,7 +1549,7 @@ static addSpawnSource(builder:flatbuffers.Builder, spawnSource:battlecode.schema * @param number actionRadiusSquared */ static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:number) { - builder.addFieldInt32(2, actionRadiusSquared, 0); + builder.addFieldInt32(15, actionRadiusSquared, 0); }; /** @@ -1535,23 +1557,7 @@ static addActionRadiusSquared(builder:flatbuffers.Builder, actionRadiusSquared:n * @param number visionRadiusSquared */ static addVisionRadiusSquared(builder:flatbuffers.Builder, visionRadiusSquared:number) { - builder.addFieldInt32(3, visionRadiusSquared, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number actionCooldown - */ -static addActionCooldown(builder:flatbuffers.Builder, actionCooldown:number) { - builder.addFieldFloat32(4, actionCooldown, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number movementCooldown - */ -static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) { - builder.addFieldFloat32(5, movementCooldown, 0.0); + builder.addFieldInt32(16, visionRadiusSquared, 0); }; /** @@ -1559,113 +1565,7 @@ static addMovementCooldown(builder:flatbuffers.Builder, movementCooldown:number) * @param number bytecodeLimit */ static addBytecodeLimit(builder:flatbuffers.Builder, bytecodeLimit:number) { - builder.addFieldInt32(6, bytecodeLimit, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number dps - */ -static addDps(builder:flatbuffers.Builder, dps:number) { - builder.addFieldInt32(7, dps, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number hp - */ -static addHp(builder:flatbuffers.Builder, hp:number) { - builder.addFieldInt32(8, hp, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number dpsMul - */ -static addDpsMul(builder:flatbuffers.Builder, dpsMul:number) { - builder.addFieldFloat32(9, dpsMul, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number hpMul - */ -static addHpMul(builder:flatbuffers.Builder, hpMul:number) { - builder.addFieldFloat32(10, hpMul, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(11, buildCost, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number buildCost - */ -static addBuildCost(builder:flatbuffers.Builder, buildCost:number) { - builder.addFieldInt32(11, buildCost, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostLeadOffset - */ -static addUpgradeCostLead(builder:flatbuffers.Builder, upgradeCostLeadOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, upgradeCostLeadOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createUpgradeCostLeadVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startUpgradeCostLeadVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset upgradeCostGoldOffset - */ -static addUpgradeCostGold(builder:flatbuffers.Builder, upgradeCostGoldOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, upgradeCostGoldOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param Array. data - * @returns flatbuffers.Offset - */ -static createUpgradeCostGoldVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { - builder.startVector(4, data.length, 4); - for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); - } - return builder.endVector(); -}; - -/** - * @param flatbuffers.Builder builder - * @param number numElems - */ -static startUpgradeCostGoldVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(4, numElems, 4); + builder.addFieldInt32(17, bytecodeLimit, 0); }; /** @@ -1677,22 +1577,26 @@ static endBodyTypeMetadata(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, spawnSource:battlecode.schema.BodyType, actionRadiusSquared:number, visionRadiusSquared:number, actionCooldown:number, movementCooldown:number, bytecodeLimit:number, dps:number, hp:number, dpsMul:number, hpMul:number, buildCost:number, upgradeCostLeadOffset:flatbuffers.Offset, upgradeCostGoldOffset:flatbuffers.Offset):flatbuffers.Offset { +static createBodyTypeMetadata(builder:flatbuffers.Builder, type:battlecode.schema.BodyType, buildCostLead:number, buildCostGold:number, level2CostLead:number, level2CostGold:number, level3CostLead:number, level3CostGold:number, actionCooldown:number, movementCooldown:number, health:number, level2Health:number, level3Health:number, damage:number, level2Damage:number, level3Damage:number, actionRadiusSquared:number, visionRadiusSquared:number, bytecodeLimit:number):flatbuffers.Offset { BodyTypeMetadata.startBodyTypeMetadata(builder); BodyTypeMetadata.addType(builder, type); - BodyTypeMetadata.addSpawnSource(builder, spawnSource); - BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); - BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); + BodyTypeMetadata.addBuildCostLead(builder, buildCostLead); + BodyTypeMetadata.addBuildCostGold(builder, buildCostGold); + BodyTypeMetadata.addLevel2CostLead(builder, level2CostLead); + BodyTypeMetadata.addLevel2CostGold(builder, level2CostGold); + BodyTypeMetadata.addLevel3CostLead(builder, level3CostLead); + BodyTypeMetadata.addLevel3CostGold(builder, level3CostGold); BodyTypeMetadata.addActionCooldown(builder, actionCooldown); BodyTypeMetadata.addMovementCooldown(builder, movementCooldown); + BodyTypeMetadata.addHealth(builder, health); + BodyTypeMetadata.addLevel2Health(builder, level2Health); + BodyTypeMetadata.addLevel3Health(builder, level3Health); + BodyTypeMetadata.addDamage(builder, damage); + BodyTypeMetadata.addLevel2Damage(builder, level2Damage); + BodyTypeMetadata.addLevel3Damage(builder, level3Damage); + BodyTypeMetadata.addActionRadiusSquared(builder, actionRadiusSquared); + BodyTypeMetadata.addVisionRadiusSquared(builder, visionRadiusSquared); BodyTypeMetadata.addBytecodeLimit(builder, bytecodeLimit); - BodyTypeMetadata.addDps(builder, dps); - BodyTypeMetadata.addHp(builder, hp); - BodyTypeMetadata.addDpsMul(builder, dpsMul); - BodyTypeMetadata.addHpMul(builder, hpMul); - BodyTypeMetadata.addBuildCost(builder, buildCost); - BodyTypeMetadata.addUpgradeCostLead(builder, upgradeCostLeadOffset); - BodyTypeMetadata.addUpgradeCostGold(builder, upgradeCostGoldOffset); return BodyTypeMetadata.endBodyTypeMetadata(builder); } } @@ -2191,123 +2095,20 @@ static startProfilesVector(builder:flatbuffers.Builder, numElems:number) { * @param flatbuffers.Builder builder * @returns flatbuffers.Offset */ -static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { - var offset = builder.endObject(); - return offset; -}; - -static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { - ProfilerFile.startProfilerFile(builder); - ProfilerFile.addFrames(builder, framesOffset); - ProfilerFile.addProfiles(builder, profilesOffset); - return ProfilerFile.endProfilerFile(builder); -} -} -} -/** - * @constructor - */ -export namespace battlecode.schema{ -export class Constants { - bb: flatbuffers.ByteBuffer|null = null; - - bb_pos:number = 0; -/** - * @param number i - * @param flatbuffers.ByteBuffer bb - * @returns Constants - */ -__init(i:number, bb:flatbuffers.ByteBuffer):Constants { - this.bb_pos = i; - this.bb = bb; - return this; -}; - -/** - * @param flatbuffers.ByteBuffer bb - * @param Constants= obj - * @returns Constants - */ -static getRootAsConstants(bb:flatbuffers.ByteBuffer, obj?:Constants):Constants { - return (obj || new Constants).__init(bb.readInt32(bb.position()) + bb.position(), bb); -}; - -/** - * @returns number - */ -leadAdditiveIncease():number { - var offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; -}; - -/** - * @returns number - */ -goldAdditiveIncease():number { - var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; -}; - -/** - * @returns number - */ -increasePeriod():number { - var offset = this.bb!.__offset(this.bb_pos, 8); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; -}; - -/** - * @param flatbuffers.Builder builder - */ -static startConstants(builder:flatbuffers.Builder) { - builder.startObject(3); -}; - -/** - * @param flatbuffers.Builder builder - * @param number leadAdditiveIncease - */ -static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { - builder.addFieldFloat64(0, leadAdditiveIncease, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number goldAdditiveIncease - */ -static addGoldAdditiveIncease(builder:flatbuffers.Builder, goldAdditiveIncease:number) { - builder.addFieldFloat64(1, goldAdditiveIncease, 0.0); -}; - -/** - * @param flatbuffers.Builder builder - * @param number increasePeriod - */ -static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { - builder.addFieldInt32(2, increasePeriod, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @returns flatbuffers.Offset - */ -static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { +static endProfilerFile(builder:flatbuffers.Builder):flatbuffers.Offset { var offset = builder.endObject(); return offset; }; -static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { - Constants.startConstants(builder); - Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); - Constants.addGoldAdditiveIncease(builder, goldAdditiveIncease); - Constants.addIncreasePeriod(builder, increasePeriod); - return Constants.endConstants(builder); +static createProfilerFile(builder:flatbuffers.Builder, framesOffset:flatbuffers.Offset, profilesOffset:flatbuffers.Offset):flatbuffers.Offset { + ProfilerFile.startProfilerFile(builder); + ProfilerFile.addFrames(builder, framesOffset); + ProfilerFile.addProfiles(builder, profilesOffset); + return ProfilerFile.endProfilerFile(builder); } } } /** -<<<<<<< HEAD -======= * @constructor */ export namespace battlecode.schema{ @@ -2338,24 +2139,16 @@ static getRootAsConstants(bb:flatbuffers.ByteBuffer, obj?:Constants):Constants { /** * @returns number */ -leadAdditiveIncease():number { +increasePeriod():number { var offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; /** * @returns number */ -goldAdditiveIncease():number { +leadAdditiveIncease():number { var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; -}; - -/** - * @returns number - */ -increasePeriod():number { - var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; }; @@ -2363,31 +2156,23 @@ increasePeriod():number { * @param flatbuffers.Builder builder */ static startConstants(builder:flatbuffers.Builder) { - builder.startObject(3); -}; - -/** - * @param flatbuffers.Builder builder - * @param number leadAdditiveIncease - */ -static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { - builder.addFieldFloat64(0, leadAdditiveIncease, 0.0); + builder.startObject(2); }; /** * @param flatbuffers.Builder builder - * @param number goldAdditiveIncease + * @param number increasePeriod */ -static addGoldAdditiveIncease(builder:flatbuffers.Builder, goldAdditiveIncease:number) { - builder.addFieldFloat64(1, goldAdditiveIncease, 0.0); +static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { + builder.addFieldInt32(0, increasePeriod, 0); }; /** * @param flatbuffers.Builder builder - * @param number increasePeriod + * @param number leadAdditiveIncease */ -static addIncreasePeriod(builder:flatbuffers.Builder, increasePeriod:number) { - builder.addFieldInt32(2, increasePeriod, 0); +static addLeadAdditiveIncease(builder:flatbuffers.Builder, leadAdditiveIncease:number) { + builder.addFieldInt32(1, leadAdditiveIncease, 0); }; /** @@ -2399,17 +2184,15 @@ static endConstants(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createConstants(builder:flatbuffers.Builder, leadAdditiveIncease:number, goldAdditiveIncease:number, increasePeriod:number):flatbuffers.Offset { +static createConstants(builder:flatbuffers.Builder, increasePeriod:number, leadAdditiveIncease:number):flatbuffers.Offset { Constants.startConstants(builder); - Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); - Constants.addGoldAdditiveIncease(builder, goldAdditiveIncease); Constants.addIncreasePeriod(builder, increasePeriod); + Constants.addLeadAdditiveIncease(builder, leadAdditiveIncease); return Constants.endConstants(builder); } } } /** ->>>>>>> engine * The first event sent in the game. Contains all metadata about the game. * * @constructor @@ -2964,10 +2747,12 @@ teamIDsArray():Int32Array|null { }; /** + * The total amount of lead change of this team, this round + * * @param number index * @returns number */ -teamLeadChange(index: number):number|null { +teamLeadChanges(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -2975,7 +2760,7 @@ teamLeadChange(index: number):number|null { /** * @returns number */ -teamLeadChangeLength():number { +teamLeadChangesLength():number { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -2983,16 +2768,18 @@ teamLeadChangeLength():number { /** * @returns Int32Array */ -teamLeadChangeArray():Int32Array|null { +teamLeadChangesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 6); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** + * The total amount of gold change of this team, this round + * * @param number index * @returns number */ -teamGoldChange(index: number):number|null { +teamGoldChanges(index: number):number|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -3000,7 +2787,7 @@ teamGoldChange(index: number):number|null { /** * @returns number */ -teamGoldChangeLength():number { +teamGoldChangesLength():number { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3008,7 +2795,7 @@ teamGoldChangeLength():number { /** * @returns Int32Array */ -teamGoldChangeArray():Int32Array|null { +teamGoldChangesArray():Int32Array|null { var offset = this.bb!.__offset(this.bb_pos, 8); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3172,69 +2959,24 @@ actionTargetsArray():Int32Array|null { }; /** - * The IDs of the robots who changed their indicator strings - * - * @param number index - * @returns number - */ -indicatorStringIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 24); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -indicatorStringIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 24); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -indicatorStringIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 24); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * The messages of the robots who changed their indicator strings + * The locations of lead drops * - * @param number index - * @param flatbuffers.Encoding= optionalEncoding - * @returns string|Uint8Array - */ -indicatorStrings(index: number):string -indicatorStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array -indicatorStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { - var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; -}; - -/** - * @returns number - */ -indicatorStringsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ leadDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 28); + var offset = this.bb!.__offset(this.bb_pos, 24); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; /** + * The amount of lead dropped at each location + * * @param number index * @returns number */ leadDropValues(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -3242,7 +2984,7 @@ leadDropValues(index: number):number|null { * @returns number */ leadDropValuesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3250,25 +2992,29 @@ leadDropValuesLength():number { * @returns Int32Array */ leadDropValuesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); + var offset = this.bb!.__offset(this.bb_pos, 26); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; /** + * The locations of gold drops + * * @param battlecode.schema.VecTable= obj * @returns battlecode.schema.VecTable|null */ goldDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); + var offset = this.bb!.__offset(this.bb_pos, 28); return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; }; /** + * The amount of gold dropped at each location + * * @param number index * @returns number */ goldDropValues(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -3276,7 +3022,7 @@ goldDropValues(index: number):number|null { * @returns number */ goldDropValuesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3284,7 +3030,7 @@ goldDropValuesLength():number { * @returns Int32Array */ goldDropValuesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 34); + var offset = this.bb!.__offset(this.bb_pos, 30); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3295,7 +3041,7 @@ goldDropValuesArray():Int32Array|null { * @returns number */ indicatorStringIDs(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; }; @@ -3303,7 +3049,7 @@ indicatorStringIDs(index: number):number|null { * @returns number */ indicatorStringIDsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; @@ -3311,7 +3057,7 @@ indicatorStringIDsLength():number { * @returns Int32Array */ indicatorStringIDsArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 24); + var offset = this.bb!.__offset(this.bb_pos, 32); return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; }; @@ -3325,7 +3071,7 @@ indicatorStringIDsArray():Int32Array|null { indicatorStrings(index: number):string indicatorStrings(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array indicatorStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { - var offset = this.bb!.__offset(this.bb_pos, 26); + var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; }; @@ -3333,78 +3079,10 @@ indicatorStrings(index: number,optionalEncoding?:any):string|Uint8Array|null { * @returns number */ indicatorStringsLength():number { - var offset = this.bb!.__offset(this.bb_pos, 26); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @param battlecode.schema.VecTable= obj - * @returns battlecode.schema.VecTable|null - */ -leadDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 28); - return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; -}; - -/** - * @param number index - * @returns number - */ -leadDropValues(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -leadDropValuesLength():number { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; -}; - -/** - * @returns Int32Array - */ -leadDropValuesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 30); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - -/** - * @param battlecode.schema.VecTable= obj - * @returns battlecode.schema.VecTable|null - */ -goldDropLocations(obj?:battlecode.schema.VecTable):battlecode.schema.VecTable|null { - var offset = this.bb!.__offset(this.bb_pos, 32); - return offset ? (obj || new battlecode.schema.VecTable).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; -}; - -/** - * @param number index - * @returns number - */ -goldDropValues(index: number):number|null { - var offset = this.bb!.__offset(this.bb_pos, 34); - return offset ? this.bb!.readInt32(this.bb!.__vector(this.bb_pos + offset) + index * 4) : 0; -}; - -/** - * @returns number - */ -goldDropValuesLength():number { var offset = this.bb!.__offset(this.bb_pos, 34); return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; }; -/** - * @returns Int32Array - */ -goldDropValuesArray():Int32Array|null { - var offset = this.bb!.__offset(this.bb_pos, 34); - return offset ? new Int32Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null; -}; - /** * The IDs of bodies that set indicator dots * @@ -3618,10 +3296,10 @@ static startTeamIDsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamLeadChangeOffset + * @param flatbuffers.Offset teamLeadChangesOffset */ -static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, teamLeadChangeOffset, 0); +static addTeamLeadChanges(builder:flatbuffers.Builder, teamLeadChangesOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, teamLeadChangesOffset, 0); }; /** @@ -3629,7 +3307,7 @@ static addTeamLeadChange(builder:flatbuffers.Builder, teamLeadChangeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamLeadChangesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3641,16 +3319,16 @@ static createTeamLeadChangeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamLeadChangeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamLeadChangesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset teamGoldChangeOffset + * @param flatbuffers.Offset teamGoldChangesOffset */ -static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatbuffers.Offset) { - builder.addFieldOffset(2, teamGoldChangeOffset, 0); +static addTeamGoldChanges(builder:flatbuffers.Builder, teamGoldChangesOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, teamGoldChangesOffset, 0); }; /** @@ -3658,7 +3336,7 @@ static addTeamGoldChange(builder:flatbuffers.Builder, teamGoldChangeOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createTeamGoldChangesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3670,7 +3348,7 @@ static createTeamGoldChangeVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startTeamGoldChangeVector(builder:flatbuffers.Builder, numElems:number) { +static startTeamGoldChangesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -3837,10 +3515,18 @@ static startActionTargetsVector(builder:flatbuffers.Builder, numElems:number) { /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicatorStringIDsOffset + * @param flatbuffers.Offset leadDropLocationsOffset */ -static addIndicatorStringIDs(builder:flatbuffers.Builder, indicatorStringIDsOffset:flatbuffers.Offset) { - builder.addFieldOffset(10, indicatorStringIDsOffset, 0); +static addLeadDropLocations(builder:flatbuffers.Builder, leadDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(10, leadDropLocationsOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset leadDropValuesOffset + */ +static addLeadDropValues(builder:flatbuffers.Builder, leadDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(11, leadDropValuesOffset, 0); }; /** @@ -3848,7 +3534,7 @@ static addIndicatorStringIDs(builder:flatbuffers.Builder, indicatorStringIDsOffs * @param Array. data * @returns flatbuffers.Offset */ -static createIndicatorStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createLeadDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3860,27 +3546,35 @@ static createIndicatorStringIDsVector(builder:flatbuffers.Builder, data:number[] * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicatorStringIDsVector(builder:flatbuffers.Builder, numElems:number) { +static startLeadDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset indicatorStringsOffset + * @param flatbuffers.Offset goldDropLocationsOffset */ -static addIndicatorStrings(builder:flatbuffers.Builder, indicatorStringsOffset:flatbuffers.Offset) { - builder.addFieldOffset(11, indicatorStringsOffset, 0); +static addGoldDropLocations(builder:flatbuffers.Builder, goldDropLocationsOffset:flatbuffers.Offset) { + builder.addFieldOffset(12, goldDropLocationsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param Array. data + * @param flatbuffers.Offset goldDropValuesOffset + */ +static addGoldDropValues(builder:flatbuffers.Builder, goldDropValuesOffset:flatbuffers.Offset) { + builder.addFieldOffset(13, goldDropValuesOffset, 0); +}; + +/** + * @param flatbuffers.Builder builder + * @param Array. data * @returns flatbuffers.Offset */ -static createIndicatorStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { +static createGoldDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { - builder.addOffset(data[i]); + builder.addInt32(data[i]); } return builder.endVector(); }; @@ -3889,24 +3583,16 @@ static createIndicatorStringsVector(builder:flatbuffers.Builder, data:flatbuffer * @param flatbuffers.Builder builder * @param number numElems */ -static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) { +static startGoldDropValuesVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropLocationsOffset - */ -static addLeadDropLocations(builder:flatbuffers.Builder, leadDropLocationsOffset:flatbuffers.Offset) { - builder.addFieldOffset(12, leadDropLocationsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset leadDropValuesOffset + * @param flatbuffers.Offset indicatorStringIDsOffset */ -static addLeadDropValues(builder:flatbuffers.Builder, leadDropValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(13, leadDropValuesOffset, 0); +static addIndicatorStringIDs(builder:flatbuffers.Builder, indicatorStringIDsOffset:flatbuffers.Offset) { + builder.addFieldOffset(14, indicatorStringIDsOffset, 0); }; /** @@ -3914,7 +3600,7 @@ static addLeadDropValues(builder:flatbuffers.Builder, leadDropValuesOffset:flatb * @param Array. data * @returns flatbuffers.Offset */ -static createLeadDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicatorStringIDsVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); @@ -3926,35 +3612,27 @@ static createLeadDropValuesVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startLeadDropValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringIDsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; /** * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropLocationsOffset - */ -static addGoldDropLocations(builder:flatbuffers.Builder, goldDropLocationsOffset:flatbuffers.Offset) { - builder.addFieldOffset(14, goldDropLocationsOffset, 0); -}; - -/** - * @param flatbuffers.Builder builder - * @param flatbuffers.Offset goldDropValuesOffset + * @param flatbuffers.Offset indicatorStringsOffset */ -static addGoldDropValues(builder:flatbuffers.Builder, goldDropValuesOffset:flatbuffers.Offset) { - builder.addFieldOffset(15, goldDropValuesOffset, 0); +static addIndicatorStrings(builder:flatbuffers.Builder, indicatorStringsOffset:flatbuffers.Offset) { + builder.addFieldOffset(15, indicatorStringsOffset, 0); }; /** * @param flatbuffers.Builder builder - * @param Array. data + * @param Array. data * @returns flatbuffers.Offset */ -static createGoldDropValuesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset { +static createIndicatorStringsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { builder.startVector(4, data.length, 4); for (var i = data.length - 1; i >= 0; i--) { - builder.addInt32(data[i]); + builder.addOffset(data[i]); } return builder.endVector(); }; @@ -3963,7 +3641,7 @@ static createGoldDropValuesVector(builder:flatbuffers.Builder, data:number[] | U * @param flatbuffers.Builder builder * @param number numElems */ -static startGoldDropValuesVector(builder:flatbuffers.Builder, numElems:number) { +static startIndicatorStringsVector(builder:flatbuffers.Builder, numElems:number) { builder.startVector(4, numElems, 4); }; @@ -4140,11 +3818,11 @@ static endRound(builder:flatbuffers.Builder):flatbuffers.Offset { return offset; }; -static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangeOffset:flatbuffers.Offset, teamGoldChangeOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { +static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset, teamLeadChangesOffset:flatbuffers.Offset, teamGoldChangesOffset:flatbuffers.Offset, movedIDsOffset:flatbuffers.Offset, movedLocsOffset:flatbuffers.Offset, spawnedBodiesOffset:flatbuffers.Offset, diedIDsOffset:flatbuffers.Offset, actionIDsOffset:flatbuffers.Offset, actionsOffset:flatbuffers.Offset, actionTargetsOffset:flatbuffers.Offset, leadDropLocationsOffset:flatbuffers.Offset, leadDropValuesOffset:flatbuffers.Offset, goldDropLocationsOffset:flatbuffers.Offset, goldDropValuesOffset:flatbuffers.Offset, indicatorStringIDsOffset:flatbuffers.Offset, indicatorStringsOffset:flatbuffers.Offset, indicatorDotIDsOffset:flatbuffers.Offset, indicatorDotLocsOffset:flatbuffers.Offset, indicatorDotRGBsOffset:flatbuffers.Offset, indicatorLineIDsOffset:flatbuffers.Offset, indicatorLineStartLocsOffset:flatbuffers.Offset, indicatorLineEndLocsOffset:flatbuffers.Offset, indicatorLineRGBsOffset:flatbuffers.Offset, roundID:number, bytecodeIDsOffset:flatbuffers.Offset, bytecodesUsedOffset:flatbuffers.Offset):flatbuffers.Offset { Round.startRound(builder); Round.addTeamIDs(builder, teamIDsOffset); - Round.addTeamLeadChange(builder, teamLeadChangeOffset); - Round.addTeamGoldChange(builder, teamGoldChangeOffset); + Round.addTeamLeadChanges(builder, teamLeadChangesOffset); + Round.addTeamGoldChanges(builder, teamGoldChangesOffset); Round.addMovedIDs(builder, movedIDsOffset); Round.addMovedLocs(builder, movedLocsOffset); Round.addSpawnedBodies(builder, spawnedBodiesOffset); @@ -4152,12 +3830,12 @@ static createRound(builder:flatbuffers.Builder, teamIDsOffset:flatbuffers.Offset Round.addActionIDs(builder, actionIDsOffset); Round.addActions(builder, actionsOffset); Round.addActionTargets(builder, actionTargetsOffset); - Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); - Round.addIndicatorStrings(builder, indicatorStringsOffset); Round.addLeadDropLocations(builder, leadDropLocationsOffset); Round.addLeadDropValues(builder, leadDropValuesOffset); Round.addGoldDropLocations(builder, goldDropLocationsOffset); Round.addGoldDropValues(builder, goldDropValuesOffset); + Round.addIndicatorStringIDs(builder, indicatorStringIDsOffset); + Round.addIndicatorStrings(builder, indicatorStringsOffset); Round.addIndicatorDotIDs(builder, indicatorDotIDsOffset); Round.addIndicatorDotLocs(builder, indicatorDotLocsOffset); Round.addIndicatorDotRGBs(builder, indicatorDotRGBsOffset); From 380482ee5001e158404572e331a8bff6f334f896 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 15:06:19 -0600 Subject: [PATCH 245/413] MapBuilder checks archon has visible lead --- engine/src/main/battlecode/world/MapBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 332836c7..f24e9e1b 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -220,13 +220,13 @@ public void assertIsValid() { // assert rubble, lead, and Archon symmetry ArrayList allMapSymmetries = getSymmetry(robots); System.out.println("This map has the following symmetries: " + allMapSymmetries); - if (!allMapSymmetries.contains(this.symmetry)) + if (!allMapSymmetries.contains(this.symmetry)) { throw new RuntimeException("Rubble, lead, and Archons must be symmetric"); } // assert that at least one lead deposit inside vision range of at least one Archon - boolean[] hasVisibleLead = {false, false}; + boolean[] hasVisibleLead = new boolean[2]; for (RobotInfo r : bodies) { if (r.getType() != RobotType.ARCHON) continue; From e356786e33afb6822998d78f328aae3243e56e64 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 17:05:58 -0500 Subject: [PATCH 246/413] tmp --- client/playback/src/gameworld.ts | 57 ++++++++++++++++--------------- client/playback/src/gen/create.ts | 44 +++++++++++------------- client/playback/src/metadata.ts | 40 +++++++++++++--------- 3 files changed, 72 insertions(+), 69 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index f0eefd5a..50cbd1aa 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -38,10 +38,15 @@ export type MapStats = { bodies: schema.SpawnedBodyTable, randomSeed: number, - passability: Float64Array, // double + rubble: Int32Array, // double leadVals: Int32Array; goldVals: Int32Array; + symmetry: number; + + anomalies: Int8Array; + anomalyRounds: Int8Array; + getIdx: (x:number, y:number) => number; getLoc: (idx: number) => Victor; }; @@ -227,10 +232,14 @@ export default class GameWorld { bodies: new schema.SpawnedBodyTable(), randomSeed: 0, - passability: new Float64Array(0), + rubble: new Int32Array(0), leadVals: new Int32Array(0), goldVals: new Int32Array(0), + symmetry: 0, + anomalies: new Int8Array(0), + anomalyRounds: new Int8Array(0), + getIdx: (x:number, y:number) => 0, getLoc: (idx: number) => new Victor(0,0) }; @@ -291,7 +300,7 @@ export default class GameWorld { this.mapStats.maxCorner.y = maxCorner.y(); this.mapStats.goldVals = new Int32Array(maxCorner.x()*maxCorner.y()) - this.mapStats.leadVals = new Int32Array(maxCorner.x()*maxCorner.y()) + this.mapStats.leadVals = map.leadArray(); const bodies = map.bodies(this._bodiesSlot); if (bodies && bodies.robotIDsLength) { @@ -300,20 +309,7 @@ export default class GameWorld { this.mapStats.randomSeed = map.randomSeed(); - this.mapStats.passability = Float64Array.from(map.passabilityArray()); - - const leadLocations = map.leadLocations(this._vecTableSlot1); - if (leadLocations) { - - const xs = leadLocations.xsArray(); - const ys = leadLocations.ysArray(); - - xs.forEach((x, i) => { - const y = ys[i] - - this.mapStats.leadVals[this.mapStats.getIdx(x,y)] = map.leadAmountsArray[i]; - }) - } + this.mapStats.rubble = map.rubbleArray(); const width = (maxCorner.x() - minCorner.x()); this.mapStats.getIdx = (x:number, y:number) => ( @@ -322,7 +318,12 @@ export default class GameWorld { this.mapStats.getLoc = (idx: number) => ( new Victor(idx % width, Math.floor(idx / width)) ); - + + this.mapStats.symmetry = map.symmetry(); + + this.mapStats.anomalies = Int8Array.from(map.anomaliesArray()); + this.mapStats.anomalyRounds = Int8Array.from(map.anomalyRoundsArray()); + // Check with header.totalRounds() ? } @@ -368,10 +369,10 @@ export default class GameWorld { let teamID = delta.teamIDs(i); let statObj = this.teamStats.get(teamID); - statObj.lead += delta.teamLeadChange(i); - statObj.gold += delta.teamGoldChange(i); - statObj.leadChange = delta.teamLeadChange(i); - statObj.goldChange = delta.teamGoldChange(i); + statObj.lead += delta.teamLeadChanges(i); + statObj.gold += delta.teamGoldChanges(i); + statObj.leadChange = delta.teamLeadChanges(i); + statObj.goldChange = delta.teamGoldChanges(i); this.teamStats.set(teamID, statObj); } @@ -408,7 +409,7 @@ export default class GameWorld { xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[this.mapStats.getIdx(x,y)] = delta.leadDropValues[i]; + this.mapStats.leadVals[this.mapStats.getIdx(x,y)] += delta.leadDropValues[i]; }) } @@ -419,7 +420,7 @@ export default class GameWorld { let inst = this; xs.forEach((x, i) => { const y = ys[i] - inst.mapStats.goldVals[inst.mapStats.getIdx(x,y)] = delta.goldDropValues(i); + inst.mapStats.goldVals[inst.mapStats.getIdx(x,y)] += delta.goldDropValues(i); }) } @@ -459,7 +460,7 @@ export default class GameWorld { setAction(); break; - case schema.Action.CONVERT_GOLD: + case schema.Action.TRANSMUTE: setAction(); teamStatsObj.gold += target; teamStatsObj.lead -= 0; @@ -470,7 +471,7 @@ export default class GameWorld { this.bodies.alter({ id: robotID, portable: 1}); break; - case schema.Action.UPGRADE: + case schema.Action.MUTATE: setAction(); teamStatsObj.robots[body.type][body.level - 1] -= 1; teamStatsObj.robots[body.type][body.level + 1 - 1] += 1; @@ -490,7 +491,7 @@ export default class GameWorld { setAction(); break; - case schema.Action.CHANGE_HP: + case schema.Action.CHANGE_HEALTH: this.bodies.alter({ id: robotID, hp: body.hp + target}); teamStatsObj.total_hp[body.type][body.level] += target; break; @@ -670,7 +671,7 @@ export default class GameWorld { // if(teams[i] == 0) continue; var statObj = this.teamStats.get(teams[i]); statObj.robots[types[i]][0] += 1; // TODO: handle level - statObj.total_hp[types[i]][0] += this.meta.types[types[i]].hp; // TODO: extract meta info + statObj.total_hp[types[i]][0] += this.meta.types[types[i]].health; // TODO: extract meta info this.teamStats.set(teams[i], statObj); } diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index cb67f28a..7b20a7e6 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -42,7 +42,7 @@ type BodiesType = { }; type MapType = { - passability: number[], + rubble: number[], }; // Class to manage IDs of units @@ -135,11 +135,11 @@ function makeRandomBodies(manager: IDsManager, unitCount: number): BodiesType{ function makeRandomMap(): MapType { const map: MapType = { - passability: new Array(SIZE*SIZE) + rubble: new Array(SIZE*SIZE) }; for(let i=0; i; - if (map) passability = map.passability; + let rubble: Array; + if (map) rubble = map.rubble; else { - passability = new Array(SIZE*SIZE); - passability.fill(0); + rubble = new Array(SIZE*SIZE); + rubble.fill(0); } // all values default to zero - const bb_passability = schema.GameMap.createPassabilityVector(builder, passability); + const bb_rubble = schema.GameMap.createRubbleVector(builder, rubble); schema.GameMap.startGameMap(builder); schema.GameMap.addName(builder, bb_name); @@ -198,7 +198,7 @@ function createMap(builder: flatbuffers.Builder, bodies: number, name: string, m if(!isNull(bodies)) schema.GameMap.addBodies(builder, bodies); schema.GameMap.addRandomSeed(builder, 42); - schema.GameMap.addPassability(builder, bb_passability); + schema.GameMap.addRubble(builder, bb_rubble); return schema.GameMap.endGameMap(builder); } @@ -210,14 +210,15 @@ function createGameHeader(builder: flatbuffers.Builder): flatbuffers.Offset { for (const body of bodyTypeList) { const btmd = schema.BodyTypeMetadata; if (body in [schema.BodyType.MINER, schema.BodyType.BUILDER, schema.BodyType.SAGE, schema.BodyType.SOLDIER]) { - var gold_costs = btmd.createUpgradeCostGoldVector(builder, [1]) - var lead_costs = btmd.createUpgradeCostLeadVector(builder, [1]) + var gold_costs = [1] + var lead_costs = [1] } else { - var gold_costs = btmd.createUpgradeCostGoldVector(builder, [1,2,3]) - var lead_costs = btmd.createUpgradeCostLeadVector(builder, [1,2,3]) + var gold_costs = [1,2,3] + var lead_costs = [1,2,3] } - bodies.push(btmd.createBodyTypeMetadata(builder, body, body, 10, 10, 2, 6, 10, 10000, 5, 2, 6, 3, gold_costs, lead_costs)); //TODO: make robots interesting + bodies.push(btmd.createBodyTypeMetadata(builder, body, lead_costs[0], gold_costs[0], lead_costs[1], gold_costs[1], lead_costs[2], gold_costs[2], + 10, 10, 2, 6, 10, 3, 5, 11, 4, 6, 10000)); //TODO: make robots interesting } const teams: flatbuffers.Offset[] = []; @@ -546,36 +547,31 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = let possible_actions = [] switch (bodies.types[j]) { case schema.BodyType.MINER: - action = schema.Action.MINE; + possible_actions = [schema.Action.MINE_GOLD, schema.Action.MINE_LEAD]; // got rid of spawn unit for now because it causes problems break; case schema.BodyType.ARCHON: possible_actions = [schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; // got rid of spawn unit for now because it causes problems - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.SOLDIER: possible_actions = [schema.Action.ATTACK]; - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.BUILDER: - possible_actions = [schema.Action.BUILD, schema.Action.REPAIR, schema.Action.UPGRADE]; - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; + possible_actions = [schema.Action.REPAIR, schema.Action.MUTATE]; // got rid of spawn unit for now because it causes problems break; case schema.BodyType.LABORATORY: - possible_actions = [schema.Action.CONVERT_GOLD, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; + possible_actions = [schema.Action.TRANSMUTE, schema.Action.FULLY_REPAIRED, schema.Action.TRANSFORM]; break; case schema.BodyType.SAGE: possible_actions = [schema.Action.ATTACK, schema.Action.LOCAL_ABYSS, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; case schema.BodyType.WATCHTOWER: possible_actions = [schema.Action.ATTACK, schema.Action.LOCAL_CHARGE, schema.Action.LOCAL_FURY]; - action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; break; default: break; } - let building_target_actions = [schema.Action.REPAIR, schema.Action.UPGRADE] + action = possible_actions[Math.floor(Math.random() * possible_actions.length)]; + let building_target_actions = [schema.Action.REPAIR, schema.Action.MUTATE] if (action !== null) { if (building_target_actions.indexOf(action) > -1){ actionTarget = buildings[Math.floor(Math.random() * buildings.length)]; diff --git a/client/playback/src/metadata.ts b/client/playback/src/metadata.ts index 578702f5..16bd68ef 100644 --- a/client/playback/src/metadata.ts +++ b/client/playback/src/metadata.ts @@ -47,19 +47,23 @@ export default class Metadata { const body = header.bodyTypeMetadata(i); this.types[body.type()] = new BodyTypeMetaData( body.type(), - body.spawnSource(), - body.actionRadiusSquared(), - body.visionRadiusSquared(), + body.buildCostLead(), + body.buildCostGold(), + body.level2CostLead(), + body.level2CostGold(), + body.level3CostLead(), + body.level3CostGold(), body.actionCooldown(), body.movementCooldown(), - body.bytecodeLimit(), - body.dps(), - body.hp(), - body.dpsMul(), - body.hpMul(), - body.buildCost(), - Array.from(body.upgradeCostLeadArray()), - Array.from(body.upgradeCostGoldArray()) + body.health(), + body.level2Health(), + body.level3Health(), + body.damage(), + body.level2Damage(), + body.level3Damage(), + body.actionRadiusSquared(), + body.visionRadiusSquared(), + body.bytecodeLimit() ); } // SAFE @@ -92,12 +96,14 @@ export class Team { * Information about a specific body type. */ export class BodyTypeMetaData { - constructor(public type: schema.BodyType, public spawnSource:schema.BodyType, - public actionRadiusSquared:number, public visionRadiusSquared:number, + constructor(public type: schema.BodyType, + public buildCostLead:number, public buildCostGold: number, + public level2CostLead: number, public level2CostGold: number, + public level3CostLead: number, public level3CostGold: number, public actionCooldown:number, public movementCooldown:number, - public bytecodeLimit:number, - public dps:number, public hp:number, public dpsMul:number, public hpMul:number, - public buildCost:number, public upgradeCostLead:number[], - public upgradeCostGold:number[]) { + public health: number, public level2Health: number, public level3Health: number, + public damage: number, public level2Damage: number, public level3Damage: number, + public actionRadiusSquared:number, public visionRadiusSquared:number, + public bytecodeLimit:number) { } } From cffbd82cb44ef3d4ffbe1c1ad224e274850c3edc Mon Sep 17 00:00:00 2001 From: meeeeee Date: Thu, 30 Dec 2021 17:06:19 -0500 Subject: [PATCH 247/413] gold and lead --- client/visualizer/src/main/looper.ts | 12 ++++++-- client/visualizer/src/sidebar/stats.ts | 38 ++++++++++++++------------ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 1a3c0fa0..574055d9 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -312,7 +312,12 @@ export default class Looper { let teamIDs: number[] = []; let teamNames: string[] = []; let totalHP = 0; - + let totalGold: Array = []; + let totalLead: Array = []; + for(let team in meta.teams){ + totalGold[meta.teams[team].teamID] = 0; + totalLead[meta.teams[team].teamID] = 0; + }; // this.stats.resetECs(); // for (let i = 0; i < world.bodies.length; i++) { // const type = world.bodies.arrays.type[i]; @@ -352,7 +357,10 @@ export default class Looper { //### this.stats.setTeamInfluence(teamID, teamHP, totalHP); // this.stats.setBuffs(teamID, teamStats.numBuffs); // this.stats.setBid(teamID, teamStats.bid); - this.stats.setIncome(teamID, teamStats.leadChange, teamStats.goldChange, world.turn); + this.stats.setIncome(teamID, teamStats.lead - totalLead[teamID], teamStats.gold - totalGold[teamID], world.turn, world.mapStats.leadVals.reduce((a, b) => a + b), world.mapStats.goldVals.reduce((a, b) => a + b)); + console.log(world.mapStats.leadVals.reduce((a, b) => a + b), world.mapStats.goldVals.reduce((a, b) => a + b), "fsdfdsds"); + totalLead[teamID] = teamStats.lead; + totalGold[teamID] = teamStats.gold; // this.stats.setIncome(teamID, 3 + teamID, 5 + teamID, world.turn); } this.stats.resetECs(); diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 7432efb1..1ddf16d1 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -168,44 +168,45 @@ export default class Stats { return table; } - private initRelativeBars(teamIDs: Array) { + private initRelativeBars() { + let metalIDs = [0, 1]; + let colors = ["#FFD700", "#212121"]; const relativeBars: HTMLDivElement[] = []; - teamIDs.forEach((id: number) => { + metalIDs.forEach((id: number) => { const bar = document.createElement("div"); - bar.style.backgroundColor = hex[id]; + bar.style.backgroundColor = colors[id]; bar.style.width = `100%`; bar.className = "influence-bar"; - bar.innerText = "0"; + bar.innerText = "0%"; relativeBars[id] = bar; }); return relativeBars; } - private getRelativeBarsElement(teamIDs: Array): HTMLElement { + private getRelativeBarsElement(): HTMLElement { + let metalIDs = [0, 1]; const div = document.createElement("div"); - div.setAttribute("align", "center"); + //div.setAttribute("align", "center"); div.id = "relative-bars"; const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'Ideas'; + label.innerText = 'Field Metal'; const frame = document.createElement("div"); frame.style.width = "100%"; - teamIDs.forEach((id: number) => { - frame.appendChild(this.relativeBars[id]); - }); + metalIDs.forEach((id: number) => {frame.appendChild(this.relativeBars[id]);}); div.appendChild(label); div.appendChild(frame); return div; } - private updateRelBars(teamID: number, newval: number){ + private updateRelBars(metalID: number, percentOpen: number){ console.log(this.div); - this.relativeBars[teamID].innerHTML = (newval === undefined) ? "0" : newval.toString(); + this.relativeBars[metalID].innerHTML = ((percentOpen === undefined) ? "0" : Math.round(percentOpen).toString()) + "%"; } private initIncomeDisplays(teamIDs: Array) { @@ -391,8 +392,8 @@ export default class Stats { archonnums[id] = (this.robotTds[id]["count"][ARCHON].inner == undefined) ? 0 : this.robotTds[id]["count"][ARCHON].inner; console.log(archonnums[id]); });*/ - this.relativeBars = this.initRelativeBars(teamIDs); - const relativeBarsElement = this.getRelativeBarsElement(teamIDs); + this.relativeBars = this.initRelativeBars(); + const relativeBarsElement = this.getRelativeBarsElement(); this.div.appendChild(relativeBarsElement); this.incomeDisplays = this.initIncomeDisplays(teamIDs); @@ -476,8 +477,6 @@ export default class Stats { */ setRobotCount(teamID: number, robotType: schema.BodyType, count: number) { let td: HTMLTableCellElement = this.robotTds[teamID]["count"][robotType]; - console.log(teamID, count, "fsdfsdf"); - if(robotType === ARCHON) this.updateRelBars(teamID, count); console.log(count, robotType); td.innerHTML = String(count); } @@ -532,7 +531,7 @@ export default class Stats { else relBar.style.width = String(Math.round(influence * 100 / totalInfluence)) + "%"; }*/ - setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number) { // incomes + setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number, fieldLead: number, fieldGold: number) { // incomes this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later this.incomeDisplays[teamID].goldIncome.textContent = String(goldIncome); if (!this.teamMapToTurnsIncomeSet.has(teamID)) { @@ -551,6 +550,11 @@ export default class Stats { teamTurnsIncomeSet?.add(turn); this.incomeChart.update(); } + // update bars here + //console.log(teamID, count, "fsdfsdf"); + //if(robotType === ARCHON) this.updateRelBars(teamID, count); + this.updateRelBars(0, 100.0*fieldGold/(fieldGold + goldIncome)); + this.updateRelBars(1, 100.0*fieldLead/(fieldLead + leadIncome)); } setWinner(teamID: number, teamNames: Array, teamIDs: Array) { From 33bfe7aa422f66fd4e5a1b16c450f471d77ce162 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 16:09:21 -0600 Subject: [PATCH 248/413] revert getDamage & getHealing --- .../src/main/battlecode/common/RobotType.java | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index a30ac63c..c9b23870 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -21,7 +21,7 @@ public enum RobotType { * Converts lead into gold * * @battlecode.doc.robot */ - LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), + LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), // BCL BCG AC MC HP DMG AR VR BL /** @@ -206,39 +206,31 @@ public int getMaxHealth(int level) { /** * Returns the damage of a robot by level. * @param level - * @return the damage for a robot by level. - * 0 if it's a non-damaging robot. + * @return the damage for a robot by level, negative if robot heals */ public int getDamage(int level) { - - // Robots that heal or don't do damage. - // Note, damage is negative in the enum if healing, so cannot directly use damage. - if (this == RobotType.ARCHON || this == RobotType.LABORATORY || this == RobotType.BUILDER) + if (!this.isBuilding() || level == 1) { + return this.damage; + } else if (this == RobotType.ARCHON) { + return level == 2 ? 3 : 4; + } else if (this == RobotType.LABORATORY) { return 0; - - if(this == RobotType.WATCHTOWER){ - if(level == 1) return this.damage; + } else { return level == 2 ? 6 : 7; } - - // Non-healing droids only. - return this.damage; } /** * @param level - * @return the healing per turn for a robot by level as a positive amount. - * 0 if robot doesn't heal. + * @return the healing per turn for a robot by level as a positive amount, + * 0 if robot doesn't heal */ public int getHealing(int level) { - if(this == BUILDER || (this == ARCHON && level == 1)) + if (this == ARCHON || this == BUILDER) { return (int) (-1 * this.getDamage(level)); - else{ - if(this == ARCHON && level != 1) - return level == 2 ? 3 : 4; + } else { + return 0; } - - return 0; } // COST RELATED FUNCTIONS From 7be672c7ca5738d84d83aa3b33c09610eb878ef1 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 17:38:54 -0500 Subject: [PATCH 249/413] Adapt to new schema --- client/playback/src/gen/create.ts | 30 ++++++---- client/visualizer/src/constants.ts | 1 + client/visualizer/src/gamearea/renderer.ts | 6 +- .../src/mapeditor/action/generator.ts | 8 +-- .../src/mapeditor/action/renderer.ts | 14 ++--- client/visualizer/src/mapeditor/form.ts | 60 +++++++++---------- 6 files changed, 64 insertions(+), 55 deletions(-) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 7b20a7e6..d509f190 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -139,7 +139,7 @@ function makeRandomMap(): MapType { }; for(let i=0; i[] = [ // Given passability, get index of tile to use. export const getLevel = (x: number): number => { + x /= 100; const nLev = TILE_COLORS.length const floatLevel = ((1 - x) - 0.1) / 0.9 * nLev const level = Math.floor(floatLevel) diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index be9f8665..fb26c4a4 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -23,7 +23,7 @@ export default class Renderer { constructor(readonly canvas: HTMLCanvasElement, readonly imgs: AllImages, private conf: config.Config, readonly metadata: Metadata, readonly onRobotSelected: (id: number) => void, - readonly onMouseover: (x: number, y: number, xrel: number, yrel: number, passability: number) => void) { + readonly onMouseover: (x: number, y: number, xrel: number, yrel: number, rubble: number) => void) { let ctx = canvas.getContext("2d") if (ctx === null) { @@ -104,7 +104,7 @@ export default class Renderer { this.ctx.globalAlpha = 1 // Fetch and draw tile image - const swampLevel = cst.getLevel(map.passability[idxVal]) + const swampLevel = cst.getLevel(map.rubble[idxVal]) const tileImg = this.imgs.tiles[swampLevel] //since tiles arent completely opaque @@ -403,7 +403,7 @@ export default class Renderer { const xrel = x - world.minCorner.x const yrel = y - world.minCorner.y const idx = world.mapStats.getIdx(xrel, yrel) - onMouseover(x, y, xrel, yrel, world.mapStats.passability[idx]) + onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx]) this.hoverPos = { x: xrel, y: yrel } } diff --git a/client/visualizer/src/mapeditor/action/generator.ts b/client/visualizer/src/mapeditor/action/generator.ts index e5441ea0..00b1f3f4 100644 --- a/client/visualizer/src/mapeditor/action/generator.ts +++ b/client/visualizer/src/mapeditor/action/generator.ts @@ -17,7 +17,7 @@ export type UploadedMap = { name: string, width: number, height: number, - passability: number[], + rubble: number[], bodies: MapUnit[] } @@ -129,7 +129,7 @@ export default class MapGenerator { // schema.SpawnedBodyTable.addInfluences(builder, influencesVectorB); const bodies = schema.SpawnedBodyTable.endSpawnedBodyTable(builder); - const passability = schema.GameMap.createPassabilityVector(builder, map.passability); + const rubble = schema.GameMap.createRubbleVector(builder, map.rubble); // Create the game map let nameP = builder.createString(name); @@ -138,7 +138,7 @@ export default class MapGenerator { schema.GameMap.addMinCorner(builder, schema.Vec.createVec(builder, minCornerX, minCornerY)); schema.GameMap.addMaxCorner(builder, schema.Vec.createVec(builder, maxCornerX, maxCornerY)); schema.GameMap.addBodies(builder, bodies); - schema.GameMap.addPassability(builder, passability); + schema.GameMap.addRubble(builder, rubble); schema.GameMap.addRandomSeed(builder, randomSeed); const gameMap = schema.GameMap.endGameMap(builder); @@ -204,7 +204,7 @@ export default class MapGenerator { name: map.name()!, width: maxCorner.x() - minCorner.x(), height: maxCorner.y() - minCorner.y(), - passability: Array.from(map.passabilityArray()!), + rubble: Array.from(map.rubbleArray()!), bodies: mapUnits }; } diff --git a/client/visualizer/src/mapeditor/action/renderer.ts b/client/visualizer/src/mapeditor/action/renderer.ts index 62690b10..324b303a 100644 --- a/client/visualizer/src/mapeditor/action/renderer.ts +++ b/client/visualizer/src/mapeditor/action/renderer.ts @@ -21,7 +21,7 @@ export default class MapRenderer { // Callbacks for clicking robots and trees on the canvas readonly onclickUnit: (id: number) => void; readonly onclickBlank: (x, y) => void; - readonly onMouseover: (x: number, y: number, passability: number) => void + readonly onMouseover: (x: number, y: number, rubble: number) => void readonly onDrag: (x, y) => void // Other useful values @@ -33,7 +33,7 @@ export default class MapRenderer { constructor(canvas: HTMLCanvasElement, imgs: AllImages, conf: config.Config, onclickUnit: (id: number) => void, onclickBlank: (x: number, y: number) => void, - onMouseover: (x: number, y: number, passability: number) => void, + onMouseover: (x: number, y: number, rubble: number) => void, onDrag: (x: number, y: number) => void) { this.canvas = canvas; this.conf = conf; @@ -91,17 +91,17 @@ export default class MapRenderer { private renderBackground(map: GameMap): void { for(let i = 0; i < this.width; i++){ for(let j = 0; j < this.height; j++){ - const passability = map.passability[(map.height-j-1)*this.width + i]; - this.renderTile(i, j, passability); + const rubble = map.rubble[(map.height-j-1)*this.width + i]; + this.renderTile(i, j, rubble); } } } - private renderTile(i: number, j: number, passability: number) { + private renderTile(i: number, j: number, rubble: number) { this.ctx.save(); const scale = 20; this.ctx.scale(1/scale, 1/scale); - const swampLevel = cst.getLevel(passability); + const swampLevel = cst.getLevel(rubble); const tileImg = this.imgs.tiles[swampLevel]; this.ctx.drawImage(tileImg, i*scale, j*scale, scale, scale); this.ctx.strokeStyle = 'gray'; @@ -184,7 +184,7 @@ export default class MapRenderer { this.canvas.onmousemove = (event) => { const {x,y} = this.getIntegerLocation(event, this.map); - this.onMouseover(x, y, this.map.passability[(y)*this.width + x]); + this.onMouseover(x, y, this.map.rubble[(y)*this.width + x]); hoverPos = {x: x, y: y}; }; diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 6b5576f2..d325e355 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -23,7 +23,7 @@ export type GameMap = { height: number, originalBodies: Map symmetricBodies: Map, - passability: number[], + rubble: number[], symmetry: number }; @@ -66,7 +66,7 @@ export default class MapEditorForm { private lastID: number; // To give bodies unique IDs private originalBodies: Map; private symmetricBodies: Map; - private passability: number[]; + private rubble: number[]; randomMode: boolean = false; // if true, all squares are randomly painted. randomHigh: number = 1; @@ -134,7 +134,7 @@ export default class MapEditorForm { this.div.appendChild(document.createElement('hr')); this.tileInfo = document.createElement("div"); - this.tileInfo.textContent = "X: | Y: | Passability:"; + this.tileInfo.textContent = "X: | Y: | Rubble:"; this.div.appendChild(this.tileInfo); this.div.appendChild(document.createElement('hr')); @@ -152,11 +152,11 @@ export default class MapEditorForm { this.getActiveForm().setForm(x, y); }; - const onMouseover = (x: number, y: number, passability: number) => { + const onMouseover = (x: number, y: number, rubble: number) => { let content: string = ""; content += 'X: ' + `${x}`.padStart(3); content += ' | Y: ' + `${y}`.padStart(3); - content += ' | Passability: ' + `${passability.toFixed(3)}`; + content += ' | Rubble: ' + `${rubble.toFixed(3)}`; this.tileInfo.textContent = content; }; @@ -174,7 +174,7 @@ export default class MapEditorForm { case "Cow": inBrush = (dx,dy) => (Math.abs(dx) < r && Math.abs(dy) < r && cow[Math.floor(20*(1+dx/r))][Math.floor(20*(1-dy/r))]); } - this.setAreaPassability(x, y, this.tiles.getPass(), inBrush); + this.setAreaRubble(x, y, this.tiles.getPass(), inBrush); this.render(); } } @@ -319,7 +319,7 @@ export default class MapEditorForm { if (this.getActiveForm() == this.tiles) { for(let x: number = 0; x < this.header.getWidth(); x++) { for(let y:number = 0; y < this.header.getHeight(); y++) { - this.setPassability(x, y, Math.random() * 0.9 + 0.1); + this.setRubble(x, y, Math.random() * 0.9 + 0.1); } } this.render(); @@ -330,7 +330,7 @@ export default class MapEditorForm { if (this.getActiveForm() == this.tiles) { for(let x: number = 0; x < this.header.getWidth(); x++) { for(let y: number = 0; y < this.header.getHeight(); y++) { - this.passability[y*this.header.getWidth() + x] = 1.1 - this.getPassability(x,y); + this.rubble[y*this.header.getWidth() + x] = 1.1 - this.getRubble(x,y); } } this.render(); @@ -342,18 +342,18 @@ export default class MapEditorForm { // for(let x: number = 0; x < this.header.getWidth(); x++) { // for(let y: number = 0; y < this.header.getHeight(); y++) { // //let sum = 0, n = 0; - // let high = this.getPassability(x, y); - // let low = this.getPassability(x, y); + // let high = this.getRubble(x, y); + // let low = this.getRubble(x, y); // for (let x2 = Math.max(0,x-1); x2 <= Math.min(x+1, this.header.getWidth()-1); x2++) { // for (let y2 = Math.max(0,y-1); y2 <= Math.min(y+1, this.header.getWidth()-1); y2++) { // // if (Math.abs(x-x2) + Math.abs(y-y2) > 1) continue; // bad code - // // sum += this.getPassability(x2, y2); + // // sum += this.getRubble(x2, y2); // //n++; - // high = Math.max(this.getPassability(x2, y2), high); - // low = Math.min(this.getPassability(x2, y2), high); + // high = Math.max(this.getRubble(x2, y2), high); + // low = Math.min(this.getRubble(x2, y2), high); // } // } - // this.setPassability(x,y, (high+low)/2); + // this.setRubble(x,y, (high+low)/2); // } // } // this.render(); @@ -414,43 +414,43 @@ export default class MapEditorForm { } /** - * Initialize passability array based on map dimensions. + * Initialize rubble array based on map dimensions. */ private initPassibility() { - this.passability = new Array(this.header.getHeight() * this.header.getWidth()); - this.passability.fill(1); + this.rubble = new Array(this.header.getHeight() * this.header.getWidth()); + this.rubble.fill(1); } - private getPassability(x: number, y: number) { - return this.passability[y*this.header.getWidth() + x]; + private getRubble(x: number, y: number) { + return this.rubble[y*this.header.getWidth() + x]; } - private setPassability(x: number, y: number, pass: number) { + private setRubble(x: number, y: number, pass: number) { if (this.randomMode) pass = this.randomLow + (this.randomHigh - this.randomLow) * Math.random(); const {x: translated_x, y: translated_y} = this.symmetry.transformLoc(x, y, this.header.getWidth(), this.header.getHeight()); - this.passability[y*this.header.getWidth() + x] = this.passability[translated_y*this.header.getWidth() + translated_x] = pass; + this.rubble[y*this.header.getWidth() + x] = this.rubble[translated_y*this.header.getWidth() + translated_x] = pass; } - private setAreaPassability(x0: number, y0: number, pass: number, inBrush: (dx, dy) => boolean) { + private setAreaRubble(x0: number, y0: number, pass: number, inBrush: (dx, dy) => boolean) { const width = this.header.getWidth(); const height = this.header.getHeight(); for (let x = 0; x < width; x++) { for (let y = 0; y < height; y++) { if (inBrush(x-x0, y-y0)) { - this.setPassability(x, y, pass); + this.setRubble(x, y, pass); } } } } /** - * Set passability of all tiles from top-left to bottom-right. + * Set rubble of all tiles from top-left to bottom-right. */ - private setRectPassability(x1: number, y1: number, x2: number, y2: number, pass: number) { + private setRectRubble(x1: number, y1: number, x2: number, y2: number, pass: number) { for (let x = x1; x <= x2; x++) { for (let y = y1; y <= y2; y++) { - this.setPassability(x, y, pass); + this.setRubble(x, y, pass); } } } @@ -485,7 +485,7 @@ export default class MapEditorForm { height: this.header.getHeight(), originalBodies: this.originalBodies, symmetricBodies: this.symmetricBodies, - passability: this.passability, + rubble: this.rubble, symmetry: this.symmetry.getSymmetry() }; } @@ -525,14 +525,14 @@ export default class MapEditorForm { // this.originalBodies = map.originalBodies; // this.symmetricBodies = map.symmetricBodies; // this.symmetry.setSymmetry(map.symmetry); - // this.passability = map.passability; + // this.rubble = map.rubble; // this.render(); // } // TODO: types setUploadedMap(map: UploadedMap) { - const symmetryAndBodies = this.symmetry.discoverSymmetryAndBodies(map.bodies, map.passability, map.width, map.height); + const symmetryAndBodies = this.symmetry.discoverSymmetryAndBodies(map.bodies, map.rubble, map.width, map.height); console.log(symmetryAndBodies); if (symmetryAndBodies === null) return; @@ -545,7 +545,7 @@ export default class MapEditorForm { this.lastID = this.originalBodies.size + 1; this.symmetricBodies = this.symmetry.getSymmetricBodies(this.originalBodies, map.width, map.height); - this.passability = map.passability; + this.rubble = map.rubble; this.render(); } From 2a07adf7666b69b9b7688f5bdd49b5edd18717ae Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 18:02:35 -0500 Subject: [PATCH 250/413] Show rubble, lead, and gold on mouseover --- client/playback/src/gameworld.ts | 4 ++-- client/playback/src/gen/create.ts | 11 +++++++++-- client/visualizer/src/gamearea/renderer.ts | 4 ++-- client/visualizer/src/main/controls.ts | 8 +++++--- client/visualizer/src/main/looper.ts | 4 ++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 50cbd1aa..8b7bbfb2 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -409,7 +409,7 @@ export default class GameWorld { xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[this.mapStats.getIdx(x,y)] += delta.leadDropValues[i]; + this.mapStats.leadVals[this.mapStats.getIdx(x,y)] += delta.leadDropValues(i); }) } @@ -419,7 +419,7 @@ export default class GameWorld { const ys = goldLocations.ysArray(); let inst = this; xs.forEach((x, i) => { - const y = ys[i] + const y = ys[i]; inst.mapStats.goldVals[inst.mapStats.getIdx(x,y)] += delta.goldDropValues(i); }) } diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index d509f190..661174d4 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -188,7 +188,7 @@ function createMap(builder: flatbuffers.Builder, bodies: number, name: string, m // all values default to zero const bb_rubble = schema.GameMap.createRubbleVector(builder, rubble); - const bb_lead = schema.GameMap.createLeadVector(builder, []); // TODO: interesting lead and anomalies + const bb_lead = schema.GameMap.createLeadVector(builder, new Array(SIZE*SIZE)); // TODO: interesting lead and anomalies const bb_anomalies = schema.GameMap.createAnomaliesVector(builder, []); const bb_anomalyRounds = schema.GameMap.createAnomalyRoundsVector(builder, []); @@ -202,7 +202,7 @@ function createMap(builder: flatbuffers.Builder, bodies: number, name: string, m schema.GameMap.addRandomSeed(builder, 42); schema.GameMap.addRubble(builder, bb_rubble); - schema.GameMap.addLead(builder, bb_rubble); + schema.GameMap.addLead(builder, bb_lead); schema.GameMap.addAnomalies(builder, bb_anomalies); schema.GameMap.addAnomalyRounds(builder, bb_anomalyRounds); @@ -601,6 +601,11 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = const goldLocs = createVecTable(builder, goldXs, goldYs); const goldVals = schema.Round.createGoldDropValuesVector(builder, [Math.floor(100*Math.random())]); + const leadXs = [Math.floor(SIZE*Math.random())] + const leadYs = [Math.floor(SIZE*Math.random())] + const leadLocs = createVecTable(builder, leadXs, leadYs); + const leadVals = schema.Round.createLeadDropValuesVector(builder, [Math.floor(100*Math.random())]); + schema.Round.startRound(builder); schema.Round.addRoundID(builder, i); schema.Round.addMovedLocs(builder, movedLocs); @@ -611,6 +616,8 @@ function createWanderGame(turns: number, unitCount: number, doActions: boolean = schema.Round.addGoldDropLocations(builder, goldLocs); schema.Round.addGoldDropValues(builder, goldVals); + schema.Round.addLeadDropLocations(builder, leadLocs); + schema.Round.addLeadDropValues(builder, leadVals); events.push(createEventWrapper(builder, schema.Round.endRound(builder), schema.Event.Round)); } diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index fb26c4a4..e77e3fb7 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -23,7 +23,7 @@ export default class Renderer { constructor(readonly canvas: HTMLCanvasElement, readonly imgs: AllImages, private conf: config.Config, readonly metadata: Metadata, readonly onRobotSelected: (id: number) => void, - readonly onMouseover: (x: number, y: number, xrel: number, yrel: number, rubble: number) => void) { + readonly onMouseover: (x: number, y: number, xrel: number, yrel: number, rubble: number, lead: number, gold: number) => void) { let ctx = canvas.getContext("2d") if (ctx === null) { @@ -403,7 +403,7 @@ export default class Renderer { const xrel = x - world.minCorner.x const yrel = y - world.minCorner.y const idx = world.mapStats.getIdx(xrel, yrel) - onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx]) + onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx], world.mapStats.leadVals[idx], world.mapStats.goldVals[idx]) this.hoverPos = { x: xrel, y: yrel } } diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 094ebbd0..514c6500 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -220,7 +220,7 @@ export default class Controls { setDefaultText() { this.timeReadout.innerHTML = 'No match loaded'; - this.tileInfo.innerHTML = 'X | Y | Passability'; + this.tileInfo.innerHTML = 'X | Y | Rubble | Lead | Gold'; this.speedReadout.textContent = 'UPS: FPS: '; } @@ -420,11 +420,13 @@ export default class Controls { /** * Updates the location readout */ - setTileInfo(x: number, y: number, xrel: number, yrel: number, passability: number): void { + setTileInfo(x: number, y: number, xrel: number, yrel: number, rubble: number, lead: number, gold: number): void { let content: string = ""; content += 'X: ' + `${xrel}`.padStart(3) + ` (${x})`.padStart(3); content += ' | Y: ' + `${yrel}`.padStart(3) + ` (${y})`.padStart(3); - content += ' | Passability: ' + `${passability.toFixed(3)}`; + content += ' | Rubble: ' + `${rubble}`; + content += ' | Lead: ' + `${lead}`; + content += ' | Gold: ' + `${gold}`; this.tileInfo.innerHTML = content; } diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index c7fd377c..bbd3a239 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -82,9 +82,9 @@ export default class Looper { this.lastSelectedID = id; this.console.setIDFilter(id); }; - const onMouseover = (x: number, y: number, xrel: number, yrel: number, passability: number) => { + const onMouseover = (x: number, y: number, xrel: number, yrel: number, rubble: number, lead: number, gold: number) => { // Better make tile type and hand that over - controls.setTileInfo(x, y, xrel, yrel, passability); + controls.setTileInfo(x, y, xrel, yrel, rubble, lead, gold); }; // Configure renderer for this match From 4444dd91866174d1d9304066fe6f9163cf62087c Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 17:39:06 -0600 Subject: [PATCH 251/413] various fixes --- engine/src/main/battlecode/world/GameWorld.java | 2 +- engine/src/main/battlecode/world/MapBuilder.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 5e4c84fe..7eb78739 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -285,7 +285,7 @@ public static MapLocation[] getAllLocationsWithinRadiusSquaredWithoutMap(MapLoca returnLocations.add(newLocation); } } - return returnLocations.toArray(new MapLocation[0]); + return returnLocations.toArray(new MapLocation[returnLocations.size()]); } /** diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index f24e9e1b..e4509d5e 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -190,13 +190,13 @@ public void assertIsValid() { robots[locationToIndex(r.location.x, r.location.y)] = r; } - if (width <= GameConstants.MAP_MIN_WIDTH || height <= GameConstants.MAP_MIN_HEIGHT || - width >= GameConstants.MAP_MAX_WIDTH || height >= GameConstants.MAP_MAX_HEIGHT) + if (width < GameConstants.MAP_MIN_WIDTH || height < GameConstants.MAP_MIN_HEIGHT || + width > GameConstants.MAP_MAX_WIDTH || height > GameConstants.MAP_MAX_HEIGHT) throw new RuntimeException("The map size must be between " + GameConstants.MAP_MIN_WIDTH + "x" + GameConstants.MAP_MIN_HEIGHT + " and " + GameConstants.MAP_MAX_WIDTH + "x" + GameConstants.MAP_MAX_HEIGHT + ", inclusive"); - // checks between 1 and 4 Archons inclusive of each team + // checks between 1 and 4 Archons (inclusive) of each team // only needs to check the Archons of Team A, because symmetry is checked int numTeamARobots = 0; for (RobotInfo r : bodies) { @@ -204,8 +204,8 @@ public void assertIsValid() { numTeamARobots++; } } - if (numTeamARobots <= GameConstants.MIN_STARTING_ARCHONS || - numTeamARobots >= GameConstants.MAX_STARTING_ARCHONS) { + if (numTeamARobots < GameConstants.MIN_STARTING_ARCHONS || + numTeamARobots > GameConstants.MAX_STARTING_ARCHONS) { throw new RuntimeException("Map must have between " + GameConstants.MIN_STARTING_ARCHONS + "and " + GameConstants.MAX_STARTING_ARCHONS + " starting Archons of each team"); } From 9c771e2b8a3fda903b616c52d510d7bc09077de6 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 17:40:10 -0600 Subject: [PATCH 252/413] style --- engine/src/main/battlecode/world/GameWorld.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 7eb78739..6f8caa00 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -271,7 +271,7 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int public static MapLocation[] getAllLocationsWithinRadiusSquaredWithoutMap(MapLocation origin, int width, int height, - MapLocation center, int radiusSquared){ + MapLocation center, int radiusSquared) { ArrayList returnLocations = new ArrayList(); int ceiledRadius = (int) Math.ceil(Math.sqrt(radiusSquared)) + 1; // add +1 just to be safe int minX = Math.max(center.x - ceiledRadius, origin.x); From 44f7711ff29ddc04e3b57ca09e5cfcb5b136b440 Mon Sep 17 00:00:00 2001 From: meeeeee Date: Thu, 30 Dec 2021 19:06:00 -0500 Subject: [PATCH 253/413] Finalized gold and lead bar visualization --- client/visualizer/src/main/looper.ts | 22 +++--- client/visualizer/src/sidebar/stats.ts | 92 ++++++++++++++-------- client/visualizer/src/static/css/style.css | 6 +- 3 files changed, 78 insertions(+), 42 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 574055d9..59e87274 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -312,12 +312,6 @@ export default class Looper { let teamIDs: number[] = []; let teamNames: string[] = []; let totalHP = 0; - let totalGold: Array = []; - let totalLead: Array = []; - for(let team in meta.teams){ - totalGold[meta.teams[team].teamID] = 0; - totalLead[meta.teams[team].teamID] = 0; - }; // this.stats.resetECs(); // for (let i = 0; i < world.bodies.length; i++) { // const type = world.bodies.arrays.type[i]; @@ -326,12 +320,15 @@ export default class Looper { // } // } + let teamLead: number[] = []; + let teamGold: number[] = []; for (let team in meta.teams) { let teamID = meta.teams[team].teamID; let teamStats = world.teamStats.get(teamID) as TeamStats; teamIDs.push(teamID); teamNames.push(meta.teams[team].name); totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); + } for (let team in meta.teams) { @@ -357,12 +354,17 @@ export default class Looper { //### this.stats.setTeamInfluence(teamID, teamHP, totalHP); // this.stats.setBuffs(teamID, teamStats.numBuffs); // this.stats.setBid(teamID, teamStats.bid); - this.stats.setIncome(teamID, teamStats.lead - totalLead[teamID], teamStats.gold - totalGold[teamID], world.turn, world.mapStats.leadVals.reduce((a, b) => a + b), world.mapStats.goldVals.reduce((a, b) => a + b)); - console.log(world.mapStats.leadVals.reduce((a, b) => a + b), world.mapStats.goldVals.reduce((a, b) => a + b), "fsdfdsds"); - totalLead[teamID] = teamStats.lead; - totalGold[teamID] = teamStats.gold; + this.stats.setIncome(teamID, teamStats.leadChange, teamStats.goldChange, world.turn); // this.stats.setIncome(teamID, 3 + teamID, 5 + teamID, world.turn); } + + for(var a = 0; a < teamIDs.length; a++){ + //@ts-ignore + teamLead.push(world.teamStats.get(teamIDs[a]).lead); + //@ts-ignore + teamGold.push(world.teamStats.get(teamIDs[a]).gold); + } + this.stats.updateBars(teamLead, teamGold); this.stats.resetECs(); const hps = world.bodies.arrays.hp; const teams = world.bodies.arrays.team; diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 1ddf16d1..0b897612 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -168,45 +168,71 @@ export default class Stats { return table; } - private initRelativeBars() { + private initRelativeBars(teamIDs: Array) { let metalIDs = [0, 1]; - let colors = ["#FFD700", "#212121"]; + let colors = ["#AA9700", "#696969"]; const relativeBars: HTMLDivElement[] = []; - metalIDs.forEach((id: number) => { + teamIDs.forEach((teamID: number) => metalIDs.forEach((id: number) => { const bar = document.createElement("div"); bar.style.backgroundColor = colors[id]; - bar.style.width = `100%`; + bar.style.border = "5px solid " + ((teamID === teamIDs[0]) ? "#C00040" : "#4000C0"); + bar.style.width = `90%`; bar.className = "influence-bar"; bar.innerText = "0%"; - - relativeBars[id] = bar; - }); + bar.id = teamID.toString(); + relativeBars[2*id + ((teamIDs[0] === teamID)?0:1)] = bar; + })); return relativeBars; } - private getRelativeBarsElement(): HTMLElement { + private getRelativeBarsElement(){ let metalIDs = [0, 1]; - const div = document.createElement("div"); - //div.setAttribute("align", "center"); - div.id = "relative-bars"; + const divleft = document.createElement("div"); + divleft.setAttribute("align", "center"); + divleft.id = "relative-bars-left"; - const label = document.createElement('div'); - label.className = "stats-header"; - label.innerText = 'Field Metal'; + const labelleft = document.createElement('div'); + labelleft.className = "stats-header"; + labelleft.innerText = 'Gold'; - const frame = document.createElement("div"); - frame.style.width = "100%"; + const frameleft = document.createElement("div"); + frameleft.style.width = "100%"; - metalIDs.forEach((id: number) => {frame.appendChild(this.relativeBars[id]);}); + frameleft.appendChild(this.relativeBars[0]); + frameleft.appendChild(this.relativeBars[1]); - div.appendChild(label); - div.appendChild(frame); - return div; + divleft.appendChild(labelleft); + divleft.appendChild(frameleft); + + const divright = document.createElement("div"); + divright.setAttribute("align", "center"); + divright.id = "relative-bars-right"; + + const labelright = document.createElement('div'); + labelright.className = "stats-header"; + labelright.innerText = 'Lead'; + + const frameright = document.createElement("div"); + frameright.style.width = "100%"; + + frameright.appendChild(this.relativeBars[2]); + frameright.appendChild(this.relativeBars[3]); + + divright.appendChild(labelright); + divright.appendChild(frameright); + return [divleft, divright]; } - private updateRelBars(metalID: number, percentOpen: number){ + private updateRelBars(teamLead: Array, teamGold: Array){ console.log(this.div); - this.relativeBars[metalID].innerHTML = ((percentOpen === undefined) ? "0" : Math.round(percentOpen).toString()) + "%"; + for(var a = 0; a < teamGold.length; a++){ + this.relativeBars[a].innerHTML = teamGold[a].toString(); + this.relativeBars[a+2].style.width = (Math.max(teamGold[0], teamGold[1]) === 0 ? 90:(90.0*teamGold[a]/Math.max(teamGold[0], teamGold[1]))).toString() + "%"; + } + for(var a = 0; a < teamLead.length; a++){ + this.relativeBars[a+2].innerHTML = teamLead[a].toString(); + this.relativeBars[a+2].style.width = (Math.max(teamLead[0], teamLead[1]) === 0 ? 90:(90.0*teamLead[a]/Math.max(teamLead[0], teamLead[1]))).toString() + "%"; + } } private initIncomeDisplays(teamIDs: Array) { @@ -216,10 +242,12 @@ export default class Stats { const goldIncome = document.createElement("span"); leadIncome.style.color = hex[id]; leadIncome.style.fontWeight = "bold"; - leadIncome.textContent = "1"; + leadIncome.textContent = "L: 0"; + leadIncome.style.padding = "10px"; goldIncome.style.color = hex[id]; goldIncome.style.fontWeight = "bold"; - goldIncome.textContent = "2"; + goldIncome.textContent = "G: 0"; + goldIncome.style.padding = "10px"; incomeDisplays[id] = {leadIncome: leadIncome, goldIncome: goldIncome}; }); return incomeDisplays; @@ -392,9 +420,9 @@ export default class Stats { archonnums[id] = (this.robotTds[id]["count"][ARCHON].inner == undefined) ? 0 : this.robotTds[id]["count"][ARCHON].inner; console.log(archonnums[id]); });*/ - this.relativeBars = this.initRelativeBars(); + this.relativeBars = this.initRelativeBars(teamIDs); const relativeBarsElement = this.getRelativeBarsElement(); - this.div.appendChild(relativeBarsElement); + relativeBarsElement.forEach((relBar: HTMLDivElement) => { this.div.appendChild(relBar);}); this.incomeDisplays = this.initIncomeDisplays(teamIDs); const incomeElement = this.getIncomeDisplaysElement(teamIDs); @@ -531,9 +559,9 @@ export default class Stats { else relBar.style.width = String(Math.round(influence * 100 / totalInfluence)) + "%"; }*/ - setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number, fieldLead: number, fieldGold: number) { // incomes - this.incomeDisplays[teamID].leadIncome.textContent = String(leadIncome); // change incomeDisplays later - this.incomeDisplays[teamID].goldIncome.textContent = String(goldIncome); + setIncome(teamID: number, leadIncome: number, goldIncome: number, turn: number) { // incomes + this.incomeDisplays[teamID].leadIncome.textContent = "L: " + String(leadIncome); // change incomeDisplays later + this.incomeDisplays[teamID].goldIncome.textContent = "G: " + String(goldIncome); if (!this.teamMapToTurnsIncomeSet.has(teamID)) { this.teamMapToTurnsIncomeSet.set(teamID, new Set()); } @@ -553,8 +581,10 @@ export default class Stats { // update bars here //console.log(teamID, count, "fsdfsdf"); //if(robotType === ARCHON) this.updateRelBars(teamID, count); - this.updateRelBars(0, 100.0*fieldGold/(fieldGold + goldIncome)); - this.updateRelBars(1, 100.0*fieldLead/(fieldLead + leadIncome)); + } + + updateBars(teamLead: Array, teamGold: Array){ + this.updateRelBars(teamLead, teamGold); } setWinner(teamID: number, teamNames: Array, teamIDs: Array) { diff --git a/client/visualizer/src/static/css/style.css b/client/visualizer/src/static/css/style.css index 9cd53dec..c78b15d7 100644 --- a/client/visualizer/src/static/css/style.css +++ b/client/visualizer/src/static/css/style.css @@ -583,10 +583,14 @@ h4 { width: 100%; } -#relative-bars { +#relative-bars-left { width: 50%; float: left; } +#relative-bars-right { + width: 50%; + float: right; +} .influence-bar { height: 30px; From 29f70154315a31a46d507540804da83952e17366 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 18:07:26 -0600 Subject: [PATCH 254/413] refactor see to sense --- .../common/GameActionExceptionType.java | 4 +- .../battlecode/common/RobotController.java | 44 +++++----- .../main/battlecode/world/InternalRobot.java | 16 ++-- .../battlecode/world/RobotControllerImpl.java | 86 +++++++++---------- .../sample/testplayeractions/RobotPlayer.java | 2 +- 5 files changed, 76 insertions(+), 76 deletions(-) diff --git a/engine/src/main/battlecode/common/GameActionExceptionType.java b/engine/src/main/battlecode/common/GameActionExceptionType.java index 38b17abf..9db4dd2e 100644 --- a/engine/src/main/battlecode/common/GameActionExceptionType.java +++ b/engine/src/main/battlecode/common/GameActionExceptionType.java @@ -22,10 +22,10 @@ public enum GameActionExceptionType { */ IS_NOT_READY, /** - * Indicates when a robot tries to see a robot that no longer exists or is no longer + * Indicates when a robot tries to sense a robot that no longer exists or is no longer * in this robot's vision range. */ - CANT_SEE_THAT, + CANT_SENSE_THAT, /** * Indicates when a robot tries to perform an action on a location that is outside * its range. diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index c024cd5d..90a651e1 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -127,7 +127,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - boolean canSeeLocation(MapLocation loc); + boolean canSenseLocation(MapLocation loc); /** * Checks whether a point at the given radius squared is within the robot's vision range. @@ -137,7 +137,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - boolean canSeeRadiusSquared(int radiusSquared); + boolean canSenseRadiusSquared(int radiusSquared); /** * Checks whether a robot is at a given location. Assumes the location is valid. @@ -148,10 +148,10 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException; + boolean canSenseRobotAtLocation(MapLocation loc) throws GameActionException; /** - * Sees the robot at the given location, or null if there is no robot + * Senses the robot at the given location, or null if there is no robot * there. * * @param loc the location to check @@ -160,7 +160,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException; + RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException; /** * Tests whether the given robot exists and if it is within this robot's @@ -172,19 +172,19 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - boolean canSeeRobot(int id); + boolean canSenseRobot(int id); /** - * Sees information about a particular robot given its ID. + * Senses information about a particular robot given its ID. * * @param id the ID of the robot to query - * @return a RobotInfo object for the seen robot - * @throws GameActionException if the robot cannot be seen (for example, + * @return a RobotInfo object for the sensed robot + * @throws GameActionException if the robot cannot be sensed (for example, * if it doesn't exist or is out of vision range) * * @battlecode.doc.costlymethod */ - RobotInfo seeRobot(int id) throws GameActionException; + RobotInfo senseRobot(int id) throws GameActionException; /** * Returns all robots within vision radius. The objects are returned in no @@ -195,10 +195,10 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo[] seeNearbyRobots(); + RobotInfo[] senseNearbyRobots(); /** - * Returns all robots that can be seen within a certain distance of this + * Returns all robots that can be sensed within a certain distance of this * robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of @@ -209,10 +209,10 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo[] seeNearbyRobots(int radiusSquared); + RobotInfo[] senseNearbyRobots(int radiusSquared); /** - * Returns all robots of a given team that can be seen within a certain + * Returns all robots of a given team that can be sensed within a certain * distance of this robot. The objects are returned in no particular order. * * @param radiusSquared return robots this distance away from the center of @@ -225,10 +225,10 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo[] seeNearbyRobots(int radiusSquared, Team team); + RobotInfo[] senseNearbyRobots(int radiusSquared, Team team); /** - * Returns all robots of a given team that can be seen within a certain + * Returns all robots of a given team that can be sensed within a certain * radius of a specified location. The objects are returned in no particular * order. * @@ -243,7 +243,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team); + RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team); /** * Given a location, returns the rubble of that location. @@ -257,29 +257,29 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - int seeRubble(MapLocation loc) throws GameActionException; + int senseRubble(MapLocation loc) throws GameActionException; /** * Given a location, returns the lead count of that location. * * @param loc the given location * @return the amount of lead at that location - * @throws GameActionException if the robot cannot see the given location + * @throws GameActionException if the robot cannot sense the given location * * @battlecode.doc.costlymethod */ - int seeLead(MapLocation loc) throws GameActionException; + int senseLead(MapLocation loc) throws GameActionException; /** * Given a location, returns the gold count of that location. * * @param loc the given location * @return the amount of gold at that location - * @throws GameActionException if the robot cannot see the given location + * @throws GameActionException if the robot cannot sense the given location * * @battlecode.doc.costlymethod */ - int seeGold(MapLocation loc) throws GameActionException; + int senseGold(MapLocation loc) throws GameActionException; /** * Returns the location adjacent to current location in the given direction. diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 9c8a1b2c..4de0f344 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -232,20 +232,20 @@ public int getVisionRadiusSquared() { } /** - * Returns whether this robot can see the given location. + * Returns whether this robot can sense the given location. * - * @param toSee the MapLocation to see + * @param toSense the MapLocation to sense */ - public boolean canSeeLocation(MapLocation toSee) { - return this.location.distanceSquaredTo(toSee) <= getVisionRadiusSquared(); + public boolean canSenseLocation(MapLocation toSense) { + return this.location.distanceSquaredTo(toSense) <= getVisionRadiusSquared(); } /** - * Returns whether this robot can see a given radius away. + * Returns whether this robot can sense a given radius away. * - * @param radiusSquared the distance squared to act + * @param radiusSquared the distance squared to sense */ - public boolean canSeeRadiusSquared(int radiusSquared) { + public boolean canSenseRadiusSquared(int radiusSquared) { return radiusSquared <= getVisionRadiusSquared(); } @@ -435,7 +435,7 @@ public void die_exception() { * @return the number of friendly robots within sensor (vision) radius. */ public int updateNumVisibleFriendlyRobots() { - return this.numVisibleFriendlyRobots = this.controller.seeNearbyRobots(-1, getTeam()).length; + return this.numVisibleFriendlyRobots = this.controller.senseNearbyRobots(-1, getTeam()).length; } @Override diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 2cdc4b2e..bb62b5e2 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -138,113 +138,113 @@ private int locationToInt(MapLocation loc) { @Override public boolean onTheMap(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSeeLocation(loc)) - throw new GameActionException(CANT_SEE_THAT, + if (!this.robot.canSenseLocation(loc)) + throw new GameActionException(CANT_SENSE_THAT, "Target location not within vision range"); return this.gameWorld.getGameMap().onTheMap(loc); } - private void assertCanSeeLocation(MapLocation loc) throws GameActionException { + private void assertCanSenseLocation(MapLocation loc) throws GameActionException { assertNotNull(loc); - if (!this.robot.canSeeLocation(loc)) - throw new GameActionException(CANT_SEE_THAT, + if (!this.robot.canSenseLocation(loc)) + throw new GameActionException(CANT_SENSE_THAT, "Target location not within vision range"); if (!this.gameWorld.getGameMap().onTheMap(loc)) - throw new GameActionException(CANT_SEE_THAT, + throw new GameActionException(CANT_SENSE_THAT, "Target location is not on the map"); } @Override - public boolean canSeeLocation(MapLocation loc) { + public boolean canSenseLocation(MapLocation loc) { try { - assertCanSeeLocation(loc); + assertCanSenseLocation(loc); return true; } catch (GameActionException e) { return false; } } @Override - public boolean canSeeRadiusSquared(int radiusSquared) { - return this.robot.canSeeRadiusSquared(radiusSquared); + public boolean canSenseRadiusSquared(int radiusSquared) { + return this.robot.canSenseRadiusSquared(radiusSquared); } @Override - public boolean canSeeRobotAtLocation(MapLocation loc) throws GameActionException { - assertCanSeeLocation(loc); + public boolean canSenseRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSenseLocation(loc); return this.gameWorld.getRobot(loc) != null; } @Override - public RobotInfo seeRobotAtLocation(MapLocation loc) throws GameActionException { - assertCanSeeLocation(loc); + public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException { + assertCanSenseLocation(loc); InternalRobot bot = this.gameWorld.getRobot(loc); return bot == null ? null : bot.getRobotInfo(); } @Override - public boolean canSeeRobot(int id) { - InternalRobot seenRobot = getRobotByID(id); - return seenRobot == null ? false : canSeeLocation(seenRobot.getLocation()); + public boolean canSenseRobot(int id) { + InternalRobot sensedRobot = getRobotByID(id); + return sensedRobot == null ? false : canSenseLocation(sensedRobot.getLocation()); } @Override - public RobotInfo seeRobot(int id) throws GameActionException { - if (!canSeeRobot(id)) - throw new GameActionException(CANT_SEE_THAT, - "Can't see given robot; It may be out of vision range or not exist anymore"); + public RobotInfo senseRobot(int id) throws GameActionException { + if (!canSenseRobot(id)) + throw new GameActionException(CANT_SENSE_THAT, + "Can't sense given robot; It may be out of vision range or not exist anymore"); return getRobotByID(id).getRobotInfo(); } @Override - public RobotInfo[] seeNearbyRobots() { - return seeNearbyRobots(-1); + public RobotInfo[] senseNearbyRobots() { + return senseNearbyRobots(-1); } @Override - public RobotInfo[] seeNearbyRobots(int radiusSquared) { - return seeNearbyRobots(radiusSquared, null); + public RobotInfo[] senseNearbyRobots(int radiusSquared) { + return senseNearbyRobots(radiusSquared, null); } @Override - public RobotInfo[] seeNearbyRobots(int radiusSquared, Team team) { - return seeNearbyRobots(getLocation(), radiusSquared, team); + public RobotInfo[] senseNearbyRobots(int radiusSquared, Team team) { + return senseNearbyRobots(getLocation(), radiusSquared, team); } @Override - public RobotInfo[] seeNearbyRobots(MapLocation center, int radiusSquared, Team team) { + public RobotInfo[] senseNearbyRobots(MapLocation center, int radiusSquared, Team team) { assertNotNull(center); int actualRadiusSquared = radiusSquared == -1 ? getType().visionRadiusSquared : Math.min(radiusSquared, getType().visionRadiusSquared); - InternalRobot[] allSeenRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); - List validSeenRobots = new ArrayList<>(); - for (InternalRobot seenRobot : allSeenRobots) { + InternalRobot[] allSensedRobots = gameWorld.getAllRobotsWithinRadiusSquared(center, actualRadiusSquared); + List validSensedRobots = new ArrayList<>(); + for (InternalRobot sensedRobot : allSensedRobots) { // check if this robot - if (seenRobot.equals(this.robot)) + if (sensedRobot.equals(this.robot)) continue; - // check if can see - if (!canSeeLocation(seenRobot.getLocation())) + // check if can sense + if (!canSenseLocation(sensedRobot.getLocation())) continue; // check if right team - if (team != null && seenRobot.getTeam() != team) + if (team != null && sensedRobot.getTeam() != team) continue; - validSeenRobots.add(seenRobot.getRobotInfo()); + validSensedRobots.add(sensedRobot.getRobotInfo()); } - return validSeenRobots.toArray(new RobotInfo[validSeenRobots.size()]); + return validSensedRobots.toArray(new RobotInfo[validSensedRobots.size()]); } @Override - public int seeRubble(MapLocation loc) throws GameActionException { - assertCanSeeLocation(loc); + public int senseRubble(MapLocation loc) throws GameActionException { + assertCanSenseLocation(loc); return this.gameWorld.getRubble(loc); } @Override - public int seeLead(MapLocation loc) throws GameActionException { - assertCanSeeLocation(loc); + public int senseLead(MapLocation loc) throws GameActionException { + assertCanSenseLocation(loc); return this.gameWorld.getLead(loc); } @Override - public int seeGold(MapLocation loc) throws GameActionException { - assertCanSeeLocation(loc); + public int senseGold(MapLocation loc) throws GameActionException { + assertCanSenseLocation(loc); return this.gameWorld.getGold(loc); } diff --git a/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java b/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java index 28a5331b..297b0481 100644 --- a/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java +++ b/engine/src/test/battlecode/instrumenter/sample/testplayeractions/RobotPlayer.java @@ -11,7 +11,7 @@ public class RobotPlayer { public static void run(RobotController rc) throws GameActionException { rc.resign(); - rc.seeNearbyRobots(); + rc.senseNearbyRobots(); System.out.println("I shouldn't overflow!"); } From 2a38433fed98904c3050250494b81b2e97e0bddd Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 30 Dec 2021 19:30:10 -0500 Subject: [PATCH 255/413] Update contrrols, halfway through map editor --- client/visualizer/src/constants.ts | 4 +- client/visualizer/src/main/controls.ts | 9 +-- client/visualizer/src/main/looper.ts | 10 +-- client/visualizer/src/main/sidebar.ts | 2 +- .../src/mapeditor/action/renderer.ts | 2 + client/visualizer/src/mapeditor/form.ts | 69 ++++++++++++------- .../visualizer/src/mapeditor/forms/robots.ts | 26 +++---- .../visualizer/src/mapeditor/forms/tiles.ts | 22 +++--- client/visualizer/src/mapeditor/index.ts | 3 +- 9 files changed, 86 insertions(+), 61 deletions(-) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 254b43b1..84852b89 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -69,8 +69,8 @@ export const DELTA = .0001 export const MIN_DIMENSION = 15 export const MAX_DIMENSION = 100 -// Initial influence of enlightenment center, for map editor -export const INITIAL_INFLUENCE = 150 +// Initial (default) HP of archons, for map editor +export const INITIAL_HP = 100 // Server settings export const NUMBER_OF_TEAMS = 2 diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 514c6500..0518b4c1 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -439,12 +439,13 @@ export default class Controls { * Bytecodes Used: bytecodes" */ // TODO fix this (different stats) - setInfoString(id, x: number, y: number, hp: number, bodyType: string, bytecodes: number, flag: number, parent?: number): void { + setInfoString(id, x: number, y: number, hp: number, max_hp: number, dp: number, bodyType: string, bytecodes: number, level: number, parent?: number): void { // console.log(carryDirt); let infoString = `ID: ${id} | `; - infoString += `Location: (${x}, ${y})
`; - infoString += `HP: ${hp} | `; - infoString += `Flag: ${flag} | `; + infoString += `Location: (${x}, ${y}) | `; + infoString += `Level: ${level}
`; + infoString += `HP: ${hp} / ${max_hp} | `; + infoString += `DP: ${dp} | `; infoString += `Bytecodes Used: ${bytecodes}`; if (parent !== undefined) infoString += ` | Parent: ${parent}`; diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index bbd3a239..17874a27 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -243,16 +243,18 @@ export default class Looper { let id = bodies.id[index]; let x = bodies.x[index]; let y = bodies.y[index]; + let type = bodies.type[index]; // let influence = bodies.influence[index]; // let conviction = bodies.conviction[index]; - let hp = bodies.hp[index]; // TODO: show max HP, DPS - let type = bodies.type[index]; + let hp = bodies.hp[index]; + let max_hp = this.meta.types[type].health; + let dp = this.meta.types[type].damage; let bytecodes = bodies.bytecodesUsed[index]; - let flag = bodies.flag[index]; + let level = bodies.level[index]; let parent = bodies.parent[index]; // let bid = bodies.bid[index]; - this.controls.setInfoString(id, x, y, hp, cst.bodyTypeToString(type), bytecodes, flag, + this.controls.setInfoString(id, x, y, hp, max_hp, dp, cst.bodyTypeToString(type), bytecodes, level, parent !== 0 ? parent : undefined); } } diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index 12b8c5e3..76a36da3 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -104,7 +104,7 @@ export default class Sidebar { this.div.appendChild(this.innerDiv); - this.conf.mode = Mode.GAME; + this.conf.mode = Mode.MAPEDITOR; //GAME; this.updateModeButtons(); this.setSidebar(); diff --git a/client/visualizer/src/mapeditor/action/renderer.ts b/client/visualizer/src/mapeditor/action/renderer.ts index 324b303a..7f131aa5 100644 --- a/client/visualizer/src/mapeditor/action/renderer.ts +++ b/client/visualizer/src/mapeditor/action/renderer.ts @@ -92,7 +92,9 @@ export default class MapRenderer { for(let i = 0; i < this.width; i++){ for(let j = 0; j < this.height; j++){ const rubble = map.rubble[(map.height-j-1)*this.width + i]; + const lead = map.leadVals[(map.height-j-1)*this.width + i]; this.renderTile(i, j, rubble); + // TODO: draw lead on map } } } diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index d325e355..751ed597 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -5,7 +5,7 @@ import {cow_border as cow} from '../cow'; import {schema, flatbuffers} from 'battlecode-playback'; -import {MapRenderer, HeaderForm, SymmetryForm, RobotForm, TileForm, UploadedMap} from './index'; +import {MapRenderer, HeaderForm, SymmetryForm, RobotForm, TileForm, LeadForm, UploadedMap} from './index'; import { SSL_OP_NO_QUERY_MTU } from 'constants'; export type MapUnit = { @@ -24,6 +24,7 @@ export type GameMap = { originalBodies: Map symmetricBodies: Map, rubble: number[], + leadVals: number[], symmetry: number }; @@ -45,9 +46,11 @@ export default class MapEditorForm { private readonly symmetry: SymmetryForm; private readonly robots: RobotForm; private readonly tiles: TileForm; + private readonly lead: LeadForm; private robotsRadio: HTMLInputElement; private tilesRadio: HTMLInputElement; + private leadRadio: HTMLInputElement; private forms: HTMLDivElement; @@ -67,6 +70,7 @@ export default class MapEditorForm { private originalBodies: Map; private symmetricBodies: Map; private rubble: number[]; + private lead_vals: number[]; randomMode: boolean = false; // if true, all squares are randomly painted. randomHigh: number = 1; @@ -99,7 +103,7 @@ export default class MapEditorForm { this.div.appendChild(this.header.div); // symmetry - this.symmetry = new SymmetryForm(() => {this.initPassibility(); this.render()}); + this.symmetry = new SymmetryForm(() => {this.initRubble(); this.render()}); this.div.appendChild(document.createElement("br")); this.div.appendChild(this.symmetry.div); this.div.appendChild(document.createElement("br")); @@ -108,6 +112,7 @@ export default class MapEditorForm { // radio buttons this.tilesRadio = document.createElement("input"); this.robotsRadio = document.createElement("input"); + this.leadRadio = document.createElement("input"); this.div.appendChild(this.createUnitOption()); this.div.appendChild(document.createElement("br")); @@ -115,6 +120,7 @@ export default class MapEditorForm { this.forms = document.createElement("div"); this.robots = new RobotForm(cbWidth, cbHeight); // robot info (type, x, y, ...) this.tiles = new TileForm(cbWidth, cbHeight); + this.lead = new LeadForm(cbWidth, cbHeight); this.buttonDelete = document.createElement("button"); this.buttonAdd = document.createElement("button"); this.buttonReverse = document.createElement("button"); @@ -174,14 +180,14 @@ export default class MapEditorForm { case "Cow": inBrush = (dx,dy) => (Math.abs(dx) < r && Math.abs(dy) < r && cow[Math.floor(20*(1+dx/r))][Math.floor(20*(1-dy/r))]); } - this.setAreaRubble(x, y, this.tiles.getPass(), inBrush); + this.setAreaRubble(x, y, this.tiles.getRubble(), inBrush); this.render(); } } this.renderer = new MapRenderer(canvas, imgs, conf, onclickUnit, onclickBlank, onMouseover, onDrag); - this.initPassibility(); + this.initRubble(); // Load callbacks and finally render this.loadCallbacks(); @@ -210,8 +216,7 @@ export default class MapEditorForm { }; const tilesLabel = document.createElement("label"); tilesLabel.setAttribute("for", this.tilesRadio.id); - tilesLabel.textContent = "Change Tiles"; - + tilesLabel.textContent = "Place Rubble"; // Radio button for placing units this.robotsRadio.id = "robots-radio"; @@ -234,11 +239,35 @@ export default class MapEditorForm { robotsLabel.setAttribute("for", this.robotsRadio.id); robotsLabel.textContent = "Place Robots"; + // Radio button for placing lead + this.leadRadio.id = "lead-radio"; + this.leadRadio.type = "radio"; + this.leadRadio.name = "edit-option"; + + this.leadRadio.onchange = () => { + // Change the displayed form + if (this.leadRadio.checked) { + while (this.forms.firstChild) this.forms.removeChild(this.forms.firstChild); + this.forms.appendChild(this.lead.div); + this.buttonDelete.style.display = ""; + this.buttonAdd.style.display = ""; + this.buttonReverse.style.display = "none"; + this.buttonRandomize.style.display = "none"; + this.buttonInvert.style.display = "none"; + } + }; + + const leadLabel = document.createElement("label"); + leadLabel.setAttribute("for", this.leadRadio.id); + leadLabel.textContent = "Place Lead"; + // Add radio buttons HTML element div.appendChild(this.tilesRadio); div.appendChild(tilesLabel); div.appendChild(this.robotsRadio); div.appendChild(robotsLabel); + div.appendChild(this.leadRadio); + div.appendChild(leadLabel); div.appendChild(document.createElement("br")); return div; @@ -416,19 +445,19 @@ export default class MapEditorForm { /** * Initialize rubble array based on map dimensions. */ - private initPassibility() { + private initRubble() { this.rubble = new Array(this.header.getHeight() * this.header.getWidth()); - this.rubble.fill(1); + this.rubble.fill(50); } private getRubble(x: number, y: number) { return this.rubble[y*this.header.getWidth() + x]; } - private setRubble(x: number, y: number, pass: number) { - if (this.randomMode) pass = this.randomLow + (this.randomHigh - this.randomLow) * Math.random(); + private setRubble(x: number, y: number, rubble: number) { + if (this.randomMode) rubble = this.randomLow + (this.randomHigh - this.randomLow) * Math.random(); const {x: translated_x, y: translated_y} = this.symmetry.transformLoc(x, y, this.header.getWidth(), this.header.getHeight()); - this.rubble[y*this.header.getWidth() + x] = this.rubble[translated_y*this.header.getWidth() + translated_x] = pass; + this.rubble[y*this.header.getWidth() + x] = this.rubble[translated_y*this.header.getWidth() + translated_x] = rubble; } private setAreaRubble(x0: number, y0: number, pass: number, inBrush: (dx, dy) => boolean) { @@ -444,22 +473,11 @@ export default class MapEditorForm { } } - /** - * Set rubble of all tiles from top-left to bottom-right. - */ - private setRectRubble(x1: number, y1: number, x2: number, y2: number, pass: number) { - for (let x = x1; x <= x2; x++) { - for (let y = y1; y <= y2; y++) { - this.setRubble(x, y, pass); - } - } - } - /** * @return the active form based on which radio button is selected */ - private getActiveForm(): RobotForm | TileForm { - return (this.tilesRadio.checked ? this.tiles : this.robots) + private getActiveForm(): RobotForm | TileForm | LeadForm { + return (this.tilesRadio.checked ? this.tiles : (this.robotsRadio.checked ? this.robots : this.lead)) } /** @@ -486,6 +504,7 @@ export default class MapEditorForm { originalBodies: this.originalBodies, symmetricBodies: this.symmetricBodies, rubble: this.rubble, + leadVals: this.lead_vals, symmetry: this.symmetry.getSymmetry() }; } @@ -554,7 +573,7 @@ export default class MapEditorForm { this.lastID = 1; this.originalBodies = new Map(); this.symmetricBodies = new Map(); - this.initPassibility(); + this.initRubble(); this.render(); } } diff --git a/client/visualizer/src/mapeditor/forms/robots.ts b/client/visualizer/src/mapeditor/forms/robots.ts index 950aaf1a..db1d2165 100644 --- a/client/visualizer/src/mapeditor/forms/robots.ts +++ b/client/visualizer/src/mapeditor/forms/robots.ts @@ -15,7 +15,7 @@ export default class RobotForm { readonly team: HTMLSelectElement; readonly x: HTMLInputElement; readonly y: HTMLInputElement; - readonly influence: HTMLInputElement; + //readonly influence: HTMLInputElement; // Callbacks on input change readonly width: () => number; @@ -151,13 +151,13 @@ export default class RobotForm { // this.influence.value = isNaN(value) ? "" : String(value); // } - this.team.onchange = () => { - if (this.getTeam() !== 0) { - this.influence.disabled = true; - this.influence.value = String(cst.INITIAL_INFLUENCE); - } - else this.influence.disabled = false; - } + // this.team.onchange = () => { + // if (this.getTeam() !== 0) { + // this.influence.disabled = true; + // this.influence.value = String(cst.INITIAL_INFLUENCE); + // } + // else this.influence.disabled = false; + // } } @@ -178,9 +178,9 @@ export default class RobotForm { return parseInt(this.y.value); } - private getInfluence(): number { - return parseInt(this.influence.value); - } + // private getInfluence(): number { + // return parseInt(this.influence.value); + // } getID(): number | undefined { const id = parseInt(this.id.textContent || "NaN"); @@ -207,8 +207,8 @@ export default class RobotForm { isValid(): boolean { const x = this.getX(); const y = this.getY(); - const I = this.getInfluence(); - return !(isNaN(x) || isNaN(y) || isNaN(I)); + //const I = this.getInfluence(); + return !(isNaN(x) || isNaN(y)); // || isNaN(I)); } getUnit(id: number): MapUnit | undefined { diff --git a/client/visualizer/src/mapeditor/forms/tiles.ts b/client/visualizer/src/mapeditor/forms/tiles.ts index da8e780c..3e2db8f6 100644 --- a/client/visualizer/src/mapeditor/forms/tiles.ts +++ b/client/visualizer/src/mapeditor/forms/tiles.ts @@ -11,7 +11,7 @@ export default class TileForm { readonly div: HTMLDivElement; // Form elements - readonly pass: HTMLInputElement; + readonly rubble: HTMLInputElement; readonly brush: HTMLInputElement; readonly style: HTMLSelectElement; @@ -27,7 +27,7 @@ export default class TileForm { // Create HTML elements this.div = document.createElement("div"); - this.pass = document.createElement("input"); + this.rubble = document.createElement("input"); this.brush = document.createElement("input"); this.style = document.createElement("select"); @@ -41,7 +41,7 @@ export default class TileForm { * Initializes input fields. */ private loadInputs(): void { - this.pass.value = "0.5"; + this.rubble.value = "50"; this.brush.value = "3"; for (var styleString of ["Circle", "Square", "Cow"]) { @@ -63,8 +63,8 @@ export default class TileForm { const brush: HTMLDivElement = document.createElement("div"); const style: HTMLDivElement = document.createElement("div"); - pass.appendChild(document.createTextNode("Passability:")); - pass.appendChild(this.pass); + pass.appendChild(document.createTextNode("Rubble:")); + pass.appendChild(this.rubble); form.appendChild(pass); brush.appendChild(document.createTextNode("Brush size:")); @@ -85,16 +85,16 @@ export default class TileForm { * Add callbacks to the form elements. */ private loadCallbacks(): void { - this.pass.onchange = () => { - this.pass.value = !isNaN(this.getPass()) ? this.validate(this.getPass(), 0.1, 1) : ""; + this.rubble.onchange = () => { + this.rubble.value = !isNaN(this.getRubble()) ? this.validate(this.getRubble(), 0, 100) : ""; }; this.brush.onchange = () => { this.brush.value = !isNaN(this.getBrush()) ? this.validate(this.getBrush(), 1) : ""; }; } - getPass(): number { - return parseFloat(this.pass.value); + getRubble(): number { + return parseFloat(this.rubble.value); } getBrush(): number { @@ -106,7 +106,7 @@ export default class TileForm { } resetForm(): void { - this.pass.value = ""; + this.rubble.value = ""; } setForm(): void { @@ -119,6 +119,6 @@ export default class TileForm { } isValid(): boolean { - return !(isNaN(this.getPass())); + return !(isNaN(this.getRubble())); } } diff --git a/client/visualizer/src/mapeditor/index.ts b/client/visualizer/src/mapeditor/index.ts index 17f8090c..bf9936da 100644 --- a/client/visualizer/src/mapeditor/index.ts +++ b/client/visualizer/src/mapeditor/index.ts @@ -8,11 +8,12 @@ import HeaderForm from './forms/header'; import RobotForm from './forms/robots'; import SymmetryForm, {Symmetry} from './forms/symmetry'; import TileForm from './forms/tiles'; +import LeadForm from './forms/lead'; import {GameMap} from './form'; import MapEditorForm from './form'; import MapEditor from './mapeditor'; export {MapGenerator, MapUnit, MapRenderer, MapValidator, UploadedMap} -export {HeaderForm, RobotForm, Symmetry, SymmetryForm, TileForm} +export {HeaderForm, RobotForm, Symmetry, SymmetryForm, TileForm, LeadForm} export {GameMap, MapEditorForm, MapEditor}; From 6348d7cd17f6f7faa6680597f817cced97ddc941 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 19:19:34 -0600 Subject: [PATCH 256/413] can sense RobotMode, archons start in TURRET mode --- .../battlecode/common/RobotController.java | 9 +++++++ .../src/main/battlecode/common/RobotInfo.java | 26 ++++++++++++++++--- .../src/main/battlecode/world/GameMapIO.java | 2 +- .../src/main/battlecode/world/GameWorld.java | 6 +---- .../main/battlecode/world/InternalRobot.java | 11 ++++++-- .../src/main/battlecode/world/MapBuilder.java | 1 + .../battlecode/world/RobotControllerImpl.java | 5 ++++ 7 files changed, 48 insertions(+), 12 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 90a651e1..cbd62db7 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -76,6 +76,15 @@ public strictfp interface RobotController { */ RobotType getType(); + /** + * Returns this robot's mode (DROID, PROTOTYPE, TURRET, PORTABLE). + * + * @return this robot's mode + * + * @battlecode.doc.costlymethod + */ + RobotMode getMode(); + /** * Returns this robot's current location. * diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index 450ba269..511a16b3 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -22,6 +22,11 @@ public class RobotInfo { */ public final RobotType type; + /** + * The mode of the robot. + */ + public final RobotMode mode; + /** * The level of the robot. */ @@ -37,11 +42,12 @@ public class RobotInfo { */ public final MapLocation location; - public RobotInfo(int ID, Team team, RobotType type, int level, int health, MapLocation location) { + public RobotInfo(int ID, Team team, RobotType type, RobotMode mode, int level, int health, MapLocation location) { super(); this.ID = ID; this.team = team; this.type = type; + this.mode = mode; this.level = level; this.health = health; this.location = location; @@ -59,7 +65,7 @@ public int getID() { /** * Returns the team that this robot is on. * - * @return the team that this robot is on. + * @return the team that this robot is on */ public Team getTeam() { return team; @@ -68,16 +74,25 @@ public Team getTeam() { /** * Returns the type of this robot. * - * @return the type of this robot. + * @return the type of this robot */ public RobotType getType() { return type; } + /** + * Returns the mode of this robot. + * + * @return the mode of this robot + */ + public RobotMode getMode() { + return mode; + } + /** * Returns the level of this robot. * - * @return the level of this robot. + * @return the level of this robot */ public int getLevel() { return level; @@ -111,6 +126,7 @@ public boolean equals(Object o) { if (ID != robotInfo.ID) return false; if (team != robotInfo.team) return false; if (type != robotInfo.type) return false; + if (mode != robotInfo.mode) return false; if (level != robotInfo.level) return false; if (health != robotInfo.health) return false; return location.equals(robotInfo.location); @@ -122,6 +138,7 @@ public int hashCode() { result = ID; result = 31 * result + team.hashCode(); result = 31 * result + type.ordinal(); + result = 31 * result + mode.ordinal(); result = 31 * result + level; result = 31 * result + health; result = 31 * result + location.hashCode(); @@ -134,6 +151,7 @@ public String toString() { "ID=" + ID + ", team=" + team + ", type=" + type + + ", mode=" + mode + ", level=" + level + ", health=" + health + ", location=" + location + diff --git a/engine/src/main/battlecode/world/GameMapIO.java b/engine/src/main/battlecode/world/GameMapIO.java index a7865545..4687e428 100644 --- a/engine/src/main/battlecode/world/GameMapIO.java +++ b/engine/src/main/battlecode/world/GameMapIO.java @@ -337,7 +337,7 @@ private static void initInitialBodiesFromSchemaBodyTable(SpawnedBodyTable bodyTa int bodyY = locs.ys(i); Team bodyTeam = TeamMapping.team(bodyTable.teamIDs(i)); if (bodyType == RobotType.ARCHON) - initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, 1, RobotType.ARCHON.health, new MapLocation(bodyX, bodyY))); + initialBodies.add(new RobotInfo(bodyID, bodyTeam, bodyType, RobotMode.TURRET, 1, RobotType.ARCHON.health, new MapLocation(bodyX, bodyY))); // ignore robots that are not archons, TODO throw error? } } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 6f8caa00..52617eed 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -64,15 +64,11 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match controlProvider.matchStarted(this); // Add the robots contained in the LiveMap to this world. - int numArchons = 0; RobotInfo[] initialBodies = this.gameMap.getInitialBodies(); for (int i = 0; i < initialBodies.length; i++) { RobotInfo robot = initialBodies[i]; MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y); - int newID = spawnRobot(robot.type, newLocation, robot.team); - initialBodies[i] = new RobotInfo(newID, robot.team, robot.type, 1, robot.health, newLocation); - if (robot.team == Team.A && robot.type == RobotType.ARCHON) - numArchons++; + spawnRobot(robot.type, newLocation, robot.team); } this.teamInfo = new TeamInfo(this); diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 4de0f344..7dcc1117 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -57,7 +57,13 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.type = type; this.location = loc; this.level = 1; - this.mode = this.type.isBuilding() ? RobotMode.PROTOTYPE : RobotMode.DROID; + if (this.type == RobotType.ARCHON) { + this.mode = RobotMode.TURRET; + } else if (this.type.isBuilding()) { + this.mode = RobotMode.PROTOTYPE; + } else { + this.mode = RobotMode.DROID; + } this.health = (int) ((this.mode == RobotMode.PROTOTYPE ? GameConstants.PROTOTYPE_HP_PERCENTAGE : 1) * this.type.getMaxHealth(this.level)); this.controlBits = 0; @@ -160,13 +166,14 @@ public RobotInfo getRobotInfo() { && cachedRobotInfo.ID == ID && cachedRobotInfo.team == team && cachedRobotInfo.type == type + && cachedRobotInfo.mode == mode && cachedRobotInfo.level == level && cachedRobotInfo.health == health && cachedRobotInfo.location.equals(location)) { return cachedRobotInfo; } - this.cachedRobotInfo = new RobotInfo(ID, team, type, level, health, location); + this.cachedRobotInfo = new RobotInfo(ID, team, type, mode, level, health, location); return this.cachedRobotInfo; } diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index e4509d5e..9a02c484 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -66,6 +66,7 @@ public void addArchon(int id, Team team, MapLocation loc) { id, team, RobotType.ARCHON, + RobotMode.TURRET, 1, RobotType.ARCHON.health, loc diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index bb62b5e2..9c6d4cf6 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -106,6 +106,11 @@ public RobotType getType() { return this.robot.getType(); } + @Override + public RobotMode getMode() { + return this.robot.getMode(); + } + @Override public MapLocation getLocation() { return this.robot.getLocation(); From 496b7fc5d28ef5afcd22ef3802ca1b2d4c02ebfd Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Thu, 30 Dec 2021 20:28:58 -0500 Subject: [PATCH 257/413] Update examplefuncsplayer for clarity --- .../main/examplefuncsplayer/RobotPlayer.java | 210 ++++++++++-------- 1 file changed, 122 insertions(+), 88 deletions(-) diff --git a/example-bots/src/main/examplefuncsplayer/RobotPlayer.java b/example-bots/src/main/examplefuncsplayer/RobotPlayer.java index 485e6290..4b964d4f 100644 --- a/example-bots/src/main/examplefuncsplayer/RobotPlayer.java +++ b/example-bots/src/main/examplefuncsplayer/RobotPlayer.java @@ -1,21 +1,31 @@ package examplefuncsplayer; + import battlecode.common.*; +import java.util.Random; +/** + * RobotPlayer is the class that describes your main robot strategy. + * The run() method inside this class is like your main function: this is what we'll call once your robot + * is created! + */ public strictfp class RobotPlayer { - static RobotController rc; - static final RobotType[] droids = { - RobotType.MINER, - RobotType.BUILDER, - RobotType.SOLDIER, - RobotType.SAGE, - }; + /** + * We will use this variable to count the number of turns this robot has been alive. + * You can use static variables like this to save any information you want. Keep in mind that even though + * these variables are static, in Battlecode they aren't actually shared between your robots. + */ + static int turnCount = 0; - static final RobotType[] buildings = { - RobotType.LABORATORY, - RobotType.WATCHTOWER, - }; + /** + * A random number generator. + * We will use this RNG to make some random moves. The Random class is provided by the java.util.Random + * import at the top of this file. Here, we *seed* the RNG with a constant number (6147); this makes sure + * we get the same sequence of numbers every time this code is run. This is very useful for debugging! + */ + static final Random rng = new Random(6147); + /** Array containing all the possible movement directions. */ static final Direction[] directions = { Direction.NORTH, Direction.NORTHEAST, @@ -27,116 +37,140 @@ public strictfp class RobotPlayer { Direction.NORTHWEST, }; - static int turnCount; - /** * run() is the method that is called when a robot is instantiated in the Battlecode world. - * If this method returns, the robot dies! + * It is like the main function for your robot. If this method returns, the robot dies! + * + * @param rc The RobotController object. You use it to perform actions from this robot, and to get + * information on its current status. Essentially your portal to interacting with the world. **/ @SuppressWarnings("unused") public static void run(RobotController rc) throws GameActionException { - // This is the RobotController object. You use it to perform actions from this robot, - // and to get information on its current status. - RobotPlayer.rc = rc; + // Hello world! Standard output is very useful for debugging. + // Everything you say here will be directly viewable in your terminal when you run a match! + System.out.println("I'm a " + rc.getType() + " and I just got created! I have health " + rc.getHealth()); - turnCount = 0; + // You can also use indicators to save debug notes in replays. + // rc.setIndicatorString("Hello world!"); // TODO: This isn't supported yet. - System.out.println("I'm a " + rc.getType() + " and I just got created! I have health " + rc.getHealth()); while (true) { - turnCount += 1; - // Try/catch blocks stop unhandled exceptions, which cause your robot to freeze + // This code runs during the entire lifespan of the robot, which is why it is in an infinite + // loop. If we ever leave this loop and return from run(), the robot dies! At the end of the + // loop, we call Clock.yield(), signifying that we've done everything we want to do. + + turnCount += 1; // We have now been alive for one more turn! + System.out.println("Age: " + turnCount + "; Location: " + rc.getLocation()); + + // Try/catch blocks stop unhandled exceptions, which cause your robot to explode. try { - // Here, we've separated the controls into a different method for each RobotType. - // You may rewrite this into your own control structure if you wish. - System.out.println("I'm a " + rc.getType() + "! Location " + rc.getLocation()); + // The same run() function is called for every robot on your team, even if they are + // different types. Here, we separate the control depending on the RobotType, so we can + // use different strategies on different robots. If you wish, you are free to rewrite + // this into a different control structure! switch (rc.getType()) { - case ARCHON: runArchon(); break; - case LABORATORY: runLaboratory(); break; - case WATCHTOWER: runWatchtower(); break; - case MINER: runMiner(); break; - case BUILDER: runBuilder(); break; - case SOLDIER: runSoldier(); break; - case SAGE: runSage(); break; + case ARCHON: runArchon(rc); break; + case MINER: runMiner(rc); break; + case SOLDIER: runSoldier(rc); break; + case LABORATORY: // Examplefuncsplayer doesn't use any of these robot types below. + case WATCHTOWER: // You might want to give them a try! + case BUILDER: + case SAGE: break; } - - // Clock.yield() makes the robot wait until the next turn, then it will perform this loop again - Clock.yield(); + } catch (GameActionException e) { + // Oh no! It looks like we did something illegal in the Battlecode world. You should + // handle GameActionExceptions judiciously, in case unexpected events occur in the game + // world. Remember, uncaught exceptions cause your robot to explode! + System.out.println(rc.getType() + " Exception"); + e.printStackTrace(); } catch (Exception e) { + // Oh no! It looks like our code tried to do something bad. This isn't a + // GameActionException, so it's more likely to be a bug in our code. System.out.println(rc.getType() + " Exception"); e.printStackTrace(); - } - } - } - static void runArchon() throws GameActionException { - RobotType toBuild = randomDroid(); - int influence = 50; - for (Direction dir : directions) { - if (rc.canBuildRobot(toBuild, dir)) { - rc.buildRobot(toBuild, dir); - } else { - break; + } finally { + // Signify we've done everything we want to do, thereby ending our turn. + // This will make our code wait until the next turn, and then perform this loop again. + Clock.yield(); } + // End of loop: go back to the top. Clock.yield() has ended, so it's time for another turn! } - } - - static void runLaboratory() throws GameActionException { - // TODO - } - static void runWatchtower() throws GameActionException { - // TODO - } - - static void runMiner() throws GameActionException { - if (tryMove(randomDirection())) - System.out.println("I moved!"); - } - - static void runBuilder() throws GameActionException { - // TODO - } - - static void runSoldier() throws GameActionException { - // TODO - } - - static void runSage() throws GameActionException { - // TODO + // Your code should never reach here (unless it's intentional)! Self-destruction imminent... } /** - * Returns a random Direction. - * - * @return a random Direction + * Run a single turn for an Archon. + * This code is wrapped inside the infinite loop in run(), so it is called once per turn. */ - static Direction randomDirection() { - return directions[(int) (Math.random() * directions.length)]; + static void runArchon(RobotController rc) throws GameActionException { + // Pick a direction to build in. + Direction dir = directions[rng.nextInt(directions.length)]; + if (rng.nextBoolean()) { + // Let's try to build a miner. + if (rc.canBuildRobot(RobotType.MINER, dir)) { + rc.buildRobot(RobotType.MINER, dir); + } + } else { + // Let's try to build a soldier. + if (rc.canBuildRobot(RobotType.SOLDIER, dir)) { + rc.buildRobot(RobotType.SOLDIER, dir); + } + } } /** - * Returns a random droid - * - * @return a random RobotType + * Run a single turn for a Miner. + * This code is wrapped inside the infinite loop in run(), so it is called once per turn. */ - static RobotType randomDroid() { - return droids[(int) (Math.random() * droids.length)]; + static void runMiner(RobotController rc) throws GameActionException { + // Try to mine on squares around us. + MapLocation me = rc.getLocation(); + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + MapLocation mineLocation = new MapLocation(me.x + dx, me.y + dy); + // Notice that the Miner's action cooldown is very low. + // You can mine multiple times per turn! + while (rc.canMineGold(mineLocation)) { + rc.mineGold(mineLocation); + } + while (rc.canMineLead(mineLocation)) { + rc.mineLead(mineLocation); + } + } + } + + // Also try to move randomly. + Direction dir = directions[rng.nextInt(directions.length)]; + if (rc.canMove(dir)) { + rc.move(dir); + System.out.println("I moved!"); + } } /** - * Attempts to move in a given direction. - * - * @param dir The intended direction of movement - * @return true if a move was performed - * @throws GameActionException + * Run a single turn for a Soldier. + * This code is wrapped inside the infinite loop in run(), so it is called once per turn. */ - static boolean tryMove(Direction dir) throws GameActionException { - System.out.println("I am trying to move " + dir + "; " + rc.isMovementReady() + " " + rc.getMovementCooldownTurns() + " " + rc.canMove(dir)); + static void runSoldier(RobotController rc) throws GameActionException { + // Try to attack someone + int radius = rc.getType().actionRadiusSquared; + Team opponent = rc.getTeam().opponent(); + RobotInfo[] enemies = rc.senseNearbyRobots(radius, opponent); + if (enemies.length > 0) { + MapLocation toAttack = enemies[0].location; + if (rc.canAttack(toAttack)) { + rc.attack(toAttack); + } + } + + // Also try to move randomly. + Direction dir = directions[rng.nextInt(directions.length)]; if (rc.canMove(dir)) { rc.move(dir); - return true; - } else return false; + System.out.println("I moved!"); + } } } From ec8d12855c2c1fb4742f33733fd0335e79540a60 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 19:34:37 -0600 Subject: [PATCH 258/413] indicator string template, fix canActLocation --- engine/src/main/battlecode/common/RobotController.java | 10 ++++++++++ engine/src/main/battlecode/world/InternalRobot.java | 3 ++- .../src/main/battlecode/world/RobotControllerImpl.java | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index cbd62db7..b0b63340 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -703,6 +703,16 @@ public strictfp interface RobotController { // ******** DEBUG METHODS ************ // *********************************** + /** + * Sets the indicator string for this robot. Strings must have max + * length GameConstants.INDICATOR_STRING_MAX_LENGTH. + * + * @param string the indicator string this round + * + * @battlecode.doc.costlymethod + */ + void setIndicatorString(String string); + /** * Draw a dot on the game map for debugging purposes. * diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 7dcc1117..a67c6f60 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -219,7 +219,8 @@ public int getActionRadiusSquared() { * @param toAct the MapLocation to act */ public boolean canActLocation(MapLocation toAct) { - return this.location.distanceSquaredTo(toAct) <= getActionRadiusSquared(); + return this.location.distanceSquaredTo(toAct) <= getActionRadiusSquared() + && this.gameWorld.getGameMap().onTheMap(toAct); } /** diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 9c6d4cf6..766afb3e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -771,6 +771,11 @@ public void resign() { // ******** DEBUG METHODS ************ // *********************************** + @Override + public void setIndicatorString(String string) { + // TODO + } + @Override public void setIndicatorDot(MapLocation loc, int red, int green, int blue) { assertNotNull(loc); From 31adaa0b84ab5f5ec8b3b8925322b9347e253ca8 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 19:58:13 -0600 Subject: [PATCH 259/413] indicator strings implemented --- .../main/battlecode/common/GameConstants.java | 4 ++-- .../main/battlecode/common/RobotController.java | 4 ++-- .../main/battlecode/world/InternalRobot.java | 17 ++++++++++++++++- .../battlecode/world/RobotControllerImpl.java | 5 ++++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 91883798..7e17c0e8 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -43,8 +43,8 @@ public class GameConstants { // ****** GAME PARAMETERS ********** // ********************************* - /** The number of indicator strings that a player can associate with a robot. */ - public static final int NUMBER_OF_INDICATOR_STRINGS = 3; + /** The maximum length of indicator strings that a player can associate with a robot. */ + public static final int INDICATOR_STRING_MAX_LENGTH = 64; /** The length of each team's shared communication array. */ public static final int SHARED_ARRAY_LENGTH = 64; diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index b0b63340..4eebc697 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -704,8 +704,8 @@ public strictfp interface RobotController { // *********************************** /** - * Sets the indicator string for this robot. Strings must have max - * length GameConstants.INDICATOR_STRING_MAX_LENGTH. + * Sets the indicator string for this robot. Only the first + * GameConstants.INDICATOR_STRING_MAX_LENGTH characters are used. * * @param string the indicator string this round * diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index a67c6f60..570abc52 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -40,6 +40,8 @@ public strictfp class InternalRobot implements Comparable { */ private RobotInfo cachedRobotInfo; + private String indicatorString; + /** * Create a new internal representation of a robot * @@ -77,6 +79,8 @@ public InternalRobot(GameWorld gw, int id, RobotType type, MapLocation loc, Team this.addMovementCooldownTurns(GameConstants.COOLDOWNS_PER_TURN); this.numVisibleFriendlyRobots = 0; + this.indicatorString = ""; + this.controller = new RobotControllerImpl(gameWorld, this); } @@ -272,6 +276,15 @@ public boolean canMutate() { // ****** UPDATE METHODS ******************** // ****************************************** + /** + * Sets the indicator string of the robot. + * + * @param string the new indicator string of the robot + */ + public void setIndicatorString(String string) { + this.indicatorString = string; + } + /** * Sets the location of the robot. * @@ -390,7 +403,7 @@ public void heal(InternalRobot bot) { // should be called at the beginning of every round public void processBeginningOfRound() { - // anything + this.indicatorString = ""; } public void processBeginningOfTurn() { @@ -402,6 +415,8 @@ public void processBeginningOfTurn() { public void processEndOfTurn() { // bytecode stuff! this.gameWorld.getMatchMaker().addBytecodes(this.ID, this.bytecodesUsed); + // indicator strings! + this.gameWorld.getMatchMaker().addIndicatorString(this.ID, this.indicatorString); this.roundsAlive++; } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 766afb3e..2451adef 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -773,7 +773,10 @@ public void resign() { @Override public void setIndicatorString(String string) { - // TODO + if (string.length() > GameConstants.INDICATOR_STRING_MAX_LENGTH) { + string = string.substring(0, GameConstants.INDICATOR_STRING_MAX_LENGTH); + } + this.robot.setIndicatorString(string); } @Override From aae2befd1d7ffcc3faa6ce81f29bf6538cddbdde Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 20:06:32 -0600 Subject: [PATCH 260/413] movement cd added after robot moves --- engine/src/main/battlecode/world/RobotControllerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 2451adef..2ee4778e 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -361,9 +361,10 @@ public boolean canMove(Direction dir) { public void move(Direction dir) throws GameActionException { assertCanMove(dir); MapLocation center = adjacentLocation(dir); - this.robot.addMovementCooldownTurns(getType().movementCooldown); this.gameWorld.moveRobot(getLocation(), center); this.robot.setLocation(center); + // this has to happen after robot's location changed because rubble + this.robot.addMovementCooldownTurns(getType().movementCooldown); this.gameWorld.getMatchMaker().addMoved(getID(), getLocation()); } From aa97e0f0f2e9edcb5f4877f886deb2e20c1f6fe0 Mon Sep 17 00:00:00 2001 From: Elizabeth Zou Date: Thu, 30 Dec 2021 20:25:28 -0600 Subject: [PATCH 261/413] replace bc21 with bc22 --- build.gradle | 10 +++++----- client/.gitignore | 4 ++-- client/playback/README.md | 8 ++++---- client/playback/src/gen/create.ts | 2 +- client/playback/src/legacy/bench/run.ts | 2 +- client/playback/src/legacy/bench/runTimeline.ts | 2 +- client/visualizer/README.md | 4 ++-- client/visualizer/package.json | 6 +++--- client/visualizer/src/main/sidebar.ts | 4 ++-- client/visualizer/src/main/tournament_new.ts | 2 +- client/visualizer/src/mapeditor/mapeditor.ts | 2 +- client/visualizer/src/runner.ts | 8 ++++---- .../src/main/examplefuncsplayer/RobotPlayer.java | 2 ++ schema/README.md | 2 +- 14 files changed, 30 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index 7aee872a..13a939c8 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,7 @@ task headless(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build' '-Dbc.game.team-a.url='+project(':example-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.team-b.url='+project(':example-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc21' + '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' ] } @@ -86,7 +86,7 @@ task debug(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build']) '-Dbc.game.team-a.url='+project(':example-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.team-b.url='+project(':example-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc21' + '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' ] } @@ -105,7 +105,7 @@ task headlessX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc21' + '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' ] } @@ -125,7 +125,7 @@ task debugX(type: JavaExec, dependsOn: [':engine:build', ':internal-test-bots:bu '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc21' + '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' ] } @@ -147,7 +147,7 @@ task runFromClient(type: JavaExec, dependsOn: [':engine:build', ':internal-test- '-Dbc.game.team-a.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.team-b.url='+project(':internal-test-bots').sourceSets.main.output.classesDirs.getAsPath(), '-Dbc.game.maps='+project.property('maps'), - '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc21' + '-Dbc.server.save-file=' + 'matches/' + project.property('teamA') + '-vs-' + project.property('teamB') + '-on-' + project.property('maps') + '.bc22' ] } diff --git a/client/.gitignore b/client/.gitignore index e1410674..16970045 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -13,11 +13,11 @@ playback/out/ # built client dist/ -# Generated test bc21 files +# Generated test bc22 files examples/ # any battlecode files -*.bc21 +*.bc22 # for mac users? **/.DS_Store diff --git a/client/playback/README.md b/client/playback/README.md index 998f7296..8c817c01 100644 --- a/client/playback/README.md +++ b/client/playback/README.md @@ -24,7 +24,7 @@ Remember to run `npm install` without any serious errors in this directory. * `npm run check`: Compile typescript files (`src/*.ts`) without creating any output files, and pipe output to less. Use this command when you need to update playback for new schema. * `npm run build`: Compile typescript files (`src/*.ts`) into javascript & typescript declaration files. (`out/*.js`, `out/*.d.ts`) - * `npm run gen`: Generate dummy `.bc21` files. It runs typescript without transcripting into javascript, by using `ts-node`. (`../examples`) + * `npm run gen`: Generate dummy `.bc22` files. It runs typescript without transcripting into javascript, by using `ts-node`. (`../examples`) * `npm run clean`: Simply remove itself and everything in `out` directory. * `npm run watch`: Watch for chanages on `src/*.ts` files, and build again whenever change is detected. @@ -34,11 +34,11 @@ The other scripts are under maintenance. ### Structure * `src/*.ts` : main source files. `index.ts` is the starting point * `src/tsconfig.json` : TypeScript compile option configuration file - * `src/gen/create.ts` : code for generating dummy `.bc21` files. + * `src/gen/create.ts` : code for generating dummy `.bc22` files. * `src/legacy/**/*.ts` : Legacy codes, including test for soa.ts and simulating * `out/*.js` : compiled javascript output of typescript files * `out/*.d.ts` : compiled typescript declaration files of typescript files - * `../examples` : generated `.bc21` files from `src/gen/*` + * `../examples` : generated `.bc22` files from `src/gen/*` ### Note @@ -68,7 +68,7 @@ const bc = require('battlecode-playback'); let aliveRobots = {}; let lifetimes = []; -bc.stream('match.bc21').on('spawn', spawnEvent => { +bc.stream('match.bc22').on('spawn', spawnEvent => { aliveRobots[spawnEvent.bodyId] = { born: spawnEvent.round }; diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 27f84172..dae328e9 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -692,7 +692,7 @@ function main(){ const prefix = "../examples/"; games.forEach(pair => { - const filename = `${prefix}${pair.name}.bc21` + const filename = `${prefix}${pair.name}.bc22` const stream = createWriteStream(filename); const game = pair.game; diff --git a/client/playback/src/legacy/bench/run.ts b/client/playback/src/legacy/bench/run.ts index a45ca9e0..d0e35c65 100644 --- a/client/playback/src/legacy/bench/run.ts +++ b/client/playback/src/legacy/bench/run.ts @@ -3,7 +3,7 @@ import {crunch} from '../simulator'; import {schema, flatbuffers} from 'battlecode-schema'; const wrapper = schema.GameWrapper.getRootAsGameWrapper( - new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc21'))) + new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc22'))) ); crunch(wrapper); diff --git a/client/playback/src/legacy/bench/runTimeline.ts b/client/playback/src/legacy/bench/runTimeline.ts index 8c853a73..5f746ff2 100644 --- a/client/playback/src/legacy/bench/runTimeline.ts +++ b/client/playback/src/legacy/bench/runTimeline.ts @@ -4,7 +4,7 @@ import {schema, flatbuffers} from 'battlecode-schema'; import Game from '../../game'; const wrapper = schema.GameWrapper.getRootAsGameWrapper( - new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc21'))) + new flatbuffers.ByteBuffer(new Uint8Array(readFileSync('test.bc22'))) ); const game = new Game(); diff --git a/client/visualizer/README.md b/client/visualizer/README.md index e9470223..9a3d5dc2 100644 --- a/client/visualizer/README.md +++ b/client/visualizer/README.md @@ -36,7 +36,7 @@ To watch using a standalone app (Electron): $ npm run electron ``` -When you `npm run electron`, you can set the default file to run when it is launched, by placing `default.bc21` in `/client` folder. So, it's loading `/client/default.bc21` file when it is launched. +When you `npm run electron`, you can set the default file to run when it is launched, by placing `default.bc22` in `/client` folder. So, it's loading `/client/default.bc22` file when it is launched. To run the tests: ```sh @@ -48,7 +48,7 @@ All code and assets go in `src`, which is written in Typescript. Note that we're If you want to add a dependency, run `npm install --save package-name` and then `npm install --save @types/package-name` (for the typescript declarations). If `@types/package-name` doesn't exist, sacrifice a goat, or possibly a grad student. -Also note that this repo doesn't contain all of the client code. See `../playback`; that's the library that actually reads and replays the `.bc21` match files. This repo has everything else; video, sound, controls, etc. +Also note that this repo doesn't contain all of the client code. See `../playback`; that's the library that actually reads and replays the `.bc22` match files. This repo has everything else; video, sound, controls, etc. If you've made a change in `../playback` and want to integrate it here, you need to do `npm install` again. It's a bit of a pain; and should probably be integrated in this folder at some point. diff --git a/client/visualizer/package.json b/client/visualizer/package.json index 401b8dbb..ddbae1ac 100644 --- a/client/visualizer/package.json +++ b/client/visualizer/package.json @@ -70,9 +70,9 @@ }, "fileAssociations": [ { - "ext": "bc21", - "name": "BC21", - "description": "Battlecode Match 2021", + "ext": "bc22", + "name": "BC22", + "description": "Battlecode Match 2022", "role": "Viewer" } ], diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index 3b85d93e..820e916b 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -169,7 +169,7 @@ export default class Sidebar { press "Kill ongoing processes". Note that the part of the match that has already loaded will remain in the client.

- From the web client: You can always upload a .bc21 file by + From the web client: You can always upload a .bc22 file by clicking the upload button in the Queue section.

Use the control buttons at the top of the screen to @@ -220,7 +220,7 @@ export default class Sidebar { (Note: the name of your .map21 file must be the same as the name of your map.)

- Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc21.`; + Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; if (this.conf.tournamentMode) { innerHTML += diff --git a/client/visualizer/src/main/tournament_new.ts b/client/visualizer/src/main/tournament_new.ts index 31d0a536..f3fe275c 100644 --- a/client/visualizer/src/main/tournament_new.ts +++ b/client/visualizer/src/main/tournament_new.ts @@ -20,7 +20,7 @@ export function readTournament(jsonFile: File, cbTournament: (t: Tournament) => team2: arr[1], map: arr[2], winner: arr[3], - url: "https://2021.battlecode.org/replays/" + arr[4] + ".bc21" + url: "https://2021.battlecode.org/replays/" + arr[4] + ".bc22" })); const desc: TournamentMatch[][] = data.filter(game => game != null).map((game) => (game.map(parseMatch))); const tournament = new Tournament(desc); diff --git a/client/visualizer/src/mapeditor/mapeditor.ts b/client/visualizer/src/mapeditor/mapeditor.ts index 30c858a6..248f9841 100644 --- a/client/visualizer/src/mapeditor/mapeditor.ts +++ b/client/visualizer/src/mapeditor/mapeditor.ts @@ -93,7 +93,7 @@ export default class MapEditor { (Note: the name of your .map21 file must be the same as the name of your map.)

- Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc21.`; + Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; return div; } diff --git a/client/visualizer/src/runner.ts b/client/visualizer/src/runner.ts index 76349474..f095d8cc 100644 --- a/client/visualizer/src/runner.ts +++ b/client/visualizer/src/runner.ts @@ -139,9 +139,9 @@ export default class Runner { let uploadLabel = document.createElement("label"); uploadLabel.setAttribute("for", "file-upload"); uploadLabel.setAttribute("class", "custom-button"); - uploadLabel.innerText = 'Upload a .bc21 replay file'; + uploadLabel.innerText = 'Upload a .bc22 replay file'; if (this.conf.tournamentMode) { - uploadLabel.innerText = "Upload a .bc21 or .json file"; + uploadLabel.innerText = "Upload a .bc22 or .json file"; } // create the functional button @@ -149,9 +149,9 @@ export default class Runner { upload.textContent = 'upload'; upload.id = "file-upload"; upload.setAttribute('type', 'file'); - upload.accept = '.bc21'; + upload.accept = '.bc22'; if (this.conf.tournamentMode) { - upload.accept = '.bc21,.json'; + upload.accept = '.bc22,.json'; } upload.onchange = () => this.loadMatch(upload.files as FileList); upload.onclick = () => upload.value = ""; diff --git a/example-bots/src/main/examplefuncsplayer/RobotPlayer.java b/example-bots/src/main/examplefuncsplayer/RobotPlayer.java index 4b964d4f..3ee08461 100644 --- a/example-bots/src/main/examplefuncsplayer/RobotPlayer.java +++ b/example-bots/src/main/examplefuncsplayer/RobotPlayer.java @@ -110,11 +110,13 @@ static void runArchon(RobotController rc) throws GameActionException { Direction dir = directions[rng.nextInt(directions.length)]; if (rng.nextBoolean()) { // Let's try to build a miner. + rc.setIndicatorString("Trying to build a miner"); if (rc.canBuildRobot(RobotType.MINER, dir)) { rc.buildRobot(RobotType.MINER, dir); } } else { // Let's try to build a soldier. + rc.setIndicatorString("Trying to build a soldier"); if (rc.canBuildRobot(RobotType.SOLDIER, dir)) { rc.buildRobot(RobotType.SOLDIER, dir); } diff --git a/schema/README.md b/schema/README.md index aa640b8d..70ffed6f 100644 --- a/schema/README.md +++ b/schema/README.md @@ -4,7 +4,7 @@ This repository contains the [Flatbuffers](https://google.github.io/flatbuffers/ ### Spec ##### Match Files -A match file has the extension `.bc21`. It consists of a single flatbuffer with a GameWrapper at its root, containing a valid stream of Events (as described in `battlecode.fbs`). The buffer will be compressed with GZIP. +A match file has the extension `.bc22`. It consists of a single flatbuffer with a GameWrapper at its root, containing a valid stream of Events (as described in `battlecode.fbs`). The buffer will be compressed with GZIP. ##### Network Protocol The battlecode server hosts an unsecured websocket server on port 6175. When you connect to that port, you will receive each Event that has occurred in the current match as a separate websocket message, in order. There are no messages that can be sent from the client to the server. The server may disconnect at any time, and might not resend its messages when it does; any client has to be able to deal with a game being only half-finished over the network. Messages over the network are unsecured. From 51abd95cb3f95c0a4f3cede6edcb2f73b32db3a2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Fri, 31 Dec 2021 11:24:23 -0500 Subject: [PATCH 262/413] Mapeditor patch up --- client/visualizer/src/main/sidebar.ts | 2 +- client/visualizer/src/mapeditor/form.ts | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index 76a36da3..e7f63822 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -104,7 +104,7 @@ export default class Sidebar { this.div.appendChild(this.innerDiv); - this.conf.mode = Mode.MAPEDITOR; //GAME; + this.conf.mode = Mode.GAME; // MAPEDITOR; this.updateModeButtons(); this.setSidebar(); diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 751ed597..30512f93 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -70,7 +70,7 @@ export default class MapEditorForm { private originalBodies: Map; private symmetricBodies: Map; private rubble: number[]; - private lead_vals: number[]; + private leadVals: number[]; randomMode: boolean = false; // if true, all squares are randomly painted. randomHigh: number = 1; @@ -103,7 +103,7 @@ export default class MapEditorForm { this.div.appendChild(this.header.div); // symmetry - this.symmetry = new SymmetryForm(() => {this.initRubble(); this.render()}); + this.symmetry = new SymmetryForm(() => {this.initRubble(); this.initLead(); this.render()}); this.div.appendChild(document.createElement("br")); this.div.appendChild(this.symmetry.div); this.div.appendChild(document.createElement("br")); @@ -188,6 +188,7 @@ export default class MapEditorForm { this.renderer = new MapRenderer(canvas, imgs, conf, onclickUnit, onclickBlank, onMouseover, onDrag); this.initRubble(); + this.initLead(); // Load callbacks and finally render this.loadCallbacks(); @@ -450,6 +451,14 @@ export default class MapEditorForm { this.rubble.fill(50); } + /** + * Initialize lead based on map dimensions. + */ + private initLead() { + this.leadVals = new Array(this.header.getHeight() * this.header.getWidth()); + this.leadVals.fill(0); + } + private getRubble(x: number, y: number) { return this.rubble[y*this.header.getWidth() + x]; } @@ -504,7 +513,7 @@ export default class MapEditorForm { originalBodies: this.originalBodies, symmetricBodies: this.symmetricBodies, rubble: this.rubble, - leadVals: this.lead_vals, + leadVals: this.leadVals, symmetry: this.symmetry.getSymmetry() }; } @@ -574,6 +583,7 @@ export default class MapEditorForm { this.originalBodies = new Map(); this.symmetricBodies = new Map(); this.initRubble(); + this.initLead(); this.render(); } } From 9902035f5ab7676127ebcb8c5dda3bef15c4219f Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Fri, 31 Dec 2021 13:14:56 -0500 Subject: [PATCH 263/413] Add lead form --- client/visualizer/src/mapeditor/forms/lead.ts | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 client/visualizer/src/mapeditor/forms/lead.ts diff --git a/client/visualizer/src/mapeditor/forms/lead.ts b/client/visualizer/src/mapeditor/forms/lead.ts new file mode 100644 index 00000000..13f76eb1 --- /dev/null +++ b/client/visualizer/src/mapeditor/forms/lead.ts @@ -0,0 +1,151 @@ +import * as cst from '../../constants'; + +import {schema} from 'battlecode-playback'; + +import {MapUnit} from '../index'; + +export default class RobotForm { + + // The public div + readonly div: HTMLDivElement; + + // Form elements for archon settings + readonly lead: HTMLInputElement; + readonly x: HTMLInputElement; + readonly y: HTMLInputElement; + //readonly influence: HTMLInputElement; + + // Callbacks on input change + readonly width: () => number; + readonly height: () => number; + + constructor(width: () => number, height: () => number) { + + // Store the callbacks + this.width = width; + this.height = height; + + // Create HTML elements + this.div = document.createElement("div"); + this.lead = document.createElement("input"); + this.x = document.createElement("input"); + this.y = document.createElement("input"); + + // Create the form + this.loadInputs(); + this.div.appendChild(this.createForm()); + this.loadCallbacks(); + } + + /** + * Initializes input fields. + */ + private loadInputs(): void { + this.x.type = "text"; + this.y.type = "text"; + this.lead.value = "50"; + } + + /** + * Creates the HTML form that collects archon information. + */ + private createForm(): HTMLFormElement { + // HTML structure + const form: HTMLFormElement = document.createElement("form"); + const lead: HTMLDivElement = document.createElement("div"); + const x: HTMLDivElement = document.createElement("div"); + const y: HTMLDivElement = document.createElement("div"); + // const influence: HTMLDivElement = document.createElement("div"); + //form.appendChild(id); + form.appendChild(lead); + form.appendChild(x); + form.appendChild(y); + // form.appendChild(influence); + form.appendChild(document.createElement("br")); + + lead.appendChild(document.createTextNode("Lead: ")); + lead.appendChild(this.lead); + + // X coordinate + x.appendChild(document.createTextNode("X: ")); + x.appendChild(this.x); + + // Y coordinate + y.appendChild(document.createTextNode("Y: ")); + y.appendChild(this.y); + + // Influence + // influence.appendChild(document.createTextNode("I: ")); + // influence.appendChild(this.influence); + + return form; + } + + /** + * Add callbacks to the form elements. + */ + private loadCallbacks(): void { + + // X must be in the range [0, this.width] + this.x.onchange = () => { + let value: number = this.getX(); + value = Math.max(value, 0); + value = Math.min(value, this.width()); + this.x.value = isNaN(value) ? "" : String(value); + }; + + // Y must be in the range [0, this.height] + this.y.onchange = () => { + let value: number = this.getY(); + value = Math.max(value, 0); + value = Math.min(value, this.height()); + this.y.value = isNaN(value) ? "" : String(value); + }; + + // this.influence.onchange = () => { + // let value: number = this.getInfluence(); + // value = Math.max(value, 50); + // value = Math.min(value, 500); + // this.influence.value = isNaN(value) ? "" : String(value); + // } + + // this.team.onchange = () => { + // if (this.getTeam() !== 0) { + // this.influence.disabled = true; + // this.influence.value = String(cst.INITIAL_INFLUENCE); + // } + // else this.influence.disabled = false; + // } + + } + + private getLead(): number { + return parseInt(this.lead.value); + } + + private getX(): number { + return parseInt(this.x.value); + } + + private getY(): number { + return parseInt(this.y.value); + } + + resetForm(): void { + this.x.value = ""; + this.y.value = ""; + this.lead.value = "50"; + } + + setForm(x, y): void { + this.x.value = String(x); + this.y.value = String(y); + } + + isValid(): boolean { + const x = this.getX(); + const y = this.getY(); + //const I = this.getInfluence(); + return !(isNaN(x) || isNaN(y)); // || isNaN(I)); + } +} From d8cbadf30fdd89d4cbbabf6cea04786f21bd0b9c Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Fri, 31 Dec 2021 16:00:08 -0500 Subject: [PATCH 264/413] Switch around rubble colors --- client/visualizer/src/constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 84852b89..776649ce 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -34,6 +34,7 @@ export const TILE_COLORS: Array[] = [ // Given passability, get index of tile to use. export const getLevel = (x: number): number => { + x = 100 - x; x /= 100; const nLev = TILE_COLORS.length const floatLevel = ((1 - x) - 0.1) / 0.9 * nLev From 1c7fa69265761c336bf0d68a740a28cedcf1dcc9 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 13:27:09 -0500 Subject: [PATCH 265/413] Fix hp tracking bug --- client/playback/src/gameworld.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 8b7bbfb2..a110bd96 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -20,7 +20,6 @@ export type BodiesSchema = { type: Int8Array, x: Int32Array, y: Int32Array, - flag: Int32Array; bytecodesUsed: Int32Array, // TODO: is this needed? action: Int8Array, parent: Int32Array, @@ -200,7 +199,6 @@ export default class GameWorld { type: new Int8Array(0), x: new Int32Array(0), y: new Int32Array(0), - flag: new Int32Array(0), bytecodesUsed: new Int32Array(0), action: new Int8Array(0), parent: new Int32Array(0), @@ -665,6 +663,7 @@ export default class GameWorld { // Store frequently used arrays var teams = bodies.teamIDsArray(); var types = bodies.typesArray(); + var hps = new Int32Array(bodies.robotIDsLength()); // Update spawn stats for(let i = 0; i < bodies.robotIDsLength(); i++) { @@ -673,6 +672,7 @@ export default class GameWorld { statObj.robots[types[i]][0] += 1; // TODO: handle level statObj.total_hp[types[i]][0] += this.meta.types[types[i]].health; // TODO: extract meta info this.teamStats.set(teams[i], statObj); + hps[i] = this.meta.types[types[i]].health; } const locs = bodies.locs(this._vecTableSlot1); @@ -701,6 +701,7 @@ export default class GameWorld { ability: new Int8Array(bodies.robotIDsLength()), bid: new Int32Array(bodies.robotIDsLength()), parent: new Int32Array(bodies.robotIDsLength()), + hp: hps, level: levels }); } From f65819ac23963fe49fdc42a47e2c7511a64235de Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 14:40:10 -0500 Subject: [PATCH 266/413] Track passive lead increase --- client/playback/src/gameworld.ts | 6 ++++++ client/playback/src/metadata.ts | 3 +++ client/visualizer/src/gamearea/renderer.ts | 14 +++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index a110bd96..ca111bd2 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -422,6 +422,12 @@ export default class GameWorld { }) } + if (delta.roundID() % this.meta.constants.increasePeriod() == 0) { + this.mapStats.leadVals.forEach((x,i) => { + this.mapStats.leadVals[i] = x > 0 ? x + this.meta.constants.leadAdditiveIncease(): 0; + }); + } + // Actions if(delta.actionsLength() > 0){ const arrays = this.bodies.arrays; diff --git a/client/playback/src/metadata.ts b/client/playback/src/metadata.ts index 16bd68ef..a76e4312 100644 --- a/client/playback/src/metadata.ts +++ b/client/playback/src/metadata.ts @@ -25,6 +25,8 @@ export default class Metadata { */ teams: {[key: number]: Team}; + constants: schema.Constants; + constructor() { this.specVersion = UNKNOWN_SPEC_VERSION; this.types = Object.create(null); @@ -66,6 +68,7 @@ export default class Metadata { body.bytecodeLimit() ); } + this.constants = header.constants(); // SAFE Object.freeze(this.types); Object.freeze(this.teams); diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index e77e3fb7..4bb790e2 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -19,7 +19,7 @@ export default class Renderer { // For rendering robot information on click private lastSelectedID: number // position of mouse cursor hovering - private hoverPos: { x: number, y: number } | null = null; + private hoverPos: { xrel: number, yrel: number } | null = null; constructor(readonly canvas: HTMLCanvasElement, readonly imgs: AllImages, private conf: config.Config, readonly metadata: Metadata, readonly onRobotSelected: (id: number) => void, @@ -141,7 +141,7 @@ export default class Renderer { const scale = 20 this.ctx.scale(1 / scale, 1 / scale) - const { x, y } = this.hoverPos + const { xrel: x, yrel: y } = this.hoverPos const cx = (minX + x) * scale, cy = (minY + (height - y - 1)) * scale this.ctx.strokeStyle = 'purple' this.ctx.lineWidth *= 2 @@ -393,6 +393,14 @@ export default class Renderer { // const minY = world.minCorner.y; // const maxY = world.maxCorner.y - 1; + if (this.hoverPos) { + const {xrel, yrel} = this.hoverPos; + const x = xrel + world.minCorner.x; + const y = yrel + world.minCorner.y; + const idx = world.mapStats.getIdx(xrel, yrel) + onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx], world.mapStats.leadVals[idx], world.mapStats.goldVals[idx]) + } + this.canvas.onmousemove = (event) => { // const x = width * event.offsetX / this.canvas.offsetWidth + world.minCorner.x; // const _y = height * event.offsetY / this.canvas.offsetHeight + world.minCorner.y; @@ -404,7 +412,7 @@ export default class Renderer { const yrel = y - world.minCorner.y const idx = world.mapStats.getIdx(xrel, yrel) onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx], world.mapStats.leadVals[idx], world.mapStats.goldVals[idx]) - this.hoverPos = { x: xrel, y: yrel } + this.hoverPos = { xrel: xrel, yrel: yrel } } this.canvas.onmouseout = (event) => { From c0eb883a2ee8b251c685cd70c4183e2bb514dccd Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 15:48:30 -0500 Subject: [PATCH 267/413] Map editor updates --- client/visualizer/src/main/scaffold.ts | 6 +-- client/visualizer/src/main/sidebar.ts | 2 +- .../src/mapeditor/action/generator.ts | 25 ++++++++--- .../src/mapeditor/action/renderer.ts | 42 ++++++++++++++++--- .../src/mapeditor/action/validator.ts | 2 +- client/visualizer/src/mapeditor/form.ts | 40 ++++++++++++------ client/visualizer/src/mapeditor/forms/lead.ts | 21 ++-------- client/visualizer/src/mapeditor/mapeditor.ts | 10 ++--- 8 files changed, 96 insertions(+), 52 deletions(-) diff --git a/client/visualizer/src/main/scaffold.ts b/client/visualizer/src/main/scaffold.ts index 842bcb77..767ee3fc 100644 --- a/client/visualizer/src/main/scaffold.ts +++ b/client/visualizer/src/main/scaffold.ts @@ -121,8 +121,8 @@ export default class ScaffoldCommunicator { } // paths are relative for readdir - return cb(null, new Set(files.filter((file) => file.endsWith('.map21')) - .map((file) => file.substring(0, file.length - '.map21'.length)) + return cb(null, new Set(files.filter((file) => file.endsWith('.map22')) + .map((file) => file.substring(0, file.length - '.map22'.length)) .concat(Array.from(SERVER_MAPS.keys())))); }); }); @@ -137,7 +137,7 @@ export default class ScaffoldCommunicator { fs.mkdirSync(dir); } - fs.writeFile(path.join(this.scaffoldPath, 'maps', `${mapName}.map21`), + fs.writeFile(path.join(this.scaffoldPath, 'maps', `${mapName}.map22`), new Buffer(mapData), cb); } diff --git a/client/visualizer/src/main/sidebar.ts b/client/visualizer/src/main/sidebar.ts index e7f63822..d29c28ff 100644 --- a/client/visualizer/src/main/sidebar.ts +++ b/client/visualizer/src/main/sidebar.ts @@ -217,7 +217,7 @@ export default class Sidebar { When you are happy with your map, click "Export". If you are directed to save your map, save it in the /battlecode-scaffold-2021/maps directory of your scaffold. - (Note: the name of your .map21 file must be the same as the name of your + (Note: the name of your .map22 file must be the same as the name of your map.)

Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; diff --git a/client/visualizer/src/mapeditor/action/generator.ts b/client/visualizer/src/mapeditor/action/generator.ts index 00b1f3f4..0e601d60 100644 --- a/client/visualizer/src/mapeditor/action/generator.ts +++ b/client/visualizer/src/mapeditor/action/generator.ts @@ -18,11 +18,14 @@ export type UploadedMap = { width: number, height: number, rubble: number[], + lead: number[], + anomalies: number[], + anomalyRounds: number[], bodies: MapUnit[] } /** - * Generates a .map21 file from a GameMap. Assumes the given GameMap represents + * Generates a .map22 file from a GameMap. Assumes the given GameMap represents * a valid game map. */ export default class MapGenerator { @@ -106,8 +109,10 @@ export default class MapGenerator { // Get header information from form let name: string = map.name; - const minCornerX = Math.random() * 20000 + 10000; - const minCornerY = Math.random() * 20000 + 10000; + // const minCornerX = Math.random() * 20000 + 10000; + // const minCornerY = Math.random() * 20000 + 10000; + const minCornerX = 0; + const minCornerY = 0; let maxCornerX = minCornerX + map.width; let maxCornerY = minCornerY + map.height; let randomSeed: number = Math.round(Math.random() * 1000); @@ -130,6 +135,9 @@ export default class MapGenerator { const bodies = schema.SpawnedBodyTable.endSpawnedBodyTable(builder); const rubble = schema.GameMap.createRubbleVector(builder, map.rubble); + const lead = schema.GameMap.createRubbleVector(builder, map.leadVals); + const anomalies = schema.GameMap.createAnomaliesVector(builder, []); + const anomalyRounds = schema.GameMap.createAnomalyRoundsVector(builder, []); // Create the game map let nameP = builder.createString(name); @@ -137,9 +145,13 @@ export default class MapGenerator { schema.GameMap.addName(builder, nameP); schema.GameMap.addMinCorner(builder, schema.Vec.createVec(builder, minCornerX, minCornerY)); schema.GameMap.addMaxCorner(builder, schema.Vec.createVec(builder, maxCornerX, maxCornerY)); + schema.GameMap.addSymmetry(builder, map.symmetry); schema.GameMap.addBodies(builder, bodies); - schema.GameMap.addRubble(builder, rubble); schema.GameMap.addRandomSeed(builder, randomSeed); + schema.GameMap.addRubble(builder, rubble); + schema.GameMap.addLead(builder, lead); + schema.GameMap.addAnomalies(builder, anomalies); + schema.GameMap.addAnomalyRounds(builder, anomalyRounds); const gameMap = schema.GameMap.endGameMap(builder); // Return the game map to write to a file @@ -173,7 +185,7 @@ export default class MapGenerator { } /** - * Reads a .map21 file. + * Reads a .map22 file. */ static readMap(file: ArrayBuffer): UploadedMap { const data = new Uint8Array(file); @@ -205,6 +217,9 @@ export default class MapGenerator { width: maxCorner.x() - minCorner.x(), height: maxCorner.y() - minCorner.y(), rubble: Array.from(map.rubbleArray()!), + lead: Array.from(map.leadArray()!), + anomalies: Array.from(map.anomaliesArray()!), + anomalyRounds: Array.from(map.anomalyRoundsArray()!), bodies: mapUnits }; } diff --git a/client/visualizer/src/mapeditor/action/renderer.ts b/client/visualizer/src/mapeditor/action/renderer.ts index 7f131aa5..a0241ab7 100644 --- a/client/visualizer/src/mapeditor/action/renderer.ts +++ b/client/visualizer/src/mapeditor/action/renderer.ts @@ -21,7 +21,7 @@ export default class MapRenderer { // Callbacks for clicking robots and trees on the canvas readonly onclickUnit: (id: number) => void; readonly onclickBlank: (x, y) => void; - readonly onMouseover: (x: number, y: number, rubble: number) => void + readonly onMouseover: (x: number, y: number, rubble: number, lead: number) => void readonly onDrag: (x, y) => void // Other useful values @@ -33,7 +33,7 @@ export default class MapRenderer { constructor(canvas: HTMLCanvasElement, imgs: AllImages, conf: config.Config, onclickUnit: (id: number) => void, onclickBlank: (x: number, y: number) => void, - onMouseover: (x: number, y: number, rubble: number) => void, + onMouseover: (x: number, y: number, rubble: number, lead: number) => void, onDrag: (x: number, y: number) => void) { this.canvas = canvas; this.conf = conf; @@ -58,7 +58,6 @@ export default class MapRenderer { * Renders the game map. */ render(map: GameMap): void { - console.log("map:", map); const scale = this.canvas.width / map.width; this.width = map.width; this.height = map.height; @@ -71,6 +70,7 @@ export default class MapRenderer { this.renderBackground(map); this.renderBodies(map); + this.renderResources(map); // restore default rendering } @@ -92,9 +92,8 @@ export default class MapRenderer { for(let i = 0; i < this.width; i++){ for(let j = 0; j < this.height; j++){ const rubble = map.rubble[(map.height-j-1)*this.width + i]; - const lead = map.leadVals[(map.height-j-1)*this.width + i]; this.renderTile(i, j, rubble); - // TODO: draw lead on map + } } } @@ -112,6 +111,37 @@ export default class MapRenderer { this.ctx.restore(); } + private renderResources(map: GameMap) { + this.ctx.save() + this.ctx.globalAlpha = 1 + + const leadImg = this.imgs.resources.lead + + const scale = 1 + + const sigmoid = (x) => { + return 1 / (1 + Math.exp(-x)) + } + + for (let i = 0; i < this. width; i++) for (let j = 0; j < this.height; j++) { + const lead = map.leadVals[(map.height-j-1)*this.width + i]; + + this.ctx.globalAlpha = 1 + const cx = i*scale, cy = j*scale + + if (lead > 0) { + let size = sigmoid(lead / 50) + this.ctx.drawImage(leadImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) + + this.ctx.strokeStyle = '#59727d' + this.ctx.lineWidth = 1 / 30 + this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + } + } + + this.ctx.restore() + } + /** * Draw trees and units on the canvas */ @@ -186,7 +216,7 @@ export default class MapRenderer { this.canvas.onmousemove = (event) => { const {x,y} = this.getIntegerLocation(event, this.map); - this.onMouseover(x, y, this.map.rubble[(y)*this.width + x]); + this.onMouseover(x, y, this.map.rubble[(y)*this.width + x], this.map.leadVals[y*this.width + x]); hoverPos = {x: x, y: y}; }; diff --git a/client/visualizer/src/mapeditor/action/validator.ts b/client/visualizer/src/mapeditor/action/validator.ts index 91c35d8f..41402e4f 100644 --- a/client/visualizer/src/mapeditor/action/validator.ts +++ b/client/visualizer/src/mapeditor/action/validator.ts @@ -4,7 +4,7 @@ import {GameMap, MapUnit} from '../index'; /** * Validates a map created by the map editor. If a map is valid, then the map - * editor is ready to generate the .map21 file. + * editor is ready to generate the .map22 file. * * In a valid map: * - No units overlap diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 30512f93..22257c05 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -140,7 +140,7 @@ export default class MapEditorForm { this.div.appendChild(document.createElement('hr')); this.tileInfo = document.createElement("div"); - this.tileInfo.textContent = "X: | Y: | Rubble:"; + this.tileInfo.textContent = "X: | Y: | Rubble: | Lead:"; this.div.appendChild(this.tileInfo); this.div.appendChild(document.createElement('hr')); @@ -158,11 +158,12 @@ export default class MapEditorForm { this.getActiveForm().setForm(x, y); }; - const onMouseover = (x: number, y: number, rubble: number) => { + const onMouseover = (x: number, y: number, rubble: number, lead: number) => { let content: string = ""; content += 'X: ' + `${x}`.padStart(3); content += ' | Y: ' + `${y}`.padStart(3); content += ' | Rubble: ' + `${rubble.toFixed(3)}`; + content += ' | Lead: ' + `${lead.toFixed(3)}`; this.tileInfo.textContent = content; }; @@ -182,7 +183,7 @@ export default class MapEditorForm { } this.setAreaRubble(x, y, this.tiles.getRubble(), inBrush); this.render(); - } + } } this.renderer = new MapRenderer(canvas, imgs, conf, onclickUnit, onclickBlank, onMouseover, onDrag); @@ -314,6 +315,12 @@ export default class MapEditorForm { this.setUnit(id, unit); form.resetForm(); } + } else if (this.getActiveForm() == this.lead) { + const form: LeadForm = this.lead; + const x = form.getX(); + const y = form.getY(); + const lead = form.getLead(); + this.setLead(x, y, lead); } } @@ -349,7 +356,7 @@ export default class MapEditorForm { if (this.getActiveForm() == this.tiles) { for(let x: number = 0; x < this.header.getWidth(); x++) { for(let y:number = 0; y < this.header.getHeight(); y++) { - this.setRubble(x, y, Math.random() * 0.9 + 0.1); + this.setRubble(x, y, Math.floor(Math.random() * 101)); } } this.render(); @@ -360,7 +367,7 @@ export default class MapEditorForm { if (this.getActiveForm() == this.tiles) { for(let x: number = 0; x < this.header.getWidth(); x++) { for(let y: number = 0; y < this.header.getHeight(); y++) { - this.rubble[y*this.header.getWidth() + x] = 1.1 - this.getRubble(x,y); + this.rubble[y*this.header.getWidth() + x] = 100 - this.getRubble(x,y); } } this.render(); @@ -451,14 +458,6 @@ export default class MapEditorForm { this.rubble.fill(50); } - /** - * Initialize lead based on map dimensions. - */ - private initLead() { - this.leadVals = new Array(this.header.getHeight() * this.header.getWidth()); - this.leadVals.fill(0); - } - private getRubble(x: number, y: number) { return this.rubble[y*this.header.getWidth() + x]; } @@ -482,6 +481,20 @@ export default class MapEditorForm { } } + /** + * Initialize lead based on map dimensions. + */ + private initLead() { + this.leadVals = new Array(this.header.getHeight() * this.header.getWidth()); + this.leadVals.fill(0); + } + + private setLead(x: number, y: number, lead: number) { + const {x: translated_x, y: translated_y} = this.symmetry.transformLoc(x, y, this.header.getWidth(), this.header.getHeight()); + this.leadVals[y*this.header.getWidth() + x] = this.leadVals[translated_y*this.header.getWidth() + translated_x] = lead; + this.render(); + } + /** * @return the active form based on which radio button is selected */ @@ -574,6 +587,7 @@ export default class MapEditorForm { this.symmetricBodies = this.symmetry.getSymmetricBodies(this.originalBodies, map.width, map.height); this.rubble = map.rubble; + this.leadVals = map.lead; this.render(); } diff --git a/client/visualizer/src/mapeditor/forms/lead.ts b/client/visualizer/src/mapeditor/forms/lead.ts index 13f76eb1..18c618a5 100644 --- a/client/visualizer/src/mapeditor/forms/lead.ts +++ b/client/visualizer/src/mapeditor/forms/lead.ts @@ -102,32 +102,17 @@ export default class RobotForm { this.y.value = isNaN(value) ? "" : String(value); }; - // this.influence.onchange = () => { - // let value: number = this.getInfluence(); - // value = Math.max(value, 50); - // value = Math.min(value, 500); - // this.influence.value = isNaN(value) ? "" : String(value); - // } - - // this.team.onchange = () => { - // if (this.getTeam() !== 0) { - // this.influence.disabled = true; - // this.influence.value = String(cst.INITIAL_INFLUENCE); - // } - // else this.influence.disabled = false; - // } - } - private getLead(): number { + getLead(): number { return parseInt(this.lead.value); } - private getX(): number { + getX(): number { return parseInt(this.x.value); } - private getY(): number { + getY(): number { return parseInt(this.y.value); } diff --git a/client/visualizer/src/mapeditor/mapeditor.ts b/client/visualizer/src/mapeditor/mapeditor.ts index 248f9841..5f3c91f1 100644 --- a/client/visualizer/src/mapeditor/mapeditor.ts +++ b/client/visualizer/src/mapeditor/mapeditor.ts @@ -11,7 +11,7 @@ import {MapUnit, MapValidator, MapGenerator, MapEditorForm, GameMap, UploadedMap import { env } from 'process'; /** - * Allows the user to download a .map21 file representing the map generated + * Allows the user to download a .map22 file representing the map generated * in the map editor. */ export default class MapEditor { @@ -90,7 +90,7 @@ export default class MapEditor { When you are happy with your map, click "Export". If you are directed to save your map, save it in the /battlecode-scaffold-2021/maps directory of your scaffold. - (Note: the name of your .map21 file must be the same as the name of your + (Note: the name of your .map22 file must be the same as the name of your map.)

Exported file name must be the same as the map name chosen above. For instance, DefaultMap.bc22.`; @@ -214,14 +214,14 @@ export default class MapEditor { let uploadLabel = document.createElement("label"); uploadLabel.setAttribute("for", "file-upload"); uploadLabel.setAttribute("class", "custom-button"); - uploadLabel.innerText = 'Upload a .map21 file'; + uploadLabel.innerText = 'Upload a .map22 file'; uploadLabel.style.backgroundColor = "mediumslateblue"; // TODO: move to CSS // create the functional button let upload = document.createElement('input'); upload.textContent = 'upload'; upload.id = "file-upload"; upload.setAttribute('type', 'file'); - upload.accept = '.map21'; + upload.accept = '.map22'; upload.onchange = () => { if (upload.files) { const reader = new FileReader(); @@ -263,7 +263,7 @@ export default class MapEditor { } }); } else { - MapGenerator.exportFile(data, `${name}.map21`); + MapGenerator.exportFile(data, `${name}.map22`); } } } From 701c00049175d615f2138af56449137119528a11 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 16:00:32 -0500 Subject: [PATCH 268/413] Add increase period to fake match files --- client/playback/src/gen/create.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/playback/src/gen/create.ts b/client/playback/src/gen/create.ts index 661174d4..fffe3dd7 100644 --- a/client/playback/src/gen/create.ts +++ b/client/playback/src/gen/create.ts @@ -4,6 +4,7 @@ import {createWriteStream} from 'fs'; import {gzip} from 'pako'; import { isNull } from 'util'; import { Signer } from 'crypto'; +import { constants } from 'buffer'; let SIZE = 32; const maxID = 4096; @@ -243,11 +244,17 @@ function createGameHeader(builder: flatbuffers.Builder): flatbuffers.Offset { const version = builder.createString('IMAGINARY VERSION!!!'); const bodiesPacked = schema.GameHeader.createBodyTypeMetadataVector(builder, bodies); const teamsPacked = schema.GameHeader.createTeamsVector(builder, teams); + + schema.Constants.startConstants(builder); + schema.Constants.addIncreasePeriod(builder, 20); + schema.Constants.addLeadAdditiveIncease(builder, 5); + const constants = schema.Constants.endConstants(builder); schema.GameHeader.startGameHeader(builder); schema.GameHeader.addSpecVersion(builder, version); schema.GameHeader.addBodyTypeMetadata(builder, bodiesPacked); schema.GameHeader.addTeams(builder, teamsPacked); + schema.GameHeader.addConstants(builder, constants); return schema.GameHeader.endGameHeader(builder); } From bf2df8b446ae70c08dfdee6d4ef78f4c4aa90acf Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 20:16:34 -0500 Subject: [PATCH 269/413] Don't error on global anomalies --- client/playback/src/gameworld.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 9b7114ab..54392162 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -436,8 +436,8 @@ export default class GameWorld { const action = delta.actions(i); const robotID = delta.actionIDs(i); const target = delta.actionTargets(i); - const body = this.bodies.lookup(robotID); - const teamStatsObj: TeamStats = this.teamStats.get(body.team); + const body = robotID != -1 ? this.bodies.lookup(robotID) : null; + const teamStatsObj = body != null ? this.teamStats.get(body.team) : null; const setAction = () => { this.bodies.alter({id: robotID, action: action as number}); this.actionRobots.push(robotID); @@ -510,10 +510,10 @@ export default class GameWorld { break; default: - console.log(`Undefined action: action(${action}), robotID(${robotID}, target(${target}))`); + //console.log(`Undefined action: action(${action}), robotID(${robotID}, target(${target}))`); break; } - this.teamStats.set(body.team, teamStatsObj); // TODO: is this necessary + if (body) this.teamStats.set(body.team, teamStatsObj); } } From a94a52e40359bbe32eda833ae90087c5111bf27c Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 21:02:15 -0500 Subject: [PATCH 270/413] Map editor anomaly start --- client/visualizer/src/mapeditor/form.ts | 15 +- .../src/mapeditor/forms/anomalies.ts | 215 ++++++++++++++++++ 2 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 client/visualizer/src/mapeditor/forms/anomalies.ts diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 22257c05..ecd0b696 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -25,7 +25,9 @@ export type GameMap = { symmetricBodies: Map, rubble: number[], leadVals: number[], - symmetry: number + symmetry: number, + anomalies: [], + anomalyRounds: [] }; /** @@ -47,6 +49,7 @@ export default class MapEditorForm { private readonly robots: RobotForm; private readonly tiles: TileForm; private readonly lead: LeadForm; + private readonly anomalies: AnomalyForm; private robotsRadio: HTMLInputElement; private tilesRadio: HTMLInputElement; @@ -218,7 +221,7 @@ export default class MapEditorForm { }; const tilesLabel = document.createElement("label"); tilesLabel.setAttribute("for", this.tilesRadio.id); - tilesLabel.textContent = "Place Rubble"; + tilesLabel.textContent = "Rubble"; // Radio button for placing units this.robotsRadio.id = "robots-radio"; @@ -239,7 +242,7 @@ export default class MapEditorForm { }; const robotsLabel = document.createElement("label"); robotsLabel.setAttribute("for", this.robotsRadio.id); - robotsLabel.textContent = "Place Robots"; + robotsLabel.textContent = "Robots"; // Radio button for placing lead this.leadRadio.id = "lead-radio"; @@ -261,7 +264,7 @@ export default class MapEditorForm { const leadLabel = document.createElement("label"); leadLabel.setAttribute("for", this.leadRadio.id); - leadLabel.textContent = "Place Lead"; + leadLabel.textContent = "Lead"; // Add radio buttons HTML element div.appendChild(this.tilesRadio); @@ -527,7 +530,9 @@ export default class MapEditorForm { symmetricBodies: this.symmetricBodies, rubble: this.rubble, leadVals: this.leadVals, - symmetry: this.symmetry.getSymmetry() + symmetry: this.symmetry.getSymmetry(), + anomalies: [], + anomalyRounds: [] }; } diff --git a/client/visualizer/src/mapeditor/forms/anomalies.ts b/client/visualizer/src/mapeditor/forms/anomalies.ts new file mode 100644 index 00000000..4755e546 --- /dev/null +++ b/client/visualizer/src/mapeditor/forms/anomalies.ts @@ -0,0 +1,215 @@ +import * as cst from '../../constants'; + +import {schema} from 'battlecode-playback'; + +import {MapUnit} from '../index'; + +export default class RobotForm { + + // The public div + readonly div: HTMLDivElement; + + // Form elements for archon settings + readonly id: HTMLLabelElement; + readonly type: HTMLSelectElement; + readonly team: HTMLSelectElement; + readonly x: HTMLInputElement; + readonly y: HTMLInputElement; + //readonly influence: HTMLInputElement; + + // Callbacks on input change + readonly width: () => number; + readonly height: () => number; + + // Constant + private readonly ROBOT_TYPES: schema.BodyType[] = cst.initialBodyTypeList; + + private readonly TEAMS = { + "0": "Neutral", + "1": "Red", + "2": "Blue" + }; + + constructor(width: () => number, height: () => number) { + + // Store the callbacks + this.width = width; + this.height = height; + + // Create HTML elements + this.div = document.createElement("div"); + this.id = document.createElement("label"); + this.type = document.createElement("select"); + this.team = document.createElement("select"); + this.x = document.createElement("input"); + this.y = document.createElement("input"); + // this.influence = document.createElement("input"); + // this.influence.value = String(cst.INITIAL_INFLUENCE); + // this.influence.disabled = true; + + // Create the form + this.loadInputs(); + this.div.appendChild(this.createForm()); + this.loadCallbacks(); + } + + /** + * Initializes input fields. + */ + private loadInputs(): void { + this.x.type = "text"; + this.y.type = "text"; + this.type.disabled = true; + this.ROBOT_TYPES.forEach((type: schema.BodyType) => { + const option = document.createElement("option"); + option.value = String(type); + option.appendChild(document.createTextNode(cst.bodyTypeToString(type))); + this.type.appendChild(option); + }); + for (let team in this.TEAMS) { + const option = document.createElement("option"); + option.value = String(team); + option.appendChild(document.createTextNode(this.TEAMS[team])); + this.team.appendChild(option); + if (this.TEAMS[team] === "Red") { + option.selected = true; + } + } + } + + /** + * Creates the HTML form that collects archon information. + */ + private createForm(): HTMLFormElement { + // HTML structure + const form: HTMLFormElement = document.createElement("form"); + const id: HTMLDivElement = document.createElement("div"); + const type: HTMLDivElement = document.createElement("div"); + const team: HTMLDivElement = document.createElement("div"); + const x: HTMLDivElement = document.createElement("div"); + const y: HTMLDivElement = document.createElement("div"); + // const influence: HTMLDivElement = document.createElement("div"); + //form.appendChild(id); + form.appendChild(type); + form.appendChild(team); + form.appendChild(x); + form.appendChild(y); + // form.appendChild(influence); + form.appendChild(document.createElement("br")); + + id.appendChild(document.createTextNode("ID: ")); + id.appendChild(this.id); + + // Robot type + type.appendChild(document.createTextNode("Type: ")); + type.appendChild(this.type); + + // Team + team.appendChild(document.createTextNode("Team: ")); + team.appendChild(this.team); + + // X coordinate + x.appendChild(document.createTextNode("X: ")); + x.appendChild(this.x); + + // Y coordinate + y.appendChild(document.createTextNode("Y: ")); + y.appendChild(this.y); + + // Influence + // influence.appendChild(document.createTextNode("I: ")); + // influence.appendChild(this.influence); + + return form; + } + + /** + * Add callbacks to the form elements. + */ + private loadCallbacks(): void { + + // X must be in the range [0, this.width] + this.x.onchange = () => { + let value: number = this.getX(); + value = Math.max(value, 0); + value = Math.min(value, this.width()); + this.x.value = isNaN(value) ? "" : String(value); + }; + + // Y must be in the range [0, this.height] + this.y.onchange = () => { + let value: number = this.getY(); + value = Math.max(value, 0); + value = Math.min(value, this.height()); + this.y.value = isNaN(value) ? "" : String(value); + }; + + // this.influence.onchange = () => { + // let value: number = this.getInfluence(); + // value = Math.max(value, 50); + // value = Math.min(value, 500); + // this.influence.value = isNaN(value) ? "" : String(value); + // } + + // this.team.onchange = () => { + // if (this.getTeam() !== 0) { + // this.influence.disabled = true; + // this.influence.value = String(cst.INITIAL_INFLUENCE); + // } + // else this.influence.disabled = false; + // } + + } + + + private getType(): schema.BodyType { + return parseInt(this.type.options[this.type.selectedIndex].value); + } + + private getTeam(): number { + return parseInt(this.team.options[this.team.selectedIndex].value); + } + + private getX(): number { + return parseInt(this.x.value); + } + + private getY(): number { + return parseInt(this.y.value); + } + + // private getInfluence(): number { + // return parseInt(this.influence.value); + // } + + getID(): number | undefined { + const id = parseInt(this.id.textContent || "NaN"); + return isNaN(id) ? undefined : id; + } + + resetForm(): void { + this.x.value = ""; + this.y.value = ""; + } + + isValid(): boolean { + const x = this.getX(); + const y = this.getY(); + //const I = this.getInfluence(); + return !(isNaN(x) || isNaN(y)); // || isNaN(I)); + } + + getUnit(id: number): MapUnit | undefined { + if (!this.isValid()) { + return undefined; + } + return { + x: this.getX(), + y: this.getY(), + radius: 0.5, + type: this.getType(), + teamID: this.getTeam() + // influence: this.getInfluence() + } + } +} From 1bf428c63db30d6dc11f12c32babaf1cd5fcff36 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 21:27:50 -0500 Subject: [PATCH 271/413] Handle vortex --- client/playback/src/gameworld.ts | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 54392162..27f379ce 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -509,6 +509,54 @@ export default class GameWorld { console.log(`Exception occured: robotID(${robotID}), target(${target}`); break; + case schema.Action.VORTEX: + console.log("vortex"); + let w = this.mapStats.maxCorner.x - this.mapStats.minCorner.x; + let h = this.mapStats.maxCorner.y - this.mapStats.minCorner.y; + switch (target) { + case 0: + for (let x = 0; x < w / 2; x++) { + for (let y = 0; y < (w + 1) / 2; y++) { + let curX = x; + let curY = y; + let lastRubble = this.mapStats.rubble[curX + curY * w]; + for (let i = 0; i < 4; i++) { + let tempX = curX; + curX = curY; + curY = (w - 1) - tempX; + let idx = curX + curY * w; + let tempRubble = this.mapStats.rubble[idx]; + this.mapStats.rubble[idx] = lastRubble; + lastRubble = tempRubble; + } + } + } + case 1: + for (let x = 0; x < w / 2; x++) { + for (let y = 0; y < h; y++) { + let idx = x + y * w; + let newX = w - 1 - x; + let newIdx = newX + y * w; + let prevRubble = this.mapStats.rubble[idx]; + this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx]; + this.mapStats.rubble[newIdx] = prevRubble; + } + } + break; + case 2: + for (let y = 0; y < h / 2; y++) { + for (let x = 0; x < w; x++) { + let idx = x + y * w; + let newY = h - 1 - y; + let newIdx = x + newY * w; + let prevRubble = this.mapStats.rubble[idx]; + this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx]; + this.mapStats.rubble[newIdx] = prevRubble; + } + } + break; + } + default: //console.log(`Undefined action: action(${action}), robotID(${robotID}, target(${target}))`); break; From a2bd82da331fdf1f6efd5fda3f393abe8a646a8a Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 22:52:00 -0500 Subject: [PATCH 272/413] tmp --- client/visualizer/src/mapeditor/form.ts | 3 +-- .../src/mapeditor/forms/anomalies.ts | 21 ++----------------- client/visualizer/src/mapeditor/index.ts | 3 ++- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index ecd0b696..566fc754 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -5,8 +5,7 @@ import {cow_border as cow} from '../cow'; import {schema, flatbuffers} from 'battlecode-playback'; -import {MapRenderer, HeaderForm, SymmetryForm, RobotForm, TileForm, LeadForm, UploadedMap} from './index'; -import { SSL_OP_NO_QUERY_MTU } from 'constants'; +import {MapRenderer, HeaderForm, SymmetryForm, RobotForm, TileForm, LeadForm, AnomalyForm, UploadedMap} from './index'; export type MapUnit = { x: number, diff --git a/client/visualizer/src/mapeditor/forms/anomalies.ts b/client/visualizer/src/mapeditor/forms/anomalies.ts index 4755e546..1f576e5a 100644 --- a/client/visualizer/src/mapeditor/forms/anomalies.ts +++ b/client/visualizer/src/mapeditor/forms/anomalies.ts @@ -4,7 +4,7 @@ import {schema} from 'battlecode-playback'; import {MapUnit} from '../index'; -export default class RobotForm { +export default class AnomalyForm { // The public div readonly div: HTMLDivElement; @@ -17,24 +17,7 @@ export default class RobotForm { readonly y: HTMLInputElement; //readonly influence: HTMLInputElement; - // Callbacks on input change - readonly width: () => number; - readonly height: () => number; - - // Constant - private readonly ROBOT_TYPES: schema.BodyType[] = cst.initialBodyTypeList; - - private readonly TEAMS = { - "0": "Neutral", - "1": "Red", - "2": "Blue" - }; - - constructor(width: () => number, height: () => number) { - - // Store the callbacks - this.width = width; - this.height = height; + constructor() { // Create HTML elements this.div = document.createElement("div"); diff --git a/client/visualizer/src/mapeditor/index.ts b/client/visualizer/src/mapeditor/index.ts index bf9936da..96c17936 100644 --- a/client/visualizer/src/mapeditor/index.ts +++ b/client/visualizer/src/mapeditor/index.ts @@ -9,11 +9,12 @@ import RobotForm from './forms/robots'; import SymmetryForm, {Symmetry} from './forms/symmetry'; import TileForm from './forms/tiles'; import LeadForm from './forms/lead'; +import AnomalyForm from './forms/anomalies'; import {GameMap} from './form'; import MapEditorForm from './form'; import MapEditor from './mapeditor'; export {MapGenerator, MapUnit, MapRenderer, MapValidator, UploadedMap} -export {HeaderForm, RobotForm, Symmetry, SymmetryForm, TileForm, LeadForm} +export {HeaderForm, RobotForm, Symmetry, SymmetryForm, TileForm, LeadForm, AnomalyForm} export {GameMap, MapEditorForm, MapEditor}; From c316532b4aaa8cddd64037ae579a6ae24f8b0ead Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sat, 1 Jan 2022 22:52:17 -0500 Subject: [PATCH 273/413] Fix typo --- client/playback/src/gameworld.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 27f379ce..d7b2e717 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -531,6 +531,7 @@ export default class GameWorld { } } } + break; case 1: for (let x = 0; x < w / 2; x++) { for (let y = 0; y < h; y++) { From 916f7b7dcb66a622144f505c5156505d574809b3 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 11:27:37 -0500 Subject: [PATCH 274/413] Anomaly scheduling in map editor (no deletion yet) --- client/visualizer/src/constants.ts | 15 ++ .../src/mapeditor/action/generator.ts | 4 +- client/visualizer/src/mapeditor/form.ts | 169 +++++++++++------- .../src/mapeditor/forms/anomalies.ts | 159 ++++------------ .../visualizer/src/mapeditor/forms/header.ts | 2 +- 5 files changed, 153 insertions(+), 196 deletions(-) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 776649ce..42d5dd68 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -12,6 +12,7 @@ export const WATCHTOWER = schema.BodyType.WATCHTOWER export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER] export const initialBodyTypeList: number[] = [ARCHON] +export const anomalyList = [schema.Action.VORTEX, schema.Action.FURY, schema.Action.CHARGE, schema.Action.ABYSS] export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots @@ -209,6 +210,20 @@ export function symmetryToString(symmetry: Symmetry) { } } +export function anomalyToString(anomaly: schema.Action) { + switch (anomaly) { + case schema.Action.VORTEX: + return "vortex" + case schema.Action.FURY: + return "fury" + case schema.Action.ABYSS: + return "abyss" + case schema.Action.CHARGE: + return "charge" + default: throw new Error("invalid anomaly") + } +} + export function abilityToEffectString(effect: number): string | null { switch (effect) { case 1: diff --git a/client/visualizer/src/mapeditor/action/generator.ts b/client/visualizer/src/mapeditor/action/generator.ts index 0e601d60..a92a489a 100644 --- a/client/visualizer/src/mapeditor/action/generator.ts +++ b/client/visualizer/src/mapeditor/action/generator.ts @@ -136,8 +136,8 @@ export default class MapGenerator { const rubble = schema.GameMap.createRubbleVector(builder, map.rubble); const lead = schema.GameMap.createRubbleVector(builder, map.leadVals); - const anomalies = schema.GameMap.createAnomaliesVector(builder, []); - const anomalyRounds = schema.GameMap.createAnomalyRoundsVector(builder, []); + const anomalies = schema.GameMap.createAnomaliesVector(builder, map.anomalies); + const anomalyRounds = schema.GameMap.createAnomalyRoundsVector(builder, map.anomalyRounds); // Create the game map let nameP = builder.createString(name); diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 566fc754..3f4fbe46 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -25,8 +25,8 @@ export type GameMap = { rubble: number[], leadVals: number[], symmetry: number, - anomalies: [], - anomalyRounds: [] + anomalies: number[], + anomalyRounds: number[] }; /** @@ -43,16 +43,17 @@ export default class MapEditorForm { private readonly renderer: MapRenderer; // Forms and text display - private readonly header: HeaderForm; - private readonly symmetry: SymmetryForm; - private readonly robots: RobotForm; - private readonly tiles: TileForm; - private readonly lead: LeadForm; - private readonly anomalies: AnomalyForm; + private readonly headerForm: HeaderForm; + private readonly symmetryForm: SymmetryForm; + private readonly robotsForm: RobotForm; + private readonly tilesForm: TileForm; + private readonly leadForm: LeadForm; + private readonly anomaliesForm: AnomalyForm; private robotsRadio: HTMLInputElement; private tilesRadio: HTMLInputElement; private leadRadio: HTMLInputElement; + private anomaliesRadio: HTMLInputElement; private forms: HTMLDivElement; @@ -73,6 +74,8 @@ export default class MapEditorForm { private symmetricBodies: Map; private rubble: number[]; private leadVals: number[]; + private anomalies: number[] = []; + private anomalyRounds: number[] = []; randomMode: boolean = false; // if true, all squares are randomly painted. randomHigh: number = 1; @@ -94,20 +97,20 @@ export default class MapEditorForm { this.div = document.createElement("div"); // callback functions for getting constants - const cbWidth = () => {return this.header.getWidth()}; - const cbHeight = () => {return this.header.getHeight()}; + const cbWidth = () => {return this.headerForm.getWidth()}; + const cbHeight = () => {return this.headerForm.getHeight()}; // header (name, width, height) - this.header = new HeaderForm(() => { + this.headerForm = new HeaderForm(() => { this.reset(); this.render(); }); - this.div.appendChild(this.header.div); + this.div.appendChild(this.headerForm.div); // symmetry - this.symmetry = new SymmetryForm(() => {this.initRubble(); this.initLead(); this.render()}); + this.symmetryForm = new SymmetryForm(() => {this.initRubble(); this.initLead(); this.render()}); this.div.appendChild(document.createElement("br")); - this.div.appendChild(this.symmetry.div); + this.div.appendChild(this.symmetryForm.div); this.div.appendChild(document.createElement("br")); this.div.appendChild(document.createElement("hr")); @@ -115,14 +118,16 @@ export default class MapEditorForm { this.tilesRadio = document.createElement("input"); this.robotsRadio = document.createElement("input"); this.leadRadio = document.createElement("input"); + this.anomaliesRadio = document.createElement("input"); this.div.appendChild(this.createUnitOption()); this.div.appendChild(document.createElement("br")); // robot delete + add/update buttons this.forms = document.createElement("div"); - this.robots = new RobotForm(cbWidth, cbHeight); // robot info (type, x, y, ...) - this.tiles = new TileForm(cbWidth, cbHeight); - this.lead = new LeadForm(cbWidth, cbHeight); + this.robotsForm = new RobotForm(cbWidth, cbHeight); // robot info (type, x, y, ...) + this.tilesForm = new TileForm(cbWidth, cbHeight); + this.leadForm = new LeadForm(cbWidth, cbHeight); + this.anomaliesForm = new AnomalyForm(); this.buttonDelete = document.createElement("button"); this.buttonAdd = document.createElement("button"); this.buttonReverse = document.createElement("button"); @@ -148,11 +153,11 @@ export default class MapEditorForm { // Renderer settings const onclickUnit = (id: number) => { - if (this.originalBodies.has(id) && this.getActiveForm() == this.robots) { + if (this.originalBodies.has(id) && this.getActiveForm() == this.robotsForm) { // Set the corresponding form appropriately let body: MapUnit = this.originalBodies.get(id)!; this.robotsRadio.click(); - this.robots.setForm(body.x, body.y, body, id); + this.robotsForm.setForm(body.x, body.y, body, id); } }; @@ -170,10 +175,10 @@ export default class MapEditorForm { }; const onDrag = (x, y) => { - if (this.getActiveForm() === this.tiles && this.tiles.isValid()) { - let r: number = this.tiles.getBrush(); + if (this.getActiveForm() === this.tilesForm && this.tilesForm.isValid()) { + let r: number = this.tilesForm.getBrush(); let inBrush: (dx, dy) => boolean = () => true; - switch (this.tiles.getStyle()) { + switch (this.tilesForm.getStyle()) { case "Circle": inBrush = (dx, dy) => dx*dx + dy*dy < r*r; break; @@ -183,7 +188,7 @@ export default class MapEditorForm { case "Cow": inBrush = (dx,dy) => (Math.abs(dx) < r && Math.abs(dy) < r && cow[Math.floor(20*(1+dx/r))][Math.floor(20*(1-dy/r))]); } - this.setAreaRubble(x, y, this.tiles.getRubble(), inBrush); + this.setAreaRubble(x, y, this.tilesForm.getRubble(), inBrush); this.render(); } } @@ -210,7 +215,7 @@ export default class MapEditorForm { // Change the displayed form if (this.tilesRadio.checked) { while (this.forms.firstChild) this.forms.removeChild(this.forms.firstChild); - this.forms.appendChild(this.tiles.div); + this.forms.appendChild(this.tilesForm.div); this.buttonDelete.style.display = "none"; this.buttonAdd.style.display = "none"; this.buttonReverse.style.display = "none"; @@ -231,7 +236,7 @@ export default class MapEditorForm { // Change the displayed form if (this.robotsRadio.checked) { while (this.forms.firstChild) this.forms.removeChild(this.forms.firstChild); - this.forms.appendChild(this.robots.div); + this.forms.appendChild(this.robotsForm.div); this.buttonDelete.style.display = ""; this.buttonAdd.style.display = ""; this.buttonReverse.style.display = ""; @@ -252,7 +257,7 @@ export default class MapEditorForm { // Change the displayed form if (this.leadRadio.checked) { while (this.forms.firstChild) this.forms.removeChild(this.forms.firstChild); - this.forms.appendChild(this.lead.div); + this.forms.appendChild(this.leadForm.div); this.buttonDelete.style.display = ""; this.buttonAdd.style.display = ""; this.buttonReverse.style.display = "none"; @@ -265,6 +270,28 @@ export default class MapEditorForm { leadLabel.setAttribute("for", this.leadRadio.id); leadLabel.textContent = "Lead"; + // Radio button for anomalies + this.anomaliesRadio.id = "anomalies-radio"; + this.anomaliesRadio.type = "radio"; + this.anomaliesRadio.name = "edit-option"; + + this.anomaliesRadio.onchange = () => { + // Change the displayed form + if (this.anomaliesRadio.checked) { + while (this.forms.firstChild) this.forms.removeChild(this.forms.firstChild); + this.forms.appendChild(this.anomaliesForm.div); + this.buttonDelete.style.display = ""; + this.buttonAdd.style.display = ""; + this.buttonReverse.style.display = "none"; + this.buttonRandomize.style.display = "none"; + this.buttonInvert.style.display = "none"; + } + }; + + const anomaliesLabel = document.createElement("label"); + anomaliesLabel.setAttribute("for", this.anomaliesRadio.id); + anomaliesLabel.textContent = "Anomalies"; + // Add radio buttons HTML element div.appendChild(this.tilesRadio); div.appendChild(tilesLabel); @@ -272,6 +299,8 @@ export default class MapEditorForm { div.appendChild(robotsLabel); div.appendChild(this.leadRadio); div.appendChild(leadLabel); + div.appendChild(this.anomaliesRadio); + div.appendChild(anomaliesLabel); div.appendChild(document.createElement("br")); return div; @@ -308,8 +337,8 @@ export default class MapEditorForm { private loadCallbacks() { this.buttonAdd.onclick = () => { - if (this.getActiveForm() == this.robots) { - const form: RobotForm = this.robots; + if (this.getActiveForm() == this.robotsForm) { + const form: RobotForm = this.robotsForm; const id: number = form.getID() || this.lastID; const unit: MapUnit | undefined = form.getUnit(id); if (unit) { @@ -317,18 +346,24 @@ export default class MapEditorForm { this.setUnit(id, unit); form.resetForm(); } - } else if (this.getActiveForm() == this.lead) { - const form: LeadForm = this.lead; + } else if (this.getActiveForm() == this.leadForm) { + const form: LeadForm = this.leadForm; const x = form.getX(); const y = form.getY(); const lead = form.getLead(); this.setLead(x, y, lead); + } else if (this.getActiveForm() == this.anomaliesForm) { + const form: AnomalyForm = this.anomaliesForm; + const anomaly = form.getAnomaly(); + const round = form.getRound(); + this.anomalies.push(anomaly); + this.anomalyRounds.push(round); } } this.buttonDelete.onclick = () => { - if (this.getActiveForm() == this.robots) { - const id: number | undefined = this.robots.getID(); + if (this.getActiveForm() == this.robotsForm) { + const id: number | undefined = this.robotsForm.getID(); if (id && !isNaN(id)) { this.deleteUnit(id); this.getActiveForm().resetForm(); @@ -337,8 +372,8 @@ export default class MapEditorForm { } this.buttonReverse.onclick = () => { - if (this.getActiveForm() == this.robots) { - const form: RobotForm = this.robots; + if (this.getActiveForm() == this.robotsForm) { + const form: RobotForm = this.robotsForm; const id: number = form.getID() || this.lastID - 1; const unit: MapUnit = this.originalBodies.get(id)!; if (unit) { @@ -355,9 +390,9 @@ export default class MapEditorForm { } this.buttonRandomize.onclick = () => { - if (this.getActiveForm() == this.tiles) { - for(let x: number = 0; x < this.header.getWidth(); x++) { - for(let y:number = 0; y < this.header.getHeight(); y++) { + if (this.getActiveForm() == this.tilesForm) { + for(let x: number = 0; x < this.headerForm.getWidth(); x++) { + for(let y:number = 0; y < this.headerForm.getHeight(); y++) { this.setRubble(x, y, Math.floor(Math.random() * 101)); } } @@ -366,10 +401,10 @@ export default class MapEditorForm { } this.buttonInvert.onclick = () => { - if (this.getActiveForm() == this.tiles) { - for(let x: number = 0; x < this.header.getWidth(); x++) { - for(let y: number = 0; y < this.header.getHeight(); y++) { - this.rubble[y*this.header.getWidth() + x] = 100 - this.getRubble(x,y); + if (this.getActiveForm() == this.tilesForm) { + for(let x: number = 0; x < this.headerForm.getWidth(); x++) { + for(let y: number = 0; y < this.headerForm.getHeight(); y++) { + this.rubble[y*this.headerForm.getWidth() + x] = 100 - this.getRubble(x,y); } } this.render(); @@ -456,23 +491,23 @@ export default class MapEditorForm { * Initialize rubble array based on map dimensions. */ private initRubble() { - this.rubble = new Array(this.header.getHeight() * this.header.getWidth()); + this.rubble = new Array(this.headerForm.getHeight() * this.headerForm.getWidth()); this.rubble.fill(50); } private getRubble(x: number, y: number) { - return this.rubble[y*this.header.getWidth() + x]; + return this.rubble[y*this.headerForm.getWidth() + x]; } private setRubble(x: number, y: number, rubble: number) { if (this.randomMode) rubble = this.randomLow + (this.randomHigh - this.randomLow) * Math.random(); - const {x: translated_x, y: translated_y} = this.symmetry.transformLoc(x, y, this.header.getWidth(), this.header.getHeight()); - this.rubble[y*this.header.getWidth() + x] = this.rubble[translated_y*this.header.getWidth() + translated_x] = rubble; + const {x: translated_x, y: translated_y} = this.symmetryForm.transformLoc(x, y, this.headerForm.getWidth(), this.headerForm.getHeight()); + this.rubble[y*this.headerForm.getWidth() + x] = this.rubble[translated_y*this.headerForm.getWidth() + translated_x] = rubble; } private setAreaRubble(x0: number, y0: number, pass: number, inBrush: (dx, dy) => boolean) { - const width = this.header.getWidth(); - const height = this.header.getHeight(); + const width = this.headerForm.getWidth(); + const height = this.headerForm.getHeight(); for (let x = 0; x < width; x++) { for (let y = 0; y < height; y++) { @@ -487,33 +522,33 @@ export default class MapEditorForm { * Initialize lead based on map dimensions. */ private initLead() { - this.leadVals = new Array(this.header.getHeight() * this.header.getWidth()); + this.leadVals = new Array(this.headerForm.getHeight() * this.headerForm.getWidth()); this.leadVals.fill(0); } private setLead(x: number, y: number, lead: number) { - const {x: translated_x, y: translated_y} = this.symmetry.transformLoc(x, y, this.header.getWidth(), this.header.getHeight()); - this.leadVals[y*this.header.getWidth() + x] = this.leadVals[translated_y*this.header.getWidth() + translated_x] = lead; + const {x: translated_x, y: translated_y} = this.symmetryForm.transformLoc(x, y, this.headerForm.getWidth(), this.headerForm.getHeight()); + this.leadVals[y*this.headerForm.getWidth() + x] = this.leadVals[translated_y*this.headerForm.getWidth() + translated_x] = lead; this.render(); } /** * @return the active form based on which radio button is selected */ - private getActiveForm(): RobotForm | TileForm | LeadForm { - return (this.tilesRadio.checked ? this.tiles : (this.robotsRadio.checked ? this.robots : this.lead)) + private getActiveForm(): RobotForm | TileForm | LeadForm | AnomalyForm { + return (this.tilesRadio.checked ? this.tilesForm : (this.robotsRadio.checked ? this.robotsForm : (this.leadRadio.checked ? this.leadForm : this.anomaliesForm))) } /** * Re-renders the canvas based on the parameters of the map editor. */ render() { - const width: number = this.header.getWidth(); - const height: number = this.header.getHeight(); + const width: number = this.headerForm.getWidth(); + const height: number = this.headerForm.getHeight(); const scale: number = this.conf.upscale / Math.sqrt(width * height); // arbitrary scaling factor this.canvas.width = width * scale; this.canvas.height = height * scale; - this.symmetricBodies = this.symmetry.getSymmetricBodies(this.originalBodies, width, height); + this.symmetricBodies = this.symmetryForm.getSymmetricBodies(this.originalBodies, width, height); this.renderer.render(this.getMap()); } @@ -522,16 +557,16 @@ export default class MapEditorForm { */ getMap(): GameMap { return { - name: this.header.getName(), - width: this.header.getWidth(), - height: this.header.getHeight(), + name: this.headerForm.getName(), + width: this.headerForm.getWidth(), + height: this.headerForm.getHeight(), originalBodies: this.originalBodies, symmetricBodies: this.symmetricBodies, rubble: this.rubble, leadVals: this.leadVals, - symmetry: this.symmetry.getSymmetry(), - anomalies: [], - anomalyRounds: [] + symmetry: this.symmetryForm.getSymmetry(), + anomalies: this.anomalies, + anomalyRounds: this.anomalyRounds }; } @@ -577,18 +612,18 @@ export default class MapEditorForm { // TODO: types setUploadedMap(map: UploadedMap) { - const symmetryAndBodies = this.symmetry.discoverSymmetryAndBodies(map.bodies, map.rubble, map.width, map.height); + const symmetryAndBodies = this.symmetryForm.discoverSymmetryAndBodies(map.bodies, map.rubble, map.width, map.height); console.log(symmetryAndBodies); if (symmetryAndBodies === null) return; this.reset(); - this.header.setName(map.name); - this.header.setWidth(map.width); - this.header.setHeight(map.height); - this.symmetry.setSymmetry(symmetryAndBodies.symmetry); + this.headerForm.setName(map.name); + this.headerForm.setWidth(map.width); + this.headerForm.setHeight(map.height); + this.symmetryForm.setSymmetry(symmetryAndBodies.symmetry); this.originalBodies = symmetryAndBodies.originalBodies; this.lastID = this.originalBodies.size + 1; - this.symmetricBodies = this.symmetry.getSymmetricBodies(this.originalBodies, map.width, map.height); + this.symmetricBodies = this.symmetryForm.getSymmetricBodies(this.originalBodies, map.width, map.height); this.rubble = map.rubble; this.leadVals = map.lead; diff --git a/client/visualizer/src/mapeditor/forms/anomalies.ts b/client/visualizer/src/mapeditor/forms/anomalies.ts index 1f576e5a..7839e2b5 100644 --- a/client/visualizer/src/mapeditor/forms/anomalies.ts +++ b/client/visualizer/src/mapeditor/forms/anomalies.ts @@ -10,25 +10,17 @@ export default class AnomalyForm { readonly div: HTMLDivElement; // Form elements for archon settings - readonly id: HTMLLabelElement; - readonly type: HTMLSelectElement; - readonly team: HTMLSelectElement; - readonly x: HTMLInputElement; - readonly y: HTMLInputElement; - //readonly influence: HTMLInputElement; + readonly anomaly: HTMLSelectElement; + readonly round: HTMLInputElement; + private readonly ANOMALIES = cst.anomalyList; + constructor() { // Create HTML elements this.div = document.createElement("div"); - this.id = document.createElement("label"); - this.type = document.createElement("select"); - this.team = document.createElement("select"); - this.x = document.createElement("input"); - this.y = document.createElement("input"); - // this.influence = document.createElement("input"); - // this.influence.value = String(cst.INITIAL_INFLUENCE); - // this.influence.disabled = true; + this.anomaly = document.createElement("select"); + this.round = document.createElement("input"); // Create the form this.loadInputs(); @@ -40,24 +32,13 @@ export default class AnomalyForm { * Initializes input fields. */ private loadInputs(): void { - this.x.type = "text"; - this.y.type = "text"; - this.type.disabled = true; - this.ROBOT_TYPES.forEach((type: schema.BodyType) => { + this.round.type = "text"; + this.ANOMALIES.forEach((anomaly: schema.Action) => { const option = document.createElement("option"); - option.value = String(type); - option.appendChild(document.createTextNode(cst.bodyTypeToString(type))); - this.type.appendChild(option); + option.value = String(anomaly); + option.appendChild(document.createTextNode(cst.anomalyToString(anomaly))); + this.anomaly.appendChild(option); }); - for (let team in this.TEAMS) { - const option = document.createElement("option"); - option.value = String(team); - option.appendChild(document.createTextNode(this.TEAMS[team])); - this.team.appendChild(option); - if (this.TEAMS[team] === "Red") { - option.selected = true; - } - } } /** @@ -66,42 +47,21 @@ export default class AnomalyForm { private createForm(): HTMLFormElement { // HTML structure const form: HTMLFormElement = document.createElement("form"); - const id: HTMLDivElement = document.createElement("div"); - const type: HTMLDivElement = document.createElement("div"); - const team: HTMLDivElement = document.createElement("div"); - const x: HTMLDivElement = document.createElement("div"); - const y: HTMLDivElement = document.createElement("div"); + const anomaly: HTMLDivElement = document.createElement("div"); + const round: HTMLDivElement = document.createElement("div"); // const influence: HTMLDivElement = document.createElement("div"); //form.appendChild(id); - form.appendChild(type); - form.appendChild(team); - form.appendChild(x); - form.appendChild(y); - // form.appendChild(influence); + form.appendChild(anomaly); + form.appendChild(round); form.appendChild(document.createElement("br")); - id.appendChild(document.createTextNode("ID: ")); - id.appendChild(this.id); - // Robot type - type.appendChild(document.createTextNode("Type: ")); - type.appendChild(this.type); - - // Team - team.appendChild(document.createTextNode("Team: ")); - team.appendChild(this.team); + anomaly.appendChild(document.createTextNode("Anomaly: ")); + anomaly.appendChild(this.anomaly); // X coordinate - x.appendChild(document.createTextNode("X: ")); - x.appendChild(this.x); - - // Y coordinate - y.appendChild(document.createTextNode("Y: ")); - y.appendChild(this.y); - - // Influence - // influence.appendChild(document.createTextNode("I: ")); - // influence.appendChild(this.influence); + round.appendChild(document.createTextNode("Round: ")); + round.appendChild(this.round); return form; } @@ -111,88 +71,35 @@ export default class AnomalyForm { */ private loadCallbacks(): void { - // X must be in the range [0, this.width] - this.x.onchange = () => { - let value: number = this.getX(); + this.round.onchange = () => { + let value: number = this.getRound(); value = Math.max(value, 0); - value = Math.min(value, this.width()); - this.x.value = isNaN(value) ? "" : String(value); + value = Math.min(value, 2000); // TODO: don't hard code + this.round.value = isNaN(value) ? "" : String(value); }; - // Y must be in the range [0, this.height] - this.y.onchange = () => { - let value: number = this.getY(); - value = Math.max(value, 0); - value = Math.min(value, this.height()); - this.y.value = isNaN(value) ? "" : String(value); - }; - - // this.influence.onchange = () => { - // let value: number = this.getInfluence(); - // value = Math.max(value, 50); - // value = Math.min(value, 500); - // this.influence.value = isNaN(value) ? "" : String(value); - // } - - // this.team.onchange = () => { - // if (this.getTeam() !== 0) { - // this.influence.disabled = true; - // this.influence.value = String(cst.INITIAL_INFLUENCE); - // } - // else this.influence.disabled = false; - // } - } - - private getType(): schema.BodyType { - return parseInt(this.type.options[this.type.selectedIndex].value); - } - - private getTeam(): number { - return parseInt(this.team.options[this.team.selectedIndex].value); - } - - private getX(): number { - return parseInt(this.x.value); + getAnomaly(): schema.Action { + return parseInt(this.anomaly.options[this.anomaly.selectedIndex].value); } - private getY(): number { - return parseInt(this.y.value); + getRound(): number { + return parseInt(this.round.value); } - // private getInfluence(): number { - // return parseInt(this.influence.value); - // } - - getID(): number | undefined { - const id = parseInt(this.id.textContent || "NaN"); - return isNaN(id) ? undefined : id; + setForm() : void { + return; } resetForm(): void { - this.x.value = ""; - this.y.value = ""; + this.anomaly.value = ""; // TODO + this.round.value = "100"; } isValid(): boolean { - const x = this.getX(); - const y = this.getY(); + const round = this.getRound(); //const I = this.getInfluence(); - return !(isNaN(x) || isNaN(y)); // || isNaN(I)); - } - - getUnit(id: number): MapUnit | undefined { - if (!this.isValid()) { - return undefined; - } - return { - x: this.getX(), - y: this.getY(), - radius: 0.5, - type: this.getType(), - teamID: this.getTeam() - // influence: this.getInfluence() - } + return !isNaN(round); } } diff --git a/client/visualizer/src/mapeditor/forms/header.ts b/client/visualizer/src/mapeditor/forms/header.ts index 7108d6d8..9a681eea 100644 --- a/client/visualizer/src/mapeditor/forms/header.ts +++ b/client/visualizer/src/mapeditor/forms/header.ts @@ -14,7 +14,7 @@ export default class HeaderForm { private readonly cb: () => void; // Constants - private readonly DEFAULT_DIM: string = "50"; + private readonly DEFAULT_DIM: string = "30"; constructor(cb: () => void) { From 67b248d29a20c4aeee09211d7a3a989c66e03a12 Mon Sep 17 00:00:00 2001 From: meeeeee Date: Sun, 2 Jan 2022 11:50:15 -0500 Subject: [PATCH 275/413] Anomaly addition to rounds list --- client/visualizer/src/main/looper.ts | 33 +++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 68fcf823..dc28f73c 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -17,6 +17,9 @@ import { TeamStats } from 'battlecode-playback/out/gameworld'; import { Tournament, readTournament } from '../main/tournament'; import { ARCHON } from '../constants'; + +import * as bcg from "../../../../schema/ts/battlecode_generated"; +let anomConsts = bcg.battlecode.schema.Action; /* Responsible for a single match in the visualizer. */ @@ -44,7 +47,7 @@ export default class Looper { private matchqueue: MatchQueue, private profiler?: Profiler, private mapinfo: string = "", showTourneyUpload: boolean = true) { - + this.console = cconsole; this.conf.mode = config.Mode.GAME; @@ -304,6 +307,22 @@ export default class Looper { //this.updateStats(this.match.current, this.meta); this.loopID = window.requestAnimationFrame((curTime) => this.loop.call(this, curTime)); + //console.log(this.match.current.mapStats.anomalies, this.match.current.mapStats.anomalyRounds, "ANOMALIES"); + /* Rendering anomalies */ + let world = this.match.current.mapStats; + + //let testAnom = [anomConsts.ABYSS, anomConsts.CHARGE]; + //let testAnomRounds = [300, 1000]; + for(var i = 0; i < world.anomalies.length; i++){ + let anom = world.anomalies[i]; + let anomRound = world.anomalyRounds[i]; + this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Grey" : "White"; + var pos = Math.round(anomRound*300.0/this.match.lastTurn); + this.controls.ctx.beginPath(); + this.controls.ctx.moveTo(pos, 0); + this.controls.ctx.lineTo(pos, 1); + this.controls.ctx.stroke(); + } } /** @@ -329,20 +348,21 @@ export default class Looper { let teamStats = world.teamStats.get(teamID) as TeamStats; teamIDs.push(teamID); teamNames.push(meta.teams[team].name); - totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); + totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => ((a === NaN)?0:a)+((b === NaN)?0:b)); } for (let team in meta.teams) { let teamID = meta.teams[team].teamID; let teamStats = world.teamStats.get(teamID) as TeamStats; - let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); + let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => ((a === NaN)?0:a)+((b === NaN)?0:b)); // Update each robot count - console.log(teamStats); + console.log(teamStats), "teamStats"; this.stats.robots.forEach((type: schema.BodyType) => { this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level - this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b), teamHP); // TODO: differentiate levels, maybe + this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => ((a === NaN)?0:a)+((b === NaN)?0:b)), teamHP); // TODO: differentiate levels, maybe + console.log(teamStats.total_hp[type], "asfsdfs"); }); /*const hps = world.bodies.arrays.hp; const types = world.bodies.arrays.type; @@ -365,7 +385,10 @@ export default class Looper { teamLead.push(world.teamStats.get(teamIDs[a]).lead); //@ts-ignore teamGold.push(world.teamStats.get(teamIDs[a]).gold); + //@ts-ignore + //console.log(world.teamStats.get(teamIDs[a]).lead, world.teamStats.get(teamIDs[a]).gold, teamIDs[a]); } + this.stats.updateBars(teamLead, teamGold); this.stats.resetECs(); const hps = world.bodies.arrays.hp; From b22da9ff5ef9b17c3dafd35ec5e753eea192e414 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 12:57:23 -0500 Subject: [PATCH 276/413] Fix gold lead hp tracking --- client/playback/src/gameworld.ts | 12 ++++++------ client/visualizer/src/main/looper.ts | 9 +++------ client/visualizer/src/mapeditor/form.ts | 5 +++++ client/visualizer/src/sidebar/stats.ts | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index d7b2e717..ab305bd8 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -466,8 +466,8 @@ export default class GameWorld { case schema.Action.TRANSMUTE: setAction(); - teamStatsObj.gold += target; - teamStatsObj.lead -= 0; + // teamStatsObj.gold += target; + // teamStatsObj.lead -= 0; break; case schema.Action.TRANSFORM: @@ -497,12 +497,12 @@ export default class GameWorld { case schema.Action.CHANGE_HEALTH: this.bodies.alter({ id: robotID, hp: body.hp + target}); - teamStatsObj.total_hp[body.type][body.level] += target; + teamStatsObj.total_hp[body.type][body.level - 1] += target; break; case schema.Action.FULLY_REPAIRED: this.bodies.alter({ id: robotID, prototype: 0}); - teamStatsObj.total_hp[body.type][body.level] += target; + //teamStatsObj.total_hp[body.type][body.level] += target; break; case schema.Action.DIE_EXCEPTION: @@ -510,7 +510,6 @@ export default class GameWorld { break; case schema.Action.VORTEX: - console.log("vortex"); let w = this.mapStats.maxCorner.x - this.mapStats.minCorner.x; let h = this.mapStats.maxCorner.y - this.mapStats.minCorner.y; switch (target) { @@ -607,7 +606,8 @@ export default class GameWorld { if(!statObj) {continue;} // In case this is a neutral bot statObj.robots[type][this.bodies.arrays.level[index] - 1] -= 1; let hp = this.bodies.arrays.hp[index]; - statObj.total_hp[type][this.bodies.arrays.level[index] - 1] -= hp; + let level = this.bodies.arrays.level[index]; + statObj.total_hp[type][level - 1] -= hp; this.teamStats.set(team, statObj); } diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index dc28f73c..110b91e6 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -348,21 +348,18 @@ export default class Looper { let teamStats = world.teamStats.get(teamID) as TeamStats; teamIDs.push(teamID); teamNames.push(meta.teams[team].name); - totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => ((a === NaN)?0:a)+((b === NaN)?0:b)); - + totalHP += teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a + b); } for (let team in meta.teams) { let teamID = meta.teams[team].teamID; let teamStats = world.teamStats.get(teamID) as TeamStats; - let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => ((a === NaN)?0:a)+((b === NaN)?0:b)); + let teamHP = teamStats.total_hp.reduce((a,b) => a.concat(b)).reduce((a, b) => a+b); // Update each robot count - console.log(teamStats), "teamStats"; this.stats.robots.forEach((type: schema.BodyType) => { this.stats.setRobotCount(teamID, type, teamStats.robots[type].reduce((a, b) => a + b)); // TODO: show number of robots per level - this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => ((a === NaN)?0:a)+((b === NaN)?0:b)), teamHP); // TODO: differentiate levels, maybe - console.log(teamStats.total_hp[type], "asfsdfs"); + this.stats.setRobotHP(teamID, type, teamStats.total_hp[type].reduce((a,b) => a+b), teamHP); // TODO: differentiate levels, maybe }); /*const hps = world.bodies.arrays.hp; const types = world.bodies.arrays.type; diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 3f4fbe46..bab8e193 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -368,6 +368,11 @@ export default class MapEditorForm { this.deleteUnit(id); this.getActiveForm().resetForm(); } + } else if (this.getActiveForm() == this.leadForm) { + const form: LeadForm = this.leadForm; + const x = form.getX(); + const y = form.getY(); + this.setLead(x, y, 0); } } diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 0b897612..2741d0fa 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -227,7 +227,7 @@ export default class Stats { console.log(this.div); for(var a = 0; a < teamGold.length; a++){ this.relativeBars[a].innerHTML = teamGold[a].toString(); - this.relativeBars[a+2].style.width = (Math.max(teamGold[0], teamGold[1]) === 0 ? 90:(90.0*teamGold[a]/Math.max(teamGold[0], teamGold[1]))).toString() + "%"; + this.relativeBars[a].style.width = (Math.max(teamGold[0], teamGold[1]) === 0 ? 90:(90.0*teamGold[a]/Math.max(teamGold[0], teamGold[1]))).toString() + "%"; } for(var a = 0; a < teamLead.length; a++){ this.relativeBars[a+2].innerHTML = teamLead[a].toString(); From ddb0587e44d777d2d631f0581b4a172b643cc654 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 14:42:52 -0500 Subject: [PATCH 277/413] Preliminary javadocs and bytecode costs --- build.gradle | 20 +- .../common/AnomalyScheduleEntry.java | 7 + .../main/battlecode/common/AnomalyType.java | 6 +- .../src/main/battlecode/common/BodyInfo.java | 28 --- .../main/battlecode/common/GameConstants.java | 2 +- .../battlecode/common/RobotController.java | 14 +- .../src/main/battlecode/common/RobotType.java | 73 ++++++-- .../bytecode/resources/MethodCosts.txt | 176 +++++++++++------- gradle.properties | 2 +- 9 files changed, 197 insertions(+), 131 deletions(-) delete mode 100644 engine/src/main/battlecode/common/BodyInfo.java diff --git a/build.gradle b/build.gradle index 2e2c4fb3..216be097 100644 --- a/build.gradle +++ b/build.gradle @@ -272,13 +272,6 @@ task releaseClientLinux32(type: Zip, dependsOn: ['prodClient']) { -task updateVersion() { - // new File("frontend/public/version.txt").write(project.findProperty('release_version')) -} - - - -publish.dependsOn(updateVersion) publishing { repositories { maven { @@ -296,11 +289,10 @@ publishing { publications { server(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21' + artifactId 'battlecode22' version project.findProperty('release_version') ?: 'NONSENSE' artifact release_main - artifact release_docs { classifier 'javadoc' @@ -312,7 +304,7 @@ publishing { clientWin(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21-client-win' + artifactId 'battlecode22-client-win' version project.findProperty('release_version') ?: 'NONSENSE' artifact releaseClientWin @@ -320,7 +312,7 @@ publishing { clientMac(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21-client-mac' + artifactId 'battlecode22-client-mac' version project.findProperty('release_version') ?: 'NONSENSE' artifact releaseClientMac @@ -328,7 +320,7 @@ publishing { clientLinux(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21-client-linux' + artifactId 'battlecode22-client-linux' version project.findProperty('release_version') ?: 'NONSENSE' artifact releaseClientLinux @@ -336,7 +328,7 @@ publishing { clientWin32(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21-client-win-32' + artifactId 'battlecode22-client-win-32' version project.findProperty('release_version') ?: 'NONSENSE' artifact releaseClientWin32 @@ -344,7 +336,7 @@ publishing { clientLinux32(MavenPublication) { groupId 'org.battlecode' - artifactId 'battlecode21-client-linux-32' + artifactId 'battlecode22-client-linux-32' version project.findProperty('release_version') ?: 'NONSENSE' artifact releaseClientLinux32 diff --git a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java index eef5c249..432a6966 100644 --- a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java @@ -1,5 +1,10 @@ package battlecode.common; +/** + * AnomalyScheduleEntry describes a single anomaly in the schedule. + * + * You can access information about that anomaly's round number and type. + */ public class AnomalyScheduleEntry { public final int roundNumber; @@ -22,6 +27,8 @@ public AnomalyScheduleEntry copyEntry() { * * @param other the other anomaly schedule entry to compare to * @return whether the two anomaly schedules entry are equivalent + * + * @battlecode.doc.costlymethod */ public boolean equals(AnomalyScheduleEntry other) { if (this.roundNumber != other.roundNumber) return false; diff --git a/engine/src/main/battlecode/common/AnomalyType.java b/engine/src/main/battlecode/common/AnomalyType.java index f09085be..198b941e 100644 --- a/engine/src/main/battlecode/common/AnomalyType.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -1,7 +1,9 @@ package battlecode.common; /** - * Holds the different anomalies in the game. + * AnomalyType enumerates the different types of anomalies in the game. + * You can also access properties about these anomalies, such as their strengths + * and whether they can be performed by Sages. */ public enum AnomalyType { ABYSS (true, true, 0.1f, 0.2f), @@ -21,4 +23,4 @@ public enum AnomalyType { this.globalPercentage = globalPercentage; this.sagePercentage = sagePercentage; } -} \ No newline at end of file +} diff --git a/engine/src/main/battlecode/common/BodyInfo.java b/engine/src/main/battlecode/common/BodyInfo.java deleted file mode 100644 index b8f008f4..00000000 --- a/engine/src/main/battlecode/common/BodyInfo.java +++ /dev/null @@ -1,28 +0,0 @@ -package battlecode.common; - -/** - * Stores information about a Object/Body in the game world - */ -public interface BodyInfo { - - /** - * Returns the ID of this body. - * - * @return the ID of this body. - */ - int getID(); - - /** - * Returns the center location of this body. - * - * @return the center location of this body. - */ - MapLocation getLocation(); - - /** - * Returns whether this body is a robot. - * - * @return true if this body is a robot; false otherwise. - */ - boolean isRobot(); -} diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index c351ed30..22a369f6 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -74,7 +74,7 @@ public class GameConstants { // ****** COOLDOWNS **************** // ********************************* - /** If the number of cooldown turns is >= this number, a robot cannot act. */ + /** If the amount of cooldown is at least this value, a robot cannot act. */ public static final int COOLDOWN_LIMIT = 10; /** The number of cooldown turns reduced per turn. */ diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 086da698..df93ba23 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -66,6 +66,7 @@ public strictfp interface RobotController { /** * Returns the amount of lead a team has in its reserves. * + * @param team the team being queried. * @return the amount of lead a team has in its reserves. * * @battlecode.doc.costlymethod @@ -75,6 +76,7 @@ public strictfp interface RobotController { /** * Returns the amount of gold a team has in its reserves. * + * @param team the team being queried. * @return the amount of gold a team has in its reserves. * * @battlecode.doc.costlymethod @@ -346,6 +348,7 @@ public strictfp interface RobotController { * @param center the given location * @param radiusSquared return locations within this distance away from center * @return list of locations on the map and within radiusSquared of center + * @throws GameActionException if the radius is negative * * @battlecode.doc.costlymethod */ @@ -504,6 +507,7 @@ public strictfp interface RobotController { /** * Attack a given location. * + * @param loc the target location to attack * @throws GameActionException if conditions for attacking are not satisfied * * @battlecode.doc.costlymethod @@ -519,6 +523,7 @@ public strictfp interface RobotController { * * Checks that the robot is a sage, and there are no cooldown turns remaining. * + * @param anomaly the type of anomaly being queried * @return whether it is possible to envision an anomaly centered at the robots location * * @battlecode.doc.costlymethod @@ -528,6 +533,7 @@ public strictfp interface RobotController { /** * Envision an anomaly centered at the robot's location. * + * @param anomaly the type of anomaly to envision * @throws GameActionException if conditions for envisioning are not satisfied * * @battlecode.doc.costlymethod @@ -556,6 +562,7 @@ public strictfp interface RobotController { /** * Repairs at a given location. * + * @param loc target location to repair at * @throws GameActionException if conditions for repairing are not satisfied * * @battlecode.doc.costlymethod @@ -584,6 +591,7 @@ public strictfp interface RobotController { /** * Mine lead at a given location. * + * @param loc target location to mine * @throws GameActionException if conditions for mining are not satisfied * * @battlecode.doc.costlymethod @@ -608,6 +616,7 @@ public strictfp interface RobotController { /** * Mine a gold at given location. * + * @param loc target location to mine * @throws GameActionException if conditions for mining are not satisfied * * @battlecode.doc.costlymethod @@ -636,6 +645,7 @@ public strictfp interface RobotController { /** * Mutate a building at a given location. * + * @param loc target location of the building to mutate * @throws GameActionException if conditions for mutating are not satisfied * * @battlecode.doc.costlymethod @@ -707,7 +717,7 @@ public strictfp interface RobotController { * * @param index the index in the team's shared array, 0-indexed * @return the value at that index in the team's shared array, - * or -1 if the index is invalid + * @throws GameActionException if the index is invalid * * @battlecode.doc.costlymethod */ @@ -719,6 +729,8 @@ public strictfp interface RobotController { * * @param index the index in the team's shared array, 0-indexed * @param value the value to set that index to + * @throws GameActionException if the index is invalid, or the value + * is out of bounds * * @battlecode.doc.costlymethod */ diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index e6582108..2c80e08d 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -12,46 +12,54 @@ public enum RobotType { * Archons are portable buildings that heal and generate robots. * Losing all archons means losing the game. * - * @battlecode.doc.robot */ + * @battlecode.doc.robottype */ ARCHON ( 0, 250, 10, 24, 1000, -2, 20, 34, 20000), // BCL BCG AC MC HP DMG AR VR BL /** - * Alchemist's laboratory - * Converts lead into gold + * Alchemist's laboratory. + * Converts lead into gold. * - * @battlecode.doc.robot */ + * @battlecode.doc.robottype */ LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), // BCL BCG AC MC HP DMG AR VR BL /** - * Guard turret - */ + * Guard turret. + * + * @battlecode.doc.robottype */ WATCHTOWER (180, 0, 10, 24, 130, 5, 20, 34, 10000), // BCL BCG AC MC HP DMG AR VR BL /** + * Miner robots. * Can mine gold or lead at their or an adjacent location. * - * @battlecode.doc.robot */ + * @battlecode.doc.robottype */ MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), // BCL BCG AC MC HP DMG AR VR BL + /** + * Builder robots. * Can build and repair buildings. * - * @battlecode.doc.robot */ + * @battlecode.doc.robottype */ BUILDER ( 40, 0, 10, 20, 30, -1, 5, 20, 7500), // BCL BCG AC MC HP DMG AR VR BL - + /** + * Soldier robots. * Ranged attacking robot. - */ + * + * @battlecode.doc.robottype */ SOLDIER ( 75, 0, 10, 16, 50, 3, 13, 20, 10000), // BCL BCG AC MC HP DMG AR VR BL - + /** + * Sage robots. * Gold robot, causes Anomalies. - */ + * + * @battlecode.doc.robottype */ SAGE ( 0, 50, 200, 25, 100, 45, 13, 20, 10000) // BCL BCG AC MC HP DMG AR VR BL ; @@ -119,6 +127,8 @@ public int getVisionRadiusSquared(int level) { /** * @param builtType type of robot being built * @return whether this type can build the given robot type + * + * @battlecode.doc.costlymethod */ public boolean canBuild(RobotType builtType) { return (this == ARCHON && (builtType == MINER || @@ -131,6 +141,8 @@ public boolean canBuild(RobotType builtType) { /** * @return whether this type can attack + * + * @battlecode.doc.costlymethod */ public boolean canAttack() { return (this == WATCHTOWER @@ -139,6 +151,8 @@ public boolean canAttack() { /** * @return whether this type can envision anomalies + * + * @battlecode.doc.costlymethod */ public boolean canEnvision() { return this == SAGE; @@ -147,6 +161,8 @@ public boolean canEnvision() { /** * @param repairedType type of robot being repaired * @return whether this type can repair the given robot type + * + * @battlecode.doc.costlymethod */ public boolean canRepair(RobotType repairedType) { return ((this == ARCHON && !repairedType.isBuilding()) || @@ -155,6 +171,8 @@ public boolean canRepair(RobotType repairedType) { /** * @return whether this type can mine + * + * @battlecode.doc.costlymethod */ public boolean canMine() { return this == MINER; @@ -163,6 +181,8 @@ public boolean canMine() { /** * @param mutatedType type of robot being mutated * @return whether this type can mutate buildings + * + * @battlecode.doc.costlymethod */ public boolean canMutate(RobotType mutatedType) { return this == BUILDER && mutatedType.isBuilding(); @@ -170,6 +190,8 @@ public boolean canMutate(RobotType mutatedType) { /** * @return whether this type can transmute lead into gold + * + * @battlecode.doc.costlymethod */ public boolean canTransmute() { return this == LABORATORY; @@ -177,6 +199,8 @@ public boolean canTransmute() { /** * @return whether or not a given robot is a building + * + * @battlecode.doc.costlymethod */ public boolean isBuilding() { return ( @@ -190,6 +214,8 @@ public boolean isBuilding() { * Returns the max health of a robot by level. * @param level of the robot * @return the max health of a robot by level + * + * @battlecode.doc.costlymethod */ public int getMaxHealth(int level) { if (!this.isBuilding() || level == 1) { @@ -204,9 +230,11 @@ public int getMaxHealth(int level) { } /** - * Returns the damage of a robot by level. - * @param level + * Determine the damage power of a robot by level. + * @param level The specific level of the robot. * @return the damage for a robot by level, negative if robot heals + * + * @battlecode.doc.costlymethod */ public int getDamage(int level) { if (!this.isBuilding() || level == 1) { @@ -221,9 +249,12 @@ public int getDamage(int level) { } /** - * @param level + * Determine the healing power of a robot by level. + * @param level The specific level of the robot. * @return the healing per turn for a robot by level as a positive amount, * 0 if robot doesn't heal + * + * @battlecode.doc.costlymethod */ public int getHealing(int level) { if (this == ARCHON || this == BUILDER) { @@ -238,6 +269,8 @@ public int getHealing(int level) { /** * @param level the level to mutate to * @return lead component of cost to mutate + * + * @battlecode.doc.costlymethod */ public int getLeadMutateCost(int level) { return level == 2 ? 600 : 0; @@ -246,6 +279,8 @@ public int getLeadMutateCost(int level) { /** * @param level the level to mutate to * @return gold component of cost to mutate. + * + * @battlecode.doc.costlymethod */ public int getGoldMutateCost(int level) { return level == 3 ? 100 : 0; @@ -254,6 +289,8 @@ public int getGoldMutateCost(int level) { /** * @param level the robot's current level * @return lead component of worth + * + * @battlecode.doc.costlymethod */ public int getLeadWorth(int level) { int leadWorth = this.buildCostLead; @@ -266,6 +303,8 @@ public int getLeadWorth(int level) { /** * @param level the robot's current level * @return gold component of worth + * + * @battlecode.doc.costlymethod */ public int getGoldWorth(int level) { int goldWorth = this.buildCostGold; @@ -278,6 +317,8 @@ public int getGoldWorth(int level) { /** * @param level the robot's current level * @return the amount of lead dropped + * + * @battlecode.doc.costlymethod */ public int getLeadDropped(int level) { return (int) (this.getLeadWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER); @@ -286,6 +327,8 @@ public int getLeadDropped(int level) { /** * @param level the robot's current level * @return the amount of gold dropped + * + * @battlecode.doc.costlymethod */ public int getGoldDropped(int level) { return (int) (this.getGoldWorth(level) * GameConstants.RECLAIM_COST_MULTIPLIER); diff --git a/engine/src/main/battlecode/instrumenter/bytecode/resources/MethodCosts.txt b/engine/src/main/battlecode/instrumenter/bytecode/resources/MethodCosts.txt index df2611d9..74c6406b 100644 --- a/engine/src/main/battlecode/instrumenter/bytecode/resources/MethodCosts.txt +++ b/engine/src/main/battlecode/instrumenter/bytecode/resources/MethodCosts.txt @@ -1,72 +1,110 @@ -battlecode/common/Clock/yield 0 true -battlecode/common/Clock/getBytecodesLeft 0 true -battlecode/common/Clock/getBytecodeNum 0 true -battlecode/common/Direction/equals 1 false -battlecode/common/Direction/getDeltaX 1 false -battlecode/common/Direction/getDeltaY 1 false -battlecode/common/Direction/rotateLeft 1 false -battlecode/common/Direction/rotateRight 1 false -battlecode/common/Direction/opposite 1 false -battlecode/common/Direction/allDirections 1 false -battlecode/common/Direction/cardinalDirections 1 false -battlecode/common/MapLocation/add 2 false -battlecode/common/MapLocation/compareTo 2 false -battlecode/common/MapLocation/directionTo 2 false -battlecode/common/MapLocation/distanceSquaredTo 2 false -battlecode/common/MapLocation/equals 2 false -battlecode/common/MapLocation/hashCode 2 false -battlecode/common/MapLocation/isWithinDistanceSquared 2 false -battlecode/common/MapLocation/isAdjacentTo 2 false -battlecode/common/MapLocation/isWithinSensorRadius 2 false -battlecode/common/MapLocation/subtract 2 false -battlecode/common/MapLocation/toString 2 false -battlecode/common/MapLocation/translate 2 false -battlecode/common/MapLocation/valueOf 25 false -battlecode/common/RobotController/adjacentLocation 1 true -battlecode/common/RobotController/bid 1 true -battlecode/common/RobotController/buildRobot 0 true -battlecode/common/RobotController/canBid 10 true -battlecode/common/RobotController/canBuildRobot 10 true -battlecode/common/RobotController/canDetectLocation 5 true -battlecode/common/RobotController/canDetectRadiusSquared 5 true -battlecode/common/RobotController/canEmpower 10 true -battlecode/common/RobotController/canExpose 10 true -battlecode/common/RobotController/canGetFlag 5 true -battlecode/common/RobotController/canMove 10 true -battlecode/common/RobotController/canSenseLocation 5 true -battlecode/common/RobotController/canSenseRadiusSquared 5 true -battlecode/common/RobotController/canSenseRobot 5 true -battlecode/common/RobotController/detectNearbyRobots 100 true -battlecode/common/RobotController/empower 0 true -battlecode/common/RobotController/expose 0 true -battlecode/common/RobotController/getConviction 1 true -battlecode/common/RobotController/getCooldownTurns 1 true -battlecode/common/RobotController/getEmpowerFactor 1 true -battlecode/common/RobotController/getFlag 5 true -battlecode/common/RobotController/getID 1 true -battlecode/common/RobotController/getInfluence 1 true -battlecode/common/RobotController/getLocation 1 true -battlecode/common/RobotController/getRobotCount 20 true -battlecode/common/RobotController/getRoundNum 1 true -battlecode/common/RobotController/getTeam 1 true -battlecode/common/RobotController/getTeamVotes 1 true -battlecode/common/RobotController/getType 1 true -battlecode/common/RobotController/isLocationOccupied 20 true -battlecode/common/RobotController/isReady 1 true -battlecode/common/RobotController/move 0 true -battlecode/common/RobotController/onTheMap 5 true -battlecode/common/RobotController/resign 0 true -battlecode/common/RobotController/senseNearbyRobots 100 true -battlecode/common/RobotController/sensePassability 1 true -battlecode/common/RobotController/senseRobot 25 true -battlecode/common/RobotController/senseRobotAtLocation 25 true -battlecode/common/RobotController/setFlag 100 true -battlecode/common/RobotController/setIndicatorDot 0 true -battlecode/common/RobotController/setIndicatorLine 0 true -battlecode/common/RobotType/getInfluenceCostForConviction 1 false -battlecode/common/RobotType/getPassiveInfluence 1 false -battlecode/common/Team/opponent 1 false -battlecode/common/Team/isPlayer 1 false +battlecode/common/AnomalyScheduleEntry/equals 2 false +battlecode/common/Clock/yield 0 true +battlecode/common/Clock/getBytecodesLeft 0 false +battlecode/common/Clock/getBytecodeNum 0 false +battlecode/common/Direction/equals 1 false +battlecode/common/Direction/getDeltaX 1 false +battlecode/common/Direction/getDeltaY 1 false +battlecode/common/Direction/rotateLeft 1 false +battlecode/common/Direction/rotateRight 1 false +battlecode/common/Direction/opposite 1 false +battlecode/common/Direction/allDirections 1 false +battlecode/common/Direction/cardinalDirections 1 false +battlecode/common/MapLocation/add 2 false +battlecode/common/MapLocation/compareTo 2 false +battlecode/common/MapLocation/directionTo 2 false +battlecode/common/MapLocation/distanceSquaredTo 2 false +battlecode/common/MapLocation/equals 2 false +battlecode/common/MapLocation/hashCode 2 false +battlecode/common/MapLocation/isWithinDistanceSquared 2 false +battlecode/common/MapLocation/isAdjacentTo 2 false +battlecode/common/MapLocation/isWithinSensorRadius 2 false +battlecode/common/MapLocation/subtract 2 false +battlecode/common/MapLocation/toString 2 false +battlecode/common/MapLocation/translate 2 false +battlecode/common/MapLocation/valueOf 25 false +battlecode/common/RobotController/adjacentLocation 1 true +battlecode/common/RobotController/attack 0 true +battlecode/common/RobotController/buildRobot 0 true +battlecode/common/RobotController/canAttack 10 true +battlecode/common/RobotController/canBuildRobot 10 true +battlecode/common/RobotController/canEnvision 10 true +battlecode/common/RobotController/canMineGold 10 true +battlecode/common/RobotController/canMineLead 10 true +battlecode/common/RobotController/canMove 10 true +battlecode/common/RobotController/canMutate 10 true +battlecode/common/RobotController/canRepair 10 true +battlecode/common/RobotController/canSenseLocation 5 true +battlecode/common/RobotController/canSenseRadiusSquared 5 true +battlecode/common/RobotController/canSenseRobot 5 true +battlecode/common/RobotController/canSenseRobotAtLocation 5 true +battlecode/common/RobotController/canTransform 10 true +battlecode/common/RobotController/canTransmute 10 true +battlecode/common/RobotController/disintegrate 0 true +battlecode/common/RobotController/envision 0 true +battlecode/common/RobotController/getActionCooldownTurns 1 true +battlecode/common/RobotController/getAllLocationsWithinRadiusSquared 100 true +battlecode/common/RobotController/getAnomalySchedule 100 true +battlecode/common/RobotController/getArchonCount 20 true +battlecode/common/RobotController/getHealth 1 true +battlecode/common/RobotController/getID 1 true +battlecode/common/RobotController/getLevel 1 true +battlecode/common/RobotController/getLocation 1 true +battlecode/common/RobotController/getMapHeight 1 true +battlecode/common/RobotController/getMapWidth 1 true +battlecode/common/RobotController/getMode 1 true +battlecode/common/RobotController/getMovementCooldownTurns 1 true +battlecode/common/RobotController/getRobotCount 20 true +battlecode/common/RobotController/getRoundNum 1 true +battlecode/common/RobotController/getTeam 1 true +battlecode/common/RobotController/getTeamGoldAmount 1 true +battlecode/common/RobotController/getTeamLeadAmount 1 true +battlecode/common/RobotController/getTransformCooldownTurns 1 true +battlecode/common/RobotController/getTransmutationRate 20 true +battlecode/common/RobotController/getType 1 true +battlecode/common/RobotController/isActionReady 1 true +battlecode/common/RobotController/isLocationOccupied 20 true +battlecode/common/RobotController/isMovementReady 1 true +battlecode/common/RobotController/isTransformReady 1 true +battlecode/common/RobotController/mineGold 0 true +battlecode/common/RobotController/mineLead 0 true +battlecode/common/RobotController/move 0 true +battlecode/common/RobotController/mutate 0 true +battlecode/common/RobotController/onTheMap 5 true +battlecode/common/RobotController/readSharedArray 2 true +battlecode/common/RobotController/repair 0 true +battlecode/common/RobotController/resign 0 true +battlecode/common/RobotController/senseGold 5 true +battlecode/common/RobotController/senseLead 5 true +battlecode/common/RobotController/senseNearbyRobots 100 true +battlecode/common/RobotController/senseRobot 25 true +battlecode/common/RobotController/senseRobotAtLocation 25 true +battlecode/common/RobotController/senseRubble 5 true +battlecode/common/RobotController/setIndicatorDot 0 true +battlecode/common/RobotController/setIndicatorLine 0 true +battlecode/common/RobotController/setIndicatorString 0 true +battlecode/common/RobotController/transform 0 true +battlecode/common/RobotController/transmute 0 true +battlecode/common/RobotController/writeSharedArray 100 true +battlecode/common/RobotType/canAttack 1 false +battlecode/common/RobotType/canBuild 1 false +battlecode/common/RobotType/canEnvision 1 false +battlecode/common/RobotType/canMine 1 false +battlecode/common/RobotType/canMutate 1 false +battlecode/common/RobotType/canRepair 1 false +battlecode/common/RobotType/canTransmute 1 false +battlecode/common/RobotType/getDamage 1 false +battlecode/common/RobotType/getGoldDropped 1 false +battlecode/common/RobotType/getGoldMutateCost 1 false +battlecode/common/RobotType/getGoldWorth 1 false +battlecode/common/RobotType/getHealing 1 false +battlecode/common/RobotType/getLeadDropped 1 false +battlecode/common/RobotType/getLeadMutateCost 1 false +battlecode/common/RobotType/getLeadWorth 1 false +battlecode/common/RobotType/getMaxHealth 1 false +battlecode/common/RobotType/isBuilding 1 false +battlecode/common/Team/opponent 1 false +battlecode/common/Team/isPlayer 1 false java/lang/Math/IEEEremainder 1 false java/lang/Math/abs 1 false java/lang/Math/acos 1 false diff --git a/gradle.properties b/gradle.properties index 3d94d4be..77abe11d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,4 @@ maps=maptestsmall profilerEnabled=false source=src mapLocation=maps -release_version=2022.0.0.0 +release_version=2022.0.0.1 From 18b634b98dd53e68b4e0c1c2e501effa3d35ac0a Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 2 Jan 2022 13:48:04 -0600 Subject: [PATCH 278/413] Changed cooldown turn count to int not double, throw exception if mode can't transform --- engine/src/main/battlecode/common/RobotController.java | 7 ++++--- .../src/main/battlecode/world/RobotControllerImpl.java | 9 ++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 086da698..6e9edff3 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -374,7 +374,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - double getActionCooldownTurns(); + int getActionCooldownTurns(); /** * Tests whether the robot can move. @@ -395,7 +395,7 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - double getMovementCooldownTurns(); + int getMovementCooldownTurns(); /** * Tests whether the robot can transform. @@ -416,10 +416,11 @@ public strictfp interface RobotController { * GameConstants.COOLDOWNS_PER_TURN every turn. * * @return the number of cooldown turns remaining before this unit can transform again + * @throws GameActionException if the robot's mode is not TURRET or PORTABLE * * @battlecode.doc.costlymethod */ - double getTransformCooldownTurns(); + int getTransformCooldownTurns() throws GameActionException; // *********************************** // ****** MOVEMENT METHODS *********** diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index c1500c7c..3eda879f 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -323,7 +323,7 @@ public boolean isActionReady() { } @Override - public double getActionCooldownTurns() { + public int getActionCooldownTurns() { return this.robot.getActionCooldownTurns(); } @@ -345,7 +345,7 @@ public boolean isMovementReady() { } @Override - public double getMovementCooldownTurns() { + public int getMovementCooldownTurns() { return this.robot.getMovementCooldownTurns(); } @@ -368,7 +368,10 @@ public boolean isTransformReady() { } @Override - public double getTransformCooldownTurns() { + public int getTransformCooldownTurns() throws GameActionException { + if (!this.robot.getMode().canTransform) + throw new GameActionException(CANT_DO_THAT, + "This robot is not in a mode that can transform."); return this.robot.getTransformCooldownTurns(); } From 561eb149b21aefb0aac11b77ba24078b88ba144e Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 2 Jan 2022 14:03:02 -0600 Subject: [PATCH 279/413] Added isLocationOccupied, removed exception for canSenseRobotAtLocation --- .../main/battlecode/common/RobotController.java | 14 ++++++++++++-- .../main/battlecode/world/RobotControllerImpl.java | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index 6e9edff3..2590d283 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -185,7 +185,7 @@ public strictfp interface RobotController { boolean canSenseRadiusSquared(int radiusSquared); /** - * Checks whether a robot is at a given location. Assumes the location is valid. + * Checks whether a robot is at a given location. Assumes the location is valid. * * @param loc the location to check * @return true if a robot is at the location @@ -193,7 +193,17 @@ public strictfp interface RobotController { * * @battlecode.doc.costlymethod */ - boolean canSenseRobotAtLocation(MapLocation loc) throws GameActionException; + boolean isLocationOccupied(MapLocation loc) throws GameActionException; + + /** + * Checks whether a robot is at a given location. Assume the location is valid. + * + * @param loc the location to check + * @return true if a robot is at the location, false if there is no robot or the location can not be sensed. + * + * @battlecode.doc.costlymethod + */ + boolean canSenseRobotAtLocation(MapLocation loc); /** * Senses the robot at the given location, or null if there is no robot diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 3eda879f..f1eaecdb 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -203,11 +203,18 @@ public boolean canSenseRadiusSquared(int radiusSquared) { } @Override - public boolean canSenseRobotAtLocation(MapLocation loc) throws GameActionException { + public boolean isLocationOccupied(MapLocation loc) throws GameActionException { assertCanSenseLocation(loc); return this.gameWorld.getRobot(loc) != null; } + @Override + public boolean canSenseRobotAtLocation(MapLocation loc) { + try { + return isLocationOccupied(loc); + } catch (GameActionException e) { return false; } + } + @Override public RobotInfo senseRobotAtLocation(MapLocation loc) throws GameActionException { assertCanSenseLocation(loc); From f38576df8211b356bcffa2b134ffc878e21d34b8 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 2 Jan 2022 14:04:52 -0600 Subject: [PATCH 280/413] Changed prototype to start with 0.6 of health --- engine/src/main/battlecode/common/GameConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index c351ed30..6186ae19 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -91,7 +91,7 @@ public class GameConstants { // ********************************* /** A blueprint building's health, as a multiplier of max health. */ - public static final float PROTOTYPE_HP_PERCENTAGE = 0.9f; + public static final float PROTOTYPE_HP_PERCENTAGE = 0.6f; /** The multiplier for reclaiming a building's cost. */ public static final float RECLAIM_COST_MULTIPLIER = 0.2f; From 4be481239b5f5a34180fd59eb4240467fa49eef7 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 15:15:41 -0500 Subject: [PATCH 281/413] Show prototype state --- client/playback/src/gameworld.ts | 6 +++++- client/playback/src/metadata.ts | 2 ++ client/visualizer/src/constants.ts | 1 + client/visualizer/src/main/controls.ts | 5 +++-- client/visualizer/src/main/looper.ts | 5 ++++- .../img/robots/blue_archon_prototype.png | Bin 1815 -> 605 bytes .../static/img/robots/blue_lab_prototype.png | Bin 1938 -> 425 bytes .../img/robots/blue_watchtower_prototype.png | Bin 1773 -> 368 bytes .../static/img/robots/red_archon_prototype.png | Bin 1736 -> 572 bytes .../static/img/robots/red_lab_prototype.png | Bin 1801 -> 409 bytes .../img/robots/red_watchtower_prototype.png | Bin 1732 -> 357 bytes 11 files changed, 15 insertions(+), 4 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index ab305bd8..9d5c041e 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -719,6 +719,7 @@ export default class GameWorld { var teams = bodies.teamIDsArray(); var types = bodies.typesArray(); var hps = new Int32Array(bodies.robotIDsLength()); + var prototypes = new Int8Array(bodies.robotIDsLength()); // Update spawn stats for(let i = 0; i < bodies.robotIDsLength(); i++) { @@ -728,6 +729,7 @@ export default class GameWorld { statObj.total_hp[types[i]][0] += this.meta.types[types[i]].health; // TODO: extract meta info this.teamStats.set(teams[i], statObj); hps[i] = this.meta.types[types[i]].health; + prototypes[i] = (this.meta.buildingTypes.includes(types[i]) && types[i] != schema.BodyType.ARCHON) ? 1 : 0; } const locs = bodies.locs(this._vecTableSlot1); @@ -757,7 +759,9 @@ export default class GameWorld { bid: new Int32Array(bodies.robotIDsLength()), parent: new Int32Array(bodies.robotIDsLength()), hp: hps, - level: levels + level: levels, + portable: new Int8Array(bodies.robotIDsLength()), + prototype: prototypes, }); } diff --git a/client/playback/src/metadata.ts b/client/playback/src/metadata.ts index a76e4312..7c797d0e 100644 --- a/client/playback/src/metadata.ts +++ b/client/playback/src/metadata.ts @@ -20,6 +20,8 @@ export default class Metadata { */ types: {[key: number]: BodyTypeMetaData}; + buildingTypes: schema.BodyType[] = [schema.BodyType.ARCHON, schema.BodyType.LABORATORY, schema.BodyType.WATCHTOWER]; + /** * All the teams in a game. */ diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 42d5dd68..89afe230 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -11,6 +11,7 @@ export const SOLDIER = schema.BodyType.SOLDIER export const WATCHTOWER = schema.BodyType.WATCHTOWER export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER] +export const buildingTypeList: number[] = [ARCHON, LABORATORY, WATCHTOWER]; export const initialBodyTypeList: number[] = [ARCHON] export const anomalyList = [schema.Action.VORTEX, schema.Action.FURY, schema.Action.CHARGE, schema.Action.ABYSS] diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 0518b4c1..dd449011 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -439,11 +439,12 @@ export default class Controls { * Bytecodes Used: bytecodes" */ // TODO fix this (different stats) - setInfoString(id, x: number, y: number, hp: number, max_hp: number, dp: number, bodyType: string, bytecodes: number, level: number, parent?: number): void { + setInfoString(id, x: number, y: number, hp: number, max_hp: number, dp: number, bodyType: string, bytecodes: number, level: number, parent?: number, portable?: boolean, prototype?: boolean): void { // console.log(carryDirt); let infoString = `ID: ${id} | `; infoString += `Location: (${x}, ${y}) | `; - infoString += `Level: ${level}
`; + infoString += `Level: ${level} | `; + if (portable !== undefined && prototype !== undefined) infoString += `Mode: ${portable ? 'Port' : prototype ? 'Prot' : 'Turr'}
`; infoString += `HP: ${hp} / ${max_hp} | `; infoString += `DP: ${dp} | `; infoString += `Bytecodes Used: ${bytecodes}`; diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 110b91e6..7f04ce71 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -256,10 +256,13 @@ export default class Looper { let bytecodes = bodies.bytecodesUsed[index]; let level = bodies.level[index]; let parent = bodies.parent[index]; + let prototype = bodies.prototype[index]; + let portable = bodies.portable[index]; // let bid = bodies.bid[index]; + let is_building = cst.buildingTypeList.includes(type); this.controls.setInfoString(id, x, y, hp, max_hp, dp, cst.bodyTypeToString(type), bytecodes, level, - parent !== 0 ? parent : undefined); + parent !== 0 ? parent : undefined, is_building ? prototype == 1 : undefined, is_building ? portable == 1 : undefined); } } diff --git a/client/visualizer/src/static/img/robots/blue_archon_prototype.png b/client/visualizer/src/static/img/robots/blue_archon_prototype.png index 787442fa8458974c9d3e475c15142567681bf245..b02d457aece37563986a1cdd87783dca56c83a7b 100644 GIT binary patch delta 580 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 W{SRq(f2aa|&fw|l=d#Wzp$PyjqK1_K literal 1773 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*atr)5S3)gY|9H?Y!FtJX0U9J1{FZ*D$B@&j0#r za?Cu=yW`3{#oo(A#-z-i^x|6QX91=@m9FxMn{+zfEsXpU~f|E?(yQMQ(dRw91v$NzYnim9{=uvuX?P#S5HstMa9*R_)dXB2I-ZNa1?o2XcyTn!7lOF%$QRTs-TjUKBq6)QZy*j#6kL)Sjf5vhc|XT!ETANO3F z9+SS$`&@R3s?2*!u?=fFT#hQ8zkDZQzq_9Gm6_+;1D3p#Om@3rZ@hM1fbvs|X_^WG z2}LTU=DDss^&cHxYzPb~KdfmL7JGQV`xl+Qh|LF|d|*GiK!!{Eqp4}XXyy(jF?Ef_ z5i*VwPfq;nC%1!(H|&XbUrLYiwHyP>Lm`sP+gX#Abemo{)!m?X=ShdDzbk9}9+m^r zWdR3&OgEYwSM=>< z!OyR7f3Ik>>&6?;GS_&g7p3H6Z4KLZ=f@52*KWy06;hLvKEJ8W7Vz!6an;X1lXuZc z!FRux^QpP}xENPgeKMPuo$`!Fa)tR_`2(e&R;JdjGO$b%HRE_LC@AK>CigbZhYeew}Mck7qmvOkqs-L{^z%tyEW)y0W*P0Ya?)>i*i{4;s+l1Vv} zm9IH(nzU*98UIM-uQA$(E}vSkJHu()w1SGef1D(C=IqfdO1<$(sZX5sgv8x*eBzgj z`nGK82tRY!&R^~Ei_cdZzZ}`qP6z730k~kep&Ig@l%BU zt^H~yRiC>3zOlB1U6#E(!Edo@d|!CVl&G`Ygw9v~dm;FPJ^BCHf+g{vI6!5-r>mdK II;Vst0LkCDDF6Tf diff --git a/client/visualizer/src/static/img/robots/red_archon_prototype.png b/client/visualizer/src/static/img/robots/red_archon_prototype.png index 9ff9a44fba508f3fd005fbf6c0868a511261353e..ae95d3392ffa14fe7cbbae81866f7444239fcd42 100644 GIT binary patch delta 547 zcmV+;0^I$`4ZH-9B!2{FK}|sb0I`n?{9y$E0004VQb$4nuFf3k0000WV@Og>004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw0005HNkl)nLxOe1cf{g7RMvYOFuqTNKhiFOn1CV$#Zw2Re@zh&1|+J$OH zP_EZ5QZxQ3s2LC0b+&ean(+`%K_MvDXcvj^1vMkP&eTp;Gva%NAgCD+*>#3?qM8xk z3(8MHIZr!D&4~XN6yhnU8QJxzc7mD_#{@OwA-j%hzd<2>3d(2NhiXQ=E+}6GHRB<> z-qk)(GvYi!Ie(`820Sk@jq(&vh3tA&dr{3eTTp(Ar$TnUqrItIBc94J?L|Q$&Qpl5vg=*#RlCe6#QDlo zb{)~)kX>dJ;xmQ#x9mEqy=#{lXDXj-2V_^xc!>8E;(w_;W!ER#LD^L^3UN#!yUx%) zkX<#S5U(i& zt#-CuW)$Mz3fXmqc7g1w8HJ!cW!F{OMY79`@|0ayYFFB2Ms{7TT`aqPg?1C|CfZH3 ln`k%DZXBZhP&58?e*u>*s=8AXx=H{5002ovPDHLkV1fn5^R)l~ literal 1736 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*W9>)5S3)gY|8ccfPQpK$+YErHoli6f|N4md9BX zKP}&y#b4|3SMaay9m`_oa}6O&eJ?j8oNWGSX5D%Gb!^$*vMp1MCMEaVTF*OgELR;K znB_cMlw%W9uR_$)OUqKOo_Vl$gQkLi)Y_fmXB(&XEDuhszHN5@?Zt^%W-W7kb8>4Z z-}Ko!Tl;w4{5eaW#r0-6mohPKE)keDb5SO%lFB>I&5S|j?yO%uOy;hdd-?L#1U{~m z?|)*>J}XW=ZM5$qEAu5q|2q@6YVdkJjb##@)Wn#XRk`0kPBLi5US5eb#|DKd2^N12?P=_-xW)weJ897uA1##5V&D;K)c?fB zva)Pd>*UM_9abl_y_qDIq{S!fVUTp6=(NhzIV;oD^at0k>9^jnpZIRuxRQrOdslhk zMD8ZWgCCZMNQnH>6s)i`(Pm`iXmOvXp0LL6S+uAb-=THEhKv@>oobUMjs$Gq;`wa66Q3%iI3B2h*+j{c!!SI!Y^vc0>5I`8=rGRYw(X z74J9~5no#RbemZi@4^ROALlJ-zgh6Y(X6_Y?c&*o4;KYK+Abon$NKxZb0X&$Y(Iaf zF}M)(()~*NqRIc>WJ~Q>c4%Q?dCi(`vApR_OacpPwPyUVp25|^JZW#!=B2@o;`%JB z4JzODXV=6s)-L@tldI>4BkOgcEj!($rNf_JJpT7ek9gBzW2Jwh$7J^&{1qUsR1*hIKMP|))!XKHF~dhK1vek zX85&v#iQThqW&sbK@JrMD{M9&dlD<olcHs}m$tvXLXNmk)V3P_Lp(RnxXEXpc|5%?ad$$_6s2JUbmS|UkPvHZtIEpwbqR-eWnu7qHDsYZ^aGMm<)fOlBlT_N_F1HQ?TXOlK8tp z+h3^tO+4__w0Y|KwPybf9=tAHpur%>$0~2MxJCF>FVdQ&MBb@03&9Dg8%>k diff --git a/client/visualizer/src/static/img/robots/red_lab_prototype.png b/client/visualizer/src/static/img/robots/red_lab_prototype.png index 4283697b722539a00ea33113730e951452bd5afc..7bd9d8569e6627dd107f14eb9b1dc6083ac91dcb 100644 GIT binary patch delta 382 zcmeC=o5?&urJg0-(btiIVPik{pF~y$1_s9BAa^H*b?0PW0yzrF9znhg3{`3j3=J&| z48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@h0Pu$bRF(iZa?!mw;Wk&&*gW(gt`+a({ z)hsDO^2_DRyvgA$4QUJ?mkR&ev`NspL-B|}5{F@nM7e(gE)khX>df6gu^>8wf5`EORX=lkH&eYA$cP?<=Kea4JZ|;UgIrmBrZQm5B zYF2V+_om2;oXb0!tsZJ7aco?f~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YpB>EalY!TNUQ$vhE5fi__d#v}V;ln%CXzyEI) zvqM3_<4tvg$^Yw@uNw8mUbVezD>+4TWm5m@nBAx6oxFFCuS_sPh3U7kr>SMngOwX* zdVW(dOgo_Ptna162b2W z-z;Ej-onzorj@UAIY*AnqnyIeXS(0pM1Qbp+PYYPQ_l1GoY35bYPLUA9*HZmPd_su zDQGU!>rhtB$0vRke-zF*$Nfq3{nm%6iR!YiW>4rlJhM`N4Qon9WRaMGn2q2*!DS8# z`_SuQPHA(kMqUc7b)9YOUy-tJSP-+xIcMlb1}8$nB1awj8hr%MU~u@SUHZ} zXbItW1m|Afx&D{+(gz#A z&6@CH!Bl}wZjIB|G#s1lIybpvv7Ud*i<#5Z7tj6@)!t~vTrsO)iQDz5cP~8V94ZQ9JOb!+SMk%hH|Aj78ms*Fv?e$un8|^OSG`HCC!=z~OV-^Q5 zPk%7;Y1lr~yX%x=lw^{am1d=}9NxitU#i)yA|Q`VWyzx{w;cQ5IzOvT)Do8SI-9+4 zo$^jYjg3N=x3Ka&IADCMG0o@TwX=>-4Aea?ta+Sy>y%>{*N10S!B)lB1-}?A&H6X&n}#7pYr?WrfJ{480`u9<}+)}YZjvzW+BxrDUKI8Io8eD<8q@Q zZo<5)lX&wor<&zd^(GXx7f!EuV6|yw&kQ-QDVDnbR$kC^+IQFY)QKs#roVG^aIRE3 zQnAQu?d41JIe%_tTrl&4nsIyN>4RHCoo26i`;=+=uRFHeR(;#mUaPry+JtIDnU&89 zJ14LiDM$aC-Q&`ifv1?`)yr;Y&U}&J;yZXx%IbfiHSRu;C21Dalt!D#asQY zchqCMa~J=QnxD_bxQ?N2;pYQqXLR^}o%+mkuE%4hGrZ4NH_g)ut-gC{)w@|48Cz`2 zl^(Ufvl6=cRDiYkql@ESi9VOW8QQm;pX?Bv&MRFA~Cf<&3D^gyvx%Xbe!AH*zJ>KuG z*8ThN@6f;}KNtRv+#I+=s?trQI_0cE>~>3&$S+>?w-)$p%=3A0?A6KC)9=h?i~ZR6 jsqD{gjyFmMicIy4-ZRgOv~!l70o4bdu6{1-oD!M<^o+UT diff --git a/client/visualizer/src/static/img/robots/red_watchtower_prototype.png b/client/visualizer/src/static/img/robots/red_watchtower_prototype.png index 3246172bc8d28a781fbc8c5e4fd45e645d8881c6..120f1c135ec68de7d5abea0c62e5a5c8b3a5f566 100644 GIT binary patch delta 330 zcmX@Y`;=*dN(0r%1acITJ%W507^>757#dm_ z7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;<2ZTV@L+;-GhNyhaCi54w_&1p7-pD z@NZ>-MI2iei28+dN-%XyfBDQ_TUyYmML^Mo14PvW>5U6=&iREGS&EQ zjH;g2?B!F>mK3)}gw&`NUM%^165>RtOZ8Jf->+r-s%mgZ((u+~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YWz)5S3)gZ1sqlYLhV1llf}7`*9r@R(Ea|M(*| z8HSC#1`a>=PxD^ocginyne|KO=_xlguYbFpYF)VNozHVYi&GpqX;F9ip8V&V7hb)F zsq$Xw-{(TtVz2UttUG1wRUe|aTkp#Bn*X~`+zYbRS@2)<#l9)`%D?^%ei@p#+9vqm zNo!G$T?_qFoOdbfu_+5Ryi2?iSkb`nqTtsHwF4dg_gha@i#E86C}}jA&VA>cvhu^b z)oKf*9&QlRsWpvdTP`)>SCm6kZSC2GIc4iZJxqBte9KxDE-d`FFe#<%%*>@)HJ8q0 z8660^R8s5v>q^k+oZ#8^mvfm67y9@%tetr7hC|yG;ehT+|FduS9gke9UiFi`c+&L_ z)z#clk3!|Q%Jj$T9M;VgKPF?u`TC;K#@;q`=48U&wrObe|p~q=EhB{U(V@tS!K6p?%CwTpN}lLw@SM3B`p=1 zX(zLIug0pCPnYm*tG1lIa#{C2PNw9mS3b==rEBdTHf%lcLJ$ml-xWSg33~>am$Q^-Wrk+p;3#N9BA|maXXdb1cqk@1BO- zd0O{pKINH^W446B{^LZITeo8GT{|LDbG|3VAtAY_P{dtR;i-a_*5#>bPkg_o*ySqe0&v%}#so=a+b^hk&8B9+5=36aoSke;aR`tnn z-t`lwB#nyZTfJCP`f24<+n!*DO~>30?^IA`R@psOUiHnI&pZ>Z>d8Or@nQ3*nP_tS zG;a$3uD{DJ+*7zQ?UiEi>R;;@iypXCyYk?zkS Date: Sun, 2 Jan 2022 14:37:23 -0600 Subject: [PATCH 282/413] Removed singularity from anomaly type --- engine/src/main/battlecode/common/AnomalyType.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/engine/src/main/battlecode/common/AnomalyType.java b/engine/src/main/battlecode/common/AnomalyType.java index f09085be..8b984671 100644 --- a/engine/src/main/battlecode/common/AnomalyType.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -7,9 +7,8 @@ public enum AnomalyType { ABYSS (true, true, 0.1f, 0.2f), CHARGE (true, true, 0.05f, 0.1f), FURY (true, true, 0.05f, 0.1f), - VORTEX (true, false, 0, 0), - SINGULARITY (true, false, 0, 0); - + VORTEX (true, false, 0, 0); + public final boolean isGlobalAnomaly; public final boolean isSageAnomaly; public final float globalPercentage; From be59dbd15d0f3bd145b14a9ba29f628a28ec417c Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 2 Jan 2022 14:45:50 -0600 Subject: [PATCH 283/413] Fixed bug where sages could not attack --- engine/src/main/battlecode/common/RobotType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index e6582108..3e31df1f 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -134,7 +134,8 @@ public boolean canBuild(RobotType builtType) { */ public boolean canAttack() { return (this == WATCHTOWER - || this == SOLDIER); + || this == SOLDIER + || this == SAGE); } /** From a62b60898ffdcbef88d42f1e6d07d6024823b608 Mon Sep 17 00:00:00 2001 From: Pranali Date: Sun, 2 Jan 2022 15:05:28 -0600 Subject: [PATCH 284/413] Removed duplicate code --- engine/src/main/battlecode/world/RobotControllerImpl.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index f1eaecdb..f67336fd 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -308,10 +308,6 @@ public MapLocation[] getAllLocationsWithinRadiusSquared(MapLocation center, int // ****** READINESS METHODS ********** // *********************************** - private boolean isLocationOccupied(MapLocation loc) throws GameActionException { - return this.gameWorld.getRobot(loc) != null; - } - private void assertIsActionReady() throws GameActionException { if (!this.robot.getMode().canAct) throw new GameActionException(CANT_DO_THAT, From bb40b6096f23ec74201ee3b4e00d68c040eb438e Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 16:19:43 -0500 Subject: [PATCH 285/413] Show level on sprites --- client/visualizer/src/gamearea/renderer.ts | 5 +- client/visualizer/src/imageloader.ts | 64 ++++++------------ .../static/img/robots/blue_archon_level1.png | Bin 0 -> 617 bytes .../static/img/robots/blue_archon_level2.png | Bin 0 -> 1309 bytes .../static/img/robots/blue_archon_level3.png | Bin 0 -> 617 bytes .../img/robots/blue_archon_portable.png | Bin 2245 -> 0 bytes .../robots/blue_archon_portable_level1.png | Bin 0 -> 477 bytes .../robots/blue_archon_portable_level2.png | Bin 0 -> 905 bytes .../robots/blue_archon_portable_level3.png | Bin 0 -> 477 bytes .../src/static/img/robots/blue_lab_level1.png | Bin 0 -> 526 bytes .../src/static/img/robots/blue_lab_level2.png | Bin 0 -> 1071 bytes .../src/static/img/robots/blue_lab_level3.png | Bin 0 -> 526 bytes .../static/img/robots/blue_lab_portable.png | Bin 612 -> 0 bytes .../img/robots/blue_lab_portable_level1.png | Bin 0 -> 385 bytes .../img/robots/blue_lab_portable_level2.png | Bin 0 -> 561 bytes .../img/robots/blue_lab_portable_level3.png | Bin 0 -> 385 bytes .../img/robots/blue_watchtower_level1.png | Bin 0 -> 423 bytes .../img/robots/blue_watchtower_level2.png | Bin 0 -> 907 bytes .../img/robots/blue_watchtower_level3.png | Bin 0 -> 423 bytes .../img/robots/blue_watchtower_portable.png | Bin 474 -> 0 bytes .../blue_watchtower_portable_level1.png | Bin 0 -> 352 bytes .../blue_watchtower_portable_level2.png | Bin 0 -> 451 bytes .../blue_watchtower_portable_level3.png | Bin 0 -> 352 bytes .../img/robots/original/blue_archon.png | Bin 0 -> 2039 bytes .../img/robots/original/blue_builder.png | Bin 0 -> 1941 bytes .../static/img/robots/original/blue_lab.png | Bin 0 -> 1938 bytes .../static/img/robots/original/blue_miner.png | Bin 0 -> 2220 bytes .../static/img/robots/original/blue_sage.png | Bin 0 -> 1962 bytes .../img/robots/original/blue_soldier.png | Bin 0 -> 2145 bytes .../img/robots/original/blue_watchtower.png | Bin 0 -> 1773 bytes .../static/img/robots/original/red_archon.png | Bin 0 -> 2125 bytes .../img/robots/original/red_builder.png | Bin 0 -> 2035 bytes .../static/img/robots/original/red_lab.png | Bin 0 -> 1801 bytes .../static/img/robots/original/red_miner.png | Bin 0 -> 2226 bytes .../static/img/robots/original/red_sage.png | Bin 0 -> 2111 bytes .../img/robots/original/red_soldier.png | Bin 0 -> 2484 bytes .../img/robots/original/red_watchtower.png | Bin 0 -> 1732 bytes .../static/img/robots/red_archon_level1.png | Bin 0 -> 643 bytes .../static/img/robots/red_archon_level2.png | Bin 0 -> 1384 bytes .../static/img/robots/red_archon_level3.png | Bin 0 -> 643 bytes .../static/img/robots/red_archon_portable.png | Bin 2225 -> 0 bytes .../img/robots/red_archon_portable_level1.png | Bin 0 -> 473 bytes .../img/robots/red_archon_portable_level2.png | Bin 0 -> 860 bytes .../img/robots/red_archon_portable_level3.png | Bin 0 -> 473 bytes .../src/static/img/robots/red_lab_level1.png | Bin 0 -> 494 bytes .../src/static/img/robots/red_lab_level2.png | Bin 0 -> 903 bytes .../src/static/img/robots/red_lab_level3.png | Bin 0 -> 494 bytes .../static/img/robots/red_lab_portable.png | Bin 584 -> 0 bytes .../img/robots/red_lab_portable_level1.png | Bin 0 -> 384 bytes .../img/robots/red_lab_portable_level2.png | Bin 0 -> 549 bytes .../img/robots/red_lab_portable_level3.png | Bin 0 -> 384 bytes .../img/robots/red_watchtower_level1.png | Bin 0 -> 442 bytes .../img/robots/red_watchtower_level2.png | Bin 0 -> 848 bytes .../img/robots/red_watchtower_level3.png | Bin 0 -> 442 bytes .../img/robots/red_watchtower_portable.png | Bin 476 -> 0 bytes .../robots/red_watchtower_portable_level1.png | Bin 0 -> 344 bytes .../robots/red_watchtower_portable_level2.png | Bin 0 -> 433 bytes .../robots/red_watchtower_portable_level3.png | Bin 0 -> 344 bytes 58 files changed, 25 insertions(+), 44 deletions(-) create mode 100644 client/visualizer/src/static/img/robots/blue_archon_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_level3.png delete mode 100644 client/visualizer/src/static/img/robots/blue_archon_portable.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_archon_portable_level3.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_level3.png delete mode 100644 client/visualizer/src/static/img/robots/blue_lab_portable.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_lab_portable_level3.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_level3.png delete mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_portable.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/blue_watchtower_portable_level3.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_archon.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_builder.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_lab.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_miner.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_sage.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_soldier.png create mode 100644 client/visualizer/src/static/img/robots/original/blue_watchtower.png create mode 100644 client/visualizer/src/static/img/robots/original/red_archon.png create mode 100644 client/visualizer/src/static/img/robots/original/red_builder.png create mode 100644 client/visualizer/src/static/img/robots/original/red_lab.png create mode 100644 client/visualizer/src/static/img/robots/original/red_miner.png create mode 100644 client/visualizer/src/static/img/robots/original/red_sage.png create mode 100644 client/visualizer/src/static/img/robots/original/red_soldier.png create mode 100644 client/visualizer/src/static/img/robots/original/red_watchtower.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_level3.png delete mode 100644 client/visualizer/src/static/img/robots/red_archon_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_archon_portable_level3.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_level3.png delete mode 100644 client/visualizer/src/static/img/robots/red_lab_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_lab_portable_level3.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_level3.png delete mode 100644 client/visualizer/src/static/img/robots/red_watchtower_portable.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_portable_level1.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_portable_level2.png create mode 100644 client/visualizer/src/static/img/robots/red_watchtower_portable_level3.png diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index c7d9ea2b..c63a5046 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -218,6 +218,7 @@ export default class Renderer { const actions = bodies.arrays.action; const portables = bodies.arrays.portable; const prototypes = bodies.arrays.prototype; + const levels = bodies.arrays.level; const minY = world.minCorner.y; const maxY = world.maxCorner.y -1; @@ -270,7 +271,9 @@ export default class Renderer { if (Boolean(prototypes[i])){ body_status = PROTOTYPE; } - const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]]; + let img: HTMLImageElement; + if (!cst.buildingTypeList.includes(types[i]) || body_status == PROTOTYPE) img = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]]; + else img = this.imgs.robots[cst.bodyTypeToString(types[i])][levels[i] * 6 + body_status * 2 + teams[i]] this.drawBot(img, realXs[i], realYs[i], hps[i]); // TODO: draw bot diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index d36eace1..3a5a72b0 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -202,55 +202,33 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { // robot sprites - loadImage(result.robots.archon, DEFAULT * 2 + RED, 'robots/red_archon'); - loadImage(result.robots.archon, PROTOTYPE * 2 + RED, 'robots/red_archon_prototype'); - loadImage(result.robots.archon, PORTABLE * 2 + RED, 'robots/red_archon_portable'); - - - loadImage(result.robots.watchtower, DEFAULT * 2 + RED, 'robots/red_watchtower'); - loadImage(result.robots.watchtower, PROTOTYPE * 2 + RED, 'robots/red_watchtower_prototype'); - loadImage(result.robots.watchtower, PORTABLE * 2 + RED, 'robots/red_watchtower_portable'); - - - loadImage(result.robots.laboratory, DEFAULT * 2 + RED, 'robots/red_lab'); - loadImage(result.robots.laboratory, PROTOTYPE * 2 + RED, 'robots/red_lab_prototype'); - loadImage(result.robots.laboratory, PORTABLE * 2 + RED, 'robots/red_lab_portable'); - - - loadImage(result.robots.builder, RED, 'robots/red_builder'); - loadImage(result.robots.miner, RED, 'robots/red_miner'); - loadImage(result.robots.sage, RED, 'robots/red_sage'); - loadImage(result.robots.soldier, RED, 'robots/red_soldier'); - - - - loadImage(result.robots.archon, DEFAULT * 2 + BLU, 'robots/blue_archon'); - loadImage(result.robots.archon, PROTOTYPE * 2 + BLU, 'robots/blue_archon_prototype'); - loadImage(result.robots.archon, PORTABLE * 2 + BLU, 'robots/blue_archon_portable'); - - loadImage(result.robots.watchtower, DEFAULT * 2 + BLU, 'robots/blue_watchtower'); - loadImage(result.robots.watchtower, PROTOTYPE * 2 + BLU, 'robots/blue_watchtower_prototype'); - loadImage(result.robots.watchtower, PORTABLE * 2 + BLU, 'robots/blue_watchtower_portable'); - - - loadImage(result.robots.laboratory, DEFAULT * 2 + BLU, 'robots/blue_lab'); - loadImage(result.robots.laboratory, PROTOTYPE * 2 + BLU, 'robots/blue_lab_prototype'); - loadImage(result.robots.laboratory, PORTABLE * 2 + BLU, 'robots/blue_lab_portable'); - + for (let team of [RED, BLU]) { + let team_str = team == RED ? 'red' : 'blue'; + for (let level = 1; level <= 3; level++) { + loadImage(result.robots.archon, level * 6 + DEFAULT * 2 + team, `robots/${team_str}_archon_level${level}`); + loadImage(result.robots.watchtower, level * 6 + DEFAULT * 2 + team, `robots/${team_str}_watchtower_level${level}`); + loadImage(result.robots.laboratory, level * 6 + DEFAULT * 2 + team, `robots/${team_str}_lab_level${level}`); + loadImage(result.robots.archon, level * 6 + PORTABLE * 2 + team, `robots/${team_str}_archon_portable_level${level}`); + loadImage(result.robots.watchtower, level * 6 + PORTABLE * 2 + team, `robots/${team_str}_watchtower_portable_level${level}`); + loadImage(result.robots.laboratory, level * 6 + PORTABLE * 2 + team, `robots/${team_str}_lab_portable_level${level}`); + } + loadImage(result.robots.soldier, DEFAULT * 2 + team, `robots/${team_str}_soldier`); + loadImage(result.robots.sage, DEFAULT * 2 + team, `robots/${team_str}_sage`); + loadImage(result.robots.miner, DEFAULT * 2 + team, `robots/${team_str}_miner`); + loadImage(result.robots.builder, DEFAULT * 2 + team, `robots/${team_str}_builder`); + loadImage(result.robots.archon, DEFAULT * 2 + team, `robots/${team_str}_archon`); + loadImage(result.robots.watchtower, DEFAULT * 2 + team, `robots/${team_str}_watchtower`); + loadImage(result.robots.laboratory, DEFAULT * 2 + team, `robots/${team_str}_lab`); + loadImage(result.robots.archon, PROTOTYPE * 2 + team, `robots/${team_str}_archon_prototype`); + loadImage(result.robots.watchtower, PROTOTYPE * 2 + team, `robots/${team_str}_watchtower_prototype`); + loadImage(result.robots.laboratory, PROTOTYPE * 2 + team, `robots/${team_str}_lab_prototype`); + } - loadImage(result.robots.builder, BLU, 'robots/blue_builder'); - loadImage(result.robots.miner, BLU, 'robots/blue_miner'); - loadImage(result.robots.sage, BLU, 'robots/blue_sage'); - loadImage(result.robots.soldier, BLU, 'robots/blue_soldier'); - loadImage(result.resources, 'lead', 'resources/lead'); loadImage(result.resources, 'gold', 'resources/gold'); - - // loadImage(result.robots.enlightenmentCenter, NEUTRAL, 'robots/center'); - // effects // loadImage(result.effects, 'death', 'effects/death/death_empty'); diff --git a/client/visualizer/src/static/img/robots/blue_archon_level1.png b/client/visualizer/src/static/img/robots/blue_archon_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..35e3471c2cc4aabd0323c98b383cf07eb9ccd602 GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lt>Qn32_C|*uZ}V1~`Jt zYu~wZhk@@uBi~3@BsWU<8UO-s)j9G6#9pjw|Ebpo&2=@NonC_Nn_9J2f=SFeEZuUpZcTYAjSjSPd<5Z5^ z=H~QMrUgF@H#t^3Xn_C9TQM@Fd3oxzrq3D@lm72J5HX`OWs#{3^Uk=N z*C#9MxCiwAeb!-r@5l_Xs!*M}?uB^~KZ>Th$KSD-c8;OKI8{wEJo8QJ48eEX?2hvP zj;!cotyQqoy*XNP)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU$n@L1LRA>dg!Cg}uM;eCV`|W879I4xYjVtAx?8o8$|DUqQTa`-K ztOJtLEd?=}>1QPpVvG&?n&G-UufqX_9(i8D8>nx=(<4vM#%2o-6^!az&4={F)1L}x z=Al6T2;piln!mYQl;sIM@bsgKW=#$aVom>LV==xRUd(^cq+A&t^Yr7FMOY#n_hQRM zc1%KHGX5Eo38;WVM?Bq|SFs+o4EW5kvP=FF1<6|A1gPnNr&|sfwG4PFkN*eBAc}jj zf#mN1qXV99HN+LqIRREQ6g*I2vE@8_O(f$;p6-Y!Ub2cyN*X{E8^SRS4KaHq$vA?i z18>drTUfD8;RFN3XTp&};k)eW-=!f3@*L^HOp{R9S!^L0MDf_~p$teS-~_1Iljk^^ zg_?Z`$9prb`GzP+b_WcB6?^a;<`lRkio*V;VafN|@k=OtC5p4`>X~Hh!E=~p1+*Nd zWymehn}wFMTxli^fQB7-_NJ5f=9br?aE!M=q97b!GiIScvK24{R&3$fi`<#H<#i|= z>&H-dpB>ks@T@4#v#Y0)v4v+Z*3N?HiU3DL!SkGHD2%de7Lw-$o}I~}ITGEu359Vo z=25(45!#C61Q^fo>_mf+xjKbH*XHcPAPQ0?D8@Hg~ID_fbrNxcC3I|C_ETt$3m+3 z2G7^r$gI5$HLuCVJI<2P0<9UdP*ddDe_Qd3MtPcA0(o6pGOq;|s}HGY;U{!zanT%T70; za6AFxFY~{#W*o?~ryI#GvePWo6g-C!Bu5o%TGo=WcFGYv2bf4k8vIJsdk&G$Ar@K; zlCd@fRvf`|xJ#0WDE8BWe!~DE3=ph1lIJ+?EW0ubg`Fi2QHZr<2r4?@IgVyhMY5JC zw#pwNij6qGoFsThM?A+Xz<^{cqIg;6UNRDVphKQ+H1MyJnB83pg>MPjkwanQ6y{54 z>5!*0|E`m;kezZUJT;fNmoHhu86ERVCTs+ zjpAM!kl{bTKLODLPfw=Ek*u&*;78ye^vKg26JQ3d;P3Rz(=&kwM9)0^6R+U^F!T+Y TDR5Wf00000NkvXXu0mjfs)j`H literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_archon_level3.png b/client/visualizer/src/static/img/robots/blue_archon_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..254c21fc2cd71d298d60a7b66cbd6173072d1595 GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lt>Qn32_C|*uZ}V1~`Jt zYhPJ!&cOGdk?$`v-%kb*`HO+?4+GzCCJ_3;!1s@l?-v{IXBNKijJ)rd`Mxpo{rms_ ze}?|foj^1AOM?7@8JL*aSUFhOnHX6a1=!ilc@Fdgr5KaE-CYzmXWKRa*|DB3jv*e$ zr%vlEYBu0;@x68F(vqnP3$N_`^uIn*vRLBwrln^M4o}!~bF0#6iNh-mvl{0ys1`FV z>F;~N8E9yr5GSj=j`7X}mUmSX1bcsPOm|B(`w=mLbECLnH~XXIyC)kMtmCNKaVke{ zb94GB(}JIdn;a{iG%ml;Y_g`uAS@wyVQRzk84g)q1VywyHOE+_SMV>E>L4qgj1tC0@EU zE}KyBa>25aw;$eKyT04>lIhywpr+ynamKI^c*cVvcGRj5u~_rko0A4OB$GR$sMyK407)^D-#(3qQBI V!>d)sv&%q{>gnp|vd$@?2>=N~>;eD) literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_archon_portable.png b/client/visualizer/src/static/img/robots/blue_archon_portable.png deleted file mode 100644 index 05134474e2d6026b16baa250892a897d4ceae9f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2245 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_lab_level1.png b/client/visualizer/src/static/img/robots/blue_lab_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..7a22eae260a73698ca20cebee4989b1285cdc61f GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lt>Qn32_C|*uZ}V1`xV) z=MKNvTS3v+JYw%T#XfL~edHH?%P0CyK=cil*arsj@7!WH2-yx%aX)Y7j zM`I7kqeTVZc=)v%{QG0JgS03ft1&({~r&FT+J>Cx@Gnv>xx2%^bF4X zB{#W)9FxjUtT9?NopZ{&cM+v literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_lab_level2.png b/client/visualizer/src/static/img/robots/blue_lab_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..17adbf82f007be6fb9de5ea342d8b1cf3549e645 GIT binary patch literal 1071 zcmV+~1kn45P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#tw}^dRA>d=!GBL%=NSOd^IX4nY)C_@6xh1{Iqmy@ph=acR;tNb zLil0qYu{&h4y6wGH4RPba!&C~6wgHQOcZ~Nuo4J#NMBI#`xVTsJH;Hu${a6{=wX2# zMhGN2TqE(7Cn~mU(77{4pdc~DYmXOJ(w!gBLqVdCH%KdKi(*7Y#PD|DEkL4ySvEYKh^ z#{hFQ=+IX;MWdpq>)URDZ+w2KqNpo&$3jI>ckSuIN_v`9QPdS%WfalP5g4LDVu8RE z>At`SSA^|CMNv2Kkv`eF(--!Rezw$P=OH6>(P*;skml`SURd*Q{0nKNhfYON@rr|Q z$TPGEERIgS%(*q$*=D9k6oZ^=bgpCIS4U??=;uNkJvaV2IeF9VnH%B~eO%bA*y8l? zt)(^wmWDa=DTdj)j)7Seo3zn$YjpIpM3=2SY4P?@O|ixMw}<|Yf(fpV&J1(rQw(#a zjbfqkTOpPYz72Gk#OCaCBx8152UvYP|2-W<^CMDj3VIg%U`fjDhLS0cYvE60tiQ`MDQIj6ln7dNkN(S9DK(bD!nfm>{)-W=(5Wjb(wFh|c;5s)bO`)-Jh3!IFK3(_s3~^9FUJ!#ix}u* zVY8wlkp3EqinKdIT~U#CN2n_*0%WYe&g7yxa*!?I#tU4^hOkLd6?23eSF-fSF>C3p^ei1ud@OWQAlym!1v-8@mEREyA6)qTiYICbH#+x3TGOCI`XJp3 pPgQ(AY2CtSR6G;KGf_Mf{{z1YOWpy%RA>MI002ovPDHLkV1la#=nwz^ literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_lab_level3.png b/client/visualizer/src/static/img/robots/blue_lab_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..9f18b2035bfa8a6e493ff6aa2640037bca5e06a1 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lt>Qn32_C|*uZ}V1`xWk z-ke|Tt)S>@9;r@NcW$w_Tw?DT#lJF&e_;^+#3cTi zLHrw|_%~*;56og8S;XG||Nnnh-_ChJJGe@M{DK)6nV4Bv*%?`wRmG*|0!0~H2-yx%aX)Y7j zM`I7kqeTVZc=)v%{QG0JgS03ft1&({~r&FT+J>Cx@Gnv>xx2%^bF4X zB{#W)9FxjUtT9?NopZ{&cM+NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBsPB=d zi(^Oz>)nHndD5v83>Usz#wQ+S^*GA3@ZOvF^R~NYe~sa7Y`GQJz^k#%eu>mcN$Z)N zGmn^lj*IHtB9y6m=`{y?;{my+U6-B;MJHFEZfU)=hxc2b+#GIwalTU*)$d5}cDB?o zzO=`_;Qb40n;-8_?fibs?1tp+1vbjQ+BpI1vil9fZY;1-JgdEZv5oRs?c_wAfVlhb zZ#+=1F;qUwo&5BUb`gu7^s*>b<%@IVqU^w9bw}B!G+P^A>Y2atzRXwW%G|#Jet#})y|LS2 z);eQ%({gBY#fN5Uq7s#KQnzP}1%a{L~zW0E`qxV(R4wqewvE0jlEws6|)j;)b zL!E~A(y1QW6T_6&x~GF2{M#$w}QGLQ{c)oj}t{b!`-TS~OoCP3kTH`cZ7PN|~6)>DJ|~ r8+pHJq#p`;`F6_2x#m+K_SG}IY^aK1EpD6+Oa=^|u6{1-oD!M3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`zU6XFV_v4Q^#3?Ovp z&Yg*~{{um8{e{^;bzCJue!&ckOw25-?2IhTs^U^}fuf8_-tI0ujhh3Lft+ogE{-7< zr;`&Fa3+Wt9npGs;J{WcCb0z_+6D()SRA!PSRWXz4r5hVnH;s1OYNv?L*5Uk89Z%U z4Nf<>85=0Pbhc>bJ`%}PV&NlsnEh!@KlQlmNAN^6#NjmeAT4*;EMVQsTL17*`Lj4 zs<`#uX~~Y*1w0*03p%r|da>y^1PD|cIz=-uoMP-hmAzRg7!(+uu6{1-oD!MNS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBsBgWe zi(^Oz>)nHaeYXrm+Ah9ttG_k%*UjvYo6T=^O^99@qU5JAucy(ow(ms?2v+btKE=SS zcA!#uPJ%b4b9FL$~UtMQlNT+Q6gX;au9IAt=- zVLxKV&UT=3J*R;eA5TMZ`-c($G7O5hGn+=ffKVB{eYV8{9&ov z==dgmir)bb>Ezq_S}wb}6Kaeva(=8jHuba9qM6b+KsMhvuPLEvt(#iUAH1Pd=5;f&>tM#jO_#lF98aB_&2!+0?4$oi9~(ekwpbz2V|#@02uKf5XO1BI z1faSSCm56o;W;Mvh#|>f8q_jokDHmQR*Eoa_S2oG?Ad&v^_>Sbeli?WPMX}?@Nv2} zoAqX(L0W8&`4$5Wou8(hpmQX_&sh9ME8C*Eh4TZY8aNBWdcq!+&biboE;LsF2!AkZ X+ZRS|kP!q%F9U<8tDnm{r-UW|>~Q99 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_lab_portable_level3.png b/client/visualizer/src/static/img/robots/blue_lab_portable_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..5af7ec12bfe7dd9209611d677ef7fecd23eb736d GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`zU6XFV_v4Q^#3?Ou6 zz4^r1|AFA^eKA>}I0}4OnJO z{IgkFQsHO1xs`$!f0wOC)dHo24N^x3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`qR6XFV_k->i`=l`8M zcNoOKGl+j<7XQd7{*_7m^Z)<x60>RvYwrp zX}qAS!N^$pfzt~k1?9AJmX^#ej;S*gjI4eVZ>CpT&tZWmm~s;uo`y7BuQ*GmP@p7<1q9Z%yHIFor`%FgCD vYgTe~DWM4finEFI literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_level2.png b/client/visualizer/src/static/img/robots/blue_watchtower_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..8119f3738f4b9e322e0f629b6c90e1e0cd2068da GIT binary patch literal 907 zcmV;619bd}P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#2}wjjRA>d=!CR9OM;HLm(@jGPSEJ^}WB&io$|DuaOYI_AVERjN zYK!R3Kw~sedrt906i-C)L=?vr>|BS0FrpY2dUb{k`MKU5X4sGnm=PPjjEszoj1KoC zkA)*9=tu?>!(P~1to}w^2Va0ziC)SvwLq;HD?I5Z4Lbf->Ga}F-&|!lxE~7K7=p}@6EIwLG_STL| zs;YRfU95d@z6mI=n)=Xme`m+gcsWZ6zq zb!PTw(@Yg|x~HJD-Rw4y;c&z*xHCBnbV$QsSDa$3=#I?pX$ z5^Ma7-;mMib=uu(Q#7c~vt6ux5cb~MOTJdtrf3kpM)ECev?&@SmlN6)S1xH&G?-xP zx)lww>sMU4(5AR@Nt@!z6?9H3u3XioXi#0h;ij0heimVq7Dk`#G zLP0@A)~i?{988c9n6oXoB^gl+ipj6i?#*IlFR7|x>)T7J2O)dV`CL-{w7l88WoAGz z;FYxdbFuayWZz53T7>M~Vl|yEZ(>XGg<`NxP;`fjA~dh;5`}Pb4f3ZOGrq1;UEwi1j1t#JCXs#u<%$o hEfBu1FrauM{s#Ac001}C(?b9N002ovPDHLkV1j}GjVS;C literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_level3.png b/client/visualizer/src/static/img/robots/blue_watchtower_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..4a12d5f50f61a8e01328feb2b4dcd3eb2e7125d4 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`qR6XFV_k->i`=l_-U z<_zNB8N|Oai+^Mk|H>r(`Tzg_hgST!0aUD8`uN?e4;t zzt_MY$hqO^;uvCaIyqs1S;7&4z=lh*4i^p_IKa5*p$LaT`MEik+$x)kpPdnQ$a;2W zrtyNR1|wtX2Tm`H6qM7>Sz0o?IHt}}Fw$yqzdI+%#qoau zBjGKTrU+od*V|dc07$+;7sO$DLb3r vu<_|s@+mQ&`R=7~O82NM<1-D5W)lX6kDKNy@S1ua0)>*NtDnm{r-UW|R$Yq2 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_portable.png b/client/visualizer/src/static/img/robots/blue_watchtower_portable.png deleted file mode 100644 index 03388193edc2873dc7c00541eef02ddbb1444b08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 474 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBs4v3P z#W5s<_3lB#yxR^Ut`~o=y}rzQ?wUT+>qcMK=&ifEwC8|0BTvGSd5VeA%ANmZCboDu zsVHvawD>H+WFWif{2T6DXZAg?-K?J>kb8fJ#?>!pf;TJ;xoqt3=)ZDV`n)E&i{EB9 z3&tngosXFq!J1&VAmnr8(plNU+QkKrD&{q`njiT%gKcBtye9S(DVO*STnU<2?;N&a z6<1G4Y`&5HEbh|KPl!v!E9AIx#aP9$5dWTBv(~M}e)PasHhd5)arv zoXPEEoL8CJ!C*W?;&=?pc11Rgt9NFB96L$CvqQy2NQo2T_HV503g2cjBLr`hKl;Zq z=cdB8nf1>!cPzGF)5Lf2iSUt~A)h^-Y4Wh}F48==be4PYs+r3T1oi+;ll?3r)0t7t zbmo84)R)`}4GF1nk_PeOCLLy<=iN*{(32|VB2>?4xW#`{!c@5_z`$qlboFyt=akR{ E0Q0T0asU7T diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_portable_level1.png b/client/visualizer/src/static/img/robots/blue_watchtower_portable_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..1c73f651ad0614107ef3cda7bb4a667f68dfaa0b GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`hO6XFV_k->i`=l`8M zcP7sM4+J&wO!h!Qj*=k1UYu8a#`!hoE)o-U3d7N?UF z7MLX*5eRI!B>_rojPyW+NsQmZc7dd;}yz8rHOD zNV3l{;^O$ffN{oj(+gX+9AIu{_FdMPF;g<&e$qt7O-co)3IYPv7^d_1ZJ+q~@gTe~DWM4fwr6d# literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_portable_level2.png b/client/visualizer/src/static/img/robots/blue_watchtower_portable_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..a4bce8c0b8d1d41f27394887b154565b483f1377 GIT binary patch literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBsL#>U z#W5s<_3lB(yxRsMt`~nlHh*hmc`eG~nUVFHh2hLv0xF8GCL42J&sUx#;Mt*a#EvmM z&Y2<2p=ajK1?SJO#sewmFMl5`Gc(>aCBZ*8Ek*O72bk=5@%!w_j`@c7)8BdIFd6(` zX!bdF>&$9l>EfbCHTN2(`XBi@gKuN9=0R>F*(9ACEE}$+%}dlgc$PKdrsA_RpV#^T zEn}P}bmmIhJ5L$)7X~f|PR;FP=QdymJL4daU;>|7Uvgg4aRK%fXKiMAIH@RtUFagD z#5u7A#C_HzEKvN61xY~9W`2XV^%1+z=YyKme;rnn5QyF95R+}ZK1DN8;e|kK;o7r% zX5BgybjaaDr-u`dj;e+5#qVr0`kQ(sxfL1`lJ7|x*o&8R*nOTl(>S3o)yhSvp0W3w W*As4ElQ+OnX7F_Nb6Mw<&;$S?T&G(A literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/blue_watchtower_portable_level3.png b/client/visualizer/src/static/img/robots/blue_watchtower_portable_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..28ad950a71b380e1c0e0eae7f49d623cc782a357 GIT binary patch literal 352 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 aTz|No+>;ho{R|KW)lHtRelF{r5}E*R_VgM6 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/blue_lab.png b/client/visualizer/src/static/img/robots/original/blue_lab.png new file mode 100644 index 0000000000000000000000000000000000000000..062e43c2078dbdffd3f52d2b74a9049825effb41 GIT binary patch literal 1938 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�YWnO_RI&Pgb?=AzmLKyqcU_&otlZ?|-@g@i zcX)4I&eHt+*Zakx&m?Zme-Nk15tOX2x*_lG6t;r-nRol%y4>JVn*Zang?*H8l)!Gj#mYx^WL$9nf1K|{`2+J)6RLTB=^xAmRal;`elF{r5}E*kZxM9> literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/blue_soldier.png b/client/visualizer/src/static/img/robots/original/blue_soldier.png new file mode 100644 index 0000000000000000000000000000000000000000..c773272996b2926311d190ed54e7e8aa17b103ad GIT binary patch literal 2145 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/blue_watchtower.png b/client/visualizer/src/static/img/robots/original/blue_watchtower.png new file mode 100644 index 0000000000000000000000000000000000000000..09532afe5429f04c48d71cd97e136fbaea79397a GIT binary patch literal 1773 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*atr)5S3)gY|9H?Y!FtJX0U9J1{FZ*D$B@&j0#r za?Cu=yW`3{#oo(A#-z-i^x|6QX91=@m9FxMn{+zfEsXpU~f|E?(yQMQ(dRw91v$NzYnim9{=uvuX?P#S5HstMa9*R_)dXB2I-ZNa1?o2XcyTn!7lOF%$QRTs-TjUKBq6)QZy*j#6kL)Sjf5vhc|XT!ETANO3F z9+SS$`&@R3s?2*!u?=fFT#hQ8zkDZQzq_9Gm6_+;1D3p#Om@3rZ@hM1fbvs|X_^WG z2}LTU=DDss^&cHxYzPb~KdfmL7JGQV`xl+Qh|LF|d|*GiK!!{Eqp4}XXyy(jF?Ef_ z5i*VwPfq;nC%1!(H|&XbUrLYiwHyP>Lm`sP+gX#Abemo{)!m?X=ShdDzbk9}9+m^r zWdR3&OgEYwSM=>< z!OyR7f3Ik>>&6?;GS_&g7p3H6Z4KLZ=f@52*KWy06;hLvKEJ8W7Vz!6an;X1lXuZc z!FRux^QpP}xENPgeKMPuo$`!Fa)tR_`2(e&R;JdjGO$b%HRE_LC@AK>CigbZhYeew}Mck7qmvOkqs-L{^z%tyEW)y0W*P0Ya?)>i*i{4;s+l1Vv} zm9IH(nzU*98UIM-uQA$(E}vSkJHu()w1SGef1D(C=IqfdO1<$(sZX5sgv8x*eBzgj z`nGK82tRY!&R^~Ei_cdZzZ}`qP6z730k~kep&Ig@l%BU zt^H~yRiC>3zOlB1U6#E(!Edo@d|!CVl&G`Ygw9v~dm;FPJ^BCHf+g{vI6!5-r>mdK II;Vst0LkCDDF6Tf literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/red_archon.png b/client/visualizer/src/static/img/robots/original/red_archon.png new file mode 100644 index 0000000000000000000000000000000000000000..43e4085e36d8453316b2dc34abbc05bf555f7b6d GIT binary patch literal 2125 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/red_lab.png b/client/visualizer/src/static/img/robots/original/red_lab.png new file mode 100644 index 0000000000000000000000000000000000000000..4283697b722539a00ea33113730e951452bd5afc GIT binary patch literal 1801 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YpB>EalY!TNUQ$vhE5fi__d#v}V;ln%CXzyEI) zvqM3_<4tvg$^Yw@uNw8mUbVezD>+4TWm5m@nBAx6oxFFCuS_sPh3U7kr>SMngOwX* zdVW(dOgo_Ptna162b2W z-z;Ej-onzorj@UAIY*AnqnyIeXS(0pM1Qbp+PYYPQ_l1GoY35bYPLUA9*HZmPd_su zDQGU!>rhtB$0vRke-zF*$Nfq3{nm%6iR!YiW>4rlJhM`N4Qon9WRaMGn2q2*!DS8# z`_SuQPHA(kMqUc7b)9YOUy-tJSP-+xIcMlb1}8$nB1awj8hr%MU~u@SUHZ} zXbItW1m|Afx&D{+(gz#A z&6@CH!Bl}wZjIB|G#s1lIybpvv7Ud*i<#5Z7tj6@)!t~vTrsO)iQDz5cP~8V94ZQ9JOb!+SMk%hH|Aj78ms*Fv?e$un8|^OSG`HCC!=z~OV-^Q5 zPk%7;Y1lr~yX%x=lw^{am1d=}9NxitU#i)yA|Q`VWyzx{w;cQ5IzOvT)Do8SI-9+4 zo$^jYjg3N=x3Ka&IADCMG0o@TwX=>-4Aea?ta+Sy>y%>{*N10S!B)lB1-}?A&H6X&n}#7pYr?WrfJ{480`u9<}+)}YZjvzW+BxrDUKI8Io8eD<8q@Q zZo<5)lX&wor<&zd^(GXx7f!EuV6|yw&kQ-QDVDnbR$kC^+IQFY)QKs#roVG^aIRE3 zQnAQu?d41JIe%_tTrl&4nsIyN>4RHCoo26i`;=+=uRFHeR(;#mUaPry+JtIDnU&89 zJ14LiDM$aC-Q&`ifv1?`)yr;Y&U}&J;yZXx%IbfiHSRu;C21Dalt!D#asQY zchqCMa~J=QnxD_bxQ?N2;pYQqXLR^}o%+mkuE%4hGrZ4NH_g)ut-gC{)w@|48Cz`2 zl^(Ufvl6=cRDiYkql@ESi9VOW8QQm;pX?Bv&MRFA~Cf<&3D^gyvx%Xbe!AH*zJ>KuG z*8ThN@6f;}KNtRv+#I+=s?trQI_0cE>~>3&$S+>?w-)$p%=3A0?A6KC)9=h?i~ZR6 jsqD{gjyFmMicIy4-ZRgOv~!l70o4bdu6{1-oD!M<^o+UT literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/red_miner.png b/client/visualizer/src/static/img/robots/original/red_miner.png new file mode 100644 index 0000000000000000000000000000000000000000..15319db2f19ca41dadb5e2ac53b30d3b5b769169 GIT binary patch literal 2226 zcmZ`)3sh3s8a|*BXeQX0`x2wL99%>+H!=n%;_#FzfFvR+ASXr`0g5<@ zNdltC)ntJ|RA6NqZvrk*gbA)DEV>^^=JI1eN1OxB*2GO61VIu%I+n0K@^|O6SBEU zpwc%YlAA1aH8D{ZT6#X8Q^<~8u9PHLd@aQb;*~piJDe?k$y*^MDYHZtGe*EoOji24 z+1uKZ7P$YDU9R+5;TOjhaut2xv!iH9!Wce}ujt8wp0KF?|BSD_mWyvsVhi2=HTWw1 zwQ9%m{ugKdGP|fC;gv1>qJ^LDXCbS&AUAaqe(AE^)K`UiD!w$eY8u7UKTd5VD1qC% z;Tto{SyY>r^V=K}F?{3@q~*QFv}Gf|#Vyggr_8eOQjtNUN$|ZpwA1@9SmyIh@hVgh zMJ|}`Yne0EF`nmEqOKsH9OefKeL{H+hZk&MtfOa+S;nRAFnf|es9=?|3yF7l@tcO z3>qE0)T?9IhG>tkCw{bAE@nbnkU3`%%k7$Imkg))7JNiZ98bn*6Dt(gIqymb-tL~xHCW16I@%& zwE?;f+%;i!XCGkjSBIgS^ud0hOmyhXj=xt;5Md`Sy`EhqJ-UKmU@fmt{w8td7~&@k1MSWDPu#SPUgw`kvuIYh3)?w%-X80VFo^CS|2oc9#@)8dAoKoKkVyb$5JCAp1 zUyk`XABYcnMeQ)XVrL%(e9z(A8=Q3QIv;BUHSw}@(o?%vwCO3z+bD;8E-bf?EpX7r zU`l_Tw~>zRn@7ByKzP%&ZSEwR29E!L-vQ z$Sswmw$io>nz13b%;M`F-58%4FPE9|9$jN3%JEvff(-|ppJdIXk=6wA{z&#J%EW(* zZQssdnU~bvG@POALkO(eADc1+gXGnX-l$npK4TyEiS~^Doa2UrQY**o8m0%&KO{Zd ze6lIi=h>JfMcT2VXz-OBn|F*4xBU;rx4T;p?tlzwvhcl8z~53@KR0ZA!T4~|RQ|D> zw^rxc9Y1oHEVE=jwk@>S+`1_x;AHsq^uf9Ax9$?KY5{K<|+B5EL?F z4J$+orv76<*skIG#UDJ+HxFR4M77TA(nu@cy{kR5wM!s%yVF3iT(2U2=sIek5sKbA z45-HJg=VS9GBk9|1B*aWw?Gw{H+wgqactL6Y@P1e)UejgKOiMr5_SU?V(!NTFfRig z-z^Jg1b{3n+o(@_KFKQ?rI-f~ex{!8nlNqD*R3g!`fG)!xK~O%y$v-dogUI-|51z_ zN6*~q%!M>~{027o2%&J8q>7xlX6Whe`*)mP=x=*UcJy6$jM-wLy>aG)`71)zTm=H2 zMi{r@Q3F20iuTxbhyy*5E!A<1O4Z=2^|Hx}`^z=@1$Pr(ZlJt_)=26O`gBje&U~F_ zVS6+~-s;}+0===u3V)zMw6lIBS~H|vuB#;mLP>dlL2$ E4-1rPmjD0& literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/red_sage.png b/client/visualizer/src/static/img/robots/original/red_sage.png new file mode 100644 index 0000000000000000000000000000000000000000..d80e3d33a5139e7bc812186eac2b56c30e38f6dc GIT binary patch literal 2111 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 B1gro6 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/original/red_watchtower.png b/client/visualizer/src/static/img/robots/original/red_watchtower.png new file mode 100644 index 0000000000000000000000000000000000000000..3246172bc8d28a781fbc8c5e4fd45e645d8881c6 GIT binary patch literal 1732 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}EvXTnX}-P; zT0k}j11lpN12aeo0~3&tVqgWc85q16rQz%#Mh%3T_DlvAsG2As4Pxqm2sq8WfDx)1 zD7JtJuG(k;GlC7$_d)d3e;~zK;1OBOz@VoL!i*J5?aLS#nD{e8B1$5BeXNr6bM+Ea z@{>~aDsl@zx)^LKtboki)RIJnirk#MVyg;UC9n!BAR8pCucQE0Qj%?}6yY17;GAES zs$i;TqGzCF$EBd4U{jQmW)z9|8>y;bpKhp8 z8yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{5kaZN`8lN^^X-fc3~az^QA80oL39LU|?L9@%zWd~uGzl*YWz)5S3)gZ1sqlYLhV1llf}7`*9r@R(Ea|M(*| z8HSC#1`a>=PxD^ocginyne|KO=_xlguYbFpYF)VNozHVYi&GpqX;F9ip8V&V7hb)F zsq$Xw-{(TtVz2UttUG1wRUe|aTkp#Bn*X~`+zYbRS@2)<#l9)`%D?^%ei@p#+9vqm zNo!G$T?_qFoOdbfu_+5Ryi2?iSkb`nqTtsHwF4dg_gha@i#E86C}}jA&VA>cvhu^b z)oKf*9&QlRsWpvdTP`)>SCm6kZSC2GIc4iZJxqBte9KxDE-d`FFe#<%%*>@)HJ8q0 z8660^R8s5v>q^k+oZ#8^mvfm67y9@%tetr7hC|yG;ehT+|FduS9gke9UiFi`c+&L_ z)z#clk3!|Q%Jj$T9M;VgKPF?u`TC;K#@;q`=48U&wrObe|p~q=EhB{U(V@tS!K6p?%CwTpN}lLw@SM3B`p=1 zX(zLIug0pCPnYm*tG1lIa#{C2PNw9mS3b==rEBdTHf%lcLJ$ml-xWSg33~>am$Q^-Wrk+p;3#N9BA|maXXdb1cqk@1BO- zd0O{pKINH^W446B{^LZITeo8GT{|LDbG|3VAtAY_P{dtR;i-a_*5#>bPkg_o*ySqe0&v%}#so=a+b^hk&8B9+5=36aoSke;aR`tnn z-t`lwB#nyZTfJCP`f24<+n!*DO~>30?^IA`R@psOUiHnI&pZ>Z>d8Or@nQ3*nP_tS zG;a$3uD{DJ+*7zQ?UiEi>R;;@iypXCyYk?zkSNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l*kG232_C|K=7Y|;XM-* zkc1<+_Vf;)Ha{9$JP$ISennfW6#^KWM6U(C#ZnVFp!8GkY} z|6peR&dmIcnfWs_voRy%|Ns9B_N_1lY7;35@(X5QV*JX^!ph9Z%=Y;G-RG}fePv>Q z>)#d!lxIxxc6U+MO3JYUvNJth978;gubtMJcUVEdrE~VZm$nkPmjFbX=<^h;iQ1RamdVCzX|s5XPx`n z#9{Pj>Ex8Brz6vM2^CG$d{P#yqOmS#*=BuV!%440INoiPDvoyE!_%*Me6B-ES{3&N z!AV;(@}$@*)-1ld&3m?C@B2n!ueP(P?Q07%ZlzmT)gP;Ta{QZ`#}4_oQ=F6b27OP6 z@9$H2D=P4~<7wD>ls|i9OXWY^e+*wNq69168*Kx{tf#A=%Q~lo FCIFw=|26;s literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_archon_level2.png b/client/visualizer/src/static/img/robots/red_archon_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..5132c6130147fffe6effd71be7b2bbe4b53ee8a9 GIT binary patch literal 1384 zcmV-u1(*7XP)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU$=1D|BRA>dg!HZH=_Zi0F-}kQn205vScnBI}X=mDLXKE(BgI;&< zpoeLiX(!Vf)MyZa%^?W5VSR67b{q~0?7dlw=P6tb0ZEGrS6~8qdr)Xmp+$z6iO9lF z?A{)X(UL-ozKF<8iG@s-q=N_W?rr8cEhx0)dW4rG0tlO%(&P`oVuaW1pkaj;%taio zNCbV$RmEH;>k`WnPcr?DtpL-ILc?xEctxV(q(k5U=m6hHJjzV$pdp2ZB~bCP4T)c6 z@=W5r=MoPy{n8E^P-xKI2ro-~ihxZZ0nztD;&!IHc5q3BhRjCzwZwV45?^KV4~h2z zSd+M!>1{i>ghB&uM7S$)5dmFJ3SdiODzmq1k1?XcCEbefy2PNKN&GpJzepVSqttnl z+56fa4=_V2T*8+T{;R|=0{9;v6Y#avS;*YRo?%FZ5zR;V?-HZPU{aRV?Ae5?a(NGxRf2Rj%*VF-pY z8?nD3aaqqL<}+E9ILj-ETbb_K3NYs=3}G(fU_+uQ1`-fw>q<;#rfmh7GZY47h?_KP zP2zqg%M$0=k+_?g*ufbJ12A-^BYHa$O-lx|BJnWO-`ff>rxY$=82>V2e@CJX`wZ@T ziTjy}9h_3Qz;wj^jzn8FCFV0(l^Ddb#9XGkc5qDL9ER$1n>Gco$Jq=7Fq6q7unTnf zSpeo2g>&4EI9!ov+m6IyCQl_kI0OXDWfH)T5Ph7@pMd;C`ByRO727BhKPRmgt%g?;CZJpm+_P#8f#&$i|>b5&wk zlQyz9ZTD*E0m&s5MigM|n9cNt#2{+mL0$8rs=($Re70^+(SX7wZQAiT(@PQ;`E6bE z->O3P>zj6G%bo;G0}2gTvh`JF{!QX6HBdz`ZLfZoIlcw+fN4mf0RjF==SJqimc*z0 zx~}fiWU@Fun93=*X~vo2f*ib&9w-&?J-(XXh|2UKV{Z$Z6+dEvV#^CS`v`h*Cr#n qyY>_NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l*kG232_C|K=7Y|;XM-* zkc1<+_Vf-CFI|1dNEV`l!(%>0p=`8PB3FJ|Vy%*;-Vj6a!~ ze=swDXJ-D!%>0>|*_e^>|Ns9%%6gB1+C)l%{DK*n7{9W!urf0;vps%)_xY<=Uzyn7 z`nSaa`YG=#}JR>Yo~SQ9aa!<>70GB#h5LPZlbpOgiwXspXwwpm};aMJ4#j&~cSild$P@bqgQpX-p4R>gfm zaMG5HJSnz{HH)uq^PX+k`@T`wtL^7^~Wlo9RH@~u|xjt6z8P9LEjVN z`}*xk4|l{K|W*(tcr;t*HB%4~qA-uO3j)Kaq55 z(=o{f=Ogx;$Q#MtaL*?y}vd$@? F2>>L?{nr2h literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_archon_portable.png b/client/visualizer/src/static/img/robots/red_archon_portable.png deleted file mode 100644 index 5324d0edf0a2bcfa37af0fc8e8a31fe3f23d6c98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2225 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_archon_portable_level2.png b/client/visualizer/src/static/img/robots/red_archon_portable_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..a582698b82a00a1aae9586c18409cb97961a9cb4 GIT binary patch literal 860 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$Ysfr06k zr;B4q2J6{_-9@(|7+ek-KT4asf8MP9WpdZntmxGik>0?-xxD&=jIhDx#RrS`FebS- z%ZjSZ`03BMaq_`FmSW+Q%PcopkMObm&J^}Dbu44txbdLft(J1%3BJO!6n3|I2ACP$ zh?`yDE1Yt^;l_yvp0gBYtI2>BHXht|t7R)tQA5Rr1nb;GrXW4{KvEwY4w~I+sRl6% zmmho#RyA8~PFB+!F*V1X7athr9txYKP|bFvm+gDD@VkpFH%%VK2&ae(m`nU=1sNET zS+Mv}_k*pR)j&N=Nv#KYxtu@TYH>GpH1plDgmY8$43?)|2YFfSXMOPTonR{tG&NyE zkYiFb$O-E*o8CwYi1UPL)Ckt(A4&&uf!10Y|8RKd3N+;WHI|#k3g>w26e@BL#euxD z2Iv6RBb^6DTbqAapLo{O@agmeu7l^*-mK-^lzGVVri|%B4>Rt*k+UT+EB6xqSerm*18w_{Fb^OtgNmvXSY+;Sdh`kcvUlOA;) zoOwv4I`5G2$z`0+Q#K38OUw}znefK!q4CMI!i3g?sgv%iz40~kwNRaXlyOF6Vu5So zBwO=DeW3lCH+A?9obhVbW?@y??OU;_sQI83P<4(cRJDe=#2WRRK(C~1mN;;xmu>sR zH)e_1n<9N2b{>A<)>@xZpMOX><#LNM&>V-Immjz_$+wE%yg#de9~kN$X5GvNpBoO! zvfSsM{AMSo^o+_25B!>#fEKJ#1x7T;bQv1V)8A(6ycBW+pc}9;Abu|4`_r4x6-ejz@sQrrRyWzz~w<`KAbT>cpJ7 znKw=*sJAx1F|QN0mU`o2z#QKg?(imO!}|OKM}&F4h0l8spKn&VtD56RHZb`!c)I$z JtaD0e0st1KX@&p* literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_archon_portable_level3.png b/client/visualizer/src/static/img/robots/red_archon_portable_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7e917b5ea2ad0490b1240f54f80f34dba62cf0 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`qR6XFV_f#5$XLKXzF zudFx!-`M#7|Npones6(%o{}KHU=fX9uQNyUYq=RhN)m6Lk{OWO+$o+ARf(~COHH z<==MNorXu>^q9?M`&M>I#HE#Cl1`~hLwR7K%QP8BC(AQ}o<&{#&Ve77Ol^Af_(xUX z#}@BE&cYRwqNG+REG_Zy(pcnwdA`TSxcQzPw`cVo@R-Jyq~hHw)P1RHd0T|_rnA>9 zW?yO$^seB25XR`VThBo1bXv7?LZ5YVG2@@epKRIo_iweH{b~1ofyP#ro%2mY6W=`j zpjs#3KJC|Qn_}Oa@1OH{&g7kKH}P5YdSBm&sP!+;i#O&xwdfa6Yfv~CuC(u@R3(FW l>mJjiF>1X#>c3q7!@%}o+q0q*F;$=-^>p=fS?83{1OSels?Goa literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_lab_level1.png b/client/visualizer/src/static/img/robots/red_lab_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..2ece4f8e9e0902e0f14a5346af0baf156fa44cc9 GIT binary patch literal 494 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l<*7i32_C|nBYGH0|ec< zbLStJ{g;8^4+Fz*28N#u3?CU7zA-R-Vqo~e!0?5E;X4DvR|ba9KxO~`>&ZpV1RBRx z666=mz{teR!phFb!mKJTH5Vw#nB?v5BKan7YX^|?$J50z#N+tgX|MU36?j@1@0N&^ zh?iIXSC@TofiZW&5#8eF?P>*fUeT_Sw|gwaMdRPBd+X}9=vdJ3ByuXf8EwJfno_x8FAuI|z?>J)jhiD}ZeK9^aWV&@_vOQjkAa6B-f(7f;{&${Z8Tz)n>+Qrc<-Nh+Aq+M9Tj%2MPa zudG|Cc5~~Ui`O@}yseqGxBX1b$;e+fr?YSKxwGPdeDdZhCg(Xu%bD|+yak24r>mdK II;Vst0E17lXaE2J literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_lab_level2.png b/client/visualizer/src/static/img/robots/red_lab_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..271c3994f3bd302e66ed2f4111fc7f9097b83769 GIT binary patch literal 903 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 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_lab_portable_level3.png b/client/visualizer/src/static/img/robots/red_lab_portable_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..cfba994cc279b1047b678f60debc35b78b049840 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`zU6XFV_F~NTZ1_-*c z-u!=K{}wCV9KN@HB1?Oa^kcdb&7< zSe#BySiqSeVsu37-GKvJxtPQjbZ8qKaA9%O5@CH{v^tDcVP$gERxY)psttKRoM!N} zZ8bRE;AU)~@Y30$nfpj2Q;CI-PQ^Ar&>*5WNvh4Zn`3tamytzH*UPL~I}@(hpD>d7(8B!L zpV8)Rxnhuv#@9tm8H=K}PGaO15IGXpb3u%OVG3jauGPwk!Jx44boFyt=akR{0D!A@ A&j0`b literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_level1.png b/client/visualizer/src/static/img/robots/red_watchtower_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..5c3c7a364c4bee030ae67489bde1a86dae6a0ac7 GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|@CmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lyD0032_C|aPS|@0+M&` z+yRo`7#RLAF#Ka+_{+fXk%8eS1H)SehTjYfUl3 zJXs<8$Gt##M~!Wg3?qkV?UWgjDRrklOpCbG8{ee0&S~k=D^cpRKi0l+u43xa(QZqb R)@%t1J5N_Xmvv4FO#qs3pmG2J literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_level2.png b/client/visualizer/src/static/img/robots/red_watchtower_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..147e1a0611fe468c725373accf9a0e45656986ee GIT binary patch literal 848 zcmV-W1F!svP)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU!&PhZ;RA>d=!P|};)fE8HwNLFCUnby8Kqzng|5qWN0tjI%&cvC% zoE^#a(2Tok`ZU4mme)#Oi1dX>Ux;*`$y0k*BCWWm-kIIvHMVAf9X=2i+)^8}hK7cQ zhCLn$pZJz~Ku00*R|I}C+Y=U~6*uUXeZZY{8|*MSR+ub%fuGSV3+vK~U#xqDvMw-L z7AVW^(5wrTW$6$4JGNBd5szpnG*6XTnBCwtRoJ7j#}A&@u(vGD0_6<5SEo$I4H-yLE;V%lm%(U17Q|l(f{fHZ;#jbl?mN5(rHyLV?y^)cS0Ia&estR z3Xj<0C2ozm!Om%EKse7m9&m?_o!P$;n6N=Otr?RB?49QkTjHH#op?hpgwx8HG~jFJ zx#PzVmIZZ>Fs2)m25g+?k?%cYLKw3*CJlJBtne0p^VB`wTUT^618%W(S{hK61-^Fd zUk-{0%J1CL40?qJr=(*JH_Od1d_r;JHgE{sV7Cf6?wXs%zna%D`qa$!uma*4gu(v|DRqygRaOQ(ek z3S-h~RjyweP%fv8Ndub831iZL$@NPE(&g-oNdsNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lyD0032_C|aPS|@0+LtO zn*+&j3=Dr582&LZ{AFPH$iVQEf#EF!!*2$LFANOd85lk>F#KR(`2YWZX2p#)K#lAr zL4Lsu%#2KoEX+IX+FgJ`j7i?^E}~Cw{9Fv=T=#Tw4DmSrcIr)`!wMX(v6qrs%3 zJXs<8$Gt##M~!Wg3?qkV?UWgjDRrklOpCbG8{ee0&S~k=D^cpRKi0l+u43xa(QZqb R)@%t1J5N_Xmvv4FO#rq0ps)Y{ literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_portable.png b/client/visualizer/src/static/img/robots/red_watchtower_portable.png deleted file mode 100644 index 978dbf9b233f823d5b44693acbb5637422c31386..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 476 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBs4vRX z#W5s<_3lCMJYh!>h67a}Z*NRx6_VL{^?HiCNZC%tgZ&lnX5+`Kh>54)9SGk{rjfdEt6UQ z=I6tTO!a_!3#-c4yt=z`>D;2nm)`C?d~IGy^{JK;hb_;zrgCP+-QdhwT|Ql4ZRNIu z*BCP+ckWrsnkkUUdU2NO)!o5fuQ`RgIJWuetbJf?FYn8Jit7@W+|PGsE^+O9c&~D) z=$-07mw>Qo*MjG@e)iB_ac^$4lnW+|63cUl3d?gq$V6=`tn5^0Uvl`A{l!__zjD>j zcnEj-ehAsSTkT?$qK}7g)ACn$x30YBn%%lVomc5>$F)0?Oy2T6-MS(887oub@;w?; q`niQKZTS=y8K&`COZbw)Kc)x!{d2qCbo~PcKZB>MpUXO@geCxu=e-92 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_portable_level1.png b/client/visualizer/src/static/img/robots/red_watchtower_portable_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..54a28158f2a723e06573d03ab90746d7fb3c1f20 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC?OZ%6XFV_;ov`*1tjm> zx%0oV@&Et-kG5@f1`4v51o;IsFf%eSvM}$kYj*((F(!GtyKsKIx%3T?Gt<+>F~s6@ za>4?;1QC$~T5)_VtUNq#6r}tb9bMhs**(}iwjS10N^x*&XjvfQF@sa7nQOvV0o~+= zU^m8x@+J(QS6R)PmQGjFuMYN<=cQ>Rh{sS$0eEcGg5;IZ2&LJ|*Te-@O!01>A^We5PU1Y{I}W{dd;> TT@yb~2Kmg>)z4*}Q$iB}v#w|1 literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_portable_level2.png b/client/visualizer/src/static/img/robots/red_watchtower_portable_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..fb66afaab5cee2df9b1518767f7328ae21fa170e GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBs88S1 z#W5s<_3lANzsCUrE(gt*ytkcIoL|tKvPAU5eq9B>M=OPVJJei+AEoQnd^iGwyDmx1Xl9|P@x+ro8BTwCf7%v1Cy6%vWDNfpz3$PqBd6xf zv6wHO@Q}OEF3lmQ!)M+ENrB>nS`9}-ZJbg*y<^hJ5%_)PvF;lI-wtLMwd$Cox}A?% znAGd^Qj#CfsBVum8qnS)0P&+L9+cZ4zK=-y7ClRy#~P9}=8fI5NPr1%1+ zr1_SN2*Fx$IsXGwd6Q=U6qspq!9MI@i-bW8)4Fw!X1XkEOmN^~iHSYBxlnXsros=P zF=|SajRlkS8-D6U%-qSq#1Zz)p847PCPu@wea63eW+cyKym&;K<%P#C9q#&Fz%XU- MboFyt=akR{08jRwf&c&j literal 0 HcmV?d00001 diff --git a/client/visualizer/src/static/img/robots/red_watchtower_portable_level3.png b/client/visualizer/src/static/img/robots/red_watchtower_portable_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..369c9a3ca7440665874d5bfa00e164db1858a97f GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_>3?$zOPHh5GEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC?OZ%6XFV_;ov`*1thPm zH~-(*`2YX^DzW0DKtcABAirP+W=1AP7Umsx?Jhte#w2fd7tW72m%agVW_r3fhFF|V zPFP@ Date: Sun, 2 Jan 2022 16:24:19 -0500 Subject: [PATCH 286/413] Beefier javadocs --- .../common/AnomalyScheduleEntry.java | 56 ++++++-- .../main/battlecode/common/AnomalyType.java | 62 ++++++++- engine/src/main/battlecode/common/Clock.java | 17 ++- .../src/main/battlecode/common/Direction.java | 21 +-- .../common/GameActionException.java | 2 +- .../main/battlecode/common/GameConstants.java | 4 +- .../main/battlecode/common/MapLocation.java | 2 +- .../battlecode/common/RobotController.java | 22 +-- .../src/main/battlecode/common/RobotInfo.java | 2 +- .../src/main/battlecode/common/RobotMode.java | 41 +++++- .../src/main/battlecode/common/RobotType.java | 130 ++++++++++++------ 11 files changed, 265 insertions(+), 94 deletions(-) diff --git a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java index 432a6966..5c9df6e4 100644 --- a/engine/src/main/battlecode/common/AnomalyScheduleEntry.java +++ b/engine/src/main/battlecode/common/AnomalyScheduleEntry.java @@ -1,37 +1,67 @@ package battlecode.common; /** - * AnomalyScheduleEntry describes a single anomaly in the schedule. - * - * You can access information about that anomaly's round number and type. + * AnomalyScheduleEntry describes a single Anomaly in the Anomaly schedule. The + * schedule of Anomalies is predetermined for each map, and you can retrieve it + * by calling {@link RobotController#getAnomalySchedule}. Each schedule entry + * provides information about the round on which it occurs, and the type of the + * Anomaly. + *

+ * Note that the Singularity is not included in the schedule. You should instead + * check {@link GameConstants#GAME_MAX_NUMBER_OF_ROUNDS}. */ public class AnomalyScheduleEntry { - + /** + * The round on which this Anomaly will occur. The Anomaly will occur at the + * end of this round, that is, after all robots have taken their turn. + */ public final int roundNumber; + + /** + * The type of this Anomaly. + */ public final AnomalyType anomalyType; - public AnomalyScheduleEntry(int round, AnomalyType anomaly) { + /** + * Constructs an AnomalyScheduleEntry using the given round number and + * Anomaly type. Note that this does not actually insert the Anomaly into + * the schedule, but only creates a local object that you are free to + * manipulate. The global Anomaly schedule is fixed and cannot be changed; + * to envision an Anomaly with a Sage, see {@link RobotController#envision}. + * + * @param round the round number of the Anomaly + * @param type the type of the Anomaly + */ + public AnomalyScheduleEntry(int round, AnomalyType type) { this.roundNumber = round; - this.anomalyType = anomaly; + this.anomalyType = type; } /** - * @return a copy of the entry + * Constructs a copy of this schedule entry. Note that this does not + * actually cause the Anomaly to happen twice, but only creates a local + * object that you are free to manipulate. The global Anomaly schedule is + * fixed and cannot be changed; to envision an Anomaly with a Sage, see + * {@link RobotController#envision}. + * + * @return a copy of this AnomalyScheduleEntry */ public AnomalyScheduleEntry copyEntry() { return new AnomalyScheduleEntry(this.roundNumber, this.anomalyType); } /** - * Returns whether two AnomalyScheduleEntrys are equal. + * Returns whether two AnomalyScheduleEntry objects are equivalent. * - * @param other the other anomaly schedule entry to compare to - * @return whether the two anomaly schedules entry are equivalent + * @param other the AnomalyScheduleEntry to compare with + * @return whether the two AnomalyScheduleEntry objects are equivalent * * @battlecode.doc.costlymethod */ - public boolean equals(AnomalyScheduleEntry other) { - if (this.roundNumber != other.roundNumber) return false; - return this.anomalyType == other.anomalyType; + @Override + public boolean equals(Object other) { + if (other == null || getClass() != other.getClass()) return false; + AnomalyScheduleEntry casted = (AnomalyScheduleEntry) other; + return this.roundNumber == casted.roundNumber && this.anomalyType == casted.anomalyType; } } diff --git a/engine/src/main/battlecode/common/AnomalyType.java b/engine/src/main/battlecode/common/AnomalyType.java index 198b941e..670e4ea9 100644 --- a/engine/src/main/battlecode/common/AnomalyType.java +++ b/engine/src/main/battlecode/common/AnomalyType.java @@ -1,20 +1,76 @@ package battlecode.common; /** - * AnomalyType enumerates the different types of anomalies in the game. - * You can also access properties about these anomalies, such as their strengths - * and whether they can be performed by Sages. + * AnomalyType represents the type of a scheduled or envisioned Anomaly. You + * can access the type of scheduled Anomalies from + * {@link AnomalyScheduleEntry#anomalyType}, and envision your own Anomalies with + * Sages by using {@link RobotController#envision}. + *

+ * AnomalyType also provides information about the strenghts of each Anomaly, as + * well as other properties. + *

+ * Note that the Singularity is not included in the schedule. You should instead + * check {@link GameConstants#GAME_MAX_NUMBER_OF_ROUNDS}. */ public enum AnomalyType { + /** + * Abyss causes proportional amounts of metal resources to be lost. When + * global, the entire map as well as team reserves are affected. When + * envisioned, a local region of the map is affected. + *

+ * {@link #globalPercentage} and {@link #sagePercentage} specify the + * proportion of metals lost. + */ ABYSS (true, true, 0.1f, 0.2f), + + /** + * Charge deals concentrated damage to Droids. When global, the top + * {@link #globalPercentage} Droids with the most nearby friendly units are + * destroyed. When envisioned, all nearby enemy Droids lose + * {@link #sagePercentage} of their maximum health. + */ CHARGE (true, true, 0.05f, 0.1f), + + /** + * Fury deals concentrated proportional damage to Turrets. When global, all + * Turrets are affected. When envisioned, a local region is affected. + *

+ * {@link #globalPercentage} and {@link #sagePercentage} specify the + * amount of damage dealt, as a proportion of the Turret's maximum health. + */ FURY (true, true, 0.05f, 0.1f), + + /** + * Vortex upends the world by transforming the map terrain. It can only + * occur globally. + *

+ * The values of {@link #globalPercentage} and {@link #sagePercentage} are + * unused. + */ VORTEX (true, false, 0, 0), + SINGULARITY (true, false, 0, 0); + /** + * Whether this type of Anomaly could appear in the global schedule. + */ public final boolean isGlobalAnomaly; + + /** + * Whether this type of Anomaly could be envisioned by Sages. + */ public final boolean isSageAnomaly; + + /** + * The strength of this Anomaly when globally scheduled. The precise + * definition of this value depends on the Anomaly type. + */ public final float globalPercentage; + + /** + * The strength of this Anomaly when envisioned by a Sage. The precise + * definition of this value depends on the Anomaly type. + */ public final float sagePercentage; AnomalyType(boolean isGlobalAnomaly, boolean isSageAnomaly, float globalPercentage, float sagePercentage) { diff --git a/engine/src/main/battlecode/common/Clock.java b/engine/src/main/battlecode/common/Clock.java index f3bba5ff..bd820a04 100644 --- a/engine/src/main/battlecode/common/Clock.java +++ b/engine/src/main/battlecode/common/Clock.java @@ -3,15 +3,14 @@ import battlecode.instrumenter.inject.RobotMonitor; /** - * Clock is a singleton that allows contestants to introspect the state of their running - * code. + * Clock is a singleton that allows contestants to introspect the state of their + * running code. * * @author james */ @SuppressWarnings("unused") public final class Clock { - - /** + /* * IMPORTANT NOTE! * This class is reloaded for every individual robot. * See Loader for more information. @@ -28,8 +27,8 @@ public static void yield() { /** * Returns the number of bytecodes this robot has left in this round. - * @return the number of bytecodes this robot has left in this round. * + * @return the number of bytecodes this robot has left in this round * @battlecode.doc.costlymethod */ public static int getBytecodesLeft() { @@ -37,11 +36,11 @@ public static int getBytecodesLeft() { } /** - * Returns the number of bytecodes the current robot has executed since the beginning - * of the current round. - * @return the number of bytecodes the current robot has executed since the beginning - * of the current round. + * Returns the number of bytecodes the current robot has executed since the + * beginning of the current round. * + * @return the number of bytecodes the current robot has executed since the + * beginning of the current round * @battlecode.doc.costlymethod */ public static int getBytecodeNum() { diff --git a/engine/src/main/battlecode/common/Direction.java b/engine/src/main/battlecode/common/Direction.java index bcc9a6d0..f8253149 100644 --- a/engine/src/main/battlecode/common/Direction.java +++ b/engine/src/main/battlecode/common/Direction.java @@ -50,9 +50,14 @@ public enum Direction { CENTER(0, 0); /** - * Change in x, change in y. + * Change in x. */ - public final int dx, dy; + public final int dx; + + /** + * Change in y. + */ + public final int dy; Direction(int dx, int dy) { this.dx = dx; @@ -102,9 +107,9 @@ public Direction rotateRight() { /** * Returns a list of all directions. This is equivalent to calling - * Direction.values(). + * {@link Direction#values}. * - * @return array of all directions. + * @return array of all directions */ public static Direction[] allDirections() { return Direction.values(); @@ -113,7 +118,7 @@ public static Direction[] allDirections() { /** * Returns a list of all cardinal directions. * - * @return array of all cardinal directions. + * @return array of all cardinal directions */ public static Direction[] cardinalDirections() { return new Direction[]{Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST}; @@ -122,7 +127,7 @@ public static Direction[] cardinalDirections() { /** * Returns the delta X of the direction. * - * @return the delta X of the direction. + * @return the delta X of the direction */ public int getDeltaX() { return this.dx; @@ -131,9 +136,9 @@ public int getDeltaX() { /** * Returns the delta Y of the direction. * - * @return the delta Y of the direction. + * @return the delta Y of the direction */ public int getDeltaY() { return this.dy; } -} \ No newline at end of file +} diff --git a/engine/src/main/battlecode/common/GameActionException.java b/engine/src/main/battlecode/common/GameActionException.java index 4bf70fd7..cdd92fd8 100644 --- a/engine/src/main/battlecode/common/GameActionException.java +++ b/engine/src/main/battlecode/common/GameActionException.java @@ -35,7 +35,7 @@ public GameActionException(GameActionExceptionType type, String message) { * Gives the type of gameworld interaction that caused this GameActionException, which * was specified when this instance was constructed. * - * @return this GameActionException's type. + * @return this GameActionException's type */ public GameActionExceptionType getType() { return type; diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 22a369f6..1ace50b8 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -1,7 +1,7 @@ package battlecode.common; /** - * Defines constants that affect gameplay. + * GameConstants defines constants that affect gameplay. */ @SuppressWarnings("unused") public class GameConstants { @@ -9,7 +9,7 @@ public class GameConstants { /** * The current spec version the server compiles with. */ - public static final String SPEC_VERSION = "1.0"; + public static final String SPEC_VERSION = "2022.0.1.0"; // ********************************* // ****** MAP CONSTANTS ************ diff --git a/engine/src/main/battlecode/common/MapLocation.java b/engine/src/main/battlecode/common/MapLocation.java index 12884b5d..60ee629e 100644 --- a/engine/src/main/battlecode/common/MapLocation.java +++ b/engine/src/main/battlecode/common/MapLocation.java @@ -138,7 +138,7 @@ public final boolean isAdjacentTo(MapLocation location) { * If location equals this location then the return value is Direction.CENTER. * * @param location The location to which the Direction will be calculated - * @return The Direction to location from this MapLocation. + * @return the Direction to location from this MapLocation * * @battlecode.doc.costlymethod */ diff --git a/engine/src/main/battlecode/common/RobotController.java b/engine/src/main/battlecode/common/RobotController.java index df93ba23..0c461422 100644 --- a/engine/src/main/battlecode/common/RobotController.java +++ b/engine/src/main/battlecode/common/RobotController.java @@ -26,7 +26,8 @@ public strictfp interface RobotController { int getRoundNum(); /** - * Returns map width. + * Returns the width of the game map. Valid x coordinates range from + * 0 (inclusive) to the width (exclusive). * * @return the map width * @@ -35,7 +36,8 @@ public strictfp interface RobotController { int getMapWidth(); /** - * Returns map height. + * Returns the height of the game map. Valid y coordinates range from + * 0 (inclusive) to the height (exclusive). * * @return the map height * @@ -369,9 +371,9 @@ public strictfp interface RobotController { /** * Returns the number of action cooldown turns remaining before this unit can act again. - * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isActionReady() + * When this number is strictly less than {@link GameConstants#COOLDOWN_LIMIT}, isActionReady() * is true and the robot can act again. This number decreases by - * GameConstants.COOLDOWNS_PER_TURN every turn. + * {@link GameConstants#COOLDOWNS_PER_TURN} every turn. * * @return the number of action turns remaining before this unit can act again * @@ -390,9 +392,9 @@ public strictfp interface RobotController { /** * Returns the number of movement cooldown turns remaining before this unit can move again. - * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isMovementReady() + * When this number is strictly less than {@link GameConstants#COOLDOWN_LIMIT}, isMovementReady() * is true and the robot can move again. This number decreases by - * GameConstants.COOLDOWNS_PER_TURN every turn. + * {@link GameConstants#COOLDOWNS_PER_TURN} every turn. * * @return the number of cooldown turns remaining before this unit can move again * @@ -414,9 +416,9 @@ public strictfp interface RobotController { /** * Returns the number of cooldown turns remaining before this unit can transform again. - * When this number is strictly less than GameConstants.COOLDOWN_LIMIT, isTransformReady() + * When this number is strictly less than {@link GameConstants#COOLDOWN_LIMIT}, isTransformReady() * is true and the robot can transform again. This number decreases by - * GameConstants.COOLDOWNS_PER_TURN every turn. + * {@link GameConstants#COOLDOWNS_PER_TURN} every turn. * * @return the number of cooldown turns remaining before this unit can transform again * @@ -766,8 +768,8 @@ public strictfp interface RobotController { // *********************************** /** - * Sets the indicator string for this robot. Only the first - * GameConstants.INDICATOR_STRING_MAX_LENGTH characters are used. + * Sets the indicator string for this robot for debugging purposes. Only the first + * {@link GameConstants#INDICATOR_STRING_MAX_LENGTH} characters are used. * * @param string the indicator string this round * diff --git a/engine/src/main/battlecode/common/RobotInfo.java b/engine/src/main/battlecode/common/RobotInfo.java index 2b16a569..39bf872d 100644 --- a/engine/src/main/battlecode/common/RobotInfo.java +++ b/engine/src/main/battlecode/common/RobotInfo.java @@ -1,7 +1,7 @@ package battlecode.common; /** - * Struct that stores basic information that was 'sensed' of another Robot. This + * RobotInfo stores basic information that was 'sensed' of another Robot. This * info is ephemeral and there is no guarantee any of it will remain the same * between rounds. */ diff --git a/engine/src/main/battlecode/common/RobotMode.java b/engine/src/main/battlecode/common/RobotMode.java index 198147d3..2e909ebe 100644 --- a/engine/src/main/battlecode/common/RobotMode.java +++ b/engine/src/main/battlecode/common/RobotMode.java @@ -1,17 +1,52 @@ package battlecode.common; /** - * Holds the different "modes" a robot can be in, mostly useful for buildings. + * Enumerates the modes that a robot could possibly be in. The mode of a robot + * determines the set of interactions with the world that it can currently + * perform legally. + *

+ * You can check the mode of another robot by inspecting {@link RobotInfo#mode}, + * or your own mode by inspecting {@link RobotController#getMode}. */ public enum RobotMode { - + /** + * The Droid mode describes all Droid robots. These robots can always act + * and move, as long as their cooldowns permit. + */ DROID (true, true, false), + + /** + * The Prototype mode describes newly-constructed Buildings. These robots + * cannot do anything until they have been repaired to full health by a + * Builder. + */ PROTOTYPE (false, false, false), + + /** + * The Turret mode describes Buildings in Turret mode. These robots can act, + * but not move. Turrets can also transform into Portable mode. + */ TURRET (true, false, true), + + /** + * The Portable mode describes Buildings in Portable mode. These robots can + * move, but not act. Portables can also transform into Turret mode. + */ PORTABLE (false, true, true); + /** + * Whether robots in this mode may perform actions other than moving. + */ public final boolean canAct; + + /** + * Whether robots in this mode may move. + */ public final boolean canMove; + + /** + * Whether robots in this mode may transform to another mode. + */ public final boolean canTransform; RobotMode(boolean canAct, boolean canMove, boolean canTransform) { @@ -19,4 +54,4 @@ public enum RobotMode { this.canMove = canMove; this.canTransform = canTransform; } -} \ No newline at end of file +} diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index 2c80e08d..50606769 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -1,7 +1,11 @@ package battlecode.common; /** - * Contains details on various attributes of the different robots. All of this information is in the specs in a more organized form. + * Enumerates the possible types of robots. More information about the + * capabilities of each robot type are available in the game specs. + * + * You can check the type of another robot by inspecting {@link RobotInfo#type}, + * or your own type by inspecting {@link RobotController#getType}. */ public enum RobotType { @@ -9,89 +13,103 @@ public enum RobotType { // Health (level 1), Damage (level 1), Action Radius (squared), Vision Radius (squared), Bytecode Limit /** - * Archons are portable buildings that heal and generate robots. - * Losing all archons means losing the game. + * Archons are the headquarters of your army. They are Buildings that can + * build and repair Droids. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ ARCHON ( 0, 250, 10, 24, 1000, -2, 20, 34, 20000), // BCL BCG AC MC HP DMG AR VR BL /** - * Alchemist's laboratory. - * Converts lead into gold. + * Laboratories house the magic of the alchemist. They are Buildings that + * can transmute lead into gold. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ LABORATORY (800, 0, 10, 24, 100, 0, 0, 53, 5000), // BCL BCG AC MC HP DMG AR VR BL /** - * Guard turret. + * Watchtowers are defensive strongholds. They are Buildings that can + * attack robots that stray too close. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ WATCHTOWER (180, 0, 10, 24, 130, 5, 20, 34, 10000), // BCL BCG AC MC HP DMG AR VR BL /** - * Miner robots. - * Can mine gold or lead at their or an adjacent location. + * Miners are resource-collecting robots. They are Droids that can mine lead + * or gold at their or an adjacent location. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ MINER ( 50, 0, 2, 20, 40, 0, 2, 20, 7500), // BCL BCG AC MC HP DMG AR VR BL /** - * Builder robots. - * Can build and repair buildings. + * Builders are resource-spending robots. They are Droids that can build, + * repair and mutate Buildings. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ BUILDER ( 40, 0, 10, 20, 30, -1, 5, 20, 7500), // BCL BCG AC MC HP DMG AR VR BL /** - * Soldier robots. - * Ranged attacking robot. + * Soldiers are general-purpose attacking robots. They are Droids that can + * attack robots within a range. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ SOLDIER ( 75, 0, 10, 16, 50, 3, 13, 20, 10000), // BCL BCG AC MC HP DMG AR VR BL /** - * Sage robots. - * Gold robot, causes Anomalies. + * Sages are wise robots with extraordinary abilities. They are Droids + * fashioned out of pure gold, able to envision Anomalies to the detriment + * of the enemy. * - * @battlecode.doc.robottype */ + * @battlecode.doc.robottype + */ SAGE ( 0, 50, 200, 25, 100, 45, 13, 20, 10000) // BCL BCG AC MC HP DMG AR VR BL ; /** - * Lead cost to build a given robot or building + * Lead cost to build a given robot or building. */ public final int buildCostLead; /** - * Gold cost to build a given robot or building (except for Archon's) + * Gold cost to build a given robot or building. */ public final int buildCostGold; /** - * Action cooldown. + * The action cooldown applied to the robot per action. */ public final int actionCooldown; /** - * Movement cooldown. + * The movement cooldown applied to the robot per move. */ public final int movementCooldown; /** - * Initial health per robot for Level 1. - */ + * The maximum health for a Level 1 robot of this type. + * + * @see #getMaxHealth + */ public final int health; /** - * Damage for each robot in Level 1. - */ + * The damage per attack for a Level 1 robot of this type. This value is + * negative for robots with repairing abilities. + * + * @see #getDamage + */ public final int damage; /** @@ -106,7 +124,7 @@ public enum RobotType { public final int visionRadiusSquared; /** - * Base bytecode limit of this robot + * Base bytecode limit of this robot. */ public final int bytecodeLimit; @@ -125,6 +143,8 @@ public int getVisionRadiusSquared(int level) { } /** + * Returns whether this type can build a robot of another given type. + * * @param builtType type of robot being built * @return whether this type can build the given robot type * @@ -140,8 +160,9 @@ public boolean canBuild(RobotType builtType) { } /** - * @return whether this type can attack + * Returns whether this type can attack. * + * @return whether this type can attack * @battlecode.doc.costlymethod */ public boolean canAttack() { @@ -150,8 +171,9 @@ public boolean canAttack() { } /** - * @return whether this type can envision anomalies + * Returns whether this type can envision Anomalies. * + * @return whether this type can envision Anomalies * @battlecode.doc.costlymethod */ public boolean canEnvision() { @@ -159,6 +181,8 @@ public boolean canEnvision() { } /** + * Returns whether this type can repair another robot of a given type. + * * @param repairedType type of robot being repaired * @return whether this type can repair the given robot type * @@ -170,8 +194,9 @@ public boolean canRepair(RobotType repairedType) { } /** - * @return whether this type can mine + * Returns whether this type can mine for metal. * + * @return whether this type can mine for metal * @battlecode.doc.costlymethod */ public boolean canMine() { @@ -179,8 +204,10 @@ public boolean canMine() { } /** + * Returns whether this type can mutate another robot of a given type. + * * @param mutatedType type of robot being mutated - * @return whether this type can mutate buildings + * @return whether this type can mutate another robot of a given type * * @battlecode.doc.costlymethod */ @@ -189,8 +216,9 @@ public boolean canMutate(RobotType mutatedType) { } /** - * @return whether this type can transmute lead into gold + * Returns whether this type can transmute lead into gold. * + * @return whether this type can transmute lead into gold * @battlecode.doc.costlymethod */ public boolean canTransmute() { @@ -198,10 +226,11 @@ public boolean canTransmute() { } /** - * @return whether or not a given robot is a building + * Returns whether or not a given robot is a Building. * + * @return whether or not a given robot is a Building * @battlecode.doc.costlymethod - */ + */ public boolean isBuilding() { return ( this == ARCHON @@ -212,6 +241,7 @@ public boolean isBuilding() { /** * Returns the max health of a robot by level. + * * @param level of the robot * @return the max health of a robot by level * @@ -231,8 +261,9 @@ public int getMaxHealth(int level) { /** * Determine the damage power of a robot by level. + * * @param level The specific level of the robot. - * @return the damage for a robot by level, negative if robot heals + * @return the damage for a robot by level, negative if robot repairs * * @battlecode.doc.costlymethod */ @@ -249,10 +280,11 @@ public int getDamage(int level) { } /** - * Determine the healing power of a robot by level. + * Determine the repairing power of a robot by level. + * * @param level The specific level of the robot. - * @return the healing per turn for a robot by level as a positive amount, - * 0 if robot doesn't heal + * @return the repair per turn for a robot by level as a positive amount, + * or 0 if robot doesn't repair * * @battlecode.doc.costlymethod */ @@ -267,8 +299,10 @@ public int getHealing(int level) { // COST RELATED FUNCTIONS /** + * Determine the lead cost of Mutating this robot to a specific level. + * * @param level the level to mutate to - * @return lead component of cost to mutate + * @return lead cost to mutate, unspecified if mutation is invalid * * @battlecode.doc.costlymethod */ @@ -277,8 +311,10 @@ public int getLeadMutateCost(int level) { } /** + * Determine the gold cost of Mutating this robot to a specific level. + * * @param level the level to mutate to - * @return gold component of cost to mutate. + * @return gold cost to mutate, unspecified if mutation is invalid * * @battlecode.doc.costlymethod */ @@ -287,6 +323,8 @@ public int getGoldMutateCost(int level) { } /** + * Determine the robot's net worth in lead. + * * @param level the robot's current level * @return lead component of worth * @@ -301,6 +339,8 @@ public int getLeadWorth(int level) { } /** + * Determine the robot's net worth in gold. + * * @param level the robot's current level * @return gold component of worth * @@ -315,6 +355,8 @@ public int getGoldWorth(int level) { } /** + * Determine the amount of lead dropped if this robot dies. + * * @param level the robot's current level * @return the amount of lead dropped * @@ -325,6 +367,8 @@ public int getLeadDropped(int level) { } /** + * Determine the amount of gold dropped if this robot dies. + * * @param level the robot's current level * @return the amount of gold dropped * From 342678acc752b32e6670272b61dd17253ea039a1 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 16:29:48 -0500 Subject: [PATCH 287/413] Remove reference to singularity --- engine/src/main/battlecode/world/LiveMap.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/LiveMap.java b/engine/src/main/battlecode/world/LiveMap.java index cd870337..45ed5509 100644 --- a/engine/src/main/battlecode/world/LiveMap.java +++ b/engine/src/main/battlecode/world/LiveMap.java @@ -92,8 +92,7 @@ public LiveMap(int width, Arrays.fill(this.rubbleArray, 1); // default cooldown factor is 1 this.leadArray = new int[width * height]; // TODO: we guarantee there to be lead within vision range of archons - this.anomalySchedule = new AnomalyScheduleEntry[1]; - this.anomalySchedule[0] = new AnomalyScheduleEntry(GameConstants.GAME_MAX_NUMBER_OF_ROUNDS, AnomalyType.SINGULARITY); + this.anomalySchedule = new AnomalyScheduleEntry[0]; this.nextAnomalyIndex = 0; // invariant: bodies is sorted by id From 4515250ff4c856310d3d4e233453c612e7e4e42c Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 16:39:30 -0500 Subject: [PATCH 288/413] Drop extraneous methods --- engine/src/main/battlecode/common/RobotType.java | 14 -------------- engine/src/main/battlecode/world/GameWorld.java | 2 +- engine/src/main/battlecode/world/MapBuilder.java | 2 +- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/engine/src/main/battlecode/common/RobotType.java b/engine/src/main/battlecode/common/RobotType.java index e6cbb0a0..8c926ab5 100644 --- a/engine/src/main/battlecode/common/RobotType.java +++ b/engine/src/main/battlecode/common/RobotType.java @@ -128,20 +128,6 @@ public enum RobotType { */ public final int bytecodeLimit; - /** - * @return the squared action radius - */ - public int getActionRadiusSquared(int level) { - return this.actionRadiusSquared; - } - - /** - * @return the squared vision radius - */ - public int getVisionRadiusSquared(int level) { - return this.visionRadiusSquared; - } - /** * Returns whether this type can build a robot of another given type. * diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 385a95b3..1402580e 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -515,7 +515,7 @@ public void setProfilerCollection(Team team, ProfilerCollection profilerCollecti private MapLocation[] getSageActionLocations(InternalRobot robot) { assert robot.getType() == RobotType.SAGE; MapLocation center = robot.getLocation(); - return getAllLocationsWithinRadiusSquared(center, robot.getType().getActionRadiusSquared(robot.getLevel())); + return getAllLocationsWithinRadiusSquared(center, robot.getType().actionRadiusSquared); } /** diff --git a/engine/src/main/battlecode/world/MapBuilder.java b/engine/src/main/battlecode/world/MapBuilder.java index 6ea6b203..838cc880 100644 --- a/engine/src/main/battlecode/world/MapBuilder.java +++ b/engine/src/main/battlecode/world/MapBuilder.java @@ -238,7 +238,7 @@ public void assertIsValid() { this.width, this.height, r.getLocation(), - r.getType().getVisionRadiusSquared(1) + r.getType().visionRadiusSquared ); for (MapLocation location : visibleLocations) From 697ba34862a0b0f06e8b22ad028c0bd0f6e0ebc4 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 17:34:20 -0500 Subject: [PATCH 289/413] Show attacks --- client/playback/src/gameworld.ts | 23 ++++++++++++++++++---- client/visualizer/src/gamearea/renderer.ts | 14 +++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index 9d5c041e..bcae16af 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -22,6 +22,9 @@ export type BodiesSchema = { y: Int32Array, bytecodesUsed: Int32Array, // TODO: is this needed? action: Int8Array, + target: Int32Array, + targetx: Int32Array, + targety: Int32Array, parent: Int32Array, hp: Int32Array, level: Int8Array, @@ -201,6 +204,9 @@ export default class GameWorld { y: new Int32Array(0), bytecodesUsed: new Int32Array(0), action: new Int8Array(0), + target: new Int32Array(0), + targetx: new Int32Array(0), + targety: new Int32Array(0), parent: new Int32Array(0), hp: new Int32Array(0), level: new Int8Array(0), @@ -392,7 +398,8 @@ export default class GameWorld { } // Remove abilities from previous round - this.bodies.alterBulk({id: new Int32Array(this.actionRobots), ability: new Int8Array(this.actionRobots.length)}); + this.bodies.alterBulk({id: new Int32Array(this.actionRobots), action: (new Int8Array(this.actionRobots.length)).fill(-1), + target: new Int32Array(this.actionRobots.length), targetx: new Int32Array(this.actionRobots.length), targety: new Int32Array(this.actionRobots.length)}); this.actionRobots = []; // Remove bids from previous round @@ -438,8 +445,13 @@ export default class GameWorld { const target = delta.actionTargets(i); const body = robotID != -1 ? this.bodies.lookup(robotID) : null; const teamStatsObj = body != null ? this.teamStats.get(body.team) : null; - const setAction = () => { + const setAction = (set_target: Boolean = false, set_target_loc: Boolean = false) => { this.bodies.alter({id: robotID, action: action as number}); + if (set_target) this.bodies.alter({id: robotID, target: target}); + if (set_target_loc) { + const target_body = this.bodies.lookup(target); + this.bodies.alter({id: robotID, targetx: target_body.x, targety: target_body.y}); + } this.actionRobots.push(robotID); }; // should be called for actions performed *by* the robot. switch (action) { @@ -447,7 +459,7 @@ export default class GameWorld { // Actions list from battlecode.fbs enum Action case schema.Action.ATTACK: - setAction(); + setAction(true, true); break; /// Slanderers passively generate influence for the /// Enlightenment Center that created them. @@ -755,7 +767,10 @@ export default class GameWorld { y: locs.ysArray(), flag: new Int32Array(bodies.robotIDsLength()), bytecodesUsed: new Int32Array(bodies.robotIDsLength()), - ability: new Int8Array(bodies.robotIDsLength()), + action: (new Int8Array(bodies.robotIDsLength())).fill(-1), + target: new Int32Array(bodies.robotIDsLength()), + targetx: new Int32Array(bodies.robotIDsLength()), + targety: new Int32Array(bodies.robotIDsLength()), bid: new Int32Array(bodies.robotIDsLength()), parent: new Int32Array(bodies.robotIDsLength()), hp: hps, diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index c63a5046..f4bd23c6 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -216,6 +216,9 @@ export default class Renderer { const xs = bodies.arrays.x; const ys = bodies.arrays.y; const actions = bodies.arrays.action; + const targets = bodies.arrays.target; + const targetxs = bodies.arrays.targetx; + const targetys = bodies.arrays.targety; const portables = bodies.arrays.portable; const prototypes = bodies.arrays.prototype; const levels = bodies.arrays.level; @@ -280,6 +283,17 @@ export default class Renderer { this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID) // draw effect + if (actions[i] == schema.Action.ATTACK) { + this.ctx.save(); + this.ctx.beginPath() + this.ctx.moveTo(realXs[i] + 0.5, realYs[i] + 0.5); + this.ctx.lineTo(targetxs[i] + 0.5, this.flip(targetys[i], minY, maxY) + 0.5) + this.ctx.strokeStyle = teams[i] == 1 ? 'red' : 'blue'; + this.ctx.lineWidth = 0.05; + this.ctx.stroke(); + this.ctx.restore(); + }; + // TODO: handle abilities/actions // let effect: string | null = cst.abilityToEffectString(abilities[i]); // if (effect !== null) drawEffect(effect, realXs[i], realYs[i]); From ab2a86689164938003534ca9bac466a3eaacf9c2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 17:45:06 -0500 Subject: [PATCH 290/413] tweak --- client/visualizer/src/sidebar/stats.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 2741d0fa..84423c0c 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -131,7 +131,7 @@ export default class Stats { robotCounts[value] = document.createElement("tr"); const title = document.createElement("td"); if (value === "count") title.innerHTML = "Count"; - if (value === "hp") title.innerHTML = "HP"; + if (value === "hp") title.innerHTML = "Σ(HP)"; robotCounts[value].appendChild(title); } From c7846258347e36c98a3370375905b0d6a2d25eee Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 17:55:08 -0500 Subject: [PATCH 291/413] another tweak --- client/visualizer/src/main/controls.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index dd449011..e7bb52ba 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -444,7 +444,8 @@ export default class Controls { let infoString = `ID: ${id} | `; infoString += `Location: (${x}, ${y}) | `; infoString += `Level: ${level} | `; - if (portable !== undefined && prototype !== undefined) infoString += `Mode: ${portable ? 'Port' : prototype ? 'Prot' : 'Turr'}
`; + if (portable !== undefined && prototype !== undefined) infoString += `Mode: ${portable ? 'Port' : prototype ? 'Prot' : 'Turr'}`; + infoString += `
`; infoString += `HP: ${hp} / ${max_hp} | `; infoString += `DP: ${dp} | `; infoString += `Bytecodes Used: ${bytecodes}`; From d6264af5c0eab042862e403e4c7f6185206a66ad Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Sun, 2 Jan 2022 18:42:52 -0500 Subject: [PATCH 292/413] Indicator strings and map changes --- client/playback/src/gameworld.ts | 635 +++++++++++---------- client/visualizer/src/constants.ts | 19 +- client/visualizer/src/gamearea/renderer.ts | 121 ++-- client/visualizer/src/imageloader.ts | 7 +- client/visualizer/src/main/controls.ts | 12 +- client/visualizer/src/main/looper.ts | 5 +- client/visualizer/src/static/css/style.css | 8 + 7 files changed, 437 insertions(+), 370 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index d7b2e717..638da95f 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -1,11 +1,11 @@ -import StructOfArrays from './soa'; -import Metadata from './metadata'; -import { flatbuffers, schema } from 'battlecode-schema'; -import {playbackConfig} from './game'; +import StructOfArrays from './soa' +import Metadata from './metadata' +import { flatbuffers, schema } from 'battlecode-schema' +import { playbackConfig } from './game' // necessary because victor doesn't use exports.default -import Victor = require('victor'); -import deepcopy = require('deepcopy'); +import Victor = require('victor') +import deepcopy = require('deepcopy') // TODO use Victor for representing positions export type DeadBodiesSchema = { @@ -27,7 +27,7 @@ export type BodiesSchema = { level: Int8Array, portable: Int8Array, prototype: Int8Array -}; +} // NOTE: consider changing MapStats to schema to use SOA for better performance, if it has large data export type MapStats = { @@ -38,17 +38,17 @@ export type MapStats = { randomSeed: number, rubble: Int32Array, // double - leadVals: Int32Array; - goldVals: Int32Array; + leadVals: Int32Array + goldVals: Int32Array - symmetry: number; + symmetry: number - anomalies: Int8Array; - anomalyRounds: Int8Array; + anomalies: Int8Array + anomalyRounds: Int8Array - getIdx: (x:number, y:number) => number; - getLoc: (idx: number) => Victor; -}; + getIdx: (x: number, y: number) => number + getLoc: (idx: number) => Victor +} export type TeamStats = { // An array of numbers corresponding to team stats, which map to RobotTypes @@ -60,7 +60,7 @@ export type TeamStats = { total_hp: [number[], number[], number[], number[], number[], number[], number[]], leadChange: number, goldChange: number -}; +} export type IndicatorDotsSchema = { id: Int32Array, @@ -88,7 +88,7 @@ export type Log = { id: number, round: number, text: string -}; +} /** * A frozen image of the game world. @@ -99,64 +99,70 @@ export default class GameWorld { /** * Bodies that died this round. */ - diedBodies: StructOfArrays; + diedBodies: StructOfArrays /** * Everything that isn't an indicator string. */ - bodies: StructOfArrays; + bodies: StructOfArrays /* * Stats for each team */ - teamStats: Map; // Team ID to their stats + teamStats: Map // Team ID to their stats /* * Stats for each team */ - mapStats: MapStats; // Team ID to their stats + mapStats: MapStats // Team ID to their stats /** * Indicator dots. */ - indicatorDots: StructOfArrays; + indicatorDots: StructOfArrays /** * Indicator lines. */ - indicatorLines: StructOfArrays; + indicatorLines: StructOfArrays + + /** + * Indicator strings. + * Stored as a dictionary of robot ids and that robot's string + */ + indicatorStrings: object /** * The current turn. */ - turn: number; + turn: number // duplicate with mapStats, but left for compatibility. // TODO: change dependencies and remove these map variables /** * The minimum corner of the game world. */ - minCorner: Victor; + minCorner: Victor /** * The maximum corner of the game world. */ - maxCorner: Victor; + maxCorner: Victor /** * The name of the map. */ - mapName: string; + mapName: string /** * Metadata about the current game. */ - meta: Metadata; + meta: Metadata /** * Whether to process logs. */ - config: playbackConfig; + config: playbackConfig /** * Recent logs, bucketed by round. @@ -172,10 +178,10 @@ export default class GameWorld { // Cache fields // We pass these into flatbuffers functions to avoid allocations, // but that's it, they don't hold any state - private _bodiesSlot: schema.SpawnedBodyTable; - private _vecTableSlot1: schema.VecTable; - private _vecTableSlot2: schema.VecTable; - private _rgbTableSlot: schema.RGBTable; + private _bodiesSlot: schema.SpawnedBodyTable + private _vecTableSlot1: schema.VecTable + private _vecTableSlot2: schema.VecTable + private _rgbTableSlot: schema.RGBTable /** * IDs of robots who performed a temporary ability in the previous round, @@ -185,13 +191,13 @@ export default class GameWorld { private bidRobots: number[] = []; constructor(meta: Metadata, config: playbackConfig) { - this.meta = meta; + this.meta = meta this.diedBodies = new StructOfArrays({ id: new Int32Array(0), x: new Int32Array(0), y: new Int32Array(0), - }, 'id'); + }, 'id') this.bodies = new StructOfArrays({ id: new Int32Array(0), @@ -206,27 +212,27 @@ export default class GameWorld { level: new Int8Array(0), portable: new Int8Array(0), prototype: new Int8Array(0) - }, 'id'); + }, 'id') // Instantiate teamStats - this.teamStats = new Map(); + this.teamStats = new Map() for (let team in this.meta.teams) { - var teamID = this.meta.teams[team].teamID; - this.teamStats.set(teamID, { - robots: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], - lead: 0, - gold: 0, - total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], - leadChange: 0, - goldChange: 0 - }); + var teamID = this.meta.teams[team].teamID + this.teamStats.set(teamID, { + robots: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + lead: 0, + gold: 0, + total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + leadChange: 0, + goldChange: 0 + }) } // Instantiate mapStats this.mapStats = { name: '????', - minCorner: new Victor(0,0), - maxCorner: new Victor(0,0), + minCorner: new Victor(0, 0), + maxCorner: new Victor(0, 0), bodies: new schema.SpawnedBodyTable(), randomSeed: 0, @@ -238,9 +244,9 @@ export default class GameWorld { anomalies: new Int8Array(0), anomalyRounds: new Int8Array(0), - getIdx: (x:number, y:number) => 0, - getLoc: (idx: number) => new Victor(0,0) - }; + getIdx: (x: number, y: number) => 0, + getLoc: (idx: number) => new Victor(0, 0) + } this.indicatorDots = new StructOfArrays({ @@ -250,7 +256,7 @@ export default class GameWorld { red: new Int32Array(0), green: new Int32Array(0), blue: new Int32Array(0) - }, 'id'); + }, 'id') this.indicatorLines = new StructOfArrays({ id: new Int32Array(0), @@ -261,66 +267,68 @@ export default class GameWorld { red: new Int32Array(0), green: new Int32Array(0), blue: new Int32Array(0) - }, 'id'); + }, 'id') - this.turn = 0; - this.minCorner = new Victor(0, 0); - this.maxCorner = new Victor(0, 0); - this.mapName = '????'; + this.indicatorStrings = {} + + this.turn = 0 + this.minCorner = new Victor(0, 0) + this.maxCorner = new Victor(0, 0) + this.mapName = '????' this._bodiesSlot = new schema.SpawnedBodyTable() - this._vecTableSlot1 = new schema.VecTable(); - this._vecTableSlot2 = new schema.VecTable(); - this._rgbTableSlot = new schema.RGBTable(); + this._vecTableSlot1 = new schema.VecTable() + this._vecTableSlot2 = new schema.VecTable() + this._rgbTableSlot = new schema.RGBTable() - this.config = config; + this.config = config } loadFromMatchHeader(header: schema.MatchHeader) { - const map = header.map(); + const map = header.map() - const name = map.name() as string; + const name = map.name() as string if (name) { - this.mapName = map.name() as string; - this.mapStats.name = map.name() as string; + this.mapName = map.name() as string + this.mapStats.name = map.name() as string } - const minCorner = map.minCorner(); - this.minCorner.x = minCorner.x(); - this.minCorner.y = minCorner.y(); - this.mapStats.minCorner.x = minCorner.x(); - this.mapStats.minCorner.y = minCorner.y(); - - const maxCorner = map.maxCorner(); - this.maxCorner.x = maxCorner.x(); - this.maxCorner.y = maxCorner.y(); - this.mapStats.maxCorner.x = maxCorner.x(); - this.mapStats.maxCorner.y = maxCorner.y(); - - this.mapStats.goldVals = new Int32Array(maxCorner.x()*maxCorner.y()) - this.mapStats.leadVals = map.leadArray(); - - const bodies = map.bodies(this._bodiesSlot); + const minCorner = map.minCorner() + this.minCorner.x = minCorner.x() + this.minCorner.y = minCorner.y() + this.mapStats.minCorner.x = minCorner.x() + this.mapStats.minCorner.y = minCorner.y() + + const maxCorner = map.maxCorner() + this.maxCorner.x = maxCorner.x() + this.maxCorner.y = maxCorner.y() + this.mapStats.maxCorner.x = maxCorner.x() + this.mapStats.maxCorner.y = maxCorner.y() + + this.mapStats.goldVals = new Int32Array(maxCorner.x() * maxCorner.y()) + this.mapStats.leadVals = map.leadArray() + + const bodies = map.bodies(this._bodiesSlot) if (bodies && bodies.robotIDsLength) { - this.insertBodies(bodies); + this.insertBodies(bodies) } - this.mapStats.randomSeed = map.randomSeed(); + this.mapStats.randomSeed = map.randomSeed() - this.mapStats.rubble = map.rubbleArray(); + this.mapStats.rubble = map.rubbleArray() - const width = (maxCorner.x() - minCorner.x()); - this.mapStats.getIdx = (x:number, y:number) => ( - Math.floor(y)*width + Math.floor(x) - ); + const width = (maxCorner.x() - minCorner.x()) + this.mapStats.getIdx = (x: number, y: number) => ( + Math.floor(y) * width + Math.floor(x) + ) this.mapStats.getLoc = (idx: number) => ( new Victor(idx % width, Math.floor(idx / width)) - ); + ) - this.mapStats.symmetry = map.symmetry(); + this.mapStats.symmetry = map.symmetry() - this.mapStats.anomalies = Int8Array.from(map.anomaliesArray()); - this.mapStats.anomalyRounds = Int8Array.from(map.anomalyRoundsArray()); + this.mapStats.anomalies = Int8Array.from(map.anomaliesArray()) + this.mapStats.anomalyRounds = Int8Array.from(map.anomalyRoundsArray()) // Check with header.totalRounds() ? } @@ -329,29 +337,30 @@ export default class GameWorld { * Create a copy of the world in its current state. */ copy(): GameWorld { - const result = new GameWorld(this.meta, this.config); - result.copyFrom(this); - return result; + const result = new GameWorld(this.meta, this.config) + result.copyFrom(this) + return result } copyFrom(source: GameWorld) { - this.turn = source.turn; - this.minCorner = source.minCorner; - this.maxCorner = source.maxCorner; - this.mapName = source.mapName; - this.diedBodies.copyFrom(source.diedBodies); - this.bodies.copyFrom(source.bodies); - this.indicatorDots.copyFrom(source.indicatorDots); - this.indicatorLines.copyFrom(source.indicatorLines); - this.teamStats = new Map(); + this.turn = source.turn + this.minCorner = source.minCorner + this.maxCorner = source.maxCorner + this.mapName = source.mapName + this.diedBodies.copyFrom(source.diedBodies) + this.bodies.copyFrom(source.bodies) + this.indicatorDots.copyFrom(source.indicatorDots) + this.indicatorLines.copyFrom(source.indicatorLines) + this.indicatorStrings = Object.assign({}, source.indicatorStrings) + this.teamStats = new Map() source.teamStats.forEach((value: TeamStats, key: number) => { - this.teamStats.set(key, deepcopy(value)); - }); - this.mapStats = deepcopy(source.mapStats); - this.actionRobots = Array.from(source.actionRobots); - this.bidRobots = Array.from(source.bidRobots); - this.logs = Array.from(source.logs); - this.logsShift = source.logsShift; + this.teamStats.set(key, deepcopy(value)) + }) + this.mapStats = deepcopy(source.mapStats) + this.actionRobots = Array.from(source.actionRobots) + this.bidRobots = Array.from(source.bidRobots) + this.logs = Array.from(source.logs) + this.logsShift = source.logsShift } /** @@ -359,210 +368,210 @@ export default class GameWorld { */ processDelta(delta: schema.Round) { // Change to reflect current game if (delta.roundID() != this.turn + 1) { - throw new Error(`Bad Round: this.turn = ${this.turn}, round.roundID() = ${delta.roundID()}`); + throw new Error(`Bad Round: this.turn = ${this.turn}, round.roundID() = ${delta.roundID()}`) } // Process team info changes for (var i = 0; i < delta.teamIDsLength(); i++) { - let teamID = delta.teamIDs(i); - let statObj = this.teamStats.get(teamID); + let teamID = delta.teamIDs(i) + let statObj = this.teamStats.get(teamID) - statObj.lead += delta.teamLeadChanges(i); - statObj.gold += delta.teamGoldChanges(i); - statObj.leadChange = delta.teamLeadChanges(i); - statObj.goldChange = delta.teamGoldChanges(i); + statObj.lead += delta.teamLeadChanges(i) + statObj.gold += delta.teamGoldChanges(i) + statObj.leadChange = delta.teamLeadChanges(i) + statObj.goldChange = delta.teamGoldChanges(i) - this.teamStats.set(teamID, statObj); - } + this.teamStats.set(teamID, statObj) + } // Location changes on bodies - const movedLocs = delta.movedLocs(this._vecTableSlot1); + const movedLocs = delta.movedLocs(this._vecTableSlot1) if (movedLocs) { this.bodies.alterBulk({ id: delta.movedIDsArray(), x: movedLocs.xsArray(), y: movedLocs.ysArray(), - }); + }) } // Spawned bodies - const bodies = delta.spawnedBodies(this._bodiesSlot); + const bodies = delta.spawnedBodies(this._bodiesSlot) if (bodies) { - this.insertBodies(bodies); + this.insertBodies(bodies) } // Remove abilities from previous round - this.bodies.alterBulk({id: new Int32Array(this.actionRobots), ability: new Int8Array(this.actionRobots.length)}); - this.actionRobots = []; + this.bodies.alterBulk({ id: new Int32Array(this.actionRobots), ability: new Int8Array(this.actionRobots.length) }) + this.actionRobots = [] // Remove bids from previous round - this.bodies.alterBulk({id: new Int32Array(this.bidRobots), bid: new Int32Array(this.bidRobots.length)}); - this.bidRobots = []; + this.bodies.alterBulk({ id: new Int32Array(this.bidRobots), bid: new Int32Array(this.bidRobots.length) }) + this.bidRobots = [] // Map changes - const leadLocations = delta.leadDropLocations(this._vecTableSlot1); + const leadLocations = delta.leadDropLocations(this._vecTableSlot1) if (leadLocations) { - const xs = leadLocations.xsArray(); - const ys = leadLocations.ysArray(); + const xs = leadLocations.xsArray() + const ys = leadLocations.ysArray() xs.forEach((x, i) => { const y = ys[i] - this.mapStats.leadVals[this.mapStats.getIdx(x,y)] += delta.leadDropValues(i); + this.mapStats.leadVals[this.mapStats.getIdx(x, y)] += delta.leadDropValues(i) }) } - const goldLocations = delta.goldDropLocations(this._vecTableSlot1); + const goldLocations = delta.goldDropLocations(this._vecTableSlot1) if (goldLocations) { - const xs = goldLocations.xsArray(); - const ys = goldLocations.ysArray(); - let inst = this; + const xs = goldLocations.xsArray() + const ys = goldLocations.ysArray() + let inst = this xs.forEach((x, i) => { - const y = ys[i]; - inst.mapStats.goldVals[inst.mapStats.getIdx(x,y)] += delta.goldDropValues(i); + const y = ys[i] + inst.mapStats.goldVals[inst.mapStats.getIdx(x, y)] += delta.goldDropValues(i) }) } if (delta.roundID() % this.meta.constants.increasePeriod() == 0) { - this.mapStats.leadVals.forEach((x,i) => { - this.mapStats.leadVals[i] = x > 0 ? x + this.meta.constants.leadAdditiveIncease(): 0; - }); + this.mapStats.leadVals.forEach((x, i) => { + this.mapStats.leadVals[i] = x > 0 ? x + this.meta.constants.leadAdditiveIncease() : 0 + }) } // Actions - if(delta.actionsLength() > 0){ - const arrays = this.bodies.arrays; - - for(let i=0; i 0) { + const arrays = this.bodies.arrays + + for (let i = 0; i < delta.actionsLength(); i++) { + const action = delta.actions(i) + const robotID = delta.actionIDs(i) + const target = delta.actionTargets(i) + const body = robotID != -1 ? this.bodies.lookup(robotID) : null + const teamStatsObj = body != null ? this.teamStats.get(body.team) : null const setAction = () => { - this.bodies.alter({id: robotID, action: action as number}); - this.actionRobots.push(robotID); - }; // should be called for actions performed *by* the robot. + this.bodies.alter({ id: robotID, action: action as number }) + this.actionRobots.push(robotID) + } // should be called for actions performed *by* the robot. switch (action) { // TODO: validate actions? // Actions list from battlecode.fbs enum Action case schema.Action.ATTACK: - setAction(); - break; + setAction() + break /// Slanderers passively generate influence for the /// Enlightenment Center that created them. /// Target: parent ID case schema.Action.LOCAL_ABYSS: - setAction(); - break; + setAction() + break case schema.Action.LOCAL_CHARGE: - setAction(); - break; - + setAction() + break + case schema.Action.LOCAL_FURY: - setAction(); - break; - + setAction() + break + case schema.Action.TRANSMUTE: - setAction(); - teamStatsObj.gold += target; - teamStatsObj.lead -= 0; - break; + setAction() + teamStatsObj.gold += target + teamStatsObj.lead -= 0 + break case schema.Action.TRANSFORM: - setAction(); - this.bodies.alter({ id: robotID, portable: 1 - body.portable}); - break; + setAction() + this.bodies.alter({ id: robotID, portable: 1 - body.portable }) + break case schema.Action.MUTATE: - setAction(); - teamStatsObj.robots[body.type][body.level - 1] -= 1; - teamStatsObj.robots[body.type][body.level + 1 - 1] += 1; - teamStatsObj.total_hp[body.type][body.level - 1] -= body.hp; - teamStatsObj.total_hp[body.type][body.level + 1 - 1] += body.hp; - this.bodies.alter({ id: robotID, level: body.level + 1}); - break; - + setAction() + teamStatsObj.robots[body.type][body.level - 1] -= 1 + teamStatsObj.robots[body.type][body.level + 1 - 1] += 1 + teamStatsObj.total_hp[body.type][body.level - 1] -= body.hp + teamStatsObj.total_hp[body.type][body.level + 1 - 1] += body.hp + this.bodies.alter({ id: robotID, level: body.level + 1 }) + break + /// Builds a unit (enlightent center). /// Target: spawned unit case schema.Action.SPAWN_UNIT: - setAction(); - this.bodies.alter({id: target, parent: robotID}); - break; + setAction() + this.bodies.alter({ id: target, parent: robotID }) + break case schema.Action.REPAIR: - setAction(); - break; + setAction() + break case schema.Action.CHANGE_HEALTH: - this.bodies.alter({ id: robotID, hp: body.hp + target}); - teamStatsObj.total_hp[body.type][body.level] += target; - break; + this.bodies.alter({ id: robotID, hp: body.hp + target }) + teamStatsObj.total_hp[body.type][body.level] += target + break case schema.Action.FULLY_REPAIRED: - this.bodies.alter({ id: robotID, prototype: 0}); - teamStatsObj.total_hp[body.type][body.level] += target; - break; + this.bodies.alter({ id: robotID, prototype: 0 }) + teamStatsObj.total_hp[body.type][body.level] += target + break case schema.Action.DIE_EXCEPTION: - console.log(`Exception occured: robotID(${robotID}), target(${target}`); - break; + console.log(`Exception occured: robotID(${robotID}), target(${target}`) + break case schema.Action.VORTEX: - console.log("vortex"); - let w = this.mapStats.maxCorner.x - this.mapStats.minCorner.x; - let h = this.mapStats.maxCorner.y - this.mapStats.minCorner.y; + console.log("vortex") + let w = this.mapStats.maxCorner.x - this.mapStats.minCorner.x + let h = this.mapStats.maxCorner.y - this.mapStats.minCorner.y switch (target) { case 0: for (let x = 0; x < w / 2; x++) { - for (let y = 0; y < (w + 1) / 2; y++) { - let curX = x; - let curY = y; - let lastRubble = this.mapStats.rubble[curX + curY * w]; - for (let i = 0; i < 4; i++) { - let tempX = curX; - curX = curY; - curY = (w - 1) - tempX; - let idx = curX + curY * w; - let tempRubble = this.mapStats.rubble[idx]; - this.mapStats.rubble[idx] = lastRubble; - lastRubble = tempRubble; - } + for (let y = 0; y < (w + 1) / 2; y++) { + let curX = x + let curY = y + let lastRubble = this.mapStats.rubble[curX + curY * w] + for (let i = 0; i < 4; i++) { + let tempX = curX + curX = curY + curY = (w - 1) - tempX + let idx = curX + curY * w + let tempRubble = this.mapStats.rubble[idx] + this.mapStats.rubble[idx] = lastRubble + lastRubble = tempRubble } + } } - break; + break case 1: - for (let x = 0; x < w / 2; x++) { - for (let y = 0; y < h; y++) { - let idx = x + y * w; - let newX = w - 1 - x; - let newIdx = newX + y * w; - let prevRubble = this.mapStats.rubble[idx]; - this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx]; - this.mapStats.rubble[newIdx] = prevRubble; - } + for (let x = 0; x < w / 2; x++) { + for (let y = 0; y < h; y++) { + let idx = x + y * w + let newX = w - 1 - x + let newIdx = newX + y * w + let prevRubble = this.mapStats.rubble[idx] + this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx] + this.mapStats.rubble[newIdx] = prevRubble } - break; - case 2: - for (let y = 0; y < h / 2; y++) { - for (let x = 0; x < w; x++) { - let idx = x + y * w; - let newY = h - 1 - y; - let newIdx = x + newY * w; - let prevRubble = this.mapStats.rubble[idx]; - this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx]; - this.mapStats.rubble[newIdx] = prevRubble; - } + } + break + case 2: + for (let y = 0; y < h / 2; y++) { + for (let x = 0; x < w; x++) { + let idx = x + y * w + let newY = h - 1 - y + let newIdx = x + newY * w + let prevRubble = this.mapStats.rubble[idx] + this.mapStats.rubble[idx] = this.mapStats.rubble[newIdx] + this.mapStats.rubble[newIdx] = prevRubble } - break; + } + break } default: //console.log(`Undefined action: action(${action}), robotID(${robotID}, target(${target}))`); - break; + break } - if (body) this.teamStats.set(body.team, teamStatsObj); + if (body) this.teamStats.set(body.team, teamStatsObj) } } @@ -598,28 +607,34 @@ export default class GameWorld { // Died bodies if (delta.diedIDsLength() > 0) { // Update team stats - var indices = this.bodies.lookupIndices(delta.diedIDsArray()); - for(let i = 0; i < delta.diedIDsLength(); i++) { - let index = indices[i]; - let team = this.bodies.arrays.team[index]; - let type = this.bodies.arrays.type[index]; - let statObj = this.teamStats.get(team); - if(!statObj) {continue;} // In case this is a neutral bot - statObj.robots[type][this.bodies.arrays.level[index] - 1] -= 1; - let hp = this.bodies.arrays.hp[index]; - statObj.total_hp[type][this.bodies.arrays.level[index] - 1] -= hp; - this.teamStats.set(team, statObj); + var indices = this.bodies.lookupIndices(delta.diedIDsArray()) + for (let i = 0; i < delta.diedIDsLength(); i++) { + let index = indices[i] + let team = this.bodies.arrays.team[index] + let type = this.bodies.arrays.type[index] + let statObj = this.teamStats.get(team) + if (!statObj) { continue } // In case this is a neutral bot + statObj.robots[type][this.bodies.arrays.level[index] - 1] -= 1 + let hp = this.bodies.arrays.hp[index] + statObj.total_hp[type][this.bodies.arrays.level[index] - 1] -= hp + this.teamStats.set(team, statObj) } // Update bodies soa - this.insertDiedBodies(delta); + this.insertDiedBodies(delta) - this.bodies.deleteBulk(delta.diedIDsArray()); + this.bodies.deleteBulk(delta.diedIDsArray()) } // Insert indicator dots and lines - this.insertIndicatorDots(delta); - this.insertIndicatorLines(delta); + this.insertIndicatorDots(delta) + this.insertIndicatorLines(delta) + + //indicator strings + for(var i = 0; i < delta.indicatorStringsLength(); i++){ + let bodyID = delta.indicatorStringIDs(i) + this.indicatorStrings[bodyID] = delta.indicatorStrings(i) + } // Logs // TODO @@ -628,14 +643,14 @@ export default class GameWorld { // TODO // Increase the turn count - this.turn = delta.roundID(); + this.turn = delta.roundID() // Update bytecode costs if (delta.bytecodeIDsLength() > 0) { this.bodies.alterBulk({ id: delta.bytecodeIDsArray(), bytecodesUsed: delta.bytecodesUsedArray() - }); + }) } // TODO: process indicator strings @@ -648,38 +663,38 @@ export default class GameWorld { // this.logs.shift(); // this.logsShift++; // } - // console.log(delta.roundID(), this.logsShift, this.logs[0]); + // console.log(delta.roundID(), this.logsShift, this.logs[0]); } private insertDiedBodies(delta: schema.Round) { // Delete the died bodies from the previous round - this.diedBodies.clear(); + this.diedBodies.clear() // Insert the died bodies from the current round const startIndex = this.diedBodies.insertBulk({ id: delta.diedIDsArray() - }); + }) // Extra initialization - const endIndex = startIndex + delta.diedIDsLength(); - const idArray = this.diedBodies.arrays.id; - const xArray = this.diedBodies.arrays.x; - const yArray = this.diedBodies.arrays.y; + const endIndex = startIndex + delta.diedIDsLength() + const idArray = this.diedBodies.arrays.id + const xArray = this.diedBodies.arrays.x + const yArray = this.diedBodies.arrays.y for (let i = startIndex; i < endIndex; i++) { - const body = this.bodies.lookup(idArray[i]); - xArray[i] = body.x; - yArray[i] = body.y; + const body = this.bodies.lookup(idArray[i]) + xArray[i] = body.x + yArray[i] = body.y } } private insertIndicatorDots(delta: schema.Round) { // Delete the dots from the previous round - this.indicatorDots.clear(); + this.indicatorDots.clear() // Insert the dots from the current round if (delta.indicatorDotIDsLength() > 0) { - const locs = delta.indicatorDotLocs(this._vecTableSlot1); - const rgbs = delta.indicatorDotRGBs(this._rgbTableSlot); + const locs = delta.indicatorDotLocs(this._vecTableSlot1) + const rgbs = delta.indicatorDotRGBs(this._rgbTableSlot) this.indicatorDots.insertBulk({ id: delta.indicatorDotIDsArray(), x: locs.xsArray(), @@ -693,13 +708,13 @@ export default class GameWorld { private insertIndicatorLines(delta: schema.Round) { // Delete the lines from the previous round - this.indicatorLines.clear(); + this.indicatorLines.clear() // Insert the lines from the current round if (delta.indicatorLineIDsLength() > 0) { - const startLocs = delta.indicatorLineStartLocs(this._vecTableSlot1); - const endLocs = delta.indicatorLineEndLocs(this._vecTableSlot2); - const rgbs = delta.indicatorLineRGBs(this._rgbTableSlot); + const startLocs = delta.indicatorLineStartLocs(this._vecTableSlot1) + const endLocs = delta.indicatorLineEndLocs(this._vecTableSlot2) + const rgbs = delta.indicatorLineRGBs(this._rgbTableSlot) this.indicatorLines.insertBulk({ id: delta.indicatorLineIDsArray(), startX: startLocs.xsArray(), @@ -716,34 +731,34 @@ export default class GameWorld { private insertBodies(bodies: schema.SpawnedBodyTable) { // Store frequently used arrays - var teams = bodies.teamIDsArray(); - var types = bodies.typesArray(); - var hps = new Int32Array(bodies.robotIDsLength()); + var teams = bodies.teamIDsArray() + var types = bodies.typesArray() + var hps = new Int32Array(bodies.robotIDsLength()) // Update spawn stats - for(let i = 0; i < bodies.robotIDsLength(); i++) { + for (let i = 0; i < bodies.robotIDsLength(); i++) { // if(teams[i] == 0) continue; - var statObj = this.teamStats.get(teams[i]); - statObj.robots[types[i]][0] += 1; // TODO: handle level - statObj.total_hp[types[i]][0] += this.meta.types[types[i]].health; // TODO: extract meta info - this.teamStats.set(teams[i], statObj); - hps[i] = this.meta.types[types[i]].health; + var statObj = this.teamStats.get(teams[i]) + statObj.robots[types[i]][0] += 1 // TODO: handle level + statObj.total_hp[types[i]][0] += this.meta.types[types[i]].health // TODO: extract meta info + this.teamStats.set(teams[i], statObj) + hps[i] = this.meta.types[types[i]].health } - - const locs = bodies.locs(this._vecTableSlot1); + + const locs = bodies.locs(this._vecTableSlot1) // Note: this allocates 6 objects with each call. // (One for the container, one for each TypedArray.) // All of the objects are small; the TypedArrays are basically // (pointer, length) pairs. // You can't reuse TypedArrays easily, so I'm inclined to // let this slide for now. - + // Initialize convictions // Insert bodies - const levels = new Int8Array(bodies.robotIDsLength()); - levels.fill(1); + const levels = new Int8Array(bodies.robotIDsLength()) + levels.fill(1) this.bodies.insertBulk({ id: bodies.robotIDsArray(), @@ -758,7 +773,7 @@ export default class GameWorld { parent: new Int32Array(bodies.robotIDsLength()), hp: hps, level: levels - }); + }) } /** @@ -767,56 +782,56 @@ export default class GameWorld { private parseLogs(round: number, logs: string) { // TODO regex this properly // Regex - let lines = logs.split(/\r?\n/); - let header = /^\[(A|B):(ENLIGHTENMENT_CENTER|POLITICIAN|SLANDERER|MUCKRAKER)#(\d+)@(\d+)\] (.*)/; + let lines = logs.split(/\r?\n/) + let header = /^\[(A|B):(ENLIGHTENMENT_CENTER|POLITICIAN|SLANDERER|MUCKRAKER)#(\d+)@(\d+)\] (.*)/ - let roundLogs = new Array(); + let roundLogs = new Array() // Parse each line - let index: number = 0; + let index: number = 0 while (index < lines.length) { - let line = lines[index]; - let matches = line.match(header); + let line = lines[index] + let matches = line.match(header) // Ignore empty string if (line === "") { - index += 1; - continue; + index += 1 + continue } // The entire string and its 5 parenthesized substrings must be matched! if (matches === null || (matches && matches.length != 6)) { // throw new Error(`Wrong log format: ${line}`); - console.log(`Wrong log format: ${line}`); - console.log('Omitting logs'); - return; + console.log(`Wrong log format: ${line}`) + console.log('Omitting logs') + return } - let shortenRobot = new Map(); - shortenRobot.set("ENLIGHTENMENT_CENTER", "EC"); - shortenRobot.set("POLITICIAN", "P"); - shortenRobot.set("SLANDERER", "SL"); - shortenRobot.set("MUCKRAKER", "MCKR"); + let shortenRobot = new Map() + shortenRobot.set("ENLIGHTENMENT_CENTER", "EC") + shortenRobot.set("POLITICIAN", "P") + shortenRobot.set("SLANDERER", "SL") + shortenRobot.set("MUCKRAKER", "MCKR") // Get the matches - let team = matches[1]; - let robotType = matches[2]; - let id = parseInt(matches[3]); - let logRound = parseInt(matches[4]); - let text = new Array(); - let mText = "[" + team + ":" + robotType + "#" + id + "@" + logRound + "]"; - let mText2 = "[" + team + ":" + shortenRobot.get(robotType) + "#" + id + "@" + logRound + "] "; - text.push(mText + mText2 + matches[5]); - index += 1; + let team = matches[1] + let robotType = matches[2] + let id = parseInt(matches[3]) + let logRound = parseInt(matches[4]) + let text = new Array() + let mText = "[" + team + ":" + robotType + "#" + id + "@" + logRound + "]" + let mText2 = "[" + team + ":" + shortenRobot.get(robotType) + "#" + id + "@" + logRound + "] " + text.push(mText + mText2 + matches[5]) + index += 1 // If there is additional non-header text in the following lines, add it while (index < lines.length && !lines[index].match(header)) { - text.push(lines[index]); - index +=1; + text.push(lines[index]) + index += 1 } if (logRound != round) { - console.warn(`Your computation got cut off while printing a log statement at round ${logRound}; the actual print happened at round ${round}`); + console.warn(`Your computation got cut off while printing a log statement at round ${logRound}; the actual print happened at round ${round}`) } // Push the parsed log @@ -826,8 +841,8 @@ export default class GameWorld { id: id, round: logRound, text: text.join('\n') - }); + }) } - this.logs.push(roundLogs); + this.logs.push(roundLogs) } } diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 776649ce..5c70c2e2 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -15,14 +15,23 @@ export const initialBodyTypeList: number[] = [ARCHON] export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots +// export const TILE_COLORS: Array[] = [ +// [168, 137, 97], +// [147, 117, 77], +// [88, 129, 87], +// [58, 90, 64], +// [52, 78, 65], +// [11, 32, 39], +// [8, 20, 20] +// ] + export const TILE_COLORS: Array[] = [ + [175, 147, 110], [168, 137, 97], + [158, 127, 87], [147, 117, 77], - [88, 129, 87], - [58, 90, 64], - [52, 78, 65], - [11, 32, 39], - [8, 20, 20] + [134, 107, 70], + [120, 96, 63] ] // flashy colors // [0, 147, 83], // turquoise diff --git a/client/visualizer/src/gamearea/renderer.ts b/client/visualizer/src/gamearea/renderer.ts index c7d9ea2b..10b0b681 100644 --- a/client/visualizer/src/gamearea/renderer.ts +++ b/client/visualizer/src/gamearea/renderer.ts @@ -33,7 +33,7 @@ export default class Renderer { } this.ctx['imageSmoothingEnabled'] = false - + //this.ctx.imageSmoothingQuality = "high" } /** @@ -60,7 +60,7 @@ export default class Renderer { this.renderBodies(world, curTime, nextStep, lerpAmount) this.renderHoverBox(world) - + this.renderIndicatorDotsLines(world) this.setMouseoverEvent(world) @@ -144,7 +144,7 @@ export default class Renderer { const { xrel: x, yrel: y } = this.hoverPos const cx = (minX + x) * scale, cy = (minY + (height - y - 1)) * scale this.ctx.strokeStyle = 'purple' - this.ctx.lineWidth *= 2 + this.ctx.lineWidth = 2 this.ctx.globalAlpha = 1 if (!this.conf.doingRotate) this.ctx.strokeRect(cx, cy, scale, scale) else this.ctx.strokeRect(cy, cx, scale, scale) @@ -176,30 +176,57 @@ export default class Renderer { let idxVal = map.getIdx(i, j) let plotJ = height - j - 1 - + this.ctx.lineWidth = 1 / 20 this.ctx.globalAlpha = 1 + const cx = (minX + i) * scale, cy = (minY + plotJ) * scale if (map.goldVals[idxVal] > 0) { - let size = sigmoid(map.goldVals[idxVal] / 50) - if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) - else this.ctx.drawImage(goldImg, cy + (1 - size) / 2, cx + (1 - size) / 2, scale * size, scale * size) - - - this.ctx.strokeStyle = 'gold' - this.ctx.lineWidth = 1 / 30 - if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) - else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) - } - if (map.leadVals[idxVal] > 0) { - let size = sigmoid(map.leadVals[idxVal] / 50) + if (map.leadVals[idxVal] <= 0) { + //gold only + let size = sigmoid(map.goldVals[idxVal] / 50) * .94 + if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) + else this.ctx.drawImage(goldImg, cy + (1 - size) / 2, cx + (1 - size) / 2, scale * size, scale * size) + + this.ctx.strokeStyle = 'gold' + if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) + + } else { + let goldShift = -.18; + let leadShift = .13; + + //lead and gold + let size = sigmoid(map.leadVals[idxVal] / 50) * .85 + if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1 - size) / 2, cy + (1 - size) / 2 + leadShift, scale * size, scale * size) + else this.ctx.drawImage(leadImg, cy + (1 - size) / 2, cx + (1 - size) / 2 + leadShift, scale * size, scale * size) + + + size = sigmoid(map.goldVals[idxVal] / 50) * .85 + if (!this.conf.doingRotate) this.ctx.drawImage(goldImg, cx + (1 - size) / 2, cy + (1 - size) / 2 + goldShift, scale * size, scale * size) + else this.ctx.drawImage(goldImg, cy + (1 - size) / 2, cx + (1 - size) / 2 + goldShift, scale * size, scale * size) + + + this.ctx.strokeStyle = 'gold' + if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) + + this.ctx.setLineDash([.1,.1]); + this.ctx.strokeStyle = '#59727d' + if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) + else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) + this.ctx.setLineDash([]); + } + } else if (map.leadVals[idxVal] > 0) { + //lead only + let size = sigmoid(map.leadVals[idxVal] / 50) * .94 if (!this.conf.doingRotate) this.ctx.drawImage(leadImg, cx + (1 - size) / 2, cy + (1 - size) / 2, scale * size, scale * size) else this.ctx.drawImage(leadImg, cy + (1 - size) / 2, cx + (1 - size) / 2, scale * size, scale * size) this.ctx.strokeStyle = '#59727d' - this.ctx.lineWidth = 1 / 30 if (!this.conf.doingRotate) this.ctx.strokeRect(cx + .05, cy + .05, scale * .9, scale * .9) else this.ctx.strokeRect(cy + .05, cx + .05, scale * .9, scale * .9) + } } @@ -207,21 +234,21 @@ export default class Renderer { } private renderBodies(world: GameWorld, curTime: number, nextStep?: NextStep, lerpAmount?: number) { - const bodies = world.bodies; - const length = bodies.length; - const types = bodies.arrays.type; - const teams = bodies.arrays.team; - const hps = bodies.arrays.hp; - const ids = bodies.arrays.id; - const xs = bodies.arrays.x; - const ys = bodies.arrays.y; - const actions = bodies.arrays.action; - const portables = bodies.arrays.portable; - const prototypes = bodies.arrays.prototype; - const minY = world.minCorner.y; - const maxY = world.maxCorner.y -1; - - let nextXs: Int32Array, nextYs: Int32Array, realXs: Float32Array, realYs: Float32Array; + const bodies = world.bodies + const length = bodies.length + const types = bodies.arrays.type + const teams = bodies.arrays.team + const hps = bodies.arrays.hp + const ids = bodies.arrays.id + const xs = bodies.arrays.x + const ys = bodies.arrays.y + const actions = bodies.arrays.action + const portables = bodies.arrays.portable + const prototypes = bodies.arrays.prototype + const minY = world.minCorner.y + const maxY = world.maxCorner.y - 1 + + let nextXs: Int32Array, nextYs: Int32Array, realXs: Float32Array, realYs: Float32Array if (nextStep && lerpAmount) { nextXs = nextStep.bodies.arrays.x @@ -257,21 +284,21 @@ export default class Renderer { } const renderBot = (i: number) => { - - const DEFAULT: number = 0; - const PORTABLE: number = 1; - const PROTOTYPE: number = 2; + + const DEFAULT: number = 0 + const PORTABLE: number = 1 + const PROTOTYPE: number = 2 let body_status = DEFAULT // console.log(i, bodies.length, types.length, "hhh"); // console.log(bodies[i]); - if (Boolean(portables[i])){ - body_status = PORTABLE; - } - if (Boolean(prototypes[i])){ - body_status = PROTOTYPE; - } - const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]]; - this.drawBot(img, realXs[i], realYs[i], hps[i]); + if (Boolean(portables[i])) { + body_status = PORTABLE + } + if (Boolean(prototypes[i])) { + body_status = PROTOTYPE + } + const img: HTMLImageElement = this.imgs.robots[cst.bodyTypeToString(types[i])][body_status * 2 + teams[i]] + this.drawBot(img, realXs[i], realYs[i], hps[i]) // TODO: draw bot this.drawSightRadii(realXs[i], realYs[i], types[i], ids[i] === this.lastSelectedID) @@ -411,9 +438,9 @@ export default class Renderer { // const maxY = world.maxCorner.y - 1; if (this.hoverPos) { - const {xrel, yrel} = this.hoverPos; - const x = xrel + world.minCorner.x; - const y = yrel + world.minCorner.y; + const { xrel, yrel } = this.hoverPos + const x = xrel + world.minCorner.x + const y = yrel + world.minCorner.y const idx = world.mapStats.getIdx(xrel, yrel) onMouseover(x, y, xrel, yrel, world.mapStats.rubble[idx], world.mapStats.leadVals[idx], world.mapStats.goldVals[idx]) } diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index d36eace1..4f36140f 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -16,7 +16,8 @@ export type AllImages = { }, resources: { lead: Image, - gold: Image + gold: Image, + both: Image } effects: { // TODO }, @@ -95,7 +96,8 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { }, resources: { lead: null, - gold: null + gold: null, + both: null }, effects: { death: null, @@ -246,6 +248,7 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { loadImage(result.resources, 'lead', 'resources/lead'); loadImage(result.resources, 'gold', 'resources/gold'); + loadImage(result.resources, 'both', 'resources/leadgold'); diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 0518b4c1..1995f2d5 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -439,16 +439,20 @@ export default class Controls { * Bytecodes Used: bytecodes" */ // TODO fix this (different stats) - setInfoString(id, x: number, y: number, hp: number, max_hp: number, dp: number, bodyType: string, bytecodes: number, level: number, parent?: number): void { + setInfoString(id, x: number, y: number, hp: number, max_hp: number, dp: number, bodyType: string, bytecodes: number, level: number, parent?: number, indicatorString?: string): void { // console.log(carryDirt); + if(!indicatorString) + indicatorString = ' ' + let infoString = `ID: ${id} | `; infoString += `Location: (${x}, ${y}) | `; - infoString += `Level: ${level}
`; - infoString += `HP: ${hp} / ${max_hp} | `; + infoString += `Level: ${level} | `; + infoString += `HP: ${hp} / ${max_hp}
`; infoString += `DP: ${dp} | `; infoString += `Bytecodes Used: ${bytecodes}`; if (parent !== undefined) infoString += ` | Parent: ${parent}`; - + infoString += `
Indicator String: ${indicatorString}`; + // (${bodyType})
// Location: (${x}, ${y})
//Influence: ${influence}, Conviction: ${conviction}
diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 68fcf823..08b110b2 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -253,10 +253,11 @@ export default class Looper { let bytecodes = bodies.bytecodesUsed[index]; let level = bodies.level[index]; let parent = bodies.parent[index]; - // let bid = bodies.bid[index]; + + let indicatorString = this.match.current.indicatorStrings[id] this.controls.setInfoString(id, x, y, hp, max_hp, dp, cst.bodyTypeToString(type), bytecodes, level, - parent !== 0 ? parent : undefined); + parent !== 0 ? parent : undefined, indicatorString); } } diff --git a/client/visualizer/src/static/css/style.css b/client/visualizer/src/static/css/style.css index c78b15d7..3881fa60 100644 --- a/client/visualizer/src/static/css/style.css +++ b/client/visualizer/src/static/css/style.css @@ -217,6 +217,14 @@ input[type='file'] { margin: 0px 1px; } +.info-string { + border-radius: 8px; + background-color: #333; + color: #49b5f3; + padding: 3px; + margin: 0px 1px; +} + #gamearea { width: calc(100vw - 405px); height: calc(100vh - 75px); From fc9661e026141a9a5d484d5f79412386993bd41f Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 18:49:22 -0500 Subject: [PATCH 293/413] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1520bf5b..671c6b02 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ 🚩 ## Note, Competitors -This is the development repo! Do not clone this. Instead, follow the instructions [here](http://2021.battlecode.org/getting-started) +This is the development repo! You most likely won't need anything in here; do not clone this. +Instead, follow the instructions [here](https://play.battlecode.org/getting-started) to get started. + ## Repository Structure -- `/backend`: Backend API in Django Rest Framework -- `/frontend`: Frontend dashboard in React - `/engine`: Game engine in Java - `/specs`: Game specs in Markdown (and HTML generation) - `/schema`: Game serialization schema (basically, an encoding of all units and events in a game) From a5465aeb321e931fa9164ed44c23577aec19efd5 Mon Sep 17 00:00:00 2001 From: Aidan Blum Levine Date: Sun, 2 Jan 2022 19:48:27 -0500 Subject: [PATCH 294/413] remove leadgold img --- client/visualizer/src/imageloader.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/visualizer/src/imageloader.ts b/client/visualizer/src/imageloader.ts index c192125e..645a4d8c 100644 --- a/client/visualizer/src/imageloader.ts +++ b/client/visualizer/src/imageloader.ts @@ -17,7 +17,6 @@ export type AllImages = { resources: { lead: Image, gold: Image, - both: Image } effects: { // TODO }, @@ -96,8 +95,7 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { }, resources: { lead: null, - gold: null, - both: null + gold: null }, effects: { death: null, @@ -229,7 +227,6 @@ export function loadAll(config: Config, callback: (arg0: AllImages) => void) { loadImage(result.resources, 'lead', 'resources/lead'); loadImage(result.resources, 'gold', 'resources/gold'); - loadImage(result.resources, 'both', 'resources/leadgold'); // effects From 15157abdc979be5630d2495ef12324daed51a7ee Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 20:28:08 -0500 Subject: [PATCH 295/413] Control bar tweaks --- client/visualizer/src/main/controls.ts | 4 ++-- client/visualizer/src/main/looper.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index 341309b8..de51ca7d 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -400,13 +400,13 @@ export default class Controls { const scale = this.canvas.width / loadedTime; this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - this.ctx.fillStyle = "rgb(39, 39, 39)"; + this.ctx.fillStyle = "rgb(144, 238, 144)"; this.ctx.fillRect(0, 0, time * scale, this.canvas.height); this.ctx.fillStyle = "#777"; this.ctx.fillRect(time * scale, 0, (loadedTime - time) * scale, this.canvas.height); - this.ctx.fillStyle = 'rgb(255,0,0)'; + this.ctx.fillStyle = 'rgb(0, 0, 0)'; this.ctx.fillRect(time * scale, 0, 2, this.canvas.height); // } diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index a2bf9dc8..37b64875 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -317,15 +317,19 @@ export default class Looper { //let testAnom = [anomConsts.ABYSS, anomConsts.CHARGE]; //let testAnomRounds = [300, 1000]; + // TODO: move this to controls for(var i = 0; i < world.anomalies.length; i++){ - let anom = world.anomalies[i]; + let anom = world.anomalies[i] + anomConsts.ABYSS; let anomRound = world.anomalyRounds[i]; - this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Grey" : "White"; + this.controls.ctx.save(); + this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Purple" : "White"; var pos = Math.round(anomRound*300.0/this.match.lastTurn); this.controls.ctx.beginPath(); this.controls.ctx.moveTo(pos, 0); this.controls.ctx.lineTo(pos, 1); + this.controls.ctx.lineWidth = 4; this.controls.ctx.stroke(); + this.controls.ctx.restore(); } } From a7bef7392f3d256948159a65262a3ebe5df49058 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 21:06:22 -0500 Subject: [PATCH 296/413] Add anomaly scheduling to map editor --- client/visualizer/src/mapeditor/form.ts | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index bab8e193..3e645aee 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -6,6 +6,7 @@ import {cow_border as cow} from '../cow'; import {schema, flatbuffers} from 'battlecode-playback'; import {MapRenderer, HeaderForm, SymmetryForm, RobotForm, TileForm, LeadForm, AnomalyForm, UploadedMap} from './index'; +import { throws } from 'assert'; export type MapUnit = { x: number, @@ -64,6 +65,7 @@ export default class MapEditorForm { readonly buttonInvert: HTMLButtonElement; readonly tileInfo: HTMLDivElement; + readonly anomalyInfo: HTMLDivElement; // Options private readonly conf: Config @@ -151,6 +153,10 @@ export default class MapEditorForm { this.div.appendChild(this.tileInfo); this.div.appendChild(document.createElement('hr')); + this.anomalyInfo = document.createElement("div"); + this.div.appendChild(this.anomalyInfo); + this.div.appendChild(document.createElement('hr')); + // Renderer settings const onclickUnit = (id: number) => { if (this.originalBodies.has(id) && this.getActiveForm() == this.robotsForm) { @@ -358,6 +364,7 @@ export default class MapEditorForm { const round = form.getRound(); this.anomalies.push(anomaly); this.anomalyRounds.push(round); + this.setAnomalyInfo(); } } @@ -373,6 +380,16 @@ export default class MapEditorForm { const x = form.getX(); const y = form.getY(); this.setLead(x, y, 0); + } else if (this.getActiveForm() == this.anomaliesForm) { + const form: AnomalyForm = this.anomaliesForm; + const round = form.getRound(); + let i = this.anomalyRounds.indexOf(round); + console.log("index:", i); + if (i != -1) { + this.anomalyRounds.splice(i, 1); + this.anomalies.splice(i, 1); + } + this.setAnomalyInfo(); } } @@ -557,6 +574,17 @@ export default class MapEditorForm { this.renderer.render(this.getMap()); } + private setAnomalyInfo() { + while (this.anomalyInfo.firstChild) this.anomalyInfo.removeChild(this.anomalyInfo.firstChild); + this.anomalies.forEach((anomaly, i) => { + let anomaly_str = cst.anomalyToString(anomaly); + let round = this.anomalyRounds[i]; + let anomaly_el: HTMLSpanElement = document.createElement("div"); + anomaly_el.innerHTML = `Round ${round}: ${anomaly_str}`; + this.anomalyInfo.appendChild(anomaly_el); + }) + } + /** * Returns a map with the given name, width, height, and bodies. */ @@ -633,15 +661,22 @@ export default class MapEditorForm { this.rubble = map.rubble; this.leadVals = map.lead; + this.anomalies = map.anomalies; + this.anomalyRounds = map.anomalyRounds; + this.render(); + this.setAnomalyInfo(); } reset(): void { this.lastID = 1; this.originalBodies = new Map(); this.symmetricBodies = new Map(); + this.anomalies = []; + this.anomalyRounds = []; this.initRubble(); this.initLead(); this.render(); + this.setAnomalyInfo(); } } From 5709428174d821bb811fd83a129045373f72246e Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 21:11:26 -0500 Subject: [PATCH 297/413] Sort anomaly schedule in map editor --- client/visualizer/src/mapeditor/form.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 3e645aee..bea78a10 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -364,6 +364,8 @@ export default class MapEditorForm { const round = form.getRound(); this.anomalies.push(anomaly); this.anomalyRounds.push(round); + this.anomalies.sort((i,j) => this.anomalyRounds[j] - this.anomalyRounds[i]); + this.anomalyRounds.sort(); this.setAnomalyInfo(); } } From cbd2ddb33d9545b86301e1c37007126f0c4b88be Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 21:24:22 -0500 Subject: [PATCH 298/413] omg javascript sort --- client/visualizer/src/mapeditor/form.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index bea78a10..614421fd 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -364,8 +364,8 @@ export default class MapEditorForm { const round = form.getRound(); this.anomalies.push(anomaly); this.anomalyRounds.push(round); - this.anomalies.sort((i,j) => this.anomalyRounds[j] - this.anomalyRounds[i]); - this.anomalyRounds.sort(); + this.anomalies.sort((i,j) => this.anomalyRounds[this.anomalies.indexOf(i)] - this.anomalyRounds[this.anomalies.indexOf(j)]); + this.anomalyRounds.sort((a,b) => a-b); this.setAnomalyInfo(); } } From 6b2ce9daf251a085430e437cdb6fc2be9a35ad42 Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 21:40:25 -0500 Subject: [PATCH 299/413] Change color scheme --- client/visualizer/src/constants.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index e667c63a..5d43ff7e 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -28,12 +28,17 @@ export const bodyTypePriority: number[] = [] // for guns, drones, etc. that shou // ] export const TILE_COLORS: Array[] = [ - [175, 147, 110], - [168, 137, 97], - [158, 127, 87], - [147, 117, 77], - [134, 107, 70], - [120, 96, 63] + [204, 191, 173], + [191, 179, 163], + [184, 169, 151], + [171, 157, 138], + [161, 146, 127], + [156, 143, 126], + [145, 130, 110], + [130, 117, 100], + [122, 109, 91], + [115, 102, 85], + [102, 92, 75] ] // flashy colors // [0, 147, 83], // turquoise @@ -45,11 +50,8 @@ export const TILE_COLORS: Array[] = [ // Given passability, get index of tile to use. export const getLevel = (x: number): number => { - x = 100 - x; - x /= 100; const nLev = TILE_COLORS.length - const floatLevel = ((1 - x) - 0.1) / 0.9 * nLev - const level = Math.floor(floatLevel) + const level = Math.floor((x + 9) / 10); return Math.min(nLev - 1, Math.max(0, level)) } From 9b9a827abe4af573a70be1a97d750bfdf1e97d10 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 21:55:02 -0500 Subject: [PATCH 300/413] Map editor tweaks --- client/visualizer/src/mapeditor/form.ts | 2 +- client/visualizer/src/mapeditor/forms/robots.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 614421fd..42908e3c 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -516,7 +516,7 @@ export default class MapEditorForm { */ private initRubble() { this.rubble = new Array(this.headerForm.getHeight() * this.headerForm.getWidth()); - this.rubble.fill(50); + this.rubble.fill(0); } private getRubble(x: number, y: number) { diff --git a/client/visualizer/src/mapeditor/forms/robots.ts b/client/visualizer/src/mapeditor/forms/robots.ts index db1d2165..a1b04b95 100644 --- a/client/visualizer/src/mapeditor/forms/robots.ts +++ b/client/visualizer/src/mapeditor/forms/robots.ts @@ -25,7 +25,6 @@ export default class RobotForm { private readonly ROBOT_TYPES: schema.BodyType[] = cst.initialBodyTypeList; private readonly TEAMS = { - "0": "Neutral", "1": "Red", "2": "Blue" }; From 562b75262643741c2449fc53da7c8f373c29b8a4 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 22:06:16 -0500 Subject: [PATCH 301/413] fix sorting --- client/visualizer/src/mapeditor/form.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 42908e3c..94545532 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -362,10 +362,18 @@ export default class MapEditorForm { const form: AnomalyForm = this.anomaliesForm; const anomaly = form.getAnomaly(); const round = form.getRound(); + this.anomalies.push(anomaly); this.anomalyRounds.push(round); - this.anomalies.sort((i,j) => this.anomalyRounds[this.anomalies.indexOf(i)] - this.anomalyRounds[this.anomalies.indexOf(j)]); + + let indices = Array.from(this.anomalyRounds.keys()) + indices.sort((i, j) => + this.anomalyRounds[i] - this.anomalyRounds[j]); this.anomalyRounds.sort((a,b) => a-b); + let old_anomalies = this.anomalies.slice(); + for (let i = 0; i < indices.length; i++) { + this.anomalies[i] = old_anomalies[indices[i]]; + } this.setAnomalyInfo(); } } From 1ccbece4e48df9bea7291ede9af807c3ca83f9ed Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 22:16:25 -0500 Subject: [PATCH 302/413] Fix sorting and anomaly serialization --- client/visualizer/src/constants.ts | 10 +++++----- client/visualizer/src/mapeditor/form.ts | 26 +++++++++++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index 5d43ff7e..a8ecd4a3 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -13,7 +13,7 @@ export const WATCHTOWER = schema.BodyType.WATCHTOWER export const bodyTypeList: number[] = [ARCHON, BUILDER, LABORATORY, MINER, SAGE, SOLDIER, WATCHTOWER] export const buildingTypeList: number[] = [ARCHON, LABORATORY, WATCHTOWER]; export const initialBodyTypeList: number[] = [ARCHON] -export const anomalyList = [schema.Action.VORTEX, schema.Action.FURY, schema.Action.CHARGE, schema.Action.ABYSS] +export const anomalyList = [0, 1, 2, 3] export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots @@ -224,13 +224,13 @@ export function symmetryToString(symmetry: Symmetry) { export function anomalyToString(anomaly: schema.Action) { switch (anomaly) { - case schema.Action.VORTEX: + case 3: return "vortex" - case schema.Action.FURY: + case 2: return "fury" - case schema.Action.ABYSS: + case 0: return "abyss" - case schema.Action.CHARGE: + case 1: return "charge" default: throw new Error("invalid anomaly") } diff --git a/client/visualizer/src/mapeditor/form.ts b/client/visualizer/src/mapeditor/form.ts index 94545532..8d872056 100644 --- a/client/visualizer/src/mapeditor/form.ts +++ b/client/visualizer/src/mapeditor/form.ts @@ -363,16 +363,22 @@ export default class MapEditorForm { const anomaly = form.getAnomaly(); const round = form.getRound(); - this.anomalies.push(anomaly); - this.anomalyRounds.push(round); - - let indices = Array.from(this.anomalyRounds.keys()) - indices.sort((i, j) => - this.anomalyRounds[i] - this.anomalyRounds[j]); - this.anomalyRounds.sort((a,b) => a-b); - let old_anomalies = this.anomalies.slice(); - for (let i = 0; i < indices.length; i++) { - this.anomalies[i] = old_anomalies[indices[i]]; + let exists = this.anomalyRounds.indexOf(round); + if (exists == -1) { + this.anomalies.push(anomaly); + this.anomalyRounds.push(round); + + let indices = Array.from(this.anomalyRounds.keys()) + indices.sort((i, j) => + this.anomalyRounds[i] - this.anomalyRounds[j]); + this.anomalyRounds.sort((a,b) => a-b); + let old_anomalies = this.anomalies.slice(); + for (let i = 0; i < indices.length; i++) { + this.anomalies[i] = old_anomalies[indices[i]]; + } + } + else { + this.anomalies[exists] = anomaly; } this.setAnomalyInfo(); } From d689cdc55f65d67b30667b572b715c781082dea4 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 22:41:43 -0500 Subject: [PATCH 303/413] Fix bugs with anomaly schedules --- client/playback/src/gameworld.ts | 20 ++++++++++++-------- client/visualizer/src/constants.ts | 2 ++ client/visualizer/src/main/looper.ts | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index c25ff528..f37dcb47 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -46,8 +46,8 @@ export type MapStats = { symmetry: number - anomalies: Int8Array - anomalyRounds: Int8Array + anomalies: Int32Array + anomalyRounds: Int32Array getIdx: (x: number, y: number) => number getLoc: (idx: number) => Victor @@ -62,7 +62,9 @@ export type TeamStats = { gold: number, total_hp: [number[], number[], number[], number[], number[], number[], number[]], leadChange: number, - goldChange: number + goldChange: number, + leadIncome: number, + goldIncome: number } export type IndicatorDotsSchema = { @@ -230,7 +232,9 @@ export default class GameWorld { gold: 0, total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], leadChange: 0, - goldChange: 0 + goldChange: 0, + leadIncome: 0, + goldIncome: 0 }) } @@ -247,8 +251,8 @@ export default class GameWorld { goldVals: new Int32Array(0), symmetry: 0, - anomalies: new Int8Array(0), - anomalyRounds: new Int8Array(0), + anomalies: new Int32Array(0), + anomalyRounds: new Int32Array(0), getIdx: (x: number, y: number) => 0, getLoc: (idx: number) => new Victor(0, 0) @@ -333,8 +337,8 @@ export default class GameWorld { this.mapStats.symmetry = map.symmetry() - this.mapStats.anomalies = Int8Array.from(map.anomaliesArray()) - this.mapStats.anomalyRounds = Int8Array.from(map.anomalyRoundsArray()) + this.mapStats.anomalies = Int32Array.from(map.anomaliesArray()) + this.mapStats.anomalyRounds = Int32Array.from(map.anomalyRoundsArray()) // Check with header.totalRounds() ? } diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index a8ecd4a3..d7e252b0 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -17,6 +17,8 @@ export const anomalyList = [0, 1, 2, 3] export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots +export const MAX_ROUNDS = 2000; + // export const TILE_COLORS: Array[] = [ // [168, 137, 97], // [147, 117, 77], diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 37b64875..8a60f4d6 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -321,9 +321,10 @@ export default class Looper { for(var i = 0; i < world.anomalies.length; i++){ let anom = world.anomalies[i] + anomConsts.ABYSS; let anomRound = world.anomalyRounds[i]; + console.log("round:", anomRound); this.controls.ctx.save(); this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Purple" : "White"; - var pos = Math.round(anomRound*300.0/this.match.lastTurn); + var pos = Math.round(anomRound/2000 * this.controls.canvas.width); this.controls.ctx.beginPath(); this.controls.ctx.moveTo(pos, 0); this.controls.ctx.lineTo(pos, 1); From 2b21f2b2885fd583e35833399795d07514a9a31e Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 22:49:19 -0500 Subject: [PATCH 304/413] Handle something correctly --- client/visualizer/src/main/looper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 8a60f4d6..2a12faf4 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -324,7 +324,7 @@ export default class Looper { console.log("round:", anomRound); this.controls.ctx.save(); this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Purple" : "White"; - var pos = Math.round(anomRound/2000 * this.controls.canvas.width); + var pos = Math.round(anomRound/ (this.conf.tournamentMode ? cst.MAX_ROUNDS : this.match.lastTurn) * this.controls.canvas.width); this.controls.ctx.beginPath(); this.controls.ctx.moveTo(pos, 0); this.controls.ctx.lineTo(pos, 1); From 7e3c953c586377c9464a12347f08bff50606b745 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 22:54:13 -0500 Subject: [PATCH 305/413] Don't hardcode max turn --- client/visualizer/src/constants.ts | 2 -- client/visualizer/src/main/controls.ts | 4 ++-- client/visualizer/src/main/looper.ts | 5 +++-- client/visualizer/src/sidebar/stats.ts | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/visualizer/src/constants.ts b/client/visualizer/src/constants.ts index d7e252b0..a8ecd4a3 100644 --- a/client/visualizer/src/constants.ts +++ b/client/visualizer/src/constants.ts @@ -17,8 +17,6 @@ export const anomalyList = [0, 1, 2, 3] export const bodyTypePriority: number[] = [] // for guns, drones, etc. that should be drawn over other robots -export const MAX_ROUNDS = 2000; - // export const TILE_COLORS: Array[] = [ // [168, 137, 97], // [147, 117, 77], diff --git a/client/visualizer/src/main/controls.ts b/client/visualizer/src/main/controls.ts index de51ca7d..305dffb1 100644 --- a/client/visualizer/src/main/controls.ts +++ b/client/visualizer/src/main/controls.ts @@ -390,9 +390,9 @@ export default class Controls { * Redraws the timeline and sets the current round displayed in the controls. */ // TODO scale should be constant; should not depend on loadedTime - setTime(time: number, loadedTime: number, upsUnpaused: number, paused: Boolean, fps: number, lagging: Boolean) { + setTime(time: number, loadedTime: number, upsUnpaused: number, paused: Boolean, fps: number, lagging: Boolean, maxTurn: number) { - if (this.conf.tournamentMode) loadedTime = 1500; + if (this.conf.tournamentMode) loadedTime = maxTurn; // if (!this.conf.tournamentMode) { // Redraw the timeline diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 2a12faf4..4ad3386b 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -229,7 +229,8 @@ export default class Looper { this.controls.getUPS(), this.isPaused(), this.rendersPerSecond.tps, - Math.abs(this.updatesPerSecond.tps) < Math.max(0, Math.abs(this.goalUPS) - 2) + Math.abs(this.updatesPerSecond.tps) < Math.max(0, Math.abs(this.goalUPS) - 2), + this.match.maxTurn ); // run simulation @@ -324,7 +325,7 @@ export default class Looper { console.log("round:", anomRound); this.controls.ctx.save(); this.controls.ctx.strokeStyle = (anom === anomConsts.ABYSS) ? "Blue" : (anom === anomConsts.CHARGE) ? "Yellow" : (anom === anomConsts.FURY) ? "Red" : (anom === anomConsts.VORTEX) ? "Purple" : "White"; - var pos = Math.round(anomRound/ (this.conf.tournamentMode ? cst.MAX_ROUNDS : this.match.lastTurn) * this.controls.canvas.width); + var pos = Math.round(anomRound/ (this.conf.tournamentMode ? this.match.maxTurn : this.match.lastTurn) * this.controls.canvas.width); this.controls.ctx.beginPath(); this.controls.ctx.moveTo(pos, 0); this.controls.ctx.lineTo(pos, 1); diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 84423c0c..393ce09f 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -293,7 +293,7 @@ export default class Stats { const div = document.createElement('div'); const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'Archon Control'; + label.innerText = 'Archon Status'; div.appendChild(label); div.appendChild(this.ECs); return div; From 2863375d1941848ae9179464bd381f565d588626 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Sun, 2 Jan 2022 23:10:07 -0500 Subject: [PATCH 306/413] Lead and gold mined --- client/playback/src/gameworld.ts | 21 ++++++++++++++++----- client/visualizer/src/main/looper.ts | 2 +- client/visualizer/src/sidebar/stats.ts | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/client/playback/src/gameworld.ts b/client/playback/src/gameworld.ts index f37dcb47..159a987a 100644 --- a/client/playback/src/gameworld.ts +++ b/client/playback/src/gameworld.ts @@ -63,8 +63,8 @@ export type TeamStats = { total_hp: [number[], number[], number[], number[], number[], number[], number[]], leadChange: number, goldChange: number, - leadIncome: number, - goldIncome: number + leadMined: number, + goldMined: number } export type IndicatorDotsSchema = { @@ -233,8 +233,8 @@ export default class GameWorld { total_hp: [[0], [0], [0], [0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], leadChange: 0, goldChange: 0, - leadIncome: 0, - goldIncome: 0 + leadMined: 0, + goldMined: 0 }) } @@ -390,6 +390,8 @@ export default class GameWorld { statObj.gold += delta.teamGoldChanges(i) statObj.leadChange = delta.teamLeadChanges(i) statObj.goldChange = delta.teamGoldChanges(i) + statObj.leadMined = 0 + statObj.goldMined = 0 this.teamStats.set(teamID, statObj) } @@ -466,7 +468,7 @@ export default class GameWorld { this.bodies.alter({id: robotID, targetx: target_body.x, targety: target_body.y}); } this.actionRobots.push(robotID); - }; // should be called for actions performed *by* the robot. + }; // should be called for actions performed *by* the robot switch (action) { // TODO: validate actions? // Actions list from battlecode.fbs enum Action @@ -500,6 +502,15 @@ export default class GameWorld { this.bodies.alter({ id: robotID, portable: 1 - body.portable }) break + case schema.Action.MINE_LEAD: + setAction() + teamStatsObj.leadMined += 1; + break + + case schema.Action.MINE_GOLD: + setAction() + teamStatsObj.goldMined += 1; + case schema.Action.MUTATE: setAction() teamStatsObj.robots[body.type][body.level - 1] -= 1 diff --git a/client/visualizer/src/main/looper.ts b/client/visualizer/src/main/looper.ts index 4ad3386b..877e1b14 100644 --- a/client/visualizer/src/main/looper.ts +++ b/client/visualizer/src/main/looper.ts @@ -383,7 +383,7 @@ export default class Looper { //### this.stats.setTeamInfluence(teamID, teamHP, totalHP); // this.stats.setBuffs(teamID, teamStats.numBuffs); // this.stats.setBid(teamID, teamStats.bid); - this.stats.setIncome(teamID, teamStats.leadChange, teamStats.goldChange, world.turn); + this.stats.setIncome(teamID, teamStats.leadMined, teamStats.goldMined, world.turn); // this.stats.setIncome(teamID, 3 + teamID, 5 + teamID, world.turn); } diff --git a/client/visualizer/src/sidebar/stats.ts b/client/visualizer/src/sidebar/stats.ts index 393ce09f..b5786efa 100644 --- a/client/visualizer/src/sidebar/stats.ts +++ b/client/visualizer/src/sidebar/stats.ts @@ -262,7 +262,7 @@ export default class Stats { title.colSpan = 4; const label = document.createElement('div'); label.className = "stats-header"; - label.innerText = 'Total Lead & Gold Income Per Turn'; + label.innerText = 'Total Lead & Gold Mined Per Turn'; const row = document.createElement("tr"); From c9bcab215bc4a5a5d6da8ec69529ef84fefa4f2e Mon Sep 17 00:00:00 2001 From: Jerry Mao Date: Sun, 2 Jan 2022 23:35:11 -0500 Subject: [PATCH 307/413] Fix engine bugs --- .../main/battlecode/common/GameConstants.java | 2 +- .../src/main/battlecode/world/BuildMaps.java | 2 - .../src/main/battlecode/world/GameWorld.java | 6 +- .../battlecode/world/RobotControllerImpl.java | 2 + .../main/battlecode/world/maps/Circle.java | 56 ------------------ .../main/battlecode/world/maps/Quadrants.java | 56 ------------------ .../battlecode/world/resources/circle.map22 | Bin 31984 -> 0 bytes .../world/resources/eckleburg.map22 | Bin 0 -> 29172 bytes .../world/resources/intersection.map22 | Bin 0 -> 10116 bytes .../world/resources/quadrants.map22 | Bin 13036 -> 0 bytes 10 files changed, 7 insertions(+), 117 deletions(-) delete mode 100644 engine/src/main/battlecode/world/maps/Circle.java delete mode 100644 engine/src/main/battlecode/world/maps/Quadrants.java delete mode 100644 engine/src/main/battlecode/world/resources/circle.map22 create mode 100644 engine/src/main/battlecode/world/resources/eckleburg.map22 create mode 100644 engine/src/main/battlecode/world/resources/intersection.map22 delete mode 100644 engine/src/main/battlecode/world/resources/quadrants.map22 diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 36667e80..f710068d 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -91,7 +91,7 @@ public class GameConstants { // ********************************* /** A blueprint building's health, as a multiplier of max health. */ - public static final float PROTOTYPE_HP_PERCENTAGE = 0.6f; + public static final float PROTOTYPE_HP_PERCENTAGE = 0.8f; /** The multiplier for reclaiming a building's cost. */ public static final float RECLAIM_COST_MULTIPLIER = 0.2f; diff --git a/engine/src/main/battlecode/world/BuildMaps.java b/engine/src/main/battlecode/world/BuildMaps.java index 148f9f2d..832f58f5 100644 --- a/engine/src/main/battlecode/world/BuildMaps.java +++ b/engine/src/main/battlecode/world/BuildMaps.java @@ -18,8 +18,6 @@ public class BuildMaps { */ public static void main(String[] args) { MapTestSmall.main(args); - Circle.main(args); - Quadrants.main(args); } } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 1402580e..dc45081e 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -480,7 +480,7 @@ public void destroyRobot(int id) { this.gold[locationToIndex(robot.getLocation())] += goldDropped; this.matchMaker.addLeadDrop(robot.getLocation(), leadDropped); - this.matchMaker.addLeadDrop(robot.getLocation(), goldDropped); + this.matchMaker.addGoldDrop(robot.getLocation(), goldDropped); controlProvider.robotKilled(robot); objectInfo.destroyRobot(id); @@ -528,10 +528,12 @@ private void causeAbyssGridUpdate(float reduceFactor, MapLocation[] locations) { int currentLead = getLead(locations[i]); int leadUpdate = (int) (reduceFactor * currentLead); setLead(locations[i], currentLead - leadUpdate); + if (leadUpdate != 0) this.matchMaker.addLeadDrop(locations[i], -leadUpdate); int currentGold = getGold(locations[i]); int goldUpdate = (int) (reduceFactor * currentGold); setGold(locations[i], currentGold - goldUpdate); + if (goldUpdate != 0) this.matchMaker.addGoldDrop(locations[i], -goldUpdate); } } @@ -597,7 +599,7 @@ public void causeChargeGlobal() { /** Used to sort droids for charge */ class SortByFriends implements Comparator { public int compare(InternalRobot a, InternalRobot b) { - return a.getNumVisibleFriendlyRobots(false) - b.getNumVisibleFriendlyRobots(false); + return b.getNumVisibleFriendlyRobots(false) - a.getNumVisibleFriendlyRobots(false); } } diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index f67336fd..32e52a3f 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -609,6 +609,7 @@ public void mineLead(MapLocation loc) throws GameActionException { this.gameWorld.setLead(loc, this.gameWorld.getLead(loc) - 1); this.gameWorld.getTeamInfo().addLead(getTeam(), 1); this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_LEAD, locationToInt(loc)); + this.gameWorld.getMatchMaker().addLeadDrop(robot.getLocation(), -1); } private void assertCanMineGold(MapLocation loc) throws GameActionException { @@ -638,6 +639,7 @@ public void mineGold(MapLocation loc) throws GameActionException { this.gameWorld.setGold(loc, this.gameWorld.getGold(loc) - 1); this.gameWorld.getTeamInfo().addGold(getTeam(), 1); this.gameWorld.getMatchMaker().addAction(getID(), Action.MINE_GOLD, locationToInt(loc)); + this.gameWorld.getMatchMaker().addGoldDrop(robot.getLocation(), -1); } // ************************* diff --git a/engine/src/main/battlecode/world/maps/Circle.java b/engine/src/main/battlecode/world/maps/Circle.java deleted file mode 100644 index a18f85bc..00000000 --- a/engine/src/main/battlecode/world/maps/Circle.java +++ /dev/null @@ -1,56 +0,0 @@ -package battlecode.world.maps; - -import battlecode.common.MapLocation; -import battlecode.common.RobotType; -import battlecode.common.Team; -import battlecode.world.GameMapIO; -import battlecode.world.LiveMap; -import battlecode.world.MapBuilder; -import battlecode.world.TestMapBuilder; - -import battlecode.common.GameConstants; - -import java.io.File; -import java.io.IOException; -import java.util.Random; - -/** - * Generate a map. - */ -public class Circle { - - // change this!!! - public static final String mapName = "circle"; - - // don't change this!! - public static final String outputDirectory = "engine/src/main/battlecode/world/resources/"; - - /** - * @param args unused - */ - public static void main(String[] args) { - try { - makeCircle(); - } catch (IOException e) { - System.out.println(e); - } - System.out.println("Generated a map!"); - } - - public static void makeCircle() throws IOException { - final int half = 31; - final MapLocation center = new MapLocation(half, half); - MapBuilder mapBuilder = new MapBuilder(mapName, 2*half+1, 2*half+1, 0, 0, 116896); - mapBuilder.addSymmetricArchon(20, 20); - mapBuilder.addSymmetricArchon(20, 2*half-20); - - for (int i = 0; i <= half; i++) { - for (int j = 0; j <= 2*half; j++) { - int d = new MapLocation(i, j).distanceSquaredTo(center); - mapBuilder.setSymmetricLead(i, j, d); - } - } - - mapBuilder.saveMap(outputDirectory); - } -} diff --git a/engine/src/main/battlecode/world/maps/Quadrants.java b/engine/src/main/battlecode/world/maps/Quadrants.java deleted file mode 100644 index ad9bc86c..00000000 --- a/engine/src/main/battlecode/world/maps/Quadrants.java +++ /dev/null @@ -1,56 +0,0 @@ -package battlecode.world.maps; - -import battlecode.common.MapLocation; -import battlecode.common.RobotType; -import battlecode.common.Team; -import battlecode.world.GameMapIO; -import battlecode.world.LiveMap; -import battlecode.world.MapBuilder; -import battlecode.world.MapSymmetry; -import battlecode.world.TestMapBuilder; - -import battlecode.common.GameConstants; - -import java.io.File; -import java.io.IOException; -import java.util.Random; - -/** - * Generate a map. - */ -public class Quadrants { - - // change this!!! - public static final String mapName = "quadrants"; - - // don't change this!! - public static final String outputDirectory = "engine/src/main/battlecode/world/resources/"; - - /** - * @param args unused - */ - public static void main(String[] args) { - try { - makeQuadrants(); - } catch (IOException e) { - System.out.println(e); - } - System.out.println("Generated a map!"); - } - - public static void makeQuadrants() throws IOException { - MapBuilder mapBuilder = new MapBuilder(mapName, 40, 40, 0, 0, 215957); - mapBuilder.setSymmetry(MapSymmetry.ROTATIONAL); - mapBuilder.addSymmetricArchon(5, 5); - mapBuilder.addSymmetricArchon(10, 30); - - for (int i = 5; i <= 15; i++) { - mapBuilder.setSymmetricLead(i, 15, 10); - mapBuilder.setSymmetricLead(i, 25, 10); - mapBuilder.setSymmetricLead(15, i, 10); - mapBuilder.setSymmetricLead(25, i, 10); - } - - mapBuilder.saveMap(outputDirectory); - } -} diff --git a/engine/src/main/battlecode/world/resources/circle.map22 b/engine/src/main/battlecode/world/resources/circle.map22 deleted file mode 100644 index 15adfd6a180796fe0563b53ba281efd711cf4e6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31984 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 v+40G-$@Y)f+5PFYtq${cZcMzy0Ud(dd5w)S{{g diff --git a/engine/src/main/battlecode/world/resources/eckleburg.map22 b/engine/src/main/battlecode/world/resources/eckleburg.map22 new file mode 100644 index 0000000000000000000000000000000000000000..cdf67a3ffd0c91883df36b28057211b1b68fa982 GIT binary patch literal 29172 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 N6^GuAz`>5c;V-+4fM);z literal 0 HcmV?d00001 diff --git a/engine/src/main/battlecode/world/resources/quadrants.map22 b/engine/src/main/battlecode/world/resources/quadrants.map22 deleted file mode 100644 index 6c4e19ca7aa02502fb94b279359aef44a497d86f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13036 zcmeI3u}T9$5QgV2r<`(yg@r=25DNk4_15{k`TUPKH`_kX?BU+*#^)o(w(+^KJsyrD z^{Rj>Fm(lv;ek{KkHa#`r8*3TLdvB&h{ZC>r8*3TLdvB&h{ZC>r8*3TLdvB&h{ZC> zr8*3TLdvB&h{ZC(4Gj$nrst9Tf=P8WKj~BfRX`O`1@a2eZ|>CJ`p9U?GwJ`xD^Xja zT&k;Ok?*2hs>?~W70RW$S{C^(%B8xTR9m53s;gy@@1k6)%Sp8r%B8wm7Wpp9rMjF{ zTcKR4t7V~Gs=)uQK-_^eUIK+`AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j` z@_;-b56A<5$peFZza<&`E+pQQJbAo$yn6Kh&ZP6--pBFwq}#`V_g5a59!J0C;@ Date: Mon, 3 Jan 2022 01:57:11 -0500 Subject: [PATCH 308/413] Add sql query for email --- EMAILS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EMAILS.md b/EMAILS.md index 9c3ee9f8..0a38c05c 100644 --- a/EMAILS.md +++ b/EMAILS.md @@ -40,6 +40,8 @@ to be able to use it. (`add consult` only works when running through bash, for s Get a list of emails, and convert it to the format as specified by mmblanche's `-f` argument: one email per line. (For example, if you're working with a Google Form, you can get a Google Sheet of responses. Create a new tab -- **not** the tab where form responses are being collected!. Convert it into only one column of values such that all the values are emails -- strip out timestamps, header row, and the like. Then download this as a csv. If you'd like to export emails from our database, you can use a nice interface to download a table as a csv, and work with it.) +If you have a terminal database client, you can instead run a command like `\copy (select email from api_user) to './emails.csv' with csv;`. + Move this file to your Athena locker; you can use `scp` for this (example [here](https://unix.stackexchange.com/questions/106480/how-to-copy-files-from-one-machine-to-another-using-ssh)). Finally run mmblanche! For example, `mmblanche [mailman-list-name] -al [path/to/file]`. Likely you'll want to use `-al`, as it simply adds any emails in the file to the list, skips over duplicates for you, and doesn't delete anything otherwise. From 558e7c09a69a3e07e4fa1859f6eb0c721c1915ea Mon Sep 17 00:00:00 2001 From: n8kim1 Date: Sun, 2 Jan 2022 23:55:58 -0800 Subject: [PATCH 309/413] add the web-based viz --- client/visualizer/visualizer.html | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 client/visualizer/visualizer.html diff --git a/client/visualizer/visualizer.html b/client/visualizer/visualizer.html new file mode 100644 index 00000000..6c822581 --- /dev/null +++ b/client/visualizer/visualizer.html @@ -0,0 +1,52 @@ + + + + Battlecode Online Match Viewer + + + + + + + +

+ + + + + + +
+

Loading Battlecode client...

+
+ + From fedf076d77af48891b7dd1121a3f0f7e5b2cb90c Mon Sep 17 00:00:00 2001 From: n8kim1 Date: Mon, 3 Jan 2022 01:14:29 -0800 Subject: [PATCH 310/413] Add the web-based-client deploy script --- client/deploy-web-client.sh | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 client/deploy-web-client.sh diff --git a/client/deploy-web-client.sh b/client/deploy-web-client.sh new file mode 100644 index 00000000..f9c54de6 --- /dev/null +++ b/client/deploy-web-client.sh @@ -0,0 +1,43 @@ +# TODO enforce state of repo up-to-date +# TODO year as arg +# TODO prereqs: npm, tsc, java?, flatc + +# TODO check rel_java.md sidebyside to see if any missing steps + +BUCKET_NAME="bc-game-storage" +# TODO make gs://$BUCKET_NAME/clients/2022/ a var, and use it + +echo "IMPORTANT: Make sure to update gameVersion in client/visualizer/src/config." +read -p "When done, press enter to proceed..." + +cd ../schema +npm install +npm run build +# TODO the following replacement could be done automatically i think +echo "IMPORTANT: " +echo "NOW, change line 3 of schema/ts/battlecode_generated.ts to \`import { flatbuffers } from \"flatbuffers\"\`." +echo "DON'T FORGET TO SAVE!" +read -p "When done, press enter to proceed..." +cd ../client + +cd playback +npm install +npm run build +cd ../visualizer +npm install +npm run prod +cd .. + +gsutil -m rm gs://$BUCKET_NAME/clients/2022/** +gsutil -m cp -r visualizer/out gs://$BUCKET_NAME/clients/2022/ +gsutil -m cp visualizer/visualizer.html gs://$BUCKET_NAME/clients/2022/ +gsutil -m setmeta -h "Cache-Control:no-cache" -r gs://$BUCKET_NAME/clients/2022/** + +echo 'Do you wish to deploy the client to the public? Type public and press enter.' +echo 'IMPORTANT: NEVER DO THIS BEFORE THE GAME IS RELEASED' +read -p 'input: ' ispublic +if [ "$ispublic" == 'public' ] +then + gsutil -m acl ch -u AllUsers:R -r gs://$BUCKET_NAME/clients/2022/** +fi + From 4a9a9c443d411b8ff3501810f80090deb74164e3 Mon Sep 17 00:00:00 2001 From: n8kim1 Date: Mon, 3 Jan 2022 01:14:44 -0800 Subject: [PATCH 311/413] Update client url --- client/visualizer/visualizer.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/visualizer/visualizer.html b/client/visualizer/visualizer.html index 6c822581..83aabde6 100644 --- a/client/visualizer/visualizer.html +++ b/client/visualizer/visualizer.html @@ -13,7 +13,11 @@ />
- + From b8868086de3cd9748fdf2de729eba3fc3e778efa Mon Sep 17 00:00:00 2001 From: Nathaniel Kim Date: Mon, 3 Jan 2022 17:42:31 -0500 Subject: [PATCH 331/413] Update specs.md.html --- specs/specs.md.html | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/specs.md.html b/specs/specs.md.html index 50a1b5f8..6055ec58 100644 --- a/specs/specs.md.html +++ b/specs/specs.md.html @@ -16,7 +16,6 @@ # Formal specification -n: 2021.3.0.5