Refactoring a use of java.util.Random to speed up stuff, and also to fix issues
This commit is contained in:
@@ -1,30 +1,16 @@
|
||||
package com.gempukku.lotro.game.state;
|
||||
|
||||
import com.gempukku.lotro.common.*;
|
||||
import com.gempukku.lotro.common.SitesBlock;
|
||||
import com.gempukku.lotro.communication.GameStateListener;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.game.LotroCardBlueprint;
|
||||
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.PhysicalCardImpl;
|
||||
import com.gempukku.lotro.game.PhysicalCardVisitor;
|
||||
import com.gempukku.lotro.game.*;
|
||||
import com.gempukku.lotro.logic.PlayerOrder;
|
||||
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
|
||||
import com.gempukku.lotro.logic.modifiers.ModifierFlag;
|
||||
import com.gempukku.lotro.logic.timing.GameStats;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class GameState {
|
||||
private static Logger _log = Logger.getLogger(GameState.class);
|
||||
@@ -1103,7 +1089,7 @@ public class GameState {
|
||||
|
||||
public void shuffleDeck(String player) {
|
||||
List<PhysicalCardImpl> deck = _decks.get(player);
|
||||
Collections.shuffle(deck);
|
||||
Collections.shuffle(deck, ThreadLocalRandom.current());
|
||||
}
|
||||
|
||||
public void sendGameStats(GameStats gameStats) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.gempukku.lotro.game.state.GameState;
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class GameUtils {
|
||||
public static Side getSide(LotroGame game, String playerId) {
|
||||
@@ -91,7 +92,7 @@ public class GameUtils {
|
||||
|
||||
public static List<PhysicalCard> getRandomCards(List<? extends PhysicalCard> cards, int count) {
|
||||
List<PhysicalCard> randomizedCards = new ArrayList<PhysicalCard>(cards);
|
||||
Collections.shuffle(randomizedCards);
|
||||
Collections.shuffle(randomizedCards, ThreadLocalRandom.current());
|
||||
|
||||
return new LinkedList<PhysicalCard>(randomizedCards.subList(0, Math.min(count, randomizedCards.size())));
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.gempukku.lotro.logic.timing.results.DiscardCardFromHandResult;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class DiscardCardAtRandomFromHandEffect extends AbstractEffect {
|
||||
private PhysicalCard _source;
|
||||
@@ -45,7 +45,7 @@ public class DiscardCardAtRandomFromHandEffect extends AbstractEffect {
|
||||
if (isPlayableInFull(game)) {
|
||||
GameState gameState = game.getGameState();
|
||||
List<? extends PhysicalCard> hand = gameState.getHand(_playerId);
|
||||
PhysicalCard randomCard = hand.get(new Random().nextInt(hand.size()));
|
||||
PhysicalCard randomCard = hand.get(ThreadLocalRandom.current().nextInt(hand.size()));
|
||||
gameState.sendMessage(_playerId + " randomly discards " + GameUtils.getCardLink(randomCard));
|
||||
gameState.removeCardsFromZone(_source.getOwner(), Collections.singleton(randomCard));
|
||||
gameState.addCardToZone(game, randomCard, Zone.DISCARD);
|
||||
|
||||
@@ -1,103 +1,104 @@
|
||||
package com.gempukku.lotro.logic.timing.processes.pregame;
|
||||
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
import com.gempukku.lotro.logic.PlayerOrder;
|
||||
import com.gempukku.lotro.logic.decisions.MultipleChoiceAwaitingDecision;
|
||||
import com.gempukku.lotro.logic.timing.PlayerOrderFeedback;
|
||||
import com.gempukku.lotro.logic.timing.processes.GameProcess;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ChooseSeatingOrderGameProcess implements GameProcess {
|
||||
private String[] _choices = new String[]{"first", "second", "third", "fourth", "fifth"};
|
||||
private Map<String, Integer> _bids;
|
||||
private PlayerOrderFeedback _playerOrderFeedback;
|
||||
|
||||
private Iterator<String> _biddingOrderPlayers;
|
||||
private String[] _orderedPlayers;
|
||||
private boolean _sentBids;
|
||||
|
||||
public ChooseSeatingOrderGameProcess(Map<String, Integer> bids, PlayerOrderFeedback playerOrderFeedback) {
|
||||
_bids = bids;
|
||||
_playerOrderFeedback = playerOrderFeedback;
|
||||
|
||||
ArrayList<String> participantList = new ArrayList<String>(bids.keySet());
|
||||
Collections.shuffle(participantList);
|
||||
|
||||
Collections.sort(participantList, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return _bids.get(o2) - _bids.get(o1);
|
||||
}
|
||||
});
|
||||
|
||||
_biddingOrderPlayers = participantList.iterator();
|
||||
_orderedPlayers = new String[participantList.size()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(LotroGame game) {
|
||||
if (!_sentBids) {
|
||||
_sentBids = true;
|
||||
for (Map.Entry<String, Integer> playerBid : _bids.entrySet())
|
||||
game.getGameState().sendMessage(playerBid.getKey() + " bid " + playerBid.getValue());
|
||||
}
|
||||
checkForNextSeating(game);
|
||||
}
|
||||
|
||||
private int getLastEmptySeat() {
|
||||
boolean found = false;
|
||||
int emptySeatIndex = -1;
|
||||
for (int i = 0; i < _orderedPlayers.length; i++) {
|
||||
if (_orderedPlayers[i] == null) {
|
||||
if (found)
|
||||
return -1;
|
||||
found = true;
|
||||
emptySeatIndex = i;
|
||||
}
|
||||
}
|
||||
return emptySeatIndex;
|
||||
}
|
||||
|
||||
private void checkForNextSeating(LotroGame game) {
|
||||
int lastEmptySeat = getLastEmptySeat();
|
||||
if (lastEmptySeat == -1)
|
||||
askNextPlayerToChoosePlace(game);
|
||||
else {
|
||||
_orderedPlayers[lastEmptySeat] = _biddingOrderPlayers.next();
|
||||
_playerOrderFeedback.setPlayerOrder(new PlayerOrder(Arrays.asList(_orderedPlayers)), _orderedPlayers[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getEmptySeatNumbers() {
|
||||
List<String> result = new LinkedList<String>();
|
||||
for (int i = 0; i < _orderedPlayers.length; i++)
|
||||
if (_orderedPlayers[i] == null)
|
||||
result.add("Go " + _choices[i]);
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
private void participantHasChosenSeat(LotroGame game, String participant, int placeIndex) {
|
||||
_orderedPlayers[placeIndex] = participant;
|
||||
|
||||
checkForNextSeating(game);
|
||||
}
|
||||
|
||||
private void askNextPlayerToChoosePlace(final LotroGame game) {
|
||||
final String playerId = _biddingOrderPlayers.next();
|
||||
game.getUserFeedback().sendAwaitingDecision(playerId,
|
||||
new MultipleChoiceAwaitingDecision(1, "Choose one", getEmptySeatNumbers()) {
|
||||
@Override
|
||||
protected void validDecisionMade(int index, String result) {
|
||||
game.getGameState().sendMessage(playerId + " has chosen to go " + _choices[index]);
|
||||
participantHasChosenSeat(game, playerId, index);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProcess getNextProcess() {
|
||||
return new FirstPlayerPlaysSiteGameProcess(_bids, _orderedPlayers[0]);
|
||||
}
|
||||
}
|
||||
package com.gempukku.lotro.logic.timing.processes.pregame;
|
||||
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
import com.gempukku.lotro.logic.PlayerOrder;
|
||||
import com.gempukku.lotro.logic.decisions.MultipleChoiceAwaitingDecision;
|
||||
import com.gempukku.lotro.logic.timing.PlayerOrderFeedback;
|
||||
import com.gempukku.lotro.logic.timing.processes.GameProcess;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class ChooseSeatingOrderGameProcess implements GameProcess {
|
||||
private String[] _choices = new String[]{"first", "second", "third", "fourth", "fifth"};
|
||||
private Map<String, Integer> _bids;
|
||||
private PlayerOrderFeedback _playerOrderFeedback;
|
||||
|
||||
private Iterator<String> _biddingOrderPlayers;
|
||||
private String[] _orderedPlayers;
|
||||
private boolean _sentBids;
|
||||
|
||||
public ChooseSeatingOrderGameProcess(Map<String, Integer> bids, PlayerOrderFeedback playerOrderFeedback) {
|
||||
_bids = bids;
|
||||
_playerOrderFeedback = playerOrderFeedback;
|
||||
|
||||
ArrayList<String> participantList = new ArrayList<String>(bids.keySet());
|
||||
Collections.shuffle(participantList, ThreadLocalRandom.current());
|
||||
|
||||
Collections.sort(participantList, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return _bids.get(o2) - _bids.get(o1);
|
||||
}
|
||||
});
|
||||
|
||||
_biddingOrderPlayers = participantList.iterator();
|
||||
_orderedPlayers = new String[participantList.size()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(LotroGame game) {
|
||||
if (!_sentBids) {
|
||||
_sentBids = true;
|
||||
for (Map.Entry<String, Integer> playerBid : _bids.entrySet())
|
||||
game.getGameState().sendMessage(playerBid.getKey() + " bid " + playerBid.getValue());
|
||||
}
|
||||
checkForNextSeating(game);
|
||||
}
|
||||
|
||||
private int getLastEmptySeat() {
|
||||
boolean found = false;
|
||||
int emptySeatIndex = -1;
|
||||
for (int i = 0; i < _orderedPlayers.length; i++) {
|
||||
if (_orderedPlayers[i] == null) {
|
||||
if (found)
|
||||
return -1;
|
||||
found = true;
|
||||
emptySeatIndex = i;
|
||||
}
|
||||
}
|
||||
return emptySeatIndex;
|
||||
}
|
||||
|
||||
private void checkForNextSeating(LotroGame game) {
|
||||
int lastEmptySeat = getLastEmptySeat();
|
||||
if (lastEmptySeat == -1)
|
||||
askNextPlayerToChoosePlace(game);
|
||||
else {
|
||||
_orderedPlayers[lastEmptySeat] = _biddingOrderPlayers.next();
|
||||
_playerOrderFeedback.setPlayerOrder(new PlayerOrder(Arrays.asList(_orderedPlayers)), _orderedPlayers[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getEmptySeatNumbers() {
|
||||
List<String> result = new LinkedList<String>();
|
||||
for (int i = 0; i < _orderedPlayers.length; i++)
|
||||
if (_orderedPlayers[i] == null)
|
||||
result.add("Go " + _choices[i]);
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
private void participantHasChosenSeat(LotroGame game, String participant, int placeIndex) {
|
||||
_orderedPlayers[placeIndex] = participant;
|
||||
|
||||
checkForNextSeating(game);
|
||||
}
|
||||
|
||||
private void askNextPlayerToChoosePlace(final LotroGame game) {
|
||||
final String playerId = _biddingOrderPlayers.next();
|
||||
game.getUserFeedback().sendAwaitingDecision(playerId,
|
||||
new MultipleChoiceAwaitingDecision(1, "Choose one", getEmptySeatNumbers()) {
|
||||
@Override
|
||||
protected void validDecisionMade(int index, String result) {
|
||||
game.getGameState().sendMessage(playerId + " has chosen to go " + _choices[index]);
|
||||
participantHasChosenSeat(game, playerId, index);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProcess getNextProcess() {
|
||||
return new FirstPlayerPlaysSiteGameProcess(_bids, _orderedPlayers[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.gempukku.lotro.logic.timing.processes.GameProcess;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class AIPlayerAssignsArcheryTotalGameProcess implements GameProcess {
|
||||
private int _woundsToAssign;
|
||||
@@ -64,8 +64,7 @@ public class AIPlayerAssignsArcheryTotalGameProcess implements GameProcess {
|
||||
List<PhysicalCard> possibleChoices = new ArrayList<PhysicalCard>(acceptableCards);
|
||||
if (possibleChoices.size()>0) {
|
||||
SubAction subAction = new SubAction(action);
|
||||
Random rnd = new Random();
|
||||
final int randomIndex = rnd.nextInt(possibleChoices.size());
|
||||
final int randomIndex = ThreadLocalRandom.current().nextInt(possibleChoices.size());
|
||||
WoundCharactersEffect woundCharacter = new WoundCharactersEffect((PhysicalCard) null, possibleChoices.get(randomIndex));
|
||||
woundCharacter.setSourceText("Archery Fire");
|
||||
subAction.appendEffect(woundCharacter);
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.gempukku.lotro.packs.PacksStorage;
|
||||
import com.gempukku.lotro.tournament.TournamentCallback;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
// TODO - it has to be thread safe
|
||||
public class DefaultDraft implements Draft {
|
||||
@@ -44,7 +45,7 @@ public class DefaultDraft implements Draft {
|
||||
_packsStorage = packsStorage;
|
||||
_draftPack = draftPack;
|
||||
_players = new ArrayList(players);
|
||||
Collections.shuffle(_players);
|
||||
Collections.shuffle(_players, ThreadLocalRandom.current());
|
||||
|
||||
_playerCount = _players.size();
|
||||
|
||||
|
||||
@@ -6,7 +6,10 @@ import com.google.common.collect.Iterables;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class StartingPoolBuilder {
|
||||
public CardCollectionProducer buildCardCollectionProducer(JSONObject startingPool) {
|
||||
@@ -39,6 +42,7 @@ public class StartingPoolBuilder {
|
||||
@Override
|
||||
public CardCollection getCardCollection(long seed) {
|
||||
Random rnd = new Random(seed);
|
||||
float thisFixesARandomnessBug = rnd.nextFloat();
|
||||
return cardCollections.get(rnd.nextInt(cardCollections.size()));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
@@ -34,7 +35,7 @@ public class GameRecorder {
|
||||
private String randomUid() {
|
||||
int length = 16;
|
||||
char[] chars = new char[length];
|
||||
Random rnd = new Random();
|
||||
Random rnd = ThreadLocalRandom.current();
|
||||
for (int i = 0; i < length; i++)
|
||||
chars[i] = _possibleChars.charAt(rnd.nextInt(_charsCount));
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@ import com.gempukku.lotro.game.CardSets;
|
||||
import com.gempukku.lotro.game.DefaultCardCollection;
|
||||
import com.gempukku.lotro.game.packs.SetDefinition;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class FixedLeaguePrizes implements LeaguePrizes {
|
||||
private List<String> _commons = new ArrayList<String>();
|
||||
@@ -174,14 +178,14 @@ public class FixedLeaguePrizes implements LeaguePrizes {
|
||||
}
|
||||
|
||||
private String getRandom(List<String> list) {
|
||||
return list.get(new Random().nextInt(list.size()));
|
||||
return list.get(ThreadLocalRandom.current().nextInt(list.size()));
|
||||
}
|
||||
|
||||
private List<String> getRandomFoil(List<String> list, int count) {
|
||||
List<String> result = new LinkedList<String>();
|
||||
for (String element : list)
|
||||
result.add(element + "*");
|
||||
Collections.shuffle(result);
|
||||
Collections.shuffle(result, ThreadLocalRandom.current());
|
||||
return result.subList(0, count);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,13 @@ import com.gempukku.lotro.game.CardCollection;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class LeagueStarterBox implements PackBox {
|
||||
private Random _random = new Random();
|
||||
|
||||
@Override
|
||||
public List<CardCollection.Item> openPack() {
|
||||
List<CardCollection.Item> result = new LinkedList<CardCollection.Item>();
|
||||
int starter = _random.nextInt(6);
|
||||
int starter = ThreadLocalRandom.current().nextInt(6);
|
||||
if (starter == 0) {
|
||||
result.add(CardCollection.Item.createItem("FotR - Gandalf Starter", 1));
|
||||
} else if (starter == 1) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.gempukku.lotro.game.packs.SetDefinition;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class RandomFoilPack implements PackBox {
|
||||
private List<String> _availableCards = new ArrayList<String>();
|
||||
@@ -21,7 +21,7 @@ public class RandomFoilPack implements PackBox {
|
||||
@Override
|
||||
public List<CardCollection.Item> openPack() {
|
||||
List<CardCollection.Item> result = new LinkedList<CardCollection.Item>();
|
||||
final String cardBlueprintId = _availableCards.get(new Random().nextInt(_availableCards.size())) + "*";
|
||||
final String cardBlueprintId = _availableCards.get(ThreadLocalRandom.current().nextInt(_availableCards.size())) + "*";
|
||||
result.add(CardCollection.Item.createItem(cardBlueprintId, 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import com.gempukku.lotro.game.CardCollection;
|
||||
import com.gempukku.lotro.game.packs.SetDefinition;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class RarityPackBox implements PackBox {
|
||||
private Random _random = new Random();
|
||||
private SetDefinition _setRarity;
|
||||
private List<String> _possibleRareCards = new ArrayList<String>();
|
||||
private List<String> _possibleFoilRareSlot = new ArrayList<String>();
|
||||
@@ -34,9 +34,9 @@ public class RarityPackBox implements PackBox {
|
||||
@Override
|
||||
public List<CardCollection.Item> openPack() {
|
||||
List<CardCollection.Item> result = new LinkedList<CardCollection.Item>();
|
||||
boolean hasFoil = (_random.nextInt(6) == 0);
|
||||
boolean hasFoil = (ThreadLocalRandom.current().nextInt(6) == 0);
|
||||
if (hasFoil) {
|
||||
int foilRarity = _random.nextInt(11);
|
||||
int foilRarity = ThreadLocalRandom.current().nextInt(11);
|
||||
if (foilRarity == 0) {
|
||||
addRandomCardsFromList(result, 1, _possibleFoilRareSlot, true);
|
||||
} else if (foilRarity < 4) {
|
||||
@@ -46,7 +46,7 @@ public class RarityPackBox implements PackBox {
|
||||
}
|
||||
}
|
||||
|
||||
addCard(result, _possibleRareCards.get(_random.nextInt(_possibleRareCards.size())), false);
|
||||
addCard(result, _possibleRareCards.get(ThreadLocalRandom.current().nextInt(_possibleRareCards.size())), false);
|
||||
|
||||
addRandomCardsOfRarity(result, 3, "U");
|
||||
addRandomCardsOfRarity(result, hasFoil ? 6 : 7, "C");
|
||||
@@ -72,7 +72,7 @@ public class RarityPackBox implements PackBox {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index;
|
||||
do {
|
||||
index = _random.nextInt(elementCount);
|
||||
index = ThreadLocalRandom.current().nextInt(elementCount);
|
||||
} while (addedIndices.contains(index));
|
||||
addedIndices.add(index);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,9 @@ import com.gempukku.lotro.game.packs.SetDefinition;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class ReflectionsPackBox implements PackBox {
|
||||
private Random _random = new Random();
|
||||
private SetDefinition _reflectionsRarity;
|
||||
private List<String> _previousSetCards = new ArrayList<String>();
|
||||
private List<String> _reflectionSlotCards = new ArrayList<String>();
|
||||
@@ -39,15 +38,15 @@ public class ReflectionsPackBox implements PackBox {
|
||||
public List<CardCollection.Item> openPack() {
|
||||
List<CardCollection.Item> result = new LinkedList<CardCollection.Item>();
|
||||
boolean foil;
|
||||
foil = _random.nextInt(15) == 0;
|
||||
foil = ThreadLocalRandom.current().nextInt(15) == 0;
|
||||
result.add(CardCollection.Item.createItem(getRandomReflectionsCard() + (foil ? "*" : ""), 1));
|
||||
foil = _random.nextInt(15) == 0;
|
||||
foil = ThreadLocalRandom.current().nextInt(15) == 0;
|
||||
result.add(CardCollection.Item.createItem(getRandomReflectionsCard() + (foil ? "*" : ""), 1));
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
final String blueprintId = _previousSetCards.get(_random.nextInt(_previousSetCards.size()));
|
||||
final String blueprintId = _previousSetCards.get(ThreadLocalRandom.current().nextInt(_previousSetCards.size()));
|
||||
// There is a 1/6 * 1/11 chance it will be a foil
|
||||
if (_random.nextInt(66) == 0)
|
||||
if (ThreadLocalRandom.current().nextInt(66) == 0)
|
||||
result.add(CardCollection.Item.createItem(blueprintId + "*", 1));
|
||||
else
|
||||
result.add(CardCollection.Item.createItem(blueprintId, 1));
|
||||
@@ -57,6 +56,6 @@ public class ReflectionsPackBox implements PackBox {
|
||||
}
|
||||
|
||||
public String getRandomReflectionsCard() {
|
||||
return _reflectionSlotCards.get(_random.nextInt(_reflectionSlotCards.size()));
|
||||
return _reflectionSlotCards.get(ThreadLocalRandom.current().nextInt(_reflectionSlotCards.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,113 +1,114 @@
|
||||
package com.gempukku.lotro.service;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class LoggedUserHolder {
|
||||
private long _loggedUserExpireLength = 1000 * 60 * 10; // 10 minutes session length
|
||||
private long _expireCheckInterval = 1000 * 60; // check every minute
|
||||
|
||||
private Map<String, String> _sessionIdsToUsers = new HashMap<String, String>();
|
||||
private Multimap<String, String> _usersToSessionIds = HashMultimap.create();
|
||||
|
||||
private Map<String, Long> _lastAccess = Collections.synchronizedMap(new HashMap<String, Long>());
|
||||
private ReadWriteLock _readWriteLock = new ReentrantReadWriteLock();
|
||||
private ClearExpiredRunnable _clearExpiredRunnable;
|
||||
|
||||
public void start() {
|
||||
_clearExpiredRunnable = new ClearExpiredRunnable();
|
||||
Thread thr = new Thread(_clearExpiredRunnable);
|
||||
thr.start();
|
||||
}
|
||||
|
||||
public String getLoggedUser(String sessionId) {
|
||||
_readWriteLock.readLock().lock();
|
||||
try {
|
||||
String loggedUser = _sessionIdsToUsers.get(sessionId);
|
||||
if (loggedUser != null) {
|
||||
_lastAccess.put(sessionId, System.currentTimeMillis());
|
||||
return loggedUser;
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.readLock().unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, String> logUser(String userName) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
Map<String, String> cookies = new HashMap<String, String>();
|
||||
String userValue = insertValueForUser(userName);
|
||||
cookies.put("loggedUser", userValue);
|
||||
_lastAccess.put(userValue, System.currentTimeMillis());
|
||||
return cookies;
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void forceLogoutUser(String userName) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
final Collection<String> sessionIds = new HashSet<String>(_usersToSessionIds.get(userName));
|
||||
for (String sessionId : sessionIds) {
|
||||
_sessionIdsToUsers.remove(sessionId);
|
||||
_usersToSessionIds.remove(userName, sessionId);
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private char[] _chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
||||
|
||||
private String insertValueForUser(String userName) {
|
||||
Random rnd = new Random();
|
||||
String sessionId;
|
||||
do {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < 20; i++)
|
||||
result.append(_chars[rnd.nextInt(_chars.length)]);
|
||||
sessionId = result.toString();
|
||||
} while (_sessionIdsToUsers.containsKey(sessionId));
|
||||
_sessionIdsToUsers.put(sessionId, userName);
|
||||
_usersToSessionIds.put(userName, sessionId);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
private class ClearExpiredRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
Iterator<Map.Entry<String, Long>> iterator = _lastAccess.entrySet().iterator();
|
||||
if (iterator.hasNext()) {
|
||||
Map.Entry<String, Long> lastAccess = iterator.next();
|
||||
long expireAt = lastAccess.getValue() + _loggedUserExpireLength;
|
||||
if (expireAt < currentTime) {
|
||||
String sessionId = lastAccess.getKey();
|
||||
final String userName = _sessionIdsToUsers.remove(sessionId);
|
||||
if (userName != null)
|
||||
_usersToSessionIds.remove(userName, sessionId);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(_expireCheckInterval);
|
||||
} catch (InterruptedException exp) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.gempukku.lotro.service;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class LoggedUserHolder {
|
||||
private long _loggedUserExpireLength = 1000 * 60 * 10; // 10 minutes session length
|
||||
private long _expireCheckInterval = 1000 * 60; // check every minute
|
||||
|
||||
private Map<String, String> _sessionIdsToUsers = new HashMap<String, String>();
|
||||
private Multimap<String, String> _usersToSessionIds = HashMultimap.create();
|
||||
|
||||
private Map<String, Long> _lastAccess = Collections.synchronizedMap(new HashMap<String, Long>());
|
||||
private ReadWriteLock _readWriteLock = new ReentrantReadWriteLock();
|
||||
private ClearExpiredRunnable _clearExpiredRunnable;
|
||||
|
||||
public void start() {
|
||||
_clearExpiredRunnable = new ClearExpiredRunnable();
|
||||
Thread thr = new Thread(_clearExpiredRunnable);
|
||||
thr.start();
|
||||
}
|
||||
|
||||
public String getLoggedUser(String sessionId) {
|
||||
_readWriteLock.readLock().lock();
|
||||
try {
|
||||
String loggedUser = _sessionIdsToUsers.get(sessionId);
|
||||
if (loggedUser != null) {
|
||||
_lastAccess.put(sessionId, System.currentTimeMillis());
|
||||
return loggedUser;
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.readLock().unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, String> logUser(String userName) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
Map<String, String> cookies = new HashMap<String, String>();
|
||||
String userValue = insertValueForUser(userName);
|
||||
cookies.put("loggedUser", userValue);
|
||||
_lastAccess.put(userValue, System.currentTimeMillis());
|
||||
return cookies;
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void forceLogoutUser(String userName) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
final Collection<String> sessionIds = new HashSet<String>(_usersToSessionIds.get(userName));
|
||||
for (String sessionId : sessionIds) {
|
||||
_sessionIdsToUsers.remove(sessionId);
|
||||
_usersToSessionIds.remove(userName, sessionId);
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private char[] _chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
||||
|
||||
private String insertValueForUser(String userName) {
|
||||
Random rnd = ThreadLocalRandom.current();
|
||||
String sessionId;
|
||||
do {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < 20; i++)
|
||||
result.append(_chars[rnd.nextInt(_chars.length)]);
|
||||
sessionId = result.toString();
|
||||
} while (_sessionIdsToUsers.containsKey(sessionId));
|
||||
_sessionIdsToUsers.put(sessionId, userName);
|
||||
_usersToSessionIds.put(userName, sessionId);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
private class ClearExpiredRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
Iterator<Map.Entry<String, Long>> iterator = _lastAccess.entrySet().iterator();
|
||||
if (iterator.hasNext()) {
|
||||
Map.Entry<String, Long> lastAccess = iterator.next();
|
||||
long expireAt = lastAccess.getValue() + _loggedUserExpireLength;
|
||||
if (expireAt < currentTime) {
|
||||
String sessionId = lastAccess.getKey();
|
||||
final String userName = _sessionIdsToUsers.remove(sessionId);
|
||||
if (userName != null)
|
||||
_usersToSessionIds.remove(userName, sessionId);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(_expireCheckInterval);
|
||||
} catch (InterruptedException exp) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.gempukku.lotro.game.packs.SetDefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class SingleEliminationOnDemandPrizes implements TournamentPrizes{
|
||||
private List<String> _promos = new ArrayList<String>();
|
||||
@@ -49,7 +49,7 @@ public class SingleEliminationOnDemandPrizes implements TournamentPrizes{
|
||||
}
|
||||
|
||||
private String getRandom(List<String> list) {
|
||||
return list.get(new Random().nextInt(list.size()));
|
||||
return list.get(ThreadLocalRandom.current().nextInt(list.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,95 +1,96 @@
|
||||
package com.gempukku.lotro.tournament;
|
||||
|
||||
import com.gempukku.lotro.competitive.PlayerStanding;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SingleEliminationPairing implements PairingMechanism {
|
||||
private String _registryRepresentation;
|
||||
|
||||
public SingleEliminationPairing(String registryRepresentation) {
|
||||
_registryRepresentation = registryRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegistryRepresentation() {
|
||||
return _registryRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished(int round, Set<String> players, Set<String> droppedPlayers) {
|
||||
return players.size() - droppedPlayers.size() < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayOffSystem() {
|
||||
return "Single elimination";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pairPlayers(int round, Set<String> players, Set<String> droppedPlayers, Map<String, Integer> playerByes, List<PlayerStanding> currentStandings,
|
||||
Map<String, Set<String>> previouslyPaired,
|
||||
Map<String, String> pairingResults, Set<String> byeResults) {
|
||||
if (isFinished(round, players, droppedPlayers))
|
||||
return true;
|
||||
|
||||
Set<String> playersInContention = new HashSet<String>(players);
|
||||
playersInContention.removeAll(droppedPlayers);
|
||||
|
||||
int maxByes = 0;
|
||||
for (Map.Entry<String, Integer> playerByeCount : playerByes.entrySet()) {
|
||||
String player = playerByeCount.getKey();
|
||||
if (playersInContention.contains(player))
|
||||
maxByes = Math.max(maxByes, playerByeCount.getValue());
|
||||
}
|
||||
|
||||
List<String>[] playersGroupedByByes = new List[maxByes+1];
|
||||
for (Map.Entry<String, Integer> playerByeCount : playerByes.entrySet()) {
|
||||
String player = playerByeCount.getKey();
|
||||
if (playersInContention.contains(player)) {
|
||||
int count = playerByeCount.getValue();
|
||||
List<String> playersWithThisNumberOfByes = playersGroupedByByes[maxByes - count];
|
||||
if (playersWithThisNumberOfByes == null) {
|
||||
playersWithThisNumberOfByes = new ArrayList<String>();
|
||||
playersGroupedByByes[maxByes - count] = playersWithThisNumberOfByes;
|
||||
}
|
||||
playersWithThisNumberOfByes.add(player);
|
||||
playersInContention.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> playersWithNoByes = playersGroupedByByes[maxByes];
|
||||
if (playersWithNoByes == null) {
|
||||
playersWithNoByes = new ArrayList<String>();
|
||||
playersGroupedByByes[maxByes] = playersWithNoByes;
|
||||
}
|
||||
playersWithNoByes.addAll(playersInContention);
|
||||
|
||||
List<String> playersRandomized = new ArrayList<String>();
|
||||
|
||||
for (List<String> playersGroupedByBye : playersGroupedByByes) {
|
||||
if (playersGroupedByBye != null) {
|
||||
Collections.shuffle(playersGroupedByBye);
|
||||
playersRandomized.addAll(playersGroupedByBye);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<String> playerIterator = playersRandomized.iterator();
|
||||
while (playerIterator.hasNext()) {
|
||||
String playerOne = playerIterator.next();
|
||||
if (playerIterator.hasNext()) {
|
||||
String playerTwo = playerIterator.next();
|
||||
pairingResults.put(playerOne, playerTwo);
|
||||
} else {
|
||||
byeResults.add(playerOne);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDropLoser() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package com.gempukku.lotro.tournament;
|
||||
|
||||
import com.gempukku.lotro.competitive.PlayerStanding;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class SingleEliminationPairing implements PairingMechanism {
|
||||
private String _registryRepresentation;
|
||||
|
||||
public SingleEliminationPairing(String registryRepresentation) {
|
||||
_registryRepresentation = registryRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegistryRepresentation() {
|
||||
return _registryRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished(int round, Set<String> players, Set<String> droppedPlayers) {
|
||||
return players.size() - droppedPlayers.size() < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayOffSystem() {
|
||||
return "Single elimination";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pairPlayers(int round, Set<String> players, Set<String> droppedPlayers, Map<String, Integer> playerByes, List<PlayerStanding> currentStandings,
|
||||
Map<String, Set<String>> previouslyPaired,
|
||||
Map<String, String> pairingResults, Set<String> byeResults) {
|
||||
if (isFinished(round, players, droppedPlayers))
|
||||
return true;
|
||||
|
||||
Set<String> playersInContention = new HashSet<String>(players);
|
||||
playersInContention.removeAll(droppedPlayers);
|
||||
|
||||
int maxByes = 0;
|
||||
for (Map.Entry<String, Integer> playerByeCount : playerByes.entrySet()) {
|
||||
String player = playerByeCount.getKey();
|
||||
if (playersInContention.contains(player))
|
||||
maxByes = Math.max(maxByes, playerByeCount.getValue());
|
||||
}
|
||||
|
||||
List<String>[] playersGroupedByByes = new List[maxByes+1];
|
||||
for (Map.Entry<String, Integer> playerByeCount : playerByes.entrySet()) {
|
||||
String player = playerByeCount.getKey();
|
||||
if (playersInContention.contains(player)) {
|
||||
int count = playerByeCount.getValue();
|
||||
List<String> playersWithThisNumberOfByes = playersGroupedByByes[maxByes - count];
|
||||
if (playersWithThisNumberOfByes == null) {
|
||||
playersWithThisNumberOfByes = new ArrayList<String>();
|
||||
playersGroupedByByes[maxByes - count] = playersWithThisNumberOfByes;
|
||||
}
|
||||
playersWithThisNumberOfByes.add(player);
|
||||
playersInContention.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> playersWithNoByes = playersGroupedByByes[maxByes];
|
||||
if (playersWithNoByes == null) {
|
||||
playersWithNoByes = new ArrayList<String>();
|
||||
playersGroupedByByes[maxByes] = playersWithNoByes;
|
||||
}
|
||||
playersWithNoByes.addAll(playersInContention);
|
||||
|
||||
List<String> playersRandomized = new ArrayList<String>();
|
||||
|
||||
for (List<String> playersGroupedByBye : playersGroupedByByes) {
|
||||
if (playersGroupedByBye != null) {
|
||||
Collections.shuffle(playersGroupedByBye, ThreadLocalRandom.current());
|
||||
playersRandomized.addAll(playersGroupedByBye);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<String> playerIterator = playersRandomized.iterator();
|
||||
while (playerIterator.hasNext()) {
|
||||
String playerOne = playerIterator.next();
|
||||
if (playerIterator.hasNext()) {
|
||||
String playerTwo = playerIterator.next();
|
||||
pairingResults.put(playerOne, playerTwo);
|
||||
} else {
|
||||
byeResults.add(playerOne);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDropLoser() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,8 @@ package com.gempukku.lotro.tournament;
|
||||
|
||||
import com.gempukku.lotro.competitive.PlayerStanding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class SwissPairingMechanism implements PairingMechanism {
|
||||
private String _registryRepresentation;
|
||||
@@ -163,7 +159,7 @@ public class SwissPairingMechanism implements PairingMechanism {
|
||||
|
||||
private void shufflePlayersWithinBrackets(List<List<String>> playersGroupedByPoints) {
|
||||
for (List<String> playersByPoint : playersGroupedByPoints) {
|
||||
Collections.shuffle(playersByPoint);
|
||||
Collections.shuffle(playersByPoint, ThreadLocalRandom.current());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package com.gempukku.mtg.provider.mtggoldfish;
|
||||
|
||||
import com.gempukku.mtg.CardData;
|
||||
import com.gempukku.mtg.MtgCardServer;
|
||||
import com.gempukku.mtg.MtgDataProvider;
|
||||
import com.gempukku.mtg.SetCardData;
|
||||
import com.gempukku.mtg.TimestampedCardCollection;
|
||||
import com.gempukku.mtg.*;
|
||||
import com.gempukku.mtg.provider.RetryUtil;
|
||||
import com.gempukku.mtg.provider.Retryable;
|
||||
import org.apache.log4j.Logger;
|
||||
@@ -21,8 +17,8 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class MtgGoldfishProvider implements MtgDataProvider {
|
||||
private static final Logger LOG = Logger.getLogger(MtgGoldfishProvider.class);
|
||||
@@ -178,8 +174,7 @@ public class MtgGoldfishProvider implements MtgDataProvider {
|
||||
}
|
||||
|
||||
private int getSleepTime() {
|
||||
Random rnd = new Random();
|
||||
return SLEEP_MINIMUM + rnd.nextInt(SLEEP_MAXIMUM - SLEEP_MINIMUM);
|
||||
return SLEEP_MINIMUM + ThreadLocalRandom.current().nextInt(SLEEP_MAXIMUM - SLEEP_MINIMUM);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,242 +1,235 @@
|
||||
package com.gempukku.lotro.tournament;
|
||||
|
||||
import com.gempukku.lotro.competitive.BestOfOneStandingsProducer;
|
||||
import com.gempukku.lotro.competitive.PlayerStanding;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class SwissPairingMechanismTest {
|
||||
// @Test
|
||||
// public void testPairingLargeTournament() {
|
||||
// int repeatCount = 1;
|
||||
// int playerCount = 4096*2;
|
||||
//
|
||||
// for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
// testSwissPairingForPlayerCount(playerCount);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void calculateSallyJackChances() {
|
||||
// 10 Sallys and 250 Jacks play in a tournament with 9 rounds of Swiss and Top 8.
|
||||
// Sally has 66% chance of winning a game against Jack and 50% against anotherSally, Jack has 50% of winning
|
||||
// a game against another Jack
|
||||
|
||||
int repeatCount = 100000;
|
||||
int roundCount = 9;
|
||||
|
||||
int betterPlayerCount = 10;
|
||||
int worsePlayerCount = 250;
|
||||
float chanceToWin = 0.66666f;
|
||||
|
||||
int playerCount = betterPlayerCount+worsePlayerCount;
|
||||
|
||||
int betterPlayerWins =0;
|
||||
|
||||
Set<String> betterPlayers = new HashSet<String>();
|
||||
Set<String> worsePlayers = new HashSet<String>();
|
||||
|
||||
Random rnd = new Random();
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
Set<String> players = new HashSet<String>();
|
||||
for (int i = 0; i < playerCount; i++) {
|
||||
String playerName = String.valueOf(i);
|
||||
players.add(playerName);
|
||||
if (i<betterPlayerCount)
|
||||
betterPlayers.add(playerName);
|
||||
else
|
||||
worsePlayers.add(playerName);
|
||||
}
|
||||
|
||||
Set<String> droppedPlayers = new HashSet<String>();
|
||||
Map<String, Integer> byes = new HashMap<String, Integer>();
|
||||
|
||||
Set<TournamentMatch> matches = new HashSet<TournamentMatch>();
|
||||
Map<String, Set<String>> previouslyPaired = new HashMap<String, Set<String>>();
|
||||
for (String player : players)
|
||||
previouslyPaired.put(player, new HashSet<String>());
|
||||
|
||||
SwissPairingMechanism pairing = new SwissPairingMechanism("swiss");
|
||||
for (int i = 1; i <= roundCount; i++) {
|
||||
if (!pairing.isFinished(i - 1, players, droppedPlayers)) {
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 3, 0, byes);
|
||||
|
||||
Map<String, String> newPairings = new LinkedHashMap<String, String>();
|
||||
Set<String> newByes = new HashSet<String>();
|
||||
|
||||
pairing.pairPlayers(i, players, droppedPlayers, byes, standings, previouslyPaired, newPairings, newByes);
|
||||
if (newByes.size() > 0) {
|
||||
for (String newBye : newByes) {
|
||||
byes.put(newBye, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> newPairing : newPairings.entrySet()) {
|
||||
String playerOne = newPairing.getKey();
|
||||
String playerTwo = newPairing.getValue();
|
||||
|
||||
String winner = getWinner(rnd, betterPlayers, worsePlayers, playerOne, playerTwo, chanceToWin);
|
||||
|
||||
previouslyPaired.get(playerOne).add(playerTwo);
|
||||
previouslyPaired.get(playerTwo).add(playerOne);
|
||||
|
||||
matches.add(new TournamentMatch(playerOne, playerTwo, winner, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
|
||||
String firstSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(0).getPlayerName(), standings.get(7).getPlayerName(), chanceToWin);
|
||||
String secondSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(1).getPlayerName(), standings.get(6).getPlayerName(), chanceToWin);
|
||||
String thirdSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(2).getPlayerName(), standings.get(5).getPlayerName(), chanceToWin);
|
||||
String fourthSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(3).getPlayerName(), standings.get(4).getPlayerName(), chanceToWin);
|
||||
|
||||
String firstFinalist = getWinner(rnd, betterPlayers, worsePlayers, firstSemi, fourthSemi, chanceToWin);
|
||||
String secondFinalist = getWinner(rnd, betterPlayers, worsePlayers, secondSemi, thirdSemi, chanceToWin);
|
||||
|
||||
String winner = getWinner(rnd, betterPlayers, worsePlayers, firstFinalist, secondFinalist, chanceToWin);
|
||||
|
||||
if (betterPlayers.contains(winner))
|
||||
betterPlayerWins++;
|
||||
}
|
||||
|
||||
System.out.println(betterPlayerWins);
|
||||
}
|
||||
|
||||
private String getWinner(Random rnd, Set<String> betterPlayers, Set<String> worsePlayers, String playerOne, String playerTwo, float winChance) {
|
||||
if (betterPlayers.contains(playerOne) && worsePlayers.contains(playerTwo)) {
|
||||
if (rnd.nextFloat() < winChance)
|
||||
return playerOne;
|
||||
else
|
||||
return playerTwo;
|
||||
} else if (betterPlayers.contains(playerTwo) && worsePlayers.contains(playerOne)) {
|
||||
if (rnd.nextFloat() < winChance)
|
||||
return playerTwo;
|
||||
else
|
||||
return playerOne;
|
||||
} else {
|
||||
if (rnd.nextBoolean())
|
||||
return playerOne;
|
||||
else
|
||||
return playerTwo;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingSmallTournament() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 12;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingVerySmallTournament() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 8;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingSmallTournamentWithOddNumberOfPlayers() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 9;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void testSwissPairingForPlayerCount(int playerCount) {
|
||||
Set<String> players = new HashSet<String>();
|
||||
for (int i = 0; i < playerCount; i++)
|
||||
players.add("p" + i);
|
||||
|
||||
Set<String> droppedPlayers = new HashSet<String>();
|
||||
Map<String, Integer> byes = new HashMap<String, Integer>();
|
||||
|
||||
Set<TournamentMatch> matches = new HashSet<TournamentMatch>();
|
||||
Map<String, Set<String>> previouslyPaired = new HashMap<String, Set<String>>();
|
||||
for (String player : players)
|
||||
previouslyPaired.put(player, new HashSet<String>());
|
||||
|
||||
SwissPairingMechanism pairing = new SwissPairingMechanism("swiss");
|
||||
for (int i = 1; i < 20; i++) {
|
||||
if (!pairing.isFinished(i - 1, players, droppedPlayers)) {
|
||||
System.out.println("Pairing round " + i);
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
for (PlayerStanding standing : standings) {
|
||||
String player = standing.getPlayerName();
|
||||
log(player + " points - " + standing.getPoints() + " played against: " + StringUtils.join(previouslyPaired.get(player), ","));
|
||||
}
|
||||
|
||||
Map<String, String> newPairings = new LinkedHashMap<String, String>();
|
||||
Set<String> newByes = new HashSet<String>();
|
||||
|
||||
assertFalse("Unable to pair for round " + i, pairing.pairPlayers(i, players, droppedPlayers, byes, standings, previouslyPaired, newPairings, newByes));
|
||||
assertEquals("Invalid number of pairings", playerCount / 2, newPairings.size());
|
||||
if (playerCount % 2 == 0)
|
||||
assertEquals("Invalid number of byes", 0, newByes.size());
|
||||
else {
|
||||
assertEquals("Invalid number of byes", 1, newByes.size());
|
||||
String newBye = newByes.iterator().next();
|
||||
log("Bye - " + newBye);
|
||||
assertNull("Player already received bye", byes.get(newBye));
|
||||
byes.put(newBye, 1);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> newPairing : newPairings.entrySet()) {
|
||||
String playerOne = newPairing.getKey();
|
||||
String playerTwo = newPairing.getValue();
|
||||
|
||||
assertFalse(previouslyPaired.get(playerOne).contains(playerTwo));
|
||||
assertFalse(previouslyPaired.get(playerTwo).contains(playerOne));
|
||||
|
||||
System.out.println("Paired " + playerOne + " against " + playerTwo + " points - " + getPlayerPoints(standings, playerOne) + " vs " + getPlayerPoints(standings, playerTwo));
|
||||
String winner = new Random().nextBoolean() ? playerOne : playerTwo;
|
||||
log("Winner - " + winner);
|
||||
|
||||
previouslyPaired.get(playerOne).add(playerTwo);
|
||||
previouslyPaired.get(playerTwo).add(playerOne);
|
||||
|
||||
matches.add(new TournamentMatch(playerOne, playerTwo, winner, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Final standings:");
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
for (PlayerStanding standing : standings) {
|
||||
String player = standing.getPlayerName();
|
||||
System.out.println(standing.getStanding() + ". " + player + " points - " + standing.getPoints() + " played against: " + StringUtils.join(previouslyPaired.get(player), ","));
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String s) {
|
||||
// System.out.println(s);
|
||||
}
|
||||
|
||||
private int getPlayerPoints(List<PlayerStanding> standings, String player) {
|
||||
for (PlayerStanding standing : standings) {
|
||||
if (standing.getPlayerName().equals(player))
|
||||
return standing.getPoints();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
package com.gempukku.lotro.tournament;
|
||||
|
||||
import com.gempukku.lotro.competitive.BestOfOneStandingsProducer;
|
||||
import com.gempukku.lotro.competitive.PlayerStanding;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class SwissPairingMechanismTest {
|
||||
// @Test
|
||||
// public void testPairingLargeTournament() {
|
||||
// int repeatCount = 1;
|
||||
// int playerCount = 4096*2;
|
||||
//
|
||||
// for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
// testSwissPairingForPlayerCount(playerCount);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void calculateSallyJackChances() {
|
||||
// 10 Sallys and 250 Jacks play in a tournament with 9 rounds of Swiss and Top 8.
|
||||
// Sally has 66% chance of winning a game against Jack and 50% against anotherSally, Jack has 50% of winning
|
||||
// a game against another Jack
|
||||
|
||||
int repeatCount = 100000;
|
||||
int roundCount = 9;
|
||||
|
||||
int betterPlayerCount = 10;
|
||||
int worsePlayerCount = 250;
|
||||
float chanceToWin = 0.66666f;
|
||||
|
||||
int playerCount = betterPlayerCount+worsePlayerCount;
|
||||
|
||||
int betterPlayerWins =0;
|
||||
|
||||
Set<String> betterPlayers = new HashSet<String>();
|
||||
Set<String> worsePlayers = new HashSet<String>();
|
||||
|
||||
Random rnd = ThreadLocalRandom.current();
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
Set<String> players = new HashSet<String>();
|
||||
for (int i = 0; i < playerCount; i++) {
|
||||
String playerName = String.valueOf(i);
|
||||
players.add(playerName);
|
||||
if (i<betterPlayerCount)
|
||||
betterPlayers.add(playerName);
|
||||
else
|
||||
worsePlayers.add(playerName);
|
||||
}
|
||||
|
||||
Set<String> droppedPlayers = new HashSet<String>();
|
||||
Map<String, Integer> byes = new HashMap<String, Integer>();
|
||||
|
||||
Set<TournamentMatch> matches = new HashSet<TournamentMatch>();
|
||||
Map<String, Set<String>> previouslyPaired = new HashMap<String, Set<String>>();
|
||||
for (String player : players)
|
||||
previouslyPaired.put(player, new HashSet<String>());
|
||||
|
||||
SwissPairingMechanism pairing = new SwissPairingMechanism("swiss");
|
||||
for (int i = 1; i <= roundCount; i++) {
|
||||
if (!pairing.isFinished(i - 1, players, droppedPlayers)) {
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 3, 0, byes);
|
||||
|
||||
Map<String, String> newPairings = new LinkedHashMap<String, String>();
|
||||
Set<String> newByes = new HashSet<String>();
|
||||
|
||||
pairing.pairPlayers(i, players, droppedPlayers, byes, standings, previouslyPaired, newPairings, newByes);
|
||||
if (newByes.size() > 0) {
|
||||
for (String newBye : newByes) {
|
||||
byes.put(newBye, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> newPairing : newPairings.entrySet()) {
|
||||
String playerOne = newPairing.getKey();
|
||||
String playerTwo = newPairing.getValue();
|
||||
|
||||
String winner = getWinner(rnd, betterPlayers, worsePlayers, playerOne, playerTwo, chanceToWin);
|
||||
|
||||
previouslyPaired.get(playerOne).add(playerTwo);
|
||||
previouslyPaired.get(playerTwo).add(playerOne);
|
||||
|
||||
matches.add(new TournamentMatch(playerOne, playerTwo, winner, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
|
||||
String firstSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(0).getPlayerName(), standings.get(7).getPlayerName(), chanceToWin);
|
||||
String secondSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(1).getPlayerName(), standings.get(6).getPlayerName(), chanceToWin);
|
||||
String thirdSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(2).getPlayerName(), standings.get(5).getPlayerName(), chanceToWin);
|
||||
String fourthSemi = getWinner(rnd, betterPlayers, worsePlayers, standings.get(3).getPlayerName(), standings.get(4).getPlayerName(), chanceToWin);
|
||||
|
||||
String firstFinalist = getWinner(rnd, betterPlayers, worsePlayers, firstSemi, fourthSemi, chanceToWin);
|
||||
String secondFinalist = getWinner(rnd, betterPlayers, worsePlayers, secondSemi, thirdSemi, chanceToWin);
|
||||
|
||||
String winner = getWinner(rnd, betterPlayers, worsePlayers, firstFinalist, secondFinalist, chanceToWin);
|
||||
|
||||
if (betterPlayers.contains(winner))
|
||||
betterPlayerWins++;
|
||||
}
|
||||
|
||||
System.out.println(betterPlayerWins);
|
||||
}
|
||||
|
||||
private String getWinner(Random rnd, Set<String> betterPlayers, Set<String> worsePlayers, String playerOne, String playerTwo, float winChance) {
|
||||
if (betterPlayers.contains(playerOne) && worsePlayers.contains(playerTwo)) {
|
||||
if (rnd.nextFloat() < winChance)
|
||||
return playerOne;
|
||||
else
|
||||
return playerTwo;
|
||||
} else if (betterPlayers.contains(playerTwo) && worsePlayers.contains(playerOne)) {
|
||||
if (rnd.nextFloat() < winChance)
|
||||
return playerTwo;
|
||||
else
|
||||
return playerOne;
|
||||
} else {
|
||||
if (rnd.nextBoolean())
|
||||
return playerOne;
|
||||
else
|
||||
return playerTwo;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingSmallTournament() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 12;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingVerySmallTournament() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 8;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingSmallTournamentWithOddNumberOfPlayers() {
|
||||
int repeatCount = 10;
|
||||
int playerCount = 9;
|
||||
|
||||
for (int repeat = 0; repeat < repeatCount; repeat++) {
|
||||
testSwissPairingForPlayerCount(playerCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void testSwissPairingForPlayerCount(int playerCount) {
|
||||
Set<String> players = new HashSet<String>();
|
||||
for (int i = 0; i < playerCount; i++)
|
||||
players.add("p" + i);
|
||||
|
||||
Set<String> droppedPlayers = new HashSet<String>();
|
||||
Map<String, Integer> byes = new HashMap<String, Integer>();
|
||||
|
||||
Set<TournamentMatch> matches = new HashSet<TournamentMatch>();
|
||||
Map<String, Set<String>> previouslyPaired = new HashMap<String, Set<String>>();
|
||||
for (String player : players)
|
||||
previouslyPaired.put(player, new HashSet<String>());
|
||||
|
||||
SwissPairingMechanism pairing = new SwissPairingMechanism("swiss");
|
||||
for (int i = 1; i < 20; i++) {
|
||||
if (!pairing.isFinished(i - 1, players, droppedPlayers)) {
|
||||
System.out.println("Pairing round " + i);
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
for (PlayerStanding standing : standings) {
|
||||
String player = standing.getPlayerName();
|
||||
log(player + " points - " + standing.getPoints() + " played against: " + StringUtils.join(previouslyPaired.get(player), ","));
|
||||
}
|
||||
|
||||
Map<String, String> newPairings = new LinkedHashMap<String, String>();
|
||||
Set<String> newByes = new HashSet<String>();
|
||||
|
||||
assertFalse("Unable to pair for round " + i, pairing.pairPlayers(i, players, droppedPlayers, byes, standings, previouslyPaired, newPairings, newByes));
|
||||
assertEquals("Invalid number of pairings", playerCount / 2, newPairings.size());
|
||||
if (playerCount % 2 == 0)
|
||||
assertEquals("Invalid number of byes", 0, newByes.size());
|
||||
else {
|
||||
assertEquals("Invalid number of byes", 1, newByes.size());
|
||||
String newBye = newByes.iterator().next();
|
||||
log("Bye - " + newBye);
|
||||
assertNull("Player already received bye", byes.get(newBye));
|
||||
byes.put(newBye, 1);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> newPairing : newPairings.entrySet()) {
|
||||
String playerOne = newPairing.getKey();
|
||||
String playerTwo = newPairing.getValue();
|
||||
|
||||
assertFalse(previouslyPaired.get(playerOne).contains(playerTwo));
|
||||
assertFalse(previouslyPaired.get(playerTwo).contains(playerOne));
|
||||
|
||||
System.out.println("Paired " + playerOne + " against " + playerTwo + " points - " + getPlayerPoints(standings, playerOne) + " vs " + getPlayerPoints(standings, playerTwo));
|
||||
String winner = ThreadLocalRandom.current().nextBoolean() ? playerOne : playerTwo;
|
||||
log("Winner - " + winner);
|
||||
|
||||
previouslyPaired.get(playerOne).add(playerTwo);
|
||||
previouslyPaired.get(playerTwo).add(playerOne);
|
||||
|
||||
matches.add(new TournamentMatch(playerOne, playerTwo, winner, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Final standings:");
|
||||
List<PlayerStanding> standings = BestOfOneStandingsProducer.produceStandings(players, matches, 1, 0, byes);
|
||||
for (PlayerStanding standing : standings) {
|
||||
String player = standing.getPlayerName();
|
||||
System.out.println(standing.getStanding() + ". " + player + " points - " + standing.getPoints() + " played against: " + StringUtils.join(previouslyPaired.get(player), ","));
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String s) {
|
||||
// System.out.println(s);
|
||||
}
|
||||
|
||||
private int getPlayerPoints(List<PlayerStanding> standings, String player) {
|
||||
for (PlayerStanding standing : standings) {
|
||||
if (standing.getPlayerName().equals(player))
|
||||
return standing.getPoints();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user