Trying to make a way to check certain conditions for a win

eeeeeeeeeeeeeeeehhhhhhhhhhhhhhhhhhhhhhhh[quote=“Ryan, post:3, topic:5849, full:true”]

This is kind of what I had in mind, I’m just not entirely sure how to check if, for example, 3 of 5 objects return the same value without going into the long if/else statements. The only way I can think of off the top of my head is basically: if object1 = object2 =object3 or object2 = object3 = object4, etc.and this is what I would prefer to avoid because then the code gets obnoxious and hard to read.
[/quote]

:slightly_frowning_face::expressionless::expressionless::expressionless:hhhhuu3y83

Good news is, this works. Now I just have to figure out how to get the straights conditions to work.

Just had an idea to check for the straights win conditions. Is there a way I can check if the results array contains the numbers required to trigger that condition?
Something like:

If(array contains 1, 2, 3, 4 or 2, 3, 4, 5 or etc.)

Forgetting about my “if array contains” idea, I gave something like this a try and it works like a charm. Here’s a link to the full code for checking the win, plus the script for cashing out based on the result.
Check result: https://playcanvas.com/editor/code/529780?tabs=10964296,10861152,10827801,10800992,10830385
Cashout: https://playcanvas.com/editor/code/529780?tabs=10964296,10861152,10827801,10800992,10830385

Cool. I’m happy it worked :slight_smile:

Pretty well, although the overall code is having a weird looping issue (made another post about it Certain parts of script being called 6 times) and it’s gotten me completely stuck.

I did just find a small bug with this method, it seems if you roll something like 1,2,4,5,6 it will return a small straight when it shouldn’t.

var results = [1, 2, 1, 4, 5, 6];
var bestCount = 0;
var bestValue = null;
var currentCount = 0;
var currentValue = null;
var i;

results.sort();
for (i = 0; i < results.length; i++) {
    if (currentValue === null || results[i] != currentValue + 1) {
      currentCount = 1;
   } else {
      currentCount++; 
   }
   currentValue = results[i];
   if (currentCount > bestCount) {
      bestCount = currentCount;
      bestValue = currentValue;
   }
}

console.log(bestCount);
console.log(bestValue);

This returns 3 as bestCount and 6 as bestValue.

This is how I managed to solve it. It includes code to check for the straight conditions, and gets around counting a straight when there isn’t one.

CheckRoll.prototype.getResults = function()
{
    //Uncomment next line and change values to test different win conditions
    //this.results = [1,2,3,4,5];
    
    //Sort results from lowest to highest
    this.results.sort();
    console.log("Results: " + this.results);
    for(i=0;i<this.results.length;i++)
    {
        if(i >= 1)
        {
            j = i - 1;
        }
        else
        {
            j = null;
        }
        //Check if the current result is the same as the last result
        if(this.results[i] !== this.currentValue)
        {
            //Make the current result the last result if it isn't
            //and start counting how many results match this one
            this.currentCount = 1;
            this.currentValue = this.results[i];
        }
        else
        {
            //Increment count if current result is same as last result
            this.currentCount++;
        }
        
        if(this.results[j] === this.results[i] - 1)
        {
            this.straightCount++;
            console.log("Result= " + this.results[i] + " Straight= " + this.straightCount);
        }
        //Minor fix here. If results = 1,2,3,4,6, straightCount = 1 before prize check and would count as loss
        else if(this.results[j] !== this.results[i] && this.straightCount < 4 || this.straightCount > 5) 
        {
            this.straightCount = 1;       
        }
        
        if(this.currentCount > this.bestCount)
        {
            if(this.currentValue !== this.bestValue)
            {
                //Set the previous best count and value to second place for later use
                this.secondCount = this.bestCount;
                this.secondValue = this.bestValue;
            }
            //Set the current best count and value
            this.bestCount = this.currentCount;
            this.bestValue = this.currentValue;
        }
        //If best value is lower than current value,
        //make it second value, and its count second count
        else if(this.currentValue > this.bestValue)
        {
            this.secondCount = this.currentCount;
            this.secondValue = this.currentValue;
        }
    }
    this.manager.script.winCheck.payTable();
};

Still can’t figure out why this gets run 6 times on the initial start call though.

Found it. For some reason on the initial start call only, this function gets run 6 times:

