Inventory List Checks

Blitz3D Forums/Blitz3D Programming/Inventory List Checks

In my RPG I want to use a List Checking System to evaluate if a player possesses a specific item(s) needed to perforrm a specific action (ie: unlock a door). This checking is at the core of every action a player can perform.

Everything for the player is stored in a single inventory list to include attributes, skills, weapons, items, etc. This is the GIVE List. Every Game Control (Trigger/ Player Control / Gui Button) has a list of required item(s) needed to activate. This is the TAKE List.

Items in both Lists could be stored as Strings. The GIVE List item contains name & value. The TAKE List item contains logic condition {>, <, <>, <=, =>, =}, name & value.

When a player attempts to activate a control, items in the GIVE list are compared to the items TAKE list. First the items are checked to see if they exist, than compared using the logic condition. Each check results in a TRUE or FALSE. If all items checks = TRUE, the action is executed. If any item check = FALSE, the action is aborted.

The GIVE list can get pretty hefty in size requiring hundred of item checks. Thus, I' m looking for the most efficient means to store items (data structure) and evaluate the list (sort algorithm).

I take it you're using types for this? Should be quite straight forward, if so - assuming I'm understanding what you want, exactly. :)

Create a GIVE type and a TAKE type with the required fields, then have a linked list of GIVE/TAKE types in your main object type(s), as required.

For the logic condition checks of the TAKE type, have a field in the type that specifies the condition needed - 1 for =, 2 for <, 3 for > etc. Then you can apply the required condition test using a simple Select statement.

@big10p: Thanks for the input. Ok, I used types. I've created one InventoryList List Type that mimics mySQL INVENTORY table. This is what I came up with:
;============================
;INVENTORYTABLEITEM CLASS
;Generated with TypeWriter V
;============================

;============================
;CONSTANTS
;============================
Const INVENTORYTABLEITEM_MAX%=1024

;============================
;GLOBALS
;============================
Global inventoryTableItem_ID.inventoryTableItem[INVENTORYTABLEITEM_MAX%];Primary Key Object Pointer
Global inventoryTableItem_Index%[INVENTORYTABLEITEM_MAX%], inventoryTableItem_IndexPointer%;Primary Key ID Management Stack

;============================
;OBJECT
;============================
Type inventoryTableItem
	;Purpose: Loolup Table by Name for all possible items 
	;Properties:
	Field id%;
	Field name$;
End Type

;============================
;METHODS
;============================
Function inventoryTableItemStart()
	;Purpose: Initialize Class
	;Parameters: TBD
	;Return: None
	For inventoryTableItemloop=INVENTORYTABLEITEM_MAX To 1 Step -1; Initialize Primary Key ID Management Stack
		inventoryTableItemIndexPush(inventoryTableItemloop)
	Next
End Function

Function inventoryTableItemStop()
	;Purpose: Shutdown Class
	;Parameters: TBD
	;Return: None
	For this.inventoryTableItem=Each inventoryTableItem
		inventoryTableItemDelete(this)
	Next
End Function

Function inventoryTableItemNew.inventoryTableItem()
	;Purpose: CONSTRUCTOR - Creates inventoryTableItem Instance; Sets Default Property Values
	;Parameters: TBD
	;Return: inventoryTableItem Instance
	this.inventoryTableItem=New inventoryTableItem
	this\id%=0
	this\name$=""
	this\id%=inventoryTableItemIndexPop()
	inventoryTableItem_ID[this\id%]=this
	Return this
End Function

Function inventoryTableItemDelete(this.inventoryTableItem)
	;Purpose: DESTRUCTOR - Removes inventoryTableItem Instance
	;Parameters: inventoryTableItem Instance
	;Return: None
	inventoryTableItem_ID[this\id]=Null
	inventoryTableItemIndexPush(this\id%)
	this\name$=""
	Delete this
End Function

Function inventoryTableItemIndexPush(inventoryTableItemid%)
	;Purpose: Pushes ID into Primary Key ID Management Stack
	;Parameters: inventoryTableItemid=Object's ID
	;Return: None
	inventoryTableItem_Index[inventoryTableItem_IndexPointer]=inventoryTableItemid%
	inventoryTableItem_IndexPointer=inventoryTableItem_IndexPointer+1
End Function

Function inventoryTableItemIndexPop()
	;Purpose: Pops ID out of Primary Key ID Management Stack
	;Parameters: None
	;Return: Object ID%
	inventoryTableItem_IndexPointer=inventoryTableItem_IndexPointer-1
	Return inventoryTableItem_Index[inventoryTableItem_IndexPointer]
End Function

Function inventoryTableItemAdd%(inventoryTableItemname$)
	;Purpose: Creates an Object and returns it ID
	;Parameters: Object's Properties
	;Return: Object's ID%
	this.inventoryTableItem=inventoryTableItemNew()
	this\name$=inventoryTableItemname$
	Return this\id
