Tag Recommendation to Game Design: A True Story of Word-Difference-Calculator
Tags: programming, javascript, softwaredevelopment, gamedev
Published: 2023-12-07 19:13:51

---
title: Tag Recommendation to Game Design: A True Story of Word-Difference-Calculator
published: true
description: Explore the development journey of the "word-difference-calculator," initially crafted to refine spending tags in a budgeting app. Discover how a seemingly small tool transforms into a versatile and creative project, touching on data science and culminating in unexpected game development.
tags: #programming #javascript #softwaredevelopment #gamedevelopment
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jlqt9nlthj5qhsfr14y.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-12-07 17:26 +0000
---
## Introduction

A while back I made an app that tracks my spending
and after a while I realized that my tag system was lacking because I had multiple tags that were similar but letter case were different or I had a missing letter. That made my statistical evaluation of my spending go nuts.

![Old app preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6vnqhjsa1qlxhvu2i7u.png)

I was promoted to make a solution and from that the "word-difference-calculator" was born.

![Tag editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fxxxf6i1xasz1t7l9kc7.png)

## Evaluating Missed Letter Cases

When typing on PC first letter is small by default, and I like my tags that way, but on mobile phone first letter is upper case by default and that is annoying.
So I addressed that problem with following code:

```javascript
if (letter1 !== letter2) {
    if (letter1.toLowerCase() === letter2.toLowerCase()) {
            weightedDifference += caseWeight; // case difference
    }
}
```

## Evaluating Missed or Added Letter

Sometime while I type i forget to type one letter so that case must be covered, I did it using word horizontal search for missing letter.

Code goes something like this:
```
get(first, second, index){
 look for letter first[index] in second[min delta index]
 return min delta index
}
```
When that is done we keep the returned index so we don't penalize one missing or added letter for all remaining letters.

## Keyboard misses

While typing on keyboard I frequently miss my keys so that was also accounted by:

```javascript
const rowDirection = firstLetter.row - secondLetter.row;
const rowDiff = Math.abs(rowDirection);
const rowAdjust = rowDirection * 0.5;
const colDiff = Math.abs(pos1.col + rowAdjust - pos2.col);
return rowDiff + colDiff;
```

So now I can fat finger my keyboard I much as I want and there was not a problem in suggesting right tags from the list that is already defined.

## Adding Tests with Realistic Scenarios

How to test something like this, well I tested it partial and in general:
Partial test would be:
```javascript
// Test for distance on eyboard
assert.equal(getKeyboardDistance('a', 'a'), 0)
assert.equal(getKeyboardDistance('a', 'A'), 0)
assert.equal(getKeyboardDistance('a', 's'), 1)
assert.equal(getKeyboardDistance('a', 'd'), 2)
assert.equal(getKeyboardDistance('b', 't'), 3)
assert.equal(getKeyboardDistance('q', 'm'), 9)
```

Whole test would be:
```javascript
for(let [first, second, expect] of tests){
    let val = computeWordDifference(first, second)
    assert.ok(Math.abs(val- expect)<0.03,first+' '+second + ' e: '+ expect+' v: '+val)
}
```

## Integration into an Application for Tag Recognition

When I got to the app integration, it was easy, I just searched all the tags on every key, if any of the tags is similar I would showed it.

There were few unexpected behaviors that required some work so I had to make an idea of the problem, while classical method would not give results I turned to some unorthodox approaches. 

## Large-Scale Testing with 4000 Words

A while back I made an app that combines text typing game with tetris game so I had a pretty good word library and I figured that I can test every word with another and find the similar ones or the ones that brake my code. It gave me some results that looked like Gaussian bell function:

![Gaussian bell function off word differnce](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szo08h0puow7q2k5wsx2.png)

I learned how to make this graph but I learned nothing about my project, so I wanted to see more.

## Graphical Representation

I wanted to see every relation of every word to another in 2d, I had an physics/game engine laying around that is easily extendable since it is ECS system, and I have a chain system implemented for testing chain mold effect:

![Chain mould](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h74z5z013tgnhtqwezqk.png)
[Interactive chain mold sim](https://slobacartoonac.github.io/pythonium/chain_mould_effect/index.html)

On the other hand had perfect interface with new interaction function reedy to be employed:

![Words competing for place](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxghidb9wcs81pjaswj2.png)
[Interactive math plotter](https://slobacartoonac.github.io/pythonium/math-plot/public/index.html)

The force function `(x-1)*(x^-1)` in my system, and it says if something is too close <1 then push it hard, if something is too far then try to attract it slightly.

After just few hours I had something that I can play with, it was interesting to watch, but it was not enough. I added one input and my word from input would join all the words that were competing to be at the right spot in relation to its neighbors.

The end result:

![Grouping of the words](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2g19yyfcr7os7ynmpex2.png)

[Interactive words 2d](https://slobacartoonac.github.io/pythonium/word-cluster/public/index.html)

## Conclusion

Sometimes you just don't know where one project could lead. "word-difference-calculator" was part of one project, then it become a toy and a headache, then it inspired me to do some data science in the end it got its own game.

## Final Thoughts

I feel very lucky that things panned out in this way, many project were touched in this journey, I had what was needed because I choose infrastructure and stick to it trough 10+ projects and 2+ years.

Thank you for reading!