Old school text adventure as a way of re-learning coding

User projects written in or related to FreeBASIC.
paul doe
Posts: 1269
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Old school text adventure as a way of re-learning coding

Postby paul doe » Jul 05, 2020 5:36

Now, every time you run the program, you'll see that it will construct a sentence, using the tags available. One run could yield, for example:

Code: Select all

I want to do something awfully cool, and also look at something incredibly nice!

And the above sentence was constructed from a very simple grammar:

Code: Select all

I want to {action}, and also {stat}!

I used curly brackets to specify 'tags', and the tags are expanded 'recursively' from there. You can of course extend the scheme to fit your needs, but this is basically what I meant with a 'grammar representation': you specify the building blocks of your descriptive sentences, and then associate tags with values to replace. A more complex scheme could involve callbacks (to be able to associate tags with functions, to handle more complex sentences regarding objects), and could even construct the tags themselves. This is way easier than try to parse full English grammar, and allows for a lot of interesting variations and complexity from a relatively reduced set of elements.

Of course, this example is too coarse to be of any real use, but this can be decomposed into very small syntactical units, and given all the context they need to create the relevant tags. Also, the grammar doesn't include repetition operators, but these can be easily implemented.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Old school text adventure as a way of re-learning coding

Postby olympic sleeper » Jul 05, 2020 22:59

Hi Paul,

Many thanks for the reply and code. There are still a great many things I do not know about Free Basic and so the code is a somewhat beyond me right now, however can I check a few things?

  • It looks like you are declaring subs (eg Constructor) within the type KeyValue - which I did not know was possible. Does this result in a pointer to that function existing in the type, or something else? Could these be an an indexed array? If I have a hash table of x elements could those elements point to functions?
  • Are public: and Private: labels, or something else? They are not preceded by namespace, but are they similar?
  • _next and _previous are the pointers forward and back through the list, yes?
  • When you declare a function in a type, as in AssociativeArray.add, what happens to the return value? Can you, for example say foo=.add( "action", "do something {qualifier} cool" ) ?
  • You are defining some subs/functions twice, as in operator_[] (didn’t know you could have brackets in var names). I have read about something called overload, though don’t know much about it, is this an example?
  • What’s the effect of declaring a var as a const in a sub/function parameter list? Does this make it read only in some way? Are there any memory/performance benefits?
  • #macros are the same as defines, in that the are replaced by their associated code at compile time, yes?
  • Whats the difference between var n => … and just n=> …?
  • Finally I’m assuming that pos_ +=> 1 is the same as C’s pos++,yes? Can you also pos+=>5?
Thanks again.
paul doe
Posts: 1269
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Old school text adventure as a way of re-learning coding

Postby paul doe » Jul 06, 2020 0:01

olympic sleeper wrote:...It looks like you are declaring subs (eg Constructor) within the type KeyValue - which I did not know was possible. Does this result in a pointer to that function existing in the type, or something else? Could these be an an indexed array? If I have a hash table of x elements could those elements point to functions?
...Are public: and Private: labels, or something else? They are not preceded by namespace, but are they similar?

See the Wiki page on user-defined types for an explanation on what constructors and destructors are in types, what they're used for, and also for an explanation on member access. Long story short, as in C++, constructors get called when a type is instantiated, and destructors get called when a type's instance is out of scope:

Code: Select all

type _
  Foo
 
  declare constructor()
  declare destructor()
 
  as integer _
    bar
end type

constructor _
  Foo()
 
  ? "Foo constructor called"
end constructor

destructor _
  Foo()
 
  ? "Foo destructor called"
end destructor

scope
  var _
    f => Foo()
end scope

?

scope
  dim as Foo _
    foos( 0 to 9 )
end scope

sleep()

This is trivial, but they're far, far more useful than they look at a first glance.

As for the hash table question, indeed, a hash table can contain anything you wish, even function pointers. So you can have, say:

Code: Select all

type _
  KeyValue
 
  as string _
    key
  as sub( _
    byval as any ptr ) _
    value
  as KeyValue ptr _
    _next, _previous
end type

And then you'll map keys to function pointers (a sub in FreeBasic is akin to a void function in C). The function pointer is of a function that accepts an any ptr (a void*) as a parameter, and you can assign any function that matches the signature.
..._next and _previous are the pointers forward and back through the list, yes?

