GameMaker Studio 2 Numbers to Roman Numerals Script


Things to know

Roman numerals were used since to conception of Rome all the way into the Late Middle Ages. You might've come across them while reading a book, a clock or a date on a monument. There are 7 symbols in total used in this numerical system (I, V, X, L, C, D, M), contrary to 10 used in the one you're most familiar with ; the Arabic numerals.

In addition to having no symbol for 0, the Roman numerals can only count up to 3999 (MMMCMXCIX). The following table can be used to get a sense of how the numbers are constructed.

ThousandsHundredsTensUnits
1MCXI
2MMCCXXII
3MMMCCCXXXIII
4CDXLIV
5DLV
6DCLXVI
7DCCLXXVII
8DCCCLXXXVIII
9CMXCIX

If you want to read more about it I recommend the Wikipedia page.

Code

The code I wrote transforms any number under 3999 to its equivalent in Roman numerals. It should ignore negative numbers (I haven't checked). All numbers above 3999 return the Roman numeral equivalent of 3999. Although you can pass strings to this script I have only tested with numbers so the output will surely be chaotic.

This script is in no way the fastest or the prettiest way to do this. But it is as least readable.

function rom_num (n) {
    var _n = is_string(n) ? n : string(n)
    
    var has_unit     = 0
    var has_ten      = 0
    var has_hundred  = 0
    var has_thousand = 0
    
    var unit, ten, hundred, thousand
    
    switch (string_length(_n)) {
        case 0:
            return ""
            break
        case 1:
            has_unit = 1
            
            ten      = ""
            hundred  = ""
            thousand = ""
            break
        case 2:
            has_unit = 1
            has_ten  = 1
            
            hundred  = ""
            thousand = ""
            break
        case 3:
            has_unit    = 1
            has_ten     = 1
            has_hundred = 1
            
            thousand = ""
            break
        case 4:
            has_unit     = 1
            has_ten      = 1
            has_hundred  = 1
            has_thousand = 1
            break
        default:
            return "MMMCMXCIX"
    }
    
    if (has_thousand) {
        var _t = real(string_char_at(_n, 1))
        switch(_t) {
            case 0:
                thousand = ""
                break
            case 1:
                thousand = "M"
                break
            case 2:
                thousand = "MM"
                break
            case 3:
                thousand = "MMM"
                break
            default:
                return "MMMCMXCIX"
        }
    }
    
    if (has_hundred) {
        var _h = real(string_char_at(_n, 1 + has_thousand))
        switch(_h) {
            case 0:
                hundred = ""
                break
            case 1:
                hundred = "C"
                break
            case 2:
                hundred = "CC"
                break
            case 3:
                hundred = "CCC"
                break
            case 4:
                hundred = "CD"
                break
            case 5:
                hundred = "D"
                break
            case 6:
                hundred = "DC"
                break
            case 7:
                hundred = "DCC"
                break
            case 8:
                hundred = "DCCC"
                break
            case 9:
                hundred = "CM"
                break
            default:
                hundred = ""
        }
    }
    
    if (has_ten) {
        var _t = real(string_char_at(_n, 1 + has_thousand + has_hundred))
        switch(_t) {
            case 0:
                ten = ""
                break
            case 1:
                ten = "X"
                break
            case 2:
                ten = "XX"
                break
            case 3:
                ten = "XXX"
                break
            case 4:
                ten = "XL"
                break
            case 5:
                ten = "L"
                break
            case 6:
                ten = "LX"
                break
            case 7:
                ten = "LXX"
                break
            case 8:
                ten = "LXXX"
                break
            case 9:
                ten = "XC"
                break
            default:
                ten = ""
        }
    }
    
    if (has_unit) {
        var _t = real(string_char_at(_n, 1 + has_thousand + has_hundred + has_ten))
        switch(_t) {
            case 0:
                unit = ""
                break
            case 1:
                unit = "I"
                break
            case 2:
                unit = "II"
                break
            case 3:
                unit = "III"
                break
            case 4:
                unit = "IV"
                break
            case 5:
                unit = "V"
                break
            case 6:
                unit = "VI"
                break
            case 7:
                unit = "VII"
                break
            case 8:
                unit = "VIII"
                break
            case 9:
                unit = "IX"
                break
            default:
                unit = ""
        }
    }
    
    return thousand + hundred + ten + unit
}

Examples:

InputOutput
0[empty string]
1I
12XII
286CCLXXXVI
2025MXXV

Why does this exist ?

When I was adding language support to PONGCADE I wanted to add as many languages as I could at once so I decided to add Latin and the 3 languages I am fluent in. I am only beginning to learn Latin so I thought it would be a fun little learning experience, and it was.

If you know how I can improve this script, let me know !

Get PONGCADE

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.