(svn r9603) [NoAI] -Add: added AIList(), a simple list in which you can add item/value pairs. You can sort them, walk them, and valuate them noai
authortruelight
Thu, 12 Apr 2007 11:37:24 +0000
branchnoai
changeset 9579 632263c0cf5a
parent 9578 2e05c1b002f0
child 9580 53bf5a5dda46
(svn r9603) [NoAI] -Add: added AIList(), a simple list in which you can add item/value pairs. You can sort them, walk them, and valuate them
-Add: added regression for AIList()
-Note: valuator is untested (and unfinished)
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
projects/openttd.vcproj
projects/openttd_vs80.vcproj
source.list
src/ai/ai_squirrel.cpp
src/ai/api/ai_list.cpp
src/ai/api/ai_list.hpp
--- a/bin/ai/regression/regression.nut	Wed Apr 11 20:53:58 2007 +0000
+++ b/bin/ai/regression/regression.nut	Thu Apr 12 11:37:24 2007 +0000
@@ -131,6 +131,33 @@
 	print("  GetIndustryCount():  " + industry.GetIndustryCount());
 }
 
+function Regression::List()
+{
+	local list = AIList();
+
+	print("");
+	print("--List--");
+
+	print("  IsEmpty():     " + list.IsEmpty());
+	list.AddItem(1);
+	list.AddItem(2);
+	for (local i = 1000; i < 1100; i++) {
+		list.AddItem(i);
+	}
+	list.RemoveItem(1050);
+	list.RemoveItem(1150);
+	print("  Count():       " + list.Count());
+	print("  HasItem(1050): " + list.HasItem(1050));
+	print("  HasItem(1051): " + list.HasItem(1051));
+	print("  IsEmpty():     " + list.IsEmpty());
+	print("  List Dump:");
+	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+		print("    " + i + " => " + list.GetValue(i));
+	}
+	list.Clear();
+	print("  IsEmpty():     " + list.IsEmpty());
+}
+
 function Regression::Map()
 {
 	local map = AIMap();
@@ -370,6 +397,7 @@
 	this.Company();
 	this.Industry();
 	this.Map();
+	this.List();
 	this.Road();
 	this.Sign();
 	this.Town();
--- a/bin/ai/regression/regression.txt	Wed Apr 11 20:53:58 2007 +0000
+++ b/bin/ai/regression/regression.txt	Thu Apr 12 11:37:24 2007 +0000
@@ -506,6 +506,116 @@
     DistanceSquare():    1746
     DistanceFromEdge():  16
 
+--List--
+  IsEmpty():     true
+  Count():       101
+  HasItem(1050): false
+  HasItem(1051): true
+  IsEmpty():     false
+  List Dump:
+    1 => 0
+    2 => 0
+    1000 => 0
+    1001 => 0
+    1002 => 0
+    1003 => 0
+    1004 => 0
+    1005 => 0
+    1006 => 0
+    1007 => 0
+    1008 => 0
+    1009 => 0
+    1010 => 0
+    1011 => 0
+    1012 => 0
+    1013 => 0
+    1014 => 0
+    1015 => 0
+    1016 => 0
+    1017 => 0
+    1018 => 0
+    1019 => 0
+    1020 => 0
+    1021 => 0
+    1022 => 0
+    1023 => 0
+    1024 => 0
+    1025 => 0
+    1026 => 0
+    1027 => 0
+    1028 => 0
+    1029 => 0
+    1030 => 0
+    1031 => 0
+    1032 => 0
+    1033 => 0
+    1034 => 0
+    1035 => 0
+    1036 => 0
+    1037 => 0
+    1038 => 0
+    1039 => 0
+    1040 => 0
+    1041 => 0
+    1042 => 0
+    1043 => 0
+    1044 => 0
+    1045 => 0
+    1046 => 0
+    1047 => 0
+    1048 => 0
+    1049 => 0
+    1051 => 0
+    1052 => 0
+    1053 => 0
+    1054 => 0
+    1055 => 0
+    1056 => 0
+    1057 => 0
+    1058 => 0
+    1059 => 0
+    1060 => 0
+    1061 => 0
+    1062 => 0
+    1063 => 0
+    1064 => 0
+    1065 => 0
+    1066 => 0
+    1067 => 0
+    1068 => 0
+    1069 => 0
+    1070 => 0
+    1071 => 0
+    1072 => 0
+    1073 => 0
+    1074 => 0
+    1075 => 0
+    1076 => 0
+    1077 => 0
+    1078 => 0
+    1079 => 0
+    1080 => 0
+    1081 => 0
+    1082 => 0
+    1083 => 0
+    1084 => 0
+    1085 => 0
+    1086 => 0
+    1087 => 0
+    1088 => 0
+    1089 => 0
+    1090 => 0
+    1091 => 0
+    1092 => 0
+    1093 => 0
+    1094 => 0
+    1095 => 0
+    1096 => 0
+    1097 => 0
+    1098 => 0
+    1099 => 0
+  IsEmpty():     true
+
 --Road--
   Road
     IsRoadTile():                  false
--- a/projects/openttd.vcproj	Wed Apr 11 20:53:58 2007 +0000
+++ b/projects/openttd.vcproj	Thu Apr 12 11:37:24 2007 +0000
@@ -1048,6 +1048,9 @@
 				RelativePath=".\..\src\ai\api\ai_industry.hpp">
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_list.hpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_map.hpp">
 			</File>
 			<File
@@ -1103,6 +1106,9 @@
 				RelativePath=".\..\src\ai\api\ai_industry.cpp">
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_list.cpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_map.cpp">
 			</File>
 			<File
--- a/projects/openttd_vs80.vcproj	Wed Apr 11 20:53:58 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Thu Apr 12 11:37:24 2007 +0000
@@ -1616,6 +1616,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_list.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_map.hpp"
 				>
 			</File>
@@ -1688,6 +1692,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_list.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_map.cpp"
 				>
 			</File>
--- a/source.list	Wed Apr 11 20:53:58 2007 +0000
+++ b/source.list	Thu Apr 12 11:37:24 2007 +0000
@@ -321,6 +321,7 @@
 ai/api/ai_controller.hpp
 ai/api/ai_execmode.hpp
 ai/api/ai_industry.hpp
+ai/api/ai_list.hpp
 ai/api/ai_map.hpp
 ai/api/ai_object.hpp
 ai/api/ai_order.hpp
@@ -340,6 +341,7 @@
 ai/api/ai_controller.cpp
 ai/api/ai_execmode.cpp
 ai/api/ai_industry.cpp
+ai/api/ai_list.cpp
 ai/api/ai_map.cpp
 ai/api/ai_object.cpp
 ai/api/ai_order.cpp
--- a/src/ai/ai_squirrel.cpp	Wed Apr 11 20:53:58 2007 +0000
+++ b/src/ai/ai_squirrel.cpp	Thu Apr 12 11:37:24 2007 +0000
@@ -28,6 +28,7 @@
 #include "api/ai_controller.hpp"
 #include "api/ai_execmode.hpp"
 #include "api/ai_industry.hpp"
+#include "api/ai_list.hpp"
 #include "api/ai_map.hpp"
 #include "api/ai_order.hpp"
 #include "api/ai_road.hpp"
@@ -197,6 +198,7 @@
 	SQAIControllerRegister(this->engine);
 	SQAIExecModeRegister(this->engine);
 	SQAIIndustryRegister(this->engine);
+	SQAIListRegister(this->engine);
 	SQAIMapRegister(this->engine);
 	SQAIOrderRegister(this->engine);
 	SQAIRoadRegister(this->engine);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_list.cpp	Thu Apr 12 11:37:24 2007 +0000
@@ -0,0 +1,362 @@
+/* $Id$ */
+
+/** @file ai_list.cpp Implementation of AIList */
+
+#include "ai_list.hpp"
+
+/**
+ * Base class for any AIList sorter.
+ */
+class AIListSorter {
+protected:
+	AIList *list;
+
+public:
+	/**
+	 * Virtual dtor, needed to mute warnings.
+	 */
+	virtual ~AIListSorter() { }
+
+	/**
+	 * Get the first item of the sorter.
+	 */
+	virtual int32 Begin() = 0;
+
+	/**
+	 * Get the next item of the sorter.
+	 */
+	virtual int32 Next() = 0;
+
+	/**
+	 * See if there is a next item of the sorter.
+	 */
+	virtual bool HasNext() = 0;
+};
+
+/**
+ * Sort by value, ascending.
+ */
+class AIListSorterValueAscending : public AIListSorter {
+private:
+	AIList::AIListBucket::iterator bucket_iter;
+	AIList::AIItemList *bucket_list;
+	AIList::AIItemList::iterator bucket_list_iter;
+
+public:
+	AIListSorterValueAscending(AIList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->bucket_iter = this->list->buckets.begin();
+		this->bucket_list = &(*this->bucket_iter).second;
+		this->bucket_list_iter = this->bucket_list->begin();
+		return *bucket_list_iter;
+	}
+
+	int32 Next()
+	{
+		this->bucket_list_iter++;
+		if (this->bucket_list_iter == this->bucket_list->end()) {
+			this->bucket_iter++;
+			if (this->bucket_iter == this->list->buckets.end()) return 0;
+			this->bucket_list = &(*this->bucket_iter).second;
+			this->bucket_list_iter = this->bucket_list->begin();
+		}
+		return *bucket_list_iter;
+	}
+
+	bool HasNext()
+	{
+		return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end();
+	}
+};
+
+/**
+ * Sort by value, descending.
+ */
+class AIListSorterValueDescending : public AIListSorter {
+private:
+	AIList::AIListBucket::reverse_iterator bucket_iter;
+	AIList::AIItemList *bucket_list;
+	AIList::AIItemList::reverse_iterator bucket_list_iter;
+
+public:
+	AIListSorterValueDescending(AIList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->bucket_iter = this->list->buckets.rbegin();
+		this->bucket_list = &(*this->bucket_iter).second;
+		this->bucket_list_iter = this->bucket_list->rbegin();
+		return *bucket_list_iter;
+	}
+
+	int32 Next()
+	{
+		this->bucket_list_iter++;
+		if (this->bucket_list_iter == this->bucket_list->rend()) {
+			this->bucket_iter++;
+			if (this->bucket_iter == this->list->buckets.rend()) return 0;
+			this->bucket_list = &(*this->bucket_iter).second;
+			this->bucket_list_iter = this->bucket_list->rbegin();
+		}
+		return *bucket_list_iter;
+	}
+
+	bool HasNext()
+	{
+		return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend();
+	}
+};
+
+/**
+ * Sort by item, ascending.
+ */
+class AIListSorterItemAscending : public AIListSorter {
+private:
+	AIList::AIListMap::iterator item_iter;
+
+public:
+	AIListSorterItemAscending(AIList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->item_iter = this->list->items.begin();
+		return (*this->item_iter).first;
+	}
+
+	int32 Next()
+	{
+		this->item_iter++;
+		return (*this->item_iter).first;
+	}
+
+	bool HasNext()
+	{
+		return this->item_iter != this->list->items.end();
+	}
+};
+
+/**
+ * Sort by item, descending.
+ */
+class AIListSorterItemDescending : public AIListSorter {
+private:
+	AIList::AIListMap::reverse_iterator item_iter;
+
+public:
+	AIListSorterItemDescending(AIList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->item_iter = this->list->items.rbegin();
+		return (*this->item_iter).first;
+	}
+
+	int32 Next()
+	{
+		this->item_iter++;
+		return (*this->item_iter).first;
+	}
+
+	bool HasNext()
+	{
+		return this->item_iter != this->list->items.rend();
+	}
+};
+
+
+
+AIList::AIList()
+{
+	/* Default sorter */
+	this->sorter = new AIListSorterValueAscending(this);
+}
+
+AIList::~AIList()
+{
+	delete this->sorter;
+}
+
+bool AIList::HasItem(int32 item)
+{
+	return this->items.count(item) == 1;
+}
+
+void AIList::Clear()
+{
+	this->items.clear();
+	this->buckets.clear();
+}
+
+void AIList::AddItem(int32 item)
+{
+	if (this->HasItem(item)) return;
+
+	this->items[item] = 0;
+	this->buckets[0].insert(item);
+}
+
+void AIList::RemoveItem(int32 item)
+{
+	if (!this->HasItem(item)) return;
+
+	this->buckets[this->GetValue(item)].erase(item);
+	this->items.erase(item);
+}
+
+int32 AIList::Begin()
+{
+	return this->sorter->Begin();
+}
+
+int32 AIList::Next()
+{
+	return this->sorter->Next();
+}
+
+bool AIList::IsEmpty()
+{
+	return this->items.empty();
+}
+
+bool AIList::HasNext()
+{
+	return this->sorter->HasNext();
+}
+
+int32 AIList::Count()
+{
+	return this->items.size();
+}
+
+int32 AIList::GetValue(int32 item)
+{
+	if (!this->HasItem(item)) return 0;
+
+	return this->items[item];
+}
+
+void AIList::SortByItem(bool ascending)
+{
+	delete this->sorter;
+	if (ascending) this->sorter = new AIListSorterItemAscending(this);
+	else           this->sorter = new AIListSorterItemDescending(this);
+}
+
+void AIList::SortByValue(bool ascending)
+{
+	delete this->sorter;
+	if (ascending) this->sorter = new AIListSorterValueAscending(this);
+	else           this->sorter = new AIListSorterValueDescending(this);
+}
+
+void AIList::RemoveAboveValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second > value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first > value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::RemoveBelowValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second < value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first < value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::RemoveBetweenValue(int32 start, int32 end)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
+	}
+}
+
+void AIList::RemoveValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second == value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first == value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::KeepAboveValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second <= value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first <= value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::KeepBelowValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second >= value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first >= value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::KeepBetweenValue(int32 start, int32 end)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
+	}
+}
+
+void AIList::KeepValue(int32 value)
+{
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		if ((*iter).second != value) this->items.erase(iter);
+	}
+
+	for (AIListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter++) {
+		if ((*iter).first != value) this->buckets.erase(iter);
+	}
+}
+
+void AIList::Valuate(AIList::Valuator *proc)
+{
+	this->buckets.clear();
+	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		int32 value = proc->Valuate((*iter).first);
+		(*iter).second = value;
+		this->buckets[value].insert((*iter).first);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_list.hpp	Thu Apr 12 11:37:24 2007 +0000
@@ -0,0 +1,233 @@
+/* $Id$ */
+
+/** @file ai_list.hpp a linked list which can keep item/value pairs */
+
+#ifndef AI_LIST_HPP
+#define AI_LIST_HPP
+
+#include "ai_object.hpp"
+#include <map>
+#include <set>
+
+class AIListSorter;
+
+/**
+ * Class that creates a linked list which can keep item/value pairs.
+ */
+class AIList : public AIObject {
+private:
+	AIListSorter *sorter;
+
+public:
+	typedef std::set<int32> AIItemList;
+	typedef std::map<int32, AIItemList> AIListBucket;
+	typedef std::map<int32, int32> AIListMap;
+
+	AIListMap items;           ///< The items in the list
+	AIListBucket buckets;      ///< The items in the list, sorted by value
+
+public:
+
+	/**
+	 * The name of the class, needed by several sub-processes.
+	 */
+	static const char *GetClassName() { return "AIList"; }
+
+	/**
+	 * Constructor of the AIList.
+	 */
+	AIList();
+
+	/**
+	 * Destructor of the AIList.
+	 */
+	~AIList();
+
+	/**
+	 * Clear the list, making Count() returning 0 and IsEmpty() returning true.
+	 */
+	void Clear();
+
+	/**
+	 * Add a single item to the list.
+	 * @param item the item to add. Should be unique, otherwise it is ignored.
+	 * @note the value is set to 0 by default.
+	 */
+	void AddItem(int32 item);
+
+	/**
+	 * Remove a single item from the list.
+	 * @param item the item to remove. If not existing, it is ignored.
+	 */
+	void RemoveItem(int32 item);
+
+	/**
+	 * Check if an item is in the list.
+	 * @param item the item to check for.
+	 * @return true if the item is in the list.
+	 */
+	bool HasItem(int32 item);
+
+	/**
+	 * Go to the beginning of the list.
+	 * @return the item value of the first item.
+	 */
+	int32 Begin();
+
+	/**
+	 * Go to the next item in the list.
+	 * @return the item value of the next item.
+	 * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list.
+	 */
+	int32 Next();
+
+	/**
+	 * Check if a list is empty.
+	 * @return true if the list is empty.
+	 **/
+	bool IsEmpty();
+
+	/**
+	 * Check if there is a next element. In other words, if this is true,
+	 *   Next() will return a valid item.
+	 * @return true if there is a next item.
+	 */
+	bool HasNext();
+
+	/**
+	 * Returns the amount of items in the list.
+	 * @return amount of items in the list.
+	 */
+	int32 Count();
+
+	/**
+	 * Get the value that belongs to this item.
+	 * @param item the item to get the value from
+	 * @return the value that belongs to this item.
+	 */
+	int32 GetValue(int32 item);
+
+	/**
+	 * Sort this list by item-value.
+	 * @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);
+
+	/**
+	 * Removes all items with a higher value than 'value'.
+	 * @param value the value above which all items are removed.
+	 */
+	void RemoveAboveValue(int32 value);
+
+	/**
+	 * Removes all items with a lower value than 'value'.
+	 * @param value the value below which all items are removed.
+	 */
+	void RemoveBelowValue(int32 value);
+
+	/**
+	 * Removes all items with a value above start and below end.
+	 * @param start the lower bound of the to be removed values (exclusive).
+	 * @param end   the upper bound of the to be removed valuens (exclusive).
+	 */
+	void RemoveBetweenValue(int32 start, int32 end);
+
+	/**
+	 * Remove all items with this value.
+	 * @param value the value to remove.
+	 */
+	void RemoveValue(int32 value);
+
+	/**
+	 * Keep all items with a higher value than 'value'.
+	 * @param value the value above which all items are kept.
+	 */
+	void KeepAboveValue(int32 value);
+
+	/**
+	 * Keep all items with a lower value than 'value'.
+	 * @param value the value below which all items are kept.
+	 */
+	void KeepBelowValue(int32 value);
+
+	/**
+	 * Keep all items with a value above start and below end.
+	 * @param start the lower bound of the to be kept values (exclusive).
+	 * @param end   the upper bound of the to be kept values (exclusive).
+	 */
+	void KeepBetweenValue(int32 start, int32 end);
+
+	/**
+	 * Keep all items with this value.
+	 * @param value the value to keep.
+	 **/
+	void KeepValue(int32 value);
+
+	/**
+	 * The definition how valuators should look.
+	 */
+	class Valuator {
+	public:
+		virtual ~Valuator() {}
+
+		virtual int32 Valuate(const int32 item) = 0;
+	};
+
+	/**
+	 * Give all items a value defined by the valuator you give.
+	 * @note the valuator should be a valid instance.
+	 */
+	void Valuate(AIList::Valuator *proc);
+};
+
+#ifdef DEFINE_SQUIRREL_CLASS
+namespace SQConvert {
+	/* Allow inner classes/structs to be used as Squirrel parameters */
+	template <> AIList::Valuator *GetParam(ForceType<AIList::Valuator *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIList::Valuator *)instance; }
+
+	/* Allow AIList to be used as Squirrel parameter */
+	template <> AIList *GetParam(ForceType<AIList *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIList *)instance; }
+}; // namespace SQConvert
+
+void SQAIListRegister(Squirrel *engine) {
+	DefSQClass <AIList> SQAIList("AIList");
+	SQAIList.PreRegister(engine);
+	SQAIList.AddConstructor(engine);
+
+	SQAIList.DefSQStaticMethod(engine, &AIList::GetClassName, "GetClassName", 1, "x");
+
+	SQAIList.DefSQMethod(engine, &AIList::Clear,              "Clear",              1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::AddItem,            "AddItem",            2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveItem,         "RemoveItem",         2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::HasItem,            "HasItem",            2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::Begin,              "Begin",              1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::Next,               "Next",               1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::IsEmpty,            "IsEmpty",            1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::HasNext,            "HasNext",            1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::Count,              "Count",              1, "x");
+	SQAIList.DefSQMethod(engine, &AIList::GetValue,           "GetValue",           2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::SortByItem,         "SortByItem",         2, "xb");
+	SQAIList.DefSQMethod(engine, &AIList::SortByValue,        "SortByValue",        2, "xb");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveAboveValue,   "RemoveAboveValue",   2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveBelowValue,   "RemoveBelowValue",   2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveValue,        "RemoveValue",        2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::KeepAboveValue,     "KeepAboveValue",     2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::KeepBelowValue,     "KeepBelowValue",     2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::KeepBetweenValue,   "KeepBetweenValue",   3, "xii");
+	SQAIList.DefSQMethod(engine, &AIList::KeepValue,          "KeepValue",          2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::Valuate,            "Valuate",            2, "xp");
+
+	SQAIList.PostRegister(engine);
+}
+#endif /* DEFINE_SQUIRREL_CLASS */
+
+#endif /* AI_LIST_HPP */