summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2013-04-15 21:21:29 (GMT)
committer Richard Maw <richard.maw@gmail.com>2013-04-18 20:34:52 (GMT)
commitcd10f23993eac0d581c6ead9e028d83598354b7b (patch)
tree7735b10a565eab59ffd98eb8e3c228b90f47c700
parent68c0699679368e8f4373fd3df274cc1df9389a51 (diff)
downloadhigher-lower-cd10f23993eac0d581c6ead9e028d83598354b7b.tar.bz2
Load a lua script as the strategy
This adds `-f strategy.lua` as a parameter to higher-lower, which loads the given script, passes a function to check the guess, the lower bound and the upper bound. It is expected to return the final result.
-rw-r--r--higher-lower.c64
-rw-r--r--higher-lower.lua9
2 files changed, 51 insertions, 22 deletions
diff --git a/higher-lower.c b/higher-lower.c
index e118fa9..470e3b9 100644
--- a/higher-lower.c
+++ b/higher-lower.c
@@ -12,55 +12,75 @@ static int rand_range(int min, int max){
static int call_count = 0;
static int target;
-int check_match(int guess){
+int check_match(lua_State *L){
+ int guess = lua_tointeger(L, 1);
call_count += 1;
if (guess > target) {
- return 1;
+ lua_pushinteger(L, 1);
} else if (guess < target) {
- return -1;
+ lua_pushinteger(L, -1);
} else {
- return 0;
+ lua_pushinteger(L, 0);
}
-}
-
-/* Using the given strategy and bounds, attempt to guess the hidden
- random number */
-int strategy_iterate(int (*check)(int guess), int lower, int upper){
- for (int i = lower; i <= upper; ++i){
- if (check(i) == 0){
- return i;
- }
- }
- return 0;
+ return 1;
}
/* Use processed command line arguments to generate a random number,
then delegate to a strategy to guess the number */
-int process_strategy(int min, int max){
+int process_strategy(char const *strategy, int min, int max){
int guess;
+ int exit = 0;
+ lua_State *L = luaL_newstate();
target = rand_range(min, max);
- guess = strategy_iterate(check_match, min, max);
+ if (luaL_loadfile(L, strategy)){
+ char const *errmsg = lua_tostring(L, 1);
+ fprintf(stderr, "Failed to load strategy file %s: %s\n",
+ strategy, errmsg);
+ exit = 1;
+ goto cleanup;
+ }
+
+ lua_pushcfunction(L, check_match);
+ lua_pushinteger(L, min);
+ lua_pushinteger(L, max);
+
+ if (lua_pcall(L, 3, 1, 0)){
+ char const *errmsg = lua_tostring(L, 1);
+ fprintf(stderr, "Failed to execute strategy file %s: %s\n",
+ strategy, errmsg);
+ exit = 1;
+ goto cleanup;
+ }
+
+ guess = lua_tointeger(L, 1);
if (guess != target){
fprintf(stderr, "Incorrect guess, got %d, wanted %d\n",
guess, target);
- return 1;
+ exit = 1;
+ goto cleanup;
}
printf("Guessed %d in %d attempts\n", target, call_count);
- return 0;
+cleanup:
+ lua_close(L);
+ return exit;
}
/* Process command line arguments and hand them off to process_strategy */
int main(int argc, char *argv[]){
+ char const *strategy = NULL;
int min = 0;
int max = 99;
{
int opt;
- while ((opt = getopt(argc, argv, "u:l:")) != -1) {
+ while ((opt = getopt(argc, argv, "f:u:l:")) != -1) {
switch (opt) {
+ case 'f':
+ strategy = optarg;
+ break;
case 'u':
max = atoi(optarg);
break;
@@ -69,12 +89,12 @@ int main(int argc, char *argv[]){
break;
default:
fprintf(stderr,
- "Usage: %s [-u max] [-l min]",
+ "Usage: %s [-f strategy.lua] [-u max] [-l min]",
argv[0]);
return 1;
}
}
}
- return process_strategy(min, max);
+ return process_strategy(strategy, min, max);
}
diff --git a/higher-lower.lua b/higher-lower.lua
new file mode 100644
index 0000000..470c8e0
--- a/dev/null
+++ b/higher-lower.lua
@@ -0,0 +1,9 @@
+local check, lower, upper = ...
+
+for i = lower, upper do
+ if check(i) == 0 then
+ return i
+ end
+end
+
+return 0