0
\$\begingroup\$

I have a problem with my code. I made so much code, and now I need to place ends, which I cannot figure out how to do because I need to line everything up and then place at least 5 or 6 ends in the right places. I am fairly new to Lua and I'm sure that there's a better way to go about this, so if there is, tell me in your answer. Also, this code is unfinished.

math.randomseed(os.clock())
math.random();math.random();math.random()
local function navigate()
  print("Where would you like to go?")
  print("Somewhere peaceful(type peaceful), somewhere dangerous(type dangerous), or somewhere civilized?")
  local destination = io.read() 
  if destination == "peaceful" then
    local event = math.random(5)
    if event == 1 then
      print("You find a leafy forest.")
      print("What would you like to do? Search, Cut tree, Inventory")
      local action = io.read()
      if action == "search" then
        local searchevent = math.random(3)
          if searchevent == 1 then
          require("battle")
          elseif searchevent == 2 then
            lootdrop = math.random(5)
            if lootdrop == 1 then
              print("You found an abandoned sword. You pick it up.")
              if g_inventory1 == nil then
                g_inventory1 = "a sword"
              elseif g_inventory2 == nil then
                g_inventory2 = "a sword"
              elseif g_inventory3 == nil then
                g_inventory3 = "a sword"
              else
                print("You don't have room for this sword.Type 'leave it' or replace items. Items to replace:")
                print(g_inventory1)
                print(g_inventory2)
                print(g_inventory3)
                replace = io.read()
                if replace == g_inventory1 then
                  io.write("You replaced the "); io.write(replace); io.write(" with a sword.")
                  g_inventory1 = "a sword"
                elseif replace == g_inventory2 then
                  io.write("You replaced the "); io.write(replace); io.write(" with a sword.")
                  inventory2 = "a sword"
                elseif replace == g_inventory3 then
                  io.write("You replaced the "); io.write(replace); io.write(" with a sword.")
                  inventory3 = "a sword"
                elseif replace == "leave it" then
                  print("You leave the sword.")
                else
                  print("You randomly thought of a pointless word and moved on ahead.")
                end
            if lootdrop == 2 then
              print("A hatchet sticks out of a tree stump, and you take it out.")
              if inventory1 == nil then
                inventory1 = "a hatchet"
              elseif inventory2 == nil then
                inventory2 = "a hatchet"
              elseif inventory3 == nil then
                inventory3 = "a hatchet"
              else
                print("You don't have room for this hatchet. Replace items or 'leave it'? Items to replace:")
                  print(g_inventory1)
                  print(g_inventory2)
                  print(g_inventory3)
                  replace = io.read()
                  if replace == g_inventory1 then
                    io.write("You replaced the "); io.write(replace); io.write(" with the hatchet.")
                    g_inventory1 = "a hatchet"
                  elseif replace == g_inventory2 then
                    io.write("You replaced the "); io.write(replace); io.write(" with the hatchet.")
                    inventory2 = "a hatchet"
                  elseif replace == g_inventory3 then
                    io.write("You replaced the "); io.write(replace); io.write(" with the hatchet.")
                    inventory3 = "a hatchet"
                  elseif replace == "leave it" then
                    print("You leave the hatchet.")
                  else
                    print("You randomly thought of a pointless word and moved on ahead.")
                  end
               end
             if lootdrop == 3 then
              if g_inventory1 == nil then
                print("You have found a carving knife. You pick it up.")
                g_inventory1 = "a carving knife"
              elseif g_inventory2 == nil then
                print("You have found a carving knife. You pick it up.")
                g_inventory2 = "a carving knife"  
              elseif g_inventory3 == nil then
                print("You have found a carving knife. You pick it up.")
                g_inventory3 = "a carving knife"
              else
                print("You have no room for this carving knife. 'leave it' or replace an item? Items to replace:")
                print(g_inventory1)
                print(g_inventory2)
                print(g_inventory3)
                replace = io.read()
                if replace == g_inventory1 then
                  io.write("You replaced the "); io.write(inventory1); io.write(" with a carving knife.")
                  g_inventory1 = "a carving knife"
                elseif replace == g_inventory2 then
                  io.write("You replaced the "); io.write(inventory1); io.write(" with a carving knife.")
                  g_inventory2 = "a carving knife"
                elseif replace == g_inventory3 then
                  io.write("You replaced the "); io.write(inventory1); io.write(" with a carving knife.")
                  g_inventory3 = "a carving knife"
                elseif replace == "leave it" then
                  print("You leave the sword.")
                else
                  print("You think of a pointless word and move on ahead.")
                end
            if lootdrop == 4 then
              if g_inventory1 == nil then
              print("You have found a magical amulet. You pick it up.")
              g_inventory1 = "a magical amulet"
            elseif g_inventory2 == nil then
              print("You have found a magical amulet. You pick it up.")
              g_inventory2 = "a magical amulet"  
            elseif g_inventory3 == nil then
              print("You have found a carving knife. You pick it up.")
              g_inventory3 = "a magical amulet"
            else
              print("You have no room for this magical amulet. 'leave it' or replace an item? Items to replace:")
              print(g_inventory1)
              print(g_inventory2)
              print(g_inventory3)
              replace = io.read()
              if replace == g_inventory1 then
                io.write("You replaced the "); io.write(inventory1); io.write(" with a magical amulet.")
                g_inventory1 = "a magical amulet"
              elseif replace == g_inventory2 then
                io.write("You replaced the "); io.write(inventory1); io.write(" with a magical amulet.")
                g_inventory2 = "a magical amulet"
              elseif replace == g_inventory3 then
                io.write("You replaced the "); io.write(inventory1); io.write(" with a magical amulet.")
                g_inventory3 = "a magical amulet"
              elseif replace == "leave it" then
                print("You leave the amulet.")
              else
                print("You think of a pointless word and move on ahead.")   
            if lootdrop == 5 then
              print("You failed to find anything useful.")
              end
          elseif searchevent == 3 then
            print("You find nothing.")
