PDA

View Full Version : How to Sort Dice Roll Results?



PneumaPilot
November 6th, 2008, 16:38
Does anyone have any idea if it is even POSSIBLE to sort the results of a die roll as it appears in the chat window?

For systems like Shadowrun and World of Darkness, that rely on comparing each die rolled to a given success number, sorting the rolls would be immensely helpful.

Oberoten
November 6th, 2008, 16:40
I have something else that might be useful... An old Exalted ruleset made during the Beta-test period. Given permission I might be able to rip out and hand over the code for the dice and modifier box from it.

- Obe

Tenian
November 6th, 2008, 16:42
It should be.

The dice are stored in a table, along with the results. It should be possible to create a local table, sort it, and then overwrite the existing table.

Oberoten
November 6th, 2008, 16:50
It even has the modifier box set so it becomes number of dice to roll or not.

PneumaPilot
November 6th, 2008, 19:11
Wow, that sounds cool. I would even be satisfied just knowing where that code is STORED, however. When I look at the various scripts, what I am looking for never quite seems to be where I would expect it. I have a decent amount of programming experience, so just point me in the right place.

Oberoten
November 6th, 2008, 19:19
https://www.fantasygrounds.com/forums/showthread.php?t=6018&highlight=Exalted+Ruleset

This thread has the ruleset available for download. And it has some pretty interesting functions as well.

- Obe

PneumaPilot
November 6th, 2008, 20:09
Great, I'll check it out. Thanks a ton.

PneumaPilot
November 6th, 2008, 21:06
Just for curiosity (and because I'll need it even when looking at the Exalted set), which script would that functionality be located in?

Oberoten
November 6th, 2008, 21:15
Let me see...

ds10dice.lua
chatmanager.lua
chat_chat.lua

Seems to be the affected ones?

PneumaPilot
November 6th, 2008, 21:44
Thanks a ton man. You're my hero. No, seriously.

Oberoten
November 6th, 2008, 21:49
I am glad I could help. You have made a LOT of people around here very happy with this ruleset.

Also? I have a major tooth-ache from a shattered tooth... so I am sleeples and bored. :) So just glad SOME good can come from that too.

- Obe

PneumaPilot
November 6th, 2008, 22:16
Gah! Sorry about the tooth! Hey, as soon as I get this ruleset cleaned up a little more (dice sorting plus removing D20 specific clutter), I'll upload it. I want other people to be able to use it.

Oberoten
November 6th, 2008, 22:17
Very good. :) It is a GOOD project and one much awaited.

- Obe

PneumaPilot
November 10th, 2008, 23:13
Well, I checked out the Exalted ruleset. I see now how to get the thing to count successes. That is a very useful thing to know. However, the dice rolls are not sorted when rolled. Of course, I suppose that there is no need to sort them if the program counts successes for you.

Also, the Exalted ruleset currently counts a 10 as two successes instead of rolling it again. I know that the other guy who was working on the World of Darkness ruleset before I came along was spending a lot of time trying to get the thing to reroll 10s. Maybe the best thing (And the only thing I can think of off the top of my head) would be to just have the chat window tell you to "reroll 2" or something. That would be easy to implement - if not ideal.

Actually, though, I still want the rolls sorted because there are some items and powers in WoD that let you reroll 9s or even 8s. I would rather put all of the impetus on the player to reroll whatever they needed. So maybe I SHOULD stay away from success counting and just try to find a sort method.

PneumaPilot
November 11th, 2008, 05:23
Dad-GUM! Why couldn't the devs just had the silly thing sort your die rolls!? I mean, it's nothing for them on their side, they just apparently haven't opened that functionality up to the user! I mean does any system ANYWHERE need a list of die rolls that are NOT sorted! Bah! The silliness of this just astounds me.

Devs, could you pretty-please add one little line of code that sorts the die rolls before they go into the drop handler?

Foen
November 11th, 2008, 06:33
Actually, I think there are times when unsorted rolls are important: I like to throw attack and damage rolls against multiple opponents in one go, and then read the results left-to-right. You couldn't do that with sorted rolls.

That said, there are probably as many times (if not more) when sorted rolls are useful.

I've not looked into it myself, but can you use table.sort from the Lua library to sort die rolls?

Foen

PneumaPilot
November 11th, 2008, 06:49
The problem with table.sort is that the way the dicelist table is built, the sort function ends up comparing two tables, and there's something secret in the construction of the dicelist that ends up foiling all attempts to reconstruct one after a workaround sort.

But, after long last I have come up with a workable solution. There is one problem that I would like some help with, but I'll get to that in a minute. First, here is the code:


function onDiceLanded(draginfo)
if draginfo.isType("dice") then
for i = 1, draginfo.getSlotCount() do
draginfo.setSlot(i);
dicelist = draginfo.getDieList();

local entry = {};
entry.font = "systemfont";
entry.icon = "indicator_casterprep";

if dicelist then
local dicecount=table.maxn(dicelist);
local successes=0;
local tens={};
local nines={};
local eights={};
local sevens={};
local sixes={};
local fives={};
local fours={};
local threes={};
local twos={};
local ones={};

local reform={};

for c = 1, dicecount do
if dicelist[c].result==10 then
successes=successes+1;
table.insert(tens,c);
elseif dicelist[c].result==9 then
successes=successes+1;
table.insert(nines,c);
elseif dicelist[c].result==8 then
successes=successes+1;
table.insert(eights,c);
elseif dicelist[c].result==7 then
table.insert(sevens,c);
elseif dicelist[c].result==6 then
table.insert(sixes,c);
elseif dicelist[c].result==5 then
table.insert(fives,c);
elseif dicelist[c].result==4 then
table.insert(fours,c);
elseif dicelist[c].result==3 then
table.insert(threes,c);
elseif dicelist[c].result==2 then
table.insert(twos,c);
elseif dicelist[c].result==1 then
table.insert(ones,c);
end
end

for c = 1, table.maxn(tens) do
table.insert(reform,dicelist[tens[c]]);
end
for c = 1, table.maxn(nines) do
table.insert(reform,dicelist[nines[c]]);
end
for c = 1, table.maxn(eights) do
table.insert(reform,dicelist[eights[c]]);
end
for c = 1, table.maxn(sevens) do
table.insert(reform,dicelist[sevens[c]]);
end
for c = 1, table.maxn(sixes) do
table.insert(reform,dicelist[sixes[c]]);
end
for c = 1, table.maxn(fives) do
table.insert(reform,dicelist[fives[c]]);
end
for c = 1, table.maxn(fours) do
table.insert(reform,dicelist[fours[c]]);
end
for c = 1, table.maxn(threes) do
table.insert(reform,dicelist[threes[c]]);
end
for c = 1, table.maxn(twos) do
table.insert(reform,dicelist[twos[c]]);
end
for c = 1, table.maxn(ones) do
table.insert(reform,dicelist[ones[c]]);
end

draginfo.setDieList(reform);

entry.text = "Success: " .. successes;
entry.dice = reform;

if User.isHost() then
entry.sender = GmIdentityManager.getCurrent();
else
entry.sender = User.getIdentityLabel();
end
else
entry.text = "No dice left to roll.";
end

deliverMessage(entry);

end
end

end


Of course, you will notice right away the ridiculousness of such a thing, but it was the only thing I could do to reconstruct a dicelist as the program builds it. I do it by breaking up the original table into one table for each possible result that does nothing but store the index of that result. Then, at the end, a dicelist is put back together by reordering the elements of the original list (rather than create it yourself). Is it ugly? Yes. Does it sort the list? Yes.

Now, the problem: I get an empty bubble following the sorted list with a big zero in it. Others have mentioned this problem before. Calling the setDieList function in the onDiceLanded event just clears the dielist totally. It will always show a 0 in this case. However, you don't want it to display the unsorted list directly after the sorted list, so the best thing would be to remove the second bubble entirely. Can this be done?

Oh, by the way, the script also counts successes for the nWoD rules (8 and above on D10s), but it does not reroll 10s for you. Sometimes you need to reroll all 9s and 10s (like when using a shotgun). And sometimes you reroll 8s, 9s, AND 10s. Maybe in the future I can turn the Modifier box into a box with 2 checkboxes: "9-Again" and "8-Again", which when activated will reroll the appropriate dice, and when not checked will only reroll 10s. But for now, it seems easier to let the player make that call rather than code.

joshuha
November 11th, 2008, 13:50
I just wrote this bit of code to perform a classic bubble sort and sort the die results in order. This doesn't iterate over the different slots but in WoD I don't see you using multi-slotted draginfo much. But if you wanted you could wrap this in a loop over the slots.



elseif draginfo.isType("dice") then
--applyModifierStackToRoll(draginfo);
a = draginfo.getDieList();
repeat
swapped = false;
for i = 1, table.maxn(a)-1 do
print(i);
if a[i].result < a[i+1].result then
tempdie = {};
tempdie.result = a[i].result;
tempdie.type = a[i].type;
print(a[i].result .. " less than " .. a[i+1].result);
a[i].type = a[i+1].type;
a[i].result = a[i+1].result;
a[i+1].result = tempdie.result;
a[i+1].type = tempdie.type;
print(a[i].result .. " swapped " .. a[i+1].result);
swapped = true;
end
end
until swapped == false;

local entry = {};
entry.text = draginfo.getStringData();
entry.font = "systemfont";
entry.dice = a;
entry.diemodifier = draginfo.getNumberData();

if User.isHost() then
if ChatManager.getDieRevealFlag() then
entry.dicesecret = false;
end
entry.sender = GmIdentityManager.getCurrent();
else
entry.sender = User.getIdentityLabel();
end

deliverMessage(entry);


return true;
end

PneumaPilot
November 11th, 2008, 14:19
I shall try it immediately the next time I boot to Windows. Thanks!

Foen
November 11th, 2008, 19:08
From a completely nerdy perspective, PneumaPilot's algorithm was more like a bucket sort (hence order n) and Joshuha's bubble sort is the classic order n-squared. For large arrays, bucket sort is fab, for FG I don't think it matters too much!

I said it was nerdy ;)

Foen

PneumaPilot
November 13th, 2008, 20:35
Eh, they get the job done, that's what's important. Any advice on how to remove the second bubble, though?

joshuha
November 13th, 2008, 21:58
Try a return true; after your deliver message. That means you want to not let FG do its default processing. In this case since you have already handled the dice list and delivered the message that should be what you want. Otherwise what it is probably trying to do is process a now empty dielist and thus returning a 0.

PneumaPilot
November 13th, 2008, 23:42
That did it! You're the man!

VenomousFiligree
June 20th, 2009, 23:09
As I wouldn't know where to even think about putting this code, is it possible it can be done as an extension?

:)
MB

Foen
June 21st, 2009, 06:33
I think you might be able to do it as an extension, but it would only work for rulesets that don't otherwise handle onDiceLanded (many of them do).

VenomousFiligree
June 21st, 2009, 08:00
OK, how about some pointers on where to look for / put the code? I've looked at the nWoD ruleset and it does what I want, except I don't want the number of successes.

Lithl
June 21st, 2009, 08:11
Check chat_chat.lua