-
Notifications
You must be signed in to change notification settings - Fork 0
/
prefDeckPile.ts
148 lines (117 loc) · 5.02 KB
/
prefDeckPile.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env node
'use strict';
import * as _ from 'lodash';
import PrefDeckCard, {PrefDeckSuit} from './prefDeckCard';
type _TPrefDeckPileSuits = { spade: PrefDeckCard[], diamond: PrefDeckCard[], heart: PrefDeckCard[], club: PrefDeckCard[] }
export enum PrefDeckSorting {
NONE = 0,
RED, BLACK, SUITS,
RED_REVERSE, BLACK_REVERSE, SUITS_REVERSE
}
const _isReverseSorting = (sorting: PrefDeckSorting): boolean => sorting > PrefDeckSorting.SUITS;
const _isSuitSorting = (sorting: PrefDeckSorting): boolean => sorting === PrefDeckSorting.SUITS || sorting === PrefDeckSorting.SUITS_REVERSE;
const _isRedSorting = (sorting: PrefDeckSorting): boolean => sorting === PrefDeckSorting.RED || sorting === PrefDeckSorting.RED_REVERSE;
const _isBlackSorting = (sorting: PrefDeckSorting): boolean => sorting === PrefDeckSorting.BLACK || sorting === PrefDeckSorting.BLACK_REVERSE;
const _countSuits = (cards: PrefDeckCard[]): number => _.size(_.uniq(_.map(cards, (card) => card.suit)));
const _sortSuit = (cards: PrefDeckCard[], reverse: boolean): PrefDeckCard[] => {
cards = _.sortBy(cards, ['value']);
if (reverse) cards = _.reverse(cards);
return cards;
};
const _getCardsOfSuit = (cards: PrefDeckCard[], suit: PrefDeckSuit): PrefDeckCard[] => _.filter(cards, ['suit', suit]);
const _getSingleSuit = (a: PrefDeckCard[], b: PrefDeckCard[]): PrefDeckCard[] => {
if (_.isEmpty(a)) return b;
if (_.isEmpty(b)) return a;
return [];
};
const _spreadSuits = (cards: PrefDeckCard[], reverse: boolean): _TPrefDeckPileSuits => ({
spade: _sortSuit(_getCardsOfSuit(cards, PrefDeckSuit.SPADE), reverse),
diamond: _sortSuit(_getCardsOfSuit(cards, PrefDeckSuit.DIAMOND), reverse),
heart: _sortSuit(_getCardsOfSuit(cards, PrefDeckSuit.HEART), reverse),
club: _sortSuit(_getCardsOfSuit(cards, PrefDeckSuit.CLUB), reverse),
});
const _sortBySuits = (cards: PrefDeckCard[], reverse: boolean): PrefDeckCard[] => {
const {spade, diamond, heart, club} = _spreadSuits(cards, reverse);
cards = _.concat(spade, diamond, heart, club);
return cards;
};
const _sort2suits = (cards: PrefDeckCard[], sorting: PrefDeckSorting): PrefDeckCard[] => {
const reverse: boolean = _isReverseSorting(sorting);
const {spade, diamond, heart, club} = _spreadSuits(cards, reverse);
const red = _.concat(diamond, heart);
const black = _.concat(spade, club);
cards = _isRedSorting(sorting) ? _.concat(red, black) : _.concat(black, red);
return cards;
};
const _sort3suits = (cards: PrefDeckCard[], sorting: PrefDeckSorting): PrefDeckCard[] => {
const reverse: boolean = _isReverseSorting(sorting);
const {spade, diamond, heart, club} = _spreadSuits(cards, reverse);
const black = _getSingleSuit(spade, club);
if (!_.isEmpty(black)) cards = _.concat(diamond, black, heart);
const red = _getSingleSuit(diamond, heart);
if (!_.isEmpty(red)) cards = _.concat(spade, red, club);
return cards;
};
const _sort4suits = (cards: PrefDeckCard[], sorting: PrefDeckSorting): PrefDeckCard[] => {
const reverse: boolean = _isReverseSorting(sorting);
const {spade, diamond, heart, club} = _spreadSuits(cards, reverse);
if (_isBlackSorting(sorting)) return _.concat(spade, diamond, club, heart);
return _.concat(diamond, spade, heart, club);
};
const _sort = (cards: PrefDeckCard[], sorting: PrefDeckSorting): PrefDeckCard[] => {
const reverse: boolean = _isReverseSorting(sorting);
const suits = _countSuits(cards);
if (suits === 2) return _sort2suits(cards, sorting);
else if (suits === 3) return _sort3suits(cards, sorting);
else if (suits === 4) return _sort4suits(cards, sorting);
else return _sortBySuits(cards, reverse);
};
const _cardsToLabel = (cards: PrefDeckCard[]): string => _.join(_.map(cards, (card) => card.label), '');
const _cardsToUnicode = (cards: PrefDeckCard[]): string => _.join(_.map(cards, (card) => card.unicode), '');
const _cardsToPPN = (cards: PrefDeckCard[]): string => _.join(_.map(cards, (card) => card.ppn), '');
export default class PrefDeckPile {
protected _cards: PrefDeckCard[];
private readonly _original: PrefDeckCard[];
constructor(cards: PrefDeckCard[]) {
this._cards = [];
this._original = [];
_.forEach(cards, (card: PrefDeckCard): void => {
this._cards.push(card);
this._original.push(card);
});
}
public sort(sorting: PrefDeckSorting = PrefDeckSorting.BLACK): PrefDeckPile {
if (sorting === PrefDeckSorting.NONE) return this;
if (_isSuitSorting(sorting)) {
const reverse: boolean = _isReverseSorting(sorting);
this._cards = _sortBySuits(this._cards, reverse);
return this;
}
this._cards = _sort(this._cards, sorting);
return this;
}
get cards(): PrefDeckCard[] {
return this._cards;
}
get label(): string {
return _cardsToLabel(this._cards);
}
get unicode(): string {
return _cardsToUnicode(this._cards);
}
get ppn(): string {
return _cardsToPPN(this._cards);
}
get original(): PrefDeckCard[] {
return this._original;
}
get originalLabel(): string {
return _cardsToLabel(this._original);
}
get originalUnicode(): string {
return _cardsToUnicode(this._original);
}
get originalPPN(): string {
return _cardsToPPN(this._original);
}
}