Makertober Day 4: Letter Tiles

In a change of plan, rather than making a box for my temperature sensor, today I’ve spent a bit of time picking random letters. Years ago I I had an idea for a tiny Windows Phone game in which the player flicked letter tiles at targets to build words. I’ve decided to finish this off using my new JavaScript Matter.js skills. The first step is to pick some letters to use in the game. I reckon I’ll need 100 or so tiles to make the game work.

Now I could just pick the letters on the tiles by getting a random number in the range 1-26 and then just match that to a letter. That would work, but it wouldn’t be fair on the player as they would get as many letter Es as Zs, and that is not how the English language works. We use a lot more Es than Zs. So I went online, found a letter frequency table and popped it into JavaScript:

this.letterList = [
    { letterChar: 'A', freq: 8.34 },
    { letterChar: 'B', freq: 1.54 },
    { letterChar: 'C', freq: 2.73 },
    { letterChar: 'D', freq: 4.14 },
    { letterChar: 'E', freq: 12.60 },
    { letterChar: 'F', freq: 2.03 },
    { letterChar: 'G', freq: 1.92 },
    { letterChar: 'H', freq: 6.11 },
    { letterChar: 'I', freq: 6.71 },
    { letterChar: 'J', freq: 0.23 },
    { letterChar: 'K', freq: 0.87 },
    { letterChar: 'L', freq: 4.24 },
    { letterChar: 'M', freq: 2.53 },
    { letterChar: 'N', freq: 6.80 },
    { letterChar: 'O', freq: 7.70 },
    { letterChar: 'P', freq: 1.66 },
    { letterChar: 'Q', freq: 0.09 },
    { letterChar: 'R', freq: 5.68 },
    { letterChar: 'S', freq: 6.11 },
    { letterChar: 'T', freq: 9.37 },
    { letterChar: 'U', freq: 2.85 },
    { letterChar: 'V', freq: 1.06 },
    { letterChar: 'W', freq: 2.34 },
    { letterChar: 'X', freq: 0.20 },
    { letterChar: 'Y', freq: 2.04 },
    { letterChar: 'Z', freq: 0.06 }];

This array contains an object that has a letterChar property (the char of the letter, and a freq property which gives the number of times that letter will appear in 100 letters. In other words, in 100 letters we should find around 12 Es, 1 V and not many Zs. I now want some JavaScript that will pick 120 tiles based on this distribution. To make the game seem more real, I also want to make sure that there is at least 1 of each character - even the one that mathematically should not be there. It turned out that the code to do this in one pass through the array of letters was a bit hard to do. In fact I didn’t manage to do it without a bit of cheating. What I came up with steals 1 tile from each calculated letter and then fills in the last few random tiles with randomly chosen tiles that have a uniform distribution over all 26. I’m kind of proud of this, until someone suggests a better way to do it…..

var createdTileCount = 0;

for (let letter of this.letterList) {
    let noOfThisLetter = Math.floor(tileCount * (letter.freq / 100))-1;
    if (noOfThisLetter < 1) {
        letter.number = 1;
    }
    else {
        letter.number = noOfThisLetter;
    }
    createdTileCount += letter.number;
}

// add in some spare random ones

while(createdTileCount<tileCount){
    let lett= this.getRandomInt(0,25);
    this.letterList[lett].number++;
    createdTileCount++;
}

Once I’d got my letters picked the next thing to do is display them. I’ve used my list of tile numbers to build all the tiles, given them some physics and then dropped them on the ground. Below you can see the result.

falling letters.png

I guess this is more of a “work in progress” than a finished item. But it is still something I’ve. I’ll put the code on GitHub when it is finished.