From 90740389b25dab4f05249b829dfcaa7cdc48deda Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 10:53:05 +0900 Subject: [PATCH 1/9] =?UTF-8?q?Chapter4=20=E5=9B=9E=E7=AD=94=E4=BE=8B?= =?UTF-8?q?=E3=81=AE=E4=BE=9D=E5=AD=98=E5=85=88(Card,=20Hand,=20OnePair,?= =?UTF-8?q?=20TwoPair)=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 poker/chapter4.snapshot.ts diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts new file mode 100644 index 0000000..2e0df84 --- /dev/null +++ b/poker/chapter4.snapshot.ts @@ -0,0 +1,53 @@ +import { Rank, Suit } from './index'; + +class Card { + constructor(private readonly suit: Suit, private readonly rank: Rank) {} +} + +class Hand { + private readonly cards: Readonly; + + constructor(cards: Card[]) { + this.cards = cards; + } +} + +enum PokerHandName { + OnePair = 'OnePair', + TwoPair = 'TwoPair', + FullHouse = 'FullHouse', +} + +interface IPokerHand { + getName(): PokerHandName; + compareByStrength(other: IPokerHand): number; +} + +class OnePair implements IPokerHand { + private static readonly pokerHandName = PokerHandName.OnePair; + + constructor(private readonly cards: [Card, Card]) {} + + getName(): PokerHandName { + return OnePair.pokerHandName; + } + + compareByStrength(other: IPokerHand): number { + return 0; // TODO + } +} + +class TwoPair implements IPokerHand { + private static readonly pokerHandName = PokerHandName.TwoPair; + + // FIXME: 引数の型を [Pair, Pair] に変えたい + constructor(private readonly pairs: [[Card, Card], [Card, Card]]) {} + + getName(): PokerHandName { + return TwoPair.pokerHandName; + } + + compareByStrength(other: IPokerHand): number { + return 0; // TODO + } +} From ad1adbdcc5d79bd174a27b9b4b20fba249583d86 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:00:37 +0900 Subject: [PATCH 2/9] =?UTF-8?q?Compare=E9=96=A2=E6=95=B0=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 2e0df84..4f44c57 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -2,6 +2,11 @@ import { Rank, Suit } from './index'; class Card { constructor(private readonly suit: Suit, private readonly rank: Rank) {} + + compareTo(other: Card): number { + // TODO: this と other のカードの強さを比較する。(まずランクで強弱比較して、それが同じ場合にはスートで比較する) + return 0; + } } class Hand { @@ -33,7 +38,18 @@ class OnePair implements IPokerHand { } compareByStrength(other: IPokerHand): number { - return 0; // TODO + if (other instanceof OnePair) { + return this.compareWithOnePair(other); + } else { + return 0; // TODO + } + } + + private compareWithOnePair(other: OnePair): number { + // TODO: this.cards と other.cards で強さを比較する。 + // 具体的な比較は、 card.compareTo(card) や rank.compareTo(rank) に移譲する。 + // ワンペアの場合には、ペア同士のランクで比較して、それが同じ場合にはスートで強さを決める。 + return 0; } } @@ -48,6 +64,17 @@ class TwoPair implements IPokerHand { } compareByStrength(other: IPokerHand): number { - return 0; // TODO + if (other instanceof TwoPair) { + return this.compareWithTwoPair(other); + } else { + return 0; // TODO + } + } + + private compareWithTwoPair(other: TwoPair): number { + // TODO: this と other で強さを比較する。 + // ツーペアの場合には、強い方のペア同士のランクで比較して、それが同じ場合には弱い方のペア同士で比較する流れになる。 + // NOTE: 弱い方のペア同士のランクが同じ場合にどちらが強いと判断するかは要確認。 + return 0; } } From 500b07bf1af2a39c1c126a3c5c985d180948f615 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:03:05 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=E5=BD=B9=E3=81=AE=E7=A8=AE=E9=A1=9E?= =?UTF-8?q?=E3=81=AB=E3=81=BE=E3=81=9F=E3=81=8C=E3=82=8B=E5=BC=B7=E5=BC=B1?= =?UTF-8?q?=E6=AF=94=E8=BC=83=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 4f44c57..7804acd 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -23,6 +23,22 @@ enum PokerHandName { FullHouse = 'FullHouse', } +class PokerHandStrength { + private static readonly strength = [ + PokerHandName.OnePair, + PokerHandName.TwoPair, + PokerHandName.FullHouse, + ]; + + static get(pokerHandName: PokerHandName): number { + return this.strength.indexOf(pokerHandName); + } + + static compare(a: PokerHandName, b: PokerHandName): number { + return this.get(a) - this.get(b); + } +} + interface IPokerHand { getName(): PokerHandName; compareByStrength(other: IPokerHand): number; @@ -41,7 +57,8 @@ class OnePair implements IPokerHand { if (other instanceof OnePair) { return this.compareWithOnePair(other); } else { - return 0; // TODO + // 比較相手が OnePair と異なる種類なので、ポーカーハンドの種類間の強弱比較をすれば良い + return PokerHandStrength.compare(this.getName(), other.getName()); } } @@ -67,7 +84,8 @@ class TwoPair implements IPokerHand { if (other instanceof TwoPair) { return this.compareWithTwoPair(other); } else { - return 0; // TODO + // 比較相手が TwoPair と異なる種類なので、ポーカーハンドの種類間の強弱比較をすれば良い + return PokerHandStrength.compare(this.getName(), other.getName()); } } From 6bb1a5a9d7e6c25e984e0eb38d1cbb50ace9c8e2 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:06:54 +0900 Subject: [PATCH 4/9] =?UTF-8?q?OnePair,=20TwoPair=20=E3=82=AA=E3=83=96?= =?UTF-8?q?=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88=E3=81=AEFactory=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 7804acd..35e892f 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -15,6 +15,22 @@ class Hand { constructor(cards: Card[]) { this.cards = cards; } + + /** + * Handの持つカードのうち引数に指定された枚数を組み合わせたセットを順に返す + * + * 手札 [A, B, C, D, E] があったとき、 numberOfCard = 2 を指定すると、以下の10要素が返される + * [A, B], [A, C], [A, D], [A, E], [B, C], [B, D], [B, E], [C, D], [C, E], [D, E] + * + * @param numberOfCard + * @param callback + */ + combinationForEach( + numberOfCard: number, + callback: (cards: Card[], index: number) => void + ): void { + // TODO + } } enum PokerHandName { @@ -96,3 +112,30 @@ class TwoPair implements IPokerHand { return 0; } } + +class OnePairFactory { + static build(hand: Hand): OnePair[] { + const onePairs: OnePair[] = []; + + // TODO: 手札のカード5枚の中から、同じランクのカード2枚のペアを全て列挙する + hand.combinationForEach(2, (cards) => { + // TODO: ここで cards の 2枚が同じランクかチェックして.. + const [a, b] = cards; + onePairs.push(new OnePair([a, b])); + }); + + return onePairs; + } +} + +class TwoPairFactory { + static build(hand: Hand): TwoPair[] { + const twoPairs: TwoPair[] = []; + + hand.combinationForEach(4, (cards) => { + // TODO: 4枚のカードのうち、同じランクのものが2枚・2組になっているかチェックして.. + }); + + return twoPairs; + } +} From 2b07add627073e37da12cc0aad8346cf480db9ef Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:11:19 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=E8=A4=87=E6=95=B0=E3=81=AE=E5=BD=B9?= =?UTF-8?q?=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88=E3=82=92?= =?UTF-8?q?=E7=94=9F=E6=88=90=E3=81=99=E3=82=8B=E5=BD=B9=E5=89=B2=E3=81=AB?= =?UTF-8?q?=E5=90=88=E3=82=8F=E3=81=9B=E3=81=A6=E5=91=BD=E5=90=8D=E3=82=92?= =?UTF-8?q?=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 35e892f..ac3e355 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -113,7 +113,7 @@ class TwoPair implements IPokerHand { } } -class OnePairFactory { +class OnePairCollectionFactory { static build(hand: Hand): OnePair[] { const onePairs: OnePair[] = []; @@ -128,14 +128,23 @@ class OnePairFactory { } } -class TwoPairFactory { +class TwoPairCollectionFactory { static build(hand: Hand): TwoPair[] { const twoPairs: TwoPair[] = []; hand.combinationForEach(4, (cards) => { // TODO: 4枚のカードのうち、同じランクのものが2枚・2組になっているかチェックして.. + // NOTE: 複雑になりそうなので別メソッドに処理を移譲しても良さそう + const twoPair = this.buildOne(cards); + if (twoPair) { + twoPairs.push(twoPair); + } }); return twoPairs; } + + private static buildOne(cards: Card[]): TwoPair | null { + return null; // 条件を満たしたときには TwoPair を返す / + } } From e69e6bac4f0501ad1aa744bf604839aa041a35f3 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:15:33 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=E6=89=8B=E6=9C=AD=E3=81=8B=E3=82=89?= =?UTF-8?q?=E5=8F=96=E3=82=8A=E3=81=86=E3=82=8B=E5=85=A8=E3=81=A6=E3=81=AE?= =?UTF-8?q?=E5=BD=B9=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=81=AE=E9=9B=86=E5=90=88=E3=82=92=E4=BD=9C=E3=82=8A=E5=87=BA?= =?UTF-8?q?=E3=81=99=20Factory=20=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index ac3e355..9d7ab2f 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -148,3 +148,28 @@ class TwoPairCollectionFactory { return null; // 条件を満たしたときには TwoPair を返す / } } + +class PokerHandCollection { + constructor(private readonly pokerHands: IPokerHand[]) {} + + strongest(): IPokerHand | undefined { + // sort() は配列を破壊的に変更するので concat() で複製する + const pokerHands = this.pokerHands.concat(); + return pokerHands.sort(PokerHandCollection.compareByStrength).pop(); + } + + private static compareByStrength(a: IPokerHand, b: IPokerHand): number { + return a.compareByStrength(b); + } +} + +class CandidatePokerHandCollectionFactory { + static build(hand: Hand): PokerHandCollection { + const pokerHands: IPokerHand[] = []; + + pokerHands.push(...OnePairCollectionFactory.build(hand)); + pokerHands.push(...TwoPairCollectionFactory.build(hand)); + + return new PokerHandCollection(pokerHands); + } +} From f391beb56a9ccd8e7ea6bdbb5b2b331d606ed0d1 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Thu, 30 Sep 2021 11:17:38 +0900 Subject: [PATCH 7/9] =?UTF-8?q?PokerHandCollectinFactory=20=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E3=81=97=E3=81=A6=E3=82=A4=E3=83=B3=E3=82=BF=E3=83=95?= =?UTF-8?q?=E3=82=A7=E3=83=BC=E3=82=B9=E3=82=92=E9=81=A9=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 9d7ab2f..e85f66f 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -113,8 +113,12 @@ class TwoPair implements IPokerHand { } } -class OnePairCollectionFactory { - static build(hand: Hand): OnePair[] { +interface IPokerHandCollectionFactory { + build(hand: Hand): IPokerHand[]; +} + +class OnePairCollectionFactory implements IPokerHandCollectionFactory { + build(hand: Hand): OnePair[] { const onePairs: OnePair[] = []; // TODO: 手札のカード5枚の中から、同じランクのカード2枚のペアを全て列挙する @@ -128,8 +132,8 @@ class OnePairCollectionFactory { } } -class TwoPairCollectionFactory { - static build(hand: Hand): TwoPair[] { +class TwoPairCollectionFactory implements IPokerHandCollectionFactory { + build(hand: Hand): TwoPair[] { const twoPairs: TwoPair[] = []; hand.combinationForEach(4, (cards) => { @@ -144,7 +148,7 @@ class TwoPairCollectionFactory { return twoPairs; } - private static buildOne(cards: Card[]): TwoPair | null { + private buildOne(cards: Card[]): TwoPair | null { return null; // 条件を満たしたときには TwoPair を返す / } } @@ -164,11 +168,17 @@ class PokerHandCollection { } class CandidatePokerHandCollectionFactory { + private static factories: IPokerHandCollectionFactory[] = [ + new OnePairCollectionFactory(), + new TwoPairCollectionFactory(), + ]; + static build(hand: Hand): PokerHandCollection { const pokerHands: IPokerHand[] = []; - pokerHands.push(...OnePairCollectionFactory.build(hand)); - pokerHands.push(...TwoPairCollectionFactory.build(hand)); + this.factories.forEach((factory) => { + pokerHands.push(...factory.build(hand)); + }); return new PokerHandCollection(pokerHands); } From d0cce366a4e6af97d5a4aceb6001356593dee1d9 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 13 Oct 2021 19:56:45 +0900 Subject: [PATCH 8/9] =?UTF-8?q?Hand=20=E5=90=8C=E5=A3=AB=E3=81=A7=E5=BC=B7?= =?UTF-8?q?=E5=BC=B1=E3=82=92=E5=88=A4=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index e85f66f..6ff044e 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -16,6 +16,17 @@ class Hand { this.cards = cards; } + compareByStrength(other: Hand): number { + const myPokerHand = CandidatePokerHandCollectionFactory.build( + this + ).strongest(); + const otherPokerHand = CandidatePokerHandCollectionFactory.build( + other + ).strongest(); + + return myPokerHand.compareByStrength(otherPokerHand); + } + /** * Handの持つカードのうち引数に指定された枚数を組み合わせたセットを順に返す * From 8c1862bd726ebca9ca3fcbd0111e4bcb7020b202 Mon Sep 17 00:00:00 2001 From: Akira Yumiyama Date: Wed, 13 Oct 2021 19:57:39 +0900 Subject: [PATCH 9/9] =?UTF-8?q?Hand=20=E3=82=92=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poker/chapter4.snapshot.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/poker/chapter4.snapshot.ts b/poker/chapter4.snapshot.ts index 6ff044e..65de787 100644 --- a/poker/chapter4.snapshot.ts +++ b/poker/chapter4.snapshot.ts @@ -16,13 +16,13 @@ class Hand { this.cards = cards; } + pokerHand(): IPokerHand { + return CandidatePokerHandCollectionFactory.build(this).strongest(); + } + compareByStrength(other: Hand): number { - const myPokerHand = CandidatePokerHandCollectionFactory.build( - this - ).strongest(); - const otherPokerHand = CandidatePokerHandCollectionFactory.build( - other - ).strongest(); + const myPokerHand = this.pokerHand(); + const otherPokerHand = other.pokerHand(); return myPokerHand.compareByStrength(otherPokerHand); }