It's an obfuscated way of multiplying by 8. Thus, (y << 3) + x
is equal to 8 * y + x
.
The reason that y << 3
is equivalent to multiplying by 8 is because <<
is the left-shift operator: it shifts all the bits of y
left by one position. In the same way that if you take a base-10 number and shift left by one position you have multiplication by 10, shifting left in base-2 is equivalent to multiplying by 2. Therefore, shifting left by three positions is equivalent to multiplying by 2 * 2 * 2 = 8. In general, shifting left by n
positions is equivalent to multiplying by 2^n
(as long as you don't have bits falling off of the left end).
In the olden days, programmers wrote code like this because left shifts are super duper fast, faster than multiplication and so 8 * y
was less optimal than y << 3
. But these days, compilers are pretty good at figuring out when to replace something like 8 * y
with y << 3
.
Therefore, I say it's obfuscated because 8 * y
more clearly expresses the intent: the intent of (y << 3) + x
is to skip by y
blocks of 8, and take the x
th position in that block. And this is much more clearly expressed by saying 8 * y + x
. Remember, we code in high-level languages for humans to read and understand the code. Our code should be written for the humans. The compiler can do its job of making good machine instructions for the machine to understand.
It's done this way because it's trying to pretend that pieceCodes
is a 2D array, just mapped into a 1D array.
That is, piecesCode
looks like this
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
but we can pretend it looks like this
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
See, given (x, y) -> 8y + x
we accessing the x
th column, y
th row of piecesCode
. That is, y
tells us how many blocks of 8 to skip, and x
tells us where to go within that block.