(svn r10579) [NoAI] -Add: functions to remove/keep the top/bottom X items from a list.
[NoAI] -Add: functions to remove/keep items given in another list.
--- a/bin/ai/regression/regression.nut Sun Jul 15 11:45:25 2007 +0000
+++ b/bin/ai/regression/regression.nut Sun Jul 15 12:36:43 2007 +0000
@@ -215,7 +215,7 @@
print(" HasItem(1050): " + list.HasItem(1050));
print(" HasItem(1051): " + list.HasItem(1051));
print(" IsEmpty(): " + list.IsEmpty());
- list.SortByItem(true);
+ list.Sort(AIAbstractList.SORT_BY_ITEM, true);
print(" List Dump:");
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
print(" " + i + " => " + list.GetValue(i));
@@ -225,6 +225,43 @@
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
print(" " + i + " => " + list.GetValue(i));
}
+
+ list.KeepTop(10);
+ print(" KeepTop(10):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+ list.KeepBottom(8);
+ print(" KeepBottom(8):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+ list.RemoveBottom(2);
+ print(" RemoveBottom(2):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+ list.RemoveTop(2);
+ print(" RemoveTop(2):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+
+ local list2 = AIList();
+ list2.AddItem(1003, 0);
+ list2.AddItem(1004, 0);
+ list.RemoveList(list2);
+ print(" RemoveList({1003, 1004}):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+ list2.AddItem(1005, 0);
+ list.KeepList(list2);
+ print(" KeepList({1003, 1004, 1005}):");
+ for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+ print(" " + i + " => " + list.GetValue(i));
+ }
+
list.Clear();
print(" IsEmpty(): " + list.IsEmpty());
}
--- a/bin/ai/regression/regression.txt Sun Jul 15 11:45:25 2007 +0000
+++ b/bin/ai/regression/regression.txt Sun Jul 15 12:36:43 2007 +0000
@@ -968,6 +968,43 @@
1097 => -1491076971
1098 => 1172943384
1099 => 9895172
+ KeepTop(10):
+ 1 => -2039536299
+ 2 => 796838333
+ 1000 => 438558874
+ 1001 => 179516226
+ 1002 => -1007339217
+ 1003 => 859527945
+ 1004 => 124767077
+ 1005 => 1693978408
+ 1006 => -880974321
+ 1007 => 559618342
+ KeepBottom(8):
+ 1000 => 438558874
+ 1001 => 179516226
+ 1002 => -1007339217
+ 1003 => 859527945
+ 1004 => 124767077
+ 1005 => 1693978408
+ 1006 => -880974321
+ 1007 => 559618342
+ RemoveBottom(2):
+ 1000 => 438558874
+ 1001 => 179516226
+ 1002 => -1007339217
+ 1003 => 859527945
+ 1004 => 124767077
+ 1005 => 1693978408
+ RemoveTop(2):
+ 1002 => -1007339217
+ 1003 => 859527945
+ 1004 => 124767077
+ 1005 => 1693978408
+ RemoveList({1003, 1004}):
+ 1002 => -1007339217
+ 1005 => 1693978408
+ KeepList({1003, 1004, 1005}):
+ 1005 => 1693978408
IsEmpty(): true
--PathFinderStupid--
--- a/src/ai/api/ai_abstractlist.cpp Sun Jul 15 11:45:25 2007 +0000
+++ b/src/ai/api/ai_abstractlist.cpp Sun Jul 15 12:36:43 2007 +0000
@@ -206,7 +206,9 @@
AIAbstractList::AIAbstractList()
{
/* Default sorter */
- this->sorter = new AIAbstractListSorterValueDescending(this);
+ this->sorter = new AIAbstractListSorterValueDescending(this);
+ this->sorter_type = SORT_BY_VALUE;
+ this->sort_ascending = false;
}
AIAbstractList::~AIAbstractList()
@@ -286,18 +288,28 @@
return true;
}
-void AIAbstractList::SortByItem(bool ascending)
+void AIAbstractList::Sort(SorterType sorter, bool ascending)
{
+ if (sorter == this->sorter_type && ascending == this->sort_ascending) return;
+
delete this->sorter;
- if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this);
- else this->sorter = new AIAbstractListSorterItemDescending(this);
-}
+ switch (sorter) {
+ case SORT_BY_ITEM:
+ if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this);
+ else this->sorter = new AIAbstractListSorterItemDescending(this);
+ break;
-void AIAbstractList::SortByValue(bool ascending)
-{
- delete this->sorter;
- if (ascending) this->sorter = new AIAbstractListSorterValueAscending(this);
- else this->sorter = new AIAbstractListSorterValueDescending(this);
+ case SORT_BY_VALUE:
+ if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this);
+ else this->sorter = new AIAbstractListSorterItemDescending(this);
+ break;
+
+ default:
+ this->Sort(SORT_BY_ITEM, false);
+ return;
+ }
+ this->sorter_type = sorter;
+ this->sort_ascending = ascending;
}
void AIAbstractList::RemoveAboveValue(int32 value)
@@ -352,6 +364,79 @@
}
}
+void AIAbstractList::RemoveTop(int32 count)
+{
+ if (!this->sort_ascending) {
+ this->Sort(this->sorter_type, !this->sort_ascending);
+ this->RemoveBottom(count);
+ this->Sort(this->sorter_type, !this->sort_ascending);
+ return;
+ }
+
+ switch (this->sorter_type) {
+ default: NOT_REACHED();
+ case SORT_BY_VALUE:
+ for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+ next_iter = iter; next_iter++;
+ AIItemList *items = &(*iter).second;
+ for (AIItemList::iterator next_iter, iter = items->begin(); iter != items->end(); iter = next_iter) {
+ if (--count < 0) return;
+ next_iter = iter; next_iter++;
+ this->RemoveItem(*iter);
+ }
+ }
+ break;
+
+ case SORT_BY_ITEM:
+ for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+ if (--count < 0) return;
+ next_iter = iter; next_iter++;
+ this->RemoveItem((*iter).first);
+ }
+ break;
+ }
+}
+
+void AIAbstractList::RemoveBottom(int32 count)
+{
+ if (!this->sort_ascending) {
+ this->Sort(this->sorter_type, !this->sort_ascending);
+ this->RemoveTop(count);
+ this->Sort(this->sorter_type, !this->sort_ascending);
+ return;
+ }
+
+ switch (this->sorter_type) {
+ default: NOT_REACHED();
+ case SORT_BY_VALUE:
+ for (AIAbstractListBucket::reverse_iterator next_iter, iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = next_iter) {
+ next_iter = iter; next_iter++;
+ AIItemList *items = &(*iter).second;
+ for (AIItemList::reverse_iterator next_iter, iter = items->rbegin(); iter != items->rend(); iter = next_iter) {
+ if (--count < 0) return;
+ next_iter = iter; next_iter++;
+ this->RemoveItem(*iter);
+ }
+ }
+
+ case SORT_BY_ITEM:
+ for (AIAbstractListMap::reverse_iterator next_iter, iter = this->items.rbegin(); iter != this->items.rend(); iter = next_iter) {
+ if (--count < 0) return;
+ next_iter = iter; next_iter++;
+ this->RemoveItem((*iter).first);
+ }
+ break;
+ }
+}
+
+void AIAbstractList::RemoveList(AIAbstractList *list)
+{
+ AIAbstractListMap *list_items = &list->items;
+ for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
+ this->RemoveItem((*iter).first);
+ }
+}
+
void AIAbstractList::KeepAboveValue(int32 value)
{
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
@@ -404,6 +489,28 @@
}
}
+void AIAbstractList::KeepTop(int32 count)
+{
+ this->RemoveBottom(this->Count() - count);
+}
+
+void AIAbstractList::KeepBottom(int32 count)
+{
+ this->RemoveTop(this->Count() - count);
+}
+
+void AIAbstractList::KeepList(AIAbstractList *list)
+{
+ AIAbstractList tmp;
+ for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+ tmp.AddItem((*iter).first);
+ tmp.SetValue((*iter).first, (*iter).second);
+ }
+
+ tmp.RemoveList(list);
+ this->RemoveList(&tmp);
+}
+
void AIAbstractList::Valuate(const AIAbstractList::Valuator &proc)
{
this->buckets.clear();
--- a/src/ai/api/ai_abstractlist.hpp Sun Jul 15 11:45:25 2007 +0000
+++ b/src/ai/api/ai_abstractlist.hpp Sun Jul 15 12:36:43 2007 +0000
@@ -15,8 +15,17 @@
* Class that creates a linked list which can keep item/value pairs.
*/
class AIAbstractList : public AIObject {
+public:
+ /** Type of sorter */
+ enum SorterType {
+ SORT_BY_VALUE = 0,
+ SORT_BY_ITEM = 1,
+ };
+
private:
AIAbstractListSorter *sorter;
+ SorterType sorter_type;
+ bool sort_ascending;
public:
typedef std::set<int32> AIItemList; ///< The list of items inside the bucket
@@ -116,18 +125,12 @@
bool SetValue(int32 item, int32 value);
/**
- * Sort this list by item-value.
+ * Sort this list by the given sorter and direction.
+ * @param sorter the type of sorter to use
* @param ascending if true, lowest value is on top, else at bottom.
* @note the current item stays at the same place.
*/
- void SortByItem(bool ascending);
-
- /**
- * Sort this list by the value of the items.
- * @param ascending if true, lowest value is on top, else at bottom.
- * @note the current item stays at the same place.
- */
- void SortByValue(bool ascending);
+ void Sort(SorterType sorter, bool ascending);
/**
* Removes all items with a higher value than 'value'.
@@ -155,6 +158,25 @@
void RemoveValue(int32 value);
/**
+ * Remove the first count items.
+ * @param count the amount of items to remove.
+ */
+ void RemoveTop(int32 count);
+
+ /**
+ * Remove the last count items.
+ * @param count the amount of items to remove.
+ */
+ void RemoveBottom(int32 count);
+
+ /**
+ * Remove everything that is in the given list from this list (same item index that is).
+ * @param list the list of items to remove.
+ * @pre list != NULL
+ */
+ void RemoveList(AIAbstractList *list);
+
+ /**
* Keep all items with a higher value than 'value'.
* @param value the value above which all items are kept.
*/
@@ -180,6 +202,25 @@
void KeepValue(int32 value);
/**
+ * Keep the first count items, i.e. remove everything except the first count items.
+ * @param count the amount of items to keep.
+ */
+ void KeepTop(int32 count);
+
+ /**
+ * Keep the last count items, i.e. remove everything except the last count items.
+ * @param count the amount of items to keep.
+ */
+ void KeepBottom(int32 count);
+
+ /**
+ * Keps everything that is in the given list from this list (same item index that is).
+ * @param list the list of items to keep.
+ * @pre list != NULL
+ */
+ void KeepList(AIAbstractList *list);
+
+ /**
* The definition how valuators should look.
*/
class Valuator {
--- a/src/ai/api/ai_abstractlist.hpp.sq Sun Jul 15 11:45:25 2007 +0000
+++ b/src/ai/api/ai_abstractlist.hpp.sq Sun Jul 15 12:36:43 2007 +0000
@@ -1,6 +1,9 @@
#include "ai_abstractlist.hpp"
namespace SQConvert {
+ /* Allow enums to be used as Squirrel parameters */
+ template <> AIAbstractList::SorterType GetParam(ForceType<AIAbstractList::SorterType>, HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAbstractList::SorterType)tmp; }
+ template <> int Return<AIAbstractList::SorterType>(HSQUIRRELVM vm, AIAbstractList::SorterType res) { sq_pushinteger(vm, (int32)res); return 1; }
/* Allow inner classes/structs to be used as Squirrel parameters */
template <> AIAbstractList::Valuator *GetParam(ForceType<AIAbstractList::Valuator *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIAbstractList::Valuator *)instance; }
template <> AIAbstractList::Valuator &GetParam(ForceType<AIAbstractList::Valuator &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList::Valuator *)instance; }
@@ -19,6 +22,9 @@
SQAIAbstractList.PreRegister(engine);
SQAIAbstractList.AddConstructor<void (AIAbstractList::*)(), 1>(engine, "x");
+ SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_VALUE, "SORT_BY_VALUE");
+ SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_ITEM, "SORT_BY_ITEM");
+
SQAIAbstractList.DefSQStaticMethod(engine, &AIAbstractList::GetClassName, "GetClassName", 1, "x");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Clear, "Clear", 1, "x");
@@ -30,16 +36,21 @@
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Count, "Count", 1, "x");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::GetValue, "GetValue", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SetValue, "SetValue", 3, "xii");
- SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SortByItem, "SortByItem", 2, "xb");
- SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SortByValue, "SortByValue", 2, "xb");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Sort, "Sort", 3, "xib");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveAboveValue, "RemoveAboveValue", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBelowValue, "RemoveBelowValue", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveValue, "RemoveValue", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveTop, "RemoveTop", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBottom, "RemoveBottom", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveList, "RemoveList", 2, "xx");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepAboveValue, "KeepAboveValue", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBelowValue, "KeepBelowValue", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBetweenValue, "KeepBetweenValue", 3, "xii");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepValue, "KeepValue", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepTop, "KeepTop", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBottom, "KeepBottom", 2, "xi");
+ SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepList, "KeepList", 2, "xx");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Valuate, "Valuate", 2, "xx");
SQAIAbstractList.PostRegister(engine);