News:

PlayBASIC2DLL V0.99 Revision I Commercial Edition released! - Convert PlayBASIC programs to super fast Machine Code. 

Main Menu

Array Type Question

Started by feildmaster, March 20, 2011, 03:40:54 PM

Previous topic - Next topic

feildmaster

Alright, I figure I better ask for help in a topic rather than sending a message to Kevin (Sorry kevin if that bothered you. ;))

Here's an example of what I'm trying to do...
PlayBASIC Code: [Select]
; PROJECT : Project1
; AUTHOR : Microsoft
; CREATED : 3/20/2011
; ---------------------------------------------------------------------

type tInventory
ItemID ; Item ID
ItemName$ ; Item Name
ItemDesc$ ; Item Description
ItemAmnt ; Item Ammount
EndType

SetFps 30 ; Limit to 30 frames per second

global inventory_count = 0 ; Items in Inventory
dim inventory(0) as tInventory ; Inventory Array

;waitkey

; Insert a few items...
AddInventoryItem(1, 55) ; Add Item 1, Amount 55
AddInventoryItem(22, 1) ; Add Item 22, Amount 1
AddInventoryItem(22, 4) ; Add Item 22, Amount 4
AddInventoryItem(10, 3) ; Add Item 10, Amount 3

cls 0
displayInventory(inventory_count, "Normal") ; Basic Inventory with a couple items...
RemoveInventoryItem(22) ; Remove all of item 22...
displayInventory(inventory_count, "'Removed' Items") ; Showing the new item list
displayInventory(GetArrayElements(inventory(),1), "Reality") ; Show real list
; Redimming erases type array data...
redim inventory(inventory_count) as tInventory ; Redim to Clip Excess
displayInventory(inventory_count,"Redimmed") ; Display Results
sync
waitKey

function displayInventory(max, type$)
print "=========== Inventory ("+type$+") ==========="
for x=1 to max
print "Item ID: "+str$(inventory(x).ItemID)+" ("+str$(inventory(x).ItemAmnt)+")"
next
endfunction

function AddInventoryItem(ItemID, ItemAmnt)
index = getfreecell(inventory()) ; Adds a new cell to the array
; Is there a reverse of this function?

inventory(index).ItemID = ItemID
inventory(index).ItemAmnt = ItemAmnt

inc inventory_count
endfunction

function RemoveInventoryItem(ItemID)
for ID = 1 to inventory_count
if ItemID <> inventory(ID).ItemID
inc count
inventory(count) = inventory(ID)
endif
Next
inventory_count = count
endfunction


The above was written up hurriedly, because i thought i found a way around it...

But I was wrong, the problem i want is to "remove" and "free" the data after the point without erasing the entire array.


I'm somewhat thinking to just do it with a dimensional array though... I don't know.

Awaiting your responses. ^^

kevin

#1
  To remove a cell from an array we use the CopyArrayCells()  function.   So to delete one, all we do is copy the next item back over the current one.


  In this example, I've added a RemoveCell() style function. This function accepts any array derived from the parent type.  So it can used as generic thing proving your types are based upon the parent type..   These some other function to add,delete, search and display the contents..

PlayBASIC Code: [Select]
   // the parent structure used for the remove cell function
Type TypedPArrayParent

Endtype

// Inventory Structure
Type Inventory as TypedPArrayParent
Name$
NameLC$ ; lower case version of the
EndType

// Array of inventory items
Dim InvArray(0) as Inventory

// Call function to add some stuff to the inventory
AddToInventory("Bucket")
AddToInventory("Cow")
AddToInventory("Milk")
ShowInventory() ; SHow the contents


// remove this and show it
RemoveFromInventory("Bucket")
ShowInventory()


// remove this
RemoveFromInventory("COw")
// add this
AddToInventory("Mountain Bike")
// show it
ShowInventory()


// remove this
RemoveFromInventory("Mountain Bike")
// remove this
RemoveFromInventory("Milk")
// show it
ShowInventory()

Sync
waitkey


Psub ShowInventory()
Print "Contents Of Inventory"
for lp=1 to GetArrayElements(InvArray())
if InvArray(lp)
print InvArray(lp).Name$
endif
next
print ""
EndPsub



Psub AddToInventory(Name$)
if FindItemByName(Name$)=0
Index=GetFreeCell(InvArray())
InvArray(Index) = New Inventory
InvArray(Index).Name$=Name$
InvArray(Index).NameLC$=lower$(Name$)
endif
Endpsub


Psub RemoveFromInventory(Name$)
Index=FindItemByName(Name$)
RemoveCell(InvArray(),Index)
Endpsub


Psub FindItemByName(Name$)
NameLC$=lower$(name$)
Index=0
for lp=1 to GetArrayElements(InvArray())
if InvArray(lp)
if InvArray(lp).NameLC$=NameLC$
Index=lp
exitfor lp
endif
endif
next
EndPsub Index


Psub RemoveCell(Me().TypedPArrayParent,Index)
// do some error checking..
// check if the passed array exists
if GetArrayStatus(me())=true
Size=GetArrayElements(me())
// Check if the index is with a legal range
if Index>-1 and Index=<Size

// Do the removal
CopyArrayCells Me(),Index+1,1,me(),Index,1,size

else
// if we get here, then Index was outside of legal
// range
#print "Error - Illegal Index"
endif

else
// if we get here, then the array that was passed
// doesn't currently exist
#print "Error - This array doesn't exist."
endif

EndPsub






feildmaster

Oh i see. I thank you. You just made my day. ^^

I see that CopyArrayCells doesn't have any tooltip for it, so do you mind explaining what each form is?

using the example:
CopyArrayCells Me(),Index+1,1,me(),Index,1,size

I can't explain it. It seems to be turning it into 2 arrays or something... But i can't tell what each value is supposed to be set as.

feildmaster

I did find one error though, and that's if you "removefrominventory" a cell that does not exist (not likely to happen, but glitches happen) the index returned will be 0.

To fix that, in the removecell function:
Code (change) Select
if Index>-1 and Index=<Size
Code (into) Select
if Index>0 and Index=<Size

feildmaster

I found the documentation...
CopyArrayCells SourceArray(), SrcStartElement, SrcElementDelta, DestArray(), DestElement, DestElementDelta, Length

Very nice documentation you have here. ^^