Ten-pin bowling score - World Bowling edition

JavaScript, 43 bytes

f=([c,...s])=>c?({'/':10,X:30}[c]|c)+f(s):0

f=([c,...s])=>c?({'/':10,X:30}[c]|c)+f(s):0
Score(<input style="width:200px" oninput="o.value=f(this.value)" />) = <output id=o></output>

How it works

We convert each character to its point:

  • 'X' worth 30 point
  • '/' worth 10 point
  • '1' .. '9' worth 1 .. 9 point
  • other characters worth 0 point

Then sum all points.

Convert

Bitwise OR operator | convert its operand to Int32 before operate. When converting to Int32, value first convert to Number (64bit float number) format, then trunk to Int32 (or converted to 0 if invalid).

  • ToInt32({'/':10,X:30}[c]) could be read as:
    • if c == '/': result is 10;
    • if c == 'X': result is 30;
    • otherwise: result is ToInt32(undefined) -> ToInt32(NaN) -> 0;
  • ToInt32(c) could be:
    • if c == '1' ... '9': result is 1 .. 9;
    • if c == ' ': Number(c) is 0, result is 0;
    • otherwise: Number(c) is NaN, result is 0;
  • Bitwise or here is same as "add", since one of its operand will be 0

Sum

  • [c,...s] = s let c = s[0], and s = s.slice(1);
    • if s is empty string, c is undefined;
    • otherwise, c is first letter of s
  • undefined is falsy, non-empty string (including space) is truthy

05AB1E, 12 11 bytes

Code

S'/T:'X30:O

Try it online!

Explanation

S             # Split the string into a list of characters
 '/T:         # Replace '/' with 10
     'X30:    # Replace 'X' with 30
          O   # Sum up the array (ignoring non-number elements)

Stax, 13 bytes

─*âⁿ┴8òt↨HÉ÷8

Run and debug it

Unpacked, ungolfed, and commented it's thus.

F               for each character in input, execute...
 9R$'/20*+'X+   build the string "123456789////////////////////X"
 I              get the index of the current character in string
 ^+             increment and add to running total
                (index is -1 when no match; space and dash are 0 score)

Run this one