├── .gitignore ├── LICENSE ├── README.md ├── bot.json ├── compile.bat ├── compile.sh ├── output ├── map.txt └── state.json ├── pom.xml ├── run.bat ├── run.sh └── src ├── main ├── java │ └── za │ │ └── co │ │ └── entelect │ │ └── challenge │ │ ├── bot │ │ └── BasicBot.java │ │ ├── dto │ │ ├── AlienManager.java │ │ ├── BuildingsAvailable.java │ │ ├── GameState.java │ │ ├── Map.java │ │ ├── Missile.java │ │ ├── Player.java │ │ ├── Row.java │ │ ├── Settings.java │ │ ├── Ship.java │ │ ├── Wave.java │ │ ├── enums │ │ │ ├── EntityType.java │ │ │ └── ShipCommand.java │ │ └── reader │ │ │ ├── BasicGameStateReader.java │ │ │ ├── GameStateReader.java │ │ │ ├── GsonGameStateReader.java │ │ │ └── JacksonGameStateReader.java │ │ ├── program │ │ └── Main.java │ │ └── utils │ │ ├── BotHelper.java │ │ ├── FileHelper.java │ │ ├── LogHelper.java │ │ └── StringUtility.java └── resources │ └── settings.properties └── test ├── java └── za │ └── co │ └── entelect │ └── challenge │ └── dto │ └── GameStateParsingTest.java └── resources └── state.json /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/** 4 | *.iml 5 | .idea 6 | **/target 7 | **/advanced/bot 8 | **/expert/bot 9 | logs 10 | **/*.log 11 | output/move.txt 12 | /target/ 13 | **/*.class 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Entelect Challenge 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java 2 | If you plan to develop your entry in Java you need to download and install the latest [Java 8 Development Kit](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). 3 | 4 | The sample bot also uses Maven for building and dependency management - detailed instructions for installing it are provided below. 5 | 6 | ## Maven Installation 7 | Installation is fairly simple: 8 | * Maven is free software that can be downloaded [here](http://maven.apache.org/download.cgi) (local mirrors are available). 9 | * Install as per the included README.txt: 10 | * Ensure the JAVA_HOME environment variable is set to the root of your JDK installation (eg. on Windows: C:\\Program Files\\Java\\jdk8). 11 | * Extract the .zip / .tar.gz archive. 12 | * Add the bin folder from the extracted directory to your path. 13 | * Verify that the installation is working by starting a new command line and running `mvn --version` it should output something similar to: 14 | ```powershell 15 | Apache Maven 3.3.1 (cab6659f9874fa96462afef40fcf6bc033d58c1c; 2015-03-13T22:10:27+02:00) 16 | Maven home: c:\DevTools\Java\maven-3.3.1 17 | Java version: 1.8.0_40, vendor: Oracle Corporation 18 | Java home: c:\DevTools\Java\jdk8u40\jre 19 | Default locale: en_GB, platform encoding: Cp1252 20 | OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos" 21 | ``` 22 | 23 | If you need to use any libraries in your bot simply include the dependencies in your project's pom.xml. 24 | 25 | ## Get The Code 26 | Download the [zip file](https://github.com/EntelectChallenge/2015-SpaceInvaders-Bot-Java/archive/master.zip) from Github or use Git to clone the repository: 27 | * Start Git Bash 28 | * Change to the directory where you want to checkout the sample bot 29 | * Run: `git clone https://github.com/EntelectChallenge/2015-SpaceInvaders-Bot-Java.git` 30 | 31 | ## Compile 32 | The easiest way to compile is to open a Command Prompt, change to your bot folder and run `compile.bat`. This will use Maven to fetch your dependencies and build your bot. 33 | 34 | ## Run 35 | Once you have compiled you can do a basic test of the bot by simply launching a Command Prompt, changing to the bot directory and running `run.bat output`. This will use the example state and map files in the output folder. -------------------------------------------------------------------------------- /bot.json: -------------------------------------------------------------------------------- 1 | { 2 | "Author": "Entelect", 3 | "Email": "", 4 | "NickName": "Java QS Bot" 5 | } -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | mvn clean compile assembly:single -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mvn clean compile assembly:single 4 | -------------------------------------------------------------------------------- /output/map.txt: -------------------------------------------------------------------------------- 1 | ################### 2 | # C# Sample Bot # 3 | # Round: 33 # 4 | # Kills: 1 # 5 | # Lives: 0 # 6 | # Missiles: 1/2 # 7 | ################### 8 | # | MMM # 9 | # VVV # 10 | # --- - --- # 11 | # --- --- --- # 12 | # -- -- --- # 13 | # # 14 | # # 15 | # x x # 16 | # i # 17 | # x x x x # 18 | # # 19 | # # 20 | # x x x # 21 | # # 22 | # x x # 23 | # ! # 24 | # # 25 | # # 26 | # -- - - --- # 27 | # --- - -- --- # 28 | # --- -- --- # 29 | # AAA # 30 | # XXX # 31 | ################### 32 | # Missiles: 1/1 # 33 | # Lives: 0 # 34 | # Kills: 1 # 35 | # Round: 33 # 36 | # Node Sample Bot # 37 | ################### 38 | 39 | -------------------------------------------------------------------------------- /output/state.json: -------------------------------------------------------------------------------- 1 | { 2 | "BuildingsAvailable": [ 3 | { 4 | "Command": "BuildAlienFactory", 5 | "Type": "AlienFactory", 6 | "Cost": 1 7 | }, 8 | { 9 | "Command": "BuildMissileController", 10 | "Type": "MissileController", 11 | "Cost": 1 12 | }, 13 | { 14 | "Command": "BuildShield", 15 | "Type": "Shield", 16 | "Cost": 1 17 | } 18 | ], 19 | "Map": { 20 | "Width": 19, 21 | "Height": 25, 22 | "Rows": [ 23 | [ 24 | { 25 | "Id": 1, 26 | "Alive": true, 27 | "X": 0, 28 | "Y": 0, 29 | "Width": 1, 30 | "Height": 1, 31 | "Type": "Wall", 32 | "PlayerNumber": 0 33 | }, 34 | { 35 | "Id": 2, 36 | "Alive": true, 37 | "X": 1, 38 | "Y": 0, 39 | "Width": 1, 40 | "Height": 1, 41 | "Type": "Wall", 42 | "PlayerNumber": 0 43 | }, 44 | { 45 | "Id": 3, 46 | "Alive": true, 47 | "X": 2, 48 | "Y": 0, 49 | "Width": 1, 50 | "Height": 1, 51 | "Type": "Wall", 52 | "PlayerNumber": 0 53 | }, 54 | { 55 | "Id": 4, 56 | "Alive": true, 57 | "X": 3, 58 | "Y": 0, 59 | "Width": 1, 60 | "Height": 1, 61 | "Type": "Wall", 62 | "PlayerNumber": 0 63 | }, 64 | { 65 | "Id": 5, 66 | "Alive": true, 67 | "X": 4, 68 | "Y": 0, 69 | "Width": 1, 70 | "Height": 1, 71 | "Type": "Wall", 72 | "PlayerNumber": 0 73 | }, 74 | { 75 | "Id": 6, 76 | "Alive": true, 77 | "X": 5, 78 | "Y": 0, 79 | "Width": 1, 80 | "Height": 1, 81 | "Type": "Wall", 82 | "PlayerNumber": 0 83 | }, 84 | { 85 | "Id": 7, 86 | "Alive": true, 87 | "X": 6, 88 | "Y": 0, 89 | "Width": 1, 90 | "Height": 1, 91 | "Type": "Wall", 92 | "PlayerNumber": 0 93 | }, 94 | { 95 | "Id": 8, 96 | "Alive": true, 97 | "X": 7, 98 | "Y": 0, 99 | "Width": 1, 100 | "Height": 1, 101 | "Type": "Wall", 102 | "PlayerNumber": 0 103 | }, 104 | { 105 | "Id": 9, 106 | "Alive": true, 107 | "X": 8, 108 | "Y": 0, 109 | "Width": 1, 110 | "Height": 1, 111 | "Type": "Wall", 112 | "PlayerNumber": 0 113 | }, 114 | { 115 | "Id": 10, 116 | "Alive": true, 117 | "X": 9, 118 | "Y": 0, 119 | "Width": 1, 120 | "Height": 1, 121 | "Type": "Wall", 122 | "PlayerNumber": 0 123 | }, 124 | { 125 | "Id": 11, 126 | "Alive": true, 127 | "X": 10, 128 | "Y": 0, 129 | "Width": 1, 130 | "Height": 1, 131 | "Type": "Wall", 132 | "PlayerNumber": 0 133 | }, 134 | { 135 | "Id": 12, 136 | "Alive": true, 137 | "X": 11, 138 | "Y": 0, 139 | "Width": 1, 140 | "Height": 1, 141 | "Type": "Wall", 142 | "PlayerNumber": 0 143 | }, 144 | { 145 | "Id": 13, 146 | "Alive": true, 147 | "X": 12, 148 | "Y": 0, 149 | "Width": 1, 150 | "Height": 1, 151 | "Type": "Wall", 152 | "PlayerNumber": 0 153 | }, 154 | { 155 | "Id": 14, 156 | "Alive": true, 157 | "X": 13, 158 | "Y": 0, 159 | "Width": 1, 160 | "Height": 1, 161 | "Type": "Wall", 162 | "PlayerNumber": 0 163 | }, 164 | { 165 | "Id": 15, 166 | "Alive": true, 167 | "X": 14, 168 | "Y": 0, 169 | "Width": 1, 170 | "Height": 1, 171 | "Type": "Wall", 172 | "PlayerNumber": 0 173 | }, 174 | { 175 | "Id": 16, 176 | "Alive": true, 177 | "X": 15, 178 | "Y": 0, 179 | "Width": 1, 180 | "Height": 1, 181 | "Type": "Wall", 182 | "PlayerNumber": 0 183 | }, 184 | { 185 | "Id": 17, 186 | "Alive": true, 187 | "X": 16, 188 | "Y": 0, 189 | "Width": 1, 190 | "Height": 1, 191 | "Type": "Wall", 192 | "PlayerNumber": 0 193 | }, 194 | { 195 | "Id": 18, 196 | "Alive": true, 197 | "X": 17, 198 | "Y": 0, 199 | "Width": 1, 200 | "Height": 1, 201 | "Type": "Wall", 202 | "PlayerNumber": 0 203 | }, 204 | { 205 | "Id": 19, 206 | "Alive": true, 207 | "X": 18, 208 | "Y": 0, 209 | "Width": 1, 210 | "Height": 1, 211 | "Type": "Wall", 212 | "PlayerNumber": 0 213 | } 214 | ], 215 | [ 216 | { 217 | "Id": 20, 218 | "Alive": true, 219 | "X": 0, 220 | "Y": 1, 221 | "Width": 1, 222 | "Height": 1, 223 | "Type": "Wall", 224 | "PlayerNumber": 0 225 | }, 226 | null, 227 | null, 228 | null, 229 | null, 230 | null, 231 | { 232 | "Id": 169, 233 | "Alive": true, 234 | "X": 6, 235 | "Y": 1, 236 | "Width": 1, 237 | "Height": 1, 238 | "Type": "Bullet", 239 | "PlayerNumber": 1 240 | }, 241 | null, 242 | { 243 | "LivesCost": 1, 244 | "Id": 140, 245 | "Alive": true, 246 | "X": 8, 247 | "Y": 1, 248 | "Width": 3, 249 | "Height": 1, 250 | "Type": "MissileController", 251 | "PlayerNumber": 2 252 | }, 253 | { 254 | "LivesCost": 1, 255 | "Id": 140, 256 | "Alive": true, 257 | "X": 8, 258 | "Y": 1, 259 | "Width": 3, 260 | "Height": 1, 261 | "Type": "MissileController", 262 | "PlayerNumber": 2 263 | }, 264 | { 265 | "LivesCost": 1, 266 | "Id": 140, 267 | "Alive": true, 268 | "X": 8, 269 | "Y": 1, 270 | "Width": 3, 271 | "Height": 1, 272 | "Type": "MissileController", 273 | "PlayerNumber": 2 274 | }, 275 | null, 276 | null, 277 | null, 278 | null, 279 | null, 280 | null, 281 | null, 282 | { 283 | "Id": 21, 284 | "Alive": true, 285 | "X": 18, 286 | "Y": 1, 287 | "Width": 1, 288 | "Height": 1, 289 | "Type": "Wall", 290 | "PlayerNumber": 0 291 | } 292 | ], 293 | [ 294 | { 295 | "Id": 22, 296 | "Alive": true, 297 | "X": 0, 298 | "Y": 2, 299 | "Width": 1, 300 | "Height": 1, 301 | "Type": "Wall", 302 | "PlayerNumber": 0 303 | }, 304 | null, 305 | null, 306 | null, 307 | null, 308 | null, 309 | null, 310 | { 311 | "Command": "Nothing", 312 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 313 | "Id": 86, 314 | "Alive": true, 315 | "X": 7, 316 | "Y": 2, 317 | "Width": 3, 318 | "Height": 1, 319 | "Type": "Ship", 320 | "PlayerNumber": 2 321 | }, 322 | { 323 | "Command": "Nothing", 324 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 325 | "Id": 86, 326 | "Alive": true, 327 | "X": 7, 328 | "Y": 2, 329 | "Width": 3, 330 | "Height": 1, 331 | "Type": "Ship", 332 | "PlayerNumber": 2 333 | }, 334 | { 335 | "Command": "Nothing", 336 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 337 | "Id": 86, 338 | "Alive": true, 339 | "X": 7, 340 | "Y": 2, 341 | "Width": 3, 342 | "Height": 1, 343 | "Type": "Ship", 344 | "PlayerNumber": 2 345 | }, 346 | null, 347 | null, 348 | null, 349 | null, 350 | null, 351 | null, 352 | null, 353 | null, 354 | { 355 | "Id": 23, 356 | "Alive": true, 357 | "X": 18, 358 | "Y": 2, 359 | "Width": 1, 360 | "Height": 1, 361 | "Type": "Wall", 362 | "PlayerNumber": 0 363 | } 364 | ], 365 | [ 366 | { 367 | "Id": 24, 368 | "Alive": true, 369 | "X": 0, 370 | "Y": 3, 371 | "Width": 1, 372 | "Height": 1, 373 | "Type": "Wall", 374 | "PlayerNumber": 0 375 | }, 376 | null, 377 | { 378 | "Id": 105, 379 | "Alive": true, 380 | "X": 2, 381 | "Y": 3, 382 | "Width": 1, 383 | "Height": 1, 384 | "Type": "Shield", 385 | "PlayerNumber": 2 386 | }, 387 | { 388 | "Id": 108, 389 | "Alive": true, 390 | "X": 3, 391 | "Y": 3, 392 | "Width": 1, 393 | "Height": 1, 394 | "Type": "Shield", 395 | "PlayerNumber": 2 396 | }, 397 | { 398 | "Id": 111, 399 | "Alive": true, 400 | "X": 4, 401 | "Y": 3, 402 | "Width": 1, 403 | "Height": 1, 404 | "Type": "Shield", 405 | "PlayerNumber": 2 406 | }, 407 | null, 408 | null, 409 | null, 410 | null, 411 | { 412 | "Id": 134, 413 | "Alive": true, 414 | "X": 9, 415 | "Y": 3, 416 | "Width": 1, 417 | "Height": 1, 418 | "Type": "Shield", 419 | "PlayerNumber": 2 420 | }, 421 | null, 422 | null, 423 | null, 424 | null, 425 | { 426 | "Id": 114, 427 | "Alive": true, 428 | "X": 14, 429 | "Y": 3, 430 | "Width": 1, 431 | "Height": 1, 432 | "Type": "Shield", 433 | "PlayerNumber": 2 434 | }, 435 | { 436 | "Id": 117, 437 | "Alive": true, 438 | "X": 15, 439 | "Y": 3, 440 | "Width": 1, 441 | "Height": 1, 442 | "Type": "Shield", 443 | "PlayerNumber": 2 444 | }, 445 | { 446 | "Id": 120, 447 | "Alive": true, 448 | "X": 16, 449 | "Y": 3, 450 | "Width": 1, 451 | "Height": 1, 452 | "Type": "Shield", 453 | "PlayerNumber": 2 454 | }, 455 | null, 456 | { 457 | "Id": 25, 458 | "Alive": true, 459 | "X": 18, 460 | "Y": 3, 461 | "Width": 1, 462 | "Height": 1, 463 | "Type": "Wall", 464 | "PlayerNumber": 0 465 | } 466 | ], 467 | [ 468 | { 469 | "Id": 26, 470 | "Alive": true, 471 | "X": 0, 472 | "Y": 4, 473 | "Width": 1, 474 | "Height": 1, 475 | "Type": "Wall", 476 | "PlayerNumber": 0 477 | }, 478 | null, 479 | { 480 | "Id": 106, 481 | "Alive": true, 482 | "X": 2, 483 | "Y": 4, 484 | "Width": 1, 485 | "Height": 1, 486 | "Type": "Shield", 487 | "PlayerNumber": 2 488 | }, 489 | { 490 | "Id": 109, 491 | "Alive": true, 492 | "X": 3, 493 | "Y": 4, 494 | "Width": 1, 495 | "Height": 1, 496 | "Type": "Shield", 497 | "PlayerNumber": 2 498 | }, 499 | { 500 | "Id": 112, 501 | "Alive": true, 502 | "X": 4, 503 | "Y": 4, 504 | "Width": 1, 505 | "Height": 1, 506 | "Type": "Shield", 507 | "PlayerNumber": 2 508 | }, 509 | null, 510 | null, 511 | null, 512 | { 513 | "Id": 132, 514 | "Alive": true, 515 | "X": 8, 516 | "Y": 4, 517 | "Width": 1, 518 | "Height": 1, 519 | "Type": "Shield", 520 | "PlayerNumber": 2 521 | }, 522 | { 523 | "Id": 135, 524 | "Alive": true, 525 | "X": 9, 526 | "Y": 4, 527 | "Width": 1, 528 | "Height": 1, 529 | "Type": "Shield", 530 | "PlayerNumber": 2 531 | }, 532 | { 533 | "Id": 138, 534 | "Alive": true, 535 | "X": 10, 536 | "Y": 4, 537 | "Width": 1, 538 | "Height": 1, 539 | "Type": "Shield", 540 | "PlayerNumber": 2 541 | }, 542 | null, 543 | null, 544 | null, 545 | { 546 | "Id": 115, 547 | "Alive": true, 548 | "X": 14, 549 | "Y": 4, 550 | "Width": 1, 551 | "Height": 1, 552 | "Type": "Shield", 553 | "PlayerNumber": 2 554 | }, 555 | { 556 | "Id": 118, 557 | "Alive": true, 558 | "X": 15, 559 | "Y": 4, 560 | "Width": 1, 561 | "Height": 1, 562 | "Type": "Shield", 563 | "PlayerNumber": 2 564 | }, 565 | { 566 | "Id": 121, 567 | "Alive": true, 568 | "X": 16, 569 | "Y": 4, 570 | "Width": 1, 571 | "Height": 1, 572 | "Type": "Shield", 573 | "PlayerNumber": 2 574 | }, 575 | null, 576 | { 577 | "Id": 27, 578 | "Alive": true, 579 | "X": 18, 580 | "Y": 4, 581 | "Width": 1, 582 | "Height": 1, 583 | "Type": "Wall", 584 | "PlayerNumber": 0 585 | } 586 | ], 587 | [ 588 | { 589 | "Id": 28, 590 | "Alive": true, 591 | "X": 0, 592 | "Y": 5, 593 | "Width": 1, 594 | "Height": 1, 595 | "Type": "Wall", 596 | "PlayerNumber": 0 597 | }, 598 | null, 599 | { 600 | "Id": 107, 601 | "Alive": true, 602 | "X": 2, 603 | "Y": 5, 604 | "Width": 1, 605 | "Height": 1, 606 | "Type": "Shield", 607 | "PlayerNumber": 2 608 | }, 609 | { 610 | "Id": 110, 611 | "Alive": true, 612 | "X": 3, 613 | "Y": 5, 614 | "Width": 1, 615 | "Height": 1, 616 | "Type": "Shield", 617 | "PlayerNumber": 2 618 | }, 619 | null, 620 | null, 621 | null, 622 | null, 623 | null, 624 | { 625 | "Id": 136, 626 | "Alive": true, 627 | "X": 9, 628 | "Y": 5, 629 | "Width": 1, 630 | "Height": 1, 631 | "Type": "Shield", 632 | "PlayerNumber": 2 633 | }, 634 | { 635 | "Id": 139, 636 | "Alive": true, 637 | "X": 10, 638 | "Y": 5, 639 | "Width": 1, 640 | "Height": 1, 641 | "Type": "Shield", 642 | "PlayerNumber": 2 643 | }, 644 | null, 645 | null, 646 | null, 647 | { 648 | "Id": 116, 649 | "Alive": true, 650 | "X": 14, 651 | "Y": 5, 652 | "Width": 1, 653 | "Height": 1, 654 | "Type": "Shield", 655 | "PlayerNumber": 2 656 | }, 657 | { 658 | "Id": 119, 659 | "Alive": true, 660 | "X": 15, 661 | "Y": 5, 662 | "Width": 1, 663 | "Height": 1, 664 | "Type": "Shield", 665 | "PlayerNumber": 2 666 | }, 667 | { 668 | "Id": 122, 669 | "Alive": true, 670 | "X": 16, 671 | "Y": 5, 672 | "Width": 1, 673 | "Height": 1, 674 | "Type": "Shield", 675 | "PlayerNumber": 2 676 | }, 677 | null, 678 | { 679 | "Id": 29, 680 | "Alive": true, 681 | "X": 18, 682 | "Y": 5, 683 | "Width": 1, 684 | "Height": 1, 685 | "Type": "Wall", 686 | "PlayerNumber": 0 687 | } 688 | ], 689 | [ 690 | { 691 | "Id": 30, 692 | "Alive": true, 693 | "X": 0, 694 | "Y": 6, 695 | "Width": 1, 696 | "Height": 1, 697 | "Type": "Wall", 698 | "PlayerNumber": 0 699 | }, 700 | null, 701 | null, 702 | null, 703 | null, 704 | null, 705 | null, 706 | null, 707 | null, 708 | null, 709 | null, 710 | null, 711 | null, 712 | null, 713 | null, 714 | null, 715 | null, 716 | null, 717 | { 718 | "Id": 31, 719 | "Alive": true, 720 | "X": 18, 721 | "Y": 6, 722 | "Width": 1, 723 | "Height": 1, 724 | "Type": "Wall", 725 | "PlayerNumber": 0 726 | } 727 | ], 728 | [ 729 | { 730 | "Id": 32, 731 | "Alive": true, 732 | "X": 0, 733 | "Y": 7, 734 | "Width": 1, 735 | "Height": 1, 736 | "Type": "Wall", 737 | "PlayerNumber": 0 738 | }, 739 | null, 740 | null, 741 | null, 742 | null, 743 | null, 744 | null, 745 | null, 746 | null, 747 | null, 748 | null, 749 | null, 750 | null, 751 | null, 752 | null, 753 | null, 754 | null, 755 | null, 756 | { 757 | "Id": 33, 758 | "Alive": true, 759 | "X": 18, 760 | "Y": 7, 761 | "Width": 1, 762 | "Height": 1, 763 | "Type": "Wall", 764 | "PlayerNumber": 0 765 | } 766 | ], 767 | [ 768 | { 769 | "Id": 34, 770 | "Alive": true, 771 | "X": 0, 772 | "Y": 8, 773 | "Width": 1, 774 | "Height": 1, 775 | "Type": "Wall", 776 | "PlayerNumber": 0 777 | }, 778 | null, 779 | null, 780 | null, 781 | null, 782 | null, 783 | null, 784 | null, 785 | null, 786 | null, 787 | { 788 | "Id": 124, 789 | "Alive": true, 790 | "X": 10, 791 | "Y": 8, 792 | "Width": 1, 793 | "Height": 1, 794 | "Type": "Alien", 795 | "PlayerNumber": 1 796 | }, 797 | null, 798 | null, 799 | { 800 | "Id": 123, 801 | "Alive": true, 802 | "X": 13, 803 | "Y": 8, 804 | "Width": 1, 805 | "Height": 1, 806 | "Type": "Alien", 807 | "PlayerNumber": 1 808 | }, 809 | null, 810 | null, 811 | null, 812 | null, 813 | { 814 | "Id": 35, 815 | "Alive": true, 816 | "X": 18, 817 | "Y": 8, 818 | "Width": 1, 819 | "Height": 1, 820 | "Type": "Wall", 821 | "PlayerNumber": 0 822 | } 823 | ], 824 | [ 825 | { 826 | "Id": 36, 827 | "Alive": true, 828 | "X": 0, 829 | "Y": 9, 830 | "Width": 1, 831 | "Height": 1, 832 | "Type": "Wall", 833 | "PlayerNumber": 0 834 | }, 835 | null, 836 | null, 837 | null, 838 | null, 839 | null, 840 | null, 841 | { 842 | "Id": 176, 843 | "Alive": true, 844 | "X": 7, 845 | "Y": 9, 846 | "Width": 1, 847 | "Height": 1, 848 | "Type": "Missile", 849 | "PlayerNumber": 2 850 | }, 851 | null, 852 | null, 853 | null, 854 | null, 855 | null, 856 | null, 857 | null, 858 | null, 859 | null, 860 | null, 861 | { 862 | "Id": 37, 863 | "Alive": true, 864 | "X": 18, 865 | "Y": 9, 866 | "Width": 1, 867 | "Height": 1, 868 | "Type": "Wall", 869 | "PlayerNumber": 0 870 | } 871 | ], 872 | [ 873 | { 874 | "Id": 38, 875 | "Alive": true, 876 | "X": 0, 877 | "Y": 10, 878 | "Width": 1, 879 | "Height": 1, 880 | "Type": "Wall", 881 | "PlayerNumber": 0 882 | }, 883 | null, 884 | null, 885 | null, 886 | { 887 | "Id": 168, 888 | "Alive": true, 889 | "X": 4, 890 | "Y": 10, 891 | "Width": 1, 892 | "Height": 1, 893 | "Type": "Alien", 894 | "PlayerNumber": 1 895 | }, 896 | null, 897 | null, 898 | { 899 | "Id": 167, 900 | "Alive": true, 901 | "X": 7, 902 | "Y": 10, 903 | "Width": 1, 904 | "Height": 1, 905 | "Type": "Alien", 906 | "PlayerNumber": 1 907 | }, 908 | null, 909 | null, 910 | { 911 | "Id": 166, 912 | "Alive": true, 913 | "X": 10, 914 | "Y": 10, 915 | "Width": 1, 916 | "Height": 1, 917 | "Type": "Alien", 918 | "PlayerNumber": 1 919 | }, 920 | null, 921 | null, 922 | { 923 | "Id": 165, 924 | "Alive": true, 925 | "X": 13, 926 | "Y": 10, 927 | "Width": 1, 928 | "Height": 1, 929 | "Type": "Alien", 930 | "PlayerNumber": 1 931 | }, 932 | null, 933 | null, 934 | null, 935 | null, 936 | { 937 | "Id": 39, 938 | "Alive": true, 939 | "X": 18, 940 | "Y": 10, 941 | "Width": 1, 942 | "Height": 1, 943 | "Type": "Wall", 944 | "PlayerNumber": 0 945 | } 946 | ], 947 | [ 948 | { 949 | "Id": 40, 950 | "Alive": true, 951 | "X": 0, 952 | "Y": 11, 953 | "Width": 1, 954 | "Height": 1, 955 | "Type": "Wall", 956 | "PlayerNumber": 0 957 | }, 958 | null, 959 | null, 960 | null, 961 | null, 962 | null, 963 | null, 964 | null, 965 | null, 966 | null, 967 | null, 968 | null, 969 | null, 970 | null, 971 | null, 972 | null, 973 | null, 974 | null, 975 | { 976 | "Id": 41, 977 | "Alive": true, 978 | "X": 18, 979 | "Y": 11, 980 | "Width": 1, 981 | "Height": 1, 982 | "Type": "Wall", 983 | "PlayerNumber": 0 984 | } 985 | ], 986 | [ 987 | { 988 | "Id": 42, 989 | "Alive": true, 990 | "X": 0, 991 | "Y": 12, 992 | "Width": 1, 993 | "Height": 1, 994 | "Type": "Wall", 995 | "PlayerNumber": 0 996 | }, 997 | null, 998 | null, 999 | null, 1000 | null, 1001 | null, 1002 | null, 1003 | null, 1004 | null, 1005 | null, 1006 | null, 1007 | null, 1008 | null, 1009 | null, 1010 | null, 1011 | null, 1012 | null, 1013 | null, 1014 | { 1015 | "Id": 43, 1016 | "Alive": true, 1017 | "X": 18, 1018 | "Y": 12, 1019 | "Width": 1, 1020 | "Height": 1, 1021 | "Type": "Wall", 1022 | "PlayerNumber": 0 1023 | } 1024 | ], 1025 | [ 1026 | { 1027 | "Id": 44, 1028 | "Alive": true, 1029 | "X": 0, 1030 | "Y": 13, 1031 | "Width": 1, 1032 | "Height": 1, 1033 | "Type": "Wall", 1034 | "PlayerNumber": 0 1035 | }, 1036 | null, 1037 | null, 1038 | { 1039 | "Id": 174, 1040 | "Alive": true, 1041 | "X": 3, 1042 | "Y": 13, 1043 | "Width": 1, 1044 | "Height": 1, 1045 | "Type": "Alien", 1046 | "PlayerNumber": 2 1047 | }, 1048 | null, 1049 | null, 1050 | { 1051 | "Id": 173, 1052 | "Alive": true, 1053 | "X": 6, 1054 | "Y": 13, 1055 | "Width": 1, 1056 | "Height": 1, 1057 | "Type": "Alien", 1058 | "PlayerNumber": 2 1059 | }, 1060 | null, 1061 | null, 1062 | { 1063 | "Id": 172, 1064 | "Alive": true, 1065 | "X": 9, 1066 | "Y": 13, 1067 | "Width": 1, 1068 | "Height": 1, 1069 | "Type": "Alien", 1070 | "PlayerNumber": 2 1071 | }, 1072 | null, 1073 | null, 1074 | null, 1075 | null, 1076 | null, 1077 | null, 1078 | null, 1079 | null, 1080 | { 1081 | "Id": 45, 1082 | "Alive": true, 1083 | "X": 18, 1084 | "Y": 13, 1085 | "Width": 1, 1086 | "Height": 1, 1087 | "Type": "Wall", 1088 | "PlayerNumber": 0 1089 | } 1090 | ], 1091 | [ 1092 | { 1093 | "Id": 46, 1094 | "Alive": true, 1095 | "X": 0, 1096 | "Y": 14, 1097 | "Width": 1, 1098 | "Height": 1, 1099 | "Type": "Wall", 1100 | "PlayerNumber": 0 1101 | }, 1102 | null, 1103 | null, 1104 | null, 1105 | null, 1106 | null, 1107 | null, 1108 | null, 1109 | null, 1110 | null, 1111 | null, 1112 | null, 1113 | null, 1114 | null, 1115 | null, 1116 | null, 1117 | null, 1118 | null, 1119 | { 1120 | "Id": 47, 1121 | "Alive": true, 1122 | "X": 18, 1123 | "Y": 14, 1124 | "Width": 1, 1125 | "Height": 1, 1126 | "Type": "Wall", 1127 | "PlayerNumber": 0 1128 | } 1129 | ], 1130 | [ 1131 | { 1132 | "Id": 48, 1133 | "Alive": true, 1134 | "X": 0, 1135 | "Y": 15, 1136 | "Width": 1, 1137 | "Height": 1, 1138 | "Type": "Wall", 1139 | "PlayerNumber": 0 1140 | }, 1141 | null, 1142 | null, 1143 | null, 1144 | null, 1145 | null, 1146 | { 1147 | "Id": 128, 1148 | "Alive": true, 1149 | "X": 6, 1150 | "Y": 15, 1151 | "Width": 1, 1152 | "Height": 1, 1153 | "Type": "Alien", 1154 | "PlayerNumber": 2 1155 | }, 1156 | null, 1157 | null, 1158 | { 1159 | "Id": 127, 1160 | "Alive": true, 1161 | "X": 9, 1162 | "Y": 15, 1163 | "Width": 1, 1164 | "Height": 1, 1165 | "Type": "Alien", 1166 | "PlayerNumber": 2 1167 | }, 1168 | null, 1169 | null, 1170 | null, 1171 | null, 1172 | null, 1173 | null, 1174 | null, 1175 | null, 1176 | { 1177 | "Id": 49, 1178 | "Alive": true, 1179 | "X": 18, 1180 | "Y": 15, 1181 | "Width": 1, 1182 | "Height": 1, 1183 | "Type": "Wall", 1184 | "PlayerNumber": 0 1185 | } 1186 | ], 1187 | [ 1188 | { 1189 | "Id": 50, 1190 | "Alive": true, 1191 | "X": 0, 1192 | "Y": 16, 1193 | "Width": 1, 1194 | "Height": 1, 1195 | "Type": "Wall", 1196 | "PlayerNumber": 0 1197 | }, 1198 | null, 1199 | null, 1200 | null, 1201 | null, 1202 | null, 1203 | null, 1204 | null, 1205 | null, 1206 | null, 1207 | null, 1208 | { 1209 | "Id": 177, 1210 | "Alive": true, 1211 | "X": 11, 1212 | "Y": 16, 1213 | "Width": 1, 1214 | "Height": 1, 1215 | "Type": "Missile", 1216 | "PlayerNumber": 1 1217 | }, 1218 | null, 1219 | null, 1220 | null, 1221 | null, 1222 | null, 1223 | null, 1224 | { 1225 | "Id": 51, 1226 | "Alive": true, 1227 | "X": 18, 1228 | "Y": 16, 1229 | "Width": 1, 1230 | "Height": 1, 1231 | "Type": "Wall", 1232 | "PlayerNumber": 0 1233 | } 1234 | ], 1235 | [ 1236 | { 1237 | "Id": 52, 1238 | "Alive": true, 1239 | "X": 0, 1240 | "Y": 17, 1241 | "Width": 1, 1242 | "Height": 1, 1243 | "Type": "Wall", 1244 | "PlayerNumber": 0 1245 | }, 1246 | null, 1247 | null, 1248 | null, 1249 | null, 1250 | null, 1251 | null, 1252 | null, 1253 | null, 1254 | null, 1255 | null, 1256 | null, 1257 | null, 1258 | null, 1259 | null, 1260 | null, 1261 | null, 1262 | null, 1263 | { 1264 | "Id": 53, 1265 | "Alive": true, 1266 | "X": 18, 1267 | "Y": 17, 1268 | "Width": 1, 1269 | "Height": 1, 1270 | "Type": "Wall", 1271 | "PlayerNumber": 0 1272 | } 1273 | ], 1274 | [ 1275 | { 1276 | "Id": 54, 1277 | "Alive": true, 1278 | "X": 0, 1279 | "Y": 18, 1280 | "Width": 1, 1281 | "Height": 1, 1282 | "Type": "Wall", 1283 | "PlayerNumber": 0 1284 | }, 1285 | null, 1286 | null, 1287 | null, 1288 | null, 1289 | null, 1290 | null, 1291 | null, 1292 | null, 1293 | null, 1294 | null, 1295 | null, 1296 | null, 1297 | null, 1298 | null, 1299 | null, 1300 | null, 1301 | null, 1302 | { 1303 | "Id": 55, 1304 | "Alive": true, 1305 | "X": 18, 1306 | "Y": 18, 1307 | "Width": 1, 1308 | "Height": 1, 1309 | "Type": "Wall", 1310 | "PlayerNumber": 0 1311 | } 1312 | ], 1313 | [ 1314 | { 1315 | "Id": 56, 1316 | "Alive": true, 1317 | "X": 0, 1318 | "Y": 19, 1319 | "Width": 1, 1320 | "Height": 1, 1321 | "Type": "Wall", 1322 | "PlayerNumber": 0 1323 | }, 1324 | null, 1325 | null, 1326 | { 1327 | "Id": 92, 1328 | "Alive": true, 1329 | "X": 3, 1330 | "Y": 19, 1331 | "Width": 1, 1332 | "Height": 1, 1333 | "Type": "Shield", 1334 | "PlayerNumber": 1 1335 | }, 1336 | { 1337 | "Id": 95, 1338 | "Alive": true, 1339 | "X": 4, 1340 | "Y": 19, 1341 | "Width": 1, 1342 | "Height": 1, 1343 | "Type": "Shield", 1344 | "PlayerNumber": 1 1345 | }, 1346 | null, 1347 | null, 1348 | { 1349 | "Id": 145, 1350 | "Alive": true, 1351 | "X": 7, 1352 | "Y": 19, 1353 | "Width": 1, 1354 | "Height": 1, 1355 | "Type": "Shield", 1356 | "PlayerNumber": 1 1357 | }, 1358 | null, 1359 | null, 1360 | { 1361 | "Id": 156, 1362 | "Alive": true, 1363 | "X": 10, 1364 | "Y": 19, 1365 | "Width": 1, 1366 | "Height": 1, 1367 | "Type": "Shield", 1368 | "PlayerNumber": 1 1369 | }, 1370 | null, 1371 | null, 1372 | null, 1373 | { 1374 | "Id": 98, 1375 | "Alive": true, 1376 | "X": 14, 1377 | "Y": 19, 1378 | "Width": 1, 1379 | "Height": 1, 1380 | "Type": "Shield", 1381 | "PlayerNumber": 1 1382 | }, 1383 | { 1384 | "Id": 101, 1385 | "Alive": true, 1386 | "X": 15, 1387 | "Y": 19, 1388 | "Width": 1, 1389 | "Height": 1, 1390 | "Type": "Shield", 1391 | "PlayerNumber": 1 1392 | }, 1393 | { 1394 | "Id": 104, 1395 | "Alive": true, 1396 | "X": 16, 1397 | "Y": 19, 1398 | "Width": 1, 1399 | "Height": 1, 1400 | "Type": "Shield", 1401 | "PlayerNumber": 1 1402 | }, 1403 | null, 1404 | { 1405 | "Id": 57, 1406 | "Alive": true, 1407 | "X": 18, 1408 | "Y": 19, 1409 | "Width": 1, 1410 | "Height": 1, 1411 | "Type": "Wall", 1412 | "PlayerNumber": 0 1413 | } 1414 | ], 1415 | [ 1416 | { 1417 | "Id": 58, 1418 | "Alive": true, 1419 | "X": 0, 1420 | "Y": 20, 1421 | "Width": 1, 1422 | "Height": 1, 1423 | "Type": "Wall", 1424 | "PlayerNumber": 0 1425 | }, 1426 | null, 1427 | { 1428 | "Id": 88, 1429 | "Alive": true, 1430 | "X": 2, 1431 | "Y": 20, 1432 | "Width": 1, 1433 | "Height": 1, 1434 | "Type": "Shield", 1435 | "PlayerNumber": 1 1436 | }, 1437 | { 1438 | "Id": 91, 1439 | "Alive": true, 1440 | "X": 3, 1441 | "Y": 20, 1442 | "Width": 1, 1443 | "Height": 1, 1444 | "Type": "Shield", 1445 | "PlayerNumber": 1 1446 | }, 1447 | { 1448 | "Id": 94, 1449 | "Alive": true, 1450 | "X": 4, 1451 | "Y": 20, 1452 | "Width": 1, 1453 | "Height": 1, 1454 | "Type": "Shield", 1455 | "PlayerNumber": 1 1456 | }, 1457 | null, 1458 | null, 1459 | { 1460 | "Id": 144, 1461 | "Alive": true, 1462 | "X": 7, 1463 | "Y": 20, 1464 | "Width": 1, 1465 | "Height": 1, 1466 | "Type": "Shield", 1467 | "PlayerNumber": 1 1468 | }, 1469 | null, 1470 | { 1471 | "Id": 150, 1472 | "Alive": true, 1473 | "X": 9, 1474 | "Y": 20, 1475 | "Width": 1, 1476 | "Height": 1, 1477 | "Type": "Shield", 1478 | "PlayerNumber": 1 1479 | }, 1480 | { 1481 | "Id": 155, 1482 | "Alive": true, 1483 | "X": 10, 1484 | "Y": 20, 1485 | "Width": 1, 1486 | "Height": 1, 1487 | "Type": "Shield", 1488 | "PlayerNumber": 1 1489 | }, 1490 | null, 1491 | null, 1492 | null, 1493 | { 1494 | "Id": 97, 1495 | "Alive": true, 1496 | "X": 14, 1497 | "Y": 20, 1498 | "Width": 1, 1499 | "Height": 1, 1500 | "Type": "Shield", 1501 | "PlayerNumber": 1 1502 | }, 1503 | { 1504 | "Id": 100, 1505 | "Alive": true, 1506 | "X": 15, 1507 | "Y": 20, 1508 | "Width": 1, 1509 | "Height": 1, 1510 | "Type": "Shield", 1511 | "PlayerNumber": 1 1512 | }, 1513 | { 1514 | "Id": 103, 1515 | "Alive": true, 1516 | "X": 16, 1517 | "Y": 20, 1518 | "Width": 1, 1519 | "Height": 1, 1520 | "Type": "Shield", 1521 | "PlayerNumber": 1 1522 | }, 1523 | null, 1524 | { 1525 | "Id": 59, 1526 | "Alive": true, 1527 | "X": 18, 1528 | "Y": 20, 1529 | "Width": 1, 1530 | "Height": 1, 1531 | "Type": "Wall", 1532 | "PlayerNumber": 0 1533 | } 1534 | ], 1535 | [ 1536 | { 1537 | "Id": 60, 1538 | "Alive": true, 1539 | "X": 0, 1540 | "Y": 21, 1541 | "Width": 1, 1542 | "Height": 1, 1543 | "Type": "Wall", 1544 | "PlayerNumber": 0 1545 | }, 1546 | null, 1547 | { 1548 | "Id": 87, 1549 | "Alive": true, 1550 | "X": 2, 1551 | "Y": 21, 1552 | "Width": 1, 1553 | "Height": 1, 1554 | "Type": "Shield", 1555 | "PlayerNumber": 1 1556 | }, 1557 | { 1558 | "Id": 90, 1559 | "Alive": true, 1560 | "X": 3, 1561 | "Y": 21, 1562 | "Width": 1, 1563 | "Height": 1, 1564 | "Type": "Shield", 1565 | "PlayerNumber": 1 1566 | }, 1567 | { 1568 | "Id": 93, 1569 | "Alive": true, 1570 | "X": 4, 1571 | "Y": 21, 1572 | "Width": 1, 1573 | "Height": 1, 1574 | "Type": "Shield", 1575 | "PlayerNumber": 1 1576 | }, 1577 | null, 1578 | null, 1579 | { 1580 | "Id": 143, 1581 | "Alive": true, 1582 | "X": 7, 1583 | "Y": 21, 1584 | "Width": 1, 1585 | "Height": 1, 1586 | "Type": "Shield", 1587 | "PlayerNumber": 1 1588 | }, 1589 | { 1590 | "Id": 146, 1591 | "Alive": true, 1592 | "X": 8, 1593 | "Y": 21, 1594 | "Width": 1, 1595 | "Height": 1, 1596 | "Type": "Shield", 1597 | "PlayerNumber": 1 1598 | }, 1599 | null, 1600 | null, 1601 | null, 1602 | null, 1603 | null, 1604 | { 1605 | "Id": 96, 1606 | "Alive": true, 1607 | "X": 14, 1608 | "Y": 21, 1609 | "Width": 1, 1610 | "Height": 1, 1611 | "Type": "Shield", 1612 | "PlayerNumber": 1 1613 | }, 1614 | { 1615 | "Id": 99, 1616 | "Alive": true, 1617 | "X": 15, 1618 | "Y": 21, 1619 | "Width": 1, 1620 | "Height": 1, 1621 | "Type": "Shield", 1622 | "PlayerNumber": 1 1623 | }, 1624 | { 1625 | "Id": 102, 1626 | "Alive": true, 1627 | "X": 16, 1628 | "Y": 21, 1629 | "Width": 1, 1630 | "Height": 1, 1631 | "Type": "Shield", 1632 | "PlayerNumber": 1 1633 | }, 1634 | null, 1635 | { 1636 | "Id": 61, 1637 | "Alive": true, 1638 | "X": 18, 1639 | "Y": 21, 1640 | "Width": 1, 1641 | "Height": 1, 1642 | "Type": "Wall", 1643 | "PlayerNumber": 0 1644 | } 1645 | ], 1646 | [ 1647 | { 1648 | "Id": 62, 1649 | "Alive": true, 1650 | "X": 0, 1651 | "Y": 22, 1652 | "Width": 1, 1653 | "Height": 1, 1654 | "Type": "Wall", 1655 | "PlayerNumber": 0 1656 | }, 1657 | null, 1658 | null, 1659 | null, 1660 | null, 1661 | null, 1662 | null, 1663 | null, 1664 | null, 1665 | null, 1666 | null, 1667 | { 1668 | "Command": "Nothing", 1669 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 1670 | "Id": 85, 1671 | "Alive": true, 1672 | "X": 11, 1673 | "Y": 22, 1674 | "Width": 3, 1675 | "Height": 1, 1676 | "Type": "Ship", 1677 | "PlayerNumber": 1 1678 | }, 1679 | { 1680 | "Command": "Nothing", 1681 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 1682 | "Id": 85, 1683 | "Alive": true, 1684 | "X": 11, 1685 | "Y": 22, 1686 | "Width": 3, 1687 | "Height": 1, 1688 | "Type": "Ship", 1689 | "PlayerNumber": 1 1690 | }, 1691 | { 1692 | "Command": "Nothing", 1693 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 1694 | "Id": 85, 1695 | "Alive": true, 1696 | "X": 11, 1697 | "Y": 22, 1698 | "Width": 3, 1699 | "Height": 1, 1700 | "Type": "Ship", 1701 | "PlayerNumber": 1 1702 | }, 1703 | null, 1704 | null, 1705 | null, 1706 | null, 1707 | { 1708 | "Id": 63, 1709 | "Alive": true, 1710 | "X": 18, 1711 | "Y": 22, 1712 | "Width": 1, 1713 | "Height": 1, 1714 | "Type": "Wall", 1715 | "PlayerNumber": 0 1716 | } 1717 | ], 1718 | [ 1719 | { 1720 | "Id": 64, 1721 | "Alive": true, 1722 | "X": 0, 1723 | "Y": 23, 1724 | "Width": 1, 1725 | "Height": 1, 1726 | "Type": "Wall", 1727 | "PlayerNumber": 0 1728 | }, 1729 | null, 1730 | null, 1731 | null, 1732 | null, 1733 | null, 1734 | null, 1735 | null, 1736 | { 1737 | "LivesCost": 1, 1738 | "Id": 130, 1739 | "Alive": true, 1740 | "X": 8, 1741 | "Y": 23, 1742 | "Width": 3, 1743 | "Height": 1, 1744 | "Type": "AlienFactory", 1745 | "PlayerNumber": 1 1746 | }, 1747 | { 1748 | "LivesCost": 1, 1749 | "Id": 130, 1750 | "Alive": true, 1751 | "X": 8, 1752 | "Y": 23, 1753 | "Width": 3, 1754 | "Height": 1, 1755 | "Type": "AlienFactory", 1756 | "PlayerNumber": 1 1757 | }, 1758 | { 1759 | "LivesCost": 1, 1760 | "Id": 130, 1761 | "Alive": true, 1762 | "X": 8, 1763 | "Y": 23, 1764 | "Width": 3, 1765 | "Height": 1, 1766 | "Type": "AlienFactory", 1767 | "PlayerNumber": 1 1768 | }, 1769 | null, 1770 | null, 1771 | null, 1772 | null, 1773 | null, 1774 | null, 1775 | null, 1776 | { 1777 | "Id": 65, 1778 | "Alive": true, 1779 | "X": 18, 1780 | "Y": 23, 1781 | "Width": 1, 1782 | "Height": 1, 1783 | "Type": "Wall", 1784 | "PlayerNumber": 0 1785 | } 1786 | ], 1787 | [ 1788 | { 1789 | "Id": 66, 1790 | "Alive": true, 1791 | "X": 0, 1792 | "Y": 24, 1793 | "Width": 1, 1794 | "Height": 1, 1795 | "Type": "Wall", 1796 | "PlayerNumber": 0 1797 | }, 1798 | { 1799 | "Id": 67, 1800 | "Alive": true, 1801 | "X": 1, 1802 | "Y": 24, 1803 | "Width": 1, 1804 | "Height": 1, 1805 | "Type": "Wall", 1806 | "PlayerNumber": 0 1807 | }, 1808 | { 1809 | "Id": 68, 1810 | "Alive": true, 1811 | "X": 2, 1812 | "Y": 24, 1813 | "Width": 1, 1814 | "Height": 1, 1815 | "Type": "Wall", 1816 | "PlayerNumber": 0 1817 | }, 1818 | { 1819 | "Id": 69, 1820 | "Alive": true, 1821 | "X": 3, 1822 | "Y": 24, 1823 | "Width": 1, 1824 | "Height": 1, 1825 | "Type": "Wall", 1826 | "PlayerNumber": 0 1827 | }, 1828 | { 1829 | "Id": 70, 1830 | "Alive": true, 1831 | "X": 4, 1832 | "Y": 24, 1833 | "Width": 1, 1834 | "Height": 1, 1835 | "Type": "Wall", 1836 | "PlayerNumber": 0 1837 | }, 1838 | { 1839 | "Id": 71, 1840 | "Alive": true, 1841 | "X": 5, 1842 | "Y": 24, 1843 | "Width": 1, 1844 | "Height": 1, 1845 | "Type": "Wall", 1846 | "PlayerNumber": 0 1847 | }, 1848 | { 1849 | "Id": 72, 1850 | "Alive": true, 1851 | "X": 6, 1852 | "Y": 24, 1853 | "Width": 1, 1854 | "Height": 1, 1855 | "Type": "Wall", 1856 | "PlayerNumber": 0 1857 | }, 1858 | { 1859 | "Id": 73, 1860 | "Alive": true, 1861 | "X": 7, 1862 | "Y": 24, 1863 | "Width": 1, 1864 | "Height": 1, 1865 | "Type": "Wall", 1866 | "PlayerNumber": 0 1867 | }, 1868 | { 1869 | "Id": 74, 1870 | "Alive": true, 1871 | "X": 8, 1872 | "Y": 24, 1873 | "Width": 1, 1874 | "Height": 1, 1875 | "Type": "Wall", 1876 | "PlayerNumber": 0 1877 | }, 1878 | { 1879 | "Id": 75, 1880 | "Alive": true, 1881 | "X": 9, 1882 | "Y": 24, 1883 | "Width": 1, 1884 | "Height": 1, 1885 | "Type": "Wall", 1886 | "PlayerNumber": 0 1887 | }, 1888 | { 1889 | "Id": 76, 1890 | "Alive": true, 1891 | "X": 10, 1892 | "Y": 24, 1893 | "Width": 1, 1894 | "Height": 1, 1895 | "Type": "Wall", 1896 | "PlayerNumber": 0 1897 | }, 1898 | { 1899 | "Id": 77, 1900 | "Alive": true, 1901 | "X": 11, 1902 | "Y": 24, 1903 | "Width": 1, 1904 | "Height": 1, 1905 | "Type": "Wall", 1906 | "PlayerNumber": 0 1907 | }, 1908 | { 1909 | "Id": 78, 1910 | "Alive": true, 1911 | "X": 12, 1912 | "Y": 24, 1913 | "Width": 1, 1914 | "Height": 1, 1915 | "Type": "Wall", 1916 | "PlayerNumber": 0 1917 | }, 1918 | { 1919 | "Id": 79, 1920 | "Alive": true, 1921 | "X": 13, 1922 | "Y": 24, 1923 | "Width": 1, 1924 | "Height": 1, 1925 | "Type": "Wall", 1926 | "PlayerNumber": 0 1927 | }, 1928 | { 1929 | "Id": 80, 1930 | "Alive": true, 1931 | "X": 14, 1932 | "Y": 24, 1933 | "Width": 1, 1934 | "Height": 1, 1935 | "Type": "Wall", 1936 | "PlayerNumber": 0 1937 | }, 1938 | { 1939 | "Id": 81, 1940 | "Alive": true, 1941 | "X": 15, 1942 | "Y": 24, 1943 | "Width": 1, 1944 | "Height": 1, 1945 | "Type": "Wall", 1946 | "PlayerNumber": 0 1947 | }, 1948 | { 1949 | "Id": 82, 1950 | "Alive": true, 1951 | "X": 16, 1952 | "Y": 24, 1953 | "Width": 1, 1954 | "Height": 1, 1955 | "Type": "Wall", 1956 | "PlayerNumber": 0 1957 | }, 1958 | { 1959 | "Id": 83, 1960 | "Alive": true, 1961 | "X": 17, 1962 | "Y": 24, 1963 | "Width": 1, 1964 | "Height": 1, 1965 | "Type": "Wall", 1966 | "PlayerNumber": 0 1967 | }, 1968 | { 1969 | "Id": 84, 1970 | "Alive": true, 1971 | "X": 18, 1972 | "Y": 24, 1973 | "Width": 1, 1974 | "Height": 1, 1975 | "Type": "Wall", 1976 | "PlayerNumber": 0 1977 | } 1978 | ] 1979 | ] 1980 | }, 1981 | "Players": [ 1982 | { 1983 | "PlayerNumberReal": 1, 1984 | "PlayerNumber": 1, 1985 | "PlayerName": "Node Sample Bot", 1986 | "Ship": { 1987 | "Command": "Nothing", 1988 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 1989 | "Id": 85, 1990 | "Alive": true, 1991 | "X": 11, 1992 | "Y": 22, 1993 | "Width": 3, 1994 | "Height": 1, 1995 | "Type": "Ship", 1996 | "PlayerNumber": 1 1997 | }, 1998 | "Kills": 1, 1999 | "Lives": 0, 2000 | "RespawnTimer": -1, 2001 | "Missiles": [ 2002 | { 2003 | "Id": 177, 2004 | "Alive": true, 2005 | "X": 11, 2006 | "Y": 16, 2007 | "Width": 1, 2008 | "Height": 1, 2009 | "Type": "Missile", 2010 | "PlayerNumber": 1 2011 | } 2012 | ], 2013 | "MissileLimit": 1, 2014 | "AlienWaveSize": 4, 2015 | "AlienFactory": { 2016 | "LivesCost": 1, 2017 | "Id": 130, 2018 | "Alive": true, 2019 | "X": 8, 2020 | "Y": 23, 2021 | "Width": 3, 2022 | "Height": 1, 2023 | "Type": "AlienFactory", 2024 | "PlayerNumber": 1 2025 | }, 2026 | "MissileController": null, 2027 | "AlienManager": { 2028 | "PlayerNumber": 1, 2029 | "Disabled": false, 2030 | "Waves": [ 2031 | [ 2032 | { 2033 | "Id": 123, 2034 | "Alive": true, 2035 | "X": 13, 2036 | "Y": 8, 2037 | "Width": 1, 2038 | "Height": 1, 2039 | "Type": "Alien", 2040 | "PlayerNumber": 1 2041 | }, 2042 | { 2043 | "Id": 124, 2044 | "Alive": true, 2045 | "X": 10, 2046 | "Y": 8, 2047 | "Width": 1, 2048 | "Height": 1, 2049 | "Type": "Alien", 2050 | "PlayerNumber": 1 2051 | }, 2052 | { 2053 | "Id": 125, 2054 | "Alive": false, 2055 | "X": 6, 2056 | "Y": 8, 2057 | "Width": 1, 2058 | "Height": 1, 2059 | "Type": "Alien", 2060 | "PlayerNumber": 1 2061 | } 2062 | ], 2063 | [ 2064 | { 2065 | "Id": 165, 2066 | "Alive": true, 2067 | "X": 13, 2068 | "Y": 10, 2069 | "Width": 1, 2070 | "Height": 1, 2071 | "Type": "Alien", 2072 | "PlayerNumber": 1 2073 | }, 2074 | { 2075 | "Id": 166, 2076 | "Alive": true, 2077 | "X": 10, 2078 | "Y": 10, 2079 | "Width": 1, 2080 | "Height": 1, 2081 | "Type": "Alien", 2082 | "PlayerNumber": 1 2083 | }, 2084 | { 2085 | "Id": 167, 2086 | "Alive": true, 2087 | "X": 7, 2088 | "Y": 10, 2089 | "Width": 1, 2090 | "Height": 1, 2091 | "Type": "Alien", 2092 | "PlayerNumber": 1 2093 | }, 2094 | { 2095 | "Id": 168, 2096 | "Alive": true, 2097 | "X": 4, 2098 | "Y": 10, 2099 | "Width": 1, 2100 | "Height": 1, 2101 | "Type": "Alien", 2102 | "PlayerNumber": 1 2103 | } 2104 | ] 2105 | ], 2106 | "ShotEnergyCost": 6, 2107 | "ShotEnergy": 3, 2108 | "DeltaX": 1 2109 | } 2110 | }, 2111 | { 2112 | "PlayerNumberReal": 2, 2113 | "PlayerNumber": 2, 2114 | "PlayerName": "C# Sample Bot", 2115 | "Ship": { 2116 | "Command": "Nothing", 2117 | "CommandFeedback": "Tried to build a building but didn't have enough lives.", 2118 | "Id": 86, 2119 | "Alive": true, 2120 | "X": 7, 2121 | "Y": 2, 2122 | "Width": 3, 2123 | "Height": 1, 2124 | "Type": "Ship", 2125 | "PlayerNumber": 2 2126 | }, 2127 | "Kills": 1, 2128 | "Lives": 0, 2129 | "RespawnTimer": -1, 2130 | "Missiles": [ 2131 | { 2132 | "Id": 176, 2133 | "Alive": true, 2134 | "X": 7, 2135 | "Y": 9, 2136 | "Width": 1, 2137 | "Height": 1, 2138 | "Type": "Missile", 2139 | "PlayerNumber": 2 2140 | } 2141 | ], 2142 | "MissileLimit": 2, 2143 | "AlienWaveSize": 3, 2144 | "AlienFactory": null, 2145 | "MissileController": { 2146 | "LivesCost": 1, 2147 | "Id": 140, 2148 | "Alive": true, 2149 | "X": 8, 2150 | "Y": 1, 2151 | "Width": 3, 2152 | "Height": 1, 2153 | "Type": "MissileController", 2154 | "PlayerNumber": 2 2155 | }, 2156 | "AlienManager": { 2157 | "PlayerNumber": 2, 2158 | "Disabled": false, 2159 | "Waves": [ 2160 | [ 2161 | { 2162 | "Id": 127, 2163 | "Alive": true, 2164 | "X": 9, 2165 | "Y": 15, 2166 | "Width": 1, 2167 | "Height": 1, 2168 | "Type": "Alien", 2169 | "PlayerNumber": 2 2170 | }, 2171 | { 2172 | "Id": 128, 2173 | "Alive": true, 2174 | "X": 6, 2175 | "Y": 15, 2176 | "Width": 1, 2177 | "Height": 1, 2178 | "Type": "Alien", 2179 | "PlayerNumber": 2 2180 | } 2181 | ], 2182 | [ 2183 | { 2184 | "Id": 172, 2185 | "Alive": true, 2186 | "X": 9, 2187 | "Y": 13, 2188 | "Width": 1, 2189 | "Height": 1, 2190 | "Type": "Alien", 2191 | "PlayerNumber": 2 2192 | }, 2193 | { 2194 | "Id": 173, 2195 | "Alive": true, 2196 | "X": 6, 2197 | "Y": 13, 2198 | "Width": 1, 2199 | "Height": 1, 2200 | "Type": "Alien", 2201 | "PlayerNumber": 2 2202 | }, 2203 | { 2204 | "Id": 174, 2205 | "Alive": true, 2206 | "X": 3, 2207 | "Y": 13, 2208 | "Width": 1, 2209 | "Height": 1, 2210 | "Type": "Alien", 2211 | "PlayerNumber": 2 2212 | } 2213 | ] 2214 | ], 2215 | "ShotEnergyCost": 6, 2216 | "ShotEnergy": 3, 2217 | "DeltaX": -1 2218 | } 2219 | } 2220 | ], 2221 | "RoundNumber": 33, 2222 | "RoundLimit": 200 2223 | } 2224 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | za.co.entelect.challenge 5 | BasicBot 6 | jar 7 | 1.0-SNAPSHOT 8 | basic-bot 9 | http://maven.apache.org 10 | 11 | 12 | 13 | junit 14 | junit 15 | 4.11 16 | test 17 | 18 | 19 | 20 | com.jayway.jsonpath 21 | json-path 22 | 2.0.0 23 | 24 | 25 | 26 | com.jayway.jsonpath 27 | json-path-assert 28 | 2.0.0 29 | test 30 | 31 | 32 | 33 | org.slf4j 34 | slf4j-log4j12 35 | 1.7.10 36 | 37 | 38 | 39 | com.fasterxml.jackson.core 40 | jackson-core 41 | 2.2.3 42 | 43 | 44 | 45 | com.fasterxml.jackson.core 46 | jackson-annotations 47 | 2.2.3 48 | 49 | 50 | 51 | com.fasterxml.jackson.core 52 | jackson-databind 53 | 2.2.3 54 | 55 | 56 | 57 | com.google.api-client 58 | google-api-client-gson 59 | 1.18.0-rc 60 | 61 | 62 | 63 | 64 | 65 | 66 | maven-compiler-plugin 67 | 68 | 1.7 69 | 1.7 70 | 71 | 72 | 73 | maven-assembly-plugin 74 | 75 | 76 | 77 | za.co.entelect.challenge.program.Main 78 | 79 | 80 | 81 | jar-with-dependencies 82 | 83 | 84 | 85 | 86 | 87 | 88 | 93 | 94 | ${project.basedir}/src/main/resources 95 | true 96 | 97 | *.properties 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | java -jar target/BasicBot-1.0-SNAPSHOT-jar-with-dependencies.jar %1 -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | java -jar target/BasicBot-1.0-SNAPSHOT-jar-with-dependencies.jar $1 4 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/bot/BasicBot.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.bot; 2 | 3 | import za.co.entelect.challenge.dto.GameState; 4 | import za.co.entelect.challenge.dto.Player; 5 | import za.co.entelect.challenge.dto.Settings; 6 | import za.co.entelect.challenge.dto.enums.ShipCommand; 7 | import za.co.entelect.challenge.dto.reader.BasicGameStateReader; 8 | import za.co.entelect.challenge.dto.reader.GameStateReader; 9 | import za.co.entelect.challenge.dto.reader.GsonGameStateReader; 10 | import za.co.entelect.challenge.dto.reader.JacksonGameStateReader; 11 | import za.co.entelect.challenge.utils.BotHelper; 12 | import za.co.entelect.challenge.utils.FileHelper; 13 | import za.co.entelect.challenge.utils.LogHelper; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.util.List; 18 | import java.util.Random; 19 | 20 | public class BasicBot { 21 | 22 | private Settings settings = null; 23 | 24 | public BasicBot(Settings settings) { 25 | this.settings = settings; 26 | } 27 | 28 | private GameState gameState; 29 | 30 | public void execute() { 31 | 32 | //Choose how you want to access the JSON 33 | GameStateReader reader = 34 | new BasicGameStateReader(); 35 | //new JacksonGameStateReader(); 36 | //new GsonGameStateReader(); 37 | 38 | gameState = loadGameState(reader); 39 | 40 | logMatchState(); 41 | 42 | StringBuilder map = loadMap(); 43 | LogHelper.logPartsOnDifferentLines("Map", map); 44 | 45 | String move = getRandomMove(); 46 | saveMove(move); 47 | } 48 | 49 | private GameState loadGameState(GameStateReader reader) { 50 | GameState gameState = null; 51 | 52 | File jsonFile = FileHelper.getFile(settings.getDefaultOutputFolder(), settings.getStateFile()); 53 | 54 | try { 55 | gameState = reader.read(jsonFile); 56 | } catch (Exception ioe) { 57 | LogHelper.log("Error reading state file: " + settings.getStateFile()); 58 | ioe.printStackTrace(); 59 | return null; 60 | } 61 | 62 | return gameState; 63 | } 64 | 65 | private void logMatchState() { 66 | LogHelper.log(LogHelper.PREFIX + "Game state:"); 67 | LogHelper.log("\tRound: " + gameState.getRoundNumber()); 68 | 69 | for (Player player : getPlayers()) { 70 | logPlayerState(player); 71 | } 72 | } 73 | 74 | public GameState getGameState() { 75 | return gameState; 76 | } 77 | 78 | public List getPlayers() { 79 | return gameState.getPlayers(); 80 | } 81 | 82 | private void logPlayerState(Player player) { 83 | LogHelper.log("\tPlayer " + player.getPlayerNumberReal() + " Kills: " + player.getKills()); 84 | LogHelper.log("\tPlayer " + player.getPlayerNumberReal() + " Lives: " + player.getLives()); 85 | LogHelper.log("\tPlayer " + player.getPlayerNumberReal() + " Missiles: " + player.getMissiles().size() + "/" + player.getMissileLimit()); 86 | } 87 | 88 | private StringBuilder loadMap() { 89 | try { 90 | return FileHelper.readFile(settings.getDefaultOutputFolder(), settings.getMapFile()); 91 | } catch(IOException ioe) { 92 | LogHelper.log("Unable to read map file: " + settings.getMapFile()); 93 | ioe.printStackTrace(); 94 | return new StringBuilder(); 95 | } 96 | } 97 | 98 | private String getRandomMove() { 99 | long seed = System.currentTimeMillis(); 100 | Random random = new Random(seed); 101 | int move = Math.abs(random.nextInt() % ShipCommand.values().length); 102 | String translatedMove = BotHelper.translateMove(move); 103 | return translatedMove; 104 | } 105 | 106 | private void saveMove(String move) { 107 | try { 108 | FileHelper.writeFile(settings.getDefaultOutputFolder(), settings.getOutputFile(), move); 109 | LogHelper.log("Move", move); 110 | } catch (IOException ioe) { 111 | LogHelper.log("Unable to write move file: " + settings.getOutputFile()); 112 | ioe.printStackTrace(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/AlienManager.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | @JsonInclude(JsonInclude.Include.NON_NULL) 14 | @Generated("org.jsonschema2pojo") 15 | @JsonPropertyOrder({ 16 | "PlayerNumber", 17 | "Disabled", 18 | "Waves", 19 | "ShotEnergyCost", 20 | "ShotEnergy", 21 | "DeltaX" 22 | }) 23 | public class AlienManager { 24 | 25 | @JsonProperty("PlayerNumber") 26 | @SerializedName("PlayerNumber") 27 | private Integer playerNumber; 28 | @JsonProperty("Disabled") 29 | @SerializedName("Disabled") 30 | private Boolean disabled; 31 | @JsonProperty("Waves") 32 | @SerializedName("Waves") 33 | private List> waves = new ArrayList>(); 34 | @JsonProperty("ShotEnergyCost") 35 | @SerializedName("ShotEnergyCost") 36 | private Integer shotEnergyCost; 37 | @JsonProperty("ShotEnergy") 38 | @SerializedName("ShotEnergy") 39 | private Integer shotEnergy; 40 | @JsonProperty("DeltaX") 41 | @SerializedName("DeltaX") 42 | private Integer deltaX; 43 | @JsonIgnore 44 | private Map additionalProperties = new HashMap(); 45 | 46 | /** 47 | * 48 | * @return 49 | * The PlayerNumber 50 | */ 51 | @JsonProperty("PlayerNumber") 52 | public Integer getPlayerNumber() { 53 | return playerNumber; 54 | } 55 | 56 | /** 57 | * 58 | * @param PlayerNumber 59 | * The PlayerNumber 60 | */ 61 | @JsonProperty("PlayerNumber") 62 | public void setPlayerNumber(Integer playerNumber) { 63 | this.playerNumber = playerNumber; 64 | } 65 | 66 | /** 67 | * 68 | * @return 69 | * The Disabled 70 | */ 71 | @JsonProperty("Disabled") 72 | public Boolean getDisabled() { 73 | return disabled; 74 | } 75 | 76 | /** 77 | * 78 | * @param Disabled 79 | * The Disabled 80 | */ 81 | @JsonProperty("Disabled") 82 | public void setDisabled(Boolean disabled) { 83 | this.disabled = disabled; 84 | } 85 | 86 | /** 87 | * 88 | * @return 89 | * The Waves 90 | */ 91 | @JsonProperty("Waves") 92 | public List> getWaves() { 93 | return waves; 94 | } 95 | 96 | /** 97 | * 98 | * @param Waves 99 | * The Waves 100 | */ 101 | @JsonProperty("Waves") 102 | public void setWaves(List> waves) { 103 | this.waves = waves; 104 | } 105 | 106 | /** 107 | * 108 | * @return 109 | * The ShotEnergyCost 110 | */ 111 | @JsonProperty("ShotEnergyCost") 112 | public Integer getShotEnergyCost() { 113 | return shotEnergyCost; 114 | } 115 | 116 | /** 117 | * 118 | * @param ShotEnergyCost 119 | * The ShotEnergyCost 120 | */ 121 | @JsonProperty("ShotEnergyCost") 122 | public void setShotEnergyCost(Integer shotEnergyCost) { 123 | this.shotEnergyCost = shotEnergyCost; 124 | } 125 | 126 | /** 127 | * 128 | * @return 129 | * The ShotEnergy 130 | */ 131 | @JsonProperty("ShotEnergy") 132 | public Integer getShotEnergy() { 133 | return shotEnergy; 134 | } 135 | 136 | /** 137 | * 138 | * @param ShotEnergy 139 | * The ShotEnergy 140 | */ 141 | @JsonProperty("ShotEnergy") 142 | public void setShotEnergy(Integer shotEnergy) { 143 | this.shotEnergy = shotEnergy; 144 | } 145 | 146 | /** 147 | * 148 | * @return 149 | * The DeltaX 150 | */ 151 | @JsonProperty("DeltaX") 152 | public Integer getDeltaX() { 153 | return deltaX; 154 | } 155 | 156 | /** 157 | * 158 | * @param DeltaX 159 | * The DeltaX 160 | */ 161 | @JsonProperty("DeltaX") 162 | public void setDeltaX(Integer deltaX) { 163 | this.deltaX = deltaX; 164 | } 165 | 166 | @JsonAnyGetter 167 | public Map getAdditionalProperties() { 168 | return this.additionalProperties; 169 | } 170 | 171 | @JsonAnySetter 172 | public void setAdditionalProperty(String name, Object value) { 173 | this.additionalProperties.put(name, value); 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/BuildingsAvailable.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.HashMap; 9 | 10 | @JsonInclude(JsonInclude.Include.NON_NULL) 11 | @Generated("org.jsonschema2pojo") 12 | @JsonPropertyOrder({ 13 | "Command", 14 | "Type", 15 | "Cost" 16 | }) 17 | public class BuildingsAvailable { 18 | 19 | @JsonProperty("Command") 20 | @SerializedName("Command") 21 | private String command; 22 | @JsonProperty("Type") 23 | @SerializedName("Type") 24 | private String type; 25 | @JsonProperty("Cost") 26 | @SerializedName("Cost") 27 | private Integer cost; 28 | @JsonIgnore 29 | private java.util.Map additionalProperties = new HashMap(); 30 | 31 | /** 32 | * 33 | * @return 34 | * The Command 35 | */ 36 | @JsonProperty("Command") 37 | public String getCommand() { 38 | return command; 39 | } 40 | 41 | /** 42 | * 43 | * @param Command 44 | * The Command 45 | */ 46 | @JsonProperty("Command") 47 | public void setCommand(String command) { 48 | this.command = command; 49 | } 50 | 51 | /** 52 | * 53 | * @return 54 | * The Type 55 | */ 56 | @JsonProperty("Type") 57 | public String getType() { 58 | return type; 59 | } 60 | 61 | /** 62 | * 63 | * @param Type 64 | * The Type 65 | */ 66 | @JsonProperty("Type") 67 | public void setType(String type) { 68 | this.type = type; 69 | } 70 | 71 | /** 72 | * 73 | * @return 74 | * The Cost 75 | */ 76 | @JsonProperty("Cost") 77 | public Integer getCost() { 78 | return cost; 79 | } 80 | 81 | /** 82 | * 83 | * @param Cost 84 | * The Cost 85 | */ 86 | @JsonProperty("Cost") 87 | public void setCost(Integer cost) { 88 | this.cost = cost; 89 | } 90 | 91 | @JsonAnyGetter 92 | public java.util.Map getAdditionalProperties() { 93 | return this.additionalProperties; 94 | } 95 | 96 | @JsonAnySetter 97 | public void setAdditionalProperty(String name, Object value) { 98 | this.additionalProperties.put(name, value); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/GameState.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | @JsonInclude(JsonInclude.Include.NON_NULL) 13 | @Generated("org.jsonschema2pojo") 14 | @JsonPropertyOrder({ 15 | "BuildingsAvailable", 16 | "Map", 17 | "Players", 18 | "RoundNumber", 19 | "RoundLimit" 20 | }) 21 | public class GameState { 22 | 23 | @JsonProperty("BuildingsAvailable") 24 | @SerializedName("BuildingsAvailable") 25 | private List buildingsAvailable = new ArrayList(); 26 | @JsonProperty("Map") 27 | @SerializedName("Map") 28 | private Map map; 29 | @JsonProperty("Players") 30 | @SerializedName("Players") 31 | private List players = new ArrayList(); 32 | @JsonProperty("RoundNumber") 33 | @SerializedName("RoundNumber") 34 | private Integer roundNumber; 35 | @JsonProperty("RoundLimit") 36 | @SerializedName("RoundLimit") 37 | private Integer roundLimit; 38 | @JsonIgnore 39 | private java.util.Map additionalProperties = new HashMap(); 40 | 41 | /** 42 | * 43 | * @return 44 | * The BuildingsAvailable 45 | */ 46 | @JsonProperty("BuildingsAvailable") 47 | public List getBuildingsAvailable() { 48 | return buildingsAvailable; 49 | } 50 | 51 | /** 52 | * 53 | * @param BuildingsAvailable 54 | * The BuildingsAvailable 55 | */ 56 | @JsonProperty("BuildingsAvailable") 57 | public void setBuildingsAvailable(List buildingsAvailable) { 58 | this.buildingsAvailable = buildingsAvailable; 59 | } 60 | 61 | /** 62 | * 63 | * @return 64 | * The Map 65 | */ 66 | @JsonProperty("Map") 67 | public Map getMap() { 68 | return map; 69 | } 70 | 71 | /** 72 | * 73 | * @param Map 74 | * The Map 75 | */ 76 | @JsonProperty("Map") 77 | public void setMap(Map map) { 78 | this.map = map; 79 | } 80 | 81 | /** 82 | * 83 | * @return 84 | * The Players 85 | */ 86 | @JsonProperty("Players") 87 | public List getPlayers() { 88 | return players; 89 | } 90 | 91 | /** 92 | * 93 | * @param Players 94 | * The Players 95 | */ 96 | @JsonProperty("Players") 97 | public void setPlayers(List players) { 98 | this.players = players; 99 | } 100 | 101 | /** 102 | * 103 | * @return 104 | * The RoundNumber 105 | */ 106 | @JsonProperty("RoundNumber") 107 | public Integer getRoundNumber() { 108 | return roundNumber; 109 | } 110 | 111 | /** 112 | * 113 | * @param RoundNumber 114 | * The RoundNumber 115 | */ 116 | @JsonProperty("RoundNumber") 117 | public void setRoundNumber(Integer roundNumber) { 118 | this.roundNumber = roundNumber; 119 | } 120 | 121 | /** 122 | * 123 | * @return 124 | * The RoundLimit 125 | */ 126 | @JsonProperty("RoundLimit") 127 | public Integer getRoundLimit() { 128 | return roundLimit; 129 | } 130 | 131 | /** 132 | * 133 | * @param RoundLimit 134 | * The RoundLimit 135 | */ 136 | @JsonProperty("RoundLimit") 137 | public void setRoundLimit(Integer roundLimit) { 138 | this.roundLimit = roundLimit; 139 | } 140 | 141 | @JsonAnyGetter 142 | public java.util.Map getAdditionalProperties() { 143 | return this.additionalProperties; 144 | } 145 | 146 | @JsonAnySetter 147 | public void setAdditionalProperty(String name, Object value) { 148 | this.additionalProperties.put(name, value); 149 | } 150 | 151 | } 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Map.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | @JsonInclude(JsonInclude.Include.NON_NULL) 13 | @Generated("org.jsonschema2pojo") 14 | @JsonPropertyOrder({ 15 | "Width", 16 | "Height", 17 | "Rows" 18 | }) 19 | public class Map { 20 | 21 | @JsonProperty("Width") 22 | @SerializedName("Width") 23 | private Integer width; 24 | @JsonProperty("Height") 25 | @SerializedName("Height") 26 | private Integer height; 27 | @JsonProperty("Rows") 28 | @SerializedName("Rows") 29 | private List> rows = new ArrayList>(); 30 | @JsonIgnore 31 | private java.util.Map additionalProperties = new HashMap(); 32 | 33 | /** 34 | * 35 | * @return 36 | * The Width 37 | */ 38 | @JsonProperty("Width") 39 | public Integer getWidth() { 40 | return width; 41 | } 42 | 43 | /** 44 | * 45 | * @param Width 46 | * The Width 47 | */ 48 | @JsonProperty("Width") 49 | public void setWidth(Integer width) { 50 | this.width = width; 51 | } 52 | 53 | /** 54 | * 55 | * @return 56 | * The Height 57 | */ 58 | @JsonProperty("Height") 59 | public Integer getHeight() { 60 | return height; 61 | } 62 | 63 | /** 64 | * 65 | * @param Height 66 | * The Height 67 | */ 68 | @JsonProperty("Height") 69 | public void setHeight(Integer height) { 70 | this.height = height; 71 | } 72 | 73 | /** 74 | * 75 | * @return 76 | * The Rows 77 | */ 78 | @JsonProperty("Rows") 79 | public List> getRows() { 80 | return rows; 81 | } 82 | 83 | /** 84 | * 85 | * @param Rows 86 | * The Rows 87 | */ 88 | @JsonProperty("Rows") 89 | public void setRows(List> rows) { 90 | this.rows = rows; 91 | } 92 | 93 | @JsonAnyGetter 94 | public java.util.Map getAdditionalProperties() { 95 | return this.additionalProperties; 96 | } 97 | 98 | @JsonAnySetter 99 | public void setAdditionalProperty(String name, Object value) { 100 | this.additionalProperties.put(name, value); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Missile.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import za.co.entelect.challenge.dto.enums.EntityType; 4 | 5 | public class Missile { 6 | 7 | private Boolean alive; 8 | private Integer x; 9 | private Integer y; 10 | private Integer width; 11 | private Integer height; 12 | 13 | private EntityType type; 14 | 15 | private Integer playerNumber; 16 | private Integer actionRate; 17 | 18 | public Boolean isAlive() { 19 | return alive; 20 | } 21 | 22 | public void setAlive(Boolean alive) { 23 | this.alive = alive; 24 | } 25 | 26 | public Integer getX() { 27 | return x; 28 | } 29 | 30 | public void setX(Integer x) { 31 | this.x = x; 32 | } 33 | 34 | public Integer getY() { 35 | return y; 36 | } 37 | 38 | public void setY(Integer y) { 39 | this.y = y; 40 | } 41 | 42 | public Integer getWidth() { 43 | return width; 44 | } 45 | 46 | public void setWidth(Integer width) { 47 | this.width = width; 48 | } 49 | 50 | public Integer getHeight() { 51 | return height; 52 | } 53 | 54 | public void setHeight(Integer height) { 55 | this.height = height; 56 | } 57 | 58 | public EntityType getType() { 59 | return type; 60 | } 61 | 62 | public void setType(EntityType type) { 63 | this.type = type; 64 | } 65 | 66 | public Integer getPlayerNumber() { 67 | return playerNumber; 68 | } 69 | 70 | public void setPlayerNumber(Integer playerNumber) { 71 | this.playerNumber = playerNumber; 72 | } 73 | 74 | public Integer getActionRate() { 75 | return actionRate; 76 | } 77 | 78 | public void setActionRate(Integer actionRate) { 79 | this.actionRate = actionRate; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Player.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | @JsonInclude(JsonInclude.Include.NON_NULL) 13 | @Generated("org.jsonschema2pojo") 14 | @JsonPropertyOrder({ 15 | "PlayerNumberReal", 16 | "PlayerNumber", 17 | "PlayerName", 18 | "Ship", 19 | "Kills", 20 | "Lives", 21 | "RespawnTimer", 22 | "Missiles", 23 | "MissileLimit", 24 | "AlienWaveSize", 25 | "AlienFactory", 26 | "MissileController", 27 | "AlienManager" 28 | }) 29 | public class Player { 30 | 31 | @JsonProperty("PlayerNumberReal") 32 | @SerializedName("PlayerNumberReal") 33 | private Integer playerNumberReal; 34 | @JsonProperty("PlayerNumber") 35 | @SerializedName("PlayerNumber") 36 | private Integer playerNumber; 37 | @JsonProperty("PlayerName") 38 | @SerializedName("PlayerName") 39 | private String playerName; 40 | @JsonProperty("Ship") 41 | @SerializedName("Ship") 42 | private Ship ship; 43 | @JsonProperty("Kills") 44 | @SerializedName("Kills") 45 | private Integer kills; 46 | @JsonProperty("Lives") 47 | @SerializedName("Lives") 48 | private Integer lives; 49 | @JsonProperty("RespawnTimer") 50 | @SerializedName("RespawnTimer") 51 | private Integer respawnTimer; 52 | @JsonProperty("Missiles") 53 | @SerializedName("Missiles") 54 | private List missiles = new ArrayList(); 55 | @JsonProperty("MissileLimit") 56 | @SerializedName("MissileLimit") 57 | private Integer missileLimit; 58 | @JsonProperty("AlienWaveSize") 59 | @SerializedName("AlienWaveSize") 60 | private Integer alienWaveSize; 61 | @JsonProperty("AlienFactory") 62 | @SerializedName("AlienFactory") 63 | private Object alienFactory; 64 | @JsonProperty("MissileController") 65 | @SerializedName("MissileController") 66 | private Object missileController; 67 | @JsonProperty("AlienManager") 68 | @SerializedName("AlienManager") 69 | private za.co.entelect.challenge.dto.AlienManager alienManager; 70 | @JsonIgnore 71 | private java.util.Map additionalProperties = new HashMap(); 72 | 73 | /** 74 | * 75 | * @return 76 | * The PlayerNumberReal 77 | */ 78 | @JsonProperty("PlayerNumberReal") 79 | public Integer getPlayerNumberReal() { 80 | return playerNumberReal; 81 | } 82 | 83 | /** 84 | * 85 | * @param PlayerNumberReal 86 | * The PlayerNumberReal 87 | */ 88 | @JsonProperty("PlayerNumberReal") 89 | public void setPlayerNumberReal(Integer playerNumberReal) { 90 | this.playerNumberReal = playerNumberReal; 91 | } 92 | 93 | /** 94 | * 95 | * @return 96 | * The PlayerNumber 97 | */ 98 | @JsonProperty("PlayerNumber") 99 | public Integer getPlayerNumber() { 100 | return playerNumber; 101 | } 102 | 103 | /** 104 | * 105 | * @param PlayerNumber 106 | * The PlayerNumber 107 | */ 108 | @JsonProperty("PlayerNumber") 109 | public void setPlayerNumber(Integer playerNumber) { 110 | this.playerNumber = playerNumber; 111 | } 112 | 113 | /** 114 | * 115 | * @return 116 | * The PlayerName 117 | */ 118 | @JsonProperty("PlayerName") 119 | public String getPlayerName() { 120 | return playerName; 121 | } 122 | 123 | /** 124 | * 125 | * @param PlayerName 126 | * The PlayerName 127 | */ 128 | @JsonProperty("PlayerName") 129 | public void setPlayerName(String playerName) { 130 | this.playerName = playerName; 131 | } 132 | 133 | /** 134 | * 135 | * @return 136 | * The Ship 137 | */ 138 | @JsonProperty("Ship") 139 | public Ship getShip() { 140 | return ship; 141 | } 142 | 143 | /** 144 | * 145 | * @param Ship 146 | * The Ship 147 | */ 148 | @JsonProperty("Ship") 149 | public void setShip(Ship ship) { 150 | this.ship = ship; 151 | } 152 | 153 | /** 154 | * 155 | * @return 156 | * The Kills 157 | */ 158 | @JsonProperty("Kills") 159 | public Integer getKills() { 160 | return kills; 161 | } 162 | 163 | /** 164 | * 165 | * @param Kills 166 | * The Kills 167 | */ 168 | @JsonProperty("Kills") 169 | public void setKills(Integer kills) { 170 | this.kills = kills; 171 | } 172 | 173 | /** 174 | * 175 | * @return 176 | * The Lives 177 | */ 178 | @JsonProperty("Lives") 179 | public Integer getLives() { 180 | return lives; 181 | } 182 | 183 | /** 184 | * 185 | * @param Lives 186 | * The Lives 187 | */ 188 | @JsonProperty("Lives") 189 | public void setLives(Integer lives) { 190 | this.lives = lives; 191 | } 192 | 193 | /** 194 | * 195 | * @return 196 | * The RespawnTimer 197 | */ 198 | @JsonProperty("RespawnTimer") 199 | public Integer getRespawnTimer() { 200 | return respawnTimer; 201 | } 202 | 203 | /** 204 | * 205 | * @param RespawnTimer 206 | * The RespawnTimer 207 | */ 208 | @JsonProperty("RespawnTimer") 209 | public void setRespawnTimer(Integer respawnTimer) { 210 | this.respawnTimer = respawnTimer; 211 | } 212 | 213 | /** 214 | * 215 | * @return 216 | * The Missiles 217 | */ 218 | @JsonProperty("Missiles") 219 | public List getMissiles() { 220 | return missiles; 221 | } 222 | 223 | /** 224 | * 225 | * @param Missiles 226 | * The Missiles 227 | */ 228 | @JsonProperty("Missiles") 229 | public void setMissiles(List missiles) { 230 | this.missiles = missiles; 231 | } 232 | 233 | /** 234 | * 235 | * @return 236 | * The MissileLimit 237 | */ 238 | @JsonProperty("MissileLimit") 239 | public Integer getMissileLimit() { 240 | return missileLimit; 241 | } 242 | 243 | /** 244 | * 245 | * @param MissileLimit 246 | * The MissileLimit 247 | */ 248 | @JsonProperty("MissileLimit") 249 | public void setMissileLimit(Integer missileLimit) { 250 | this.missileLimit = missileLimit; 251 | } 252 | 253 | /** 254 | * 255 | * @return 256 | * The AlienWaveSize 257 | */ 258 | @JsonProperty("AlienWaveSize") 259 | public Integer getAlienWaveSize() { 260 | return alienWaveSize; 261 | } 262 | 263 | /** 264 | * 265 | * @param AlienWaveSize 266 | * The AlienWaveSize 267 | */ 268 | @JsonProperty("AlienWaveSize") 269 | public void setAlienWaveSize(Integer alienWaveSize) { 270 | this.alienWaveSize = alienWaveSize; 271 | } 272 | 273 | /** 274 | * 275 | * @return 276 | * The AlienFactory 277 | */ 278 | @JsonProperty("AlienFactory") 279 | public Object getAlienFactory() { 280 | return alienFactory; 281 | } 282 | 283 | /** 284 | * 285 | * @param AlienFactory 286 | * The AlienFactory 287 | */ 288 | @JsonProperty("AlienFactory") 289 | public void setAlienFactory(Object alienFactory) { 290 | this.alienFactory = alienFactory; 291 | } 292 | 293 | /** 294 | * 295 | * @return 296 | * The MissileController 297 | */ 298 | @JsonProperty("MissileController") 299 | public Object getMissileController() { 300 | return missileController; 301 | } 302 | 303 | /** 304 | * 305 | * @param MissileController 306 | * The MissileController 307 | */ 308 | @JsonProperty("MissileController") 309 | public void setMissileController(Object missileController) { 310 | this.missileController = missileController; 311 | } 312 | 313 | /** 314 | * 315 | * @return 316 | * The AlienManager 317 | */ 318 | @JsonProperty("AlienManager") 319 | public AlienManager getAlienManager() { 320 | return alienManager; 321 | } 322 | 323 | /** 324 | * 325 | * @param AlienManager 326 | * The AlienManager 327 | */ 328 | @JsonProperty("AlienManager") 329 | public void setAlienManager(AlienManager alienManager) { 330 | this.alienManager = alienManager; 331 | } 332 | 333 | @JsonAnyGetter 334 | public java.util.Map getAdditionalProperties() { 335 | return this.additionalProperties; 336 | } 337 | 338 | @JsonAnySetter 339 | public void setAdditionalProperty(String name, Object value) { 340 | this.additionalProperties.put(name, value); 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Row.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.HashMap; 9 | 10 | @JsonInclude(JsonInclude.Include.NON_NULL) 11 | @Generated("org.jsonschema2pojo") 12 | @JsonPropertyOrder({ 13 | "Id", 14 | "Alive", 15 | "x", 16 | "y", 17 | "Width", 18 | "Height", 19 | "Type", 20 | "PlayerNumber" 21 | }) 22 | public class Row { 23 | 24 | @JsonProperty("Id") 25 | @SerializedName("Id") 26 | private Integer id; 27 | @JsonProperty("Alive") 28 | @SerializedName("Alive") 29 | private Boolean alive; 30 | @JsonProperty("X") 31 | @SerializedName("X") 32 | private Integer x; 33 | @JsonProperty("Y") 34 | @SerializedName("Y") 35 | private Integer y; 36 | @JsonProperty("Width") 37 | @SerializedName("Width") 38 | private Integer width; 39 | @JsonProperty("Height") 40 | @SerializedName("Height") 41 | private Integer height; 42 | @JsonProperty("Type") 43 | @SerializedName("Type") 44 | private String type; 45 | @JsonProperty("PlayerNumber") 46 | @SerializedName("PlayerNumber") 47 | private Integer playerNumber; 48 | @JsonIgnore 49 | private java.util.Map additionalProperties = new HashMap(); 50 | 51 | /** 52 | * 53 | * @return 54 | * The Id 55 | */ 56 | @JsonProperty("Id") 57 | public Integer getId() { 58 | return id; 59 | } 60 | 61 | /** 62 | * 63 | * @param Id 64 | * The Id 65 | */ 66 | @JsonProperty("Id") 67 | public void setId(Integer id) { 68 | this.id = id; 69 | } 70 | 71 | /** 72 | * 73 | * @return 74 | * The Alive 75 | */ 76 | @JsonProperty("Alive") 77 | public Boolean getAlive() { 78 | return alive; 79 | } 80 | 81 | /** 82 | * 83 | * @param Alive 84 | * The Alive 85 | */ 86 | @JsonProperty("Alive") 87 | public void setAlive(Boolean alive) { 88 | this.alive = alive; 89 | } 90 | 91 | /** 92 | * 93 | * @return 94 | * The x 95 | */ 96 | @JsonProperty("x") 97 | public Integer getX() { 98 | return x; 99 | } 100 | 101 | /** 102 | * 103 | * @param x 104 | * The x 105 | */ 106 | @JsonProperty("x") 107 | public void setX(Integer x) { 108 | this.x = x; 109 | } 110 | 111 | /** 112 | * 113 | * @return 114 | * The y 115 | */ 116 | @JsonProperty("y") 117 | public Integer getY() { 118 | return y; 119 | } 120 | 121 | /** 122 | * 123 | * @param y 124 | * The y 125 | */ 126 | @JsonProperty("y") 127 | public void setY(Integer y) { 128 | this.y = y; 129 | } 130 | 131 | /** 132 | * 133 | * @return 134 | * The Width 135 | */ 136 | @JsonProperty("Width") 137 | public Integer getWidth() { 138 | return width; 139 | } 140 | 141 | /** 142 | * 143 | * @param Width 144 | * The Width 145 | */ 146 | @JsonProperty("Width") 147 | public void setWidth(Integer width) { 148 | this.width = width; 149 | } 150 | 151 | /** 152 | * 153 | * @return 154 | * The Height 155 | */ 156 | @JsonProperty("Height") 157 | public Integer getHeight() { 158 | return height; 159 | } 160 | 161 | /** 162 | * 163 | * @param Height 164 | * The Height 165 | */ 166 | @JsonProperty("Height") 167 | public void setHeight(Integer height) { 168 | this.height = height; 169 | } 170 | 171 | /** 172 | * 173 | * @return 174 | * The Type 175 | */ 176 | @JsonProperty("Type") 177 | public String getType() { 178 | return type; 179 | } 180 | 181 | /** 182 | * 183 | * @param Type 184 | * The Type 185 | */ 186 | @JsonProperty("Type") 187 | public void setType(String type) { 188 | this.type = type; 189 | } 190 | 191 | /** 192 | * 193 | * @return 194 | * The PlayerNumber 195 | */ 196 | @JsonProperty("PlayerNumber") 197 | public Integer getPlayerNumber() { 198 | return playerNumber; 199 | } 200 | 201 | /** 202 | * 203 | * @param PlayerNumber 204 | * The PlayerNumber 205 | */ 206 | @JsonProperty("PlayerNumber") 207 | public void setPlayerNumber(Integer playerNumber) { 208 | this.playerNumber = playerNumber; 209 | } 210 | 211 | @JsonAnyGetter 212 | public java.util.Map getAdditionalProperties() { 213 | return this.additionalProperties; 214 | } 215 | 216 | @JsonAnySetter 217 | public void setAdditionalProperty(String name, Object value) { 218 | this.additionalProperties.put(name, value); 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Settings.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | public class Settings { 4 | 5 | private String defaultOutputFolder = "output"; 6 | private String outputFile = "move.txt"; 7 | private String stateFile = "state.json"; 8 | private String mapFile = "map.txt"; 9 | 10 | public String getDefaultOutputFolder() { 11 | return defaultOutputFolder; 12 | } 13 | 14 | public void setDefaultOutputFolder(String defaultOutputFolder) { 15 | this.defaultOutputFolder = defaultOutputFolder; 16 | } 17 | 18 | public String getOutputFile() { 19 | return outputFile; 20 | } 21 | 22 | public void setOutputFile(String outputFile) { 23 | this.outputFile = outputFile; 24 | } 25 | 26 | public String getStateFile() { 27 | return stateFile; 28 | } 29 | 30 | public void setStateFile(String stateFile) { 31 | this.stateFile = stateFile; 32 | } 33 | 34 | public String getMapFile() { 35 | return mapFile; 36 | } 37 | 38 | public void setMapFile(String mapFile) { 39 | this.mapFile = mapFile; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Ship.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import javax.annotation.Generated; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 8 | import com.google.gson.annotations.SerializedName; 9 | 10 | @JsonInclude(JsonInclude.Include.NON_NULL) 11 | @Generated("org.jsonschema2pojo") 12 | @JsonPropertyOrder({ "Command", "CommandFeedback", "Id", "Alive", "X", "Y", 13 | "Width", "Height", "Type", "PlayerNumber" }) 14 | public class Ship { 15 | @JsonProperty("Command") 16 | @SerializedName("Command") 17 | private String command; 18 | 19 | @JsonProperty("CommandFeedback") 20 | @SerializedName("CommandFeedback") 21 | private String commandFeedback; 22 | 23 | @JsonProperty("Id") 24 | @SerializedName("Id") 25 | private Integer id; 26 | 27 | public String getCommand() { 28 | return command; 29 | } 30 | 31 | public void setCommand(String command) { 32 | this.command = command; 33 | } 34 | 35 | public String getCommandFeedback() { 36 | return commandFeedback; 37 | } 38 | 39 | public void setCommandFeedback(String commandFeedback) { 40 | this.commandFeedback = commandFeedback; 41 | } 42 | 43 | public Integer getId() { 44 | return id; 45 | } 46 | 47 | public void setId(Integer id) { 48 | this.id = id; 49 | } 50 | 51 | public Boolean getAlive() { 52 | return alive; 53 | } 54 | 55 | public void setAlive(Boolean alive) { 56 | this.alive = alive; 57 | } 58 | 59 | public Integer getWidth() { 60 | return width; 61 | } 62 | 63 | public void setWidth(Integer width) { 64 | this.width = width; 65 | } 66 | 67 | public Integer getHeight() { 68 | return height; 69 | } 70 | 71 | public void setHeight(Integer height) { 72 | this.height = height; 73 | } 74 | 75 | public String getType() { 76 | return type; 77 | } 78 | 79 | public void setType(String type) { 80 | this.type = type; 81 | } 82 | 83 | public Integer getPlayerNumber() { 84 | return playerNumber; 85 | } 86 | 87 | public void setPlayerNumber(Integer playerNumber) { 88 | this.playerNumber = playerNumber; 89 | } 90 | 91 | @JsonProperty("Alive") 92 | @SerializedName("Alive") 93 | private Boolean alive; 94 | 95 | @JsonProperty("X") 96 | @SerializedName("X") 97 | private Integer x; 98 | 99 | @JsonProperty("Y") 100 | @SerializedName("Y") 101 | private Integer y; 102 | 103 | 104 | 105 | @JsonProperty("Width") 106 | @SerializedName("Width") 107 | private Integer width; 108 | 109 | @JsonProperty("Height") 110 | @SerializedName("Height") 111 | private Integer height; 112 | 113 | @JsonProperty("Type") 114 | @SerializedName("Type") 115 | private String type; 116 | 117 | @JsonProperty("PlayerNumber") 118 | @SerializedName("PlayerNumber") 119 | private Integer playerNumber; 120 | 121 | 122 | 123 | public Integer getY() { 124 | return y; 125 | } 126 | 127 | public Integer getX() { 128 | return x; 129 | } 130 | 131 | public void setX(Integer x) { 132 | this.x = x; 133 | } 134 | 135 | public void setY(Integer y) { 136 | this.y = y; 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/Wave.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import com.fasterxml.jackson.annotation.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import javax.annotation.Generated; 7 | 8 | import java.util.HashMap; 9 | 10 | @JsonInclude(JsonInclude.Include.NON_NULL) 11 | @Generated("org.jsonschema2pojo") 12 | @JsonPropertyOrder({ 13 | "DeltaY", 14 | "DeltaX", 15 | "Command", 16 | "Id", 17 | "Alive", 18 | "x", 19 | "y", 20 | "Width", 21 | "Height", 22 | "Type", 23 | "PlayerNumber" 24 | }) 25 | public class Wave { 26 | 27 | @JsonProperty("DeltaY") 28 | @SerializedName("DeltaY") 29 | private Integer deltaY; 30 | @JsonProperty("DeltaX") 31 | @SerializedName("DeltaX") 32 | private Integer deltaX; 33 | @JsonProperty("Command") 34 | @SerializedName("Command") 35 | private Integer command; 36 | @JsonProperty("Id") 37 | @SerializedName("Id") 38 | private Integer id; 39 | @JsonProperty("Alive") 40 | @SerializedName("Alive") 41 | private Boolean alive; 42 | @JsonProperty("X") 43 | @SerializedName("X") 44 | private Integer x; 45 | @JsonProperty("Y") 46 | @SerializedName("Y") 47 | private Integer y; 48 | @JsonProperty("Width") 49 | @SerializedName("Width") 50 | private Integer width; 51 | @JsonProperty("Height") 52 | @SerializedName("Height") 53 | private Integer height; 54 | @JsonProperty("Type") 55 | @SerializedName("Type") 56 | private String type; 57 | @JsonProperty("PlayerNumber") 58 | @SerializedName("PlayerNumber") 59 | private Integer playerNumber; 60 | @JsonIgnore 61 | private java.util.Map additionalProperties = new HashMap(); 62 | 63 | /** 64 | * 65 | * @return 66 | * The DeltaY 67 | */ 68 | @JsonProperty("DeltaY") 69 | public Integer getDeltaY() { 70 | return deltaY; 71 | } 72 | 73 | /** 74 | * 75 | * @param DeltaY 76 | * The DeltaY 77 | */ 78 | @JsonProperty("DeltaY") 79 | public void setDeltaY(Integer deltaY) { 80 | this.deltaY = deltaY; 81 | } 82 | 83 | /** 84 | * 85 | * @return 86 | * The DeltaX 87 | */ 88 | @JsonProperty("DeltaX") 89 | public Integer getDeltaX() { 90 | return deltaX; 91 | } 92 | 93 | /** 94 | * 95 | * @param DeltaX 96 | * The DeltaX 97 | */ 98 | @JsonProperty("DeltaX") 99 | public void setDeltaX(Integer deltaX) { 100 | this.deltaX = deltaX; 101 | } 102 | 103 | /** 104 | * 105 | * @return 106 | * The Command 107 | */ 108 | @JsonProperty("Command") 109 | public Integer getCommand() { 110 | return command; 111 | } 112 | 113 | /** 114 | * 115 | * @param Command 116 | * The Command 117 | */ 118 | @JsonProperty("Command") 119 | public void setCommand(Integer command) { 120 | this.command = command; 121 | } 122 | 123 | /** 124 | * 125 | * @return 126 | * The Id 127 | */ 128 | @JsonProperty("Id") 129 | public Integer getId() { 130 | return id; 131 | } 132 | 133 | /** 134 | * 135 | * @param Id 136 | * The Id 137 | */ 138 | @JsonProperty("Id") 139 | public void setId(Integer id) { 140 | this.id = id; 141 | } 142 | 143 | /** 144 | * 145 | * @return 146 | * The Alive 147 | */ 148 | @JsonProperty("Alive") 149 | public Boolean getAlive() { 150 | return alive; 151 | } 152 | 153 | /** 154 | * 155 | * @param Alive 156 | * The Alive 157 | */ 158 | @JsonProperty("Alive") 159 | public void setAlive(Boolean alive) { 160 | this.alive = alive; 161 | } 162 | 163 | /** 164 | * 165 | * @return 166 | * The x 167 | */ 168 | @JsonProperty("x") 169 | public Integer getX() { 170 | return x; 171 | } 172 | 173 | /** 174 | * 175 | * @param x 176 | * The x 177 | */ 178 | @JsonProperty("x") 179 | public void setX(Integer x) { 180 | this.x = x; 181 | } 182 | 183 | /** 184 | * 185 | * @return 186 | * The y 187 | */ 188 | @JsonProperty("y") 189 | public Integer getY() { 190 | return y; 191 | } 192 | 193 | /** 194 | * 195 | * @param y 196 | * The y 197 | */ 198 | @JsonProperty("y") 199 | public void setY(Integer y) { 200 | this.y = y; 201 | } 202 | 203 | /** 204 | * 205 | * @return 206 | * The Width 207 | */ 208 | @JsonProperty("Width") 209 | public Integer getWidth() { 210 | return width; 211 | } 212 | 213 | /** 214 | * 215 | * @param Width 216 | * The Width 217 | */ 218 | @JsonProperty("Width") 219 | public void setWidth(Integer width) { 220 | this.width = width; 221 | } 222 | 223 | /** 224 | * 225 | * @return 226 | * The Height 227 | */ 228 | @JsonProperty("Height") 229 | public Integer getHeight() { 230 | return height; 231 | } 232 | 233 | /** 234 | * 235 | * @param Height 236 | * The Height 237 | */ 238 | @JsonProperty("Height") 239 | public void setHeight(Integer height) { 240 | this.height = height; 241 | } 242 | 243 | /** 244 | * 245 | * @return 246 | * The Type 247 | */ 248 | @JsonProperty("Type") 249 | public String getType() { 250 | return type; 251 | } 252 | 253 | /** 254 | * 255 | * @param Type 256 | * The Type 257 | */ 258 | @JsonProperty("Type") 259 | public void setType(String type) { 260 | this.type = type; 261 | } 262 | 263 | /** 264 | * 265 | * @return 266 | * The PlayerNumber 267 | */ 268 | @JsonProperty("PlayerNumber") 269 | public Integer getPlayerNumber() { 270 | return playerNumber; 271 | } 272 | 273 | /** 274 | * 275 | * @param PlayerNumber 276 | * The PlayerNumber 277 | */ 278 | @JsonProperty("PlayerNumber") 279 | public void setPlayerNumber(Integer playerNumber) { 280 | this.playerNumber = playerNumber; 281 | } 282 | 283 | @JsonAnyGetter 284 | public java.util.Map getAdditionalProperties() { 285 | return this.additionalProperties; 286 | } 287 | 288 | @JsonAnySetter 289 | public void setAdditionalProperty(String name, Object value) { 290 | this.additionalProperties.put(name, value); 291 | } 292 | 293 | } 294 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/enums/EntityType.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.enums; 2 | 3 | public enum EntityType{ 4 | Ship, 5 | Missile, 6 | Wall, 7 | Shield, 8 | EmptyTile, 9 | Alien, 10 | Bullet, 11 | BuildingEnergy, 12 | BuildingMissile, 13 | BuildingAlienFactory; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/enums/ShipCommand.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.enums; 2 | 3 | public enum ShipCommand { 4 | 5 | Nothing, 6 | MoveLeft, 7 | MoveRight, 8 | Shoot, 9 | BuildAlienFactory, 10 | BuildMissileController, 11 | BuildShield; 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/reader/BasicGameStateReader.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.reader; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.LinkedHashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import net.minidev.json.JSONArray; 11 | 12 | import com.jayway.jsonpath.JsonPath; 13 | import com.jayway.jsonpath.PathNotFoundException; 14 | 15 | import za.co.entelect.challenge.dto.GameState; 16 | import za.co.entelect.challenge.dto.Missile; 17 | import za.co.entelect.challenge.dto.Player; 18 | import za.co.entelect.challenge.dto.Ship; 19 | import za.co.entelect.challenge.dto.enums.EntityType; 20 | import za.co.entelect.challenge.utils.LogHelper; 21 | 22 | /** 23 | * This class accesses the json elements directly 24 | * Advantage: Fast and no need initialise everything - only use what you need 25 | * Disadvantage: Match/Game State model only partially initialised 26 | */ 27 | public class BasicGameStateReader implements GameStateReader 28 | { 29 | @Override 30 | public GameState read(File jsonFile) throws IOException { 31 | try { 32 | GameState gameState = new GameState(); 33 | 34 | loadRoundNumber(jsonFile, gameState); 35 | 36 | String player1Path = "$.Players[0]"; 37 | String player2Path = "$.Players[1]"; 38 | 39 | Player player1 = loadPlayer(jsonFile, player1Path); 40 | Player player2 = loadPlayer(jsonFile, player2Path); 41 | 42 | gameState.getPlayers().add(player1); 43 | gameState.getPlayers().add(player2); 44 | 45 | return gameState; 46 | } catch (NumberFormatException nfe) { 47 | throw new RuntimeException("Unable to convert Round Number to int", nfe); 48 | } 49 | } 50 | 51 | private void loadRoundNumber(File jsonFile, GameState gameState) throws IOException { 52 | String roundNumber = "$.RoundNumber"; 53 | gameState.setRoundNumber(Integer.valueOf(JsonPath.read(jsonFile, roundNumber).toString())); 54 | } 55 | 56 | private Player loadPlayer(File jsonFile, String playerPath) throws IOException { 57 | Player player = new Player(); 58 | 59 | try { 60 | Map playerMap = JsonPath.read(jsonFile, playerPath); 61 | 62 | player.setPlayerName((String)playerMap.get("PlayerName")); 63 | player.setPlayerNumber((Integer)playerMap.get("PlayerNumber")); 64 | player.setPlayerNumberReal((Integer)playerMap.get("PlayerNumberReal")); 65 | player.setKills((Integer)playerMap.get("Kills")); 66 | player.setLives((Integer)playerMap.get("Lives")); 67 | player.setMissileLimit((Integer)playerMap.get("MissileLimit")); 68 | 69 | JSONArray missiles = (JSONArray)playerMap.get("Missiles"); 70 | 71 | player.setMissiles(loadMissiles(missiles)); 72 | 73 | Ship ship = loadShip ((Map)playerMap.get("Ship")); 74 | 75 | player.setShip(ship ); 76 | 77 | } catch (PathNotFoundException pnfe) { 78 | LogHelper.log("Index out of bounds when evaluating path " + playerPath); 79 | pnfe.printStackTrace(); 80 | } 81 | 82 | return player; 83 | } 84 | 85 | private Ship loadShip(Map in) { 86 | Ship ship = new Ship(); 87 | 88 | ship.setAlive((Boolean) in.get("Alive")); 89 | ship.setCommand(in.get("Command").toString()); 90 | ship.setCommandFeedback(in.get("CommandFeedback").toString()); 91 | ship.setHeight((Integer) in.get("Height")); 92 | ship.setId((Integer) in.get("Id")); 93 | ship.setPlayerNumber((Integer) in.get ("PlayerNumber")); 94 | ship.setType((String) in.get("Type")); 95 | ship.setWidth((Integer) in.get ("Width")); 96 | ship.setX((Integer) in.get("X")); 97 | ship.setY((Integer) in.get("Y")); 98 | 99 | return ship; 100 | } 101 | 102 | private List loadMissiles(JSONArray missiles) { 103 | List playerMissiles = new ArrayList<>(); 104 | Missile playerMissile; 105 | 106 | for (Object missile : missiles) { 107 | playerMissile = new Missile(); 108 | 109 | @SuppressWarnings("unchecked") 110 | LinkedHashMap playerMissilesMap = (LinkedHashMap) missile; 111 | 112 | playerMissile.setAlive((Boolean)playerMissilesMap.get("Alive")); 113 | playerMissile.setX((Integer)playerMissilesMap.get("x")); 114 | playerMissile.setY((Integer)playerMissilesMap.get("y")); 115 | playerMissile.setWidth((Integer)playerMissilesMap.get("Width")); 116 | playerMissile.setHeight((Integer)playerMissilesMap.get("Height")); 117 | for (EntityType type : EntityType.values()) { 118 | if (((String)playerMissilesMap.get("Type")).equalsIgnoreCase(type.toString())) { 119 | playerMissile.setType(type); 120 | break; 121 | } 122 | } 123 | playerMissile.setPlayerNumber((Integer)playerMissilesMap.get("PlayerNumber")); 124 | playerMissile.setActionRate((Integer)playerMissilesMap.get("ActionRate")); 125 | 126 | playerMissiles.add(playerMissile); 127 | } 128 | 129 | return playerMissiles; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/reader/GameStateReader.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.reader; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import za.co.entelect.challenge.dto.GameState; 7 | 8 | public interface GameStateReader 9 | { 10 | public GameState read(File jsonFile) throws IOException; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/reader/GsonGameStateReader.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.reader; 2 | 3 | import java.io.File; 4 | import java.io.FileReader; 5 | import java.io.IOException; 6 | 7 | import com.google.gson.Gson; 8 | 9 | import za.co.entelect.challenge.dto.GameState; 10 | 11 | public class GsonGameStateReader implements GameStateReader 12 | { 13 | @Override 14 | public GameState read(File jsonFile) throws IOException { 15 | 16 | try (FileReader reader = new FileReader(jsonFile)) { 17 | return (new Gson()).fromJson(reader, GameState.class); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/dto/reader/JacksonGameStateReader.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto.reader; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | 8 | import za.co.entelect.challenge.dto.GameState; 9 | 10 | public class JacksonGameStateReader implements GameStateReader 11 | { 12 | public GameState read(File jsonFile) throws IOException { 13 | 14 | // ObjectMapper provides functionality for data binding between 15 | // Java Bean Objects/POJO and JSON constructs/string 16 | ObjectMapper mapper = new ObjectMapper(); 17 | 18 | return mapper.readValue(jsonFile, GameState.class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/program/Main.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.program; 2 | 3 | import za.co.entelect.challenge.bot.BasicBot; 4 | import za.co.entelect.challenge.dto.Settings; 5 | import za.co.entelect.challenge.utils.LogHelper; 6 | import za.co.entelect.challenge.utils.StringUtility; 7 | 8 | import java.io.FileNotFoundException; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.Properties; 12 | 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | 17 | long startTime = System.currentTimeMillis(); 18 | 19 | if (args.length != 1) { 20 | printUsage(); 21 | } 22 | 23 | Settings settings = loadSettings(); 24 | 25 | getDefaultFolderNameFromArguments(args, settings); 26 | 27 | BasicBot bot = new BasicBot(settings); 28 | bot.execute(); 29 | 30 | long runTime = System.currentTimeMillis() - startTime; 31 | 32 | printRunTime(bot, runTime); 33 | } 34 | 35 | private static void printUsage() { 36 | LogHelper.log("Java QuickStartBot usage: java -jar target/BasicBot-1.0-SNAPSHOT-jar-with-dependencies.jar "); 37 | LogHelper.logEmptyLine(); 38 | LogHelper.log("\tdefaultOutputFolderName\tThe folder into which the bot should write its move."); 39 | } 40 | 41 | private static Settings loadSettings() { 42 | Settings settings = new Settings(); 43 | Properties prop = new Properties(); 44 | String propFileName = "settings.properties"; 45 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 46 | InputStream stream = loader.getResourceAsStream(propFileName); 47 | try { 48 | if (stream != null) { 49 | prop.load(stream); 50 | settings.setDefaultOutputFolder(prop.getProperty("DefaultOutputFolder")); 51 | settings.setOutputFile(prop.getProperty("OutputFile")); 52 | settings.setStateFile(prop.getProperty("StateFile")); 53 | settings.setMapFile(prop.getProperty("MapFile")); 54 | } else { 55 | LogHelper.log(propFileName + " not found in the classpath"); 56 | } 57 | } catch (FileNotFoundException fnfe) { 58 | LogHelper.log(propFileName + " not found in the classpath"); 59 | } catch (IOException ioe) { 60 | LogHelper.log("Error reading " + propFileName); 61 | } 62 | return settings; 63 | } 64 | 65 | private static void getDefaultFolderNameFromArguments(String[] args, Settings settings) 66 | { 67 | if (StringUtility.isValidString(args[0])) { 68 | settings.setDefaultOutputFolder(args[0]); 69 | } else { 70 | LogHelper.log("Invalid output folder. Defaulting to: " + settings.getDefaultOutputFolder()); 71 | } 72 | } 73 | 74 | private static void printRunTime(BasicBot bot, long runTime) { 75 | LogHelper.log(LogHelper.PREFIX + getPlayerName(bot) + " finished in " + runTime + " ms."); 76 | } 77 | 78 | /** 79 | * You can always assume that you are player 1 80 | * 81 | * @param bot 82 | * @return playerName 83 | */ 84 | private static String getPlayerName(BasicBot bot) { 85 | return bot.getPlayers().get(0).getPlayerName(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/utils/BotHelper.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.utils; 2 | 3 | import za.co.entelect.challenge.dto.enums.ShipCommand; 4 | 5 | public class BotHelper { 6 | 7 | public static String translateMove(int number) { 8 | return ShipCommand.values()[number].toString(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/utils/FileHelper.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.utils; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.nio.charset.Charset; 7 | import java.nio.charset.StandardCharsets; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.nio.file.Paths; 11 | import java.util.Scanner; 12 | 13 | public class FileHelper { 14 | 15 | private final static Charset ENCODING = StandardCharsets.UTF_8; 16 | 17 | public static File getFile(String outputFolder, String fileName) { 18 | File file = Paths.get(outputFolder, fileName).toFile(); 19 | 20 | return file; 21 | } 22 | 23 | public static StringBuilder readFile(String folder, String aFileName) throws IOException { 24 | Path path = Paths.get(folder, aFileName); 25 | try (Scanner scanner = new Scanner(path, ENCODING.name())) { 26 | StringBuilder textData = new StringBuilder(); 27 | while (scanner.hasNextLine()) { 28 | textData.append(scanner.nextLine() + "\n"); 29 | } 30 | return textData; 31 | } 32 | } 33 | 34 | public static void writeFile(String folder, String aFileName, String aItem) throws IOException { 35 | Path path = Paths.get(folder, aFileName); 36 | try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING)) { 37 | writer.write(aItem); 38 | writer.newLine(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/utils/LogHelper.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.utils; 2 | 3 | public class LogHelper { 4 | 5 | public final static String PREFIX = "[BOT]\t"; 6 | 7 | public static void log(Object aMsg) { 8 | System.out.println(String.valueOf(aMsg)); 9 | } 10 | 11 | public static void log(String description, Object aMsg) { 12 | System.out.print(PREFIX + description + ": "); 13 | log(aMsg); 14 | } 15 | 16 | public static void logPartsOnDifferentLines(String description, Object aMsg) { 17 | log(PREFIX + description + ":"); 18 | log(aMsg); 19 | } 20 | 21 | public static void logEmptyLine() { 22 | System.out.println(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/za/co/entelect/challenge/utils/StringUtility.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.utils; 2 | 3 | public final class StringUtility { 4 | /** 5 | * Takes in a string and checks to see that it is not null and 6 | * that its length is greater than zero. It does not however check 7 | * the contents of the string. It can contain any kind of character. 8 | */ 9 | public static boolean isValidString(final String source) { 10 | return (source != null && source.length() > 0); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/settings.properties: -------------------------------------------------------------------------------- 1 | DefaultOutputFolder=output 2 | OutputFile=move.txt 3 | StateFile=state.json 4 | MapFile=map.txt -------------------------------------------------------------------------------- /src/test/java/za/co/entelect/challenge/dto/GameStateParsingTest.java: -------------------------------------------------------------------------------- 1 | package za.co.entelect.challenge.dto; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.io.File; 6 | 7 | import org.junit.Test; 8 | 9 | import za.co.entelect.challenge.dto.reader.BasicGameStateReader; 10 | import za.co.entelect.challenge.dto.reader.GameStateReader; 11 | import za.co.entelect.challenge.utils.FileHelper; 12 | import za.co.entelect.challenge.utils.LogHelper; 13 | 14 | public class GameStateParsingTest { 15 | 16 | @Test 17 | public void test() { 18 | GameStateReader reader = 19 | new BasicGameStateReader(); 20 | //new JacksonGameStateReader(); 21 | //new GsonGameStateReader(); 22 | 23 | GameState gameState = loadGameState(reader); 24 | assertNotNull(gameState); 25 | 26 | Ship ship =gameState.getPlayers().get(0).getShip(); 27 | assertNotNull (ship); 28 | assertEquals(7, ship.getX().intValue()); 29 | assertEquals(22, ship.getY().intValue()); 30 | 31 | } 32 | 33 | private GameState loadGameState(GameStateReader reader) { 34 | GameState gameState = null; 35 | 36 | File jsonFile = new File ("src/test/resources/state.json"); 37 | 38 | try { 39 | gameState = reader.read(jsonFile); 40 | } catch (Exception ioe) { 41 | 42 | ioe.printStackTrace(); 43 | return null; 44 | } 45 | 46 | return gameState; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/state.json: -------------------------------------------------------------------------------- 1 | { 2 | "BuildingsAvailable": [ 3 | { 4 | "Command": "BuildAlienFactory", 5 | "Type": "AlienFactory", 6 | "Cost": 1 7 | }, 8 | { 9 | "Command": "BuildMissileController", 10 | "Type": "MissileController", 11 | "Cost": 1 12 | }, 13 | { 14 | "Command": "BuildShield", 15 | "Type": "Shield", 16 | "Cost": 1 17 | } 18 | ], 19 | "Map": { 20 | "Width": 19, 21 | "Height": 25, 22 | "Rows": [ 23 | [ 24 | { 25 | "Id": 1, 26 | "Alive": true, 27 | "X": 0, 28 | "Y": 0, 29 | "Width": 1, 30 | "Height": 1, 31 | "Type": "Wall", 32 | "PlayerNumber": 0 33 | }, 34 | { 35 | "Id": 2, 36 | "Alive": true, 37 | "X": 1, 38 | "Y": 0, 39 | "Width": 1, 40 | "Height": 1, 41 | "Type": "Wall", 42 | "PlayerNumber": 0 43 | }, 44 | { 45 | "Id": 3, 46 | "Alive": true, 47 | "X": 2, 48 | "Y": 0, 49 | "Width": 1, 50 | "Height": 1, 51 | "Type": "Wall", 52 | "PlayerNumber": 0 53 | }, 54 | { 55 | "Id": 4, 56 | "Alive": true, 57 | "X": 3, 58 | "Y": 0, 59 | "Width": 1, 60 | "Height": 1, 61 | "Type": "Wall", 62 | "PlayerNumber": 0 63 | }, 64 | { 65 | "Id": 5, 66 | "Alive": true, 67 | "X": 4, 68 | "Y": 0, 69 | "Width": 1, 70 | "Height": 1, 71 | "Type": "Wall", 72 | "PlayerNumber": 0 73 | }, 74 | { 75 | "Id": 6, 76 | "Alive": true, 77 | "X": 5, 78 | "Y": 0, 79 | "Width": 1, 80 | "Height": 1, 81 | "Type": "Wall", 82 | "PlayerNumber": 0 83 | }, 84 | { 85 | "Id": 7, 86 | "Alive": true, 87 | "X": 6, 88 | "Y": 0, 89 | "Width": 1, 90 | "Height": 1, 91 | "Type": "Wall", 92 | "PlayerNumber": 0 93 | }, 94 | { 95 | "Id": 8, 96 | "Alive": true, 97 | "X": 7, 98 | "Y": 0, 99 | "Width": 1, 100 | "Height": 1, 101 | "Type": "Wall", 102 | "PlayerNumber": 0 103 | }, 104 | { 105 | "Id": 9, 106 | "Alive": true, 107 | "X": 8, 108 | "Y": 0, 109 | "Width": 1, 110 | "Height": 1, 111 | "Type": "Wall", 112 | "PlayerNumber": 0 113 | }, 114 | { 115 | "Id": 10, 116 | "Alive": true, 117 | "X": 9, 118 | "Y": 0, 119 | "Width": 1, 120 | "Height": 1, 121 | "Type": "Wall", 122 | "PlayerNumber": 0 123 | }, 124 | { 125 | "Id": 11, 126 | "Alive": true, 127 | "X": 10, 128 | "Y": 0, 129 | "Width": 1, 130 | "Height": 1, 131 | "Type": "Wall", 132 | "PlayerNumber": 0 133 | }, 134 | { 135 | "Id": 12, 136 | "Alive": true, 137 | "X": 11, 138 | "Y": 0, 139 | "Width": 1, 140 | "Height": 1, 141 | "Type": "Wall", 142 | "PlayerNumber": 0 143 | }, 144 | { 145 | "Id": 13, 146 | "Alive": true, 147 | "X": 12, 148 | "Y": 0, 149 | "Width": 1, 150 | "Height": 1, 151 | "Type": "Wall", 152 | "PlayerNumber": 0 153 | }, 154 | { 155 | "Id": 14, 156 | "Alive": true, 157 | "X": 13, 158 | "Y": 0, 159 | "Width": 1, 160 | "Height": 1, 161 | "Type": "Wall", 162 | "PlayerNumber": 0 163 | }, 164 | { 165 | "Id": 15, 166 | "Alive": true, 167 | "X": 14, 168 | "Y": 0, 169 | "Width": 1, 170 | "Height": 1, 171 | "Type": "Wall", 172 | "PlayerNumber": 0 173 | }, 174 | { 175 | "Id": 16, 176 | "Alive": true, 177 | "X": 15, 178 | "Y": 0, 179 | "Width": 1, 180 | "Height": 1, 181 | "Type": "Wall", 182 | "PlayerNumber": 0 183 | }, 184 | { 185 | "Id": 17, 186 | "Alive": true, 187 | "X": 16, 188 | "Y": 0, 189 | "Width": 1, 190 | "Height": 1, 191 | "Type": "Wall", 192 | "PlayerNumber": 0 193 | }, 194 | { 195 | "Id": 18, 196 | "Alive": true, 197 | "X": 17, 198 | "Y": 0, 199 | "Width": 1, 200 | "Height": 1, 201 | "Type": "Wall", 202 | "PlayerNumber": 0 203 | }, 204 | { 205 | "Id": 19, 206 | "Alive": true, 207 | "X": 18, 208 | "Y": 0, 209 | "Width": 1, 210 | "Height": 1, 211 | "Type": "Wall", 212 | "PlayerNumber": 0 213 | } 214 | ], 215 | [ 216 | { 217 | "Id": 20, 218 | "Alive": true, 219 | "X": 0, 220 | "Y": 1, 221 | "Width": 1, 222 | "Height": 1, 223 | "Type": "Wall", 224 | "PlayerNumber": 0 225 | }, 226 | null, 227 | null, 228 | null, 229 | null, 230 | null, 231 | null, 232 | null, 233 | { 234 | "LivesCost": 1, 235 | "Id": 129, 236 | "Alive": true, 237 | "X": 8, 238 | "Y": 1, 239 | "Width": 3, 240 | "Height": 1, 241 | "Type": "AlienFactory", 242 | "PlayerNumber": 2 243 | }, 244 | { 245 | "LivesCost": 1, 246 | "Id": 129, 247 | "Alive": true, 248 | "X": 8, 249 | "Y": 1, 250 | "Width": 3, 251 | "Height": 1, 252 | "Type": "AlienFactory", 253 | "PlayerNumber": 2 254 | }, 255 | { 256 | "LivesCost": 1, 257 | "Id": 129, 258 | "Alive": true, 259 | "X": 8, 260 | "Y": 1, 261 | "Width": 3, 262 | "Height": 1, 263 | "Type": "AlienFactory", 264 | "PlayerNumber": 2 265 | }, 266 | null, 267 | null, 268 | null, 269 | null, 270 | null, 271 | null, 272 | null, 273 | { 274 | "Id": 21, 275 | "Alive": true, 276 | "X": 18, 277 | "Y": 1, 278 | "Width": 1, 279 | "Height": 1, 280 | "Type": "Wall", 281 | "PlayerNumber": 0 282 | } 283 | ], 284 | [ 285 | { 286 | "Id": 22, 287 | "Alive": true, 288 | "X": 0, 289 | "Y": 2, 290 | "Width": 1, 291 | "Height": 1, 292 | "Type": "Wall", 293 | "PlayerNumber": 0 294 | }, 295 | null, 296 | null, 297 | null, 298 | null, 299 | null, 300 | null, 301 | null, 302 | null, 303 | { 304 | "Command": "Nothing", 305 | "CommandFeedback": "Fired a missile.", 306 | "Id": 86, 307 | "Alive": true, 308 | "X": 9, 309 | "Y": 2, 310 | "Width": 3, 311 | "Height": 1, 312 | "Type": "Ship", 313 | "PlayerNumber": 2 314 | }, 315 | { 316 | "Command": "Nothing", 317 | "CommandFeedback": "Fired a missile.", 318 | "Id": 86, 319 | "Alive": true, 320 | "X": 9, 321 | "Y": 2, 322 | "Width": 3, 323 | "Height": 1, 324 | "Type": "Ship", 325 | "PlayerNumber": 2 326 | }, 327 | { 328 | "Command": "Nothing", 329 | "CommandFeedback": "Fired a missile.", 330 | "Id": 86, 331 | "Alive": true, 332 | "X": 9, 333 | "Y": 2, 334 | "Width": 3, 335 | "Height": 1, 336 | "Type": "Ship", 337 | "PlayerNumber": 2 338 | }, 339 | null, 340 | null, 341 | null, 342 | null, 343 | null, 344 | null, 345 | { 346 | "Id": 23, 347 | "Alive": true, 348 | "X": 18, 349 | "Y": 2, 350 | "Width": 1, 351 | "Height": 1, 352 | "Type": "Wall", 353 | "PlayerNumber": 0 354 | } 355 | ], 356 | [ 357 | { 358 | "Id": 24, 359 | "Alive": true, 360 | "X": 0, 361 | "Y": 3, 362 | "Width": 1, 363 | "Height": 1, 364 | "Type": "Wall", 365 | "PlayerNumber": 0 366 | }, 367 | null, 368 | { 369 | "Id": 105, 370 | "Alive": true, 371 | "X": 2, 372 | "Y": 3, 373 | "Width": 1, 374 | "Height": 1, 375 | "Type": "Shield", 376 | "PlayerNumber": 2 377 | }, 378 | { 379 | "Id": 108, 380 | "Alive": true, 381 | "X": 3, 382 | "Y": 3, 383 | "Width": 1, 384 | "Height": 1, 385 | "Type": "Shield", 386 | "PlayerNumber": 2 387 | }, 388 | { 389 | "Id": 111, 390 | "Alive": true, 391 | "X": 4, 392 | "Y": 3, 393 | "Width": 1, 394 | "Height": 1, 395 | "Type": "Shield", 396 | "PlayerNumber": 2 397 | }, 398 | null, 399 | null, 400 | { 401 | "Id": 132, 402 | "Alive": true, 403 | "X": 7, 404 | "Y": 3, 405 | "Width": 1, 406 | "Height": 1, 407 | "Type": "Shield", 408 | "PlayerNumber": 2 409 | }, 410 | { 411 | "Id": 135, 412 | "Alive": true, 413 | "X": 8, 414 | "Y": 3, 415 | "Width": 1, 416 | "Height": 1, 417 | "Type": "Shield", 418 | "PlayerNumber": 2 419 | }, 420 | null, 421 | { 422 | "Id": 155, 423 | "Alive": true, 424 | "X": 10, 425 | "Y": 3, 426 | "Width": 1, 427 | "Height": 1, 428 | "Type": "Missile", 429 | "PlayerNumber": 2 430 | }, 431 | null, 432 | null, 433 | null, 434 | { 435 | "Id": 114, 436 | "Alive": true, 437 | "X": 14, 438 | "Y": 3, 439 | "Width": 1, 440 | "Height": 1, 441 | "Type": "Shield", 442 | "PlayerNumber": 2 443 | }, 444 | { 445 | "Id": 117, 446 | "Alive": true, 447 | "X": 15, 448 | "Y": 3, 449 | "Width": 1, 450 | "Height": 1, 451 | "Type": "Shield", 452 | "PlayerNumber": 2 453 | }, 454 | { 455 | "Id": 120, 456 | "Alive": true, 457 | "X": 16, 458 | "Y": 3, 459 | "Width": 1, 460 | "Height": 1, 461 | "Type": "Shield", 462 | "PlayerNumber": 2 463 | }, 464 | null, 465 | { 466 | "Id": 25, 467 | "Alive": true, 468 | "X": 18, 469 | "Y": 3, 470 | "Width": 1, 471 | "Height": 1, 472 | "Type": "Wall", 473 | "PlayerNumber": 0 474 | } 475 | ], 476 | [ 477 | { 478 | "Id": 26, 479 | "Alive": true, 480 | "X": 0, 481 | "Y": 4, 482 | "Width": 1, 483 | "Height": 1, 484 | "Type": "Wall", 485 | "PlayerNumber": 0 486 | }, 487 | null, 488 | { 489 | "Id": 106, 490 | "Alive": true, 491 | "X": 2, 492 | "Y": 4, 493 | "Width": 1, 494 | "Height": 1, 495 | "Type": "Shield", 496 | "PlayerNumber": 2 497 | }, 498 | { 499 | "Id": 109, 500 | "Alive": true, 501 | "X": 3, 502 | "Y": 4, 503 | "Width": 1, 504 | "Height": 1, 505 | "Type": "Shield", 506 | "PlayerNumber": 2 507 | }, 508 | { 509 | "Id": 112, 510 | "Alive": true, 511 | "X": 4, 512 | "Y": 4, 513 | "Width": 1, 514 | "Height": 1, 515 | "Type": "Shield", 516 | "PlayerNumber": 2 517 | }, 518 | { 519 | "Id": 141, 520 | "Alive": true, 521 | "X": 5, 522 | "Y": 4, 523 | "Width": 1, 524 | "Height": 1, 525 | "Type": "Bullet", 526 | "PlayerNumber": 1 527 | }, 528 | null, 529 | { 530 | "Id": 133, 531 | "Alive": true, 532 | "X": 7, 533 | "Y": 4, 534 | "Width": 1, 535 | "Height": 1, 536 | "Type": "Shield", 537 | "PlayerNumber": 2 538 | }, 539 | { 540 | "Id": 136, 541 | "Alive": true, 542 | "X": 8, 543 | "Y": 4, 544 | "Width": 1, 545 | "Height": 1, 546 | "Type": "Shield", 547 | "PlayerNumber": 2 548 | }, 549 | { 550 | "Id": 139, 551 | "Alive": true, 552 | "X": 9, 553 | "Y": 4, 554 | "Width": 1, 555 | "Height": 1, 556 | "Type": "Shield", 557 | "PlayerNumber": 2 558 | }, 559 | null, 560 | null, 561 | null, 562 | null, 563 | { 564 | "Id": 115, 565 | "Alive": true, 566 | "X": 14, 567 | "Y": 4, 568 | "Width": 1, 569 | "Height": 1, 570 | "Type": "Shield", 571 | "PlayerNumber": 2 572 | }, 573 | { 574 | "Id": 118, 575 | "Alive": true, 576 | "X": 15, 577 | "Y": 4, 578 | "Width": 1, 579 | "Height": 1, 580 | "Type": "Shield", 581 | "PlayerNumber": 2 582 | }, 583 | { 584 | "Id": 121, 585 | "Alive": true, 586 | "X": 16, 587 | "Y": 4, 588 | "Width": 1, 589 | "Height": 1, 590 | "Type": "Shield", 591 | "PlayerNumber": 2 592 | }, 593 | null, 594 | { 595 | "Id": 27, 596 | "Alive": true, 597 | "X": 18, 598 | "Y": 4, 599 | "Width": 1, 600 | "Height": 1, 601 | "Type": "Wall", 602 | "PlayerNumber": 0 603 | } 604 | ], 605 | [ 606 | { 607 | "Id": 28, 608 | "Alive": true, 609 | "X": 0, 610 | "Y": 5, 611 | "Width": 1, 612 | "Height": 1, 613 | "Type": "Wall", 614 | "PlayerNumber": 0 615 | }, 616 | null, 617 | { 618 | "Id": 107, 619 | "Alive": true, 620 | "X": 2, 621 | "Y": 5, 622 | "Width": 1, 623 | "Height": 1, 624 | "Type": "Shield", 625 | "PlayerNumber": 2 626 | }, 627 | { 628 | "Id": 110, 629 | "Alive": true, 630 | "X": 3, 631 | "Y": 5, 632 | "Width": 1, 633 | "Height": 1, 634 | "Type": "Shield", 635 | "PlayerNumber": 2 636 | }, 637 | { 638 | "Id": 113, 639 | "Alive": true, 640 | "X": 4, 641 | "Y": 5, 642 | "Width": 1, 643 | "Height": 1, 644 | "Type": "Shield", 645 | "PlayerNumber": 2 646 | }, 647 | null, 648 | null, 649 | { 650 | "Id": 134, 651 | "Alive": true, 652 | "X": 7, 653 | "Y": 5, 654 | "Width": 1, 655 | "Height": 1, 656 | "Type": "Shield", 657 | "PlayerNumber": 2 658 | }, 659 | { 660 | "Id": 137, 661 | "Alive": true, 662 | "X": 8, 663 | "Y": 5, 664 | "Width": 1, 665 | "Height": 1, 666 | "Type": "Shield", 667 | "PlayerNumber": 2 668 | }, 669 | { 670 | "Id": 140, 671 | "Alive": true, 672 | "X": 9, 673 | "Y": 5, 674 | "Width": 1, 675 | "Height": 1, 676 | "Type": "Shield", 677 | "PlayerNumber": 2 678 | }, 679 | null, 680 | null, 681 | null, 682 | null, 683 | { 684 | "Id": 116, 685 | "Alive": true, 686 | "X": 14, 687 | "Y": 5, 688 | "Width": 1, 689 | "Height": 1, 690 | "Type": "Shield", 691 | "PlayerNumber": 2 692 | }, 693 | { 694 | "Id": 119, 695 | "Alive": true, 696 | "X": 15, 697 | "Y": 5, 698 | "Width": 1, 699 | "Height": 1, 700 | "Type": "Shield", 701 | "PlayerNumber": 2 702 | }, 703 | { 704 | "Id": 122, 705 | "Alive": true, 706 | "X": 16, 707 | "Y": 5, 708 | "Width": 1, 709 | "Height": 1, 710 | "Type": "Shield", 711 | "PlayerNumber": 2 712 | }, 713 | null, 714 | { 715 | "Id": 29, 716 | "Alive": true, 717 | "X": 18, 718 | "Y": 5, 719 | "Width": 1, 720 | "Height": 1, 721 | "Type": "Wall", 722 | "PlayerNumber": 0 723 | } 724 | ], 725 | [ 726 | { 727 | "Id": 30, 728 | "Alive": true, 729 | "X": 0, 730 | "Y": 6, 731 | "Width": 1, 732 | "Height": 1, 733 | "Type": "Wall", 734 | "PlayerNumber": 0 735 | }, 736 | null, 737 | null, 738 | null, 739 | null, 740 | null, 741 | null, 742 | null, 743 | null, 744 | null, 745 | null, 746 | null, 747 | null, 748 | null, 749 | null, 750 | null, 751 | null, 752 | null, 753 | { 754 | "Id": 31, 755 | "Alive": true, 756 | "X": 18, 757 | "Y": 6, 758 | "Width": 1, 759 | "Height": 1, 760 | "Type": "Wall", 761 | "PlayerNumber": 0 762 | } 763 | ], 764 | [ 765 | { 766 | "Id": 32, 767 | "Alive": true, 768 | "X": 0, 769 | "Y": 7, 770 | "Width": 1, 771 | "Height": 1, 772 | "Type": "Wall", 773 | "PlayerNumber": 0 774 | }, 775 | null, 776 | null, 777 | null, 778 | null, 779 | null, 780 | null, 781 | null, 782 | null, 783 | null, 784 | null, 785 | null, 786 | null, 787 | null, 788 | null, 789 | null, 790 | null, 791 | null, 792 | { 793 | "Id": 33, 794 | "Alive": true, 795 | "X": 18, 796 | "Y": 7, 797 | "Width": 1, 798 | "Height": 1, 799 | "Type": "Wall", 800 | "PlayerNumber": 0 801 | } 802 | ], 803 | [ 804 | { 805 | "Id": 34, 806 | "Alive": true, 807 | "X": 0, 808 | "Y": 8, 809 | "Width": 1, 810 | "Height": 1, 811 | "Type": "Wall", 812 | "PlayerNumber": 0 813 | }, 814 | null, 815 | null, 816 | null, 817 | null, 818 | null, 819 | null, 820 | null, 821 | null, 822 | null, 823 | null, 824 | null, 825 | null, 826 | null, 827 | null, 828 | null, 829 | null, 830 | null, 831 | { 832 | "Id": 35, 833 | "Alive": true, 834 | "X": 18, 835 | "Y": 8, 836 | "Width": 1, 837 | "Height": 1, 838 | "Type": "Wall", 839 | "PlayerNumber": 0 840 | } 841 | ], 842 | [ 843 | { 844 | "Id": 36, 845 | "Alive": true, 846 | "X": 0, 847 | "Y": 9, 848 | "Width": 1, 849 | "Height": 1, 850 | "Type": "Wall", 851 | "PlayerNumber": 0 852 | }, 853 | null, 854 | { 855 | "Id": 144, 856 | "Alive": true, 857 | "X": 2, 858 | "Y": 9, 859 | "Width": 1, 860 | "Height": 1, 861 | "Type": "Bullet", 862 | "PlayerNumber": 1 863 | }, 864 | null, 865 | null, 866 | null, 867 | null, 868 | null, 869 | null, 870 | null, 871 | null, 872 | null, 873 | null, 874 | null, 875 | null, 876 | null, 877 | null, 878 | null, 879 | { 880 | "Id": 37, 881 | "Alive": true, 882 | "X": 18, 883 | "Y": 9, 884 | "Width": 1, 885 | "Height": 1, 886 | "Type": "Wall", 887 | "PlayerNumber": 0 888 | } 889 | ], 890 | [ 891 | { 892 | "Id": 38, 893 | "Alive": true, 894 | "X": 0, 895 | "Y": 10, 896 | "Width": 1, 897 | "Height": 1, 898 | "Type": "Wall", 899 | "PlayerNumber": 0 900 | }, 901 | null, 902 | { 903 | "Id": 125, 904 | "Alive": true, 905 | "X": 2, 906 | "Y": 10, 907 | "Width": 1, 908 | "Height": 1, 909 | "Type": "Alien", 910 | "PlayerNumber": 1 911 | }, 912 | null, 913 | null, 914 | { 915 | "Id": 124, 916 | "Alive": true, 917 | "X": 5, 918 | "Y": 10, 919 | "Width": 1, 920 | "Height": 1, 921 | "Type": "Alien", 922 | "PlayerNumber": 1 923 | }, 924 | null, 925 | null, 926 | { 927 | "Id": 123, 928 | "Alive": true, 929 | "X": 8, 930 | "Y": 10, 931 | "Width": 1, 932 | "Height": 1, 933 | "Type": "Alien", 934 | "PlayerNumber": 1 935 | }, 936 | null, 937 | null, 938 | null, 939 | null, 940 | null, 941 | null, 942 | null, 943 | null, 944 | null, 945 | { 946 | "Id": 39, 947 | "Alive": true, 948 | "X": 18, 949 | "Y": 10, 950 | "Width": 1, 951 | "Height": 1, 952 | "Type": "Wall", 953 | "PlayerNumber": 0 954 | } 955 | ], 956 | [ 957 | { 958 | "Id": 40, 959 | "Alive": true, 960 | "X": 0, 961 | "Y": 11, 962 | "Width": 1, 963 | "Height": 1, 964 | "Type": "Wall", 965 | "PlayerNumber": 0 966 | }, 967 | null, 968 | null, 969 | null, 970 | null, 971 | null, 972 | null, 973 | null, 974 | null, 975 | null, 976 | null, 977 | null, 978 | null, 979 | null, 980 | null, 981 | null, 982 | null, 983 | null, 984 | { 985 | "Id": 41, 986 | "Alive": true, 987 | "X": 18, 988 | "Y": 11, 989 | "Width": 1, 990 | "Height": 1, 991 | "Type": "Wall", 992 | "PlayerNumber": 0 993 | } 994 | ], 995 | [ 996 | { 997 | "Id": 42, 998 | "Alive": true, 999 | "X": 0, 1000 | "Y": 12, 1001 | "Width": 1, 1002 | "Height": 1, 1003 | "Type": "Wall", 1004 | "PlayerNumber": 0 1005 | }, 1006 | null, 1007 | null, 1008 | null, 1009 | null, 1010 | null, 1011 | null, 1012 | null, 1013 | null, 1014 | { 1015 | "Id": 130, 1016 | "Alive": true, 1017 | "X": 9, 1018 | "Y": 12, 1019 | "Width": 1, 1020 | "Height": 1, 1021 | "Type": "Missile", 1022 | "PlayerNumber": 1 1023 | }, 1024 | null, 1025 | null, 1026 | null, 1027 | null, 1028 | null, 1029 | null, 1030 | null, 1031 | null, 1032 | { 1033 | "Id": 43, 1034 | "Alive": true, 1035 | "X": 18, 1036 | "Y": 12, 1037 | "Width": 1, 1038 | "Height": 1, 1039 | "Type": "Wall", 1040 | "PlayerNumber": 0 1041 | } 1042 | ], 1043 | [ 1044 | { 1045 | "Id": 44, 1046 | "Alive": true, 1047 | "X": 0, 1048 | "Y": 13, 1049 | "Width": 1, 1050 | "Height": 1, 1051 | "Type": "Wall", 1052 | "PlayerNumber": 0 1053 | }, 1054 | null, 1055 | null, 1056 | null, 1057 | null, 1058 | null, 1059 | null, 1060 | null, 1061 | null, 1062 | null, 1063 | null, 1064 | null, 1065 | null, 1066 | null, 1067 | null, 1068 | null, 1069 | null, 1070 | null, 1071 | { 1072 | "Id": 45, 1073 | "Alive": true, 1074 | "X": 18, 1075 | "Y": 13, 1076 | "Width": 1, 1077 | "Height": 1, 1078 | "Type": "Wall", 1079 | "PlayerNumber": 0 1080 | } 1081 | ], 1082 | [ 1083 | { 1084 | "Id": 46, 1085 | "Alive": true, 1086 | "X": 0, 1087 | "Y": 14, 1088 | "Width": 1, 1089 | "Height": 1, 1090 | "Type": "Wall", 1091 | "PlayerNumber": 0 1092 | }, 1093 | null, 1094 | { 1095 | "Id": 128, 1096 | "Alive": true, 1097 | "X": 2, 1098 | "Y": 14, 1099 | "Width": 1, 1100 | "Height": 1, 1101 | "Type": "Alien", 1102 | "PlayerNumber": 2 1103 | }, 1104 | null, 1105 | null, 1106 | { 1107 | "Id": 127, 1108 | "Alive": true, 1109 | "X": 5, 1110 | "Y": 14, 1111 | "Width": 1, 1112 | "Height": 1, 1113 | "Type": "Alien", 1114 | "PlayerNumber": 2 1115 | }, 1116 | null, 1117 | null, 1118 | { 1119 | "Id": 126, 1120 | "Alive": true, 1121 | "X": 8, 1122 | "Y": 14, 1123 | "Width": 1, 1124 | "Height": 1, 1125 | "Type": "Alien", 1126 | "PlayerNumber": 2 1127 | }, 1128 | null, 1129 | null, 1130 | null, 1131 | null, 1132 | null, 1133 | null, 1134 | null, 1135 | null, 1136 | null, 1137 | { 1138 | "Id": 47, 1139 | "Alive": true, 1140 | "X": 18, 1141 | "Y": 14, 1142 | "Width": 1, 1143 | "Height": 1, 1144 | "Type": "Wall", 1145 | "PlayerNumber": 0 1146 | } 1147 | ], 1148 | [ 1149 | { 1150 | "Id": 48, 1151 | "Alive": true, 1152 | "X": 0, 1153 | "Y": 15, 1154 | "Width": 1, 1155 | "Height": 1, 1156 | "Type": "Wall", 1157 | "PlayerNumber": 0 1158 | }, 1159 | null, 1160 | { 1161 | "Id": 145, 1162 | "Alive": true, 1163 | "X": 2, 1164 | "Y": 15, 1165 | "Width": 1, 1166 | "Height": 1, 1167 | "Type": "Bullet", 1168 | "PlayerNumber": 2 1169 | }, 1170 | null, 1171 | null, 1172 | null, 1173 | null, 1174 | null, 1175 | null, 1176 | null, 1177 | null, 1178 | null, 1179 | null, 1180 | null, 1181 | null, 1182 | null, 1183 | null, 1184 | null, 1185 | { 1186 | "Id": 49, 1187 | "Alive": true, 1188 | "X": 18, 1189 | "Y": 15, 1190 | "Width": 1, 1191 | "Height": 1, 1192 | "Type": "Wall", 1193 | "PlayerNumber": 0 1194 | } 1195 | ], 1196 | [ 1197 | { 1198 | "Id": 50, 1199 | "Alive": true, 1200 | "X": 0, 1201 | "Y": 16, 1202 | "Width": 1, 1203 | "Height": 1, 1204 | "Type": "Wall", 1205 | "PlayerNumber": 0 1206 | }, 1207 | null, 1208 | null, 1209 | null, 1210 | null, 1211 | null, 1212 | null, 1213 | null, 1214 | null, 1215 | null, 1216 | null, 1217 | null, 1218 | null, 1219 | null, 1220 | null, 1221 | null, 1222 | null, 1223 | null, 1224 | { 1225 | "Id": 51, 1226 | "Alive": true, 1227 | "X": 18, 1228 | "Y": 16, 1229 | "Width": 1, 1230 | "Height": 1, 1231 | "Type": "Wall", 1232 | "PlayerNumber": 0 1233 | } 1234 | ], 1235 | [ 1236 | { 1237 | "Id": 52, 1238 | "Alive": true, 1239 | "X": 0, 1240 | "Y": 17, 1241 | "Width": 1, 1242 | "Height": 1, 1243 | "Type": "Wall", 1244 | "PlayerNumber": 0 1245 | }, 1246 | null, 1247 | null, 1248 | null, 1249 | null, 1250 | null, 1251 | null, 1252 | null, 1253 | null, 1254 | null, 1255 | null, 1256 | null, 1257 | null, 1258 | null, 1259 | null, 1260 | null, 1261 | null, 1262 | null, 1263 | { 1264 | "Id": 53, 1265 | "Alive": true, 1266 | "X": 18, 1267 | "Y": 17, 1268 | "Width": 1, 1269 | "Height": 1, 1270 | "Type": "Wall", 1271 | "PlayerNumber": 0 1272 | } 1273 | ], 1274 | [ 1275 | { 1276 | "Id": 54, 1277 | "Alive": true, 1278 | "X": 0, 1279 | "Y": 18, 1280 | "Width": 1, 1281 | "Height": 1, 1282 | "Type": "Wall", 1283 | "PlayerNumber": 0 1284 | }, 1285 | null, 1286 | null, 1287 | null, 1288 | null, 1289 | null, 1290 | null, 1291 | null, 1292 | null, 1293 | null, 1294 | null, 1295 | null, 1296 | null, 1297 | null, 1298 | null, 1299 | null, 1300 | null, 1301 | null, 1302 | { 1303 | "Id": 55, 1304 | "Alive": true, 1305 | "X": 18, 1306 | "Y": 18, 1307 | "Width": 1, 1308 | "Height": 1, 1309 | "Type": "Wall", 1310 | "PlayerNumber": 0 1311 | } 1312 | ], 1313 | [ 1314 | { 1315 | "Id": 56, 1316 | "Alive": true, 1317 | "X": 0, 1318 | "Y": 19, 1319 | "Width": 1, 1320 | "Height": 1, 1321 | "Type": "Wall", 1322 | "PlayerNumber": 0 1323 | }, 1324 | null, 1325 | { 1326 | "Id": 89, 1327 | "Alive": true, 1328 | "X": 2, 1329 | "Y": 19, 1330 | "Width": 1, 1331 | "Height": 1, 1332 | "Type": "Shield", 1333 | "PlayerNumber": 1 1334 | }, 1335 | { 1336 | "Id": 92, 1337 | "Alive": true, 1338 | "X": 3, 1339 | "Y": 19, 1340 | "Width": 1, 1341 | "Height": 1, 1342 | "Type": "Shield", 1343 | "PlayerNumber": 1 1344 | }, 1345 | { 1346 | "Id": 95, 1347 | "Alive": true, 1348 | "X": 4, 1349 | "Y": 19, 1350 | "Width": 1, 1351 | "Height": 1, 1352 | "Type": "Shield", 1353 | "PlayerNumber": 1 1354 | }, 1355 | null, 1356 | null, 1357 | { 1358 | "Id": 148, 1359 | "Alive": true, 1360 | "X": 7, 1361 | "Y": 19, 1362 | "Width": 1, 1363 | "Height": 1, 1364 | "Type": "Shield", 1365 | "PlayerNumber": 1 1366 | }, 1367 | { 1368 | "Id": 151, 1369 | "Alive": true, 1370 | "X": 8, 1371 | "Y": 19, 1372 | "Width": 1, 1373 | "Height": 1, 1374 | "Type": "Shield", 1375 | "PlayerNumber": 1 1376 | }, 1377 | { 1378 | "Id": 154, 1379 | "Alive": true, 1380 | "X": 9, 1381 | "Y": 19, 1382 | "Width": 1, 1383 | "Height": 1, 1384 | "Type": "Shield", 1385 | "PlayerNumber": 1 1386 | }, 1387 | null, 1388 | null, 1389 | null, 1390 | null, 1391 | { 1392 | "Id": 98, 1393 | "Alive": true, 1394 | "X": 14, 1395 | "Y": 19, 1396 | "Width": 1, 1397 | "Height": 1, 1398 | "Type": "Shield", 1399 | "PlayerNumber": 1 1400 | }, 1401 | { 1402 | "Id": 101, 1403 | "Alive": true, 1404 | "X": 15, 1405 | "Y": 19, 1406 | "Width": 1, 1407 | "Height": 1, 1408 | "Type": "Shield", 1409 | "PlayerNumber": 1 1410 | }, 1411 | { 1412 | "Id": 104, 1413 | "Alive": true, 1414 | "X": 16, 1415 | "Y": 19, 1416 | "Width": 1, 1417 | "Height": 1, 1418 | "Type": "Shield", 1419 | "PlayerNumber": 1 1420 | }, 1421 | null, 1422 | { 1423 | "Id": 57, 1424 | "Alive": true, 1425 | "X": 18, 1426 | "Y": 19, 1427 | "Width": 1, 1428 | "Height": 1, 1429 | "Type": "Wall", 1430 | "PlayerNumber": 0 1431 | } 1432 | ], 1433 | [ 1434 | { 1435 | "Id": 58, 1436 | "Alive": true, 1437 | "X": 0, 1438 | "Y": 20, 1439 | "Width": 1, 1440 | "Height": 1, 1441 | "Type": "Wall", 1442 | "PlayerNumber": 0 1443 | }, 1444 | null, 1445 | { 1446 | "Id": 88, 1447 | "Alive": true, 1448 | "X": 2, 1449 | "Y": 20, 1450 | "Width": 1, 1451 | "Height": 1, 1452 | "Type": "Shield", 1453 | "PlayerNumber": 1 1454 | }, 1455 | { 1456 | "Id": 91, 1457 | "Alive": true, 1458 | "X": 3, 1459 | "Y": 20, 1460 | "Width": 1, 1461 | "Height": 1, 1462 | "Type": "Shield", 1463 | "PlayerNumber": 1 1464 | }, 1465 | { 1466 | "Id": 94, 1467 | "Alive": true, 1468 | "X": 4, 1469 | "Y": 20, 1470 | "Width": 1, 1471 | "Height": 1, 1472 | "Type": "Shield", 1473 | "PlayerNumber": 1 1474 | }, 1475 | { 1476 | "Id": 142, 1477 | "Alive": true, 1478 | "X": 5, 1479 | "Y": 20, 1480 | "Width": 1, 1481 | "Height": 1, 1482 | "Type": "Bullet", 1483 | "PlayerNumber": 2 1484 | }, 1485 | null, 1486 | { 1487 | "Id": 147, 1488 | "Alive": true, 1489 | "X": 7, 1490 | "Y": 20, 1491 | "Width": 1, 1492 | "Height": 1, 1493 | "Type": "Shield", 1494 | "PlayerNumber": 1 1495 | }, 1496 | { 1497 | "Id": 150, 1498 | "Alive": true, 1499 | "X": 8, 1500 | "Y": 20, 1501 | "Width": 1, 1502 | "Height": 1, 1503 | "Type": "Shield", 1504 | "PlayerNumber": 1 1505 | }, 1506 | { 1507 | "Id": 153, 1508 | "Alive": true, 1509 | "X": 9, 1510 | "Y": 20, 1511 | "Width": 1, 1512 | "Height": 1, 1513 | "Type": "Shield", 1514 | "PlayerNumber": 1 1515 | }, 1516 | null, 1517 | null, 1518 | null, 1519 | null, 1520 | { 1521 | "Id": 97, 1522 | "Alive": true, 1523 | "X": 14, 1524 | "Y": 20, 1525 | "Width": 1, 1526 | "Height": 1, 1527 | "Type": "Shield", 1528 | "PlayerNumber": 1 1529 | }, 1530 | { 1531 | "Id": 100, 1532 | "Alive": true, 1533 | "X": 15, 1534 | "Y": 20, 1535 | "Width": 1, 1536 | "Height": 1, 1537 | "Type": "Shield", 1538 | "PlayerNumber": 1 1539 | }, 1540 | { 1541 | "Id": 103, 1542 | "Alive": true, 1543 | "X": 16, 1544 | "Y": 20, 1545 | "Width": 1, 1546 | "Height": 1, 1547 | "Type": "Shield", 1548 | "PlayerNumber": 1 1549 | }, 1550 | null, 1551 | { 1552 | "Id": 59, 1553 | "Alive": true, 1554 | "X": 18, 1555 | "Y": 20, 1556 | "Width": 1, 1557 | "Height": 1, 1558 | "Type": "Wall", 1559 | "PlayerNumber": 0 1560 | } 1561 | ], 1562 | [ 1563 | { 1564 | "Id": 60, 1565 | "Alive": true, 1566 | "X": 0, 1567 | "Y": 21, 1568 | "Width": 1, 1569 | "Height": 1, 1570 | "Type": "Wall", 1571 | "PlayerNumber": 0 1572 | }, 1573 | null, 1574 | { 1575 | "Id": 87, 1576 | "Alive": true, 1577 | "X": 2, 1578 | "Y": 21, 1579 | "Width": 1, 1580 | "Height": 1, 1581 | "Type": "Shield", 1582 | "PlayerNumber": 1 1583 | }, 1584 | { 1585 | "Id": 90, 1586 | "Alive": true, 1587 | "X": 3, 1588 | "Y": 21, 1589 | "Width": 1, 1590 | "Height": 1, 1591 | "Type": "Shield", 1592 | "PlayerNumber": 1 1593 | }, 1594 | { 1595 | "Id": 93, 1596 | "Alive": true, 1597 | "X": 4, 1598 | "Y": 21, 1599 | "Width": 1, 1600 | "Height": 1, 1601 | "Type": "Shield", 1602 | "PlayerNumber": 1 1603 | }, 1604 | null, 1605 | null, 1606 | { 1607 | "Id": 146, 1608 | "Alive": true, 1609 | "X": 7, 1610 | "Y": 21, 1611 | "Width": 1, 1612 | "Height": 1, 1613 | "Type": "Shield", 1614 | "PlayerNumber": 1 1615 | }, 1616 | { 1617 | "Id": 149, 1618 | "Alive": true, 1619 | "X": 8, 1620 | "Y": 21, 1621 | "Width": 1, 1622 | "Height": 1, 1623 | "Type": "Shield", 1624 | "PlayerNumber": 1 1625 | }, 1626 | { 1627 | "Id": 152, 1628 | "Alive": true, 1629 | "X": 9, 1630 | "Y": 21, 1631 | "Width": 1, 1632 | "Height": 1, 1633 | "Type": "Shield", 1634 | "PlayerNumber": 1 1635 | }, 1636 | null, 1637 | null, 1638 | null, 1639 | null, 1640 | { 1641 | "Id": 96, 1642 | "Alive": true, 1643 | "X": 14, 1644 | "Y": 21, 1645 | "Width": 1, 1646 | "Height": 1, 1647 | "Type": "Shield", 1648 | "PlayerNumber": 1 1649 | }, 1650 | { 1651 | "Id": 99, 1652 | "Alive": true, 1653 | "X": 15, 1654 | "Y": 21, 1655 | "Width": 1, 1656 | "Height": 1, 1657 | "Type": "Shield", 1658 | "PlayerNumber": 1 1659 | }, 1660 | { 1661 | "Id": 102, 1662 | "Alive": true, 1663 | "X": 16, 1664 | "Y": 21, 1665 | "Width": 1, 1666 | "Height": 1, 1667 | "Type": "Shield", 1668 | "PlayerNumber": 1 1669 | }, 1670 | null, 1671 | { 1672 | "Id": 61, 1673 | "Alive": true, 1674 | "X": 18, 1675 | "Y": 21, 1676 | "Width": 1, 1677 | "Height": 1, 1678 | "Type": "Wall", 1679 | "PlayerNumber": 0 1680 | } 1681 | ], 1682 | [ 1683 | { 1684 | "Id": 62, 1685 | "Alive": true, 1686 | "X": 0, 1687 | "Y": 22, 1688 | "Width": 1, 1689 | "Height": 1, 1690 | "Type": "Wall", 1691 | "PlayerNumber": 0 1692 | }, 1693 | null, 1694 | null, 1695 | null, 1696 | null, 1697 | null, 1698 | null, 1699 | { 1700 | "Command": "Nothing", 1701 | "CommandFeedback": "Built shields.", 1702 | "Id": 85, 1703 | "Alive": true, 1704 | "X": 7, 1705 | "Y": 22, 1706 | "Width": 3, 1707 | "Height": 1, 1708 | "Type": "Ship", 1709 | "PlayerNumber": 1 1710 | }, 1711 | { 1712 | "Command": "Nothing", 1713 | "CommandFeedback": "Built shields.", 1714 | "Id": 85, 1715 | "Alive": true, 1716 | "X": 7, 1717 | "Y": 22, 1718 | "Width": 3, 1719 | "Height": 1, 1720 | "Type": "Ship", 1721 | "PlayerNumber": 1 1722 | }, 1723 | { 1724 | "Command": "Nothing", 1725 | "CommandFeedback": "Built shields.", 1726 | "Id": 85, 1727 | "Alive": true, 1728 | "X": 7, 1729 | "Y": 22, 1730 | "Width": 3, 1731 | "Height": 1, 1732 | "Type": "Ship", 1733 | "PlayerNumber": 1 1734 | }, 1735 | null, 1736 | null, 1737 | null, 1738 | null, 1739 | null, 1740 | null, 1741 | null, 1742 | null, 1743 | { 1744 | "Id": 63, 1745 | "Alive": true, 1746 | "X": 18, 1747 | "Y": 22, 1748 | "Width": 1, 1749 | "Height": 1, 1750 | "Type": "Wall", 1751 | "PlayerNumber": 0 1752 | } 1753 | ], 1754 | [ 1755 | { 1756 | "Id": 64, 1757 | "Alive": true, 1758 | "X": 0, 1759 | "Y": 23, 1760 | "Width": 1, 1761 | "Height": 1, 1762 | "Type": "Wall", 1763 | "PlayerNumber": 0 1764 | }, 1765 | null, 1766 | null, 1767 | null, 1768 | null, 1769 | null, 1770 | null, 1771 | null, 1772 | { 1773 | "LivesCost": 1, 1774 | "Id": 131, 1775 | "Alive": true, 1776 | "X": 8, 1777 | "Y": 23, 1778 | "Width": 3, 1779 | "Height": 1, 1780 | "Type": "AlienFactory", 1781 | "PlayerNumber": 1 1782 | }, 1783 | { 1784 | "LivesCost": 1, 1785 | "Id": 131, 1786 | "Alive": true, 1787 | "X": 8, 1788 | "Y": 23, 1789 | "Width": 3, 1790 | "Height": 1, 1791 | "Type": "AlienFactory", 1792 | "PlayerNumber": 1 1793 | }, 1794 | { 1795 | "LivesCost": 1, 1796 | "Id": 131, 1797 | "Alive": true, 1798 | "X": 8, 1799 | "Y": 23, 1800 | "Width": 3, 1801 | "Height": 1, 1802 | "Type": "AlienFactory", 1803 | "PlayerNumber": 1 1804 | }, 1805 | null, 1806 | null, 1807 | null, 1808 | null, 1809 | null, 1810 | null, 1811 | null, 1812 | { 1813 | "Id": 65, 1814 | "Alive": true, 1815 | "X": 18, 1816 | "Y": 23, 1817 | "Width": 1, 1818 | "Height": 1, 1819 | "Type": "Wall", 1820 | "PlayerNumber": 0 1821 | } 1822 | ], 1823 | [ 1824 | { 1825 | "Id": 66, 1826 | "Alive": true, 1827 | "X": 0, 1828 | "Y": 24, 1829 | "Width": 1, 1830 | "Height": 1, 1831 | "Type": "Wall", 1832 | "PlayerNumber": 0 1833 | }, 1834 | { 1835 | "Id": 67, 1836 | "Alive": true, 1837 | "X": 1, 1838 | "Y": 24, 1839 | "Width": 1, 1840 | "Height": 1, 1841 | "Type": "Wall", 1842 | "PlayerNumber": 0 1843 | }, 1844 | { 1845 | "Id": 68, 1846 | "Alive": true, 1847 | "X": 2, 1848 | "Y": 24, 1849 | "Width": 1, 1850 | "Height": 1, 1851 | "Type": "Wall", 1852 | "PlayerNumber": 0 1853 | }, 1854 | { 1855 | "Id": 69, 1856 | "Alive": true, 1857 | "X": 3, 1858 | "Y": 24, 1859 | "Width": 1, 1860 | "Height": 1, 1861 | "Type": "Wall", 1862 | "PlayerNumber": 0 1863 | }, 1864 | { 1865 | "Id": 70, 1866 | "Alive": true, 1867 | "X": 4, 1868 | "Y": 24, 1869 | "Width": 1, 1870 | "Height": 1, 1871 | "Type": "Wall", 1872 | "PlayerNumber": 0 1873 | }, 1874 | { 1875 | "Id": 71, 1876 | "Alive": true, 1877 | "X": 5, 1878 | "Y": 24, 1879 | "Width": 1, 1880 | "Height": 1, 1881 | "Type": "Wall", 1882 | "PlayerNumber": 0 1883 | }, 1884 | { 1885 | "Id": 72, 1886 | "Alive": true, 1887 | "X": 6, 1888 | "Y": 24, 1889 | "Width": 1, 1890 | "Height": 1, 1891 | "Type": "Wall", 1892 | "PlayerNumber": 0 1893 | }, 1894 | { 1895 | "Id": 73, 1896 | "Alive": true, 1897 | "X": 7, 1898 | "Y": 24, 1899 | "Width": 1, 1900 | "Height": 1, 1901 | "Type": "Wall", 1902 | "PlayerNumber": 0 1903 | }, 1904 | { 1905 | "Id": 74, 1906 | "Alive": true, 1907 | "X": 8, 1908 | "Y": 24, 1909 | "Width": 1, 1910 | "Height": 1, 1911 | "Type": "Wall", 1912 | "PlayerNumber": 0 1913 | }, 1914 | { 1915 | "Id": 75, 1916 | "Alive": true, 1917 | "X": 9, 1918 | "Y": 24, 1919 | "Width": 1, 1920 | "Height": 1, 1921 | "Type": "Wall", 1922 | "PlayerNumber": 0 1923 | }, 1924 | { 1925 | "Id": 76, 1926 | "Alive": true, 1927 | "X": 10, 1928 | "Y": 24, 1929 | "Width": 1, 1930 | "Height": 1, 1931 | "Type": "Wall", 1932 | "PlayerNumber": 0 1933 | }, 1934 | { 1935 | "Id": 77, 1936 | "Alive": true, 1937 | "X": 11, 1938 | "Y": 24, 1939 | "Width": 1, 1940 | "Height": 1, 1941 | "Type": "Wall", 1942 | "PlayerNumber": 0 1943 | }, 1944 | { 1945 | "Id": 78, 1946 | "Alive": true, 1947 | "X": 12, 1948 | "Y": 24, 1949 | "Width": 1, 1950 | "Height": 1, 1951 | "Type": "Wall", 1952 | "PlayerNumber": 0 1953 | }, 1954 | { 1955 | "Id": 79, 1956 | "Alive": true, 1957 | "X": 13, 1958 | "Y": 24, 1959 | "Width": 1, 1960 | "Height": 1, 1961 | "Type": "Wall", 1962 | "PlayerNumber": 0 1963 | }, 1964 | { 1965 | "Id": 80, 1966 | "Alive": true, 1967 | "X": 14, 1968 | "Y": 24, 1969 | "Width": 1, 1970 | "Height": 1, 1971 | "Type": "Wall", 1972 | "PlayerNumber": 0 1973 | }, 1974 | { 1975 | "Id": 81, 1976 | "Alive": true, 1977 | "X": 15, 1978 | "Y": 24, 1979 | "Width": 1, 1980 | "Height": 1, 1981 | "Type": "Wall", 1982 | "PlayerNumber": 0 1983 | }, 1984 | { 1985 | "Id": 82, 1986 | "Alive": true, 1987 | "X": 16, 1988 | "Y": 24, 1989 | "Width": 1, 1990 | "Height": 1, 1991 | "Type": "Wall", 1992 | "PlayerNumber": 0 1993 | }, 1994 | { 1995 | "Id": 83, 1996 | "Alive": true, 1997 | "X": 17, 1998 | "Y": 24, 1999 | "Width": 1, 2000 | "Height": 1, 2001 | "Type": "Wall", 2002 | "PlayerNumber": 0 2003 | }, 2004 | { 2005 | "Id": 84, 2006 | "Alive": true, 2007 | "X": 18, 2008 | "Y": 24, 2009 | "Width": 1, 2010 | "Height": 1, 2011 | "Type": "Wall", 2012 | "PlayerNumber": 0 2013 | } 2014 | ] 2015 | ] 2016 | }, 2017 | "Players": [ 2018 | { 2019 | "PlayerNumberReal": 1, 2020 | "PlayerNumber": 1, 2021 | "PlayerName": "NodeSimpleton", 2022 | "Ship": { 2023 | "Command": "Nothing", 2024 | "CommandFeedback": "Built shields.", 2025 | "Id": 85, 2026 | "Alive": true, 2027 | "X": 7, 2028 | "Y": 22, 2029 | "Width": 3, 2030 | "Height": 1, 2031 | "Type": "Ship", 2032 | "PlayerNumber": 1 2033 | }, 2034 | "Kills": 0, 2035 | "Lives": 1, 2036 | "RespawnTimer": -1, 2037 | "Missiles": [ 2038 | { 2039 | "Id": 130, 2040 | "Alive": true, 2041 | "X": 9, 2042 | "Y": 12, 2043 | "Width": 1, 2044 | "Height": 1, 2045 | "Type": "Missile", 2046 | "PlayerNumber": 1 2047 | } 2048 | ], 2049 | "MissileLimit": 1, 2050 | "AlienWaveSize": 4, 2051 | "AlienFactory": { 2052 | "LivesCost": 1, 2053 | "Id": 131, 2054 | "Alive": true, 2055 | "X": 8, 2056 | "Y": 23, 2057 | "Width": 3, 2058 | "Height": 1, 2059 | "Type": "AlienFactory", 2060 | "PlayerNumber": 1 2061 | }, 2062 | "MissileController": null, 2063 | "AlienManager": { 2064 | "PlayerNumber": 1, 2065 | "Disabled": false, 2066 | "Waves": [ 2067 | [ 2068 | { 2069 | "Id": 123, 2070 | "Alive": true, 2071 | "X": 8, 2072 | "Y": 10, 2073 | "Width": 1, 2074 | "Height": 1, 2075 | "Type": "Alien", 2076 | "PlayerNumber": 1 2077 | }, 2078 | { 2079 | "Id": 124, 2080 | "Alive": true, 2081 | "X": 5, 2082 | "Y": 10, 2083 | "Width": 1, 2084 | "Height": 1, 2085 | "Type": "Alien", 2086 | "PlayerNumber": 1 2087 | }, 2088 | { 2089 | "Id": 125, 2090 | "Alive": true, 2091 | "X": 2, 2092 | "Y": 10, 2093 | "Width": 1, 2094 | "Height": 1, 2095 | "Type": "Alien", 2096 | "PlayerNumber": 1 2097 | } 2098 | ] 2099 | ], 2100 | "ShotEnergyCost": 6, 2101 | "ShotEnergy": 0, 2102 | "DeltaX": 1 2103 | } 2104 | }, 2105 | { 2106 | "PlayerNumberReal": 2, 2107 | "PlayerNumber": 2, 2108 | "PlayerName": "NodeIdiot", 2109 | "Ship": { 2110 | "Command": "Nothing", 2111 | "CommandFeedback": "Fired a missile.", 2112 | "Id": 86, 2113 | "Alive": true, 2114 | "X": 9, 2115 | "Y": 2, 2116 | "Width": 3, 2117 | "Height": 1, 2118 | "Type": "Ship", 2119 | "PlayerNumber": 2 2120 | }, 2121 | "Kills": 0, 2122 | "Lives": 1, 2123 | "RespawnTimer": -1, 2124 | "Missiles": [ 2125 | { 2126 | "Id": 155, 2127 | "Alive": true, 2128 | "X": 10, 2129 | "Y": 3, 2130 | "Width": 1, 2131 | "Height": 1, 2132 | "Type": "Missile", 2133 | "PlayerNumber": 2 2134 | } 2135 | ], 2136 | "MissileLimit": 1, 2137 | "AlienWaveSize": 4, 2138 | "AlienFactory": { 2139 | "LivesCost": 1, 2140 | "Id": 129, 2141 | "Alive": true, 2142 | "X": 8, 2143 | "Y": 1, 2144 | "Width": 3, 2145 | "Height": 1, 2146 | "Type": "AlienFactory", 2147 | "PlayerNumber": 2 2148 | }, 2149 | "MissileController": null, 2150 | "AlienManager": { 2151 | "PlayerNumber": 2, 2152 | "Disabled": false, 2153 | "Waves": [ 2154 | [ 2155 | { 2156 | "Id": 126, 2157 | "Alive": true, 2158 | "X": 8, 2159 | "Y": 14, 2160 | "Width": 1, 2161 | "Height": 1, 2162 | "Type": "Alien", 2163 | "PlayerNumber": 2 2164 | }, 2165 | { 2166 | "Id": 127, 2167 | "Alive": true, 2168 | "X": 5, 2169 | "Y": 14, 2170 | "Width": 1, 2171 | "Height": 1, 2172 | "Type": "Alien", 2173 | "PlayerNumber": 2 2174 | }, 2175 | { 2176 | "Id": 128, 2177 | "Alive": true, 2178 | "X": 2, 2179 | "Y": 14, 2180 | "Width": 1, 2181 | "Height": 1, 2182 | "Type": "Alien", 2183 | "PlayerNumber": 2 2184 | } 2185 | ] 2186 | ], 2187 | "ShotEnergyCost": 6, 2188 | "ShotEnergy": 0, 2189 | "DeltaX": 1 2190 | } 2191 | } 2192 | ], 2193 | "RoundNumber": 12, 2194 | "RoundLimit": 200 2195 | } 2196 | --------------------------------------------------------------------------------