Indeed, they are. It is a doubly linked list.
...When you declare a function in a type, as in AssociativeArray.add, what happens to the return value? Can you, for example say foo=.add( "action", "do something {qualifier} cool" ) ?

The return value of a function can be ignored if you wish. There, I just return a reference to the type itself, so you can chain method calls one after the other, like this:

Code: Select all

myAssocArray.add( "foo", "A foo" ).add( "bar", "A bar" ).add( "baz", "A baz" )

This is more useful when you return the type from inside a function, or another method.
...You are defining some subs/functions twice, as in operator_[] (didn’t know you could have brackets in var names). I have read about something called overload, though don’t know much about it, is this an example?

Indeed, it effectively overloads an operator for convenience. Var names can't contain brackets. See the Wiki page on operators for an exhaustive explanation on them.

You can overload any function within a type, as long as the parameter list is different (even constructors). You can't overload functions based only on their return value (unless it's the cast() operator).
...What’s the effect of declaring a var as a const in a sub/function parameter list? Does this make it read only in some way? Are there any memory/performance benefits?

It is used, as in C++, to avoid modifying the var inside the function. Since strings are mostly passed by reference (so as to avoid unnecessary copying), this ensures the function cannot modify it. No effect at run-time; it's just for the compiler to enforce.
...#macros are the same as defines, in that the are replaced by their associated code at compile time, yes?

Yes. The difference is that #macros can have multiple lines.
...Whats the difference between var n => … and just n=> …?

var declares a variable, inferring its type from the expression you assign. Equivalent to C++ 11 auto. As in C, in FreeBasic you can't refer to a var if you don't declare it first.
...Finally I’m assuming that pos_ +=> 1 is the same as C’s pos++,yes? Can you also pos+=>5?[/list]

Indeed. FreeBasic doesn't have pre or post-increment operators, so that is an 'increment and assign' operation. You can use either = or => for assignments. It's a matter of preference (and to distinguish between the assignment and comparison operators).
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Postby olympic sleeper » Jul 24, 2020 19:59

Hello again,

Sorry to say that I am a bit stuck and would appreciate some advice.

I am currently working on portals. A portal is an object that may be moved around and allows access to places that are high up or low down. Its a bit like a ladder, but as its an object it can be opened and closed. It can also be fixed in place like a window, door etc, here's some example text from a test location.

Code: Select all

You are standing in a narrow ally that runs between Muddle’s pawn shop and Mildred's cakes.
Above on the wall of Muddle’s pawn shop is an open window and leaning against this is a wooden ladder.


In this both the window and the ladder are portals and the code links these when a player says something like

Code: Select all

Put ladder against window

as has been done above.

The player can climb the ladder, which will put them at its top by the window or just type in or up, which will take them straight through the window into the room beyond.

So the problem. I am struggling to work out how to code the fact that the player has done one or other of these. At present they can type ‘climb ladder and in’, ‘in’ or ‘up’ to enter the window. Once through they only have the option of out and down as the code has lost track of where the ladder is, its not in the new location, so the code's forgotten it. Thus if they climb the ladder and enter the window and then type out or down they always end up in the alley and never back on the ladder. Unfortunately I cannot store the last command as they could have carried out all sorts of actions while they are on the other side of the window.

This has bitten me when adding and landings to rooms. A landing is an object linked to by stairs (a portal), there are doors (portals) off it. If the player climbs the stairs, goes through a door and they back out. They wind up at the bottom of the stairs again and not on the landing. The code that handles this is the same as that for ladders, which is why they are behaving the same. So I need some way of knowing what object the player was on prior to passing through a portal. But its a bit more complex as they could have been sitting in an armchair, type north to go north and south where upon they would be confused if they ended up back in the armchair.

Any thoughts?
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

NPCs people and animals

Postby olympic sleeper » Aug 10, 2020 22:48

Hello,

I am now starting on the NPC part of my text adventure. In Zork, which is the inspiration for this, there were a number of NPCs, though they did not do much, other than the thief who would rob you bind at every opportunity. I’d like to try and expand on this so that NPCs do sort of realistic things, at least for a given value of real. My initial idea is to give them a few simple ‘needs’ which are basic actions they want to accomplish. Suppose someone wants to put a book on a shelf.

