Expression of numbers in the form of letters

Short description

When developing Idle games, developers often need to express large numbers in abbreviated forms. If the numbers are small, they can be expressed in their existing form, but for larger numbers, the exponential or the “1A, 1B, 1C” format can be used. The latter requires a script that converts numbers to letters. The script uses an array to indicate how many values exist in each range of numbers and an array of letters to replace the numbers. The script also considers the length of the number to decide how to convert it and calculates the level of data that needs to be converted. Finally, the script converts the numbers to letters and returns the abbreviated form of the number.

Expression of numbers in the form of letters

When developing Idle games, you are often faced with the fact that you need to express a number through 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, we will create a display of coins and a button that will multiply the number of coins by some value:

I’ll add a script to the button that will take a number from the coins text field and multiply it by a 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 reference to the display of coins and a multiplier. The multiplier and coin display properties are displayed as a serializable field. And one method that will multiply the number of coins we have by a multiplier and record the resulting number on 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 you can shorten the record is to express it through an exponential record, for this I will add another 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");
    } 
}

Thus, the output number will look like this:

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

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

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

Our 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();
    }

I will explain by code:

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

An array that tells how many values ​​exist in a certain 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' }; 

We store the letters with which we will replace the numbers in the form of an array

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

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

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

Consider the number of digits that we will display before the letters, it can be from 1 to 3 characters, since higher digits are replaced by letters (999 is still the number 999, but at 1000, the value becomes 1A). Accordingly, if the number of signs is divisible by 3, we assume that 3 digits are output.

1 = 1

1000 = 1A (000 = A)

10000 = 10A (000 = A)

1000000 = 1V (000000 = V)

 int CountNumberForTransformation = (lengthNumb - countLiderNumber) / 3;

We consider the number of characters that we need to convert into letters, this is the total number of characters except the 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 level of data 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 a group of digits. And then we start converting.

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 digit (we divide the number of signs, excluding the previous level, by the 26th 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 greater detail, we derive the tenth part of our number

1100 = 1.1A

25500 = 25.5A

And we return the received number.

Well, actually the final option:

The report is over!

Related posts