Skip to content

Commit 26da452

Browse files
committed
Update poker deal example
1 parent 657c987 commit 26da452

File tree

15 files changed

+542
-205
lines changed

15 files changed

+542
-205
lines changed

.eslintrc.json

+3-15
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,13 @@
44
"es6": true,
55
"node": true
66
},
7-
"extends": ["airbnb-base", "prettier"],
7+
"extends": ["eslint:recommended"],
88
"globals": {
99
"Atomics": "readonly",
1010
"SharedArrayBuffer": "readonly"
1111
},
1212
"parserOptions": {
13-
"ecmaVersion": 2018
14-
},
15-
"rules": {
16-
"linebreak-style": "off",
17-
"strict": "off",
18-
"no-plusplus": "off",
19-
"no-console": "off",
20-
"prefer-destructuring": "off",
21-
"func-names": "off",
22-
"class-methods-use-this": "off",
23-
"prefer-template": "off",
24-
"no-param-reassign": "off",
25-
"object-shorthand": "off",
26-
"max-classes-per-file": "off"
13+
"ecmaVersion": 2018,
14+
"sourceType": "module"
2715
}
2816
}

src/week1/13-final/app.js

+48-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
/*
2-
Render laureate details and add CSS styling.
3-
*/
4-
51
'use strict';
62

73
{
84
const API_BASE_URL = 'http://api.nobelprize.org/v1';
95

6+
/**
7+
*
8+
* @param {string} url
9+
* @param {(err: Error, data: any) => void} cb
10+
*/
1011
function fetchJSON(url, cb) {
1112
const xhr = new XMLHttpRequest();
1213
xhr.open('GET', url);
@@ -22,6 +23,12 @@
2223
xhr.send();
2324
}
2425

26+
/**
27+
*
28+
* @param {string} name
29+
* @param {HTMLElement} parent
30+
* @param {{[key: string]: string}} options
31+
*/
2532
function createAndAppend(name, parent, options = {}) {
2633
const elem = document.createElement(name);
2734
parent.appendChild(elem);
@@ -35,6 +42,10 @@
3542
return elem;
3643
}
3744

45+
/**
46+
*
47+
* @param {Error} err
48+
*/
3849
function renderError(err) {
3950
const listContainer = document.getElementById('list-container');
4051
listContainer.innerHTML = '';
@@ -45,12 +56,23 @@
4556
});
4657
}
4758

59+
/**
60+
*
61+
* @param {HTMLElement} tbody
62+
* @param {string} label
63+
* @param {string} value
64+
*/
4865
function addRow(tbody, label, value) {
4966
const tr = createAndAppend('tr', tbody);
5067
createAndAppend('td', tr, { text: `${label}:`, class: 'label' });
5168
createAndAppend('td', tr, { text: value });
5269
}
5370

71+
/**
72+
*
73+
* @param {HTMLElement} tbody
74+
* @param {any[]} prizes
75+
*/
5476
function renderLaureatePrizes(tbody, prizes) {
5577
const tr = createAndAppend('tr', tbody);
5678
createAndAppend('td', tr, { text: 'Prizes:', class: 'label' });
@@ -68,6 +90,11 @@
6890
});
6991
}
7092

93+
/**
94+
*
95+
* @param {any[]} laureates
96+
* @param {HTMLElement} listContainer
97+
*/
7198
function renderLaureates(laureates, listContainer) {
7299
laureates.forEach(laureate => {
73100
const { surname, firstname } = laureate;
@@ -80,19 +107,24 @@
80107
addRow(
81108
tbody,
82109
'Born',
83-
`${laureate.born}, ${laureate.bornCity}, ${laureate.bornCountry}`,
110+
`${laureate.born}, ${laureate.bornCity}, ${laureate.bornCountry}`
84111
);
85112
if (laureate.died !== '0000-00-00') {
86113
addRow(
87114
tbody,
88115
'Died',
89-
`${laureate.died}, ${laureate.diedCity}, ${laureate.diedCountry}`,
116+
`${laureate.died}, ${laureate.diedCity}, ${laureate.diedCountry}`
90117
);
91118
}
92119
renderLaureatePrizes(tbody, laureate.prizes);
93120
});
94121
}
95122