End Function

Function inventoryTableItemIndexGet%(inventoryTableItemname$)
	;Purpose: Returns Index for inventorytableitem,  a unique index is used for each entry 
	;	If the name is not found it will add it to the table, returning the  new index
	;Parameters: TBD
	;Return: None
	For this.inventoryTableItem = Each inventoryTableItem
		If this\name = inventoryTableItemname$ 
			Return this\ID 
		EndIf	
	Next
	Return inventoryTableItemAdd(inventoryTableItemname$)
End Function


;============================
;INVENTORY CLASS
;Generated with TypeWriter V
;============================

;============================
;CONSTANTS
;============================
Const INVENTORY_MAX%=16
Const INVENTORY_TYPE_GIVE%=0
Const INVENTORY_TYPE_TAKE%=1

;============================
;OBJECT
;============================
Type inventory
	;Purpose: 
	;Properties:
	Field typeid%;
	Field inventoryitem.inventoryitem[INVENTORYITEM_MAX%];
	Field inventoryitems;
End Type

;============================
;METHODS
;============================
Function inventoryStart()
	;Purpose: Initialize Class
	;Parameters: TBD
	;Return: None
End Function

Function inventoryStop()
	;Purpose: Shutdown Class
	;Parameters: TBD
	;Return: None
	For this.inventory=Each inventory
		inventoryDelete(this)
	Next
End Function

Function inventoryNew.inventory(inventorytypeid=INVENTORY_TYPE_GIVE)
	;Purpose: CONSTRUCTOR - Creates inventory Instance; Sets Default Property Values
	;Parameters: TBD
	;Return: inventory Instance
	this.inventory=New inventory
	this\typeid%=inventorytypeid
	Return this
End Function

Function inventoryDelete(this.inventory)
	;Purpose: DESTRUCTOR - Removes inventory Instance
	;Parameters: inventory Instance
	;Return: None
	Delete this
End Function

Function InventoryCheck(take.inventory,give.inventory)
	;Purpose: Checks all items in the take list against item players give inventory.
	;Parameters:
	;	take inventory list object
	;	give inventory list object
	;Return: FALSE if a failure exists, TRUE Otherwise
	For takeinventoryitems = 1 To take\inventoryitems
		;DebugLog take\inventoryitem[takeinventoryitems]\inventoryID
		If  give\inventoryitem[take\inventoryitem[takeinventoryitems]\inventorytableid] <> Null 
			If Not InventoryItemCompare(take\inventoryitem[takeinventoryitems], give\inventoryitem[take\inventoryitem[takeinventoryitems]\inventorytableid]) Return False
			InventoryItemMatch = True
		EndIf
		If InventoryItemMatch = False  And take\inventoryitem[takeinventoryitems]\requirement = INVENTORYITEM_REQUIREMENT_MANDATORY Return False
		InventoryItemMatch = False
	Next
	Return True
End Function


Function InventoryAddItem(this.inventory, inventoryitemname$="", inventoryitemvalue%=0, inventoryitemcondition%=0, inventoryitemrequirement%=INVENTORYITEM_REQUIREMENT_MANDATORY)
	;Purpose: Adss item to inventory list. the last item in the list is move into the open position.
	;Parameters:
	;	this give inventory list object
	;	inventoryitem name - name of item
	;	inventoryitemvalue - value of inventory
	;	inventoryitemcondition -	INVENTORYITEM_CONDITION_NQ:1,INVENTORYITEM_CONDITION_EQ:2,INVENTORYITEM_CONDITION_GT:3
	;								INVENTORYITEM_CONDITION_GE:4,INVENTORYITEM_CONDITION_LT:5,INVENTORYITEM_CONDITION_LE:6
	;Return: none
	Select this\typeid
		Case INVENTORY_TYPE_TAKE
			this\inventoryitems = this\inventoryitems + 1
			this\inventoryitem[this\inventoryitems]	= inventoryitemNew(InventoryTableItemIndexGet%(inventoryitemname$), inventoryitemvalue, inventoryitemcondition%, inventoryitemrequirement%)
		Case INVENTORY_TYPE_GIVE
			this\inventoryitems = this\inventoryitems + 1
			this\inventoryitem[inventoryTableItemIndexGet%(inventoryitemname$)] = inventoryitemNew(inventoryTableItemIndexGet%(inventoryitemname$), inventoryitemvalue%, inventoryitemcondition%, inventoryitemrequirement%)
	End Select 	
End Function

Function InventoryRemoveItem(this.inventory,inventoryitemtableid)
	;Purpose: Removes item from inventory list
	;Parameters:
	;	take inventory list object
	;Return: none
	inventoryItemDelete(this\inventoryitem[inventoryitemtableid])
	this\inventoryitems = this\inventoryitems - 1
