A presentation at EmberFest in September 2022 in Paris, France by Anne-Greeth van Herwijnen
SET
SET THE CARD GAME By Anne-Greeth Schot-van Herwijnen
SHAPE
SHAPE FILLING
SHAPE FILLING AMOUNT
SHAPE FILLING COLOR AMOUNT GREEN RED PURPLE
SO WHAT’S A SET?
isSet(cardA, cardB, cardC) { return ( this.validateProps(cardA.shape, cardB.shape, cardC.shape) && this.validateProps(cardA.amount, cardB.amount, cardC.amount) && this.validateProps(cardA.filling, cardB.filling, cardC.filling) && this.validateProps(cardA.color, cardB.color, cardC.color) ); }
validateProps(propCardA, propCardB, propCardC) { return (propCardA === propCardB && propCardB === propCardC) || (propCardA !== propCardB && propCardA !== propCardC && propCardB !== propCardC); }
~% EMBER GENERATE COMPONENT CARD
<button …attributes data-test-card type=”button” {{on “click” (fn this.handleClick @image) }} local-class=”button {{if @selected “selected” “”}} {{if @wrong “wrong”}} {{if @hint “hint”}}”> <img src={{@image}} alt={{@image}} local-class=”img”/> </button>
<button …attributes data-test-card type=”button” {{on “click” (fn this.handleClick @image) }} local-class=”button {{if @selected “selected” “”}} {{if @wrong “wrong”}} {{if @hint “hint”}}”> <img src={{@image}} alt={{@image}} local-class=”img”/> </button> .button.hint { border: 3px dashed #4caf50; } .button.selected { border: 3px solid orange; } .button.wrong { border: 3px solid red; animation: shake … transform: translateX(0, 0, 0); }
<button …attributes data-test-card type=”button” {{on “click” (fn this.handleClick @image) }} local-class=”button {{if @selected “selected” “”}} {{if @wrong “wrong”}} {{if @hint “hint”}}”> <img src={{@image}} alt={{@image}} local-class=”img”/> </button> .button.hint { border: 3px dashed #4caf50; } .button.selected { border: 3px solid orange; } .button.wrong { border: 3px solid red; animation: shake … transform: translateX(0, 0, 0); } @keyframes shake { 10%, 90% { transform: translateX(-1px); } 20%, 80% { transform: translateX(2px); } 30%, 50%, 70% { transform: translateX(-4px); } 40%, 60% { transform: translateX(4px); } }
~% EMBER GENERATE COMPONENT PLAYINGFIELD
@task *timerTask() { while (true) { yield new Promise((resolve) => setTimeout(resolve, 1000)); this.time = Math.floor((Date.now() - this.startTime) / 1000); } }
@action getHint() { const combinations = this.k_combinations(this.field, 3); let foundSet = combinations.find((comb) => this.isSet(…comb)); foundSet[Math.floor(Math.random() * 3)].hint = true; if (this.hintsActive < 3) { this.hintCounter++; this.hintsActive++; } }
let highscoresString = localStorage.getItem(‘highscores’); this.highscores = JSON.parse(highscoresString)?.sort((a, b) => a > b) localStorage.setItem(‘highscores’, JSON.stringify(this.highscores)); localStorage.clear();
“ember-web-app”: “^5.0.1”
MULTIPLAYER COLOR PICKING
SET-THE-GAME.NETLIFY.APP GITHUB: @MINTHAMIE TWITTER: @AGVANHERWIJNEN INSTAGRAM: @A.G.VANHERWIJNEN NOTIST: NOTI.ST/MINTHAMIE
View Set! on Notist.
Dismiss
How I built a simple PWA for playing Set the card game