Reputation: 63
First of all, thank you for taking the time to read this. I am quite new to android development and appreciate all the help I can get. I'll keep the description brief.
I'm developing an app as a side project to speed up the d&d sessions of me and my friends by automating the initiative rolls (rolling a 20-sided dice, adding a personal modifier and sorting from largest to smallest). Everything was going great until I hit a bug which to my frustration I haven't been able to fix. The length of the sorted Arraylist with names and of the complimentary dictionary always seems to be zero and I cannot find out why. Code is posted below.
First step is to collect user data from the input. the input works like this (this explains the weird ID's)
//updates player database with user input
private void updateDictionaryManager(int _partySize) {
listManager.empty();
if (_partySize > 0) {
for (int i = 0; i < _partySize + 1; i++) {
EditText Name = (EditText)findViewById(i);
EditText dexMod = (EditText)findViewById(i + 10);
String playerName = "player " + String.valueOf(i);
int playerDexMod = 0;
if (Name.getText() != null) {
playerName = Name.getText().toString();
}
if (dexMod.getText() != null) {
try {
playerDexMod = Integer.parseInt(dexMod.getText().toString());
} catch (Exception e) {
playerDexMod = 0;
}
}
listManager.append(playerName, playerDexMod, i);
}
}
}
This is the code from the listmanager class
public void append(String _name, int _dexMod, int _playerNumber) {
if (!_name.equals("")) {
playerNames.add(_name);
} else {
String defaultName = "player " + String.valueOf(_playerNumber);
playerNames.add(defaultName);
}
dexMod.add(_dexMod);
}
public void empty() {
playerNames.clear();
dexMod.clear();
}
I guess the problem hides here (but I send the prvious just in case I missed something there)
final class InitiativeRoller extends ListManager{
Map<Integer, List<String>> playerRolls = new HashMap<>();
Map<String, Integer> outputDictionary = new HashMap<>();
List<Integer> alreadyRolled = new ArrayList<>();
List<String> outputOrder = new ArrayList<>();
public void roll() {
//retrieve lists from manager
List<String> _names = getPlayerNames();
List<Integer> _dexMod = getDexMod();
//rolling the dice and saving values
for (int i = 0; i < getSize(); i++) {
int _roll = (int) Math.round(Math.random() * 19) + 1 + _dexMod.get(i);
if (alreadyRolled.contains(_roll)) {
//add name to list in dictionary with corresponding roll
playerRolls.get(_roll).add(_names.get(i));
} else {
//generate new list for players with this roll and add to playerRolls
List<String> _list = new ArrayList<>();
_list.add(_names.get(i));
playerRolls.put(_roll, _list);
alreadyRolled.add(_roll);
}
}
//sorting the rolls from largest to smallest
Collections.sort(alreadyRolled);
Collections.reverse(alreadyRolled);
//generating output dictionary
for (int i = 0; i < alreadyRolled.size(); i++) {
int _roll = alreadyRolled.get(i);
List<String> list = playerRolls.get(_roll);
//shuffling order of players with the same roll
Collections.shuffle(list);
//add to output dictionary and list
for (int x = 0; x < list.size(); x++) {
outputDictionary.put(list.get(x), _roll);
outputOrder.add(list.get(x));
}
}
}
public Map<String, Integer> getOutputDictionary() {
return outputDictionary;
}
public List<String> getOutputOrder() {
return outputOrder;
}
}
Every time I check, the resulting outputDictionary and outputorder have a length of zero. What am I missing? Sorry for the long post.
EDIT: I have checked the code and there does not seem to be a problem with the length of the list until the point where getPlayerNames and getDexMod are called inside the InitiativeRollerClass.
EDIT: Here are the get-methods
public List<String> getPlayerNames() {
return playerNames;
}
public List<Integer> getDexMod() {
return dexMod;
}
UPDATE: This is the code bound to the roll-button:
rollInitiative.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//update dictionary
int roundedProgress = Math.round(playerSlider.getProgress());
try {
updateDictionaryManager(roundedProgress);
} catch (Exception e) {
updateDictionaryManagerOnException(roundedProgress, playerList);
}
initiativeRoller.roll();
displayResult(initiativeRoller.getOutputOrder(), initiativeRoller.getOutputDictionary(), InitiativeList);
}
});
the method is described here, this is just for debugging
//displays output to user
private void displayResult(List<String> _outputOrder, Map<String, Integer> _outputDictionary, TextView _initiativelist) {
_initiativelist.setText(listManager.getDexMod() + "\n" + listManager.getPlayerNames()
+ "\n" + initiativeRoller.getOutputOrder());
}
This brings me the following
I also checked online if the code itself for the roll class was even functioning, it was. Here is the result for four hard coded names and values after a number of runs:
[Aaron, Josh, Clide, Li]
{Aaron=24, Clide=20, Josh=22, Li=8}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Josh, Li, Aaron, Clide]
{Aaron=6, Clide=6, Josh=20, Li=12}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Aaron, Clide, Li, Josh]
{Aaron=20, Clide=17, Josh=10, Li=11}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Li, Aaron, Clide, Josh]
{Aaron=19, Clide=18, Josh=18, Li=21}
Everything seems to be working just fine, I just don't understand why the returned list has a length of zero.
p.s. the code for the getSize() method
public int getSize() {
return playerNames.size();
}
Upvotes: 1
Views: 178
Reputation: 74
Ok, this might be the error: keep in mind that in Java every variable just as any other compiled language has a scope. Now you decleare playerName and playerDexMod inside the for and you append them inside that for, up until now everything is in check. When you exit the for however those variables just die, and by that I mean that the java garbage collector, since they're out of scope, should deallocate them. Now the listManager ( which I suppose is an ArrayList) finds itself with objects that don't exist anymore, so basically null. And that's just an empty array list. If the listManager you use is decleared in a class try to decleare also the other variables in a class, so they won't get out of scope. Tell me if this helps.
Upvotes: 1