



Adjudicate (lines 3032-3267)
Back to List
Browsing parserm.h
3032 ! The Adjudicate routine tries to see if there is an obvious choice, when
3033 ! faced with a list of objects (the match_list) each of which matches the
3034 ! player's specification equally well.
3035 !
3036 ! To do this it makes use of the context (the token type being worked on).
3037 ! It counts up the number of obvious choices for the given context
3038 ! (all to do with where a candidate is, except for 6 (animate) which is to
3039 ! do with whether it is animate or not);
3040 !
3041 ! if only one obvious choice is found, that is returned;
3042 !
3043 ! if we are in indefinite mode (don't care which) one of the obvious choices
3044 ! is returned, or if there is no obvious choice then an unobvious one is
3045 ! made;
3046 !
3047 ! at this stage, we work out whether the objects are distinguishable from
3048 ! each other or not: if they are all indistinguishable from each other,
3049 ! then choose one, it doesn't matter which;
3050 !
3051 ! otherwise, 0 (meaning, unable to decide) is returned (but remember that
3052 ! the equivalence classes we've just worked out will be needed by other
3053 ! routines to clear up this mess, so we can't economise on working them
3054 ! out).
3055 !
3056 ! Returns -1 if an error occurred
3057 ! ----------------------------------------------------------------------------
3058
3059 Constant SCORE__CHOOSEOBJ = 1000;
3060 Constant SCORE__IFGOOD = 500;
3061 Constant SCORE__UNCONCEALED = 100;
3062 Constant SCORE__BESTLOC = 60;
3063 Constant SCORE__NEXTBESTLOC = 40;
3064 Constant SCORE__NOTCOMPASS = 20;
3065 Constant SCORE__NOTSCENERY = 10;
3066 Constant SCORE__NOTACTOR = 5;
3067 Constant SCORE__GNA = 1;
3068 Constant SCORE__DIVISOR = 20;
3069
3070 [ Adjudicate context i j k good_flag good_ones last n flag offset sovert;
3071 #Ifdef DEBUG;
3072 if (parser_trace >= 4) {
3073 print " [Adjudicating match list of size ", number_matched, " in context ", context, "^";
3074 print " ";
3075 if (indef_mode) {
3076 print "indefinite type: ";
3077 if (indef_type & OTHER_BIT) print "other ";
3078 if (indef_type & MY_BIT) print "my ";
3079 if (indef_type & THAT_BIT) print "that ";
3080 if (indef_type & PLURAL_BIT) print "plural ";
3081 if (indef_type & LIT_BIT) print "lit ";
3082 if (indef_type & UNLIT_BIT) print "unlit ";
3083 if (indef_owner ~= 0) print "owner:", (name) indef_owner;
3084 new_line;
3085 print " number wanted: ";
3086 if (indef_wanted == 100) print "all"; else print indef_wanted;
3087 new_line;
3088 print " most likely GNAs of names: ", indef_cases, "^";
3089 }
3090 else print "definite object^";
3091 }
3092 #Endif; ! DEBUG
3093
3094 j = number_matched-1; good_ones = 0; last = match_list-->0;
3095 for (i=0 : i<=j : i++) {
3096 n = match_list-->i;
3097 match_scores-->i = 0;
3098
3099 good_flag = false;
3100
3101 switch (context) {
3102 HELD_TOKEN, MULTIHELD_TOKEN:
3103 if (parent(n) == actor) good_flag = true;
3104 MULTIEXCEPT_TOKEN:
3105 if (advance_warning == -1) {
3106 good_flag = true;
3107 }
3108 else {
3109 if (n ~= advance_warning) good_flag = true;
3110 }
3111 MULTIINSIDE_TOKEN:
3112 if (advance_warning == -1) {
3113 if (parent(n) ~= actor) good_flag = true;
3114 }
3115 else {
3116 if (n in advance_warning) good_flag = true;
3117 }
3118 CREATURE_TOKEN:
3119 if (CreatureTest(n) == 1) good_flag = true;
3120 default:
3121 good_flag = true;
3122 }
3123
3124 if (good_flag) {
3125 match_scores-->i = SCORE__IFGOOD;
3126 good_ones++; last = n;
3127 }
3128 }
3129 if (good_ones == 1) return last;
3130
3131 ! If there is ambiguity about what was typed, but it definitely wasn't
3132 ! animate as required, then return anything; higher up in the parser
3133 ! a suitable error will be given. (This prevents a question being asked.)
3134
3135 if (context == CREATURE_TOKEN && good_ones == 0) return match_list-->0;
3136
3137 if (indef_mode == 0) indef_type=0;
3138
3139 ScoreMatchL(context);
3140 if (number_matched == 0) return -1;
3141
3142 if (indef_mode == 0) {
3143 ! Is there now a single highest-scoring object?
3144 i = SingleBestGuess();
3145 if (i >= 0) {
3146
3147 #Ifdef DEBUG;
3148 if (parser_trace >= 4) print " Single best-scoring object returned.]^";
3149 #Endif; ! DEBUG
3150 return i;
3151 }
3152 }
3153
3154 if (indef_mode == 1 && indef_type & PLURAL_BIT ~= 0) {
3155 if (context ~= MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
3156 or MULTIINSIDE_TOKEN) {
3157 etype = MULTI_PE;
3158 return -1;
3159 }
3160 i = 0; offset = multiple_object-->0; sovert = -1;
3161 for (j=BestGuess() : j~=-1 && i<indef_wanted && i+offset<63 : j=BestGuess()) {
3162 flag = 0;
3163 if (j hasnt concealed && j hasnt worn) flag = 1;
3164 if (sovert == -1) sovert = bestguess_score/SCORE__DIVISOR;
3165 else {
3166 if (indef_wanted == 100 && bestguess_score/SCORE__DIVISOR < sovert)
3167 flag = 0;
3168 }
3169 if (context == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN && parent(j) ~= actor)
3170 flag = 0;
3171 if (action_to_be == ##Take or ##Remove && parent(j) == actor)
3172 flag = 0;
3173 k = ChooseObjects(j, flag);
3174 if (k == 1)
3175 flag = 1;
3176 else {
3177 if (k == 2) flag = 0;
3178 }
3179 if (flag == 1) {
3180 i++; multiple_object-->(i+offset) = j;
3181 #Ifdef DEBUG;
3182 if (parser_trace >= 4) print " Accepting it^";
3183 #Endif; ! DEBUG
3184 }
3185 else {
3186 i = i;
3187 #Ifdef DEBUG;
3188 if (parser_trace >= 4) print " Rejecting it^";
3189 #Endif; ! DEBUG
3190 }
3191 }
3192 if (i < indef_wanted && indef_wanted < 100) {
3193 etype = TOOFEW_PE; multi_wanted = indef_wanted;
3194 multi_had=i;
3195 return -1;
3196 }
3197 multiple_object-->0 = i+offset;
3198 multi_context = context;
3199 #Ifdef DEBUG;
3200 if (parser_trace >= 4)
3201 print " Made multiple object of size ", i, "]^";
3202 #Endif; ! DEBUG
3203 return 1;
3204 }
3205
3206 for (i=0 : i<number_matched : i++) match_classes-->i = 0;
3207
3208 n = 1;
3209 for (i=0 : i<number_matched : i++)
3210 if (match_classes-->i == 0) {
3211 match_classes-->i = n++; flag = 0;
3212 for (j=i+1 : j<number_matched : j++)
3213 if (match_classes-->j == 0 && Identical(match_list-->i, match_list-->j) == 1) {
3214 flag=1;
3215 match_classes-->j = match_classes-->i;
3216 }
3217 if (flag == 1) match_classes-->i = 1-n;
3218 }
3219 n--; number_of_classes = n;
3220
3221 #Ifdef DEBUG;
3222 if (parser_trace >= 4) {
3223 print " Grouped into ", n, " possibilities by name:^";
3224 for (i=0 : i<number_matched : i++)
3225 if (match_classes-->i > 0)
3226 print " ", (The) match_list-->i, " (", match_list-->i, ") --- group ",
3227 match_classes-->i, "^";
3228 }
3229 #Endif; ! DEBUG
3230
3231 if (indef_mode == 0) {
3232 if (n > 1) {
3233 k = -1;
3234 for (i=0 : i<number_matched : i++) {
3235 if (match_scores-->i > k) {
3236 k = match_scores-->i;
3237 j = match_classes-->i; j = j*j;
3238 flag = 0;
3239 }
3240 else
3241 if (match_scores-->i == k) {
3242 if ((match_classes-->i) * (match_classes-->i) ~= j)
3243 flag = 1;
3244 }
3245 }
3246
3247 if (flag) {
3248 #Ifdef DEBUG;
3249 if (parser_trace >= 4) print " Unable to choose best group, so ask player.]^";
3250 #Endif; ! DEBUG
3251 return 0;
3252 }
3253 #Ifdef DEBUG;
3254 if (parser_trace >= 4) print " Best choices are all from the same group.^";
3255 #Endif; ! DEBUG
3256 }
3257 }
3258
3259 ! When the player is really vague, or there's a single collection of
3260 ! indistinguishable objects to choose from, choose the one the player
3261 ! most recently acquired, or if the player has none of them, then
3262 ! the one most recently put where it is.
3263
3264 if (n == 1) dont_infer = true;
3265 return BestGuess();
3266
3267 ]; ! Adjudicate
Last updated 27 February 2004. The librarian in charge of this page is Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight. Please email any comments, suggestions or corrections to cedenqs@inform-fiction.org.