Fix some C that gcc tags as unclean or unsafe. Rename 'a' structure to 'game'.
[super-star-trek.git] / ai.c
1 #include "sst.h"\r
2 \r
3 static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {\r
4         int iqx, iqy, l;\r
5 \r
6         iqx = quadx+(lookx+9)/10 - 1;\r
7         iqy = quady+(looky+9)/10 - 1;\r
8         if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
9                 d.galaxy[iqx][iqy] > 899)\r
10                 return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */\r
11         if (ienm == IHR) return 0; /* Romulans cannot escape! */\r
12         if (irun == 0) {\r
13                 /* avoid intruding on another commander's territory */\r
14                 if (ienm == IHC) {\r
15                         for (l = 1; l <= d.remcom; l++)\r
16                                 if (d.cx[l]==iqx && d.cy[l]==iqy) return 0;\r
17                         /* refuse to leave if currently attacking starbase */\r
18                         if (batx==quadx && baty==quady) return 0;\r
19                 }\r
20                 /* don't leave if over 1000 units of energy */\r
21                 if (kpower[loccom] > 1000.) return 0;\r
22         }\r
23         /* print escape message and move out of quadrant.\r
24            We know this if either short or long range sensors are working */\r
25         if (damage[DSRSENS] == 0.0 || damage[DLRSENS] == 0.0 ||\r
26                 condit == IHDOCKED) {\r
27                 proutn("***");\r
28                 cramen(ienm);\r
29                 proutn(" escapes to");\r
30                 cramlc(1, iqx, iqy);\r
31                 prout(" (and regains strength).");\r
32         }\r
33         /* handle local matters related to escape */\r
34         kx[loccom] = kx[nenhere];\r
35         ky[loccom] = ky[nenhere];\r
36         kavgd[loccom] = kavgd[nenhere];\r
37         kpower[loccom] = kpower[nenhere];\r
38         kdist[loccom] = kdist[nenhere];\r
39         klhere--;\r
40         nenhere--;\r
41         if (condit != IHDOCKED) newcnd();\r
42         /* Handle global matters related to escape */\r
43         d.galaxy[quadx][quady] -= 100;\r
44         d.galaxy[iqx][iqy] += 100;\r
45         if (ienm==IHS) {\r
46                 ishere=0;\r
47                 iscate=0;\r
48                 ientesc=0;\r
49                 isatb=0;\r
50                 future[FSCMOVE]=0.2777+d.date;\r
51                 future[FSCDBAS]=1e30;\r
52                 d.isx=iqx;\r
53                 d.isy=iqy;\r
54         }\r
55         else {\r
56                 for (l=1; l<=d.remcom; l++) {\r
57                         if (d.cx[l]==quadx && d.cy[l]==quady) {\r
58                                 d.cx[l]=iqx;\r
59                                 d.cy[l]=iqy;\r
60                                 break;\r
61                         }\r
62                 }\r
63                 comhere = 0;\r
64         }\r
65         return 1; /* success */\r
66 }\r
67 \r
68 \r
69 static void movebaddy(int comx, int comy, int loccom, int ienm) {\r
70         int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;\r
71         int irun = 0;\r
72         int krawlx, krawly;\r
73         int success;\r
74         int attempts;\r
75         /* This should probably be just comhere + ishere */\r
76         int nbaddys = skill > 3 ?\r
77                                   (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):\r
78                                   (comhere + ishere);\r
79         double dist1, forces;\r
80 \r
81         dist1 = kdist[loccom];\r
82         mdist = dist1 + 0.5; /* Nearest integer distance */\r
83 \r
84         /* If SC, check with spy to see if should hi-tail it */\r
85         if (ienm==IHS &&\r
86                 (kpower[loccom] <= 500.0 || (condit==IHDOCKED && damage[DPHOTON]==0))) {\r
87                 irun = 1;\r
88                 motion = -10;\r
89         }\r
90         else {\r
91                 /* decide whether to advance, retreat, or hold position */\r
92 /* Algorithm:\r
93    * Enterprise has "force" based on condition of phaser and photon torpedoes.\r
94      If both are operating full strength, force is 1000. If both are damaged,\r
95          force is -1000. Having shields down subtracts an additional 1000.\r
96 \r
97    * Enemy has forces equal to the energy of the attacker plus\r
98      100*(K+R) + 500*(C+S) - 400 for novice through good levels OR\r
99          346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.\r
100 \r
101          Attacker Initial energy levels (nominal):\r
102                   Klingon   Romulan   Commander   Super-Commander\r
103          Novice    400        700        1200        \r
104          Fair      425        750        1250\r
105          Good      450        800        1300        1750\r
106          Expert    475        850        1350        1875\r
107          Emeritus  500        900        1400        2000\r
108      VARIANCE   75        200         200         200\r
109 \r
110          Enemy vessels only move prior to their attack. In Novice - Good games\r
111          only commanders move. In Expert games, all enemy vessels move if there\r
112          is a commander present. In Emeritus games all enemy vessels move.\r
113 \r
114   *  If Enterprise is not docked, an agressive action is taken if enemy\r
115      forces are 1000 greater than Enterprise.\r
116 \r
117          Agressive action on average cuts the distance between the ship and\r
118          the enemy to 1/4 the original.\r
119 \r
120   *  At lower energy advantage, movement units are proportional to the\r
121      advantage with a 650 advantage being to hold ground, 800 to move forward\r
122          1, 950 for two, 150 for back 4, etc. Variance of 100.\r
123 \r
124          If docked, is reduced by roughly 1.75*skill, generally forcing a\r
125          retreat, especially at high skill levels.\r
126 \r
127   *  Motion is limited to skill level, except for SC hi-tailing it out.\r
128   */\r
129 \r
130                 forces = kpower[loccom]+100.0*nenhere+400*(nbaddys-1);\r
131                 if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */\r
132                 if (damage[DPHASER] == 0.0 || damage[DPHOTON] == 0.0) {\r
133                         if (damage[DPHASER] != 0) /* phasers damaged */\r
134                                 forces += 300.0;\r
135                         else\r
136                                 forces -= 0.2*(energy - 2500.0);\r
137                         if (damage[DPHOTON] != 0) /* photon torpedoes damaged */\r
138                                 forces += 300.0;\r
139                         else\r
140                                 forces -= 50.0*torps;\r
141                 }\r
142                 else {\r
143                         /* phasers and photon tubes both out! */\r
144                         forces += 1000.0;\r
145                 }\r
146                 motion = 0;\r
147                 if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */\r
148                         motion = ((forces+200.0*Rand())/150.0) - 5.0;\r
149                 else {\r
150                         if (forces > 1000.0) /* Very strong -- move in for kill */\r
151                                 motion = (1.0-square(Rand()))*dist1 + 1.0;\r
152                         if (condit==IHDOCKED) /* protected by base -- back off ! */\r
153                                 motion -= skill*(2.0-square(Rand()));\r
154                 }\r
155 #ifdef DEBUG\r
156                 if (idebug) {\r
157                         proutn("MOTION = ");\r
158                         cramf(motion, 1, 2);\r
159             proutn("  FORCES = ");\r
160                         cramf(forces, 1, 2);\r
161                         skip(1);\r
162                 }\r
163 #endif\r
164                 /* don't move if no motion */\r
165                 if (motion==0) return;\r
166                 /* Limit motion according to skill */\r
167                 if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;\r
168         }\r
169         /* calcuate preferred number of steps */\r
170         nsteps = motion < 0 ? -motion : motion;\r
171         if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */\r
172         if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */\r
173         if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */\r
174 #ifdef DEBUG\r
175         if (idebug) {\r
176                 proutn("NSTEPS = ");\r
177                 crami(nsteps, 1);\r
178                 skip(1);\r
179         }\r
180 #endif\r
181         /* Compute preferred values of delta X and Y */\r
182         mx = sectx - comx;\r
183         my = secty - comy;\r
184         if (2.0 * abs(mx) < abs(my)) mx = 0;\r
185         if (2.0 * abs(my) < abs(sectx-comx)) my = 0;\r
186         if (mx != 0) mx = mx*motion < 0 ? -1 : 1;\r
187         if (my != 0) my = my*motion < 0 ? -1 : 1;\r
188         nextx = comx;\r
189         nexty = comy;\r
190         quad[comx][comy] = IHDOT;\r
191         /* main move loop */\r
192         for (ll = 1; ll <= nsteps; ll++) {\r
193 #ifdef DEBUG\r
194                 if (idebug) {\r
195                         crami(ll,2);\r
196                         skip(1);\r
197                 }\r
198 #endif\r
199                 /* Check if preferred position available */\r
200                 lookx = nextx + mx;\r
201                 looky = nexty + my;\r
202                 krawlx = mx < 0 ? 1 : -1;\r
203                 krawly = my < 0 ? 1 : -1;\r
204                 success = 0;\r
205                 attempts = 0; /* Settle mysterious hang problem */\r
206                 while (attempts++ < 20 && !success) {\r
207                         if (lookx < 1 || lookx > 10) {\r
208                                 if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
209                                         return;\r
210                                 if (krawlx == mx || my == 0) break;\r
211                                 lookx = nextx + krawlx;\r
212                                 krawlx = -krawlx;\r
213                         }\r
214                         else if (looky < 1 || looky > 10) {\r
215                                 if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
216                                         return;\r
217                                 if (krawly == my || mx == 0) break;\r
218                                 looky = nexty + krawly;\r
219                                 krawly = -krawly;\r
220                         }\r
221                         else if (quad[lookx][looky] != IHDOT) {\r
222                                 /* See if we should ram ship */\r
223                                 if (quad[lookx][looky] == ship &&\r
224                                         (ienm == IHC || ienm == IHS)) {\r
225                                         ram(1, ienm, comx, comy);\r
226                                         return;\r
227                                 }\r
228                                 if (krawlx != mx && my != 0) {\r
229                                         lookx = nextx + krawlx;\r
230                                         krawlx = -krawlx;\r
231                                 }\r
232                                 else if (krawly != my && mx != 0) {\r
233                                         looky = nexty + krawly;\r
234                                         krawly = -krawly;\r
235                                 }\r
236                                 else break; /* we have failed */\r
237                         }\r
238                         else success = 1;\r
239                 }\r
240                 if (success) {\r
241                         nextx = lookx;\r
242                         nexty = looky;\r
243 #ifdef DEBUG\r
244                         if (idebug) {\r
245                                 cramlc(0, nextx, nexty);\r
246                                 skip(1);\r
247                         }\r
248 #endif\r
249                 }\r
250                 else break; /* done early */\r
251         }\r
252         /* Put commander in place within same quadrant */\r
253         quad[nextx][nexty] = ienm;\r
254         if (nextx != comx || nexty != comy) {\r
255                 /* it moved */\r
256                 kx[loccom] = nextx;\r
257                 ky[loccom] = nexty;\r
258                 kdist[loccom] = kavgd[loccom] =\r
259                                         sqrt(square(sectx-nextx)+square(secty-nexty));\r
260                 if (damage[DSRSENS] == 0 || condit == IHDOCKED) {\r
261                         proutn("***");\r
262                         cramen(ienm);\r
263                         if (kdist[loccom] < dist1) proutn(" advances to");\r
264                         else proutn(" retreats to");\r
265                         cramlc(2, nextx, nexty);\r
266                         skip(1);\r
267                 }\r
268         }\r
269 }\r
270 \r
271 void movcom(void) {\r
272         int ix, iy, i;\r
273 \r
274 #ifdef DEBUG\r
275         if (idebug) prout("MOVCOM");\r
276 #endif\r
277 \r
278         /* Figure out which Klingon is the commander (or Supercommander)\r
279            and do move */\r
280         if (comhere) for (i = 1; i <= nenhere; i++) {\r
281                 ix = kx[i];\r
282                 iy = ky[i];\r
283                 if (quad[ix][iy] == IHC) {\r
284                         movebaddy(ix, iy, i, IHC);\r
285                         break;\r
286                 }\r
287         }\r
288         if (ishere) for (i = 1; i <= nenhere; i++) {\r
289                 ix = kx[i];\r
290                 iy = ky[i];\r
291                 if (quad[ix][iy] == IHS) {\r
292                         movebaddy(ix, iy, i, IHS);\r
293                         break;\r
294                 }\r
295         }\r
296         /* if skill level is high, move other Klingons and Romulans too!\r
297            Move these last so they can base their actions on what the\r
298        commander(s) do. */\r
299         if (skill > 3) for (i = 1; i <= nenhere; i++) {\r
300                 ix = kx[i];\r
301                 iy = ky[i];\r
302                 if (quad[ix][iy] == IHK || quad[ix][iy] == IHR)\r
303                         movebaddy(ix, iy, i, quad[ix][iy]);\r
304         }\r
305 \r
306         sortkl();\r
307 }\r
308 \r
309 static int checkdest(int iqx, int iqy, int flag, int *ipage) {\r
310         int i, j;\r
311 \r
312         if ((iqx==quadx && iqy==quady) ||\r
313                 iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
314                 d.galaxy[iqx][iqy] > 899) return 1;\r
315         if (flag) {\r
316                 /* Avoid quadrants with bases if we want to avoid Enterprise */\r
317                 for (i = 1; i <= d.rembase; i++)\r
318                         if (d.baseqx[i]==iqx && d.baseqy[i]==iqy) return 1;\r
319         }\r
320 \r
321         /* do the move */\r
322         d.galaxy[d.isx][d.isy] -= 100;\r
323         d.isx = iqx;\r
324         d.isy = iqy;\r
325         d.galaxy[d.isx][d.isy] += 100;\r
326         if (iscate) {\r
327                 /* SC has scooted, Remove him from current quadrant */\r
328                 iscate=0;\r
329                 isatb=0;\r
330                 ishere=0;\r
331                 ientesc=0;\r
332                 future[FSCDBAS]=1e30;\r
333                 for (i = 1; i <= nenhere; i++) \r
334                         if (quad[kx[i]][ky[i]] == IHS) break;\r
335                 quad[kx[i]][ky[i]] = IHDOT;\r
336                 kx[i] = kx[nenhere];\r
337                 ky[i] = ky[nenhere];\r
338                 kdist[i] = kdist[nenhere];\r
339                 kavgd[i] = kavgd[nenhere];\r
340                 kpower[i] = kpower[nenhere];\r
341                 klhere--;\r
342                 nenhere--;\r
343                 if (condit!=IHDOCKED) newcnd();\r
344                 sortkl();\r
345         }\r
346         /* check for a helpful planet */\r
347         for (i = 1; i <= inplan; i++) {\r
348                 if (d.plnets[i].x==d.isx && d.plnets[i].y==d.isy &&\r
349                         d.plnets[i].crystals == 1) {\r
350                         /* destroy the planet */\r
351                         d.plnets[i] = nulplanet;\r
352                         d.newstuf[d.isx][d.isy] -= 1;\r
353                         if (damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
354                                 if (*ipage==0) pause(1);\r
355                                 *ipage = 1;\r
356                                 prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
357                                 proutn("   a planet in");\r
358                                 cramlc(1, d.isx, d.isy);\r
359                                 prout(" has been destroyed");\r
360                                 prout("   by the Super-commander.\"");\r
361                         }\r
362                         break;\r
363                 }\r
364         }\r
365         return 0; /* looks good! */\r
366 }\r
367                         \r
368                 \r
369         \r
370 \r
371 \r
372 void scom(int *ipage) {\r
373         int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;\r
374         int iqx, iqy;\r
375         int basetbl[6];\r
376         double bdist[6];\r
377         int flag;\r
378 #ifdef DEBUG\r
379         if (idebug) prout("SCOM");\r
380 #endif\r
381 \r
382         /* Decide on being active or passive */\r
383         flag = ((d.killc+d.killk)/(d.date+0.01-indate) < 0.1*skill*(skill+1.0) ||\r
384                         (d.date-indate) < 3.0);\r
385         if (iscate==0 && flag) {\r
386                 /* compute move away from Enterprise */\r
387                 ideltax = d.isx-quadx;\r
388                 ideltay = d.isy-quady;\r
389                 if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {\r
390                         /* circulate in space */\r
391                         ideltax = d.isy-quady;\r
392                         ideltay = quadx-d.isx;\r
393                 }\r
394         }\r
395         else {\r
396                 /* compute distances to starbases */\r
397                 if (d.rembase <= 0) {\r
398                         /* nothing left to do */\r
399                         future[FSCMOVE] = 1e30;\r
400                         return;\r
401                 }\r
402                 sx = d.isx;\r
403                 sy = d.isy;\r
404                 for (i = 1; i <= d.rembase; i++) {\r
405                         basetbl[i] = i;\r
406                         ibqx = d.baseqx[i];\r
407                         ibqy = d.baseqy[i];\r
408                         bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));\r
409                 }\r
410                 if (d.rembase > 1) {\r
411                         /* sort into nearest first order */\r
412                         int iswitch;\r
413                         do {\r
414                                 iswitch = 0;\r
415                                 for (i=1; i < d.rembase-1; i++) {\r
416                                         if (bdist[i] > bdist[i+1]) {\r
417                                                 int ti = basetbl[i];\r
418                                                 double t = bdist[i];\r
419                                                 bdist[i] = bdist[i+1];\r
420                                                 bdist[i+1] = t;\r
421                                                 basetbl[i] = basetbl[i+1];\r
422                                                 basetbl[i+1] =ti;\r
423                                                 iswitch = 1;\r
424                                         }\r
425                                 }\r
426                         } while (iswitch);\r
427                 }\r
428                 /* look for nearest base without a commander, no Enterprise, and\r
429                    without too many Klingons, and not already under attack. */\r
430                 ifindit = iwhichb = 0;\r
431 \r
432                 for (i2 = 1; i2 <= d.rembase; i2++) {\r
433                         i = basetbl[i2];        /* bug in original had it not finding nearest*/\r
434                         ibqx = d.baseqx[i];\r
435                         ibqy = d.baseqy[i];\r
436                         if ((ibqx == quadx && ibqy == quady) ||\r
437                                 (ibqx == batx && ibqy == baty) ||\r
438                                 d.galaxy[ibqx][ibqy] > 899) continue;\r
439                         /* if there is a commander, an no other base is appropriate,\r
440                            we will take the one with the commander */\r
441                         for (j = 1; j <= d.remcom; j++) {\r
442                                 if (ibqx==d.cx[j] && ibqy==d.cy[j] && ifindit!= 2) {\r
443                                                 ifindit = 2;\r
444                                                 iwhichb = i;\r
445                                                 break;\r
446                                 }\r
447                         }\r
448                         if (j > d.remcom) { /* no commander -- use this one */\r
449                                 ifindit = 1;\r
450                                 iwhichb = i;\r
451                                 break;\r
452                         }\r
453                 }\r
454                 if (ifindit==0) return; /* Nothing suitable -- wait until next time*/\r
455                 ibqx = d.baseqx[iwhichb];\r
456                 ibqy = d.baseqy[iwhichb];\r
457                 /* decide how to move toward base */\r
458                 ideltax = ibqx - d.isx;\r
459                 ideltay = ibqy - d.isy;\r
460         }\r
461         /* Maximum movement is 1 quadrant in either or both axis */\r
462         if (ideltax > 1) ideltax = 1;\r
463         if (ideltax < -1) ideltax = -1;\r
464         if (ideltay > 1) ideltay = 1;\r
465         if (ideltay < -1) ideltay = -1;\r
466 \r
467         /* try moving in both x and y directions */\r
468         iqx = d.isx + ideltax;\r
469         iqy = d.isy + ideltax;\r
470         if (checkdest(iqx, iqy, flag, ipage)) {\r
471                 /* failed -- try some other maneuvers */\r
472                 if (ideltax==0 || ideltay==0) {\r
473                         /* attempt angle move */\r
474                         if (ideltax != 0) {\r
475                                 iqy = d.isy + 1;\r
476                                 if (checkdest(iqx, iqy, flag, ipage)) {\r
477                                         iqy = d.isy - 1;\r
478                                         checkdest(iqx, iqy, flag, ipage);\r
479                                 }\r
480                         }\r
481                         else {\r
482                                 iqx = d.isx + 1;\r
483                                 if (checkdest(iqx, iqy, flag, ipage)) {\r
484                                         iqx = d.isx - 1;\r
485                                         checkdest(iqx, iqy, flag, ipage);\r
486                                 }\r
487                         }\r
488                 }\r
489                 else {\r
490                         /* try moving just in x or y */\r
491                         iqy = d.isy;\r
492                         if (checkdest(iqx, iqy, flag, ipage)) {\r
493                                 iqy = d.isy + ideltay;\r
494                                 iqx = d.isx;\r
495                                 checkdest(iqx, iqy, flag, ipage);\r
496                         }\r
497                 }\r
498         }\r
499         /* check for a base */\r
500         if (d.rembase == 0) {\r
501                 future[FSCMOVE] = 1e30;\r
502         }\r
503         else for (i=1; i<=d.rembase; i++) {\r
504                 ibqx = d.baseqx[i];\r
505                 ibqy = d.baseqy[i];\r
506                 if (ibqx==d.isx && ibqy == d.isy && d.isx != batx && d.isy != baty) {\r
507                         /* attack the base */\r
508                         if (flag) return; /* no, don't attack base! */\r
509                         iseenit = 0;\r
510                         isatb=1;\r
511                         future[FSCDBAS] = d.date + 1.0 +2.0*Rand();\r
512                         if (batx != 0) future[FSCDBAS] += future[FCDBAS]-d.date;\r
513                         if (damage[DRADIO] > 0 && condit != IHDOCKED)\r
514                                 return; /* no warning */\r
515                         iseenit = 1;\r
516                         if (*ipage == 0)  pause(1);\r
517                         *ipage=1;\r
518                         proutn("Lt. Uhura-  \"Captain, the starbase in");\r
519                         cramlc(1, d.isx, d.isy);\r
520                         skip(1);\r
521                         prout("   reports that it is under attack from the Klingon Super-commander.");\r
522                         proutn("   It can survive until stardate ");\r
523                         cramf(future[FSCDBAS], 0, 1);\r
524                         prout(" .\"");\r
525                         if (resting==0) return;\r
526                         prout("Mr. Spock-  \"Captain, shall we cancel the rest period?\"");\r
527                         if (ja()==0) return;\r
528                         resting = 0;\r
529                         Time = 0.0; /* actually finished */\r
530                         return;\r
531                 }\r
532         }\r
533         /* Check for intelligence report */\r
534         if (\r
535 #ifdef DEBUG\r
536                 idebug==0 &&\r
537 #endif\r
538                 (Rand() > 0.2 ||\r
539                  (damage[DRADIO] > 0.0 && condit != IHDOCKED) ||\r
540                  starch[d.isx][d.isy] > 0))\r
541                 return;\r
542         if (*ipage==0) pause(1);\r
543         *ipage = 1;\r
544         prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
545         proutn("   the Super-commander is in");\r
546         cramlc(1, d.isx, d.isy);\r
547         prout(".\"");\r
548         return;\r
549 }\r
550 \r
551 void movetho(void) {\r
552         int idx, idy, im, i, dum, my;\r
553         /* Move the Tholian */\r
554         if (ithere==0 || justin == 1) return;\r
555 \r
556         if (ithx == 1 && ithy == 1) {\r
557                 idx = 1; idy = 10;\r
558         }\r
559         else if (ithx == 1 && ithy == 10) {\r
560                 idx = 10; idy = 10;\r
561         }\r
562         else if (ithx == 10 && ithy == 10) {\r
563                 idx = 10; idy = 1;\r
564         }\r
565         else if (ithx == 10 && ithy == 1) {\r
566                 idx = 1; idy = 1;\r
567         }\r
568         else {\r
569                 /* something is wrong! */\r
570                 ithere = 0;\r
571                 return;\r
572         }\r
573 \r
574         /* Do nothing if we are blocked */\r
575         if (quad[idx][idy]!= IHDOT && quad[idx][idy]!= IHWEB) return;\r
576         quad[ithx][ithy] = IHWEB;\r
577 \r
578         if (ithx != idx) {\r
579                 /* move in x axis */\r
580                 im = fabs((double)idx - ithx)/((double)idx - ithx);\r
581                 while (ithx != idx) {\r
582                         ithx += im;\r
583                         if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
584                 }\r
585         }\r
586         else if (ithy != idy) {\r
587                 /* move in y axis */\r
588                 im = fabs((double)idy - ithy)/((double)idy - ithy);\r
589                 while (ithy != idy) {\r
590                         ithy += im;\r
591                         if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
592                 }\r
593         }\r
594         quad[ithx][ithy] = IHT;\r
595 \r
596         /* check to see if all holes plugged */\r
597         for (i = 1; i < 11; i++) {\r
598                 if (quad[1][i]!=IHWEB && quad[1][i]!=IHT) return;\r
599                 if (quad[10][i]!=IHWEB && quad[10][i]!=IHT) return;\r
600                 if (quad[i][1]!=IHWEB && quad[i][1]!=IHT) return;\r
601                 if (quad[i][10]!=IHWEB && quad[i][10]!=IHT) return;\r
602         }\r
603         /* All plugged up -- Tholian splits */\r
604         quad[ithx][ithy]=IHWEB;\r
605         dropin(IHBLANK, &dum, &my);\r
606         crmena(1,IHT, 2, ithx, ithy);\r
607         prout(" completes web.");\r
608         ithere = ithx = ithy = 0;\r
609         return;\r
610 }\r