The book is an object as is the shelf. So the need would be a simple action (put) the books id (say 10) on the shelf’s id (say 25). Now place the book in a locked chest and the npc somewhere away from the shelf. I think the logic could work as follows.

Code: Select all

Do I need something? If so what (in this case put 10 on 25). OK do I have 10? No. Do I know where is? No. Is there anything ‘here’ that might hold it? No. At which point we move the NPC.

Now maybe they are in a room with a chest. Repeating the above we get to 'is there anything here that might hold it?' Yes, try and open it, failed (the chest is locked). Add a need to unlock the chest and add the chest’s location to the npc’s memory – see later. Now move the NPC.

Perhaps they moved into a room containing a key. We now have two needs, put the book on the shelf and open the chest. If the book isn’t here, check is there anything that might satisfy the chest need? Yes there is a key here, so take it. Move the npc back to the chest. It may be that the needs will have to nest somehow so if the NPC finds the book they drop all the needs associated with trying to find it. (At present I don’t know how to do this, a stack perhaps? :/  ).

Repeat above, again no book, but the key unlocks things, and the chest is locked. Try to unlock the chest. This will either fail (wrong key) or succeed. If it fails we add an item note to the npc’s memory – that key does not open that chest, if it succeeds then we add that key does open that chest. I have yet to figure out how the memory will work, suggestions welcome, but it might just need to be x goes here x does not go here.

Lets assume that the key fits. The unlock need is fulfilled and removed from the list. So we still need to put the book on the shelf. Again we repeat, is there a thing that might contain the book,yes, open it. Is the book here? Etc…

Once the NPC has the book they then search for the shelf the same way. It is possible that in searching for the key or the book or anything else that they happen upon the shelf, in which case the memory gets updated, again this could be as simple as ‘x is here’. I already have code for this in the narrator so the player can ask ‘where is the ball?’, and get reminded where they last saw the ball. They also get told where several matching objects were last seen, like shirts – eg ‘there are several on the shelf’.

This is all very rough and likely to change, however has anyone got any thoughts, perhaps suitable data structures for the memory/needs etc?

As always thanks in advance.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

NPCs people and animals

Postby olympic sleeper » Aug 13, 2020 9:07

Hello,

When I checked the forum a couple of days ago someone had posted whether I had considered GOAP, with a very useful YouTube link. I hadn't considered it as I did not know it was a thing but went off to look. Unfortunately I did not make a note of their name and the post has now disappeared so I cannot thank you more directly, however GOAP is a very close fit at least in ideas to what I had in mind.

So thank you for that post and sorry I cannot thank you by name.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Old school text adventure as a way of re-learning coding

Postby olympic sleeper » Aug 15, 2020 22:56

Hello,

A quick update:
NPC movement is now complete, they path correctly from location to location, goals are in progress however I'm wondering on the best way to get the npcs to 'talk' to the main code. That is if an npc turns on a TV how is the code going to know? I supose I could just use lots of flags and if statements but I'm wondering if there isn't a more elegent solution? It could be that there is something in GOAP - I haven't had a chance to really go into it yet and as mentioned I didn't know it was a thing - however does anyone have any suggestions?

Thanks in advance.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

NPCs people and animals

Postby olympic sleeper » Aug 21, 2020 16:40

Hello,

Another quick update and also a link for anyone interested in text adventures etc. There is a podcast called the Retro hour on YouTube and elsewhere which featured text adventures - https://www.youtube.com/watch?v=w8IQZJJFqCU. Its more of an overview and interview with a dev who is/has produced an engine similar to Infocom's z machine, as well as a quick oveview of AI writing games. Folks might find it interesting.

Relating to the previous post I realised that the NPC did not need to talk to the code, but to the main database as they influence the world and the world is the db. Thus NPC needs and GOAP (ish) is moving forward, an example output, the NPC Midlred is looking for a book.

Code: Select all

You're standing outside Mildred's cake emporium, its window laden with all kinds of cakes and pastries, bread, rolls and doughnuts.
There is a sea chest, a bank safe and a safe key here.

Mildred just walked in.

What now? <I just pressed enter>
{in search      20           the Tales of Hoffmann}

