Inform - Support - Source

Back to List

Inventory
Complete

Backward
Forward

Plain
Coloured
Gaudy

This code
in plain text

Browsing parserm.h

Adjudicate (lines 3032-3267)

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.