Help Converting Java/JS to C# for Unity

Hey guys, I know this is a big ask but would anyone be able to help me convert this snippet of code to C# for use in Unity? I found it on this thread while looking for bit-wise poker hand evaluators, which is based on this article.

EDIT: Ignore the rest of this comment and skip to my latest reply, this just turned into a mess of me trying to bumble my way through this problem.

function evaluateHand(cs, ss) {
    var pokerHands = ["4 of a Kind",
                      "Straight Flush",
                      "Straight",
                      "Flush",
                      "High Card",
                      "1 Pair",
                      "2 Pair",
                      "Royal Flush",
                      "3 of a Kind",
                      "Full House"];

    var v,i,o,s = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];
    for (i = -1, v = o = 0; i < 5; i++, o = Math.pow(2, cs[i] * 4)) {
         v += o * ((v / o & 15) + 1);
    }
    v = v % 15 - ((s / (s & -s) == 31) || (s == 0x403c) ? 3 : 1);
    v -= (ss[0] == (ss[1] | ss[2] | ss[3] | ss[4])) * ((s == 0x7c00) ? -5 : 1);

    return pokerHands[v];
}

I tried my best at the conversion attempting to fix any errors in Unity’s console log, these are the steps I took but I had no luck in the end :(:

First error; implicit variables v, i, o, s can’t have multiple declarators (I actually have no idea what the typing is on these variables). So I changed this:

var v,i,o,s = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];

To this:

var v = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];
var i = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];
var o = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];
var s = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];

Which looks horrid, but the errors are gone now. Then next I cast: Mathf.Pow(2, cs[i] * 4) -in the for loop to an int. But the last error I can’t seem to figure out (on line 19):
Operator ‘*’ cannot be applied to operands of type ‘bool’ and ‘int’

This means that:

(ss[0] == (ss[1] | ss[2] | ss[3] | ss[4]))

-is a boolean right? I’ve never even seen these ‘|’ operators so I’m not sure how to go about fixing this. Any help would be appreciated! <3

EDIT: With a bit more searching, I’ve learned that ‘|’ is a bit-wise or operator in JavaScript, which seems different to C# from the Googling I’ve done:

JS: “Sets each bit to 1 if one of two bits is 1”
C#: “Copies a bit if it exists in either operand”

I’ve never even heard of bit-wise operators before this so I don’t know how to approach this.

Also those implicit variables are actually integers so I collapsed them back into 1 line.

EDIT2: Seems like the 2 operators are equivalent in both languages. I tried removing the comparison of ss[0] on line 19 which got rid of the error, but now there’s a divide by zero error on line 16 in the for loop. I’m unsure if this is caused by the removal, but I don’t know why it’s happening.

This is what my converted code currently looks like, which should be the same as the source code? However I’m still getting a divide by 0 error on line 8 (in the for loop). I’ve checked the variables I’m passing to the function and they seem to be the same as the one in the example of the original answer.

public string EvaluateHand(int[] ranks, int[] suits)
{
    var hands = new string[] { "4 of a Kind", "Straight Flush", "Straight", "Flush", "High Card", "1 Pair", "2 Pair", "Royal Flush", "3 of a Kind", "Full House" };

    int v, i, o, s = 1 << ranks[0] | 1 << ranks[1] | 1 << ranks[2] | 1 << ranks[3] | 1 << ranks[4];

    for (i = -1, v = o = 0; i < 5; i++, o = (int)Mathf.Pow(2, ranks[i] * 4))
        v += o * ((v / o & 15) + 1);

    v = v % 15 - ((s / (s & -s) == 31) || (s == 0x403c) ? 3 : 1);
    if (suits[0] == (suits[1] | suits[2] | suits[3] | suits[4]))
        v += (s == 0x7c00) ? 5 : -1;

    return hands[v];
}

Here’s my console log (the error still happens if I hard code the 2 arrays that were in the example):
7593601--941797--upload_2021-10-22_22-19-16.png

The only thing I could think of is that the int casting of the o variable in the for loop header could be causing the issue, but I’m not sure how to fix that. Please help :frowning:

Please share your exact code you are using. You have Debug.Log output in your screenshot, but no Debug.Log statements in your code. I would highly recommend using more descriptive variables names instead of just “o” (looks like a zero!) What is your intent in this code, for example

v += (s == 0x7c00)

You are adding a boolean result to a integer? I assume your intent that true = 1, correct?

I might suggest to add a dozen more Debug.Log statements, one before and after each if statement (overkill, but hopefully you get the idea!)

Maybe the code wasn’t scrolled far enough, the full line is:
v += (s == 0x7c00) ? 5 : -1;

Unfortunately I actually have no idea what any of the variables are supposed to be, and I didn’t want to rename much since I’d probably make a mistake and cause even more issues.

I also took your advice with more debug statements, still have a divide by 0 error but it turns out it didn’t like multiple declarators and was only assigning a value to s, out of the variables v, i, o, s.

These values are also usually in the thousands, and thus the index in the for loop header used to access the ranks array is way out of bounds.

I’m not sure what index is supposed to be used here, since the first value of i in the for loop overrides the previous assignment? It also initializes at -1, which can’t be used as an index right? I’m getting more and more confused!

Thanks for the reply though, I feel like some progress was made. I’ve attached the relevant cs files, I don’t really want to copy paste all that trash into this reply.

7594558–942049–CS Files.zip (2.18 KB)

My code portion was correct, I was asking about the logic you’re using. That is a “shorthand” notation for an If statement, I was asking specifically about v += (s == 0x7c00), what is your expectation for the value of v? And what is 0x7c00 there for? If it’s dividing my zero, use Debug.Log to find out which variable it is! It will be equal to zero, prior to the division. However, and a word of advice, if you don’t understand the code that you are writing, you shouldn’t be using it. You should back up and work with a few tutorials and C# lessons. This may provide more insight into using Debug.Log https://discussions.unity.com/t/748729/14 What I typically do when learning something new (like using Debug.Log!), I create a new/simple project, outside of my main project. This way my main project is never “broken”. Like a project named “MyDebugLogTestProject” :slight_smile:

You’re definitely right about not understanding the code, I wanted to see if I could use this function since it seems to be the most effective method (to evaluate poker hands) and fits my needs perfectly. Though it seems I’m way out of my depth. The other methods I’ve seen that evaluate poker hands are either even more complex or in languages that are too far removed from C# for me to understand.

I also technically never started with a working main project, since I just copied the JavaScript code directly into Unity and tried to convert it to C# piecemeal. Which I know is dumb, but I thought this code snippet was short enough to work with, which obviously was not the case.

Anyway, I have absolutely no idea what the expected value of v is in v += (s == 0x7c00).

The divide by 0 error lies in the o variable in v += o * ((v / o & 15) + 1). The debug shows o has a value of 0, which I assume is a result of (int)Mathf.Pow(2, ranks * 4))? I don’t know what the value of the index i is, since it’s within the for loop header and I’m unsure if it’s supposed to be the previously assigned i, or the newly assigned i within the header itself (which starts at -1?).
I’ve decided I’ll probably give up on the project, maybe come back in the future. Thanks for the input!