Generate lottery numbers
Voor pubquiz
by PhilQ
HTML
<button onclick="window.print();">Print</button>
<div id="app">
<div id="controls">
Eerste nummer: <input type="number" v-model="number_start"/><br/>
Laatste nummer: <input type="number" v-model="number_end"/><br/>
Aantal teams: <input type="number" v-model="number_of_teams"/><br/>
<input type="checkbox" v-model="distribute_leftovers"/> Overgebleven nummers verdelen over teams<br/>
<input type="checkbox" v-model="mark_starts"/> Markeer eerste nummer per team<br/>
<input type="checkbox" v-model="mark_leftovers"/> Markeer overgebleven nummers<br/>
</div>
<div class="number"
v-for="(v,i) in a"
:class="{ 'underline':isUnderline(v), 'start':isStart(i), 'leftover':isLeftover(i) }"
>{{ v }}</div>
</div>
SCSS
*,::before,::after {
margin: 0; padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
font-family: sans-serif;
}
#app {
width: 680px;
display: block;
margin: 0px auto;
}
button {
position: fixed;
top: 20px;
right: 20px;
font-size: 18px;
padding: 5px 10px;
}
@media print {
button, #controls {
display: none;
}
}
.number {
position: relative;
float: left;
font-family: sans-serif;
font-weight: bold;
font-size: 50px;
display: inline-block;
padding: 10px;
border: 2px solid #ccc;
width: 85px;
height: 85px;
text-align: center;
&.start::before, &.leftover::before {
content: '';
position: absolute;
top: 3px;
left: 3px;
border-radius: 50%;
width: 6px;
height: 6px;
border: 3px solid #ccc;
}
&.leftover::after {
content: '';
position: absolute;
top: 3px;
left: 11px;
border-radius: 50%;
width: 6px;
height: 6px;
border: 3px solid #ccc;
}
}
.underline {
text-decoration: underline;
}
Vue
new Vue({
el: "#app",
data: {
number_start: 1,
number_end: 64,
number_of_teams: 1,
mark_starts: true,
mark_leftovers: true,
distribute_leftovers: true,
a: [],
},
computed: {
per_team: function() {
return Math.floor(this.a.length/this.number_of_teams);
},
left_over: function() {
return this.a.length-this.per_team*this.number_of_teams;
},
},
methods: {
number_range(start, end) {
return new Array(end - start).fill().map((d, i) => i + start);
},
shuffle_fisher_yates(array) {
var m = array.length, t, i;
// While there remain elements to shuffle
while (m) {
// Pick a remaining element
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
},
isUnderline(v) {
return /^([69][689]*|8[69][689]*)$/gi.test(v);
},
isStart(i) {
return this.mark_starts && (
(
this.distribute_leftovers &&
(
(
0 == i % (this.per_team+1) &&
Math.floor(i/(this.per_team+1)) < this.left_over
) || (
i >= this.left_over * (this.per_team+1) &&
(i - this.left_over * (this.per_team+1)) % this.per_team == 0
)
)
) || (
!this.distribute_leftovers &&
i % this.per_team == 0 &&
i < (this.number_of_teams * this.per_team)
)
);
},
isLeftover(i) {
return this.mark_leftovers && (
(
!this.distribute_leftovers &&
i >= this.per_team*this.number_of_teams
) || (
this.distribute_leftovers &&
i < this.left_over * (this.per_team+1) &&
0 == (i-this.per_team) % (this.per_team+1)
)
);
},
generateList() {
if (
/\-?[0-9]+/.test(this.number_start) &&
/\-?[0-9]+/.test(this.number_end) &&
this.number_end >= this.number_start &&
this.number_of_teams > 0
) {
this.a = this.shuffle_fisher_yates(
this.number_range(
parseInt(this.number_start),
parseInt(this.number_end)+1
)
);
} else {
this.a = [];
}
},
},
...