/************************************************************************************ *** FILE: PQueue.cpp *** DATE: 04/27/2006 *** GOAL: This file illustrates how to create a simple Priority Queue in MS *** Managd Extension. The most important class here is PQueue which is *** derived from System::Collections::ArrayList class. *** As you can see we only overwrote method Add(), which now not only adds *** a new Robot to the list, but also sorts the list. Note, that in order to *** sort the list we need to define a Comparer class RobotComparer. *** We also added a couple of methods: *** - push (alias for Add) *** - pop that returns the top element of the queue and removes it from *** the queue *** - and a property Elem, which behaves symilar to standard property Item *** but returns Robot* instead of generic Object*. *** BUILD: in order to compile this program use *** c:> cl /clr PQueue.cpp *** command ************************************************************************************/ #using using namespace System; using namespace System::Collections; __gc class Robot : public Object { private: static int lastID = 1; static Random *rand = new Random; int robotHP; int robotID; public: Robot() { robotID=lastID++; robotHP=rand->Next(100); }; String* ToString() { return String::Concat(S"Robot #", robotID.ToString(), S" HP:", robotHP.ToString()); }; __property int get_HP() { return robotHP; }; __property void set_HP(int newHP) { if(newHP>=0) robotHP=newHP; }; __property int get_ID() { return robotID; }; __gc struct RobotComparer : Collections::IComparer { int Compare(Object *a, Object *b) { Robot *left = dynamic_cast(a); Robot *right = dynamic_cast(b); return right->HP - left->HP; } }; }; __gc class PQueue : public ArrayList { public: __property Robot* get_Elem(int index) { return dynamic_cast(Item[index]); }; void Add(Robot *r) { __super::Add(r); Sort(new Robot::RobotComparer); }; void push(Robot *r) { Add(r); }; Robot* pop() { Robot *r = Elem[0]; RemoveAt(0); return r; }; }; int main() { // TODO: Please replace the sample code below with your own. Console::WriteLine(S"Testing managed robot queue:"); int i; Robot *r; PQueue *queue = new PQueue; for(i=0;i<10;i++){ r = new Robot; Console::WriteLine("{0} created and added to the queue", r); queue->Add(r); } Console::WriteLine(S"Initill robot queue is:"); for(i=0;iCount;i++) Console::WriteLine("{0}: {1}", i.ToString(), queue->Elem[i]); Console::WriteLine(S"\nLet's remove the last added element and a couple of top elements:"); queue->Remove(r); Console::WriteLine(S" - {0} removed", r); Console::WriteLine(S" - {0} removed", queue->pop()); Console::WriteLine(S" - {0} removed", queue->pop()); Console::WriteLine(S"Robot queue now is:"); for(i=0;iCount;i++) Console::WriteLine("{0}: {1}", i.ToString(), queue->Elem[i]); Console::WriteLine(S"\nLet's kill some robots ..."); dynamic_cast(queue->Item[1])->HP = 0; dynamic_cast(queue->Item[4])->HP = 0; Console::WriteLine(S"Robot queue now is:"); for(i=0;iCount;i++) Console::WriteLine("{0}: {1}", i.ToString(), queue->Elem[i]); Console::WriteLine(S"\n...and remove the dead robot from the queue:"); for(i=0;iCount;) if( queue->Elem[i]->HP == 0 ) queue->RemoveAt(i); else i++; Console::WriteLine(S"Robot queue now is:"); for(i=0;iCount;i++) Console::WriteLine("{0}: {1}", i.ToString(), queue->Elem[i]); return 0; }