Last active
February 6, 2019 20:34
-
-
Save sukima/156293e8b441570dee285a0ca062f768 to your computer and use it in GitHub Desktop.
Card Shuffle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Component from '@ember/component'; | |
import { computed } from '@ember/object'; | |
import { reads } from '@ember/object/computed'; | |
import { htmlSafe } from '@ember/string'; | |
import { SUITS, JOKER } from '../libs/card'; | |
const SUIT_MAP = Object.freeze({ | |
[SUITS.CLUBS]: 'clubs', | |
[SUITS.DIAMONDS]: 'diams', | |
[SUITS.HEARTS]: 'hearts', | |
[SUITS.SPADES]: 'spades' | |
}); | |
const JOKER_RANK_MAP = Object.freeze({ | |
[JOKER.A]: 'big', | |
[JOKER.B]: 'little' | |
}); | |
export default Component.extend({ | |
tagName: 'span', | |
classNames: ['card'], | |
classNameBindings: ['rankClass', 'suitClass'], | |
rankClass: computed('data.{isJoker,rank}', function() { | |
return this.data.isJoker | |
? JOKER_RANK_MAP[this.data.rank] | |
: `rank-${this.data.rank}`; | |
}), | |
suitClass: computed('data.{isJoker,rank,suit}', function() { | |
return this.data.isJoker | |
? 'joker' | |
: SUIT_MAP[this.data.suit]; | |
}), | |
rank: computed('data.rank', function() { | |
return `${this.data.rank}`.toUpperCase(); | |
}), | |
suit: computed('data.{isJoker,suit}', function() { | |
return this.data.isJoker | |
? 'Joker' | |
: htmlSafe(`&${SUIT_MAP[this.data.suit]};`); | |
}) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Controller from '@ember/controller'; | |
import { computed } from '@ember/object'; | |
import move from 'ember-animated/motions/move'; | |
import adjustCSS from 'ember-animated/motions/adjust-css'; | |
import { serial } from 'ember-animated'; | |
import { task, timeout } from 'ember-concurrency'; | |
import { orderedDeck, shuffledDeck } from '../libs/deck'; | |
import { JOKER } from '../libs/card'; | |
export default Controller.extend({ | |
deck: orderedDeck(), | |
transition: function * (context) { | |
let { keptSprites } = context; | |
keptSprites.forEach(move); | |
}, | |
jokers: computed('deck', function() { | |
let jokers = this.deck.filterBy('isJoker'); | |
return jokers[0].rank === JOKER.A | |
? { A: jokers[0], B: jokers[1] } | |
: { A: jokers[1], B: jokers[0] }; | |
}), | |
cryptoSequence: task(function* () { | |
this.move(this.jokers.A, -1); | |
yield timeout(1000); | |
this.move(this.jokers.B, -2); | |
yield timeout(2000); | |
yield this.jokerCutFlip.perform(); | |
}).drop(), | |
jokerCutFlip: task(function* () { | |
let jokers = []; | |
for (let i = 0; i < this.deck.length && jokers.length < 2; i++) { | |
if (this.deck.objectAt(i).isJoker) jokers.push(i); | |
} | |
let [jokerA, jokerB] = jokers; | |
let sets = [ | |
this.deck.slice(0, jokerA), | |
this.deck.slice(jokerA, jokerB + 1), | |
this.deck.slice(jokerB + 1) | |
]; | |
this.set('deck', sets[2].concat(sets[1], sets[0])); | |
}).drop(), | |
shuffle() { | |
this.set('deck', shuffledDeck()); | |
}, | |
move(card, count) { | |
let len = this.deck.length; | |
let fromIndex = this.deck.indexOf(card); | |
let toIndex = (fromIndex + count + len) % len; | |
this.deck.splice(fromIndex, 1); | |
this.deck.splice(toIndex, 0, card); | |
this.deck.arrayContentDidChange(fromIndex, 0, 0); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import EmberObject from '@ember/object'; | |
import { equal, or } from '@ember/object/computed'; | |
export const SUITS = Object.freeze({ | |
CLUBS: 1, | |
DIAMONDS: 2, | |
HEARTS: 3, | |
SPADES: 4 | |
}); | |
export const RANKS = Object.freeze({ | |
ACE: 'a', | |
TWO: 2, | |
THREE: 3, | |
FOUR: 4, | |
FIVE: 5, | |
SIX: 6, | |
SEVEN: 7, | |
EIGHT: 8, | |
NINE: 9, | |
TEN: 10, | |
JACK: 'j', | |
QUEEN: 'q', | |
KING: 'k' | |
}); | |
export const JOKER = Object.freeze({ | |
A: '+', | |
B: '-' | |
}); | |
export const Card = EmberObject.extend(); | |
export const Joker = Card.extend({ | |
isJoker: true, | |
suit: 'joker' | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Card, Joker, SUITS, RANKS, JOKER } from './card'; | |
export function orderedDeck() { | |
const { SPADES, HEARTS, DIAMONDS, CLUBS } = SUITS; | |
let id = 1; | |
let deck = [ | |
Joker.create({ id: id++, rank: JOKER.B }), | |
Joker.create({ id: id++, rank: JOKER.A }) | |
]; | |
for (let suit of suitsBridgeOrder()) { | |
for (let rank of ranksBridgeOrder()) { | |
deck.push(Card.create({ id: id++, rank, suit })); | |
} | |
} | |
return deck; | |
} | |
export function shuffledDeck() { | |
const { floor, random } = Math; | |
let deck = orderedDeck(); | |
let counter = deck.length; | |
while (counter > 0) { | |
let index = floor(random() * counter); | |
counter--; | |
let temp = deck[counter]; | |
deck[counter] = deck[index]; | |
deck[index] = temp; | |
} | |
return deck; | |
} | |
export function * suitsBridgeOrder() { | |
yield SUITS.SPADES; | |
yield SUITS.HEARTS; | |
yield SUITS.DIAMONDS; | |
yield SUITS.CLUBS; | |
} | |
export function * ranksBridgeOrder() { | |
yield RANKS.KING; | |
yield RANKS.QUEEN; | |
yield RANKS.JACK; | |
yield RANKS.TEN; | |
yield RANKS.NINE; | |
yield RANKS.EIGHT; | |
yield RANKS.SEVEN; | |
yield RANKS.SIX; | |
yield RANKS.FIVE; | |
yield RANKS.FOUR; | |
yield RANKS.THREE; | |
yield RANKS.TWO; | |
yield RANKS.ACE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.full-deck { | |
position: relative; | |
height: 132px; | |
padding: 0; | |
} | |
.full-deck .card { | |
position: absolute; | |
width: 63px; | |
height: 88px; | |
bottom: 0px; | |
box-shadow: none; | |
} | |
.full-deck .card.joker, | |
.full-deck .card.selected { | |
bottom: 15px; | |
} | |
.full-deck .card:nth-child(1) { left: calc(0 * 15px); z-index: 2; } | |
.full-deck .card:nth-child(2) { left: calc(1 * 15px); z-index: 3; } | |
.full-deck .card:nth-child(3) { left: calc(2 * 15px); z-index: 4; } | |
.full-deck .card:nth-child(4) { left: calc(3 * 15px); z-index: 5; } | |
.full-deck .card:nth-child(5) { left: calc(4 * 15px); z-index: 6; } | |
.full-deck .card:nth-child(6) { left: calc(5 * 15px); z-index: 7; } | |
.full-deck .card:nth-child(7) { left: calc(6 * 15px); z-index: 8; } | |
.full-deck .card:nth-child(8) { left: calc(7 * 15px); z-index: 9; } | |
.full-deck .card:nth-child(9) { left: calc(8 * 15px); z-index: 10; } | |
.full-deck .card:nth-child(10) { left: calc(9 * 15px); z-index: 11; } | |
.full-deck .card:nth-child(11) { left: calc(10 * 15px); z-index: 12; } | |
.full-deck .card:nth-child(12) { left: calc(11 * 15px); z-index: 13; } | |
.full-deck .card:nth-child(13) { left: calc(12 * 15px); z-index: 14; } | |
.full-deck .card:nth-child(14) { left: calc(13 * 15px); z-index: 15; } | |
.full-deck .card:nth-child(15) { left: calc(14 * 15px); z-index: 16; } | |
.full-deck .card:nth-child(16) { left: calc(15 * 15px); z-index: 17; } | |
.full-deck .card:nth-child(17) { left: calc(16 * 15px); z-index: 18; } | |
.full-deck .card:nth-child(18) { left: calc(17 * 15px); z-index: 19; } | |
.full-deck .card:nth-child(19) { left: calc(18 * 15px); z-index: 20; } | |
.full-deck .card:nth-child(20) { left: calc(19 * 15px); z-index: 21; } | |
.full-deck .card:nth-child(21) { left: calc(20 * 15px); z-index: 22; } | |
.full-deck .card:nth-child(22) { left: calc(21 * 15px); z-index: 23; } | |
.full-deck .card:nth-child(23) { left: calc(22 * 15px); z-index: 24; } | |
.full-deck .card:nth-child(24) { left: calc(23 * 15px); z-index: 25; } | |
.full-deck .card:nth-child(25) { left: calc(24 * 15px); z-index: 26; } | |
.full-deck .card:nth-child(26) { left: calc(25 * 15px); z-index: 27; } | |
.full-deck .card:nth-child(27) { left: calc(26 * 15px); z-index: 28; } | |
.full-deck .card:nth-child(28) { left: calc(27 * 15px); z-index: 29; } | |
.full-deck .card:nth-child(29) { left: calc(28 * 15px); z-index: 30; } | |
.full-deck .card:nth-child(30) { left: calc(29 * 15px); z-index: 31; } | |
.full-deck .card:nth-child(31) { left: calc(30 * 15px); z-index: 32; } | |
.full-deck .card:nth-child(32) { left: calc(31 * 15px); z-index: 33; } | |
.full-deck .card:nth-child(33) { left: calc(32 * 15px); z-index: 34; } | |
.full-deck .card:nth-child(34) { left: calc(33 * 15px); z-index: 35; } | |
.full-deck .card:nth-child(35) { left: calc(34 * 15px); z-index: 36; } | |
.full-deck .card:nth-child(36) { left: calc(35 * 15px); z-index: 37; } | |
.full-deck .card:nth-child(37) { left: calc(36 * 15px); z-index: 38; } | |
.full-deck .card:nth-child(38) { left: calc(37 * 15px); z-index: 39; } | |
.full-deck .card:nth-child(39) { left: calc(38 * 15px); z-index: 40; } | |
.full-deck .card:nth-child(40) { left: calc(39 * 15px); z-index: 41; } | |
.full-deck .card:nth-child(41) { left: calc(40 * 15px); z-index: 42; } | |
.full-deck .card:nth-child(42) { left: calc(41 * 15px); z-index: 43; } | |
.full-deck .card:nth-child(43) { left: calc(42 * 15px); z-index: 44; } | |
.full-deck .card:nth-child(44) { left: calc(43 * 15px); z-index: 45; } | |
.full-deck .card:nth-child(45) { left: calc(44 * 15px); z-index: 46; } | |
.full-deck .card:nth-child(46) { left: calc(45 * 15px); z-index: 47; } | |
.full-deck .card:nth-child(47) { left: calc(46 * 15px); z-index: 48; } | |
.full-deck .card:nth-child(48) { left: calc(47 * 15px); z-index: 49; } | |
.full-deck .card:nth-child(49) { left: calc(48 * 15px); z-index: 50; } | |
.full-deck .card:nth-child(50) { left: calc(49 * 15px); z-index: 51; } | |
.full-deck .card:nth-child(51) { left: calc(50 * 15px); z-index: 52; } | |
.full-deck .card:nth-child(52) { left: calc(51 * 15px); z-index: 53; } | |
.full-deck .card:nth-child(53) { left: calc(52 * 15px); z-index: 54; } | |
.full-deck .card:nth-child(54) { left: calc(53 * 15px); z-index: 55; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.15.1", | |
"EmberENV": { | |
"FEATURES": {} | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"cards_css": "https://selfthinker.github.io/CSS-Playing-Cards/cards.css", | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js", | |
"ember": "3.4.3", | |
"ember-template-compiler": "3.4.3", | |
"ember-testing": "3.4.3" | |
}, | |
"addons": { | |
"ember-animated": "0.4.1", | |
"ember-concurrency": "0.8.27" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment