Two teams try and fill in any horizontal, vertical, or diagonal line on a bingo board by playing maps on osu! osu.bingo
osu
at microservice 60 lines 1.7 kB view raw
1<script lang="ts"> 2 import { checkWin } from '$lib/bingo-helpers/check_win'; 3 import type { Writable } from 'svelte/store'; 4 5 export let cardStore: Writable<Bingo.Card | null>; 6 export let cardPadding = 5; 7 export let padding = 5; 8 export let labels = true; 9 export let rounded = true; 10 11 let yMax: number; 12 let xMax: number; 13 14 let winningLine: number[] | null = null; 15 16 const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 17 18 cardStore.subscribe((card) => { 19 if (!card) return; 20 21 if (card.squares) { 22 yMax = Math.max(...card.squares.map((x) => x.y_pos)); 23 xMax = Math.max(...card.squares.map((x) => x.x_pos)); 24 } 25 const win = checkWin(card); 26 if (win) { 27 winningLine = win.line; 28 } 29 }); 30</script> 31 32<div 33 class="grid w-full rounded p-[var(--p2)]" 34 style=" 35 --p2: {cardPadding}px; 36 grid-template-columns: repeat({xMax + 1}, {xMax + 1}fr); 37 grid-template-rows: repeat({yMax + 1}, {yMax + 1}fr); 38 aspect-ratio: {xMax + 1} / {yMax + 1} 39 " 40> 41 {#if $cardStore && $cardStore.squares} 42 {#each $cardStore.squares as square, i} 43 <div 44 class="p-[var(--p)]" 45 style="grid-area: {square.y_pos + 1} / {square.x_pos + 1} / {square.y_pos + 46 2} / {square.x_pos + 2}; --p: {padding}px; --r: {rounded ? padding : 0}px" 47 > 48 <div 49 class="flex size-full items-center justify-center rounded-[var(--r)] bg-base-700 font-rounded text-2xl font-black text-white/50 data-[winning=true]:animate-pulse data-[team=BLUE]:bg-blue-600 data-[team=RED]:bg-red-500" 50 data-team={square.claimed_by?.team_name.toUpperCase()} 51 data-winning={winningLine?.includes(i)} 52 > 53 {#if labels} 54 {alphabet.charAt(square.x_pos)}{square.y_pos + 1} 55 {/if} 56 </div> 57 </div> 58 {/each} 59 {/if} 60</div>