CheckRoll.prototype.check = function()
{
    //Makes sure each dice has stopped by comparing its current position
    //to its last position
    for(i=0;i<dice.length;i++)
    {
        if(dice[i].stopped !== true)
        {
            var diePos = dice[i].getLocalPosition();
        
            currPos = new pc.Vec3(this.toDecimal(diePos.x), this.toDecimal(diePos.y), this.toDecimal(diePos.z));
            if(currPos.x === lastPos.x && currPos.y === lastPos.y && currPos.z === lastPos.z)
            {
                dice[i].stopped = true;
                this.stopped = true;
            }
            else
            {
                lastPos = currPos;
                this.check();
            }
        }
    }
    this.stopCheck();
};

I understand it has something to do with calling check() in the else statement, but the overall function doesn’t work at all if it’s not there.

I didn’t open the project (too few time available, sorry), but looking at this code there are a few things I would review/fix:

  1. Don’t make one huge function to check all the possible results. Create one function for each type of check and start checking from the highest possible result to the lowest. As soon as one function returns a positive match, then stop the research and use the result for your next step (for examples calculating rewards).
  2. You should check that all the dices are stopped before to search for results.
  3. The check function calls itself. It’s a bit weird and dangerous. I don’t understand why you do this. I would call this check once per frame from the update function.

I had made the function call itself because it would end up skipping over the check for when the dice are stopped altogether, although I suppose putting in update would work just as well. I just realized that I could have just wrapped the whole thing in a while loop.

I have something like this, unfortunately it’s tied to a timer that seems to take precedence over the actual check.

Are you referring to the checkResult function or that assigns the roll’s value to the dice or the getResults function that comes after?

getResults

I was also looking at your check function. You already loop through all the dices. Why you have that additional do/while? Why should the dice change its position during the same loop?

What I see is:

  1. dice 1 is now in position 10 and before was in position 9 (lastPos).
  2. is the same position? no, so store in lastPos the current position as 10.
  3. in the same frame and before the dice could be moved again by the engine you check it the position of the dice that is still 10 is equal to lastPos. Of course it is… so it is stopped…
  4. now go to dice 2 and repeat

I wonder how is it working at all. Or I’m missing something…

Remove the do/while and call the check function every frame. not just once in a while. Wait a split of second from when you roll the dices so that the check is executed when the dice are already moving, and keep calling it until all dices are stopped.

A problem I found with this was due to the speed at which the dice move and the rate at which update ticks the dice would barely move before it would call check and get the results, so by the time they had actually settled the final call ends up being whatever position the dice were in before they cam to a complete stop. This is still evident when I attempt to debug and end up holding up the check, all of the dice are assigned a value of 1.

Okay, I see what you mean by breaking that one up.

For some reason the check function doesn’t fire at all when I try doing this, unless I’m going about it wrong.

CheckRoll.prototype.update = function(dt)
{
    
    this.timer += dt * 6;
    console.log(this.toDecimal(this.timer));
    if(this.timer>=5)
    {
        this.timer = 0;
        this.check();
    }
};

CheckRoll.prototype.check = function()
{
    //Makes sure each dice has stopped by comparing its current position
    //to its last position
    for(i=0;i<dice.length;i++)
    {
        var diePos = dice[i].getLocalPosition();
        currPos = new pc.Vec3(this.toDecimal(diePos.x), this.toDecimal(diePos.y), this.toDecimal(diePos.z));
        if(currPos.x === lastPos.x && currPos.y === lastPos.y && currPos.z === lastPos.z)
        {
            dice[i].stopped = true;
            this.stopped = true;
        }
        else
        {
             lastPos = currPos;
        }
    }
    this.stopCheck();
};

I see that you use the getDecimal function to round to just one digit after the comma, like 1,23 = 1,2
This, of course, will break the check on the dice movement, because 1,23 will be the same as 1,24
I would not round the dice coordinates at all. Once the dice stop moving its position will be exactly the same as in the previous frame. Otherwise will be just a bit different enough to make the stopping check to fail.

I see what you mean here, but what was happening was I would click the roll button and the check would count the position the dice were at before they even moved due to update firing so frequently. Although, the issue now is check doesn’t trigger at all.

this has nothing to do with the getDecimal (that could only make the thing worst), but with a starting timer that should delay the starting check.

I’m looking at it but I don’t see why this code should not call the check function after about 1 second.

I have it set for 5, if the math is right, but it just keeps looping the timer even after I click the button.

Simplify it a bit.
dt is a fraction of time, so just increase this.time by dt and check for the amount of seconds you want to wait:

CheckRoll.prototype.update = function(dt)
{
    
    this.timer += dt;
    console.log(this.timer);
    if(this.timer>=1) // 1 second
    {
        this.timer = 0;
        this.check();
    }
};

in the console you should see the timer value to go up to 1 and then from 0 again.
Is it happening? So the check function for sure is called.