Expressing a number as letters


When developing Idle games, one often encounters the need to express a number in terms of its abbreviated form. If the game uses small numbers (at least up to 20 characters), then such numbers can in principle be expressed in their existing form. For example, in the unity project, I will create a display of coins and a button that will multiply the number of coins by a certain value:

I will add a script to the button that will take a number from the text field with coins and multiply it by the number:

using System.Numerics;
using UnityEngine;
using UnityEngine.UI; 
public class MLMon : MonoBehaviour
{
    BigInteger money = 1;
    [SerializeField]
    GameObject TextMoney; 
    [SerializeField]
    int Multiplier; 
    public void ButtonClick()
    {
        money *= Multiplier;
        TextMoney.GetComponent<Text>().text = money.ToString();
    } 
}

The class itself has 3 properties – the number of coins, a link to display coins and a multiplier. The coin multiplier and display properties are mapped as a serializable field. And 1 method that will multiply the number of coins we have by the multiplier and write the resulting number to the display.

By pressing the button, our number is multiplied every time and at some point it becomes too large and inconvenient to read:

The first way that you can shorten the record is to express it through exponential notation, for this I will add one more display to the output form and make a small change to the code:

using System.Numerics;
using UnityEngine;
using UnityEngine.UI; 
public class MLMon : MonoBehaviour
{
    BigInteger money = 1;
    [SerializeField]
    GameObject TextMoney, TextMoneyE; 
    [SerializeField]
    int Multiplier; 
    public void ButtonClick()
    {
        money *= Multiplier;
        TextMoney.GetComponent<Text>().text = money.ToString( );
        TextMoneyE.GetComponent<Text>().text = money.ToString("E");
    } 
}

So the output will look like this:

In general, the number of characters has decreased, but let’s consider another method of displaying information.

We will display numbers in the form 1a,1b,1c,…,100xx. For example, if our number = 1000 then we will replace the assignment with “1A”, if the number = 10000 then we will replace it with “10A”, if the number is 1000000 then we will replace it with 1B and so on.

The information output area now has 3 number output fields, it looks like this:

The final code looks like this:

using System;
using System.Numerics;
using UnityEngine;
using UnityEngine.UI; 
public class MLMon : MonoBehaviour
{
    BigInteger money = 1;
    [SerializeField]
    GameObject TextMoney, TextMoneyE, TextMoneyABC; 
    [SerializeField]
    int Multiplier; 
    public void ButtonClick()
    {
        money *= Multiplier;
        TextMoney.GetComponent<Text>().text = money.ToString( );
        TextMoneyE.GetComponent<Text>().text = money.ToString("E");
        TextMoneyABC.GetComponent<Text>().text = TO_abc(money.ToString());
    }
     
    int[] arrayCountDigit = new int[6] { 26, 702, 18278, 475254, 12356630, 321272406 };
    char[] lit = new char[26] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; 
    public string TO_abc(string biStr)
    { 
        int lengthNumb = biStr.ToString().Length;
        if (lengthNumb > 3)
        {
            int countLiderNumber = lengthNumb % 3;
            if (countLiderNumber == 0) countLiderNumber = 3;
            int CountNumberForTransformation = (lengthNumb - countLiderNumber) / 3;
            string NameLiterIsNmber = "";
            byte level = 1;
            for (int i = 0; i < arrayCountDigit.Length; i++)
            {
                if (CountNumberForTransformation > arrayCountDigit[i]) { level++; } else { break; }
            }
            for (int i = level; i > 0; i--)
            {
                int del = i > 1 ? arrayCountDigit[i - 2] : 0;
                int currentindex = (int)(Math.Ceiling((CountNumberForTransformation - del) / Math.Pow(26, i - 1)));
                if (currentindex > 26) currentindex = currentindex % 26;
                currentindex--;
                if (currentindex < 0) { currentindex = 25; }
                NameLiterIsNmber += lit[currentindex];
            }
            string first3number = biStr.ToString().Substring(0, countLiderNumber + 1).Insert(countLiderNumber, ",");
            return first3number + NameLiterIsNmber;
        }
        return biStr.ToString();
    }

Let me explain with the code:

int[] arrayCountDigit = new int[6] { 26, 702, 18278, 475254, 12356630, 321272406 };

An array that tells how many values ​​there are in a given range of numbers.

In the first one we have 26 values ​​a,b,c,…,z

In the second 702 = a,b,c,…,z + combinations of values ​​aa,ab,ac,…,az,ba,bb,…,zz

In the third 18278 = previous range + combinations of values ​​aaa,aab,aac,…,zzz

char[] lit = new char[26] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; 

The letters with which we will replace the numbers are stored as an array

  int lengthNumb = biStr.ToString().Length;
        if (lengthNumb > 3)
        {код} 
      return biStr.ToString();

we consider the length of the number and if it is less than 4 then there is no point in doing anything with it and just return the number itself. If the number is 4 or more in length, then we replace the numbers with letters:

  int countLiderNumber = lengthNumb % 3;
  if (countLiderNumber == 0) countLiderNumber = 3;

We count the number of digits that we will display in front of the letters, it can be from 1 to 3 characters, since the highest digits are replaced by letters (999 is still the number 999, but at 1000 the value becomes 1A). Accordingly, if the number of characters is divisible by 3, then we consider which outputs 3 digits.

1 = 1

1000 = 1A (000=A)

10000 = 10A (000=A)

1000000=1B (000000=B)

 int CountNumberForTransformation = (lengthNumb - countLiderNumber) / 3;

We consider the number of characters that we need to convert to letters, this is the total number of characters, excluding leading digits, divided by 3 (since we are converting thousands).


 byte level = 1;
for (int i = 0; i < arrayCountDigit.Length; i++)
{
      if (CountNumberForTransformation > arrayCountDigit[i]) 
      {
        level++;
      } 
        else 
      {
         break; 
      }
}

We consider the data level that needs to be converted, for this we compare the amount of data being converted with the next value of the bit array.

string NameLiterIsNmber = "";

we create a variable in which we will write the converted numbers, and the level of the number for counting the group of digits. And then we begin to transform.

for (int i = level; i > 0; i--)
            {
                int del = i > 1 ? arrayCountDigit[i - 2] : 0;
                int currentindex = (int)(Math.Ceiling((CountNumberForTransformation - del) / Math.Pow(26, i - 1)));
                if (currentindex > 26) currentindex = currentindex % 26;
                currentindex--;
                if (currentindex < 0) { currentindex = 25; }
                NameLiterIsNmber += lit[currentindex];
            }

We go through each level of the converted data and calculate the letter that we will replace in this bit (we divide the number of characters, except for the previous level, by 26 to the power of the current level). Having received the index of the current letter, we add this letter to the string representation of the number.

string first3number = biStr.ToString().Substring(0, countLiderNumber + 1).Insert(countLiderNumber, ",");
  return first3number + NameLiterIsNmber;

For more detail, we display a tenth of our number

1100 = 1.1A

25500=25.5A

And return the resulting number.

Well, actually the final version:

The report is finished!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *