kolmafia / kolmafia
Showing 1 of 1 files from the diff.

@@ -33,7 +33,7 @@
Loading
33 33
  // engages in a combat with another castle in order to accumulate cheese.
34 34
  //
35 35
  // A Game has up to five Battles. You play until you are defeated or until
36 -
  // your fifth battle. Your score is the total cheese you gained.
36 +
  // you win the fifth battle. Your score is the total cheese you gained.
37 37
  //
38 38
  // Each Battle has two turns of preparation, where you attempt to improve
39 39
  // stats and/or gather cheese, and one round of combat.
@@ -44,28 +44,81 @@
Loading
44 44
  //
45 45
  // You can play up to 5 games per day.
46 46
  //
47 -
  // This module is intended to track the state over the course of a game:
48 -
  // initial stats, changes as you train them, cheese accumulated, and so
49 -
  // on. These will be made available in properties so that scripts can use
50 -
  // them without having to parse the response text for themselves. These
51 -
  // properties will be reset at the beginning of each game and will only be
52 -
  // valid while a game is underway.
47 +
  // This module tracks the state over the course of a game:
48 +
  // stats, changes as you train them, cheese accumulated, and so on.
53 49
  //
54 -
  // Additionally, it is intended to record the results of games in other
55 -
  // properties, which will persist until rollover, in other scripts wish to
56 -
  // analyze them.
50 +
  // These are made available in properties so that scripts can use them
51 +
  // without having to parse the response text for themselves. The properties
52 +
  // reset at the beginning of a game and are valid while a game is underway.
53 +
  //
54 +
  // This module records the results of games in other properties, which will
55 +
  // persist until rollover, in other scripts wish to analyze them.
56 +
  //
57 +
  // If the user opts in (via property), the results of all battles and all
58 +
  // cheese acquisitions are recorded in files in the "data" directory for
59 +
  // later analysis by ASH programs.
60 +
61 +
  // *** Ongoing research:
62 +
  //
63 +
  // Stats:
64 +
  //
65 +
  // - We know stat bonuses offered by style sets as displayed by
66 +
  //   "needles". Is it possible to determine actual stat values?
67 +
  //   Maybe: 12 cheese encounters scale (positively or negatively) according
68 +
  //   to one of the 6 stats. We collect data based on stat bonuses - and the
69 +
  //   yield is linear, with randomizing fuzz. Look at the x-intercepts?
70 +
  // - Is there a randomizing factor in player stats per game? One hopes not.
71 +
  // - How do the potions affect your stats during battles? They do not
72 +
  //   register on the "needles" as stat bonuses, and they do not affect
73 +
  //   cheese yields that scale by stat. But you can definitely win against
74 +
  //   tougher castles if you have them in effect than if you do not.
75 +
  //
76 +
  // Castles:
77 +
  //
78 +
  // - What are initial stats for the six castles?
79 +
  //   (Conjecture is that each is "better" at one of the six stats.)
80 +
  // - Is there a randomizing factor per game or battle?
81 +
  // - How do they scale as fight # increases?
82 +
  // - When comparing castle and player stats, one is always "higher" or
83 +
  //   "lower" than the other. Really? Perhaps equal stats have a 50% chance of
84 +
  //   winning or losing the toss?
85 +
  //
86 +
  // Battles:
87 +
  //
88 +
  // - It "feels" like you sometimes just can't win against what are normally
89 +
  //   easy opponents. Can we use statistics to confirm or deny the "feeling"?
90 +
  //   If there is a randomizing factor, which has fuzz? Player stats or castle
91 +
  //   stats? KoL "monsters" have such for attack/defense - not the player.
92 +
  //
93 +
  // Cheese:
94 +
  //
95 +
  // - What are the linear formulae for the 12 stat-scaling cheese encounters?
96 +
97 +
  // *** Solved research:
98 +
  //
99 +
  // Cheese:
100 +
  //
101 +
  // - The yields of the 3 non-scaling encounters (20, 50, 100)
102 +
  // - The yields from defeated castles (45 * castle level)
103 +
  // - The wishing well succeeds 1/3 of the time with a yield of 300.
104 +
  // - Potions that affect stats do not affect stat-scaling yields
105 +
  //
106 +
  // Stances:
107 +
  //
108 +
  // - offensive is 80% aggressor, 20% defender
109 +
  // - waiting is 50% aggressor, 50% defender
110 +
  // - defensive is 20% aggressor, 80% defender
57 111
58 112
  private BastilleBattalionManager() {}
59 113
60 114
  // *** Stats
61 115
62 -
  // We don't actually know what your stats start at,
