function love.load()
    love.graphics.setBackgroundColor(1, 1, .75)

    level = {
        {'#', '#', '#', '#', '#'},
        {'#', '@', ' ', '.', '#'},
        {'#', ' ', '$', ' ', '#'},
        {'#', '.', '$', ' ', '#'},
        {'#', ' ', '$', '.', '#'},
        {'#', '.', '$', '.', '#'},
        {'#', '.', '*', ' ', '#'},
        {'#', ' ', '*', '.', '#'},
        {'#', ' ', '*', ' ', '#'},
        {'#', '.', '*', '.', '#'},
        {'#', '#', '#', '#', '#'},
    }

    player = '@'
    playerOnStorage = '+'
    box = '$'
    boxOnStorage = '*'
    storage = '.'
    wall = '#'
    empty = ' '
end

function love.keypressed(key)
    if key == 'up' or key == 'down' or key == 'left' or key == 'right' then
        local playerX
        local playerY

        for testY, row in ipairs(level) do
            for testX, cell in ipairs(row) do
                if cell == player or cell == playerOnStorage then
                    playerX = testX
                    playerY = testY
                end
            end
        end

        local dx = 0
        local dy = 0
        if key == 'left' then
            dx = -1
        elseif key == 'right' then
            dx = 1
        elseif key == 'up' then
            dy = -1
        elseif key == 'down' then
            dy = 1
        end

        local current = level[playerY][playerX]
        local adjacent = level[playerY + dy][playerX + dx]
        local beyond
        if level[playerY + dy + dy] then
            beyond = level[playerY + dy + dy][playerX + dx + dx]
        end
        local nextAdjacent = {
            [empty] = player,
            [storage] = playerOnStorage,
        }
        local nextCurrent = {
            [player] = empty,
            [playerOnStorage] = storage,
        }

        if nextAdjacent[adjacent] then
            level[playerY][playerX] = nextCurrent[current]
            level[playerY + dy][playerX + dx] = nextAdjacent[adjacent]

        elseif adjacent == box then
            if beyond == empty then
                level[playerY][playerX] = nextCurrent[current]
                level[playerY + dy][playerX + dx] = player
                level[playerY + dy + dy][playerX + dx + dx] = box
            elseif beyond == storage then
                level[playerY][playerX] = nextCurrent[current]
                level[playerY + dy][playerX + dx] = player
                level[playerY + dy + dy][playerX + dx + dx] = boxOnStorage
            end
        end
    end
end

function love.draw()
    for y, row in ipairs(level) do
        for x, cell in ipairs(row) do
            if cell ~= empty then
                local cellSize = 23

                local colors = {
                    [player] = {.64, .53, 1},
                    [playerOnStorage] = {.62, .47, 1},
                    [box] = {1, .79, .49},
                    [boxOnStorage] = {.59, 1, .5},
                    [storage] = {.61, .9, 1},
                    [wall] = {1, .58, .82},
                }

                love.graphics.setColor(colors[cell])
                love.graphics.rectangle(
                    'fill',
                    (x - 1) * cellSize,
                    (y - 1) * cellSize,
                    cellSize,
                    cellSize
                )
                love.graphics.setColor(1, 1, 1)
                love.graphics.print(
                    level[y][x],
                    (x - 1) * cellSize,
                    (y - 1) * cellSize
                )
            end
        end
    end
end