home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / s / sd-27.zip / sdgetout.c < prev    next >
C/C++ Source or Header  |  1992-11-23  |  48KB  |  1,063 lines

  1. /* SD -- square dance caller's helper.
  2.  
  3.     Copyright (C) 1990, 1991, 1992  William B. Ackerman.
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     This is for version 27. */
  20.  
  21. /* This defines the following functions:
  22.    resolve_p
  23.    full_resolve
  24. */
  25.  
  26. #include "sd.h"
  27.  
  28.  
  29. /* bits that we need to manipulate, segregated by word number in the personrec */
  30. #define ID_BITS_1 000000700
  31. #define ID_BITS_2 017770000
  32.  
  33.  
  34. static configuration huge_history_save[100];              /* **** for now */
  35. static int huge_history_ptr;
  36.  
  37.  
  38.  
  39.  
  40.  
  41. /* maximum number of resolves we allow the guy to ponder. */
  42. #define max_resolves 50
  43.  
  44. /* maximum number of hashes we remember to avoid duplicates.
  45.    This may be bigger because we remember hashes of things the
  46.    guy threw away, so as not to annoy him too much. */
  47. #define avoid_list_max 100
  48.  
  49. /* maximum length of anything we search for (actually the limit is 3) */
  50. #define STUPH_SIZE 5
  51.  
  52. typedef struct {
  53.    configuration stuph[STUPH_SIZE];
  54.    int size;
  55.    int insertion_point;
  56.    int permute1[8];
  57.    int permute2[8];
  58.    int rotchange;
  59.    } resolve_rec;
  60.  
  61. static int avoid_list[avoid_list_max];
  62. static int avoid_list_size;
  63. static int perm_array[8];
  64. static setup_kind goal_kind;
  65. static int goal_directions[8];
  66.  
  67. static char *title_string[] = {
  68.    "Anything: ",
  69.    "Nice setup: ",
  70.    "Resolve: ",
  71.    "Reconcile: "};
  72.  
  73.  
  74.  
  75. static void config_copy_for_buggy_compiler(configuration *a, configuration *b)
  76. {
  77.    (*b) = (*a);
  78. }
  79.  
  80.  
  81.  
  82.  
  83.  
  84. extern resolve_indicator resolve_p(setup *s)
  85.  
  86. /* Warning: heavy number-crunching ahead.  This is designed to be fast.  (Isn't everything in this program?) */
  87.  
  88. {
  89.    resolve_indicator k;
  90.  
  91.    switch (s->kind) {
  92.       case s_qtag:
  93.          switch (s->people[5].id1 & 0177) {
  94.             case 010:
  95.                if (          /* Look for dixie grand from 1/4 tag. */
  96.                      calling_level >= dixie_grand_level &&
  97.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0202 &&
  98.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0200 &&
  99.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0176 &&
  100.                      ((s->people[5].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  101.                      ((s->people[6].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  102.                      ((s->people[1].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  103.                      ((s->people[2].id1 ^ s->people[7].id1) & 0777) == 0100) {
  104.                   k.kind = resolve_dixie_grand;
  105.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 2;
  106.                   return(k);
  107.                }
  108.                break;
  109.             case 012:
  110.                if (          /* Look for RLG from 3/4 tag. */
  111.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0200 &&
  112.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0202 &&
  113.                      ((s->people[5].id1 - s->people[7].id1) & 0777) == 0200 &&
  114.                      ((s->people[3].id1 ^ s->people[2].id1) & 0777) == 0102 &&
  115.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  116.                      ((s->people[7].id1 ^ s->people[6].id1) & 0777) == 0102 &&
  117.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0100) {
  118.                   k.kind = resolve_rlg;
  119.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 4;
  120.                   return(k);
  121.                }
  122.                break;
  123.             case 001:
  124.                if (          /* Look for RLG from diamonds with points facing each other. */
  125.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0173 &&
  126.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0207 &&
  127.                      ((s->people[5].id1 - s->people[7].id1) & 0777) == 0167 &&
  128.                      ((s->people[3].id1 ^ s->people[2].id1) & 0777) == 0102 &&
  129.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  130.                      ((s->people[7].id1 ^ s->people[6].id1) & 0777) == 0102 &&
  131.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102) {
  132.                   k.kind = resolve_rlg;
  133.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 4;
  134.                   return(k);
  135.                }
  136.                break;
  137.          }
  138.          break;
  139.       case s2x4:
  140.          switch (s->people[5].id1 & 0177) {
  141.             case 010:
  142.                if (            /* Look for RLG from waves. */
  143.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  144.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0202 &&
  145.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  146.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  147.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  148.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  149.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0102) {
  150.                   k.kind = resolve_rlg;
  151.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 3;
  152.                   return(k);
  153.                }
  154.                else if (       /* Look for extend-RLG from waves. */
  155.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  156.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0202 &&
  157.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  158.                      ((s->people[5].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  159.                      ((s->people[2].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  160.                      ((s->people[1].id1 ^ s->people[7].id1) & 0777) == 0102 &&
  161.                      ((s->people[6].id1 ^ s->people[4].id1) & 0777) == 0100) {
  162.                   k.kind = resolve_ext_rlg;
  163.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 2;
  164.                   return(k);
  165.                }
  166.                else if (       /* Look for circulate-RLG from waves. */
  167.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  168.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0202 &&
  169.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  170.                      ((s->people[5].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  171.                      ((s->people[2].id1 ^ s->people[7].id1) & 0777) == 0100 &&
  172.                      ((s->people[1].id1 ^ s->people[4].id1) & 0777) == 0100 &&
  173.                      ((s->people[6].id1 ^ s->people[3].id1) & 0777) == 0100) {
  174.                   k.kind = resolve_circ_rlg;
  175.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 1;
  176.                   return(k);
  177.                }
  178.                else if (       /* Look for promenade. */
  179.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  180.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0202 &&
  181.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  182.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0100 &&
  183.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  184.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  185.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0100) {
  186.                   k.kind = resolve_prom;
  187.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 7;
  188.                   return(k);
  189.                }
  190.                break;
  191.             case 012:
  192.                if (            /* Look for LA from waves. */
  193.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  194.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0176 &&
  195.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  196.                      ((s->people[5].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  197.                      ((s->people[2].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  198.                      ((s->people[1].id1 ^ s->people[7].id1) & 0777) == 0102 &&
  199.                      ((s->people[6].id1 ^ s->people[4].id1) & 0777) == 0100) {
  200.                   k.kind = resolve_la;
  201.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 6;
  202.                   return(k);
  203.                }
  204.                else if (       /* Look for ext-LA from waves. */
  205.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  206.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0176 &&
  207.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  208.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  209.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  210.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  211.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0102) {
  212.                   k.kind = resolve_ext_la;
  213.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 7;
  214.                   return(k);
  215.                }
  216.                else if (       /* Look for circulate-LA from waves. */
  217.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  218.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0176 &&
  219.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  220.                      ((s->people[5].id1 ^ s->people[7].id1) & 0777) == 0100 &&
  221.                      ((s->people[2].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  222.                      ((s->people[1].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  223.                      ((s->people[6].id1 ^ s->people[0].id1) & 0777) == 0102) {
  224.                   k.kind = resolve_circ_la;
  225.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 0;
  226.                   return(k);
  227.                }
  228.                break;
  229.             case 01:
  230.                if (            /* Look for RLG from 8-chain. */
  231.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0202 &&
  232.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0200 &&
  233.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0176 &&
  234.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  235.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  236.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  237.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0102) {
  238.                   k.kind = resolve_rlg;
  239.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 3;
  240.                   return(k);
  241.                }
  242.                else if (       /* Look for pass-thru-RLG from 8-chain. */
  243.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0202 &&
  244.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0200 &&
  245.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0176 &&
  246.                      ((s->people[5].id1 ^ s->people[2].id1) & 0777) == 0100 &&
  247.                      ((s->people[0].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  248.                      ((s->people[1].id1 ^ s->people[6].id1) & 0777) == 0100 &&
  249.                      ((s->people[4].id1 ^ s->people[7].id1) & 0777) == 0102) {
  250.                   k.kind = resolve_pth_rlg;
  251.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 2;
  252.                   return(k);
  253.                }
  254.                break;
  255.             case 03:
  256.                if (            /* Look for LA from trade-by. */
  257.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0176 &&
  258.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0200 &&
  259.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0202 &&
  260.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  261.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  262.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  263.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0102) {
  264.                   k.kind = resolve_la;
  265.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 7;
  266.                   return(k);
  267.                }
  268.                else if (       /* Look for trade-by-LA from trade-by. */
  269.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0176 &&
  270.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0200 &&
  271.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0202 &&
  272.                      ((s->people[5].id1 ^ s->people[6].id1) & 0777) == 0102 &&
  273.                      ((s->people[4].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  274.                      ((s->people[1].id1 ^ s->people[2].id1) & 0777) == 0102 &&
  275.                      ((s->people[0].id1 ^ s->people[7].id1) & 0777) == 0100) {
  276.                   k.kind = resolve_tby_la;
  277.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 0;
  278.                   return(k);
  279.                }
  280.                else if (          /* Look for dixie grand from DPT. */
  281.                      calling_level >= dixie_grand_level &&
  282.                      ((s->people[4].id1 - s->people[5].id1) & 0777) == 0200 &&
  283.                      ((s->people[1].id1 - s->people[4].id1) & 0777) == 0176 &&
  284.                      ((s->people[0].id1 - s->people[1].id1) & 0777) == 0200 &&
  285.                      ((s->people[5].id1 ^ s->people[2].id1) & 0777) == 0100 &&
  286.                      ((s->people[4].id1 ^ s->people[7].id1) & 0777) == 0102 &&
  287.                      ((s->people[1].id1 ^ s->people[6].id1) & 0777) == 0100 &&
  288.                      ((s->people[0].id1 ^ s->people[3].id1) & 0777) == 0102) {
  289.                   k.kind = resolve_dixie_grand;
  290.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 2;
  291.                   return(k);
  292.                }
  293.                break;
  294.             case 0112:
  295.                if (            /* Look for cross-by-RLG from waves. */
  296.                      calling_level >= cross_by_level &&
  297.                      ((s->people[2].id1 - s->people[5].id1) & 0777) == 0200 &&
  298.                      ((s->people[1].id1 - s->people[2].id1) & 0777) == 0176 &&
  299.                      ((s->people[6].id1 - s->people[1].id1) & 0777) == 0200 &&
  300.                      ((s->people[4].id1 ^ s->people[2].id1) & 0777) == 0102 &&
  301.                      ((s->people[3].id1 ^ s->people[1].id1) & 0777) == 0100 &&
  302.                      ((s->people[0].id1 ^ s->people[6].id1) & 0777) == 0102 &&
  303.                      ((s->people[7].id1 ^ s->people[5].id1) & 0777) == 0100) {
  304.                   k.kind = resolve_xby_rlg;
  305.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 3;
  306.                   return(k);
  307.                }
  308.                break;
  309.             case 0110:
  310.                if (            /* Look for cross-by-LA from waves. */
  311.                      calling_level >= cross_by_level &&
  312.                      ((s->people[3].id1 - s->people[4].id1) & 0777) == 0200 &&
  313.                      ((s->people[0].id1 - s->people[3].id1) & 0777) == 0176 &&
  314.                      ((s->people[7].id1 - s->people[0].id1) & 0777) == 0200 &&
  315.                      ((s->people[4].id1 ^ s->people[5].id1) & 0777) == 0102 &&
  316.                      ((s->people[3].id1 ^ s->people[2].id1) & 0777) == 0102 &&
  317.                      ((s->people[0].id1 ^ s->people[1].id1) & 0777) == 0102 &&
  318.                      ((s->people[7].id1 ^ s->people[6].id1) & 0777) == 0102) {
  319.                   k.kind = resolve_xby_la;
  320.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 6;
  321.                   return(k);
  322.                }
  323.                break;
  324.             case 0101:
  325.                if (            /* Look for LA from 8-chain. */
  326.                      ((s->people[2].id1 - s->people[4].id1) & 0777) == 0176 &&
  327.                      ((s->people[0].id1 - s->people[2].id1) & 0777) == 0200 &&
  328.                      ((s->people[6].id1 - s->people[0].id1) & 0777) == 0202 &&
  329.                      ((s->people[4].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  330.                      ((s->people[2].id1 ^ s->people[1].id1) & 0777) == 0102 &&
  331.                      ((s->people[7].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  332.                      ((s->people[6].id1 ^ s->people[5].id1) & 0777) == 0102) {
  333.                   k.kind = resolve_la;
  334.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 7;
  335.                   return(k);
  336.                }
  337.                else if (       /* Look for pass-thru-LA from 8-chain. */
  338.                      ((s->people[2].id1 - s->people[4].id1) & 0777) == 0176 &&
  339.                      ((s->people[0].id1 - s->people[2].id1) & 0777) == 0200 &&
  340.                      ((s->people[6].id1 - s->people[0].id1) & 0777) == 0202 &&
  341.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  342.                      ((s->people[0].id1 ^ s->people[1].id1) & 0777) == 0102 &&
  343.                      ((s->people[7].id1 ^ s->people[6].id1) & 0777) == 0102 &&
  344.                      ((s->people[4].id1 ^ s->people[5].id1) & 0777) == 0102) {
  345.                   k.kind = resolve_pth_la;
  346.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 6;
  347.                   return(k);
  348.                }
  349.                break;
  350.             case 0103:
  351.                if (            /* Look for RLG from trade-by. */
  352.                      ((s->people[2].id1 - s->people[4].id1) & 0777) == 0202 &&
  353.                      ((s->people[0].id1 - s->people[2].id1) & 0777) == 0200 &&
  354.                      ((s->people[6].id1 - s->people[0].id1) & 0777) == 0176 &&
  355.                      ((s->people[4].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  356.                      ((s->people[2].id1 ^ s->people[1].id1) & 0777) == 0102 &&
  357.                      ((s->people[7].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  358.                      ((s->people[6].id1 ^ s->people[5].id1) & 0777) == 0102) {
  359.                   k.kind = resolve_rlg;
  360.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 3;
  361.                   return(k);
  362.                }
  363.                else if (       /* Look for trade-by-RLG from trade-by. */
  364.                      ((s->people[2].id1 - s->people[4].id1) & 0777) == 0202 &&
  365.                      ((s->people[0].id1 - s->people[2].id1) & 0777) == 0200 &&
  366.                      ((s->people[6].id1 - s->people[0].id1) & 0777) == 0176 &&
  367.                      ((s->people[6].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  368.                      ((s->people[4].id1 ^ s->people[1].id1) & 0777) == 0100 &&
  369.                      ((s->people[7].id1 ^ s->people[2].id1) & 0777) == 0100 &&
  370.                      ((s->people[0].id1 ^ s->people[5].id1) & 0777) == 0100) {
  371.                   k.kind = resolve_tby_rlg;
  372.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 4;
  373.                   return(k);
  374.                }
  375.                break;
  376.          }
  377.          break;
  378.       case s_crosswave:
  379.          switch (s->people[5].id1 & 0177) {
  380.             case 010:
  381.                if (            /* Look for RLG from crossed waves. */
  382.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0173 &&
  383.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0207 &&
  384.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0167 &&
  385.  
  386.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0102 &&
  387.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0102 &&
  388.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0102 &&
  389.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0102) {
  390.                   k.kind = resolve_rlg;
  391.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 2;
  392.                   return(k);
  393.                }
  394.                else if (       /* Look for promenade from crossed lines. */
  395.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0173 &&
  396.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0207 &&
  397.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0167 &&
  398.  
  399.                      ((s->people[5].id1 ^ s->people[4].id1) & 0777) == 0100 &&
  400.                      ((s->people[2].id1 ^ s->people[3].id1) & 0777) == 0100 &&
  401.                      ((s->people[1].id1 ^ s->people[0].id1) & 0777) == 0100 &&
  402.                      ((s->people[6].id1 ^ s->people[7].id1) & 0777) == 0100) {
  403.                   k.kind = resolve_prom;
  404.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 6;
  405.                   return(k);
  406.                }
  407.                break;
  408.             case 012:
  409.                if (            /* Look for LA from crossed waves. */
  410.                      ((s->people[3].id1 - s->people[5].id1) & 0777) == 0167 &&
  411.                      ((s->people[1].id1 - s->people[3].id1) & 0777) == 0207 &&
  412.                      ((s->people[7].id1 - s->people[1].id1) & 0777) == 0173 &&
  413.                      ((s->people[5].id1 ^ s->people[2].id1) & 0777) == 0111 &&
  414.                      ((s->people[3].id1 ^ s->people[0].id1) & 0777) == 0113 &&
  415.                      ((s->people[1].id1 ^ s->people[6].id1) & 0777) == 0111 &&
  416.                      ((s->people[7].id1 ^ s->people[4].id1) & 0777) == 0113) {
  417.                   k.kind = resolve_la;
  418.                   k.distance = (s->rotation << 1) + (s->people[5].id1 >> 6) + 5;
  419.                   return(k);
  420.                }
  421.                break;
  422.          }
  423.          break;
  424.    }
  425.  
  426.    k.kind = resolve_none;
  427.    return(k);
  428. }
  429.  
  430.  
  431. /* These variables are actually local to inner_search, but they are
  432.    expected to be preserved across the longjmp, so they must be static. */
  433.  
  434. static int perm_indices[8];
  435. static int attempt_count, little_count;
  436. static int hashed_random_list[5];
  437. static parse_block *inner_parse_mark, *outer_parse_mark;
  438. static int history_insertion_point;    /* Where our resolve should lie in the history.
  439.                                           This is normally the end of the history, but
  440.                                           may be earlier if doing a reconcile.  We clobber
  441.                                           everything in the given history past this point. */
  442. static int history_save;               /* Where we are inserting calls now.  This moves
  443.                                           forward as we build multiple-call resolves. */
  444.        
  445.  
  446. static long_boolean inner_search(search_kind goal, resolve_rec *new_resolve, long_boolean accept_extend, int insertion_point)
  447. {
  448.    long_boolean retval;
  449.    int i, j;
  450.    setup *ns;
  451.    real_jmp_buf my_longjmp_buffer;
  452.  
  453.    history_insertion_point = huge_history_ptr;
  454.  
  455.    if (goal == search_reconcile) {
  456.       history_insertion_point -= insertion_point;    /* strip away the extra calls */
  457.  
  458.       goal_kind = history[history_insertion_point].state.kind;
  459.       if (setup_limits[goal_kind] != 7) return(FALSE);
  460.       for (j=0; j<8; j++) goal_directions[j] = history[history_insertion_point].state.people[j].id1 & d_mask;
  461.  
  462.       for (j=0; j<8; j++) {
  463.          perm_indices[j] = -1;
  464.          for (i=0; i<8; i++)
  465.             if ((history[history_insertion_point].state.people[i].id1 & 0700) == perm_array[j]) perm_indices[j] = i;
  466.          if (perm_indices[j] < 0) return(FALSE);      /* didn't find the person???? */
  467.       }
  468.    }
  469.  
  470.    history_save = history_insertion_point;
  471.  
  472.    little_count = 0;
  473.    attempt_count = 0;
  474.    hashed_random_list[0] = 0;
  475.    not_interactive = TRUE;
  476.    /* Mark the parse block allocation, so that we throw away the garbage
  477.       created by failing attempts. */
  478.    inner_parse_mark = outer_parse_mark = mark_parse_blocks();
  479.    
  480.    /* Create a special error handler.  Any time a call fails, we will get back here. */
  481.    
  482.    longjmp_ptr = &my_longjmp_buffer;          /* point the global pointer at it. */
  483.    setjmp(my_longjmp_buffer.the_buf);
  484.    
  485.    /* This loop searches through a group of twenty single-call resolves, then a group
  486.       of twenty two-call resolves, then a group of twenty three-call resolves,
  487.       repeatedly.  Any time it finds a resolve in less than the length of the sequence
  488.       it is looking for, it of course accepts it.  Why don't we simply always search
  489.       for three call resolves and accept shorter ones that it might stumble upon?
  490.       Because this might make the program "lazy": it would settle for long resolves
  491.       rather than looking harder for short ones.  We bias it in favor of short
  492.       resolves by making it sometimes search only for short ones, refusing to look
  493.       deeper when an attempt fails.  The searches are in groups of twenty in order
  494.       to save time: once we decide to search for some two-call resolves, we re-use
  495.       the setup left by the same initial call. */
  496.    
  497.    try_again:
  498.  
  499.    /* Throw away garbage from last attempt. */
  500.    release_parse_blocks_to_mark(inner_parse_mark);
  501.    testing_fidelity = FALSE;
  502.    history_ptr = history_save;
  503.    attempt_count++;
  504.    if (attempt_count > 5000) {
  505.       /* Too many tries -- too bad. */
  506.       history_ptr = huge_history_ptr;
  507.       retval = FALSE;
  508.       goto timeout;
  509.    }
  510.  
  511.    /* Now clear any concepts if we are not on the first call of the series. */
  512.    
  513.    if (history_ptr != history_insertion_point || goal == search_reconcile)
  514.       initialize_parse();
  515.    else
  516.       (void) restore_parse_state();
  517.    
  518.    /* Generate the concepts and call. */
  519.    
  520.    hashed_randoms = hashed_random_list[history_ptr - history_insertion_point];
  521.  
  522.    /* Put in a special initial concept if needed to make a nice setup. */
  523.  
  524.    switch (goal) {
  525.       case search_nice_setup:
  526.          i = generate_random_number(4);
  527.          /* The table "nice_setup_concept" is defined in the interface file,
  528.             containing the 4 concept indices that we want. */
  529.          deposit_concept(&concept_descriptor_table[nice_setup_concept[i]]);
  530.          break;
  531.    }
  532.    
  533.    /* Select the call.  Selecting one that says "don't use in resolve" will signal and go to try_again. */
  534.    /* This may, of course, add more concepts. */
  535.    
  536.    history[history_ptr+1].warnings.bits[0] = 0;
  537.    history[history_ptr+1].warnings.bits[1] = 0;
  538.    (void) query_for_call();
  539.    
  540.    /* Do the call.  An error will signal and go to try_again. */
  541.    
  542.    toplevelmove();
  543.    
  544.    if (history[history_ptr+1].warnings.bits[0] & Warnings_That_Preclude_Searching) goto try_again;      /* We don't like certain warnings either. */
  545.    
  546.    /* See if we have already seen this sequence. */
  547.    
  548.    for (i=0; i<avoid_list_size; i++)
  549.       if (hashed_randoms == avoid_list[i]) goto try_again;
  550.    
  551.    /* The call was legal, see if it satisfies our criterion. */
  552.    
  553.    /* ***** Because of an apparent bug in the C compiler, the "switch" statement that we would
  554.       like to have used doesn't work, so we use an "if". */
  555.  
  556.    ns = &history[history_ptr+1].state;
  557.  
  558.    if (goal == search_resolve) {
  559.       /* Here we bias the search against resolves with circulates (which we
  560.          consider to be of lower quality) by only sometimes accepting them. */
  561.       if (history[history_ptr+1].resolve_flag.kind == resolve_none ||
  562.          ((attempt_count & 1)
  563.             && history[history_ptr+1].resolve_flag.kind != resolve_rlg
  564.             && history[history_ptr+1].resolve_flag.kind != resolve_ext_rlg
  565.             && history[history_ptr+1].resolve_flag.kind != resolve_la
  566.             && history[history_ptr+1].resolve_flag.kind != resolve_xby_la
  567.             && history[history_ptr+1].resolve_flag.kind != resolve_dixie_grand
  568.             && history[history_ptr+1].resolve_flag.kind != resolve_prom))
  569.          goto what_a_loss;
  570.    }
  571.    else if (goal == search_nice_setup) {
  572.       if (ns->kind != s2x4) goto what_a_loss;
  573.    }
  574.    else if (goal == search_reconcile) {
  575.       if (ns->kind != goal_kind) goto what_a_loss;
  576.       for (j=0; j<8; j++)
  577.          if ((ns->people[j].id1 & d_mask) != goal_directions[j]) goto what_a_loss;
  578.  
  579.          {        /* Need some local temporaries -- ugly in C, impossible in Pascal! */
  580.          int p0 = ns->people[perm_indices[0]].id1 & 0700;
  581.          int p1 = ns->people[perm_indices[1]].id1 & 0700;
  582.          int p2 = ns->people[perm_indices[2]].id1 & 0700;
  583.          int p3 = ns->people[perm_indices[3]].id1 & 0700;
  584.          int p4 = ns->people[perm_indices[4]].id1 & 0700;
  585.          int p5 = ns->people[perm_indices[5]].id1 & 0700;
  586.          int p6 = ns->people[perm_indices[6]].id1 & 0700;
  587.          int p7 = ns->people[perm_indices[7]].id1 & 0700;
  588.  
  589.          /* This person must be a boy. */
  590.          if (p0 & 0100) goto what_a_loss;
  591.  
  592.          p7 = (p7 - p6) & 0700;
  593.          p6 = (p6 - p5) & 0700;
  594.          p5 = (p5 - p4) & 0700;
  595.          p4 = (p4 - p3) & 0700;
  596.          p3 = (p3 - p2) & 0700;
  597.          p2 = (p2 - p1) & 0700;
  598.          p1 = (p1 - p0) & 0700;
  599.  
  600.          /* By checking that the other 7 people are all in ascending sequence from the first, we know that they
  601.             are alternating boys and girls, with partners, in ascending couple number. */
  602.          if (  (p1 == 0100) && (p2 == 0100) &&
  603.                (p3 == 0100) && (p4 == 0100) &&
  604.                (p5 == 0100) && (p6 == 0100) &&
  605.                (p7 == 0100))
  606.             ;
  607.          else if (accept_extend &&           /* check for off by 1 ==> extend */
  608.                (p1 == 0700) && (p2 == 0300) &&
  609.                (p3 == 0700) && (p4 == 0300) &&
  610.                (p5 == 0700) && (p6 == 0300) &&
  611.                (p7 == 0700))
  612.             ;
  613.          else if (accept_extend &&           /* check for off by 2 ==> circulate */
  614.                (p1 == 0500) && (p2 == 0500) &&
  615.                (p3 == 0500) && (p4 == 0500) &&
  616.                (p5 == 0500) && (p6 == 0500) &&
  617.                (p7 == 0500))
  618.             ;
  619.          else
  620.             goto what_a_loss;
  621.          }
  622.    }
  623.  
  624.    /* The call (or sequence thereof) seems to satisfy our criterion.  Just to be
  625.       sure, we have to examine all future calls, to make sure that, aside from
  626.       the permutation that gets performed, they will be executed the same way. */
  627.    
  628.    /* But first, we make the dynamic part of the parse state be a copy of what we
  629.       had, since we are repeatedly overwriting existing blocks. */
  630.  
  631.    history[history_ptr+1].command_root = copy_parse_tree(history[history_ptr+1].command_root);
  632.  
  633.  
  634.    /* Save the entire resolve, that is, the calls we inserted, and where we inserted them. */
  635.  
  636.    history_ptr++;
  637.    new_resolve->size = history_ptr - history_insertion_point;
  638.  
  639.    if (goal == search_reconcile) {
  640.       for (j=0; j<8; j++) {
  641.          new_resolve->permute1[perm_array[j] >> 6] = ns->people[perm_indices[j]].id1 & ID_BITS_1;
  642.          new_resolve->permute2[perm_array[j] >> 6] = ns->people[perm_indices[j]].id2 & ID_BITS_2;
  643.       }
  644.  
  645.       new_resolve->rotchange = ns->rotation - history[history_insertion_point].state.rotation;
  646.       new_resolve->insertion_point = insertion_point;
  647.    }
  648.    else {
  649.       new_resolve->insertion_point = 0;
  650.    }
  651.  
  652.    /* Now test the "fidelity" of the pre-existing calls after the insertion point,
  653.       to be sure they still behave the way we expect, that is, that they move the
  654.       permuted people around in the same way.  (If one of those calls uses a predicate
  655.       like "heads" or "boys" it will likely fail this test until we get around to
  656.       doing something clever.  Oh well.) */
  657.  
  658.    testing_fidelity = TRUE;
  659.  
  660.    for (j=0; j<new_resolve->insertion_point; j++) {
  661.       int k;
  662.       configuration this_state;
  663.  
  664.       /* Copy the whole thing into the history, chiefly to get the call and concepts. */
  665.       written_history_items = -1;
  666.       config_copy_for_buggy_compiler(&huge_history_save[j+huge_history_ptr+1-new_resolve->insertion_point], &history[history_ptr+1]);
  667.  
  668.       /* Now execute the call again, from the new starting configuration. */
  669.       /* This might signal and go to try_again. */
  670.       history[history_ptr+1].warnings.bits[0] = 0;
  671.       history[history_ptr+1].warnings.bits[1] = 0;
  672.       toplevelmove();
  673.  
  674.       this_state = history[history_ptr+1];
  675.       this_state.state.rotation -= new_resolve->rotchange;
  676.       canonicalize_rotation(&this_state.state);
  677.  
  678.       if (this_state.state.rotation != huge_history_save[j+huge_history_ptr+1-new_resolve->insertion_point].state.rotation)
  679.          goto try_again;
  680.       if (this_state.warnings.bits[0] != huge_history_save[j+huge_history_ptr+1-new_resolve->insertion_point].warnings.bits[0])
  681.          goto try_again;
  682.       if (this_state.warnings.bits[1] != huge_history_save[j+huge_history_ptr+1-new_resolve->insertion_point].warnings.bits[1])
  683.          goto try_again;
  684.  
  685.       for (k=0; k<=setup_limits[this_state.state.kind]; k++) {
  686.          personrec t = huge_history_save[j+huge_history_ptr+1-new_resolve->insertion_point].state.people[k];
  687.  
  688.          if (t.id1) {
  689.             if (this_state.state.people[k].id1 !=
  690.                   ((t.id1 & (~ID_BITS_1)) | new_resolve->permute1[(t.id1 & 0700) >> 6]))
  691.                goto try_again;
  692.             if (this_state.state.people[k].id2 !=
  693.                   ((t.id2 & (~ID_BITS_2)) | new_resolve->permute2[(t.id1 & 0700) >> 6]))
  694.                goto try_again;
  695.          }
  696.          else {
  697.             if (this_state.state.people[k].id1)
  698.                goto try_again;
  699.          }
  700.       }
  701.  
  702.       history_ptr++;
  703.    }
  704.  
  705.    testing_fidelity = FALSE;
  706.    
  707.    /* We win.  Really save it and exit.  History_ptr has been clobbered. */
  708.  
  709.    for (j=0; j<STUPH_SIZE; j++)
  710.       new_resolve->stuph[j] = history[j+history_insertion_point+1];
  711.    
  712.    if (avoid_list_size < avoid_list_max)
  713.       avoid_list[avoid_list_size++] = hashed_randoms;
  714.  
  715.    retval = TRUE;
  716.    goto timeout;
  717.    
  718.    what_a_loss:
  719.    
  720.    if (++little_count == 60) {
  721.       /* Revert back to beginning. */
  722.       history_save = history_insertion_point;
  723.       inner_parse_mark = outer_parse_mark;
  724.       little_count = 0;
  725.    }
  726.    else if (little_count == 20 || little_count == 40) {
  727.       /* Save current state as a base for future calls. */
  728.       history_save = history_ptr + 1;
  729.       inner_parse_mark = mark_parse_blocks();
  730.       hashed_random_list[history_save - history_insertion_point] = hashed_randoms;
  731.    }
  732.  
  733.    goto try_again;
  734.    
  735.    timeout:
  736.  
  737.    /* Restore the global error handler. */
  738.  
  739.    longjmp_ptr = &longjmp_buffer;
  740.    not_interactive = FALSE;
  741.    return(retval);
  742. }
  743.  
  744.  
  745. static int promperm[8] = {1, 0, 6, 7, 5, 4, 2, 3};
  746. static int qtagperm[8] = {1, 0, 7, 6, 5, 4, 3, 2};
  747. static int crossperm[8] = {5, 4, 3, 2, 1, 0, 7, 6};
  748. static int laperm[8] = {1, 3, 6, 0, 5, 7, 2, 4};
  749.  
  750.  
  751. extern uims_reply full_resolve(search_kind goal)
  752. {
  753.    int j, k, dirmask;
  754.    uims_reply reply;
  755.    char title[MAX_TEXT_LINE_LENGTH];
  756.    char junk[MAX_TEXT_LINE_LENGTH];
  757.    char *titleptr;
  758.    int current_resolve_index, max_resolve_index;
  759.    resolve_rec all_resolves[max_resolves];
  760.    long_boolean show_resolve;
  761.    long_boolean accept_extend = FALSE;
  762.    int current_depth = 0;
  763.    long_boolean find_another_resolve = TRUE;
  764.  
  765.    /* See if we are in a reasonable position to do the search. */
  766.  
  767.    switch (goal) {
  768.       case search_resolve:
  769.          if (history[history_ptr].state.kind != s2x4 &&
  770.                history[history_ptr].state.kind != s1x8 &&
  771.                history[history_ptr].state.kind != s_qtag)
  772.             specialfail("Not in acceptable setup for resolve.");
  773.          break;
  774.       case search_reconcile:
  775.          /* Since we are going to go back 1 call, demand we have at least 3. ***** */
  776.          if (history_ptr < 3) specialfail("Can't reconcile sequence this short.");
  777.  
  778.          /* Demand no concepts already in place. */
  779.          if (history[history_ptr+1].command_root)
  780.             specialfail("Can't do this when concepts are selected.");
  781.  
  782.          dirmask = 0;
  783.          for (k=0; k<8; k++) {
  784.             dirmask = (dirmask << 2) | (history[history_ptr].state.people[k].id1 & 3);
  785.          }
  786.  
  787.          if (history[history_ptr].state.kind == s2x4 && dirmask == 0xA00A) {
  788.             /* L2FL, looking for promenade. */
  789.             for (j=0; j<8; j++)
  790.                perm_array[j] = history[history_ptr].state.people[promperm[j]].id1 & 0700;
  791.          }
  792.          else if (history[history_ptr].state.kind == s_qtag && dirmask == 0x08A2) {
  793.             /* RQTAG, looking for RLG. */
  794.             for (j=0; j<8; j++)
  795.                perm_array[j] = history[history_ptr].state.people[qtagperm[j]].id1 & 0700;
  796.          }
  797.          else if (history[history_ptr].state.kind == s_qtag && dirmask == 0x78D2) {
  798.             /* diamonds with points facing, looking for RLG. */
  799.             for (j=0; j<8; j++)
  800.                perm_array[j] = history[history_ptr].state.people[qtagperm[j]].id1 & 0700;
  801.          }
  802.          else if (history[history_ptr].state.kind == s_crosswave && dirmask == 0x278D) {
  803.             /* crossed waves, looking for RLG. */
  804.             for (j=0; j<8; j++)
  805.                perm_array[j] = history[history_ptr].state.people[crossperm[j]].id1 & 0700;
  806.          }
  807.          else if (history[history_ptr].state.kind == s2x4 && dirmask == 0x2288) {
  808.             /* Rwave, looking for RLG, we turn on "accept_extend" to tell it
  809.                to measure couple number only approximately. */
  810.             accept_extend = TRUE;
  811.             for (j=0; j<8; j++)
  812.                perm_array[j] = history[history_ptr].state.people[promperm[j]].id1 & 0700;
  813.          }
  814.          else if (history[history_ptr].state.kind == s2x4 && dirmask == 0x8822) {
  815.             /* Lwave, looking for LA, we turn on "accept_extend" to tell it
  816.                to measure couple number only approximately. */
  817.             accept_extend = TRUE;
  818.             for (j=0; j<8; j++)
  819.                perm_array[j] = history[history_ptr].state.people[laperm[j]].id1 & 0700;
  820.          }
  821.          else
  822.             specialfail("Not in acceptable setup for reconcile.");
  823.  
  824.          current_depth = 1;
  825.          find_another_resolve = FALSE;       /* We initially don't look for resolves; we wait for the user
  826.                                                 to set the depth. */
  827.          break;
  828.       case search_anything:
  829.          break;
  830.       case search_nice_setup:
  831.          if (history[history_ptr].state.kind != s4x4)
  832.             specialfail("Sorry, can only do this in 4x4 setup.");
  833.          /* Demand no concepts already in place. */
  834.          if (history[history_ptr+1].command_root)
  835.             specialfail("Can't do this when concepts are selected.");
  836.          break;
  837.    }
  838.  
  839.    for (j=0; j<100; j++)
  840.       config_copy_for_buggy_compiler(&history[j], &huge_history_save[j]);
  841.  
  842.    huge_history_ptr = history_ptr;
  843.    save_parse_state();
  844.       
  845.    (void) (restore_parse_state());
  846.    current_resolve_index = 0;
  847.    show_resolve = TRUE;
  848.    max_resolve_index = 0;
  849.    avoid_list_size = 0;
  850.  
  851.    for (;;) {
  852.       /* We know the history is restored at this point. */
  853.       if (find_another_resolve) {
  854.          /* Put up the resolve title showing that we are searching. */
  855.  
  856.          titleptr = title;
  857.          string_copy(&titleptr, title_string[goal]);
  858.          if (max_resolve_index != 0) {
  859.             /* We have a resolve, show which one it is and let the user stare at it
  860.                while we try to create another. */
  861.             add_resolve_indices(junk, current_resolve_index, max_resolve_index);
  862.             string_copy(&titleptr, junk);
  863.             string_copy(&titleptr, " searching ...");
  864.          }
  865.          else {
  866.             string_copy(&titleptr, "searching ...");
  867.          }
  868.  
  869.          uims_update_resolve_menu(title);
  870.  
  871.          (void) restore_parse_state();
  872.    
  873.          if (inner_search(goal, &all_resolves[max_resolve_index], accept_extend, current_depth)) {
  874.             /* Search succeeded, save it. */
  875.             max_resolve_index++;
  876.             /* Make it the current one. */
  877.             current_resolve_index = max_resolve_index;
  878.  
  879.             /* Put up the resolve title showing this resolve,
  880.                but without saying "searching". */
  881.       
  882.             titleptr = title;
  883.             string_copy(&titleptr, title_string[goal]);
  884.             add_resolve_indices(junk, current_resolve_index, max_resolve_index);
  885.             string_copy(&titleptr, junk);
  886.          }
  887.          else {
  888.             /* Display the sequence with the current resolve inserted. */
  889.             /* Put up a resolve title indicating failure. */
  890.       
  891.             titleptr = title;
  892.             string_copy(&titleptr, title_string[goal]);
  893.             if (max_resolve_index != 0) {
  894.                add_resolve_indices(junk, current_resolve_index, max_resolve_index);
  895.                string_copy(&titleptr, junk);
  896.                string_copy(&titleptr, ", failed");
  897.             }
  898.             else {
  899.                /* We failed, and we don't even have an old one to show. */
  900.                string_copy(&titleptr, "failed");
  901.             }
  902.          }
  903.  
  904.          written_history_items = -1;
  905.          for (j=0; j<100; j++)
  906.             config_copy_for_buggy_compiler(&huge_history_save[j], &history[j]);
  907.  
  908.          history_ptr = huge_history_ptr;
  909.          find_another_resolve = FALSE;
  910.       }
  911.       else {
  912.          /* Just display the sequence with the current resolve inserted. */
  913.          /* Put up a neutral resolve title. */
  914.  
  915.          titleptr = title;
  916.          string_copy(&titleptr, title_string[goal]);
  917.          if ((max_resolve_index != 0) && show_resolve) {
  918.             add_resolve_indices(junk, current_resolve_index, max_resolve_index);
  919.             string_copy(&titleptr, junk);
  920.          }
  921.       }
  922.  
  923.       uims_update_resolve_menu(title);
  924.  
  925.       /* Modify the history to show the current resolve. */
  926.       /* Note that the currrent history has been restored to its saved state. */
  927.  
  928.       if ((current_resolve_index != 0) && show_resolve) {
  929.          /* Display the current resolve. */
  930.          resolve_rec *this_resolve;
  931.          configuration *this_state;
  932.  
  933.          this_resolve = &all_resolves[current_resolve_index-1];
  934.  
  935.          /* Copy the inserted calls. */
  936.          written_history_items = -1;
  937.          for (j=0; j<this_resolve->size; j++)
  938.             config_copy_for_buggy_compiler(&this_resolve->stuph[j],
  939.                            &history[j+huge_history_ptr+1-this_resolve->insertion_point]);
  940.  
  941.          /* Copy and repair the calls after the insertion. */
  942.          for (j=0; j<this_resolve->insertion_point; j++) {
  943.             this_state = &history[j+huge_history_ptr+1-this_resolve->insertion_point+this_resolve->size];
  944.             config_copy_for_buggy_compiler(&huge_history_save[j+huge_history_ptr+1-this_resolve->insertion_point], this_state);
  945.             this_state->state.rotation += this_resolve->rotchange;
  946.             canonicalize_rotation(&this_state->state);
  947.  
  948.             /* Repair this setup by permuting all the people. */
  949.  
  950.             for (k=0; k<=setup_limits[this_state->state.kind]; k++) {
  951.                personrec t = this_state->state.people[k];
  952.  
  953.                if (t.id1) {
  954.                   this_state->state.people[k].id1 = 
  955.                      (t.id1 & (~ID_BITS_1)) | this_resolve->permute1[(t.id1 & 0700) >> 6];
  956.                   this_state->state.people[k].id2 = 
  957.                      (t.id2 & (~ID_BITS_2)) | this_resolve->permute2[(t.id1 & 0700) >> 6];
  958.                }
  959.             }
  960.             
  961.             this_state->resolve_flag = resolve_p(&this_state->state);
  962.          }
  963.  
  964.          history_ptr = huge_history_ptr + this_resolve->size;
  965.  
  966.          /* Show the history up to the start of the resolve, forcing a picture on the last item. */
  967.  
  968.          display_initial_history(huge_history_ptr-this_resolve->insertion_point, 1);
  969.  
  970.          /* Show the resolve itself, without its last item. */
  971.  
  972.          for (j=huge_history_ptr-this_resolve->insertion_point+1; j<history_ptr-this_resolve->insertion_point; j++)
  973.             write_history_line(j, (char *) 0, FALSE, file_write_no);
  974.  
  975.          /* Show the last item of the resolve, with a forced picture. */
  976.          write_history_line(history_ptr-this_resolve->insertion_point, (char *) 0, TRUE, file_write_no);
  977.  
  978.          /* Show whatever comes after the resolve. */
  979.          for (j=history_ptr-this_resolve->insertion_point+1; j<=history_ptr; j++)
  980.             write_history_line(j, (char *) 0, j==history_ptr-this_resolve->insertion_point, file_write_no);
  981.       }
  982.       else if (show_resolve) {
  983.          /* We don't have any resolve to show.  Just draw the usual picture. */
  984.          display_initial_history(huge_history_ptr, 2);
  985.       }
  986.       else {
  987.          /* Don't show any resolve, because we want to display the current
  988.             insertion point.  Display what we have, with the insertion point. */
  989.          display_initial_history(huge_history_ptr-current_depth, 0);
  990.          if (current_depth) {
  991.             writestuff("------------------------------------");
  992.             newline();
  993.             for (j=huge_history_ptr-current_depth+1; j<=huge_history_ptr; j++) write_history_line(j, (char *) 0, FALSE, file_write_no);
  994.          }
  995.       }
  996.  
  997.       if (history[history_ptr].resolve_flag.kind != resolve_none) {
  998.          newline();
  999.          writestuff("     resolve is:");
  1000.          newline();
  1001.          writestuff(resolve_names[history[history_ptr].resolve_flag.kind]);
  1002.          writestuff(resolve_distances[history[history_ptr].resolve_flag.distance & 7]);
  1003.          newline();
  1004.       }
  1005.  
  1006.       show_resolve = TRUE;
  1007.       for (;;) {        /* We ignore any "undo" clicks. */
  1008.          reply = uims_get_command(mode_resolve, call_list_any, FALSE);
  1009.          if ((reply != ui_command_select) || (uims_menu_index != command_undo)) break;
  1010.       }
  1011.    
  1012.       if (reply == ui_resolve_select) {
  1013.          switch ((resolve_command_kind) uims_menu_index) {
  1014.             case resolve_command_find_another:
  1015.                if (max_resolve_index < max_resolves)
  1016.                   find_another_resolve = TRUE;             /* will get it next time around */
  1017.                break;
  1018.             case resolve_command_goto_next:
  1019.                if (current_resolve_index < max_resolve_index)
  1020.                   current_resolve_index++;
  1021.                break;
  1022.             case resolve_command_goto_previous:
  1023.                if (current_resolve_index > 1)
  1024.                   current_resolve_index--;
  1025.                break;
  1026.             case resolve_command_raise_rec_point:
  1027.                if (current_depth < huge_history_ptr-2)
  1028.                   current_depth++;
  1029.                show_resolve = FALSE;
  1030.                break;
  1031.             case resolve_command_lower_rec_point:
  1032.                if (current_depth > 0)
  1033.                   current_depth--;
  1034.                show_resolve = FALSE;
  1035.                break;
  1036.             case resolve_command_abort:
  1037.                written_history_items = -1;
  1038.                for (j=0; j<100; j++) {
  1039.                   config_copy_for_buggy_compiler(&huge_history_save[j], &history[j]);
  1040.                }
  1041.       
  1042.                history_ptr = huge_history_ptr;
  1043.                return(reply);
  1044.             default:
  1045.                /* Clicked on "accept choice", or something not on this submenu. */
  1046.                return(reply);
  1047.          }
  1048.       }
  1049.       else {
  1050.          /* Clicked on "accept choice", or something not on this submenu. */
  1051.          return(reply);
  1052.       }
  1053.  
  1054.       /* Restore history for next cycle. */
  1055.       written_history_items = -1;
  1056.       for (j=0; j<100; j++) {
  1057.             config_copy_for_buggy_compiler(&huge_history_save[j], &history[j]);
  1058.       }
  1059.  
  1060.       history_ptr = huge_history_ptr;
  1061.    }
  1062. }
  1063.