! The Adjudicate routine tries to see if there is an obvious choice, when ! faced with a list of objects (the match_list) each of which matches the ! player's specification equally well. ! ! To do this it makes use of the context (the token type being worked on). ! It counts up the number of obvious choices for the given context ! (all to do with where a candidate is, except for 6 (animate) which is to ! do with whether it is animate or not); ! ! if only one obvious choice is found, that is returned; ! ! if we are in indefinite mode (don't care which) one of the obvious choices ! is returned, or if there is no obvious choice then an unobvious one is ! made; ! ! at this stage, we work out whether the objects are distinguishable from ! each other or not: if they are all indistinguishable from each other, ! then choose one, it doesn't matter which; ! ! otherwise, 0 (meaning, unable to decide) is returned (but remember that ! the equivalence classes we've just worked out will be needed by other ! routines to clear up this mess, so we can't economise on working them ! out). ! ! Returns -1 if an error occurred ! ---------------------------------------------------------------------------- Constant SCORE__CHOOSEOBJ = 1000; Constant SCORE__IFGOOD = 500; Constant SCORE__UNCONCEALED = 100; Constant SCORE__BESTLOC = 60; Constant SCORE__NEXTBESTLOC = 40; Constant SCORE__NOTCOMPASS = 20; Constant SCORE__NOTSCENERY = 10; Constant SCORE__NOTACTOR = 5; Constant SCORE__GNA = 1; Constant SCORE__DIVISOR = 20; [ Adjudicate context i j k good_flag good_ones last n flag offset sovert; #ifdef DEBUG; if (parser_trace>=4) { print " [Adjudicating match list of size ", number_matched, " in context ", context, "^"; print " "; if (indef_mode) { print "indefinite type: "; if (indef_type & OTHER_BIT) print "other "; if (indef_type & MY_BIT) print "my "; if (indef_type & THAT_BIT) print "that "; if (indef_type & PLURAL_BIT) print "plural "; if (indef_type & LIT_BIT) print "lit "; if (indef_type & UNLIT_BIT) print "unlit "; if (indef_owner ~= 0) print "owner:", (name) indef_owner; new_line; print " number wanted: "; if (indef_wanted == 100) print "all"; else print indef_wanted; new_line; print " most likely GNAs of names: ", indef_cases, "^"; } else print "definite object^"; } #endif; j=number_matched-1; good_ones=0; last=match_list-->0; for (i=0:i<=j:i++) { n=match_list-->i; match_scores-->i = 0; good_flag = false; switch(context) { HELD_TOKEN, MULTIHELD_TOKEN: if (parent(n)==actor) good_flag = true; MULTIEXCEPT_TOKEN: if (advance_warning == -1) { good_flag = true; } else { if (n ~= advance_warning) good_flag = true; } MULTIINSIDE_TOKEN: if (advance_warning == -1) { if (parent(n) ~= actor) good_flag = true; } else { if (n in advance_warning) good_flag = true; } CREATURE_TOKEN: if (CreatureTest(n)==1) good_flag = true; default: good_flag = true; } if (good_flag) { match_scores-->i = SCORE__IFGOOD; good_ones++; last = n; } } if (good_ones==1) return last; ! If there is ambiguity about what was typed, but it definitely wasn't ! animate as required, then return anything; higher up in the parser ! a suitable error will be given. (This prevents a question being asked.) ! if (context==CREATURE_TOKEN && good_ones==0) return match_list-->0; if (indef_mode==0) indef_type=0; ScoreMatchL(context); if (number_matched == 0) return -1; if (indef_mode == 0) { ! Is there now a single highest-scoring object? i = SingleBestGuess(); if (i >= 0) { #ifdef DEBUG; if (parser_trace>=4) print " Single best-scoring object returned.]^"; #endif; return i; } } if (indef_mode==1 && indef_type & PLURAL_BIT ~= 0) { if (context ~= MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN) { etype=MULTI_PE; return -1; } i=0; offset=multiple_object-->0; sovert = -1; for (j=BestGuess():j~=-1 && i(i+offset) = j; #ifdef DEBUG; if (parser_trace>=4) print " Accepting it^"; #endif; } else { i=i; #ifdef DEBUG; if (parser_trace>=4) print " Rejecting it^"; #endif; } } if (i0 = i+offset; multi_context=context; #ifdef DEBUG; if (parser_trace>=4) print " Made multiple object of size ", i, "]^"; #endif; return 1; } for (i=0:ii=0; n=1; for (i=0:ii==0) { match_classes-->i=n++; flag=0; for (j=i+1:jj==0 && Identical(match_list-->i, match_list-->j)==1) { flag=1; match_classes-->j=match_classes-->i; } if (flag==1) match_classes-->i = 1-n; } n--; number_of_classes = n; #ifdef DEBUG; if (parser_trace>=4) { print " Grouped into ", n, " possibilities by name:^"; for (i=0:ii > 0) print " ", (The) match_list-->i, " (", match_list-->i, ") --- group ", match_classes-->i, "^"; } #endif; if (indef_mode == 0) { if (n > 1) { k = -1; for (i=0:ii > k) { k = match_scores-->i; j = match_classes-->i; j=j*j; flag = 0; } else if (match_scores-->i == k) { if ((match_classes-->i) * (match_classes-->i) ~= j) flag = 1; } } if (flag) { #ifdef DEBUG; if (parser_trace>=4) print " Unable to choose best group, so ask player.]^"; #endif; return 0; } #ifdef DEBUG; if (parser_trace>=4) print " Best choices are all from the same group.^"; #endif; } } ! When the player is really vague, or there's a single collection of ! indistinguishable objects to choose from, choose the one the player ! most recently acquired, or if the player has none of them, then ! the one most recently put where it is. if (n==1) dont_infer = true; return BestGuess(); ];