End Function


;============================
;INVENTORYITEM CLASS
;Generated with TypeWriter V
;============================
;============================
;CONSTANTS
;============================
Const INVENTORYITEM_MAX%=1024
Const INVENTORYITEM_CONDITION_NQ	= 	0
Const INVENTORYITEM_CONDITION_EQ	= 	1
Const INVENTORYITEM_CONDITION_GT	= 	2
Const INVENTORYITEM_CONDITION_GE	= 	3
Const INVENTORYITEM_CONDITION_LT	= 	4
Const INVENTORYITEM_CONDITION_LE	= 	5
Const INVENTORYITEM_REQUIREMENT_OPTIONAL = 0
Const INVENTORYITEM_REQUIREMENT_MANDATORY = 1

;============================
;OBJECT
;============================
Type inventoryItem
	;Purpose: 
	;Properties:
	Field inventorytableid%;
	Field value%;
	Field condition%;
	Field requirement%;
End Type

;============================
;METHODS
;============================
Function inventoryItemStart()
	;Purpose: Initialize Class
	;Parameters: TBD
	;Return: None
End Function

Function inventoryItemStop()
	;Purpose: Shutdown Class
	;Parameters: TBD
	;Return: None
	For this.inventoryItem=Each inventoryItem
		inventoryItemDelete(this)
	Next
End Function

Function inventoryItemNew.inventoryItem(inventoryitemtableid%=0, inventoryitemvalue%=0, inventoryitemcondition%=0, inventoryitemrequirement%=INVENTORYITEM_REQUIREMENT_MANDATORY)
	;Purpose: CONSTRUCTOR - Creates inventoryItem Instance; Sets Default Property Values
	;Parameters: 
	;	inventoryitemtableid% Lookup TableID 
	;	inventoryitemvalue% Value
	;	inventoryitemcondition% Logic Condition
	;	inventoryitemrequirement%=INVENTORYITEM_REQUIREMENT_MANDATORY,_OPTIONAL,_RANDOM
	;Return: inventoryItem Instance
	this.inventoryItem=New inventoryItem
	this\inventorytableid%=inventoryitemtableid%
	this\value%=inventoryitemvalue
	this\condition%=inventoryitemcondition
	this\requirement% = inventoryitemrequirement
	Return this
End Function

Function inventoryItemDelete(this.inventoryItem)
	;Purpose: DESTRUCTOR - Removes inventoryItem Instance
	;Parameters: inventoryItem Instance
	;Return: None
	Delete this
End Function

Function InventoryItemCompare(takeinventoryitem.inventoryitem,giveinventoryitem.inventoryitem)
	;Purpose: compares take inventory item value against give inventory item value using the condition in the take item 
	;Parameters: takeinventoryitem , giveinventoryitem
	;Return: TRUE if check is sucessful, FALSE otherwise
	Select takeinventoryitem\condition
		Case 0:	If giveinventoryitem\value <> takeinventoryitem\value Return True
		Case 1: If giveinventoryitem\value =  takeinventoryitem\value Return True
		Case 2:	If giveinventoryitem\value >  takeinventoryitem\value Return True
		Case 3:	If giveinventoryitem\value => takeinventoryitem\value Return True
		Case 4:	If giveinventoryitem\value <  takeinventoryitem\value Return True
		Case 5:	If giveinventoryitem\value <= takeinventoryitem\value Return True
	End Select	
	Return False
End Function

;================================================

	;item lookup table
	inventoryTableItemStart()
	inventoryTableItemAdd("HP")
	inventoryTableItemAdd("ST")
	inventoryTableItemAdd("DX")
	inventoryTableItemAdd("IQ")
	inventoryTableItemAdd("MP")
	inventoryTableItemAdd("Level")
	inventoryTableItemAdd("LockPick")
	inventoryTableItemAdd("Dazed")

	;door
	take.inventory = inventorynew(INVENTORY_TYPE_TAKE)
	InventoryAddItem(take,"Level",5,INVENTORYITEM_CONDITION_GE)
	InventoryAddItem(take,"LockPick",2,INVENTORYITEM_CONDITION_GE)
	InventoryAddItem(take,"Dazed",False,INVENTORYITEM_CONDITION_EQ,INVENTORYITEM_REQUIREMENT_OPTIONAL)
		
	;player
	give.inventory = inventorynew(INVENTORY_TYPE_GIVE)
	InventoryAddItem(give ,"Level",5)
	InventoryAddItem(give ,"LockPick",2)
	InventoryAddItem(give, "Dazed",False)
	
	;inventoryitemmatch 
	Select InventoryCheck(take,give)
		Case True	Print "Player has sufficent skills to open the door."
		Case False	Print "Player is too weak to open the door."
	End Select	
	
	inventoryitemstop()
	inventorystop()
	inventoryitemstop