Mildred opens the sea chest, looks mildly disappointed and closes it again, she seems to be looking for something.
Mildred tries to open the bank safe, but it is locked.
Mildred picks up the safe key.
Mildred unlocks the bank safe, takes a book out of it and relocks it.


The text is stil rather clunky but the logic is working, she would have looked for the safe key and continued to look for the book if they were elsewhere. NPCS also have basic personalities, which is why she looked mildy disappointed , and get annoyed if they cannot find what they want reasonably quickly.

The next task is to let them use ladders to get things off of shelves.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

[off topic?] Ice creams and keys

Postby olympic sleeper » Aug 26, 2020 8:53

Hello,

In the text adventure I am writing I have an NCP that sells ice creams, however I am struggling with thinking up enough (around 20) different enough flavours. So I thought I'd ask here, while I have 9 so far it may be that there are better options out there.

So...What's your favourite ice cream flavour? Have you come across any unusual ones - the most unusual I have tasted was blue cheese ice cream, which was actually rather good.

The other thing I having 'fun' with is my npc's habbit of hording keys. If they come across something that is locked while looking for something else they will hunt for a suitable key. However they are not omnipotent so do not know what unlocks what without trying it (unless they own the locked item). Thus they keep hold of every key they find - a pain for the player.

I need a way of making them put keys down, but just having them randomly drop them seems unrealistic - not to mention untidy. So they will leave keys in 'suitable places' like on a key board, or in a tray - but again I'm struggling to think up places.

So where would you leave keys so you don't have to hunt for them again? A tray, hook on the wall, top of the fridge?

Thanks in advance.
grindstone
Posts: 752
Joined: May 05, 2015 5:35
Location: Germany

Re: [off topic?] Ice creams and keys

Postby grindstone » Aug 26, 2020 13:19

olympic sleeper wrote:So...What's your favourite ice cream flavour?

Chocolate
Vanilla
Lemmon
Strawberry
Raspberry
Woodruff
Apple
Pistachio
Malaga
Stracciatella
Tomato (!)
Mocca
Blackberry
Cherry
Rockmelon
Gooseberry
Pear
Elder
Kiwi
Peach

My favoured flavour by far is (homemade) chocolate ice. *smile*
marcov
Posts: 3011
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: [off topic?] Ice creams and keys

Postby marcov » Aug 26, 2020 14:46

Cassis (black currant)
Wallnut
badidea
Posts: 2149
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: [off topic?] Ice creams and keys

Postby badidea » Aug 26, 2020 17:10

I don't like ice cream too much. Too cold, too sweet, too soft. I limit my consumption to once a year, and I have not had any this year yet. If I have too choose, then something with nuts. So pistache or walnut sounds good. You can find a lot of flavors using any search machine. Example:
Image
Concerning keys. I normally leave my keys in my trousers. So if I have to leave the house in the middle of the night, I only have to remember to put my trousers on. Else, I would check the following: Tables, couch, fireplace mantel, backpack, door locks, car, washing machine.
jj2007
Posts: 1693
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: [off topic?] Ice creams and keys

Postby jj2007 » Aug 26, 2020 17:19

badidea wrote:I don't like ice cream too much. Too cold, too sweet, too soft. I limit my consumption to once a year
I also limit mine: no more than once a day.
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: [off topic?] Ice creams and keys

Postby olympic sleeper » Aug 26, 2020 23:04

Many thanks, never heard of Woodruff as a thing never mind ice cream - cassis also a good one. I did search before I posted (missed the woodruff though - its not in the wikipeidia entry but then neither is cassis) but the problem with that is, well you can make ice cream out of *anything* (including crab?) I even found a guy on YouTube making it out of a kind of ketchup (ugh) https://www.youtube.com/watch?v=KelcWLQvfuA. So getting favourites seemed the best way forward. That said I don't think I'd like ice cream made from scratch - does not sound very appetising.

Also thanks @badidea for the keys list, would not have thought of the washing machine.

Thanks again.
srvaldez
Posts: 2513
Joined: Sep 25, 2005 21:54

Re: [off topic?] Ice creams and keys

Postby srvaldez » Aug 26, 2020 23:55

what about a careless npc that leaves the key in the lock?

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 5 guests