I’m an inexperienced JavaScript user working through the book CoffeeScript: Accelerated JavaScript Development, in which the author makes a kind of Scrabble app (with Scrabble words in a 5 x 5 grid) to demonstrate some of the concepts in practice. I’m having a bit of trouble with the randomLetter method below. Can someone explain the code snippet below, with reference to these points:
i) the author does x = 1 but then seems to assign a letter to x with, x += tileCounts[letter]. Why do that?
ii) If, contrary to what I assume in (i), he is assigning a number rather than a letter to x, how does it work that ‘letter’ actually represents the number associated with each letter?
iii) based on what you see here, can you figure out why he would only return x if it was greater than the randomNumber? I realize there may not be enough information here to answer this question but if there is, please explain
tileCounts =
A: 9, B: 2, C: 2, D: 4, E: 12, F: 2, G: 3, H: 2, I: 9, J: 1, K: 1, L: 4
M: 2, N: 6, O: 8, P: 2, Q: 1, R: 6, S: 4, T: 6, U: 4, V: 2, W: 2, X: 1
Y: 2, Z: 1
totalTiles = 0
totalTiles += count for letter, count of tileCounts
alphabet = (letter for letter of tileCounts).sort()
randomLetter = ->
randomNumber = Math.ceil Math.random() * totalTiles
x = 1
for letter in alphabet
x += tileCounts[letter]
return letter if x > randomNumber
#END:moduleVars
I agree that
randomLetter()is difficult to understand. As the author of the book, let me try to clarify.The only form of randomness available to us in pure JavaScript is
Math.random(), which returns a number between 0 and 1. So the idea ofrandomLetter()is to convert that random number into a random letter, with each letter having a probability of being drawn that’s proportionate to the number of Scrabble tiles with that letter.To make the analogy of what we’re simulating more precise, picture a stack of all the Scrabble tiles sorted from
"A"to"Z". Then all we have to do is:Math.random()(with range0to1) into something with range0tototalTiles(the size of the tile stack) and assign it torandomNumber.randomNumber-th tile and return that letter.In hindsight, I should probably have written this function to more literally follow that analogy by first creating an array of all the tiles and then drawing random values from it. Instead, I opted for an indirect approach: Iterating through the letters of the alphabet, drawing all the tiles with that letter, and asking “Have we drawn
randomNumbertiles yet? If so, we’ve reached our random letter.”So to give a short answer:
xrepresents the number of tiles that have been drawn from the stack, starting by drawing all of the"A"s, then the"B"s, and so on.I hope that helps!