Scaling cellmap

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
TheOddByte
Prole
Posts: 35
Joined: Sun Dec 15, 2013 7:15 pm

Scaling cellmap

Post by TheOddByte »

I'm currently working on class that generates a cave world using a cellmap

The cellmap could example look like this if it was 3x3

Code: Select all

--[[
111
101  --# The visual representation of the cellmap
111
--]]

--# The cellmap uses x and y indexes ( cellmap[x][y] = some_id )
local cellmap = {
    [1][1] = "1";
    [1][2] = "1";
    [1][3] = "1";
    [2][1] = "1";
    [2][2] = "0";
    [2][3] = "1";
    [3][1] = "1";
    [3][2] = "1";
    [3][3] = "1";
 }
 
But I want to convert that like this

Code: Select all

cellmap = scale( cellmap, 2 )
--[[
111111
111111
110011 --# Since it was scaled by 2 it doubled in size
110011
111111
111111
--]]

Here's the function I use for scaling, when using the scaling function it messes up, otherwise it works as expected.

Code: Select all

function World:scale_cellmap( cellmap, scale )
    local new_cellmap = {}
    for x = 1, #cellmap do
        for y = 1, #cellmap[x] do
            for w = 1, scale do
                local index = #new_cellmap + 1
                new_cellmap[ index ] = {}
                for h = 1, scale do
                    new_cellmap[ index ][ #new_cellmap[index] + 1 ] = cellmap[x][y]
                end
            end
        end
    end
    return new_cellmap
end
Can someone spot my mistake?
What's the object-oriented way to get wealthy? Inheritance.
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Scaling cellmap

Post by zorg »

The mistake would be that your algorithm is wrong, since the function fails on doing the exact thing you want it to do.

Let me illustrate what you want to accomplish a bit differently:

Code: Select all

ABC
DEF
GHI

--into

AABBCC
AABBCC
DDEEFF
DDEEFF
GGHHII
GGHHII

-- for a scale of two, for example.
If you think about it in order, it duplicates each cell in the original table "scale" amount of times, then it duplicates that whole (newly generated) row (or cell, depending on the order of them) "scale" amount of times again.

Code: Select all

ABC -> x2 -> AABBCC(next row/column)AABBCC
Using this info, writing a correct algorithm will be easier; try it, then if you still have problems, i'm sure someone will give you more hints.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Scaling cellmap

Post by ivan »

Note that whenever you find yourself shifting/copying a lot of data around, stop and seriously consider what you are doing.
Generally speaking, you shouldn't have to scale/copy data in this manner because it's utterly pointless.
What's the point of shifting around memory, just make your original map 'scaled' to begin with and you'll be fine.
Ok, so now that we have established that what you are trying to do is not good, let's fix the code:

Code: Select all

function World:scale_cellmap( cellmap, scale )
    local w, h =  #cellmap, #cellmap[1]
    local new_cellmap = {}
    for x = 1, w*scale  do
        new_cellmap[x] = {} -- bug fix
        for y = 1, h*scale  do
            local x2, y2 = math.ceil(x/scale), math.ceil(y/scale)
            -- todo: as a further optimization move x2 outside of the inner loop
            new_cellmap[x][y] = cellmap[x2][y2]
        end
    end
    return new_cellmap
end
Similar operations may be MUCH easier to perform on images or strings, just remember that this is a terrible use of tables.
Last edited by ivan on Mon Jul 31, 2017 5:09 pm, edited 1 time in total.
User avatar
TheOddByte
Prole
Posts: 35
Joined: Sun Dec 15, 2013 7:15 pm

Re: Scaling cellmap

Post by TheOddByte »

ivan wrote: Sun Jul 30, 2017 5:11 pm Note that whenever you find yourself shifting/copying a lot of data around, stop and seriously consider what you are doing.
Generally speaking, you shouldn't have to scale/copy data in this manner because it's utterly pointless.
What's the point of shifting around memory, just make your original map 'scaled' to begin with and you'll be fine.
Ok, so now that we have established that what you are trying to do is not good, let's fix the code:

Code: Select all

function World:scale_cellmap( cellmap, scale )
    local w, h =  #cellmap, #cellmap[1]
    local new_cellmap = {}
    for x = 1, w*scale  do
        for y = 1, h*scale  do
            local x2, y2 = math.ceil(x/scale), math.ceil(y/scale)
            -- todo: as a further optimization move x2 outside of the inner loop
            new_cellmap[x][y] = cellmap[x2][y2]
        end
    end
    return new_cellmap
end
Similar operations may be MUCH easier to perform on images or strings, just remember that this is a terrible use of tables.
Thanks for all the responses, I know I haven't created the ideal solution to what I'm trying to accomplish, mostly it's just an idea I'm working on that I plan to improve later on. I'm currently using cellular automata(https://gamedevelopment.tutsplus.com/tu ... medev-9664) to generate caves and I'm not completely sure how to "scale" it up during the generation, thus I'm scaling the small map into a larger one, because I plan to create a Liero like clone.

I plan on changing the structure of the cellmap into strings as soon as possible, by the way the code above threw an error when trying to index the new_cellmap table, probably because you forgot to create new_cellmap[x] before assigning a value to new_cellmap[x][y]

Anyway, thanks for all the help, I'll probably ask for more help as I progress.
What's the object-oriented way to get wealthy? Inheritance.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest