public Hand dealHand(int endExclusive) {
List<Card> randomCardsCreated = IntStream.range(0, endExclusive).
mapToObj(i -> {
Card randomCard = generateRandomCard();
while (this.cardsDealt.contains(randomCard)) {
randomCard = generateRandomCard();
}
return randomCard;
}).
collect(Collectors.toList());
this.cardsDealt.addAll(randomCardsCreated);
return Hand.hand(randomCardsCreated);
}
我有这种方法,它生成一张随机卡并将其添加到字段列表(cardsDealt)。它还确保randomCard不在列表中,如果是,它将生成一个新的随机卡。然后它将创建一个x卡列表以添加到cardsDealt中,然后它将创建一个包含cardsDealt的新Hand对象。我认为这是不言自明的。
我想摆脱randomCard的可变性,而不是改变randomCard我想在功能上做到这一点,但到目前为止还没有成功。 我也试图摆脱while循环并使用流。
任何建议都会有所帮助。感谢。
修改
根据以下评论,这里有更多信息。
以下是如何使用上述代码的更多代码。
public List<PlayerResult> playGame(Player... players) {
List<Player> playersWithAHandOfCards = dealHandToAllPlayers(players);
...
}
private List<Player> dealHandToAllPlayers(Player[] players) {
return Arrays.stream(players).map(this::dealHand).collect(Collectors.toList());
}
private Player dealHand(Player player) {
Hand hand = deck.dealHand(5);
return player(player.playerName, hand);
}
代码在我的github https://github.com/hanfak/poker-game
编辑2:
我已经用程序格式重写了这个方法,它看起来不错,采取了列出所有卡片的建议,洗牌并选择前5张牌作为牌并将其从牌组中移除。
更多信息。 Rank和Suit只是枚举,Card类包含Rank和Suit的构造函数,以及重写的equals和hashcode方法。手和卡是使用静态工厂方法创建的。
private final List<Rank> ranks = Arrays.asList(Rank.values());
private final List<Suit> suits = Arrays.asList(Suit.values());
private List<Card> deck = createDeck();
public Hand dealHand(int endExclusive) {
Collections.shuffle(deck);
List<Card> dealtCards = getHand(endExclusive);
deck = deck.stream()
.filter(card -> !dealtCards.contains(card))
.collect(Collectors.toList());
return Hand.hand(dealtCards);
}
private List<Card> getHand(int endExclusive) {
if(deck.size() >= 5) {
return deck.subList(0, endExclusive);
} else {
throw new IllegalArgumentException("Not enough cards left over");
}
}
private List<Card> createDeck() {
List<Card> deck = new ArrayList<>();
for(Rank rank : ranks) {
for(Suit suit : suits) {
deck.add(Card.card(rank, suit));
}
}
return deck;
}
如果可以将其转换为功能样式,我仍然会感激,我不喜欢使用Collections.shuffle(套牌)而且不能使用final来进行字段&#39; deck&#39;。
答案 0 :(得分:1)
如果你想使用函数式编程,你几乎就在那里 - 你只需要考虑一些小的改动。
在您制作的信息流中,不是使用Stream.range运行endExclusive
次,而是generate
无限流而limit
到{{1} }}?它是一个int,它正是写入限制方法的东西的类型。
而不是在while循环中运行以确保您的随机卡不在已发卡中 - 如何在流中使用EndExclusive
本地执行此操作?
简而言之,我的代码建议是:
filter
public Hand dealHand(int endExclusive) {
List<Card> randomCardsCreated = Stream.generate(()->generateRandomCard()).distinct().
filter(i->!cardsDealt.contains(i)).limit(endExclusive).
collect(Collectors.toList());
this.cardsDealt.addAll(randomCardsCreated);
return Hand.hand(randomCardsCreated);
}
- 生成无限的随机卡流。
Stream.generate(()->generateRandomCard())
过滤当前手中的所有重复卡片(原始代码中未处理的问题)。
distinct()
删除已经处理过的任何卡片。
filter(i->!cardsDealt.contains(i))
将结果限制在手中的endExclusive卡片。
这对您的实施有用吗?