Skip to content
This repository was archived by the owner on Oct 24, 2021. It is now read-only.

Commit

Permalink
fix(mulligan): refine mulligan timing for slightly earlier exit (#43)
Browse files Browse the repository at this point in the history
* fix(mulligan): refine mulligan timing for slightly earlier exit

* refactor: define deck card count as const
  • Loading branch information
Hoishin authored Jul 24, 2019
1 parent 25eb961 commit f2d755d
Show file tree
Hide file tree
Showing 10 changed files with 6,094 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/GameState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Player {
cardCount: number;
position: 'top' | 'bottom';
secrets: Secret[];
cardsReplacedInMulligan: number;
}

export class GameState {
Expand Down
1 change: 1 addition & 0 deletions src/data/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DECK_CARD_COUNT = 30;
27 changes: 14 additions & 13 deletions src/line-parsers/game-tag-change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@ export class GameTagChangeLineParser extends AbstractLineParser {
lineMatched(parts: string[], gameState: GameState): void {
const data = formatParts(parts);

if (data.entity === 'GameEntity' && data.tag === 'STEP' && data.value === 'MAIN_READY') {
gameState.mulliganActive = false;
gameState.turnStartTime = new Date();

// Neither of players have turn true which means bottom player is playing first
if (gameState.players.every(player => !player.turn)) {
const bottomPlayer = gameState.getPlayerByPosition('bottom');
if (bottomPlayer) {
bottomPlayer.turn = true;
}
if (data.entity === 'GameEntity' && data.value === 'MAIN_READY') {
if (data.tag === 'NEXT_STEP') {
gameState.mulliganActive = false;
}
}

if (data.tag === 'MULLIGAN_STATE' && data.value === 'DEALING') {
gameState.mulliganActive = true;
if (data.tag === 'STEP') {
gameState.turnStartTime = new Date();

// Neither of players have turn true which means bottom player is playing first
if (gameState.players.every(player => !player.turn)) {
const bottomPlayer = gameState.getPlayerByPosition('bottom');
if (bottomPlayer) {
bottomPlayer.turn = true;
}
}
}
}

if (data.tag === 'TIMEOUT') {
Expand Down
5 changes: 4 additions & 1 deletion src/line-parsers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ZoneChangeLineParser} from './zone-change';
import {TagChangeLineParser} from './tag-change';
import {GameState} from '../GameState';
import {MulliganStartParser} from './mulligan-start';
import {MullinganResultParser} from './mulligan-result';

export const lineParsers = [
new GameOverLineParser(),
Expand All @@ -16,7 +17,8 @@ export const lineParsers = [
new ZoneChangeLineParser(),
new TagChangeLineParser(),
new GameTagChangeLineParser(),
new MulliganStartParser()
new MulliganStartParser(),
new MullinganResultParser()
];

export interface Events {
Expand All @@ -29,4 +31,5 @@ export interface Events {
'tag-change': void;
'zone-change': void;
'mulligan-start': void;
'mulligan-result': void;
}
44 changes: 44 additions & 0 deletions src/line-parsers/mulligan-result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {AbstractLineParser} from './AbstractLineParser';
import {GameState} from '../GameState';
import {DECK_CARD_COUNT} from '../data/meta';

const calcCardsReplaced = (cardsLeft: number, cardCount: number): number => {
return DECK_CARD_COUNT - cardCount - cardsLeft;
};

// Detect how many cards are replaced in mulligan
export class MullinganResultParser extends AbstractLineParser {
regex = /\[Power\]\s+GameState\.DebugPrintEntitiesChosen\(\)\s+-\s+id=\w+\s+Player=(.*)\s+EntitiesCount=(\d+)/;

eventName = 'mulligan-result' as const;

lineMatched([, name, cardsLeft]: string[], gameState: GameState): void {
if (!gameState.mulliganActive) {
return;
}

const player = gameState.getPlayerByName(name);
if (!player) {
return;
}

player.cardsReplacedInMulligan = calcCardsReplaced(parseInt(cardsLeft, 10), player.cardCount);
}

formatLogMessage([, name, cardsLeft]: string[], gameState: GameState): string | false {
if (!gameState.mulliganActive) {
return false;
}

const player = gameState.getPlayerByName(name);
if (!player) {
return false;
}

return `${player.name} replaced ${calcCardsReplaced(parseInt(cardsLeft, 10), player.cardCount)} cards in mulligan`;
}

shouldEmit(gameState: GameState): boolean {
return gameState.mulliganActive;
}
}
3 changes: 2 additions & 1 deletion src/line-parsers/new-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export class NewPlayerLineParser extends AbstractLineParser {
timeout: 45,
cardCount: 0,
position: gameState.numPlayers === 0 ? 'bottom' : 'top',
secrets: []
secrets: [],
cardsReplacedInMulligan: 0
});
}

Expand Down
4,166 changes: 4,166 additions & 0 deletions test/artifacts/mulligan-card-count.log

Large diffs are not rendered by default.

215 changes: 215 additions & 0 deletions test/artifacts/mulligan-end.log

Large diffs are not rendered by default.

Loading

0 comments on commit f2d755d

Please sign in to comment.