328 lines
8.3 KiB
Vue
328 lines
8.3 KiB
Vue
<script setup>
|
|
import { ref, onBeforeMount } from 'vue'
|
|
|
|
// reactive state
|
|
const count = ref(0)
|
|
const boardSize = ref(5)
|
|
const boardNumber = ref(5)
|
|
|
|
let centerTasks = [
|
|
'Say [hello|good day|greetings|greetings|good gravy|hinklty-pinklty|hello|hello|congrats] to Max and Grace.'
|
|
]
|
|
let innerTasks = [
|
|
`Find someone who speaks a language other than English.`,
|
|
`Have someone tell you a [real life|fond|funny] story about [Max|Grace].`,
|
|
`Dance all out to [a fun|a slow|any] song.`,
|
|
`Introduce yourself to the [bride's|groom's] family.`,
|
|
`Find someone who just met Max or Grace today.`,
|
|
`Pick up some trash that didn't make it to the garbage can.`,
|
|
`Ask someone how they met [Max|Grace|Max's Family|Grace's Family].`,
|
|
`Ask someone how they met another guest at the party.`,
|
|
`Ask someone you don't know what they do for work.`,
|
|
]
|
|
let outerTasks = [
|
|
`Figure out Max's preferred aerial apparatus.`,
|
|
`Learn a fact about [Max|Grace]'s immediate family.`,
|
|
`Find one of [Max|Grace]'s college roommates.`,
|
|
`Find someone who knows what "504" is.`,
|
|
`Make a [heartwarming toast|30 second speech|funny toast].`,
|
|
`Talk to someone who has lived in [Japan|Brazil|Europe|China].`,
|
|
`Low five someone who has done Jiu-Jitsu with Max.`,
|
|
`High five someone who has played Frisbee with [Max|Grace].`,
|
|
`Find someone who has done aerial with Grace.`,
|
|
`Meet Max's Grandma.`,
|
|
`Meet all of Max's and Grace's brothers.`,
|
|
`Meet a Mingo manager. The Blue Mingo a truly memorable experience.`,
|
|
`Find [Max's|Grace's] best childhood friend.`,
|
|
`Find someone with a Clark Sports Center membership.`,
|
|
`Find someone who lives in [Arizona|Massachusetts|California|Colorado].`,
|
|
`Find someone who has actually enjoyed the baseball hall of fame.`,
|
|
`Find someone who has stayed at Grace's parent's house`,
|
|
`Learn an [outrageous|embarrassing] story about [Max|Grace].`,
|
|
`Check yourself for ticks.`,
|
|
`Make a new friend.`,
|
|
`Count Grace's cousins.`,
|
|
`Meet Max's cousins.`,
|
|
`High five a child with consent.`,
|
|
`Do a [covert handshake|elaborate handshake] with someone who [runs|wore a tie|has cool hair].`,
|
|
`Find someone with [pets|a baby] and look at their pictures.`,
|
|
`Find the wedding crasher.`,
|
|
`Catch up with someone you haven't seen in awhile`,
|
|
`Learn Max's latest nerdy hobby.`,
|
|
`Find someone who has never been to Cooperstown before.`,
|
|
`Find someone who is a [teacher|nurse].`,
|
|
`Take a joyful selfie with [a friend|someone you just met] & send it to Max.`
|
|
]
|
|
|
|
const hardnessMap = {
|
|
11:'innerTasks',
|
|
12:'innerTasks',
|
|
13:'innerTasks',
|
|
|
|
21:'innerTasks',
|
|
22:'centerTasks',
|
|
23:'innerTasks',
|
|
|
|
31:'innerTasks',
|
|
32:'innerTasks',
|
|
33:'innerTasks',
|
|
}
|
|
|
|
|
|
function shuffle(array, seed){
|
|
|
|
// pseudo-random array shuffle
|
|
let arrayClone = [...array]
|
|
let psudoShuffledArray = []
|
|
for (var i = arrayClone.length - 1; i >= 0; i--) {
|
|
|
|
const seedIteration = polynomialRollingHash(seed+i)
|
|
const psudoRandomIndex = seedIteration % arrayClone.length
|
|
const nextTask = arrayClone.splice( psudoRandomIndex, 1 )
|
|
psudoShuffledArray.push(nextTask[0])
|
|
|
|
}
|
|
|
|
return psudoShuffledArray
|
|
}
|
|
|
|
|
|
function getBoardArray(seed){
|
|
|
|
let setupCenterTasks = shuffle([...centerTasks], seed)
|
|
let setupInnerTasks = shuffle([...innerTasks], seed)
|
|
let setupOuterTasks = shuffle([...outerTasks], seed)
|
|
|
|
|
|
// Final setup for board, iterate in template
|
|
let setupBoard = []
|
|
|
|
for (var i = 0; i < 5; i++) {
|
|
for (var k = 0; k < 5; k++) {
|
|
|
|
const hardness = hardnessMap[parseInt(`${i}${k}`)] || 'outerTasks'
|
|
|
|
let text = 'nay'
|
|
if(hardness == 'innerTasks'){
|
|
text = setupInnerTasks.pop()
|
|
}
|
|
if(hardness == 'centerTasks'){
|
|
text = setupCenterTasks.pop()
|
|
}
|
|
if(hardness == 'outerTasks'){
|
|
text = setupOuterTasks.pop()
|
|
}
|
|
|
|
setupBoard.push(text)
|
|
|
|
}
|
|
}
|
|
|
|
return setupBoard
|
|
|
|
}
|
|
|
|
function polynomialRollingHash(str){
|
|
|
|
str = String(str)
|
|
|
|
// P and M
|
|
let p = 31;
|
|
let m = (1e9 + 9);
|
|
let power_of_p = 1;
|
|
let hash_val = 0;
|
|
|
|
// Loop to calculate the hash value
|
|
// by iterating over the elements of String
|
|
for(let i = 0; i < str.length; i++)
|
|
{
|
|
hash_val = (hash_val + (str[i].charCodeAt() -
|
|
'a'.charCodeAt() + 1) * power_of_p) % m;
|
|
power_of_p = (power_of_p * p) % m;
|
|
}
|
|
return Math.abs(hash_val);
|
|
}
|
|
|
|
function getTitle(){
|
|
|
|
let text = 'Bingo'
|
|
let rand = Math.floor(Math.random() * 100)
|
|
|
|
if(rand > 85){
|
|
text = 'Bingle'
|
|
}
|
|
|
|
return text
|
|
}
|
|
|
|
function getSubtitle(boardNumber){
|
|
|
|
let text = 'Error'
|
|
|
|
switch(boardNumber % 4){
|
|
case 0:
|
|
text = 'Small talk boring, bingo is fun! Use this bingo board to be social. Fill 5 in a row for a chance to win a prize.'
|
|
break;
|
|
case 1:
|
|
text = 'Mingle and play bingo! Chat with other guests. Fill 5 boxes in a row. Submit for a chance to win a prize!'
|
|
break;
|
|
case 2:
|
|
text = 'Fill in 5 in a row for a chance to win a prize. Get the answers from other guests. Surely someone here can be of assistance.'
|
|
break;
|
|
case 3:
|
|
text = 'Talking to other people is hard. Perhaps this bingo board can motivate you. Get some answers. Fill in 5 in a row for a chance to win!'
|
|
break;
|
|
}
|
|
|
|
return text
|
|
}
|
|
|
|
|
|
function fillOutTaskOptions(array){
|
|
// fill out array options
|
|
for (var i = array.length - 1; i >= 0; i--) {
|
|
|
|
let task = array[i]
|
|
|
|
if(task.indexOf('|') > -1){
|
|
let filledOptions = [task]
|
|
|
|
// count brackets
|
|
let totalOptions = (task.match(/\[/g) || []).length || 0
|
|
|
|
// iterate over set of options [],[] -> 2
|
|
for (var k = 0; k < totalOptions; k++) {
|
|
|
|
// total options in each
|
|
let optionsRaw = task.match(/\[(.*?)\]/g)[k].replaceAll('[','').replaceAll(']','')
|
|
let options = optionsRaw.split('|')
|
|
|
|
for (var x = filledOptions.length - 1; x >= 0; x--) {
|
|
options.forEach(option => {
|
|
let replacedOption = filledOptions[x].replace(/\[.*?\]/, option)
|
|
filledOptions.push(replacedOption)
|
|
})
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
// clean up array
|
|
filledOptions = filledOptions.filter(v => v.indexOf('[') == -1)
|
|
|
|
// after cleaning filled options, push into array, remove current entry
|
|
array.splice(i,1)
|
|
array.push(...filledOptions)
|
|
}
|
|
}
|
|
|
|
return array
|
|
}
|
|
|
|
let boards = []
|
|
onBeforeMount(() => {
|
|
|
|
// Fill out options in each array
|
|
centerTasks = fillOutTaskOptions(centerTasks)
|
|
innerTasks = fillOutTaskOptions(innerTasks)
|
|
outerTasks = fillOutTaskOptions(outerTasks)
|
|
|
|
console.log('Inner Tasks: ' + innerTasks.length)
|
|
console.log('Outer Tasks: ' + outerTasks.length)
|
|
|
|
const totalBoards = 50
|
|
|
|
for (var i = totalBoards - 1; i >= 0; i--) {
|
|
boards.push(getBoardArray(i))
|
|
}
|
|
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
|
|
<div class="board" v-for="(board,boardNumber) in boards">
|
|
<h2 class="board-title">
|
|
Wedding Mingle {{ getTitle() }}
|
|
<span class="float-right grey">Board #{{ boardNumber+1 }}</span>
|
|
<p class="sub-title grey">
|
|
{{ getSubtitle(boardNumber) }}
|
|
<span class="name-field float-right">Name _________________________</span>
|
|
</p>
|
|
</h2>
|
|
|
|
<div class="tile" v-for="task in board">
|
|
<span>{{ task }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
</template>
|
|
|
|
<style scoped>
|
|
.board {
|
|
width: calc(100vw - 15px);
|
|
height: 100vh;
|
|
flex-direction: row;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-content: flex-start;
|
|
}
|
|
.tile {
|
|
width: 20%;
|
|
height: 110px;
|
|
outline: 1px dashed grey;
|
|
display: inline-block;
|
|
text-align: center;
|
|
overflow: hidden;
|
|
font-size: 14px;
|
|
word-break: break-word;
|
|
position: relative;
|
|
}
|
|
.tile > span {
|
|
display: inline-block;
|
|
position: relative;
|
|
/* top: 50%;
|
|
-webkit-transform: translateY(-50%);
|
|
-ms-transform: translateY(-50%);
|
|
transform: translateY(-50%);*/
|
|
overflow-wrap: break-word;
|
|
word-break: break-word;
|
|
hyphens: auto;
|
|
border-bottom: 1px solid black;
|
|
position: absolute;
|
|
top: 5px;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 15px;
|
|
margin: 0 10px;
|
|
}
|
|
|
|
.board-title {
|
|
width: 100%;
|
|
text-align: left;
|
|
padding: 20px 0;
|
|
font-size: 2em;
|
|
line-height: 30px;
|
|
}
|
|
.sub-title {
|
|
width: 100%;
|
|
display: inline-block;
|
|
font-size: 12px;
|
|
}
|
|
.float-right {
|
|
float: right;
|
|
}
|
|
.name-field {
|
|
display: inline-block;
|
|
color: black;
|
|
}
|
|
.grey {
|
|
color: #6b6b6b !important;
|
|
}
|
|
.page-break {
|
|
page-break-after:always;
|
|
}
|
|
</style> |