116 +
  // We don't know what your (internal to KoL) stats start at,
63 117
  //
64 -
  // Each of the four castle Upgrades will provide bonuses to one or more
65 -
  // stats.
118 +
  // Each of the four castle Upgrades provides bonuses to one or more stats.
66 119
  //
67 120
  // There are three potions which are rewards you can get from your first game
68 -
  // (won or lost) of the day which affect your stats.
121 +
  // (won or lost) of the day which affect your stats (for combats only).
69 122
  //
70 123
  // sharkfin gumbo grants 1 turn of Shark Tooth Grin
71 124
  //    Boosts military attack and defense in Bastille Battalion.
@@ -74,16 +127,16 @@
Loading
74 127
  // interrogative elixir grants 1 turn of Enhanced Interrogation
75 128
  //    Boosts psychological attack and defense in Bastille Battalion.
76 129
  //
77 -
  // The image of the rig has six indicators ("needles") at the bottom
78 -
  // which show your upgrade-granted boosts to your six stats. The potions are
79 -
  // not accounted for in those.
130 +
  // The image of the rig has six indicators ("needles") at the bottom which
131 +
  // show your upgrade-granted boosts to your six stats. The potions do not
132 +
  // affect that display.
80 133
  //
81 134
  // The "needles" each have a horizontal location (measured in pixels) which
82 135
  // can be used to determine the current level of boostage.
83 136
  //
84 137
  // (Ezandora's relay script displays that pixel value as the value of your
85 138
  // stats. That's pretty funny; they do show how your stats compare to each
86 -
  // other, but I am sure the stats are not internally measured in pixels.
139 +
  // other, but I am sure the stats are not internally measured in pixels.)
87 140
88 141
  private static Map<String, Stat> enumNameToStat = new HashMap<>();
89 142
@@ -248,15 +301,10 @@
Loading
248 301
  //
249 302
  //     Avant-Garde - higher psychological defense?
250 303
  //     Imposing Citadel - higher psychological attack
251 -
  //     Generic - higher military defense??
304 +
  //     Generic - higher military defense?
252 305
  //     Military Fortress - higher military attack
253 306
  //     Fortified Stronghold - higher castle defense?
254 307
  //     Sprawling Chateau - higher castle attack?
255 -
  //
256 -
  // Observations:
257 -
  //
258 -
  // "shieldmaster" - the Fortified Stronghold - will never attack, even if you
259 -
  // selected a defensive Stance
260 308
261 309
  private static Map<String, Castle> imageToCastle = new HashMap<>();
262 310
  private static Map<String, Castle> descriptionToCastle = new HashMap<>();
@@ -295,10 +343,10 @@
Loading
295 343
296 344
  // You can upgrade four areas of your castle
297 345
  //
298 -
  // Each upgrade provides a reward at the end of your first game, depending on
299 -
  // the style you selected for the upgrade.
346 +
  // Each upgrade provides a reward at the end of your first game of the day,
347 +
  // depending on the style you selected for the upgrade.
300 348
  //
301 -
  // Each upgrade/style also provides a boost to specific attack/defense game stats
349 +
  // Each upgrade/style also provides a boost to specific attack/defense stats
302 350
  //
303 351
  // The Barbican is the fortified gateway.
304 352
  //    The reward is {Muscle, Mysticality, Moxie} substats
@@ -410,9 +458,9 @@
Loading
410 458
  // I experimented a lot transitioning between one upgrade and another and observing
411 459
  // how my stat bonuses changed.
412 460
  //
413 -
  // It turns out that those values depend on what the other upgrades happen to be;
414 -
  // the same upgrade swap might grant +1 or +2 Castle Attack, say, depending on which
415 -
  // other upgrades are in place.
461 +
  // It turns out that those values are not independent; the same upgrade swap
462 +
  // might grant +1 or +2 Castle Attack, say, depending on which other upgrades
463 +
  // are in place.
416 464
  //
417 465
  // There are three Styles for each of four Upgrades, so there are a total of 81 = (3 ^ 4)
418 466
  // configurations.
@@ -471,10 +519,11 @@
Loading
471 519
        int key = StringUtilities.parseInt(data[0]) - 1;
472 520
473 521
        if (styleSetToStats.containsKey(key)) {
522 +
          // Should be impossible.
474 523
          continue;
475 524
        }
476 525
477 -
        // Ignore the style names; they are for human use
526 +
        // Ignore the style names; they are for humans to read
478 527
        // String styleName1 = data[1];
479 528
        // String styleName2 = data[2];
480 529
        // String styleName3 = data[3];
