Skip to content

Commit

Permalink
0.6.0: Added turn card gains count tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
JessicaMulein committed Oct 27, 2024
1 parent 8986e1d commit b400e02
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 18 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ Join our community of developers.
## Changelog
### Sun Oct 27 16:00:00 2024
- Version 0.6.0
- Added turn card gains count tracking
### Sun Oct 27 15:35:00 2024
- Version 0.5.0
Expand Down
28 changes: 26 additions & 2 deletions src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ const CenteredTitle = styled(Box)({

const CorrectionCheckboxContainer = styled(Box)({
position: 'absolute',
bottom: 10,
left: 30,
bottom: 0,
left: 10,
display: 'flex',
alignItems: 'center',
});
Expand Down Expand Up @@ -302,6 +302,7 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Actions"
value={player.turn.actions}
tooltip="Tracks the number of actions available this turn"
onIncrement={() => handleFieldChange('turn', 'actions', 1)}
onDecrement={() => {
// greatLeaderProphecy gives unlimited actions when the prophecy is empty
Expand All @@ -319,21 +320,31 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Buys"
value={player.turn.buys}
tooltip="Tracks the number of buys available this turn"
onIncrement={() => handleFieldChange('turn', 'buys', 1)}
onDecrement={() => handleFieldChange('turn', 'buys', -1)}
/>
<IncrementDecrementControl
label="Coins"
value={player.turn.coins}
tooltip="Tracks the number of coins played this turn"
onIncrement={() => handleFieldChange('turn', 'coins', 1)}
onDecrement={() => handleFieldChange('turn', 'coins', -1)}
/>
<IncrementDecrementControl
label="Cards"
value={player.turn.cards}
tooltip="Tracks the number of cards drawn this turn"
onIncrement={() => handleFieldChange('turn', 'cards', 1)}
onDecrement={() => handleFieldChange('turn', 'cards', -1)}
/>
<IncrementDecrementControl
label="Gains"
value={player.turn.gains}
tooltip="Tracks the number of cards gained this turn"
onIncrement={() => handleFieldChange('turn', 'gains', 1)}
onDecrement={() => handleFieldChange('turn', 'gains', -1)}
/>
</ColumnBox>
{(showMats || showGlobalMats) && (
<ColumnBox>
Expand Down Expand Up @@ -380,6 +391,7 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Debt"
value={player.mats.debt}
tooltip="Tracks players' debt across turns"
onIncrement={() => handleFieldChange('mats', 'debt', 1)}
onDecrement={() => handleFieldChange('mats', 'debt', -1)}
/>
Expand All @@ -388,6 +400,7 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Favors"
value={player.mats.favors}
tooltip="Tracks players' favors across turns"
onIncrement={() => handleFieldChange('mats', 'favors', 1)}
onDecrement={() => handleFieldChange('mats', 'favors', -1)}
/>
Expand Down Expand Up @@ -426,6 +439,7 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Curses"
value={player.victory.curses}
tooltip="Tracks players' curses across turns"
onIncrement={() => handleFieldChange('victory', 'curses', 1)}
onDecrement={() => handleFieldChange('victory', 'curses', -1)}
onTrash={() => handleFieldChange('victory', 'curses', -1, undefined, true)}
Expand All @@ -434,20 +448,23 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Estates"
value={player.victory.estates}
tooltip="Tracks players' estates owned across turns"
onIncrement={() => handleFieldChange('victory', 'estates', 1)}
onDecrement={() => handleFieldChange('victory', 'estates', -1)}
onTrash={() => handleFieldChange('victory', 'estates', -1, undefined, true)}
/>
<IncrementDecrementControl
label="Duchies"
value={player.victory.duchies}
tooltip="Tracks players' duchies owned across turns"
onIncrement={() => handleFieldChange('victory', 'duchies', 1)}
onDecrement={() => handleFieldChange('victory', 'duchies', -1)}
onTrash={() => handleFieldChange('victory', 'duchies', -1, undefined, true)}
/>
<IncrementDecrementControl
label="Provinces"
value={player.victory.provinces}
tooltip="Tracks players' provinces owned across turns"
onIncrement={() => handleFieldChange('victory', 'provinces', 1)}
onDecrement={() => handleFieldChange('victory', 'provinces', -1)}
onTrash={() => handleFieldChange('victory', 'provinces', -1, undefined, true)}
Expand All @@ -456,6 +473,7 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Colonies"
value={player.victory.colonies}
tooltip="Tracks players' colonies owned across turns"
onIncrement={() => handleFieldChange('victory', 'colonies', 1)}
onDecrement={() => handleFieldChange('victory', 'colonies', -1)}
onTrash={() => handleFieldChange('victory', 'colonies', -1, undefined, true)}
Expand All @@ -464,12 +482,14 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Tokens"
value={player.victory.tokens}
tooltip="Tracks players' victory tokens owned across turns"
onIncrement={() => handleFieldChange('victory', 'tokens', 1)}
onDecrement={() => handleFieldChange('victory', 'tokens', -1)}
/>
<IncrementDecrementControl
label="Other"
value={player.victory.other}
tooltip="Tracks players' other victory points owned across turns"
onIncrement={() => handleFieldChange('victory', 'other', 1)}
onDecrement={() => handleFieldChange('victory', 'other', -1)}
/>
Expand All @@ -496,24 +516,28 @@ const Player: React.FC = () => {
<IncrementDecrementControl
label="Actions"
value={player.newTurn.actions}
tooltip="Number of actions available for new turns"
onIncrement={() => handleFieldChange('newTurn', 'actions', 1)}
onDecrement={() => handleFieldChange('newTurn', 'actions', -1)}
/>
<IncrementDecrementControl
label="Buys"
value={player.newTurn.buys}
tooltip="Number of buys available for new turns"
onIncrement={() => handleFieldChange('newTurn', 'buys', 1)}
onDecrement={() => handleFieldChange('newTurn', 'buys', -1)}
/>
<IncrementDecrementControl
label="Coins"
value={player.newTurn.coins}
tooltip="Number of coins available for new turns"
onIncrement={() => handleFieldChange('newTurn', 'coins', 1)}
onDecrement={() => handleFieldChange('newTurn', 'coins', -1)}
/>
<IncrementDecrementControl
label="Cards"
value={player.newTurn.cards}
tooltip="Number of cards available for new turns"
onIncrement={() => handleFieldChange('newTurn', 'cards', 1)}
onDecrement={() => handleFieldChange('newTurn', 'cards', -1)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ describe('victoryFieldToGameLogAction', () => {
expect(fieldSubfieldToGameLogAction('turn', 'cards', -1)).toBe(GameLogAction.REMOVE_CARDS);
});

it('should return ADD_GAINS for turn gains increment', () => {
expect(fieldSubfieldToGameLogAction('turn', 'gains', 1)).toBe(GameLogAction.ADD_GAINS);
});

it('should return REMOVE_GAINS for turn gains decrement', () => {
expect(fieldSubfieldToGameLogAction('turn', 'gains', -1)).toBe(GameLogAction.REMOVE_GAINS);
});

it('should return ADD_COFFERS for mats coffers increment', () => {
expect(fieldSubfieldToGameLogAction('mats', 'coffers', 1)).toBe(GameLogAction.ADD_COFFERS);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ describe('getFieldAndSubfieldFromAction', () => {
[GameLogAction.REMOVE_COINS, 'turn', 'coins'],
[GameLogAction.ADD_CARDS, 'turn', 'cards'],
[GameLogAction.REMOVE_CARDS, 'turn', 'cards'],
[GameLogAction.ADD_GAINS, 'turn', 'gains'],
[GameLogAction.REMOVE_GAINS, 'turn', 'gains'],
])(
'should return correct field and subfield for %s',
(action, expectedField, expectedSubfield) => {
Expand Down
4 changes: 3 additions & 1 deletion src/game/__tests__/dominion-lib-log-addLogEntry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ describe('addLogEntry', () => {
});

it('should add a log entry with player turn details', () => {
const playerTurnDetails = [{ playerIndex: 0, actions: 1, buys: 1, coins: 1, cards: 5 }];
const playerTurnDetails = [
{ playerIndex: 0, actions: 1, buys: 1, coins: 1, cards: 5, gains: 0 },
];
addLogEntry(mockGame, 0, GameLogAction.ADD_COINS, {
count: 5,
playerTurnDetails,
Expand Down
41 changes: 30 additions & 11 deletions src/game/__tests__/dominion-lib-resetPlayerTurnCounters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,32 @@ describe('resetPlayerTurnCounters', () => {
const initialGame = createMockGame([
createMockPlayer(
'Player 1',
{ actions: 0, buys: 0, coins: 0, cards: 5 },
{ actions: 1, buys: 1, coins: 0, cards: 5 }
{ actions: 0, buys: 0, coins: 0, cards: 5, gains: 0 },
{ actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 }
),
createMockPlayer(
'Player 2',
{ actions: 2, buys: 1, coins: 3, cards: 5 },
{ actions: 1, buys: 1, coins: 0, cards: 5 }
{ actions: 2, buys: 1, coins: 3, cards: 5, gains: 0 },
{ actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 }
),
]);

const updatedGame = resetPlayerTurnCounters(initialGame);

expect(updatedGame.players[0].turn).toEqual({ actions: 1, buys: 1, coins: 0, cards: 5 });
expect(updatedGame.players[1].turn).toEqual({ actions: 1, buys: 1, coins: 0, cards: 5 });
expect(updatedGame.players[0].turn).toEqual({
actions: 1,
buys: 1,
coins: 0,
cards: 5,
gains: 0,
});
expect(updatedGame.players[1].turn).toEqual({
actions: 1,
buys: 1,
coins: 0,
cards: 5,
gains: 0,
});
});

it('should handle an empty player array', () => {
Expand All @@ -83,8 +95,8 @@ describe('resetPlayerTurnCounters', () => {
const initialGame = createMockGame([
createMockPlayer(
'Player 1',
{ actions: 0, buys: 0, coins: 0, cards: 5 },
{ actions: 1, buys: 1, coins: 0, cards: 5 }
{ actions: 0, buys: 0, coins: 0, cards: 5, gains: 0 },
{ actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 }
),
]);
initialGame.players[0].victory = { ...EmptyVictoryDetails(), estates: 3 };
Expand All @@ -111,15 +123,16 @@ describe('resetPlayerTurnCounters', () => {
buys: 1,
coins: 0,
cards: 5,
gains: 0,
});
});

it('should not modify the original game object', () => {
const initialGame = createMockGame([
createMockPlayer(
'Player 1',
{ actions: 0, buys: 0, coins: 0, cards: 5 },
{ actions: 1, buys: 1, coins: 0, cards: 5 }
{ actions: 0, buys: 0, coins: 0, cards: 5, gains: 0 },
{ actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 }
),
]);

Expand All @@ -129,6 +142,12 @@ describe('resetPlayerTurnCounters', () => {
expect(updatedGame.players).not.toBe(initialGame.players);
expect(updatedGame.players[0]).not.toBe(initialGame.players[0]);
expect(updatedGame.players[0].turn).not.toBe(initialGame.players[0].turn);
expect(initialGame.players[0].turn).toEqual({ actions: 0, buys: 0, coins: 0, cards: 5 });
expect(initialGame.players[0].turn).toEqual({
actions: 0,
buys: 0,
coins: 0,
cards: 5,
gains: 0,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,14 @@ describe('reconstructGameState', () => {
coins: 0,
buys: 2,
cards: 5,
gains: 0,
});
expect(result.players[1].turn).toStrictEqual({
actions: 1,
coins: 3,
buys: 1,
cards: 5,
gains: 0,
});
});
});
4 changes: 2 additions & 2 deletions src/game/__tests__/dominion-lib-updatePlayerField.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ describe('updatePlayerField', () => {
name: 'Test Player',
color: DefaultPlayerColors[0],
mats: { coffers: 0, villagers: 0, debt: 0, favors: 0 },
turn: { actions: 1, buys: 1, coins: 0, cards: 5 },
newTurn: { actions: 1, buys: 1, coins: 0, cards: 5 },
turn: { actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 },
newTurn: { actions: 1, buys: 1, coins: 0, cards: 5, gains: 0 },
victory: {
estates: 3,
duchies: 0,
Expand Down
6 changes: 5 additions & 1 deletion src/game/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IMatsEnabled } from '@/game/interfaces/mats-enabled';
import { IGameOptions } from '@/game/interfaces/game-options';
import { deepClone } from '@/game/utils';

export const VERSION_NUMBER = '0.5.0';
export const VERSION_NUMBER = '0.6.0';

export const MIN_PLAYERS = 2;
export const MAX_PLAYERS = 6;
Expand Down Expand Up @@ -107,6 +107,7 @@ export function DefaultTurnDetails(): IPlayerGameTurnDetails {
buys: 1,
coins: 0,
cards: 5,
gains: 0,
});
}

Expand Down Expand Up @@ -146,6 +147,8 @@ export const AdjustmentActions = [
GameLogAction.REMOVE_BUYS,
GameLogAction.ADD_CARDS,
GameLogAction.REMOVE_CARDS,
GameLogAction.ADD_GAINS,
GameLogAction.REMOVE_GAINS,
// mats
GameLogAction.ADD_COFFERS,
GameLogAction.REMOVE_COFFERS,
Expand Down Expand Up @@ -190,6 +193,7 @@ export const NegativeAdjustmentActions = [
GameLogAction.REMOVE_COINS,
GameLogAction.REMOVE_BUYS,
GameLogAction.REMOVE_CARDS,
GameLogAction.REMOVE_GAINS,
// mats
GameLogAction.REMOVE_COFFERS,
GameLogAction.REMOVE_VILLAGERS,
Expand Down
2 changes: 2 additions & 0 deletions src/game/dominion-lib-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export function fieldSubfieldToGameLogAction<T extends keyof PlayerFieldMap>(
return increment > 0 ? GameLogAction.ADD_COINS : GameLogAction.REMOVE_COINS;
case 'cards':
return increment > 0 ? GameLogAction.ADD_CARDS : GameLogAction.REMOVE_CARDS;
case 'gains':
return increment > 0 ? GameLogAction.ADD_GAINS : GameLogAction.REMOVE_GAINS;
default:
throw new InvalidFieldError(field as string, subfield as string);
}
Expand Down
3 changes: 3 additions & 0 deletions src/game/dominion-lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ export function getFieldAndSubfieldFromAction(action: GameLogAction): {
case GameLogAction.ADD_CARDS:
case GameLogAction.REMOVE_CARDS:
return { field: 'turn', subfield: 'cards' };
case GameLogAction.ADD_GAINS:
case GameLogAction.REMOVE_GAINS:
return { field: 'turn', subfield: 'gains' };
case GameLogAction.ADD_COFFERS:
case GameLogAction.REMOVE_COFFERS:
return { field: 'mats', subfield: 'coffers' };
Expand Down
2 changes: 2 additions & 0 deletions src/game/enumerations/game-log-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export enum GameLogAction {
REMOVE_COINS = 'Removed {COUNT} Coins',
ADD_CARDS = 'Added {COUNT} Cards',
REMOVE_CARDS = 'Removed {COUNT} Cards',
ADD_GAINS = 'Added {COUNT} Gains',
REMOVE_GAINS = 'Removed {COUNT} Gains',
ADD_COFFERS = 'Added {COUNT} Coffers',
REMOVE_COFFERS = 'Removed {COUNT} Coffers',
ADD_VILLAGERS = 'Added {COUNT} Villagers',
Expand Down
1 change: 1 addition & 0 deletions src/game/interfaces/player-game-turn-details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface IPlayerGameTurnDetails {
buys: number;
coins: number;
cards: number;
gains: number;
}
2 changes: 1 addition & 1 deletion src/game/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IGameOptions } from '@/game/interfaces/game-options';
import { IPlayer } from '@/game/interfaces/player';

export type TurnField = 'actions' | 'buys' | 'coins' | 'cards';
export type TurnField = 'actions' | 'buys' | 'coins' | 'cards' | 'gains';
export type VictoryField =
| 'curses'
| 'estates'
Expand Down

0 comments on commit b400e02

Please sign in to comment.