带你读《现代TypeScript高级教程》十八、TS实战之扑克牌排序(2)https://developer.aliyun.com/article/1348421?groupCode=tech_library
现在我们可以开始识别手牌了。我们只需要查看按等级计数即可识别几种手牌:
// ...继续 . . . if (count BySet[4] === 1 && countBySet[1] === 1) return Hand.FourOfAKind; else if (countBySet[3] && countBySet[2] === 1) return Hand.FullHouse; else if (countBySet[3] && countBySet[1] === 2) return Hand.ThreeOfAKind; else if (countBySet[2] === 2 && countBySet[1] === 1) return Hand.TwoPairs; else if (countBySet[2] === 1 && countBySet[1] === 3) return Hand.OnePair; . . . // 继续...
例如,如果有四张相同等级的牌,我们知道玩家将获得“四条”。可能会问:如果countBySet[4] === 1,为什么还要测试countBySet[1] === 1?如果四张牌的等级相同,应该只有一张其他牌,对吗?答案是“防御性编程”——在开发代码时,有时会出现错误,通过在测试中更加具体,有助于排查错误。
上面的情况包括了所有某个等级出现多次的可能性。我们必须处理其他情况,包括顺子、同花和“高牌”。
// ...继续 . . . else if (countBySet[1] === 5) { if (countByRank.join('').includes('11111')) return !countBySuit.includes(5) ? Hand.Straight : countByRank.slice(10).join('') === '11111' ? Hand.RoyalFlush : Hand.StraightFlush; else { return countBySuit.includes(5) ? Hand.Flush : Hand.HighCard; } } else { throw new Error( 'Unknown hand! This cannot happen! Bad logic!' ); }
这里我们再次进行防御性编程;即使我们知道我们有五个不同的等级,我们也确保逻辑工作良好,甚至在出现问题时抛出一个throw。
我们如何测试顺子?我们应该有五个连续的等级。如果我们查看countByRank数组,它应该有五个连续的1,所以通过执行countByRank.join()并检查生成的字符串是否包含11111,我们可以确定是顺子。
-
我们必须区分几种情况:
- 如果没有五张相同花色的牌,那么它是一个普通的顺子
- 如果所有牌都是相同花色,如果顺子以一张A结束,则为皇家同花顺
- 如果所有牌都是相同花色,但我们不以A结束,那么我们有一个同花顺
如果我们没有顺子,只有两种可能性:
- 如果所有牌都是相同花色,我们有一个同花
- 如果不是所有牌都是相同花色,我们有一个“高牌”
带你读《现代TypeScript高级教程》十八、TS实战之扑克牌排序(4)https://developer.aliyun.com/article/1348418?groupCode=tech_library