@@ -498,7 +547,7 @@
Loading
498 547
    }
499 548
  }
500 549
501 -
  // Write data file: only for testing. Or for generating it the first time.
550 +
  // Write data file: for testing or for generating the first time.
502 551
503 552
  private static String generateStyleSetFields(int key) {
504 553
    Collection<Style> styleSet = keyToStyleSet(key);
@@ -536,8 +585,7 @@
Loading
536 585
    assert styleSetToStats.size() == 81;
537 586
  }
538 587
539 -
  // *** Cached state. This resets when you visit the Bastille Battalion
540 -
  // *** control rig
588 +
  // *** Cached state. Resets when you visit the Bastille Battalion control rig
541 589
542 590
  private static final Map<Upgrade, Style> currentStyles = new TreeMap<>();
543 591
  private static Stats currentStats = new Stats();
@@ -546,18 +594,19 @@
Loading
546 594
547 595
  // *** Cheese
548 596
549 -
  // When you are in choice 1315, you can focus on offense, defense, or to seek
550 -
  // cheese.
597 +
  // When you are in choice 1314 - Bastille Battalion (Master of None) - you
598 +
  // can focus on offense or defense, or choose to seek cheese.
551 599
  //
552 600
  // If you select Cheese Seeking Behavior (choice 1319), you will be presented
553 -
  // with 3 different options out of a pool of 16 possibilities. You will have
554 -
  // a chance to do this twice before entering into a Battle with the
555 -
  // approaching castle, and the choices do not appear to recur - until the
556 -
  // next castle.
601 +
  // with 3 different options out of a pool of 16 possibilities. You can take
602 +
  // each option only once per game. Since you have 2 rounds of preparation and
603 +
  // up to 5 castles per game, if you do nothing except look for cheese, your
604 +
  // first prep round will offer 3 out of 16, the second, 3 out of 15, until
605 +
  // the 10th, which will offer 3 out of 7 options.
557 606
  //
558 607
  // The Wishing Well is useless if it occurs on the very first turn, since you
559 -
  // will not have the 10 cheese required to activate it. It may occur later
560 -
  // during the same turn, at most once.
608 +
  // will not have the 10 cheese required to activate it. If you skip it, like
609 +
  // all untaken options, it may be offered again later in the same game.
561 610
  //
562 611
  // The 16 possible Cheese Seeking encounters include these:
563 612
  //
@@ -570,9 +619,8 @@
Loading
570 619
  //
571 620
  // 3 that are not affected by a stat
572 621
  //
573 -
  // The Wishing Well does not appear to be affected by a stat, but either
574 -
  // gives you no cheese or about 300 cheese. This may be random or may be
575 -
  // affected by something I do not know about.
622 +
  // The Wishing Well is not affected by a stat, but either gives you no cheese
623 +
  // (2/3 chance) or about 300 cheese (1/3 chance).
576 624
  //
577 625
  // Other sources of cheese:
578 626
  //
@@ -661,23 +709,27 @@
Loading
661 709
662 710
  // *** Battle
663 711
664 -
  // One of the reasons I started this project was to collect data that could be analyzed to
665 -
  // understand how to do well at this game. The already released improved logging has made the game
666 -
  // play much more enjoyable, but I have been manually making observations and taking notes that
667 -
  // could much more usefully be recorded automatically.
712 +
  // One of the reasons I started this project was to collect data that could
713 +
  // be analyzed to understand how to do well at this game. The improved
714 +
  // logging makes the game play much more enjoyable, but the collected data
715 +
  // makes automated data analysis possible without manual data entry.
668 716
  //
669 -
  // Some observations so far:
717 +
  // Observations so far:
670 718
  //
671 -
  // Each kind of castle has particular strengths and weaknesses. There are six kinds of castle. I
672 -
  // believe that each is stronger in one of the six stats.
719 +
  // Each kind of castle has particular strengths and weaknesses. There are six
720 +
  // kinds of castle. Each appears to be stronger in one of the six stats.
673 721
  //
674 -
  // A "game" has 5 rounds. Your foes increase in power depending on which round you encounter them.
675 -
  // For example, if I attack castle type A on round one, my attack vs. his defense may be 3:0, but
676 -
  // on rounds 2 - 5, attack vs. defense may decrease to 2:1, 1:2, and eventually 0:3. Your rewards
677 -
  // for beating a foe go up correspondingly to the difficulty.
722 +
  // A "game" has 5 rounds. Your foes increase in power depending on which
723 +
  // round you encounter them.  For example, if I attack castle type A on round
