Author Topic: [Python] Conditionals and reading list elements  (Read 10605 times)

Avagart

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 567
  • Karma: +0/-0
    • View Profile
[Python] Conditionals and reading list elements
« on: October 24, 2014, 03:25:22 PM »
Hi guys. I have a... small... problem with conditionals. My roguelike based on Jotaf's tutorial, but during one and a half years working on it I learnt a lot about Python (but I'm still a novice, my profession is the totally unrelated to programming). Roguelike has wilderness, cities (above-ground and underground), classes, races, d20srd system, etc. Now I'm working on quests... And here there is problem.

I have three lists (are made in the same manner): active_quest, past_quest, quest_item_inventory. Start with empty lists; when you talk to specific NPC game add 'firstquest' to active_quest list. When 'firstquest' is in active_quest, new location in worldmap appear. PC descends on the third level of location, take 'firstquestitem'. 'firstquestitem' is added to the list quest_items_inventory. All the aforesaid works, I tested it.

Problem occurs with interaction with the NPC at the completion of the quest. Action should be such as:
Code: [Select]
talk
if you are talking with first_npc_from_first_city:
    if 'firstquest' is inactive and isn't in past_quest
        add 'firstquest' to active_quest
        npc say 'give me firstquestitem'
    if 'firstquest' is active and player have not 'firstquestitem'
        npc say 'found firstquestitem'
    if 'firstquest' is active and player have 'firstquestitem'
        remove 'firstquestitem' from quest_item_inventory
        remove 'firstquest' from active_quest
        add 'firstquest' to past_quest
        npc say 'thx'
    if 'firstquest' is inactive and is in past_quest
        npc say 'you are true hero!'

code looks like this (with some changes, I have tried several, hm, solutions (?))
Code: [Select]
    if '1st npc 1st city' in object.name: #NPC named '1st...'
        if 'firstquest' not in active_quest and 'firstquest' not in past_quest:
            message('add 1st_q_from_1st_c to active_quest!')
            active_quest.append('firstquest')
            return
        elif 'firstquest' in active_quest:
            if 'firstquestitem' in quest_items_inventory: #PC have questitem
                message('thx')
                quest_items_inventory.remove('firstquestitem')
                active_quest.remove('firstquest')
                past_quest.append('firstquest') #end of quest
                return
            else:
                message('where is firstquestitem?') #PC have not firstquestitem
        elif 'firstquest' in past_quest:
            message('you are true hero') #talk after complete quest
            return
        else:
            message('error?') #test

I made some tests. I'm sure that 'firstquestitem' is in quest_items_inventory. It seems that python cannot read the content of quest_item_inventory. It surprise me, because there are no such problems with active_quest which is constructed in a same manner.
Can someone tell me what could cause this?

LindaJeanne

  • Newcomer
  • Posts: 22
  • Karma: +0/-0
    • View Profile
Re: [Python] Conditionals and reading list elements
« Reply #1 on: October 24, 2014, 04:46:57 PM »
Hi!

Just some clarification first of all.  Are you saying that even when the first quest item is in the quest items inventory, you are still getting the "where is questitem" message as though it were not?

Also, I'm a bit confused by the first line of your example code. Are you really checking for a string in the object name to verify who you're talking to?

it might be helpful to see the relevent class code that's being used here, to better understand what's going on.

« Last Edit: October 24, 2014, 04:54:20 PM by LindaJeanne »

Aukustus

  • Rogueliker
  • ***
  • Posts: 440
  • Karma: +0/-0
    • View Profile
    • The Temple of Torment
Re: [Python] Conditionals and reading list elements
« Reply #2 on: October 24, 2014, 08:50:29 PM »
It seems to me that 'firstquest' is string and 'firstquestitem' is object as in a real pickup-able item so you'd need to access the 'firstquestitem' without the single quotes.

You could do "if player in objects:" but not "if 'player' in objects:". Player is the player object as in the Jotaf's tutorial.

mushroom patch

  • Rogueliker
  • ***
  • Posts: 554
  • Karma: +0/-0
    • View Profile
Re: [Python] Conditionals and reading list elements
« Reply #3 on: October 24, 2014, 09:24:25 PM »
I am sceptical about the value of entertaining this kind of debugging request. This code does not seem to conform to the most basic coding "best practices." It's telling that responses show confusion over whether the text snippets contained in your string literals are supposed to be variable names.

In the interest of being positive about trying to write games, I guess I find it admirable to stick with something like this for a year and a half. On the other hand, this strikes me as setting an example it would not be good for beginning programmers to follow, either as a matter of programming or forum posting.

Avagart

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 567
  • Karma: +0/-0
    • View Profile