123+
/**
124+
*
125+
* @param {string} countryCode
126+
* @param {HTMLElement} ul
127+
*/
96128
function onChangeSelect(countryCode, ul) {
97129
ul.innerHTML = '';
98130

@@ -104,7 +136,7 @@
104136
return;
105137
}
106138
renderLaureates(data.laureates, ul);
107-
},
139+
}
108140
);
109141
}
110142

@@ -114,7 +146,11 @@
114146
const header = createAndAppend('header', root);
115147
const ul = createAndAppend('ul', root, { id: 'list-container' });
116148

117-
const select = createAndAppend('select', header);
149+
/* prettier-ignore */
150+
const select = /**@type HTMLSelectElement*/ (createAndAppend(
151+
'select',
152+
header
153+
));
118154
createAndAppend('option', select, {
119155
text: 'Select a country',
120156
disabled: 'disabled',
@@ -127,7 +163,10 @@
127163
return;
128164
}
129165

130-
data.countries
166+
/**@type {{code: string, name: string}[]} */
167+
const countries = data.countries;
168+
169+
countries
131170
.filter(country => country.code !== undefined)
132171
.sort((a, b) => a.name.localeCompare(b.name))
133172
.forEach(country => {
+8-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
'use strict';
1+
import CardDeck from './CardDeck.js';
2+
import CardGame from './CardGame.js';
23

3-
{
4-
const { CardDeck, CardGame } = window;
5-
6-
class App {
7-
constructor() {
8-
const cardDeck = new CardDeck();
9-
this.game = new CardGame(cardDeck);
10-
}
4+
class App {
5+
constructor() {
6+
const cardDeck = new CardDeck();
7+
this.game = new CardGame(cardDeck);
118
}
12-
13-
window.onload = () => new App();
149
}
10+
11+
window.onload = () => new App();
+33-22
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
'use strict';
1+
import Util from './Util.js';
22

3-
{
4-
const { createAndAppend } = window.Util;
5-
6-
class Card {
7-
static getCardHtml(rank, symbol) {
8-
return `
3+
class Card {
4+
/**
5+
* Generate HTML for a play card
6+
* @param {string} rank
7+
* @param {string} symbol
8+
*/
9+
static getCardHtml(rank, symbol) {
10+
return `
911
<div class='card-row row-top'>
1012
<div class="card-text">
1113
<div>${rank}</div>
@@ -26,22 +28,31 @@
2628
<div class="card-symbol">${symbol}</div>
2729
</div>
2830
</div>`;
29-
}
30-
31-
constructor(symbol, color, rank) {
32-
this.symbol = symbol;
33-
this.color = color;
34-
this.rank = rank;
35-
}
31+
}
3632

37-
render(container) {
38-
const cardContainer = createAndAppend('div', container, {
39-
class: 'card-container',
40-
style: `color: ${this.color}`,
41-
});
42-
cardContainer.innerHTML = Card.getCardHtml(this.rank, this.symbol);
43-
}
33+
/**
34+
*
35+
* @param {string} symbol
36+
* @param {string} color
37+
* @param {string} rank
38+
*/
39+
constructor(symbol, color, rank) {
40+
this.symbol = symbol;
41+
this.color = color;
42+
this.rank = rank;
4443
}
4544

46-
window.Card = Card;
45+
/**
46+
*
47+
* @param {HTMLElement} container
48+
*/
49+
render(container) {
50+
const cardContainer = Util.createAndAppend('div', container, {
51+
class: 'card-container',
52+
style: `color: ${this.color}`,
53+
});
54+
cardContainer.innerHTML = Card.getCardHtml(this.rank, this.symbol);
55+
}
4756
}
57+
58+
export default Card;
+65-59
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,76 @@
1-
'use strict';
1+
import Card from './Card.js';
2+
import Util from './Util.js';
23

3-
{
4-
const {
5-
Card,
6-
Util: { createAndAppend },
7-
} = window;
4+
const CARD_SUITS = [
5+
{ symbol: '♦️', color: 'red' },
6+
{ symbol: '♠️', color: 'black' },
7+
{ symbol: '♥️', color: 'red' },
8+
{ symbol: '♣️', color: 'black' },
9+
];
810

9-
const CARD_SUITS = [
10-
{ symbol: '♦️', color: 'red' },
11-
{ symbol: '♠️', color: 'black' },
12-
{ symbol: '♥️', color: 'red' },
13-
{ symbol: '♣️', color: 'black' },
14-
];
11+
const CARD_RANKS = [
12+
'2',
13+
'3',
14+
'4',
15+
'5',
16+
'6',
17+
'7',
18+
'8',
19+
'9',
20+
'10',
21+
'J',
22+
'Q',
23+
'K',
24+
'A',
25+
];
1526

16-
const CARD_RANKS = [
17-
'2',
18-
'3',
19-
'4',
20-
'5',
21-
'6',
22-
'7',
23-
'8',
24-
'9',
25-
'10',
26-
'J',
27-
'Q',
28-
'K',
29-
'A',
30-
];
27+
class CardDeck {
28+
constructor() {
29+
/** @type {Card []} */
3130

32-
class CardDeck {
33-
constructor() {
34-
this.allCards = [];
35-
CARD_SUITS.forEach(suit => {
36-
const suitCards = CARD_RANKS.map(
37-
rank => new Card(suit.symbol, suit.color, rank),
38-
);
39-
this.allCards = this.allCards.concat(suitCards);
40-
});
41-
this.cards = this.allCards.slice();
42-
}
31+
this.allCards = [];
4332

44-
canDeal(count) {
45-
return this.cards.length >= count;
46-
}
33+
CARD_SUITS.forEach(suit => {
34+
const suitCards = CARD_RANKS.map(
35+
rank => new Card(suit.symbol, suit.color, rank)
36+
);
37+
this.allCards = this.allCards.concat(suitCards);
38+
});
39+
this.cards = this.allCards.slice();
40+
}
4741

48-
deal(container, count) {
49-
if (this.canDeal(count)) {
50-
const dealContainer = createAndAppend('div', container, {
51-
class: 'deal-container',
52-
});
53-
const cards = this.cards.splice(0, count);
54-
cards.forEach(card => card.render(dealContainer));
55-
}
56-
}
42+
/**
43+
*
44+
* @param {number} count
45+
*/
46+
canDeal(count) {
47+
return this.cards.length >= count;
48+
}
5749

58-
// ref: https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
59-
shuffle() {
60-
const cards = this.allCards.slice();
61-
for (let i = cards.length - 1; i > 0; i--) {
62-
const j = Math.floor(Math.random() * (i + 1));
63-
[cards[i], cards[j]] = [cards[j], cards[i]];
64-
}
65-
this.cards = cards;
50+
/**
51+
*
52+
* @param {HTMLElement} container
53+
* @param {number} count
54+
*/
55+
deal(container, count) {
56+
if (this.canDeal(count)) {
57+
const dealContainer = Util.createAndAppend('div', container, {
58+
class: 'deal-container',
59+
});
60+
const cards = this.cards.splice(0, count);
61+
cards.forEach(card => card.render(dealContainer));
6662
}
6763
}
6864

69-
window.CardDeck = CardDeck;
65+
// ref: https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
66+
shuffle() {
67+
const cards = this.allCards.slice();
68+
for (let i = cards.length - 1; i > 0; i--) {
69+
const j = Math.floor(Math.random() * (i + 1));
70+
[cards[i], cards[j]] = [cards[j], cards[i]];
71+
}
72+
this.cards = cards;
73+
}
7074
}
75+
76+
export default CardDeck;

0 commit comments

Comments
 (0)