724 +
  // one, my attack vs. his defense may be 3:0, but on rounds 2 - 5, attack
725 +
  // vs. defense may decrease to 2:1, 1:2, and eventually 0:3. Your cheese
726 +
  // reward for beating a foe go up correspondingly to the difficulty.
678 727
  //
679 -
  // The role of "stance" is unclear: none of offense, bide, and defense guarantees that you will be
680 -
  // the aggressor or the defender.
728 +
  // Depending on your stat configuration, you will have to depend on offense
729 +
  // or defense (i.e., which stance you select) to even have a chance against
730 +
  // higher difficulty castles. For a given stat configuration, some castles
731 +
  // will be unbeatable at higher levels - and to get the highest scores, you
732 +
  // have to be lucky enough to get one of the castles you CAN beat.
681 733
682 734
  // *** Stances
683 735
@@ -689,6 +741,19 @@
Loading
689 741
  //
690 742
  // In a battle, either (all of) your Attack stats are compared to your foe's
691 743
  // Defense stats, or vice versa.
744 +
  //
745 +
  // Observations collected from 4308 battles as of 2022/06/20:
746 +
  //
747 +
  // "offensive" stance (901): 80% aggressor/20% defender
748 +
  // "waiting" stance (1586): 50% aggressor/50% defender
749 +
  // "defensive" stance (1821): 20% aggressor/80% defender
750 +
  //
751 +
  // With an "offensive" stance (80% of the time):
752 +
  // You charge toward your enemy.
753 +
  //
754 +
  // With a "defensive" stance (20% of the time):
755 +
  // You squat and wait for the attack, but it never comes. You sigh, uproot yourself, and attack
756 +
  // them.
692 757
693 758
  private static final Map<Integer, Stance> optionToStance = new HashMap<>();
694 759
@@ -712,9 +777,9 @@
Loading
712 777
713 778
  // *** Results
714 779
715 -
  // Your Stance may indicate your desire to attack vs. defend, but it's not entirely up to you.
716 -
  // Even if you charge in, your foe may attack first. Even if you try to defend, you may end up
717 -
  // attacking first.
780 +
  // Your Stance indicates your desire to attack vs. defend, but it's not
781 +
  // entirely up to you.  Even if you charge in, your foe may attack
782 +
  // first. Even if you try to defend, you may end up attacking first.
718 783
  //
719 784
  // The aggressor's attacks are compared against the defender's defense.
720 785
  // You can win from 0 to 3 of these comparisons.
@@ -1357,9 +1422,9 @@
Loading
1357 1422
      case 1316: // GAME OVER
1358 1423
        return;
1359 1424
1360 -
      case 1319: // Cheese Seeking Behavior
1361 1425
      case 1317: // A Hello to Arms (Battalion)
1362 1426
      case 1318: // Defensive Posturing
1427 +
      case 1319: // Cheese Seeking Behavior
1363 1428
        collectCheese(text);
1364 1429
        if (!parseTurn(text)) {
1365 1430
          nextTurn();
@@ -1454,7 +1519,7 @@
Loading
1454 1519
  // data to be automatically saved to a file in a format which can be read by
1455 1520
  // an analysis script via file_to_map().
1456 1521
  //
1457 -
  // This is the proposed format.
1522 +
  // This is the format.
1458 1523
  //
1459 1524
  // The file is a tab delimited file in "data" named Bastille.battles.txt
1460 1525
  //
@@ -1470,8 +1535,8 @@
Loading
1470 1535
  //     int number;         // Affects strength of enemy
1471 1536
  //     int [6] stats;      // MA/MD/CA/CD/PA/PD
1472 1537
  //     string boosts;      // MCP
1473 -
  //     string enemy;       // frenchcastle,masterofnone,bigcastle,
1474 -
  //                         // berserker,shieldmaster,barracks
1538 +
  //     string enemy;       // {frenchcastle,masterofnone,bigcastle,
1539 +
  //                         // berserker,shieldmaster,barracks}
1475 1540
  //     string stance;      // {offensive,waiting,defensive}
1476 1541
  //     boolean aggressor;  // as opposed to defender
1477 1542
  //     boolean military;   // true if won
Files Complexity Coverage
src/net/sourceforge/kolmafia 20.33% 25.44%
Project Totals (1019 files) 20.33% 25.44%
coverage-windows-latest-java-17
Build #2543225942 -
JAVA=17
OS=windows-latest
coverage-ubuntu-latest-java-17
Build #2543225942 -
JAVA=17
OS=ubuntu-latest
coverage-macos-latest-java-17
Build #2543225942 -
JAVA=17
OS=macos-latest

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading