Table of Contents

Shortnote

Given the description on non-transitive dice we build a Second Life implementation that will allow the user to roll some dice. Essentially, the dice are rigged (they are not usual dice) so that the overall probability of the red dice will beat the probabilities of the blue dice and the blue dice will always beat the overall outcome of the green dice.

Demonstration

Implementation

Implementation wise, the actual spinning is performed by selecting any random combinations of the vector <x, y, z> and then spinning the dice 90 degrees on the axes of that vector.

In other words, the vector <1,0,1> will perform a 90 degree rotation on the $x$-axis and a 90 degree rotation on the $z$-axis.

These rotations are performed incrementally by first getting the current rotation of the dice and then spinning the dice starting from that rotation. Rotating the cube in 90 degree increments, and supposing that the cubes have a ZERO_ROTATION initial rotation, ensures that regardless of the spinning, the cubes will still end up with a face pointing upward.

Resources

Die Image Second Life UUID
1 55136c20-d5f1-23bc-8124-32d4804d2dc9
2 43a1dbab-2c13-16e1-efe8-54910ac1f0f8
3 405ca573-4c03-fe74-5cfc-36bbb8ce0d00
4 3b4f69f6-5297-ff40-ae06-36719fce559f
5 224d66a8-5f98-2e6f-d71a-d3c8f2256522
6 20bfd762-cfe1-3604-9724-0ad2cefd80e9
7 2ac84108-f73f-3056-575c-2758d64e41c5
8 7d896fd5-d6eb-cc04-5185-18e886aba4df
9 1c35c0a1-8f85-fb85-32fa-6e00fcc1d804

Code

dice_roll.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasProgress(integer percent, integer length, list symbols) {
    percent /= (integer)((float)100.0/(length));
    string p = llList2String(symbols,0);
    integer itra = 0;
    do {
        if(itra>percent-1) p += llList2String(symbols,2);
        else p += llList2String(symbols,1);
    } while(++itra<length);
    return p + llList2String(symbols,3);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
wasRandomRotate(integer times, float angle) {
    if(times <= 0) return;
    llSetText("⟳ Rolling ⟲\n" + wasProgress(times, 20, ["[", "█", "░", "]"]), <1,1,1>, 1);
    integer x = (integer)llFrand(2);
    integer y = (integer)llFrand(2);
    integer z = (integer)llFrand(2);
    vector rot = <x,y,z>*angle;
    llSetRot(llGetRot()*llEuler2Rot(rot*DEG_TO_RAD));
    wasRandomRotate(--times, angle);
}
 
integer power = 0;
 
default {
    state_entry() {
        power = 10;
        state arm;
    }
}
 
state arm {
    state_entry() {
        // alarm 5
        llSetTimerEvent(5);
    }
    touch_start(integer num) {
        llSetTimerEvent(0);
    }
    touch(integer num) {
        if(power > 99) return;
        ++power;
        llSetText("⟳ Power ⟲\n" + wasProgress(power, 20, ["[", "█", "░", "]"]), <1,1,1>, 1);
    }
    touch_end(integer num) {
        state release;
    }
    timer() {
        llSetText("", <1,1,1>, 1);
    }
}
 
state release {
    state_entry() {
        wasRandomRotate(power, 90);
        state default;
    }
}