\$\endgroup\$
2
  • \$\begingroup\$ Most important tip: code turned on its side is not a graph of how awesome it is. Pull stuff out into methods. That will start you down a better road. \$\endgroup\$ Commented Jun 29, 2016 at 16:21
  • \$\begingroup\$ If you interested in text adventures you should google "interactive fiction". There is a very active community. Usually special programming languages are used, but If you want to focus on Lua, there seem to some resources for that, for example this tutorial: playwithlua.com/?p=20 \$\endgroup\$
    – RoToRa
    Commented Jun 30, 2016 at 7:42

1 Answer 1

2
\$\begingroup\$

I would separate the data from the navigation; have variables for a state. That way, as you expand your game, if you decide to change something about the interface, it's in one spot instead instead of mixed in with the data.

#!/usr/local/bin/lua

map = {
    ["peace"] = {
        title = "Peaceful",
        description = [[You find a leafy forest.]],
        exits = { danger = true },
        objects = { "tree" }
    },
    ["danger"] = {
        title = "Dangerous",
        description = [[You are on an erupting volcano with hot lava.]],
        exits = { peace = true, civil = true },
        objects = { "sword" }
    },
    ["civil"] = {
        title = "Civilized",
        description = [[You find yourself having tea in the countryside.]],
        exits = { danger = true },
        objects = {  }
    }
}

objects = {
    ["tree"] = {
        name = "tree",
        description = "A tree is here.",
        take = false
    },
    ["sword"] = {
        name = "sharp sword",
        description = "A sword is here.",
        take = "You found an abandoned sword. You pick it up."
    }
}

-- these are commands that the user enters
-- they take a list of words that are generated by split()
action = {
    ["exit"] = function(words)
        where = nil
    end,
    ["go"]   = function(words)
        local to = words[2]
        if(to == nil) then
            print("Go where?")
            return
        end
        if(map[where].exits[to] == true) then
            where = to
        else
            print("No exit to " .. to .. ".")
        end
    end,
    ["take"] = function(words)
        print("fixme: take has not been implemented")
    end,
    ["look"] = function(words)
        -- it refreshes the screen automatically anyway
    end
}

-- split by white space
function split(str)
    local words = {}
    local w = 1
    for s in str:gmatch("([%S]+)") do
        words[w] = s
        w = w + 1
    end
    return words
end

-- this is called in a loop; io.read is blocking for input
function navigate()
    -- describe state
    print(map[where].title .. "\n" .. map[where].description);
    for k,v in pairs(map[where].objects) do print(objects[v].description) end
    print("Exits:")
    for k,v in pairs(map[where].exits) do print(k) end

    -- input
    print("Where would you like to do?")
    local input = io.read("*line")
    local words = split(input)

    -- parse to command
    local act = action[words[1]]
    if act then
        act(words)
    else
        print("That is not a command; commands:")
        for k, v in pairs(action) do print(k) end
    end

end

-- starting state
where = "civil"
inventory = { }

-- main loop
while where do
    navigate();
    print("")
end

print("Goodbye.")

The state I used is contained in where and it's an index to the table map; when it goes nil, it exits the programme. Also inventory is a state list, but it is not used, yet. I used the tutorials at:

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.