TypeScriptの練習がてら、ポーカーの役を判定するプログラムを書きました。
poker_checker.ts
// Setup
export enum Suit {
spade,
heart,
club,
diamond
}
export class Card {
suit: Suit
numeral: number
constructor(suit: Suit, numeral: number) {
this.suit = suit
this.numeral = numeral
}
}
const cardsLength = 5
// 実際のプログラムならユーザーからの入力を代入する形になる
const cards: Card[] = [
new Card(Suit.heart, 8),
new Card(Suit.club, 10),
new Card(Suit.spade, 7),
new Card(Suit.spade, 10),
new Card(Suit.diamond, 8)
]
customSort(cards)
// Functions
export function customSort(cards: Card[]) {
cards.sort(function (c1, c2) {
if (c1.numeral < c2.numeral) return -1
if (c1.numeral > c2.numeral) return 1
if (c1.suit < c2.suit) return -1
if (c1.suit > c2.suit) return 1
return 0
})
}
export function validate(cards: Card[]): Error | null {
if (cards.length !== cardsLength) throw new Error("CardsLength is not 5.")
if (!cards.every(c => c.numeral >= 1 && c.numeral <= 13)) throw new Error("Some numeral is not within 1-13.")
for (let i = 0; i < cardsLength - 1; i++) if (JSON.stringify(cards[i]) === JSON.stringify(cards[i + 1])) throw new Error("There are duplicate cards.")
return null
}
export function isStraight(cards: Card[]): boolean {
const numerals = cards.map(c => c.numeral)
if (numerals.includes(1) && numerals.includes(10)) {
return numerals.includes(11) && numerals.includes(12) && numerals.includes(13)
} else {
return numerals.every((n, index) => cards[0].numeral === (n - index))
}
}
export function isFlush(cards: Card[]): boolean {
return cards.every(c => cards[0].suit === c.suit)
}
export function isStraightFlush(cards: Card[]): boolean {
return isFlush(cards) && isStraight(cards)
}
export function isRoyalFlush(cards: Card[]): boolean {
const numerals = cards.map(c => c.numeral)
return isStraightFlush(cards) && numerals.includes(1) && numerals.includes(10)
}
// どの数字が何枚含まれているかを数える
export function counter(cards: Card[]): { [key: number]: number } {
let counter: { [key: number]: number } = {}
for (let i = 0; i < cards.length; i++) {
const n = cards[i].numeral
if (Object.keys(counter).includes(String(n))) {
counter[n] += 1
} else {
counter[n] = 1
}
}
return counter
}
export function isFourOfAKind(cards: Card[]): boolean {
return Object.values(counter(cards)).includes(4)
}
export function isFullHouse(cards: Card[]): boolean {
return Object.values(counter(cards)).includes(2) && Object.values(counter(cards)).includes(3)
}
export function isThreeOfAKind(cards: Card[]): boolean {
return Object.values(counter(cards)).includes(3)
}
export function isTwoPair(cards: Card[]): boolean {
return Object.values(counter(cards)).includes(2) && Object.keys(counter(cards)).length === 3
}
export function isOnePair(cards: Card[]): boolean {
return Object.values(counter(cards)).includes(2) && Object.keys(counter(cards)).length === 4
}
export function isHighCard(cards: Card[]): boolean {
return Object.keys(counter(cards)).length === cardsLength
}
// Execution
console.log(cards) // e.g [ { "suit": 0, "numeral": 7 }, { "suit": 1, "numeral": 8 }, { "suit": 3, "numeral": 8 }, { "suit": 0, "numeral": 10 }, { "suit": 2, "numeral": 10 } ]
console.log(counter(cards)) // e.g. { "7": 1, "8": 2, "10": 2 }
try {
validate(cards)
if (isRoyalFlush(cards)) console.log("isRoyalFlush")
else if (isStraightFlush(cards)) console.log("isStraightFlush")
else if (isFourOfAKind(cards)) console.log("isFourOfAKind")
else if (isFullHouse(cards)) console.log("isFullHouse")
else if (isFlush(cards)) console.log("isFlush")
else if (isStraight(cards)) console.log("isStraight")
else if (isThreeOfAKind(cards)) console.log("isThreeOfAKind")
else if (isTwoPair(cards)) console.log("isTwoPair") // この例ではisTwoPairが出力される
else if (isOnePair(cards)) console.log("isOnePair")
else if (isHighCard(cards)) console.log("isHighCard")
else throw new Error("No hands.")
} catch (e) {
console.log(e)
}