Skip to content

Commit

Permalink
Setup Tiles Randomizer (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert authored Dec 5, 2024
1 parent 556eda3 commit fc146f4
Show file tree
Hide file tree
Showing 110 changed files with 480 additions and 28 deletions.
Binary file added src/assets/book-actions-background.webp
Binary file not shown.
Binary file added src/assets/competency-display.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/1.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/2.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/3.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/4.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/5.webp
Binary file not shown.
Binary file added src/assets/icons/book-action/6.webp
Binary file not shown.
Binary file added src/assets/icons/competency/1.webp
Binary file not shown.
Binary file added src/assets/icons/competency/10.webp
Binary file not shown.
Binary file added src/assets/icons/competency/11.webp
Binary file not shown.
Binary file added src/assets/icons/competency/12.webp
Binary file not shown.
Binary file added src/assets/icons/competency/2.webp
Binary file not shown.
Binary file added src/assets/icons/competency/3.webp
Binary file not shown.
Binary file added src/assets/icons/competency/4.webp
Binary file not shown.
Binary file added src/assets/icons/competency/5.webp
Binary file not shown.
Binary file added src/assets/icons/competency/6.webp
Binary file not shown.
Binary file added src/assets/icons/competency/7.webp
Binary file not shown.
Binary file added src/assets/icons/competency/8.webp
Binary file not shown.
Binary file added src/assets/icons/competency/9.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/1.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/10.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/11.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/12.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/13.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/14.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/15.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/16.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/17.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/18.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/2.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/3.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/4.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/5.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/6.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/7.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/8.webp
Binary file not shown.
Binary file added src/assets/icons/innovation/9.webp
Binary file not shown.
Binary file added src/assets/icons/palace/1.webp
Binary file not shown.
Binary file added src/assets/icons/palace/10.webp
Binary file not shown.
Binary file added src/assets/icons/palace/11.webp
Binary file not shown.
Binary file added src/assets/icons/palace/12.webp
Binary file not shown.
Binary file added src/assets/icons/palace/13.webp
Binary file not shown.
Binary file added src/assets/icons/palace/14.webp
Binary file not shown.
Binary file added src/assets/icons/palace/15.webp
Binary file not shown.
Binary file added src/assets/icons/palace/16.webp
Binary file not shown.
Binary file added src/assets/icons/palace/17.webp
Binary file not shown.
Binary file added src/assets/icons/palace/2.webp
Binary file not shown.
Binary file added src/assets/icons/palace/3.webp
Binary file not shown.
Binary file added src/assets/icons/palace/4.webp
Binary file not shown.
Binary file added src/assets/icons/palace/5.webp
Binary file not shown.
Binary file added src/assets/icons/palace/6.webp
Binary file not shown.
Binary file added src/assets/icons/palace/7.webp
Binary file not shown.
Binary file added src/assets/icons/palace/8.webp
Binary file not shown.
Binary file added src/assets/icons/palace/9.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/1.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/10.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/2.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/3.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/4.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/5.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/6.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/7.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/8.webp
Binary file not shown.
Binary file added src/assets/icons/round-bonus/9.webp
Binary file not shown.
Binary file added src/assets/icons/round-score-final/1.webp
Binary file not shown.
Binary file added src/assets/icons/round-score-final/2.webp
Binary file not shown.
Binary file added src/assets/icons/round-score-final/3.webp
Binary file not shown.
Binary file added src/assets/icons/round-score-final/4.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/1-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/1-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/10-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/10-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/11-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/11-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/12-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/12-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/2-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/2-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/3-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/3-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/4-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/4-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/5-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/5-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/6-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/6-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/7-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/7-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/8-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/8-456.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/9-123.webp
Binary file not shown.
Binary file added src/assets/icons/round-score/9-456.webp
Binary file not shown.
Binary file removed src/assets/icons/scoring-tile-game-end-token.png
Binary file not shown.
Binary file removed src/assets/icons/scoring-tile-setup.png
Binary file not shown.
Binary file added src/assets/innovation-display-2player.webp
Binary file not shown.
Binary file added src/assets/innovation-display-3player.webp
Binary file not shown.
Binary file added src/assets/round-score-tile-background.webp
Binary file not shown.
16 changes: 0 additions & 16 deletions src/components/setup/AutomaSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
<p v-html="t('setupGameAutoma.generalSetupIntro')"></p>
<ol>
<li v-if="isTwoPlayerGame" v-html="t('setupGameAutoma.noTwoPlayerSpecialRules')"></li>
<li>
<AppIcon name="scoring-tile-setup" class="scoring-tile-icon"/>
<span v-html="t('setupGameAutoma.roundScoreTiles')"></span>
</li>
<li>
<AppIcon name="scoring-tile-game-end-token" class="scoring-tile-icon"/>
<span v-html="t('setupGameAutoma.gameEndToken')"></span>
</li>
<li v-html="t('setupGameAutoma.palaceTiles', {count:palaceTileCount})"></li>
<li v-if="isTwoHumanPlayers" v-html="t('setupGameAutoma.factionSelectionTwoHumanPlayer')"></li>
<li v-else>
Expand Down Expand Up @@ -146,12 +138,4 @@ li {
height: 1.75rem;
filter: drop-shadow(2px 2px 2px #888);
}
.scoring-tile-icon {
float: right;
height: 6rem;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
margin-left: 1rem;
margin-right: 1rem;
}
</style>
331 changes: 331 additions & 0 deletions src/components/setup/TilesSetup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
<template>
<h4>{{t('setupTiles.roundScore.title')}}</h4>
<div v-html="t('setupTiles.roundScore.intro')"></div>
<div class="roundScoreTiles mb-2">
<img src="@/assets/round-score-tile-background.webp" alt="" class="background"/>
<AppIcon v-for="(tile,index) of setup.roundScoreTiles" :key="tile" type="round-score" extension="webp"
:name="`${tile}-${index < 3 ? '123' : '456'}`" class="roundScoreTileIcon"/><br/>
<AppIcon type="round-score-final" extension="webp" :name="`${setup.roundScoreFinalTile}`" class="roundScoreFinalTileIcon overlay"/>
</div>
<button class="btn btn-sm btn-secondary me-2" data-bs-toggle="modal" data-bs-target="#roundScoreTilesModal">{{t('setupTiles.roundScore.select')}}</button>
<button class="btn btn-sm btn-secondary me-2" @click="randomizeRoundScoreTiles">{{t('action.randomize')}}</button>

<h4 class="mt-3">{{t('setupTiles.other.title')}}</h4>

<div>
<button class="btn btn-outline-secondary me-2 mb-2" data-bs-toggle="collapse" data-bs-target="#randomizedSetup">
{{t('setupTiles.other.randomizer')}} &#x25BC;
</button>
</div>
<div class="collapse mt-2" id="randomizedSetup">
<div class="alert alert-secondary fst-italic">
<span v-html="t('setupTiles.other.notice')"></span>
<button class="btn btn-sm btn-secondary ms-2" @click="randomizeOtherTiles">{{t('action.randomize')}}</button>
</div>

<div class="tilesContainerWrapper">
<div class="bookActions mb-2">
<img src="@/assets/book-actions-background.webp" alt="" class="background"/>
<div>
<AppIcon v-for="tile of setup.setupBookActions" :key="tile" type="book-action" extension="webp" :name="`${tile}`" class="tile"/><br/>
</div>
</div>
</div>

<div class="palaceTiles mb-2">
<AppIcon v-for="id of setup.setupPalaceTiles" :key="id" type="palace" :name="`${id}`" extension="webp" class="tile"/>
<AppIcon type="palace" name="17" extension="webp" class="tile"/>
</div>

<div class="tilesContainerWrapper" v-if="setup.setupInnovationTiles && setup.setupCompetencyTiles">
<div class="innovation" :class="{[`player${totalPlayerCount}`]:true}">
<img v-if="totalPlayerCount == 3" src="@/assets/innovation-display-3player.webp" alt="" class="background"/>
<img v-else src="@/assets/innovation-display-2player.webp" alt="" class="background"/>
<div>
<AppIcon v-for="(id,index) of setup.setupInnovationTiles" :key="id" type="innovation" :name="`${id}`" extension="webp" class="tile"
:class="{[`row${(index >= setup.setupInnovationTiles.length - 4) ? '2' : '1'}`]:true}"/>
</div>
</div>
<div class="competency">
<img src="@/assets/competency-display.webp" alt="" class="background"/>
<AppIcon v-for="(id,index) of setup.setupCompetencyTiles" :key="id" type="competency" :name="`${id}`" extension="webp" class="tile"
:class="{[`row${Math.floor(index / 4) + 1}`]:true}"/>
</div>
</div>

</div>

<ModalDialog id="roundScoreTilesModal" :title="t('setupTiles.roundScore.title')" :size-lg="true">
<template #body>
{{t('setupTiles.roundScore.available')}}<br/>
<AppIcon v-for="tile of roundScoreTilesAllWithoutSelection" :key="tile" type="round-score" extension="webp" :name="`${tile}-123`"
class="roundScoreTileIcon select" @click="selectScoringRoundTile(tile)"/><br/>
<AppIcon v-for="tile of roundScoreFinalTilesAllWithoutSelection" :key="tile" type="round-score-final" extension="webp" :name="`${tile}`"
class="roundScoreFinalTileIcon select" @click="selectScoringRoundFinalTile(tile)"/>
<hr/>
{{t('setupTiles.roundScore.selected')}}<br/>
<AppIcon v-for="(tile,index) of roundScoreTilesSelection" :key="tile" type="round-score" extension="webp" :name="`${tile}-${index < 3 ? '123' : '456'}`"
class="roundScoreTileIcon select" @click="deselectScoringRoundTile(tile)"/>
<AppIcon v-if="roundScoreFinalTileSelection" type="round-score-final" extension="webp" :name="`${roundScoreFinalTileSelection}`" class="roundScoreFinalTileIcon select"
@click="roundScoreFinalTileSelection=undefined"/>
<p v-if="roundScoreTilesSelection.length == 0 && !roundScoreFinalTileSelection" class="fst-italic">
{{t('setupTiles.roundScore.none')}}
</p>
</template>
<template #footer>
<button class="btn btn-outline-secondary" @click="roundScoreTilesSelection=[];roundScoreFinalTileSelection=undefined;">{{t('action.reset')}}</button>
<button class="btn btn-success" data-bs-dismiss="modal" :disabled="!isValidRoundScoreTiles(roundScoreTilesSelection) || !roundScoreFinalTileSelection" @click="setScoringRoundTileSelection">{{t('setupTiles.roundScore.select')}}</button>
<button class="btn btn-secondary" data-bs-dismiss="modal">{{t('action.cancel')}}</button>
</template>
</ModalDialog>

</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import rollDice from '@brdgm/brdgm-commons/src/util/random/rollDice'
import rollDiceMultiDifferentValue from '@brdgm/brdgm-commons/src/util/random/rollDiceMultiDifferentValue'
import AppIcon from '../structure/AppIcon.vue'
import { useStateStore } from '@/store/state'
import ModalDialog from '@brdgm/brdgm-commons/src/components/structure/ModalDialog.vue'
import { range } from 'lodash'
import getRoundScoreTile from '@/util/getRoundScoreTile'
const ROUND_SCORE_TILES_TOTAL = 12
const ROUND_SCORE_TILES_COUNT = 6
const ROUND_SCORE_FINAL_TILES_TOTAL = 4
const BOOK_ACTIONS_TOTAL = 6
const BOOK_ACTIONS_COUNT = 3
const COMPETENCY_TILES_TOTAL = 12
const COMPETENCY_TILES_COUNT = 12
const INNOVATION_TILES_TOTAL = 18
const INNOVATION_TILES_COUNT_2PLAYER = 6
const INNOVATION_TILES_COUNT_3PLAYER = 8
const PALACE_TILES_TOTAL = 16
const PALACE_TILES_COUNT_2PLAYER = 2
const PALACE_TILES_COUNT_3PLAYER = 3
export default defineComponent({
name: 'TilesSetup',
components: {
AppIcon,
ModalDialog
},
setup() {
const { t } = useI18n()
const state = useStateStore()
const { setup } = state
const totalPlayerCount = state.setup.playerSetup.botCount + state.setup.playerSetup.playerCount
const innovationTilesCount = totalPlayerCount == 2 ? INNOVATION_TILES_COUNT_2PLAYER : INNOVATION_TILES_COUNT_3PLAYER
const palaceTilesCount = totalPlayerCount == 2 ? PALACE_TILES_COUNT_2PLAYER : PALACE_TILES_COUNT_3PLAYER
const isValidRoundScoreTiles = function(tiles : number[]) : boolean {
return tiles.length == ROUND_SCORE_TILES_COUNT
// round 5, 6 must not have a spade action
&& !(getRoundScoreTile(tiles[4]).hasSpade || getRoundScoreTile(tiles[5]).hasSpade)
}
const getRandomValidRoundScoreTiles = function() : number[] {
const result = rollDiceMultiDifferentValue(ROUND_SCORE_TILES_TOTAL, ROUND_SCORE_TILES_COUNT)
if (!isValidRoundScoreTiles(result)) {
return getRandomValidRoundScoreTiles()
}
return result
}
setup.roundScoreTiles = setup.roundScoreTiles ?? getRandomValidRoundScoreTiles()
setup.roundScoreFinalTile = setup.roundScoreFinalTile ?? rollDice(ROUND_SCORE_FINAL_TILES_TOTAL)
const roundScoreTilesSelection = ref([] as number[])
const roundScoreFinalTileSelection = ref(undefined as number|undefined)
setup.setupBookActions = setup.setupBookActions ?? rollDiceMultiDifferentValue(BOOK_ACTIONS_TOTAL, BOOK_ACTIONS_COUNT)
setup.setupCompetencyTiles = setup.setupCompetencyTiles ?? rollDiceMultiDifferentValue(COMPETENCY_TILES_TOTAL, COMPETENCY_TILES_COUNT)
setup.setupInnovationTiles = setup.setupInnovationTiles ?? rollDiceMultiDifferentValue(INNOVATION_TILES_TOTAL, innovationTilesCount)
setup.setupPalaceTiles = setup.setupPalaceTiles ?? rollDiceMultiDifferentValue(PALACE_TILES_TOTAL, palaceTilesCount)
return { t, state, setup, totalPlayerCount, innovationTilesCount, palaceTilesCount,
roundScoreTilesSelection, roundScoreFinalTileSelection,
isValidRoundScoreTiles, getRandomValidRoundScoreTiles }
},
computed: {
gameBoardPlayerCount(): string {
if (this.totalPlayerCount > 2) {
return '3-4'
}
else {
return '1-2'
}
},
roundScoreTilesAllWithoutSelection() : number[] {
return range(1, ROUND_SCORE_TILES_TOTAL+1).filter(tile => !this.roundScoreTilesSelection.includes(tile))
},
roundScoreFinalTilesAllWithoutSelection() : number[] {
return range(1, ROUND_SCORE_FINAL_TILES_TOTAL+1).filter(tile => tile != this.roundScoreFinalTileSelection)
}
},
methods: {
randomizeRoundScoreTiles() : void {
this.setup.roundScoreTiles = this.getRandomValidRoundScoreTiles()
this.setup.roundScoreFinalTile = rollDice(ROUND_SCORE_FINAL_TILES_TOTAL)
this.roundScoreTilesSelection = []
this.roundScoreFinalTileSelection = undefined
},
selectScoringRoundTile(tile: number) : void {
if (this.roundScoreTilesSelection.length < ROUND_SCORE_TILES_COUNT) {
this.roundScoreTilesSelection.push(tile)
}
},
deselectScoringRoundTile(tile: number) : void {
this.roundScoreTilesSelection = this.roundScoreTilesSelection.filter(t => t != tile)
},
selectScoringRoundFinalTile(tile: number) : void {
this.roundScoreFinalTileSelection = tile
},
setScoringRoundTileSelection() : void {
this.setup.roundScoreTiles = this.roundScoreTilesSelection
this.setup.roundScoreFinalTile = this.roundScoreFinalTileSelection
},
randomizeOtherTiles() : void {
this.setup.setupBookActions = rollDiceMultiDifferentValue(BOOK_ACTIONS_TOTAL, BOOK_ACTIONS_COUNT)
this.setup.setupCompetencyTiles = rollDiceMultiDifferentValue(COMPETENCY_TILES_TOTAL, COMPETENCY_TILES_COUNT)
this.setup.setupInnovationTiles = rollDiceMultiDifferentValue(INNOVATION_TILES_TOTAL, this.innovationTilesCount)
this.setup.setupPalaceTiles = rollDiceMultiDifferentValue(PALACE_TILES_TOTAL, this.palaceTilesCount)
}
}
})
</script>

<style lang="scss" scoped>
.roundScoreTiles {
position: relative;
display: flex;
flex-direction: column-reverse;
.background {
position: absolute;
width: 150px;
opacity: 50%;
border-radius: 5px;
z-index: -100;
filter: drop-shadow(2px 2px 2px #888);
}
}
.roundScoreTileIcon {
width: 130px;
margin-left: 10px;
margin-bottom: 8px;
object-fit: contain;
&.select {
cursor: pointer;
}
}
.roundScoreFinalTileIcon {
width: 65px;
margin-left: 10px;
margin-bottom: 8px;
&.overlay {
position: absolute;
left: 66px;
top: 24px;
}
&.select {
cursor: pointer;
}
}
.tilesContainerWrapper {
width: 100%;
overflow-x: auto;
}
.bookActions {
position: relative;
height: 75px;
width: 400px;
.background {
position: absolute;
width: 400px;
opacity: 50%;
border-radius: 5px;
z-index: -100;
filter: drop-shadow(2px 2px 2px #888);
}
.tile {
width: 118px;
margin-top: 7px;
margin-left: 7px;
margin-right: 9px;
&:nth-child(3n) {
margin-right: 0;
}
}
}
.palaceTiles .tile {
width: 130px;
margin-right: 10px;
filter: drop-shadow(2px 2px 2px #888);
}
.innovation {
position: relative;
width: 600px;
height: 300px;
.background {
position: absolute;
width: 600px;
opacity: 50%;
z-index: -100;
filter: drop-shadow(2px 2px 2px #888);
}
.tile {
width: 125px;
margin-top: 24px;
margin-left: 8px;
margin-right: 18px;
}
&.player2 {
.tile.row1 {
margin-top: 48px;
margin-left: 90px;
margin-right: 82px;
}
.tile.row2 {
margin-top: 80px;
margin-left: 11px
}
.tile:nth-child(2), .tile:nth-child(6) {
margin-right: 0;
}
}
&.player3 {
.tile.row1 {
margin-top: 90px;
}
.tile:nth-child(4n) {
margin-right: 0;
}
}
}
.competency {
position: relative;
width: 600px;
height: 350px;
margin-top: -25px;
.background {
position: absolute;
width: 600px;
opacity: 50%;
z-index: -150;
filter: drop-shadow(2px 2px 2px #888);
}
.tile {
width: 74px;
margin-top: 16px;
margin-left: 65px;
margin-right: 9px;
&:nth-child(4n-2) {
margin-left: 58px;
}
&.row1 {
margin-top: 80px;
}
}
}
</style>
Loading

0 comments on commit fc146f4

Please sign in to comment.