我如何摆脱所有这些重复代码?
How do I get rid of all this duplicate code?
private Optional<Player> playerWithMostCards()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = p.pile.size();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithMostSevens()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(Card.Value.SEVEN))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithMostSpades()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(Card.Suit.SPADES))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithSevenOfSpades()
{
for(Player p : players)
{
for(Card c : p.pile)
{
if(c == new Card("7S"))
{
return Optional.of(p);
}
}
}
return Optional.empty();
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCards().ifPresent(p -> p.score += 1);
playerWithMostSevens().ifPresent(p -> p.score += 1);
playerWithMostSpades().ifPresent(p -> p.score += 1);
playerWithSevenOfSpades().ifPresent(p -> p.score += 1);
}
基本上,我正在制作纸牌游戏(称为 Scopa),当调用 updateScores() 时,应该更新每个玩家的分数。玩家可以通过持有最多的牌、最多的 7 或黑桃 7 来获得积分。确定谁拥有最多的牌、7 和黑桃的逻辑非常相似。如何避免在这三种方法中重复逻辑?谢谢。
对于最后两个,你可以做一个函数。我不熟悉您使用的编程语言(我什至不知道它是哪种语言 - 请下次标记您的问题),但它看起来像这样:
private Optional<Player> playerWithMostCards()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = p.pile.size();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.of(scoringPlayer);
}
private Optional<Player> playerWithMost([type] cvalue) // I don't know what the type of Card.[Value/Suit].[SEVEN/SPADES] is.
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(cvalue))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.of(scoringPlayer);
}
private Optional<Player> playerWithSevenOfSpades()
{
for(Player p : players)
{
for(Card c : p.pile)
{
if(c == new Card("7S"))
{
return Optional.of(p);
}
}
}
return Optional.empty();
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCards().ifPresent(p -> p.score += 1);
playerWithMost(Card.Value.SEVEN).ifPresent(p -> p.score += 1);
playerWithMost(Card.Suit.SPADES).ifPresent(p -> p.score += 1);
playerWithSevenOfSpades().ifPresent(p -> p.score += 1);
}
我不确定如何将最上面的那个集成到函数中。
另一种解决方案是只做一个函数来计算分数。您循环播放玩家列表 4 次,循环播放卡片 3 次。你只需要一个玩家循环和一个卡片循环来检查所有内容。
像这样:
private void updateScores()
{
Player playerWithMostCards = null;
Player playerWithMostSevens = null;
Player playerWithMostSpades = null;
int mostCards = 0;
int mostSevens = 0;
int mostSpades = 0;
for(Player p : players)
{
// Most cards
final int playerPileSize = p.pile.size();
if(playerPileSize > mostCards)
{
playerWithMostCards = p;
mostCards = playerPileSize;
}
else if(playerPileSize == mostCards)
{
playerWithMostCards = null;
}
// NumberOfSevens and Spades
int numberOfSevens = 0
int numberOfSpades = 0
for(Card c : p.pile)
{
if(c.is(Card.Value.SEVEN))
{
numberOfSevens++;
}
if(c.is(Card.Suit.SPADES))
{
numberOfSpades++;
}
}
if (numberOfSevens > maxSevens) {
playerWithMostSevens = p
mostSevens = numberOfSevens
} else if (numberOfSevens == maxSevens) {
playerWithMostSevens = null
}
if (numberOfSpades > maxSpades) {
playerWithMostSpades = p
mostSevens = numberOfSpades
} else if (numberOfSpades == maxSpades) {
playerWithMostSpades = null
}
}
playerWithMostCards.score += 1;
playerWithMostSevens.score += 1;
playerWithMostSpades.score += 1;
}
我还没有测试过这个,但这显示了粗略的想法。你可以通过添加最后一个功能来练习。
我不喜欢我想出的方法的名称,但这是我经过一段时间后得出的结果。它大大减少了我拥有的代码量,并且具有同样多的灵活性,如果不是更多的话。如果您能为“playerBestMatching”想出一个更好的名称,请告诉我,我可以对此进行编辑。
编辑:“playerBestMatching”现在是“playerWithMostCardsMatching”
private Optional<Player> playerWithMostCardsMatching(
final Predicate<Card> predicate)
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = (int)p.pile.stream()
.filter(predicate)
.count();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCardsMatching(c -> true).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c.is(Card.Value.SEVEN)).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c.is(Card.Suit.SPADES)).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c == new Card("7S")).ifPresent(p -> p.score += 1);
}
private Optional<Player> playerWithMostCards()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = p.pile.size();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithMostSevens()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(Card.Value.SEVEN))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithMostSpades()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(Card.Suit.SPADES))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private Optional<Player> playerWithSevenOfSpades()
{
for(Player p : players)
{
for(Card c : p.pile)
{
if(c == new Card("7S"))
{
return Optional.of(p);
}
}
}
return Optional.empty();
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCards().ifPresent(p -> p.score += 1);
playerWithMostSevens().ifPresent(p -> p.score += 1);
playerWithMostSpades().ifPresent(p -> p.score += 1);
playerWithSevenOfSpades().ifPresent(p -> p.score += 1);
}
基本上,我正在制作纸牌游戏(称为 Scopa),当调用 updateScores() 时,应该更新每个玩家的分数。玩家可以通过持有最多的牌、最多的 7 或黑桃 7 来获得积分。确定谁拥有最多的牌、7 和黑桃的逻辑非常相似。如何避免在这三种方法中重复逻辑?谢谢。
对于最后两个,你可以做一个函数。我不熟悉您使用的编程语言(我什至不知道它是哪种语言 - 请下次标记您的问题),但它看起来像这样:
private Optional<Player> playerWithMostCards()
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = p.pile.size();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.of(scoringPlayer);
}
private Optional<Player> playerWithMost([type] cvalue) // I don't know what the type of Card.[Value/Suit].[SEVEN/SPADES] is.
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
int count = 0;
for(Card c : p.pile)
{
if(c.is(cvalue))
{
count++;
}
}
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.of(scoringPlayer);
}
private Optional<Player> playerWithSevenOfSpades()
{
for(Player p : players)
{
for(Card c : p.pile)
{
if(c == new Card("7S"))
{
return Optional.of(p);
}
}
}
return Optional.empty();
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCards().ifPresent(p -> p.score += 1);
playerWithMost(Card.Value.SEVEN).ifPresent(p -> p.score += 1);
playerWithMost(Card.Suit.SPADES).ifPresent(p -> p.score += 1);
playerWithSevenOfSpades().ifPresent(p -> p.score += 1);
}
我不确定如何将最上面的那个集成到函数中。
另一种解决方案是只做一个函数来计算分数。您循环播放玩家列表 4 次,循环播放卡片 3 次。你只需要一个玩家循环和一个卡片循环来检查所有内容。
像这样:
private void updateScores()
{
Player playerWithMostCards = null;
Player playerWithMostSevens = null;
Player playerWithMostSpades = null;
int mostCards = 0;
int mostSevens = 0;
int mostSpades = 0;
for(Player p : players)
{
// Most cards
final int playerPileSize = p.pile.size();
if(playerPileSize > mostCards)
{
playerWithMostCards = p;
mostCards = playerPileSize;
}
else if(playerPileSize == mostCards)
{
playerWithMostCards = null;
}
// NumberOfSevens and Spades
int numberOfSevens = 0
int numberOfSpades = 0
for(Card c : p.pile)
{
if(c.is(Card.Value.SEVEN))
{
numberOfSevens++;
}
if(c.is(Card.Suit.SPADES))
{
numberOfSpades++;
}
}
if (numberOfSevens > maxSevens) {
playerWithMostSevens = p
mostSevens = numberOfSevens
} else if (numberOfSevens == maxSevens) {
playerWithMostSevens = null
}
if (numberOfSpades > maxSpades) {
playerWithMostSpades = p
mostSevens = numberOfSpades
} else if (numberOfSpades == maxSpades) {
playerWithMostSpades = null
}
}
playerWithMostCards.score += 1;
playerWithMostSevens.score += 1;
playerWithMostSpades.score += 1;
}
我还没有测试过这个,但这显示了粗略的想法。你可以通过添加最后一个功能来练习。
我不喜欢我想出的方法的名称,但这是我经过一段时间后得出的结果。它大大减少了我拥有的代码量,并且具有同样多的灵活性,如果不是更多的话。如果您能为“playerBestMatching”想出一个更好的名称,请告诉我,我可以对此进行编辑。
编辑:“playerBestMatching”现在是“playerWithMostCardsMatching”
private Optional<Player> playerWithMostCardsMatching(
final Predicate<Card> predicate)
{
Player scoringPlayer = null;
int maxCount = 0;
for(Player p : players)
{
final int count = (int)p.pile.stream()
.filter(predicate)
.count();
if(count > maxCount)
{
scoringPlayer = p;
maxCount = count;
}
else if(count == maxCount)
{
scoringPlayer = null;
}
}
return Optional.ofNullable(scoringPlayer);
}
private void updateScores()
{
for(Player p : players)
{
p.score = p.scopas;
}
playerWithMostCardsMatching(c -> true).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c.is(Card.Value.SEVEN)).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c.is(Card.Suit.SPADES)).ifPresent(p -> p.score += 1);
playerWithMostCardsMatching(c -> c == new Card("7S")).ifPresent(p -> p.score += 1);
}