Skip to content

Commit

Permalink
feat(webapp): add v2 card information
Browse files Browse the repository at this point in the history
  • Loading branch information
ben196888 committed Jul 18, 2024
1 parent 40aa55a commit 1619d60
Show file tree
Hide file tree
Showing 6 changed files with 625 additions and 737 deletions.
4 changes: 4 additions & 0 deletions packages/webapp/src/game/card.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export type ProjectName = string;
export type ProjectCard = {
id: string;
name: ProjectName;
type: string;
difficulty: number;
description: string;
requirements: Record<JobName, number>;
};

Expand All @@ -18,4 +21,5 @@ export type EventCard = {
name: EventName;
description: string;
function_name: EventFunctionName;
type: string;
};
59 changes: 51 additions & 8 deletions packages/webapp/src/game/core/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ const getUuid = (randomFn: () => number = Math.random ) => {
return randomFn().toString(32).slice(2);
}

interface RawProjectCard {
name: string;
type: string;
difficulty: number;
description: string;
requirements: Record<string, number>;
}

interface RawJobCard {
name: string;
number_of_cards: number;
}

export const setup: SetupFn<GameState> = ({ ctx, random }) => {
console.log('setup game')

Expand All @@ -35,27 +48,57 @@ export const setup: SetupFn<GameState> = ({ ctx, random }) => {

console.log('setup decks')
// add cards to decks
const projectCards = rawProjectCards.map(rawProjectCard => ({ id: getUuid(random.Number), ...rawProjectCard }) as unknown as ProjectCard);
console.log('setup project cards')
const mapToProjectCards = (rawProjectCards: RawProjectCard[]): ProjectCard[] => {
return rawProjectCards.map(rawProjectCard => ({
id: getUuid(random.Number),
...rawProjectCard,
}));
};

const projectCards = mapToProjectCards(rawProjectCards as unknown as RawProjectCard[]);
const shuffledProjectCards = random.Shuffle(projectCards);
DeckMutator.initialize(G.decks.projects, shuffledProjectCards);

const jobCards = rawJobCards.map(rawJobCard => ({ id: getUuid(random.Number), ...rawJobCard }) as unknown as JobCard);
console.log('setup job cards')
const mapToJobCards = (rawJobCards: RawJobCard[]): JobCard[] => {
const jobCards: JobCard[] = [];
rawJobCards.forEach(rawJobCard => {
const jobCardCreator = () => ({
id: getUuid(random.Number),
name: rawJobCard.name,
});
for (let i = 0; i < rawJobCard.number_of_cards; i++) {
jobCards.push(jobCardCreator());
}
})
return jobCards;
};

const jobCards = mapToJobCards(rawJobCards);
const shuffledJobCards = random.Shuffle(jobCards);
DeckMutator.initialize(G.decks.jobs, shuffledJobCards);

console.log('setup event cards');
// TODO: Validate event card function names
const eventCards = rawEventCards.map(rawEventCard => ({ id: getUuid(random.Number), ...rawEventCard }) as unknown as EventCard);
// find end game event card
// pick N random event cards based on rule and shuffle them
// add end game event card to the end
const endGameEvent = eventCards.find(card => card.function_name === 'end_game_after_this_round');
if (!endGameEvent) {
throw new Error('end_game_after_this_round event card not found');
const lastRoundEventCards = eventCards.filter(card => card.type === 'last_round');
if (lastRoundEventCards.length === 0) {
throw new Error('last round event card not found');
}
const restEventCards = eventCards.filter(card => card.function_name !== 'end_game_after_this_round');
if (lastRoundEventCards.length > 1) {
throw new Error('multiple last round event cards found');
}
const endGameEventCard = lastRoundEventCards[0];

const basicEventCards = eventCards.filter(card => card.type === 'basic');
const nonEndGameEventCardCount = RuleSelector.getNonEndGameNumberOfEventCards(G.rules);
const eventCardsWithoutEndGame = reservoirSampling(restEventCards, nonEndGameEventCardCount, random.Number);
const eventCardsWithoutEndGame = reservoirSampling(basicEventCards, nonEndGameEventCardCount, random.Number);
const shuffledEventCards = random.Shuffle(eventCardsWithoutEndGame);
shuffledEventCards.push(endGameEvent);
shuffledEventCards.push(endGameEventCard);
// initialize event deck
DeckMutator.initialize(G.decks.events, shuffledEventCards);

Expand Down
21 changes: 14 additions & 7 deletions packages/webapp/src/game/data/card/events.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,43 @@
{
"name": "是芥末日",
"description": "翻開此卡,本輪結束後,遊戲結束。在回合中可不將行動點用完,剩餘一個行動點數 +1 分",
"function_name": "end_game_after_this_round"
"function_name": "end_game_after_this_round",
"type": "last_round"
},
{
"name": "人力釋出",
"description": "立即將人力資源區的人力卡全部棄掉,並重新補滿",
"function_name": "discard_and_refill_all_worker_slots"
"function_name": "discard_and_refill_all_worker_slots",
"type": "basic"
},
{
"name": "斜槓青年",
"description": "本輪所有玩家在發起專案行動或招募人力行動時,使用的第一張人力卡可以無視人力需求招募至專案",
"function_name": "ignore_first_worker_requirement"
"function_name": "ignore_first_worker_requirement",
"type": "basic"
},
{
"name": "四大自由",
"description": "立即多翻開兩張人力卡至人力資源區,即人力資源區上限 +2。本輪結束時由尾家選擇兩張棄掉",
"function_name": "add_two_worker_slots"
"function_name": "add_two_worker_slots",
"type": "basic"
},
{
"name": "會計年度結算",
"description": "本輪結案的專案,發起者額外獲得 2分",
"function_name": "project_owner_gets_two_points"
"function_name": "project_owner_gets_two_points",
"type": "basic"
},
{
"name": "青年補助",
"description": "本輪目前影響力分數最低的玩家,可多使用一個灰色行動點指示物,若最低分不只一位,則無人可以使用",
"function_name": "the_only_player_with_the_lowest_victory_points_gets_one_extra_action_token"
"function_name": "the_only_player_with_the_lowest_victory_points_gets_one_extra_action_token",
"type": "basic"
},
{
"name": "番茄醬工作法",
"description": "本輪執行發起人貢獻時可分配的貢獻值 +1",
"function_name": "increase_one_owned_project_contribution_value"
"function_name": "increase_one_owned_project_contribution_value",
"type": "basic"
}
]
180 changes: 14 additions & 166 deletions packages/webapp/src/game/data/card/jobs.json
Original file line number Diff line number Diff line change
@@ -1,182 +1,30 @@
[
{
"name": "行銷公關"
"name": "行銷公關",
"number_of_cards": 3
},
{
"name": "行銷公關"
"name": "法務專家",
"number_of_cards": 5
},
{
"name": "法務"
"name": "美術設計",
"number_of_cards": 7
},
{
"name": "法務"
"name": "公務人員",
"number_of_cards": 7
},
{
"name": "法務"
"name": "文字工作者",
"number_of_cards": 7
},
{
"name": "法務"
"name": "議題工作者",
"number_of_cards": 9
},
{
"name": "美術與設計"
},
{
"name": "美術與設計"
},
{
"name": "美術與設計"
},
{
"name": "美術與設計"
},
{
"name": "美術與設計"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "公務員"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "文字工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "議題工作者"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
},
{
"name": "工程師"
"name": "工程師",
"number_of_cards": 12
}
]
Loading

0 comments on commit 1619d60

Please sign in to comment.