Committed a patch by ivan_i:
- Added a command-line option to invoke wesnoth's built-in python interpreter in interactive mode. - Exposed wesnoth's random number generator to python.
This commit is contained in:
parent
c9ad39ddc1
commit
2709806eec
10 changed files with 94 additions and 16 deletions
|
@ -1,7 +1,6 @@
|
|||
#!WPY
|
||||
|
||||
import time
|
||||
import wesnoth, random
|
||||
import ai as wesnoth
|
||||
|
||||
## Copyright 2006 by Michael Schmahl
|
||||
## This code is available under the latest version of the GNU Public License.
|
||||
|
@ -282,7 +281,7 @@ class AI:
|
|||
while 1:
|
||||
|
||||
# pick a random recruit in proportion to the weights
|
||||
r = random.uniform(0,sumweights)
|
||||
r = wesnoth.get_random(0,sumweights)
|
||||
for recruit,weight in recruit_list:
|
||||
r -= weight
|
||||
if r < 0: break
|
||||
|
@ -528,8 +527,14 @@ class AI:
|
|||
|
||||
return score
|
||||
|
||||
#import time
|
||||
#st = time.time()
|
||||
|
||||
import sys
|
||||
print "Running bruteforce ai."
|
||||
print "Wesnoth", wesnoth.get_version()
|
||||
print "Python", sys.version
|
||||
|
||||
st = time.time()
|
||||
ai = AI()
|
||||
ai.recruit()
|
||||
while True:
|
||||
|
|
|
@ -161,7 +161,7 @@
|
|||
## ** Overall 25-8-0 76 10 Wins, 1 Loss (91%)
|
||||
|
||||
import time
|
||||
import wesnoth, random
|
||||
import ai as wesnoth
|
||||
|
||||
assert not restricted, "Can only be run outside of restricted environment!"
|
||||
try:
|
||||
|
@ -343,7 +343,7 @@ class AI:
|
|||
while 1:
|
||||
|
||||
# pick a random recruit in proportion to the weights
|
||||
r = random.uniform(0,sumweights)
|
||||
r = wesnoth.get_random(0,sumweights)
|
||||
for recruit,weight in recruit_list:
|
||||
r -= weight
|
||||
if r < 0: break
|
||||
|
@ -588,6 +588,11 @@ class AI:
|
|||
|
||||
return score
|
||||
|
||||
import sys
|
||||
print "Running bruteforce unsafe ai."
|
||||
print "Wesnoth", wesnoth.get_version()
|
||||
print "Python", sys.version
|
||||
|
||||
st = time.time()
|
||||
ai = AI()
|
||||
ai.recruit()
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
from __future__ import with_statement
|
||||
|
||||
import time
|
||||
import wail, random
|
||||
import wail
|
||||
import ai
|
||||
|
||||
## Copyright 2006 by Michael Schmahl
|
||||
## This code is available under the latest version of the GNU Public License.
|
||||
|
@ -289,7 +290,7 @@ class AI:
|
|||
while 1:
|
||||
|
||||
# pick a random recruit in proportion to the weights
|
||||
r = random.uniform(0,sumweights)
|
||||
r = ai.get_random(0,sumweights)
|
||||
for recruit,weight in recruit_list:
|
||||
r -= weight
|
||||
if r < 0: break
|
||||
|
@ -535,6 +536,10 @@ class AI:
|
|||
|
||||
return score
|
||||
|
||||
import sys
|
||||
print "Running bruteforce wail ai."
|
||||
print "Wesnoth", wesnoth.get_version()
|
||||
print "Python", sys.version
|
||||
|
||||
st = time.time()
|
||||
ai = AI()
|
||||
|
|
|
@ -85,7 +85,7 @@ if __name__ == "__main__":
|
|||
os.system("src/wesnoth --python-api")
|
||||
else:
|
||||
# If we are run as a python script, output the documentation to stdout.
|
||||
import wesnoth
|
||||
import ai as wesnoth
|
||||
topics = []
|
||||
myhelp("wesnoth", topics)
|
||||
output(topics, 1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import re, os, safe
|
||||
|
||||
whitelisted = [ "collections", "functools", "heapq", "math", "Queue", "random", "re", "sets", "string", "threading", "time", "wail", "wesnoth"]
|
||||
whitelisted = ["ai", "collections", "functools", "heapq", "math", "Queue", "re", "sets", "string", "threading", "time", "wail", "wesnoth"]
|
||||
rex = re.compile(r"^import\s+(.*)", re.M)
|
||||
modules = {}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
"""This is a rather simple minded example of a python AI."""
|
||||
|
||||
import wesnoth, heapq, random
|
||||
import ai as wesnoth
|
||||
import heapq
|
||||
|
||||
def pos(location):
|
||||
"""Just a helper function for printing positions in debug messages."""
|
||||
|
@ -277,7 +278,7 @@ class AI:
|
|||
v *= v * v
|
||||
total_v += v
|
||||
heapq.heappush(heap, (-v, r[0]))
|
||||
r = random.uniform(0, total_v)
|
||||
r = wesnoth.get_random(0, total_v)
|
||||
while 1:
|
||||
v, recruit = heapq.heappop(heap)
|
||||
debug("%d %d" % (r, v))
|
||||
|
@ -393,4 +394,9 @@ class AI:
|
|||
return location
|
||||
return location
|
||||
|
||||
import sys
|
||||
print "Running sample ai."
|
||||
print "Wesnoth", wesnoth.get_version()
|
||||
print "Python", sys.version
|
||||
|
||||
AI()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!WPY
|
||||
import wesnoth
|
||||
import ai as wesnoth
|
||||
|
||||
class AI:
|
||||
def __init__(self):
|
||||
|
@ -65,4 +65,4 @@ class AI:
|
|||
return location
|
||||
return location
|
||||
|
||||
AI()
|
||||
AI()
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "attack_prediction.hpp"
|
||||
#include "gamestatus.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "random.hpp"
|
||||
#include "log.hpp"
|
||||
#include "map.hpp"
|
||||
#include "menu_events.hpp"
|
||||
|
@ -1949,6 +1950,15 @@ PyObject* python_ai::wrapper_test_move(PyObject* /*self*/, PyObject* args)
|
|||
return ret;
|
||||
}
|
||||
|
||||
PyObject* python_ai::wrapper_get_random(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
int a, b, r;
|
||||
if (!PyArg_ParseTuple(args, CC("ii"), &a, &b))
|
||||
return NULL;
|
||||
r = get_random() % (b-a+1) + a;
|
||||
return Py_BuildValue(INTVALUE, r);
|
||||
}
|
||||
|
||||
static PyMethodDef wesnoth_python_methods[] = {
|
||||
MDEF("log_message", python_ai::wrapper_log_message,
|
||||
"Parameters: string\n"
|
||||
|
@ -1957,6 +1967,10 @@ static PyMethodDef wesnoth_python_methods[] = {
|
|||
"Parameters: string\n"
|
||||
"Writes a debug message to the AI log. This should be used instead of "
|
||||
"print to not clutter stdout if AI logging is disabled.")
|
||||
MDEF("get_random", python_ai::wrapper_get_random,
|
||||
"Parameters: a, b\n"
|
||||
"Returns: random number\n"
|
||||
"Get random number in the range [a, b].")
|
||||
MDEF("get_units", python_ai::wrapper_get_units,
|
||||
"Returns: units\n"
|
||||
"Returns a dictionary containing (location, unit) pairs.")
|
||||
|
@ -2057,7 +2071,7 @@ void python_ai::initialize_python()
|
|||
init_ = true;
|
||||
|
||||
Py_Initialize( );
|
||||
PyObject* module = Py_InitModule3(CC("wesnoth"), wesnoth_python_methods,
|
||||
PyObject* module = Py_InitModule3(CC("ai"), wesnoth_python_methods,
|
||||
CC("This is the wesnoth AI module. "
|
||||
"The python script will be executed once for each turn of the side with the "
|
||||
"python AI using the script."));
|
||||
|
@ -2095,6 +2109,44 @@ void python_ai::invoke(std::string name)
|
|||
Py_DECREF(globals);
|
||||
}
|
||||
|
||||
/***
|
||||
* Invoke the Wesnoth's builtin interactive Python interpreter.
|
||||
*/
|
||||
int python_ai::run_shell()
|
||||
{
|
||||
initialize_python();
|
||||
PyErr_Clear();
|
||||
PyObject* globals = PyDict_New();
|
||||
PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
|
||||
std::string python_code;
|
||||
// Inspired by Django shell command implementation.
|
||||
python_code +=
|
||||
"import sys\n"
|
||||
"sys.path.append(\"" + game_config::path + "/data/ai/python\")\n"
|
||||
"sys.path.append(\"" + game_config::path + "/data/tools/wesnoth\")\n"
|
||||
"import code\n"
|
||||
"imported_objects = {}\n"
|
||||
"try: # Try activating rlcompleter, because it's handy.\n"
|
||||
"\timport readline\n"
|
||||
"except ImportError:\n"
|
||||
"\tpass\n"
|
||||
"else:\n"
|
||||
"\timport rlcompleter\n"
|
||||
"\treadline.set_completer(rlcompleter.Completer(imported_objects).complete)\n"
|
||||
"\treadline.parse_and_bind('tab:complete')\n"
|
||||
"code.interact(local=imported_objects)\n"
|
||||
;
|
||||
PyObject *ret = PyRun_String(python_code.c_str(), Py_file_input, globals,
|
||||
globals);
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
|
||||
int cret = (int)PyInt_AsLong(ret);
|
||||
Py_XDECREF(ret);
|
||||
Py_DECREF(globals);
|
||||
return cret; //Py_Main(argc, argv);
|
||||
}
|
||||
|
||||
python_ai::python_ai(ai_interface::info& info) :
|
||||
ai_interface(info),
|
||||
exception(QUIT),
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
W(get_version);
|
||||
W(raise_user_interact);
|
||||
W(test_move);
|
||||
W(get_random);
|
||||
|
||||
static PyObject* unittype_advances_to( wesnoth_unittype* type, PyObject* args );
|
||||
static PyObject* wrapper_team_recruits( wesnoth_team* team, PyObject* args );
|
||||
|
@ -82,6 +83,7 @@ public:
|
|||
std::vector<team>& get_teams() { return get_info().teams; }
|
||||
static void initialize_python();
|
||||
static void invoke(std::string name);
|
||||
static int run_shell();
|
||||
|
||||
friend void recalculate_movemaps();
|
||||
private:
|
||||
|
|
|
@ -1804,8 +1804,11 @@ static int process_command_args(int argc, char** argv) {
|
|||
return 0;
|
||||
#ifdef HAVE_PYTHON
|
||||
} else if(val == "--python-api") {
|
||||
python_ai::invoke("documentation.py");
|
||||
python_ai::invoke("documentation");
|
||||
return 0;
|
||||
} else if(val == "--python-shell") {
|
||||
int ret = python_ai::run_shell();
|
||||
return 0;
|
||||
#endif
|
||||
} else if(val == "--config-dir") {
|
||||
if (argc <= ++arg)
|
||||
|
|
Loading…
Add table
Reference in a new issue