- Home
- Discussion Forum
- AROS FORUMS
- PortablE
- bitset inventory example 2
bitset inventory example 2
Last updated on 13 years ago
SamuraiCrowSoftware Dev
Posted 13 years agoIn our last lesson, we showed how to do a simple 64 item bitset. Now we're going to make it more flexible and object-oriented. I'll discuss the changes I've made in a later post.
Here are the new codes:
inventorybase.e
textitem.e
inventorybasetest.e
Here are the new codes:
inventorybase.e
Code Download source
OPT MODULE
CLASS item
itemnum:INT
pad1:INT
ENDCLASS
DEF nextitem:INT,itemlist[SIZEOF BIGVALUE*8]:ARRAY OF PTR TO item
PROC makeitem() NEW OF item
self.itemnum:=nextitem
itemlist[nextitem]:=self
++nextitem
IF nextitem>(SIZEOF BIGVALUE*8) THEN Raise("ARG")
ENDPROC
PROC getmask() OF item RETURNS mask:BIGVALUE IS 1 SHL self.itemnum
PROC getdescription() OF item IS EMPTY
CLASS inventory
mask:BIGVALUE
ENDCLASS
PROC makeinventory() NEW OF inventory
self.mask:=0
ENDPROC
PROC additem(myitem:PTR TO item) OF inventory
self.mask:=self.mask OR myitem.getmask()
ENDPROC
PROC removeitem(youritem:PTR TO item) OF inventory
self.mask:=self.mask AND NOT youritem.getmask()
ENDPROC
PROC hasitem(myitem:PTR TO item) OF inventory RETURNS ret:BOOL
ret:= (self.mask AND myitem.getmask()=myitem.getmask())
ENDPROC
PROC hasany(items:PTR TO inventory) OF inventory RETURNS ret:BOOL
ret:=(self.mask AND items.mask <> 0)
ENDPROC
PROC hasall(items:PTR TO inventory) OF inventory RETURNS ret:BOOL
ret:=(self.mask AND items.mask = items.mask)
ENDPROC
PROC getitem(source:PTR TO inventory, theitem:PTR TO item) OF inventory RETURNS ret:BOOL
ret:=FALSE
IF source.hasitem(theitem)
source.removeitem(theitem)
self.additem(theitem)
ret:=TRUE
ENDIF
ENDPROC
PROC giveitem(destination:PTR TO inventory, theitem:PTR TO item) OF inventory RETURNS ret:BOOL
ret:=destination.getitem(self,theitem)
ENDPROC
PROC useall(items:PTR TO inventory) OF inventory RETURNS ret:BOOL
ret:=FALSE
IF self.hasall(items)
self.mask:=self.mask AND NOT items.mask
ret:=TRUE
ENDIF
ENDPROC
PROC list() OF inventory
DEF count:INT,current:PTR TO item
FOR count:=0 TO nextitem-1
current:=itemlist[count]
IF self.hasitem(current)
current.getdescription()
Print('\n')
ENDIF
ENDFOR
ENDPROC
textitem.e
Code Download source
OPT MODULE
MODULE '*inventorybase'
CLASS textitem OF item
description:STRING
ENDCLASS
PROC getdescription() OF textitem IS Print('\s',self.description)
PROC maketextitem(describe:STRING) NEW OF textitem
SUPER self.makeitem()
self.description:=describe
ENDPROC
inventorybasetest.e
Code Download source
MODULE '*textitem', '*inventorybase'
DEF lamp:PTR TO textitem, torch:PTR TO textitem, bag:PTR TO textitem,
room:PTR TO inventory, mystuff:PTR TO inventory, lights:PTR TO inventory,
allstuff:PTR TO inventory
PROC getit(what:PTR TO textitem)
IF mystuff.getitem(room,what)
Print('You\'ve picked up ')
what.getdescription()
ELSE
Print('You aleady have ')
what.getdescription()
ENDIF
Print('.\n')
ENDPROC
PROC main()
DEF in[4]:STRING
NEW lamp.maketextitem(NEW 'a lamp')
NEW torch.maketextitem(NEW 'a torch')
NEW bag.maketextitem(NEW 'a bag')
NEW room.makeinventory()
NEW mystuff.makeinventory()
NEW lights.makeinventory()
NEW allstuff.makeinventory()
room.additem(lamp)
room.additem(torch)
room.additem(bag)
lights.additem(lamp)
lights.additem(torch)
allstuff.additem(lamp)
allstuff.additem(torch)
allstuff.additem(bag)
REPEAT
IF mystuff.hasany(lights)
Print('You are in a room with no doors and no windows.\n')
Print('You see:\n')
room.list()
ELSE
Print('It\'s dark. You are likely to be eaten by a grue.\n')
ENDIF
Print('\nWhat do you grab?\n')
PrintFlush()
ReadStr(stdin,in)
SELECT in[0]
CASE "l"; getit(lamp)
CASE "t"; getit(torch)
CASE "b"; getit(bag)
DEFAULT; Print('I don\'t see it here.\n')
ENDSELECT
UNTIL mystuff.hasall(allstuff)
Print('You have everything! You win!\n')
PrintFlush()
FINALLY
PrintException()
ENDPROC
SamuraiCrowSoftware Dev
Posted 13 years agoOk. Now notice the way that the description is no longer embedded in the item class? It is now accessed by the getdescription() method. But wait! The getdescription() method is EMPTY in the item class. This means that item is an abstract class. You can't use it by itself but you can use child classes of it. The textitem.e file has all of the stuff in it that allows us to define an item and still expect it to work.
Let's look at textitem.e for a while. It is a module which allows it to be reused. The textitem class definition is of the item class. This is called inheritance in object-oriented terminology. The getdescription() method is defined here using a print statement that prints the description. This is called "overloading" the method definition. Lastly, the constructor of textitem has to call the makeitem constructor as well as initialize the description string so it uses the SUPER keyword to indicate that the computer is to call the parent class's version of the constructor. This is called "chaining" the constructors.
What inheritance means is that everything that can be done to an item can be done to a textitem since it is a child class. This also means that the item class fields are present in the child class even though we didn't have to copy and paste them. This saves us typing and also saves memory since we can have several kinds of items with different ways to describe themselves. The tradeoff in such an arrangement is that the code will execute more slowly since methods have to look up a pointer in a table to find which function they are supposed to be calling while functions that are not object-oriented methods can be called directly.
There have been changes here and there in the itembasetest.e file from the itemtest.e file from the previous lesson. The main difference is that everything that used to be an item is now a textitem and every NEW call to the constructor makeitem() now calls maketextitem() instead. Since the description string is not expected to have a newline character at the end, I also made adjustments to the usage of every call to the getdescription() method. Did you notice that I had to call both the textitem and inventorybase modules from within the inventorybasetest.e file? This is because I call the inventory class objects from within the inventorybasetest program directly. Otherwise I could have let textitem.e chain call the inventorybase.e module since the item class is needed by the testitem child class.
Feel free to ask any questions.
Let's look at textitem.e for a while. It is a module which allows it to be reused. The textitem class definition is of the item class. This is called inheritance in object-oriented terminology. The getdescription() method is defined here using a print statement that prints the description. This is called "overloading" the method definition. Lastly, the constructor of textitem has to call the makeitem constructor as well as initialize the description string so it uses the SUPER keyword to indicate that the computer is to call the parent class's version of the constructor. This is called "chaining" the constructors.
What inheritance means is that everything that can be done to an item can be done to a textitem since it is a child class. This also means that the item class fields are present in the child class even though we didn't have to copy and paste them. This saves us typing and also saves memory since we can have several kinds of items with different ways to describe themselves. The tradeoff in such an arrangement is that the code will execute more slowly since methods have to look up a pointer in a table to find which function they are supposed to be calling while functions that are not object-oriented methods can be called directly.
There have been changes here and there in the itembasetest.e file from the itemtest.e file from the previous lesson. The main difference is that everything that used to be an item is now a textitem and every NEW call to the constructor makeitem() now calls maketextitem() instead. Since the description string is not expected to have a newline character at the end, I also made adjustments to the usage of every call to the getdescription() method. Did you notice that I had to call both the textitem and inventorybase modules from within the inventorybasetest.e file? This is because I call the inventory class objects from within the inventorybasetest program directly. Otherwise I could have let textitem.e chain call the inventorybase.e module since the item class is needed by the testitem child class.
Feel free to ask any questions.
You can view all discussion threads in this forum.
You cannot start a new discussion thread in this forum.
You cannot reply in this discussion thread.
You cannot start on a poll in this forum.
You cannot upload attachments in this forum.
You can download attachments in this forum.
You cannot start a new discussion thread in this forum.
You cannot reply in this discussion thread.
You cannot start on a poll in this forum.
You cannot upload attachments in this forum.
You can download attachments in this forum.
Moderator: Administrator
Users who participated in discussion: SamuraiCrow