Re: [Python] Conditionals and reading list elements
« Reply #4 on: October 24, 2014, 11:26:25 PM »
@LindaJeanne - yes. No matter whether I have firstquestitem in quest_items_inventory I'm getting the 'where is questitem' message. Of course firstquestitem still is in quest_items_inventory.

I really use string name to verify to whom (? I'm sorry, English isn't my native language) I speak. It's very ugly but it works. For now it's enough for me - anything related to programming is just hobby. A poor excuse, I know ;)

@Aukustus - I didn't think about it (shame on me). I'l do it tomorrow after work, thanks for idea :)

@mushroom patch - generally agree with your point of view :) it isn't good for beginning programmers to follow. But I'm afraid that I do not understand the last part of your answer - "either (...) or forum posting.". Do you think that I did wrong that posted here to ask?... Maybe. But in spite of everything I write for myself, don't I push my roguelike on roguetemple and do not write anywhere 'check it, please, review it'. I wrote here because I have a problem with a fragment of code (true, poor), and not to advertise my work :)

For now - thank you all for replies :)

LindaJeanne

  • Newcomer
  • Posts: 22
  • Karma: +0/-0
    • View Profile
Re: [Python] Conditionals and reading list elements
« Reply #5 on: October 25, 2014, 12:43:03 AM »
The real question is do you want to learn better ways of doing things?  8)

Coding best practises aren't what they are "Just Because." They exist to make it easier to write, maintain, and (ahem) debug code.

Anyway, there's no way of figuring out where your bug is with just the code shown.  Where is the code that you use to put firstquestitem in quest_items_inventory, for instance? And what did you do to determine that it's populated? You said you verified this, but didn't say how.

But, really, difficult-to-find bugs are what best-practises and non-ugly code exit to avoid. If you don't learn the right way of doing something because it's "just a hobby" and "it's ugly but it works" (except when it doesn't, and the bug is hard to find), you're just making things more difficult for yourself, not easier.

Any good advice you get about your code will probably involve substantial revision, rather than just a quick "change this small thing to fix your bug". If that's what you're looking for, lets see the rest of the relevant code :). If you just want a quick answer to "make it work", I doubt I'll be able to help you -- I can't speak for anyone else.

Aukustus

  • Rogueliker
  • ***
  • Posts: 440
  • Karma: +0/-0
    • View Profile
    • The Temple of Torment
Re: [Python] Conditionals and reading list elements
« Reply #6 on: October 25, 2014, 09:31:02 AM »

@Aukustus - I didn't think about it (shame on me). I'l do it tomorrow after work, thanks for idea :)


I'll elaborate even a little more with examples from my game that fit the Jotaf's tutorial.

You can do the following things:

Code: [Select]
item_component = Item(count = 1, use_function=None)
item = Object(x, y, amulet_tile, '*', 'Quest Item: Eilinmyr\'s Amulet', libtcod.white, description = 'Eilinmyr\'s amulet is Magically enchanted and acts as a holy symbol. It has no use for any other person than Eilinmyr.', item=item_component)

for item in inventory:
    if item.name ==  'Quest Item: Eilinmyr\'s Amulet':
        inventory.remove(item)

Code: [Select]
item_component = Item(count = 1, use_function=None)
eilinmyrAmulet = Object(x, y, amulet_tile, '*', 'Quest Item: Eilinmyr\'s Amulet', libtcod.white, description = 'Eilinmyr\'s amulet is Magically enchanted and acts as a holy symbol. It has no use for any other person than Eilinmyr.', item=item_component)

for item in inventory:
    if item.name ==  'Quest Item: Eilinmyr\'s Amulet':
        inventory.remove(item)

Code: [Select]
item_component = Item(count = 1, use_function=None)
eilinmyrAmulet = Object(x, y, amulet_tile, '*', 'Quest Item: Eilinmyr\'s Amulet', libtcod.white, description = 'Eilinmyr\'s amulet is Magically enchanted and acts as a holy symbol. It has no use for any other person than Eilinmyr.', item=item_component)

if eilinmyrAmulet in inventory:
    inventory.remove(eilinmyrAmulet)

In last case the object eilinmyrAmulet should be declared global when spawned in game and probably saved in save file when saving game. I use the first example in my game because it works and I couldn't bother making it better. My inventories are quite short with maximum of 25 objects so I do not notice any speed problems when handling lists of objects like that.

Edit: I use another list for quest flags, and picking up of quest items is forced so I use like "if 'EilinmyrDied' in questFlags:" and then one of the loops that go through the items and removes one with the correct name.
« Last Edit: October 25, 2014, 09:45:58 AM by Aukustus »