#include /* #define DEBUG 1 */ /* count3.c - example showing use of the Fril embedded foreign language * interface to play a "countdown" style game. Select 6 numbers (typically * four numbers which are less than 10 and two from {25, 50, 75, 100} and * a target number in the range 100-999, then use the six numbers at most once each to * create an expression involving +, -, * and / which evaluates to the target value. * e.g. target = 643, numbers = {1, 2, 5, 7, 25, 75} * expression = (((((5 - 1) * 75) + 25) * 2) - 7) * Mostly uses the high level interface functions. Little error checking is performed - return values from the * Fril interface functions are ignored, and * it is assumed that options arrive in the correct order. * * Author T. P. Martin March 2002 - beta release at best */ #define LOWERTARGET 100 #define UPPERTARGET 999 #define N_VALUES (sizeof(allowed_values)/sizeof(int)) #define N_NUMBERS 6 typedef int Boolean; #define false 0 #define TRUE 1 static int allowed_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100}; /* dummy function needed for embedded Fril output */ output_fn(mesg) char *mesg; { printf("%s", mesg); return (1); } /* main - loads the file "count3" and repeatedly runs * the countdown solver in Fril, reporting answers back to the * user. * Any target value outside the range 100-999 terminates the program. * This version uses the high level exec_fril call, and allows * Fril to print the result. */ main(int argc, char **argv) { char tmp[256]; char buffer[2048]; int err = 0; int values[N_NUMBERS]; Boolean status; int value; int output_fn(); int fril_ans = 1; int target=0; int i; if (initialise_fril() != 1) printf("couldn't initialise fril"); else { status = exec_fril("load count3", &output_fn); while(status) { printf("Fril Countdown demo - input a target integer in the range 100-999\n"); printf("\t and six numbers from {1, 2, 3, ..., 9, 10, 25, 50, 75, 100}\n"); printf("\t Fril will attempt to find an arithmetic expression involving those numbers\n"); printf("\t which evaluates to the target.\n\n"); printf("what is the target number? (0 to finish) "); scanf("%d", &target); if ((target < 100) || (target > 999)) /* check the value - anything outside the range stops execution */ status = false; else { printf("now enter %d numbers from the set: ", N_NUMBERS); for(i=0; i < N_VALUES; i++ ) printf("%d ", allowed_values[i]); printf("\n"); for(i=0; i < N_NUMBERS; ) { scanf("%d", &value); if (check_value(value, allowed_values, N_VALUES)) values[i++] = value; printf("accepted %d numbers, %d more required\n", i, N_NUMBERS-i); } sprintf(buffer, "?((build %d (%d %d %d %d %d %d) EXPR) (pp EXPR))", target, values[0], values[1], values[2], values[3], values[4], values[5]); printf("\nCalling fril with the query %s\n", buffer); fril_ans = exec_fril(buffer, &output_fn); while(fril_ans) { printf("\nfind another expression for %d? y/n", target); scanf("%s", tmp); fril_ans = (tmp[0] == 'y'); if(fril_ans) fril_ans = resume_fril("", &output_fn); } } } } printf("Demo finished - thank you for playing\n"); } /* check that an input value is in the set allowed * NB in the real version, there are restrictions on how many large/small values * are permitted, and no there are repeats of large numbers. */ Boolean check_value(int val, int *allowed, int array_size) { Boolean found = false; int i; for (i=0; (i