"Fossies" - the Fresh Open Source Software Archive

Member "xlockmore-5.59/modes/dilemma.c" (8 Sep 2019, 32034 Bytes) of package /linux/misc/xlockmore-5.59.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dilemma.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.58_vs_5.59.

    1 /* -*- Mode: C; tab-width: 4 -*- */
    2 /* dilemma --- Lloyd's Prisoner's Dilemma Simulation */
    3 
    4 #if 0
    5 static const char sccsid[] = "@(#)dilemma.c 5.24 2007/01/18 xlockmore";
    6 
    7 #endif
    8 
    9 /*-
   10  * Copyright (c) 1997 by David Bagley.
   11  *
   12  * Permission to use, copy, modify, and distribute this software and its
   13  * documentation for any purpose and without fee is hereby granted,
   14  * provided that the above copyright notice appear in all copies and that
   15  * both that copyright notice and this permission notice appear in
   16  * supporting documentation.
   17  *
   18  * This file is provided AS IS with no warranties of any kind.  The author
   19  * shall have no liability with respect to the infringement of copyrights,
   20  * trade secrets or any patents by this file or any part thereof.  In no
   21  * event will the author be liable for any lost revenue or profits or
   22  * other special, indirect and consequential damages.
   23  *
   24  * Revision History:
   25  * 18-Jan-2007: Added vertical option.
   26  * 01-Nov-2000: Allocation checks
   27  * 20-Oct-1997: Computing Bouts of the Prisoner's Dilemma by Alun L. Lloyd
   28  *              Scientific American Magazine June 1995
   29  *              Used voters.c as a guide.
   30  */
   31 
   32 /*-
   33  *                      Opponent's Strategy
   34  *
   35  *                      Cooperate     Defect
   36  *                     -----------------------
   37  *                    |           |           |
   38  *          Cooperate |     1     |     0     |
   39  * Player's           |           |           |
   40  * Strategy           |-----------+-----------|
   41  *                    |           |           |
   42  *          Defect    |     b     |     0     |
   43  *                    |           |           |
   44  *                     -----------------------
   45  *
   46  *                        The Payoff Matrix
   47  *
   48  * An interesting value of "b" for a 8 neighbor grid is 1.85
   49  * What does b stand for?  "bonus"?
   50  * Cells get 1 if they and their opponent cooperates.
   51  * Cells get b if they cheat and their opponent cooperates.
   52  * Cells get 0 in the 2 other cases.
   53  * If b is greater then a cell should always cheat except
   54  * they have to live with their neighbor... so on the next go around
   55  * their neighbor might not see any benefit in cooperating.
   56  * Cells add up the previous results of their neighbors
   57  * and decide if its their best strategy is to cheat or not to cheat.
   58  *
   59  * I have noticed round off errors  I have not as yet tracked them down.
   60  * Try
   61  * -bonus 1.99 -neighbors 12  -size 10
   62  * -bonus 241 -neighbors 6  -size 8
   63  * -bonus 1.71 -neighbors 4  -size 4
   64  */
   65 
   66 #ifdef STANDALONE
   67 #define MODE_dilemma
   68 #define DEFAULTS "*delay: 200000 \n" \
   69     "*batchcount: -2 \n" \
   70     "*cycles: 1000 \n" \
   71     "*size: 0 \n" \
   72     "*ncolors: 6 \n" \
   73 
   74 # define reshape_dilemma 0
   75 # define dilemma_handle_event 0
   76 #include "xlockmore.h"      /* in xscreensaver distribution */
   77 #define UNIFORM_COLORS
   78 #define BRIGHT_COLORS
   79 #define SMOOTH_COLORS
   80 #else /* STANDALONE */
   81 #include "xlock.h"      /* in xlockmore distribution */
   82 #endif /* STANDALONE */
   83 #include "automata.h"
   84 
   85 #ifdef MODE_dilemma
   86 
   87 /*-
   88  * neighbors of 0 randomizes it between 3, 4, 6, 8, 9, and 12.
   89  */
   90 #define DEF_NEIGHBORS  "0"      /* choose random value */
   91 #define DEF_BONUS  "1.85"
   92 #define DEF_CONSCIOUS  "True"
   93 #define DEF_VERTICAL "False"
   94 
   95 static int  neighbors;
   96 static float bonus;
   97 static Bool conscious;
   98 static Bool vertical;
   99 
  100 static XrmOptionDescRec opts[] =
  101 {
  102     {(char *) "-neighbors", (char *) ".dilemma.neighbors", XrmoptionSepArg, (caddr_t) NULL},
  103     {(char *) "-bonus", (char *) ".dilemma.bonus", XrmoptionSepArg, (caddr_t) NULL},
  104     {(char *) "-conscious", (char *) ".dilemma.conscious", XrmoptionNoArg, (caddr_t) "on"},
  105     {(char *) "+conscious", (char *) ".dilemma.conscious", XrmoptionNoArg, (caddr_t) "off"},
  106     {(char *) "-vertical", (char *) ".dilemma.vertical", XrmoptionNoArg, (caddr_t) "on"},
  107     {(char *) "+vertical", (char *) ".dilemma.vertical", XrmoptionNoArg, (caddr_t) "off"}
  108 };
  109 static argtype vars[] =
  110 {
  111     {(void *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int},
  112     {(void *) & bonus, (char *) "bonus", (char *) "Bonus", (char *) DEF_BONUS, t_Float},
  113     {(void *) & conscious, (char *) "conscious", (char *) "Conscious", (char *) DEF_CONSCIOUS, t_Bool},
  114     {(void *) & vertical, (char *) "vertical", (char *) "Vertical", (char *) DEF_VERTICAL, t_Bool}
  115 };
  116 static OptionStruct desc[] =
  117 {
  118     {(char *) "-neighbors num", (char *) "squares 4 or 8, hexagons 6, triangles 3, 9 or 12"},
  119     {(char *) "-bonus value", (char *) "bonus for cheating... between 1.0 and 4.0"},
  120     {(char *) "-/+conscious", (char *) "turn on/off self-awareness"},
  121     {(char *) "-/+vertical", (char *) "change orientation for hexagons and triangles"}
  122 };
  123 
  124 ENTRYPOINT ModeSpecOpt dilemma_opts =
  125 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
  126 
  127 #ifdef USE_MODULES
  128 ModStruct   dilemma_description =
  129 {"dilemma", "init_dilemma", "draw_dilemma", "release_dilemma",
  130  "refresh_dilemma", "init_dilemma", "free_dilemma", &dilemma_opts,
  131  200000, -2, 1000, 0, 64, 1.0, "",
  132  "Shows Lloyd's Prisoner's Dilemma simulation", 0, NULL};
  133 
  134 #endif
  135 
  136 /* Better bitmaps needed :) */
  137 #include "bitmaps/cooperat.xbm" /* age > 1 then blue, age = 1 then green */
  138 #include "bitmaps/defect.xbm"   /* age > 1 then red, age = 1 then yellow */
  139 
  140 #define DEFECTOR 0
  141 #define COOPERATOR 1
  142 #define COLORS 4
  143 #define BLUE (45 * MI_NPIXELS(mi) / 64)     /* COOPERATING, was cooperating */
  144 #define GREEN (23 * MI_NPIXELS(mi) / 64)    /* COOPERATING, was defecting */
  145 #define YELLOW (MI_NPIXELS(mi) / 6) /* DEFECTING, was cooperating */
  146 #define RED 0       /* DEFECTING, was defecting */
  147 #define MINDEFECT 1
  148 #define BITMAPS 2
  149 #define MINGRIDSIZE 16
  150 #define MINSIZE 10
  151 #define FACTOR 10
  152 #define NEIGHBORKINDS 2
  153 #define REDRAWSTEP 2000     /* How many cells to draw per cycle */
  154 #define ROUND_FLOAT(x,a) ((float) ((int) ((x) / (a) + 0.5)) * (a))
  155 
  156 static XImage logo[BITMAPS] =
  157 {
  158     {0, 0, 0, XYBitmap, (char *) cooperat_bits, LSBFirst, 8, LSBFirst, 8, 1},
  159     {0, 0, 0, XYBitmap, (char *) defect_bits, LSBFirst, 8, LSBFirst, 8, 1}
  160 };
  161 
  162 /* Dilemma data */
  163 
  164 /* Singly linked list */
  165 typedef struct _CellList {
  166     XPoint      pt;
  167     struct _CellList *next;
  168 } CellList;
  169 
  170 typedef struct {
  171     Bool        vertical;
  172     int         defectors;  /* portion of defectors */
  173     float       pm[2][2];   /* payoff matrix */
  174     unsigned long colors[2][2];
  175     CellList   *cellList[COLORS];
  176     char       *s, *sn; /* cell strategies */
  177     float      *payoff;
  178     int         initialized;
  179     int         xs, ys; /* Size of cooperators and defectors */
  180     int         xb, yb; /* Bitmap offset for cooperators and defectors */
  181     int         state;
  182     int         redrawing, redrawpos;
  183     int         pixelmode;
  184     int         generation;
  185     int         ncols, nrows;
  186     int         npositions;
  187     int         width, height;
  188     int         neighbors, polygon;
  189     union {
  190         XPoint      hexagon[7];
  191         XPoint      triangle[2][4];
  192     } shape;
  193 } dilemmastruct;
  194 
  195 static char plots[NEIGHBORKINDS] =
  196 {
  197     4, 8    /* Neighborhoods: 3, 6, 9 & 12 do not really work */
  198 };
  199 
  200 static dilemmastruct *dilemmas = (dilemmastruct *) NULL;
  201 static int  icon_width, icon_height;
  202 
  203 static void
  204 drawcell(ModeInfo * mi, int col, int row, unsigned long color, int bitmap,
  205         Bool firstChange)
  206 {
  207     Display    *display = MI_DISPLAY(mi);
  208     Window      window = MI_WINDOW(mi);
  209     GC          gc = MI_GC(mi);
  210     dilemmastruct *dp = &dilemmas[MI_SCREEN(mi)];
  211     unsigned long colour = (MI_NPIXELS(mi) >= COLORS) ?
  212         color : MI_WHITE_PIXEL(mi);
  213 
  214     XSetForeground(display, gc, colour);
  215     if (dp->neighbors == 6) {
  216         int ccol = 2 * col + !(row & 1), crow = 2 * row;
  217 
  218         if (dp->vertical) {
  219             dp->shape.hexagon[0].x = dp->xb + ccol * dp->xs;
  220             dp->shape.hexagon[0].y = dp->yb + crow * dp->ys;
  221         } else {
  222             dp->shape.hexagon[0].y = dp->xb + ccol * dp->xs;
  223             dp->shape.hexagon[0].x = dp->yb + crow * dp->ys;
  224         }
  225         if (dp->xs == 1 && dp->ys == 1)
  226             XDrawPoint(display, window, gc,
  227                 dp->shape.hexagon[0].x,
  228                 dp->shape.hexagon[0].y);
  229         else if (bitmap == BITMAPS - 1)
  230             XFillPolygon(display, window, gc,
  231                 dp->shape.hexagon, 6,
  232                 Convex, CoordModePrevious);
  233         else {
  234             int ix = 0, iy = 0, sx, sy;
  235 
  236             if (firstChange) {
  237                 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
  238                 XFillPolygon(display, window, gc,
  239                     dp->shape.hexagon, 6,
  240                     Convex, CoordModePrevious);
  241                 XSetForeground(display, gc, colour);
  242             }
  243             if (dp->vertical) {
  244                 dp->shape.hexagon[0].x -= dp->xs;
  245                 dp->shape.hexagon[0].y += dp->ys / 4;
  246                 sx = 2 * dp->xs - 6;
  247                 sy = 2 * dp->ys - 2;
  248                 if (dp->xs <= 6 || dp->ys <= 2) {
  249                     ix = 3;
  250                     iy = 1;
  251                 } else
  252                     ix = 5;
  253             } else {
  254                 dp->shape.hexagon[0].y -= dp->xs;
  255                 dp->shape.hexagon[0].x += dp->ys / 4;
  256                 sy = 2 * dp->xs - 6;
  257                 sx = 2 * dp->ys - 2;
  258                 if (dp->xs <= 6 || dp->ys <= 2) {
  259                     iy = 3;
  260                     ix = 1;
  261                 } else
  262                     iy = 5;
  263             }
  264             if (dp->xs <= 6 || dp->ys <= 2)
  265                 XFillRectangle(display, window, gc,
  266                     dp->shape.hexagon[0].x + ix,
  267                     dp->shape.hexagon[0].y + iy,
  268                     dp->xs, dp->ys);
  269             else
  270                 XFillArc(display, window, gc,
  271                     dp->shape.hexagon[0].x + ix,
  272                     dp->shape.hexagon[0].y + iy,
  273                     sx, sy,
  274                     0, 23040);
  275         }
  276     } else if (dp->neighbors == 4 || dp->neighbors == 8) {
  277         if (dp->pixelmode) {
  278             if (bitmap == BITMAPS - 1 || (dp->xs <= 2 || dp->ys <= 2))
  279                 XFillRectangle(display, window, gc,
  280                     dp->xb + dp->xs * col,
  281                     dp->yb + dp->ys * row,
  282                     dp->xs - (dp->xs > 3),
  283                     dp->ys - (dp->ys > 3));
  284             else {
  285                 if (firstChange) {
  286                     XSetForeground(display, gc,
  287                         MI_BLACK_PIXEL(mi));
  288                     XFillRectangle(display, window, gc,
  289                         dp->xb + dp->xs * col,
  290                         dp->yb + dp->ys * row,
  291                         dp->xs, dp->ys);
  292                     XSetForeground(display, gc, colour);
  293                 }
  294                 XFillArc(display, window, gc,
  295                     dp->xb + dp->xs * col,
  296                     dp->yb + dp->ys * row,
  297                     dp->xs - 1, dp->ys - 1,
  298                     0, 23040);
  299             }
  300         } else
  301             (void) XPutImage(display, window, gc,
  302                 &logo[bitmap], 0, 0,
  303                 dp->xb + dp->xs * col, dp->yb + dp->ys * row,
  304                 icon_width, icon_height);
  305     } else {        /* TRI */
  306         int orient = (col + row) % 2;   /* O left 1 right */
  307         Bool small = (dp->xs <= 3 || dp->ys <= 3);
  308         int ix = 0, iy = 0;
  309 
  310         if (dp->vertical) {
  311             dp->shape.triangle[orient][0].x = dp->xb + col * dp->xs;
  312             dp->shape.triangle[orient][0].y = dp->yb + row * dp->ys;
  313             if (small)
  314                 dp->shape.triangle[orient][0].x +=
  315                     ((orient) ? -1 : 1);
  316             else
  317                 dp->shape.triangle[orient][0].x +=
  318                     (dp->xs / 2  - 1) * ((orient) ? 1 : -1);
  319             ix = ((orient) ? -dp->xs / 2 : dp->xs / 2);
  320         } else {
  321             dp->shape.triangle[orient][0].y = dp->xb + col * dp->xs;
  322             dp->shape.triangle[orient][0].x = dp->yb + row * dp->ys;
  323             if (small)
  324                 dp->shape.triangle[orient][0].y +=
  325                     ((orient) ? -1 : 1);
  326             else
  327                 dp->shape.triangle[orient][0].y +=
  328                     (dp->xs / 2  - 1) * ((orient) ? 1 : -1);
  329             iy = ((orient) ? -dp->xs / 2 : dp->xs / 2);
  330         }
  331         if (small)
  332             XDrawPoint(display, window, gc,
  333                 dp->shape.triangle[orient][0].x,
  334                 dp->shape.triangle[orient][0].y);
  335         else {
  336             if (bitmap == BITMAPS - 1) {
  337                 XFillPolygon(display, window, gc,
  338                     dp->shape.triangle[orient], 3,
  339                     Convex, CoordModePrevious);
  340                 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
  341                 XDrawLines(display, window, gc,
  342                     dp->shape.triangle[orient], 4,
  343                     CoordModePrevious);
  344             } else {
  345                 if (firstChange) {
  346                     XSetForeground(display, gc,
  347                         MI_BLACK_PIXEL(mi));
  348                     XFillPolygon(display, window, gc,
  349                         dp->shape.triangle[orient], 3,
  350                         Convex, CoordModePrevious);
  351                     XSetForeground(display, gc, colour);
  352                 }
  353                 if (dp->vertical) {
  354                     dp->shape.triangle[orient][0].x += -4 * dp->xs / 5 +
  355                         ((orient) ? dp->xs / 3 : 3 * dp->xs / 5);
  356                     dp->shape.triangle[orient][0].y += -dp->ys / 2 + 1;
  357                     ix = ((orient) ? -dp->xs / 2 : dp->xs / 2);
  358                 } else {
  359                     dp->shape.triangle[orient][0].y += -4 * dp->xs / 5 +
  360                         ((orient) ? dp->xs / 3 : 3 * dp->xs / 5);
  361                     dp->shape.triangle[orient][0].x += -dp->ys / 2 + 1;
  362                     iy = ((orient) ? -dp->xs / 2 : dp->xs / 2);
  363                 }
  364                 XFillArc(display, window, gc,
  365                     dp->shape.triangle[orient][0].x + ix,
  366                     dp->shape.triangle[orient][0].y + iy,
  367                     dp->ys - 3, dp->ys - 3,
  368                     0, 23040);
  369             }
  370         }
  371     }
  372 }
  373 
  374 static void
  375 addtolist(ModeInfo * mi, int col, int row, int state)
  376 {
  377     dilemmastruct *dp = &dilemmas[MI_SCREEN(mi)];
  378     CellList   *current;
  379 
  380     current = dp->cellList[state];
  381     dp->cellList[state] = (CellList *) malloc(sizeof (CellList));
  382     dp->cellList[state]->pt.x = col;
  383     dp->cellList[state]->pt.y = row;
  384     dp->cellList[state]->next = current;
  385 }
  386 
  387 #ifdef DEBUG
  388 static void
  389 print_state(ModeInfo * mi, int state)
  390 {
  391     dilemmastruct *dp = &dilemmas[MI_SCREEN(mi)];
  392     CellList   *locallist;
  393     int         i = 0;
  394 
  395     locallist = dp->cellList[state];
  396     (void) printf("state %d\n", state);
  397     while (locallist) {
  398         (void) printf("%d x %d, y %d\n", i,
  399                   locallist->pt.x, locallist->pt.y);
  400         locallist = locallist->next;
  401         i++;
  402     }
  403 }
  404 
  405 #endif
  406 
  407 static void
  408 free_state(dilemmastruct * dp, int state)
  409 {
  410     CellList   *current;
  411 
  412     while (dp->cellList[state]) {
  413         current = dp->cellList[state];
  414         dp->cellList[state] = dp->cellList[state]->next;
  415         free(current);
  416     }
  417     dp->cellList[state] = (CellList *) NULL;
  418 }
  419 
  420 
  421 static void
  422 free_list(dilemmastruct * dp)
  423 {
  424     int         state;
  425 
  426     for (state = 0; state < COLORS; state++)
  427         free_state(dp, state);
  428 }
  429 
  430 static void
  431 free_dilemma_screen(dilemmastruct *dp)
  432 {
  433     if (dp == NULL) {
  434         return;
  435     }
  436     free_list(dp);
  437     if (dp->sn != NULL) {
  438         free(dp->sn);
  439         dp->sn = (char *) NULL;
  440     }
  441     if (dp->s != NULL) {
  442         free(dp->s);
  443         dp->s = (char *) NULL;
  444     }
  445     if (dp->payoff != NULL) {
  446         free(dp->payoff);
  447         dp->payoff = (float *) NULL;
  448     }
  449     dp = NULL;
  450 }
  451 
  452 ENTRYPOINT void
  453 free_dilemma(ModeInfo * mi)
  454 {
  455     free_dilemma_screen(&dilemmas[MI_SCREEN(mi)]);
  456 }
  457 
  458 static void
  459 alloc_dilemma(dilemmastruct *dp)
  460 {
  461     if ((dp->s = (char *) calloc(dp->npositions, sizeof (char))) == NULL) {
  462         free_dilemma_screen(dp);
  463         return;
  464     }
  465     if ((dp->sn = (char *) calloc(dp->npositions, sizeof (char))) == NULL) {
  466         free_dilemma_screen(dp);
  467         return;
  468     }
  469     if ((dp->payoff = (float *) calloc(dp->npositions,
  470             sizeof (float))) == NULL) {
  471         free_dilemma_screen(dp);
  472         return;
  473     }
  474 }
  475 
  476 
  477 static int
  478 positionOfNeighbor(dilemmastruct * dp, int n, int col, int row)
  479 {
  480     int dir = n * (360 / dp->neighbors);
  481 
  482     if (dp->polygon == 4 || dp->polygon == 6) {
  483         switch (dir) {
  484         case 0:
  485             col = (col + 1 == dp->ncols) ? 0 : col + 1;
  486             break;
  487         case 45:
  488             col = (col + 1 == dp->ncols) ? 0 : col + 1;
  489             row = (!row) ? dp->nrows - 1 : row - 1;
  490             break;
  491         case 60:
  492             if (!(row & 1))
  493                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  494             row = (!row) ? dp->nrows - 1 : row - 1;
  495             break;
  496         case 90:
  497             row = (!row) ? dp->nrows - 1 : row - 1;
  498             break;
  499         case 120:
  500             if (row & 1)
  501                 col = (!col) ? dp->ncols - 1 : col - 1;
  502             row = (!row) ? dp->nrows - 1 : row - 1;
  503             break;
  504         case 135:
  505             col = (!col) ? dp->ncols - 1 : col - 1;
  506             row = (!row) ? dp->nrows - 1 : row - 1;
  507             break;
  508         case 180:
  509             col = (!col) ? dp->ncols - 1 : col - 1;
  510             break;
  511         case 225:
  512             col = (!col) ? dp->ncols - 1 : col - 1;
  513             row = (row + 1 == dp->nrows) ? 0 : row + 1;
  514             break;
  515         case 240:
  516             if (row & 1)
  517                 col = (!col) ? dp->ncols - 1 : col - 1;
  518             row = (row + 1 == dp->nrows) ? 0 : row + 1;
  519             break;
  520         case 270:
  521             row = (row + 1 == dp->nrows) ? 0 : row + 1;
  522             break;
  523         case 300:
  524             if (!(row & 1))
  525                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  526             row = (row + 1 == dp->nrows) ? 0 : row + 1;
  527             break;
  528         case 315:
  529             col = (col + 1 == dp->ncols) ? 0 : col + 1;
  530             row = (row + 1 == dp->nrows) ? 0 : row + 1;
  531             break;
  532         default:
  533             (void) fprintf(stderr, "wrong direction %d\n", dir);
  534         }
  535     } else if (dp->polygon == 3) {
  536         if ((col + row) & 1) {  /* right */
  537             switch (dir) {
  538             case 0:
  539                 col = (!col) ? dp->ncols - 1 : col - 1;
  540                 break;
  541             case 30:
  542             case 40:
  543                 col = (!col) ? dp->ncols - 1 : col - 1;
  544                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  545                 break;
  546             case 60:
  547                 col = (!col) ? dp->ncols - 1 : col - 1;
  548                 if (row + 1 == dp->nrows)
  549                     row = 1;
  550                 else if (row + 2 == dp->nrows)
  551                     row = 0;
  552                 else
  553                     row = row + 2;
  554                 break;
  555             case 80:
  556             case 90:
  557                 if (row + 1 == dp->nrows)
  558                     row = 1;
  559                 else if (row + 2 == dp->nrows)
  560                     row = 0;
  561                 else
  562                     row = row + 2;
  563                 break;
  564             case 120:
  565                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  566                 break;
  567             case 150:
  568             case 160:
  569                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  570                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  571                 break;
  572             case 180:
  573                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  574                 break;
  575             case 200:
  576             case 210:
  577                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  578                 row = (!row) ? dp->nrows - 1 : row - 1;
  579                 break;
  580             case 240:
  581                 row = (!row) ? dp->nrows - 1 : row - 1;
  582                 break;
  583             case 270:
  584             case 280:
  585                 if (!row)
  586                     row = dp->nrows - 2;
  587                 else if (!(row - 1))
  588                     row = dp->nrows - 1;
  589                 else
  590                     row = row - 2;
  591                 break;
  592             case 300:
  593                 col = (!col) ? dp->ncols - 1 : col - 1;
  594                 if (!row)
  595                     row = dp->nrows - 2;
  596                 else if (!(row - 1))
  597                     row = dp->nrows - 1;
  598                 else
  599                     row = row - 2;
  600                 break;
  601             case 320:
  602             case 330:
  603                 col = (!col) ? dp->ncols - 1 : col - 1;
  604                 row = (!row) ? dp->nrows - 1 : row - 1;
  605                 break;
  606             default:
  607                 (void) fprintf(stderr, "wrong direction %d\n",
  608                     dir);
  609             }
  610         } else {    /* left */
  611             switch (dir) {
  612             case 0:
  613                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  614                 break;
  615             case 30:
  616             case 40:
  617                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  618                 row = (!row) ? dp->nrows - 1 : row - 1;
  619                 break;
  620             case 60:
  621                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  622                 if (!row)
  623                     row = dp->nrows - 2;
  624                 else if (row == 1)
  625                     row = dp->nrows - 1;
  626                 else
  627                     row = row - 2;
  628                 break;
  629             case 80:
  630             case 90:
  631                 if (!row)
  632                     row = dp->nrows - 2;
  633                 else if (row == 1)
  634                     row = dp->nrows - 1;
  635                 else
  636                     row = row - 2;
  637                 break;
  638             case 120:
  639                 row = (!row) ? dp->nrows - 1 : row - 1;
  640                 break;
  641             case 150:
  642             case 160:
  643                 col = (!col) ? dp->ncols - 1 : col - 1;
  644                 row = (!row) ? dp->nrows - 1 : row - 1;
  645                 break;
  646             case 180:
  647                 col = (!col) ? dp->ncols - 1 : col - 1;
  648                 break;
  649             case 200:
  650             case 210:
  651                 col = (!col) ? dp->ncols - 1 : col - 1;
  652                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  653                 break;
  654             case 240:
  655                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  656                 break;
  657             case 270:
  658             case 280:
  659                 if (row + 1 == dp->nrows)
  660                     row = 1;
  661                 else if (row + 2 == dp->nrows)
  662                     row = 0;
  663                 else
  664                     row = row + 2;
  665                 break;
  666             case 300:
  667                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  668                 if (row + 1 == dp->nrows)
  669                     row = 1;
  670                 else if (row + 2 == dp->nrows)
  671                     row = 0;
  672                 else
  673                     row = row + 2;
  674                 break;
  675             case 320:
  676             case 330:
  677                 col = (col + 1 == dp->ncols) ? 0 : col + 1;
  678                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  679                 break;
  680             default:
  681                 (void) fprintf(stderr, "wrong direction %d\n",
  682                     dir);
  683             }
  684         }
  685 #if 0
  686     } else {
  687         int orient = ((row & 1) * 2 + col) % 4;
  688         switch (orient) { /* up, down, left, right */
  689         case 0:
  690             switch (dir) {
  691             case 0:
  692                 col++;
  693                 break;
  694             case 51: /* 7 */
  695             case 72: /* 5 */
  696                 col = (col + 2 >= dp->ncols) ? 0 : col + 2;
  697                 break;
  698             case 102: /* 7 corner */
  699                 col = (col + 3 >= dp->ncols) ? 1 : col + 3;
  700                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  701                 break;
  702             case 144: /* 5 */
  703             case 153: /* 7 */
  704                 col++;
  705                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  706                 break;
  707             case 204: /* 7 */
  708             case 216: /* 5 */
  709                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  710                 break;
  711             case 255: /* 7 */
  712                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  713                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  714                 break;
  715             case 288: /* 5 */
  716             case 306: /* 7 */
  717                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  718                 break;
  719             default:
  720                 (void) fprintf(stderr, "wrong direction %d\n",
  721                     dir);
  722             }
  723             break;
  724         case 1:
  725             switch (dir) {
  726             case 0:
  727                 col--;
  728                 break;
  729             case 51: /* 7 */
  730             case 72: /* 5 */
  731                 col = (col == 1) ? dp->ncols - 1 : col - 2;
  732                 break;
  733             case 102: /* 7 */
  734                 col = (col == 1) ? dp->ncols - 2 : col - 3;
  735                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  736                 break;
  737             case 144: /* 5 */
  738             case 153: /* 7 */
  739                 col--;
  740                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  741                 break;
  742             case 204: /* 7 */
  743             case 216: /* 5 */
  744                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  745                 break;
  746             case 255: /* 7 */
  747                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  748                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  749                 break;
  750             case 288: /* 5 */
  751             case 306: /* 7 */
  752                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  753                 break;
  754             default:
  755                 (void) fprintf(stderr, "wrong direction %d\n",
  756                     dir);
  757             }
  758             break;
  759         case 2:
  760             switch (dir) {
  761             case 0:
  762                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  763                 break;
  764             case 51: /* 7 */
  765             case 72: /* 5 */
  766                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  767                 col++;
  768                 break;
  769             case 102: /* 7 */
  770                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  771                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  772                 break;
  773             case 144: /* 5 */
  774             case 153: /* 7 */
  775                 col = (col == 0) ? dp->ncols - 2 : col - 2;
  776                 break;
  777             case 204: /* 7 */
  778             case 216: /* 5 */
  779                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  780                 break;
  781             case 255: /* 7 */
  782                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  783                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  784                 break;
  785             case 288: /* 5 */
  786             case 306: /* 7 */
  787                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  788                 break;
  789             default:
  790                 (void) fprintf(stderr, "wrong direction %d\n",
  791                     dir);
  792             }
  793             break;
  794         case 3:
  795             switch (dir) {
  796             case 0:
  797                 col--;
  798                 break;
  799             case 51: /* 7 */
  800             case 72: /* 5 */
  801                 col = (col == 0) ? dp->ncols - 1 : col - 1;
  802                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  803                 break;
  804             case 102: /* 7 */
  805                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  806                 row = (row + 1 == dp->nrows) ? 0 : row + 1;
  807                 break;
  808             case 144: /* 5 */
  809             case 153: /* 7 */
  810                 col = (col + 2 >= dp->ncols) ? 1 : col + 2;
  811                 break;
  812             case 204: /* 7 */
  813             case 216: /* 5 */
  814                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  815                 break;
  816             case 255: /* 7 */
  817                 col = (col + 1 >= dp->ncols) ? 0 : col + 1;
  818                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  819                 break;
  820             case 288: /* 5 */
  821             case 306: /* 7 */
  822                 row = (row == 0) ? dp->nrows - 1 : row - 1;
  823                 break;
  824             default:
  825                 (void) fprintf(stderr, "wrong direction %d\n",
  826                     dir);
  827             }
  828             break;
  829         default:
  830             (void) fprintf(stderr, "wrong orient %d\n",
  831                 orient);
  832         }
  833 #endif
  834     }
  835     return (row * dp->ncols + col);
  836 }
  837 static void
  838 draw_state(ModeInfo * mi, int state)
  839 {
  840     dilemmastruct *dp = &dilemmas[MI_SCREEN(mi)];
  841     CellList   *current;
  842 
  843 
  844     current = dp->cellList[state];
  845     while (current) {
  846         int         col = current->pt.x;
  847         int         row = current->pt.y;
  848         int         colrow = col + row * dp->ncols;
  849 
  850         drawcell(mi, col, row,
  851                dp->colors[(int) dp->sn[colrow]][(int) dp->s[colrow]],
  852              dp->sn[colrow], False);
  853         if (dp->s[colrow] && !dp->sn[colrow])
  854             dp->defectors--;
  855         if (!dp->s[colrow] && dp->sn[colrow])
  856             dp->defectors++;
  857         dp->s[colrow] = dp->sn[colrow];
  858         current = current->next;
  859     }
  860     free_state(dp, state);
  861     XFlush(MI_DISPLAY(mi));
  862 }
  863 
  864 ENTRYPOINT void
  865 init_dilemma(ModeInfo * mi)
  866 {
  867     int         size = MI_SIZE(mi);
  868     int         i, col, row, colrow, mrow;
  869     dilemmastruct *dp;
  870 
  871     MI_INIT(mi, dilemmas);
  872     dp = &dilemmas[MI_SCREEN(mi)];
  873 
  874     dp->generation = 0;
  875     dp->redrawing = 0;
  876     dp->state = 0;
  877     free_dilemma_screen(dp);
  878 
  879     if (!dp->initialized) { /* Genesis */
  880         icon_width = cooperat_width;
  881         icon_height = cooperat_height;
  882         dp->initialized = 1;
  883         for (i = 0; i < BITMAPS; i++) {
  884             logo[i].width = icon_width;
  885             logo[i].height = icon_height;
  886             logo[i].bytes_per_line = (icon_width + 7) / 8;
  887         }
  888     }
  889     if (MI_IS_FULLRANDOM(mi)) {
  890         dp->vertical = (Bool) (LRAND() & 1);
  891     } else {
  892         dp->vertical = vertical;
  893     }
  894     dp->width = MI_WIDTH(mi);
  895     dp->height = MI_HEIGHT(mi);
  896 
  897     for (i = 0; i < NEIGHBORKINDS; i++) {
  898         if (neighbors == plots[i]) {
  899             dp->neighbors = neighbors;
  900             break;
  901         }
  902         if (i == NEIGHBORKINDS - 1) {
  903 #if 0
  904             dp->neighbors = plots[NRAND(NEIGHBORKINDS)];
  905             dp->neighbors = (LRAND() & 1) ? 4 : 8;
  906 #else
  907             dp->neighbors = 8;
  908 #endif
  909             break;
  910         }
  911     }
  912 
  913     if (dp->neighbors == 6) {
  914         int nccols, ncrows, sides;
  915 
  916         dp->polygon = 6;
  917         if (!dp->vertical) {
  918             dp->height = MI_WIDTH(mi);
  919             dp->width = MI_HEIGHT(mi);
  920         }
  921         if (dp->width < 2)
  922             dp->width = 2;
  923         if (dp->height < 4)
  924             dp->height = 4;
  925         if (size < -MINSIZE)
  926             dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) /
  927                       MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
  928         else if (size < MINSIZE) {
  929             if (!size)
  930                 dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE);
  931             else
  932                 dp->ys = MINSIZE;
  933         } else
  934             dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) /
  935                            MINGRIDSIZE));
  936         dp->xs = dp->ys;
  937         dp->pixelmode = True;
  938         nccols = MAX(dp->width / dp->xs - 2, 2);
  939         ncrows = MAX(dp->height / dp->ys - 1, 2);
  940         dp->ncols = nccols / 2;
  941         dp->nrows = 2 * (ncrows / 4);
  942         dp->xb = (dp->width - dp->xs * nccols) / 2 + dp->xs / 2;
  943         dp->yb = (dp->height - dp->ys * (ncrows / 2) * 2) / 2 +
  944             dp->ys - 2;
  945         for (sides = 0; sides < 6; sides++) {
  946             if (dp->vertical) {
  947                 dp->shape.hexagon[sides].x =
  948                     (dp->xs - 1) * hexagonUnit[sides].x;
  949                 dp->shape.hexagon[sides].y =
  950                     ((dp->ys - 1) * hexagonUnit[sides].y /
  951                     2) * 4 / 3;
  952             } else {
  953                 dp->shape.hexagon[sides].y =
  954                     (dp->xs - 1) * hexagonUnit[sides].x;
  955                 dp->shape.hexagon[sides].x =
  956                     ((dp->ys - 1) * hexagonUnit[sides].y /
  957                     2) * 4 / 3;
  958             }
  959         }
  960     } else if (dp->neighbors == 4 || dp->neighbors == 8) {
  961         dp->polygon = 4;
  962         if (dp->width < 2)
  963             dp->width = 2;
  964         if (dp->height < 2)
  965             dp->height = 2;
  966         if (size == 0 ||
  967             MINGRIDSIZE * size > dp->width || MINGRIDSIZE * size > dp->height) {
  968             if (dp->width > MINGRIDSIZE * icon_width &&
  969                 dp->height > MINGRIDSIZE * icon_height) {
  970                 dp->pixelmode = False;
  971                 dp->xs = icon_width;
  972                 dp->ys = icon_height;
  973             } else {
  974                 dp->pixelmode = True;
  975                 dp->xs = dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) /
  976                               MINGRIDSIZE);
  977             }
  978         } else {
  979             dp->pixelmode = True;
  980             if (size < -MINSIZE)
  981                 dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) /
  982                       MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
  983             else if (size < MINSIZE)
  984                 dp->ys = MINSIZE;
  985             else
  986                 dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) /
  987                                MINGRIDSIZE));
  988             dp->xs = dp->ys;
  989         }
  990         dp->ncols = MAX(dp->width / dp->xs, 2);
  991         dp->nrows = MAX(dp->height / dp->ys, 2);
  992         dp->xb = (dp->width - dp->xs * dp->ncols) / 2;
  993         dp->yb = (dp->height - dp->ys * dp->nrows) / 2;
  994     } else {        /* TRI */
  995         int orient;
  996 
  997         dp->polygon = 3;
  998         if (!dp->vertical) {
  999             dp->height = MI_WIDTH(mi);
 1000             dp->width = MI_HEIGHT(mi);
 1001         }
 1002         if (dp->width < 2)
 1003             dp->width = 2;
 1004         if (dp->height < 2)
 1005             dp->height = 2;
 1006         if (size < -MINSIZE)
 1007             dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) /
 1008                       MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
 1009         else if (size < MINSIZE) {
 1010             if (!size)
 1011                 dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE);
 1012             else
 1013                 dp->ys = MINSIZE;
 1014         } else
 1015             dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) /
 1016                            MINGRIDSIZE));
 1017         dp->xs = (int) (1.52 * dp->ys);
 1018         dp->pixelmode = True;
 1019         dp->ncols = (MAX(dp->width / dp->xs - 1, 2) / 2) * 2;
 1020         dp->nrows = (MAX(dp->height / dp->ys - 1, 2) / 2) * 2;
 1021         dp->xb = (dp->width - dp->xs * dp->ncols) / 2 + dp->xs / 2;
 1022         dp->yb = (dp->height - dp->ys * dp->nrows) / 2 + dp->ys / 2;
 1023         for (orient = 0; orient < 2; orient++) {
 1024             for (i = 0; i < 3; i++) {
 1025                 if (dp->vertical) {
 1026                     dp->shape.triangle[orient][i].x =
 1027                         (dp->xs - 2) * triangleUnit[orient][i].x;
 1028                     dp->shape.triangle[orient][i].y =
 1029                         (dp->ys - 2) * triangleUnit[orient][i].y;
 1030                 } else {
 1031                     dp->shape.triangle[orient][i].y =
 1032                         (dp->xs - 2) * triangleUnit[orient][i].x;
 1033                     dp->shape.triangle[orient][i].x =
 1034                         (dp->ys - 2) * triangleUnit[orient][i].y;
 1035                 }
 1036             }
 1037         }
 1038     }
 1039 
 1040     dp->npositions = dp->ncols * dp->nrows;
 1041 
 1042     dp->pm[0][0] = 1, dp->pm[0][1] = 0;
 1043     if (bonus < 1.0 || bonus > 4.0)
 1044         dp->pm[1][0] = 1.85;
 1045     else
 1046         dp->pm[1][0] = bonus;
 1047     dp->pm[1][1] = 0;
 1048 
 1049     if (MI_NPIXELS(mi) >= COLORS) {
 1050 
 1051         dp->colors[0][0] = MI_PIXEL(mi, BLUE);  /* COOPERATING, was cooperating */
 1052         dp->colors[0][1] = MI_PIXEL(mi, GREEN);     /* COOPERATING, was defecting */
 1053         dp->colors[1][0] = MI_PIXEL(mi, YELLOW);    /* DEFECTING, was cooperating */
 1054         dp->colors[1][1] = MI_PIXEL(mi, RED);   /* DEFECTING, was defecting */
 1055     } else {
 1056         dp->colors[0][0] = MI_WHITE_PIXEL(mi);
 1057         dp->colors[0][1] = MI_WHITE_PIXEL(mi);
 1058         dp->colors[1][0] = MI_WHITE_PIXEL(mi);
 1059         dp->colors[1][1] = MI_WHITE_PIXEL(mi);
 1060     }
 1061     alloc_dilemma(dp);
 1062     if (dp->s == NULL)
 1063         return;
 1064     MI_CLEARWINDOW(mi);
 1065 
 1066     dp->defectors = MI_COUNT(mi);
 1067     if (dp->defectors < -MINDEFECT) {
 1068         dp->defectors = NRAND(-dp->defectors - MINDEFECT + 1) + MINDEFECT;
 1069     } else if (dp->defectors < MINDEFECT)
 1070         dp->defectors = MINDEFECT;
 1071     if (dp->defectors > dp->npositions)
 1072         dp->defectors = dp->npositions;
 1073 
 1074     for (i = 0; i < dp->defectors; i++) {
 1075         do {
 1076             colrow = NRAND(dp->npositions);
 1077         } while (dp->sn[colrow]);
 1078         dp->sn[colrow] = 1;
 1079     }
 1080 #if 0               /* if p was a float... */
 1081     mrow = 0;
 1082     for (row = 0; row < dp->nrows; row++) {
 1083         for (col = 0; col < dp->ncols; col++) {
 1084             dp->sn[col + mrow] = ((float) LRAND() / MAXRAND < dp->p);
 1085         }
 1086         mrow += dp->ncols;
 1087     }
 1088 #endif
 1089 
 1090     dp->defectors = 0;
 1091 
 1092     /* Show initial state... real important for debugging */
 1093     mrow = 0;
 1094     for (row = 0; row < dp->nrows; ++row) {
 1095         for (col = 0; col < dp->ncols; ++col) {
 1096             addtolist(mi, col, row,
 1097                dp->sn[col + mrow] * BITMAPS + dp->s[col + mrow]);
 1098         }
 1099         mrow += dp->ncols;
 1100     }
 1101 }
 1102 
 1103 ENTRYPOINT void
 1104 draw_dilemma(ModeInfo * mi)
 1105 {
 1106     int         col, row, mrow, colrow, n, i;
 1107     dilemmastruct *dp;
 1108 
 1109     if (dilemmas == NULL)
 1110         return;
 1111     dp = &dilemmas[MI_SCREEN(mi)];
 1112     if (dp->s == NULL)
 1113         return;
 1114 
 1115     MI_IS_DRAWN(mi) = True;
 1116 
 1117     if (dp->state >= 2 * COLORS) {
 1118 
 1119         for (col = 0; col < dp->ncols; col++) {
 1120             for (row = 0; row < dp->nrows; row++) {
 1121                 colrow = col + row * dp->ncols;
 1122                 if (conscious)
 1123                     dp->payoff[colrow] =
 1124                         dp->pm[(int) dp->s[colrow]][(int) dp->s[colrow]];
 1125                 else
 1126                     dp->payoff[colrow] = 0.0;
 1127                 for (n = 0; n < dp->neighbors; n++)
 1128                     dp->payoff[colrow] +=
 1129                         dp->pm[(int) dp->s[colrow]][(int)
 1130                           dp->s[positionOfNeighbor(dp,
 1131                     n, col, row)]];
 1132 
 1133             }
 1134         }
 1135         for (row = 0; row < dp->nrows; row++) {
 1136             for (col = 0; col < dp->ncols; col++) {
 1137                 float       hp;
 1138                 int         position;
 1139 
 1140                 colrow = col + row * dp->ncols;
 1141                 hp = dp->payoff[colrow];
 1142                 dp->sn[colrow] = dp->s[colrow];
 1143                 for (n = 0; n < dp->neighbors; n++) {
 1144                     position = positionOfNeighbor(dp, n, col, row);
 1145                     if (ROUND_FLOAT(dp->payoff[position], 0.001) >
 1146                         ROUND_FLOAT(hp, 0.001)) {
 1147                         hp = dp->payoff[position];
 1148                         dp->sn[colrow] = dp->s[position];
 1149                     }
 1150                 }
 1151             }
 1152         }
 1153         mrow = 0;
 1154         for (row = 0; row < dp->nrows; row++) {
 1155             for (col = 0; col < dp->ncols; col++) {
 1156                 addtolist(mi, col, row,
 1157                       dp->sn[col + mrow] * BITMAPS + dp->s[col + mrow]);
 1158             }
 1159             mrow += dp->ncols;
 1160         }
 1161 
 1162         if (++dp->generation > MI_CYCLES(mi) ||
 1163             dp->defectors == dp->npositions || dp->defectors == 0)
 1164             init_dilemma(mi);
 1165         dp->state = 0;
 1166     } else {
 1167         if (dp->state < COLORS) {
 1168             draw_state(mi, dp->state);
 1169         }
 1170         dp->state++;
 1171     }
 1172 #if 1
 1173     if (dp->redrawing) {
 1174         for (i = 0; i < REDRAWSTEP; i++) {
 1175             drawcell(mi, dp->redrawpos % dp->ncols, dp->redrawpos / dp->ncols,
 1176                  dp->colors[(int) dp->sn[dp->redrawpos]][(int) dp->s[dp->redrawpos]],
 1177                  dp->sn[dp->redrawpos], False);
 1178             if (++(dp->redrawpos) >= dp->npositions) {
 1179                 dp->redrawing = 0;
 1180                 break;
 1181             }
 1182         }
 1183     }
 1184 #endif
 1185 }
 1186 
 1187 ENTRYPOINT void
 1188 release_dilemma(ModeInfo * mi)
 1189 {
 1190     if (dilemmas != NULL) {
 1191         int         screen;
 1192 
 1193         for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
 1194             free_dilemma_screen(&dilemmas[screen]);
 1195         free(dilemmas);
 1196         dilemmas = (dilemmastruct *) NULL;
 1197     }
 1198 }
 1199 
 1200 #ifndef STANDALONE
 1201 ENTRYPOINT void
 1202 refresh_dilemma(ModeInfo * mi)
 1203 {
 1204     dilemmastruct *dp = &dilemmas[MI_SCREEN(mi)];
 1205 
 1206     dp->redrawing = 1;
 1207     dp->redrawpos = 0;
 1208 }
 1209 #endif
 1210 
 1211 XSCREENSAVER_MODULE ("Dilemma", dilemma)
 1212 
 1213 #endif /* MODE_dilemma */