home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sources / x / 425 < prev    next >
Encoding:
Internet Message Format  |  1992-07-23  |  50.6 KB

  1. Path: sparky!uunet!ogicse!uwm.edu!caen!sdd.hp.com!mips!msi!dcmartin
  2. From: jung@dia.informatik.uni-stuttgart.de (Norbert Jung)
  3. Newsgroups: comp.sources.x
  4. Subject: v18i057: xvier v1.0 - cute GO'ish game, Part01/02
  5. Message-ID: <csx-18i057-xview-1.0@uunet.UU.NET>
  6. Date: 23 Jul 92 14:16:33 GMT
  7. Article-I.D.: uunet.csx-18i057-xview-1.0
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: Molecular Simulations, Inc.
  10. Lines: 1800
  11. Approved: dcmartin@msi.com
  12. Originator: dcmartin@fascet
  13.  
  14. Submitted-by: Norbert Jung <jung@dia.informatik.uni-stuttgart.de>
  15. Posting-number: Volume 18, Issue 57
  16. Archive-name: xview-1.0/part01
  17.  
  18. xvier is a simple game where you and your opponent alternately throw
  19. stones into free columns. The stones pile up in the columns, and the
  20. goal is to get four stones in a row, in a column or diagonally. The
  21. game compiles without modifications at least on
  22.  
  23.     Sun Sun4        SunOS 4.0, 4.1.1
  24.     Sun Sun3/60        SunOS 4.0
  25.     IBM RS6000        AIX 3.1
  26.     HP 9000/720        HP-UX 8.05
  27.     HP 9000/350        HP-UX 8.00
  28.     DEC VS3100        Ultrix-32 V3.1
  29.     DEC DS5400        Ultrix 4.2
  30.     Sequent Symmetry    Dynix 3.0.17.9
  31.  
  32. #!/bin/sh
  33. # This is a shell archive (produced by shar 3.50)
  34. # To extract the files from this archive, save it to a file, remove
  35. # everything above the "!/bin/sh" line above, and type "sh file_name".
  36. #
  37. # made 07/23/1992 14:14 UTC by dcmartin@fascet
  38. # Source directory /home/fascet/dcmartin/csx/src/tmp/xvier-1.0
  39. #
  40. # existing files will NOT be overwritten unless -c is specified
  41. #
  42. # This is part 1 of a multipart archive                                    
  43. # do not concatenate these parts, unpack them in order with /bin/sh        
  44. #
  45. # This shar contains:
  46. # length  mode       name
  47. # ------ ---------- ------------------------------------------
  48. #    901 -rw-r--r-- Imakefile
  49. #   1251 -rw-r--r-- Makefile.std
  50. #   1502 -rw-r--r-- README
  51. #     42 -rw-r--r-- patchlevel.h
  52. #    322 -rw-r--r-- qdown.xbm
  53. #    290 -rw-r--r-- qdownm.xbm
  54. #    322 -rw-r--r-- qleft.xbm
  55. #    290 -rw-r--r-- qleftm.xbm
  56. #    327 -rw-r--r-- qright.xbm
  57. #    293 -rw-r--r-- qrightm.xbm
  58. #    312 -rw-r--r-- qup.xbm
  59. #    284 -rw-r--r-- qupm.xbm
  60. #  17343 -rw-r--r-- vier.c
  61. #    307 -rw-r--r-- vier.h
  62. #   2741 -rw-r--r-- vierinit.c
  63. #  39330 -rw-r--r-- xvier.c
  64. #    149 -rw-r--r-- xvier.h
  65. #   2486 -rw-r--r-- xvier.man
  66. #  11332 -rw-r--r-- Makefile
  67. #
  68. if test -r _shar_seq_.tmp; then
  69.     echo 'Must unpack archives in sequence!'
  70.     echo Please unpack part `cat _shar_seq_.tmp` next
  71.     exit 1
  72. fi
  73. # ============= Imakefile ==============
  74. if test -f 'Imakefile' -a X"$1" != X"-c"; then
  75.     echo 'x - skipping Imakefile (File already exists)'
  76.     rm -f _shar_wnt_.tmp
  77. else
  78. > _shar_wnt_.tmp
  79. echo 'x - extracting Imakefile (Text)'
  80. sed 's/^X//' << 'SHAR_EOF' > 'Imakefile' &&
  81. # I've seen window managers which couldn't handle aspect ratio hints.
  82. # Uncomment if you have resize problems.
  83. #XVIER_ASPECT    = -DXVIER_WM_ASPECT_BUG
  84. X
  85. # Some systems don't provide FD_SET #define's. HP 9000 and IBM RS6000
  86. # are handled in xvier.h, but on other systems you can uncomment this.
  87. #NO_FD_SET = -DNO_FD_SET
  88. X
  89. # If "select" is missing, but you have "poll", try this:
  90. #NO_SELECT = -DNO_SELECT
  91. X
  92. # And if "getdtablesize" is missing, use the following:
  93. #NO_GETDTABSIZE = -DNO_GETDTABSIZE
  94. X
  95. PROGNAME    = $(LIBDIR)$(PATHSEP)xvier_prog
  96. DEFINES        = $(XVIER_ASPECT) $(NO_FD_SET) $(NO_SELECT) \
  97. X            $(NO_GETDTABSIZE) -DPROGNAME=\"$(PROGNAME)\"
  98. X
  99. PROGRAMS    = xvier xvier_prog
  100. X
  101. SRCS1        = xvier.c
  102. OBJS1        = xvier.o
  103. SRCS2        = vierinit.c vier.c
  104. OBJS2        = vierinit.o vier.o
  105. X
  106. ComplexProgramTarget_1(xvier, $(XLIB), /**/)
  107. NormalProgramTarget(xvier_prog, $(OBJS2), /**/, /**/, /**/)
  108. X
  109. InstallProgram(xvier_prog, $(PROGNAME))
  110. SHAR_EOF
  111. chmod 0644 Imakefile ||
  112. echo 'restore of Imakefile failed'
  113. Wc_c="`wc -c < 'Imakefile'`"
  114. test 901 -eq "$Wc_c" ||
  115.     echo 'Imakefile: original size 901, current size' "$Wc_c"
  116. rm -f _shar_wnt_.tmp
  117. fi
  118. # ============= Makefile.std ==============
  119. if test -f 'Makefile.std' -a X"$1" != X"-c"; then
  120.     echo 'x - skipping Makefile.std (File already exists)'
  121.     rm -f _shar_wnt_.tmp
  122. else
  123. > _shar_wnt_.tmp
  124. echo 'x - extracting Makefile.std (Text)'
  125. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.std' &&
  126. # I've seen window managers which couldn't handle aspect ratio hints.
  127. # Uncomment if you have resize problems.
  128. #XVIER_ASPECT = -DXVIER_WM_ASPECT_BUG
  129. X
  130. # Some systems don't provide FD_SET #define's. HP 9000 and IBM RS6000
  131. # are handled in xvier.h, but on other systems you can uncomment this.
  132. #NO_FD_SET = -DNO_FD_SET
  133. X
  134. # If "select" is missing, but you have "poll", try this:
  135. #NO_SELECT = -DNO_SELECT
  136. X
  137. # And if "getdtablesize" is missing, use the following:
  138. #NO_GETDTABSIZE = -DNO_GETDTABSIZE
  139. X
  140. CFLAGS = -O $(XVIER_ASPECT) $(NO_FD_SET) $(NO_SELECT) $(NO_GETDTABSIZE)
  141. XX11LIB = -lX11
  142. DESTDIR = /usr/local/bin
  143. PROGDESTDIR = /usr/local/lib
  144. PROGDEST = -DPROGNAME=\"$(PROGDESTDIR)/xvier_prog\"
  145. MANDESTDIR = /usr/local/man
  146. MANSECT = 6
  147. X
  148. all:    xvier xvier_prog
  149. X
  150. xvier:    xvier.c xvier.h qdown.xbm qleft.xbm qright.xbm qup.xbm\
  151. X        qdownm.xbm qleftm.xbm qrightm.xbm qupm.xbm patchlevel.h
  152. X    $(CC) -o xvier $(CFLAGS) $(PROGDEST) xvier.c $(X11LIB)
  153. X
  154. xvier_prog:    vier.o vierinit.o
  155. X    $(CC) -o xvier_prog vier.o vierinit.o
  156. X
  157. vier.o:     vier.h vier.c xvier.h
  158. vierinit.o: vier.h vierinit.c xvier.h
  159. X
  160. install: all xvier.man
  161. X    cp xvier_prog $(PROGDESTDIR)
  162. X    cp xvier $(DESTDIR)
  163. X    cp xvier.man $(MANDESTDIR)/man$(MANSECT)/xvier.$(MANSECT)
  164. X
  165. clean::
  166. X    -rm *.o *~ xvier vier core xvier_prog
  167. SHAR_EOF
  168. chmod 0644 Makefile.std ||
  169. echo 'restore of Makefile.std failed'
  170. Wc_c="`wc -c < 'Makefile.std'`"
  171. test 1251 -eq "$Wc_c" ||
  172.     echo 'Makefile.std: original size 1251, current size' "$Wc_c"
  173. rm -f _shar_wnt_.tmp
  174. fi
  175. # ============= README ==============
  176. if test -f 'README' -a X"$1" != X"-c"; then
  177.     echo 'x - skipping README (File already exists)'
  178.     rm -f _shar_wnt_.tmp
  179. else
  180. > _shar_wnt_.tmp
  181. echo 'x - extracting README (Text)'
  182. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  183. xvier is a simple game where you and your opponent alternately throw
  184. stones into free columns. The stones pile up in the columns, and the
  185. goal is to get four stones in a row, in a column or diagonally. The
  186. game compiles without modifications at least on
  187. X
  188. X    Sun Sun4        SunOS 4.0, 4.1.1
  189. X    Sun Sun3/60        SunOS 4.0
  190. X    IBM RS6000        AIX 3.1
  191. X    HP 9000/720        HP-UX 8.05
  192. X    HP 9000/350        HP-UX 8.00
  193. X    DEC VS3100        Ultrix-32 V3.1
  194. X    DEC DS5400        Ultrix 4.2
  195. X    Sequent Symmetry    Dynix 3.0.17.9
  196. X
  197. To install xvier:
  198. X
  199. 1. If you use Makefile.std, copy it to Makefile and choose locations
  200. X   for the X11-binary (default: /usr/local/bin), the game program
  201. X   (default: /usr/local/lib), and the manual page (default:
  202. X   /usr/local/man/man6).
  203. X   If you use imake, type "xmkmf" and "make depend".
  204. X
  205. 2. Type "make".
  206. X
  207. 3. Test the game with "./xvier -prog ./xvier_prog"
  208. X
  209. 4. If it works, type "make install" (and "make install.man" with
  210. X   imake).
  211. X
  212. If you have problems with the compilation, look at the comments in
  213. Makefile.std or Imakefile.
  214. X
  215. The game program uses a simple search tree, and the levels correspond
  216. to the depth of this tree. Thus the higher levels are quite slow, but
  217. normally I don't need them to get a good opponent ;-)
  218. It's interesting that level 1 seems to be weaker than level 0.
  219. X
  220. You may use, copy, modify, and distribute this software and its
  221. documentation for any purpose and without fee. It is provided "as is"
  222. without any express or implied warranty.
  223. X
  224. Have fun!
  225. X
  226. X    Norbert Jung
  227. X    Email: jung@dia.informatik.uni-stuttgart.de
  228. SHAR_EOF
  229. chmod 0644 README ||
  230. echo 'restore of README failed'
  231. Wc_c="`wc -c < 'README'`"
  232. test 1502 -eq "$Wc_c" ||
  233.     echo 'README: original size 1502, current size' "$Wc_c"
  234. rm -f _shar_wnt_.tmp
  235. fi
  236. # ============= patchlevel.h ==============
  237. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  238.     echo 'x - skipping patchlevel.h (File already exists)'
  239.     rm -f _shar_wnt_.tmp
  240. else
  241. > _shar_wnt_.tmp
  242. echo 'x - extracting patchlevel.h (Text)'
  243. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  244. #define XVIER_VERSION "xvier Version 1.0"
  245. SHAR_EOF
  246. chmod 0644 patchlevel.h ||
  247. echo 'restore of patchlevel.h failed'
  248. Wc_c="`wc -c < 'patchlevel.h'`"
  249. test 42 -eq "$Wc_c" ||
  250.     echo 'patchlevel.h: original size 42, current size' "$Wc_c"
  251. rm -f _shar_wnt_.tmp
  252. fi
  253. # ============= qdown.xbm ==============
  254. if test -f 'qdown.xbm' -a X"$1" != X"-c"; then
  255.     echo 'x - skipping qdown.xbm (File already exists)'
  256.     rm -f _shar_wnt_.tmp
  257. else
  258. > _shar_wnt_.tmp
  259. echo 'x - extracting qdown.xbm (Text)'
  260. sed 's/^X//' << 'SHAR_EOF' > 'qdown.xbm' &&
  261. #define qdown_width 16
  262. #define qdown_height 16
  263. #define qdown_x_hot 8
  264. #define qdown_y_hot 8
  265. static char qdown_bits[] = {
  266. X   0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
  267. X   0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x18, 0x30, 0x18,
  268. X   0x30, 0x18, 0x60, 0x0c, 0xc0, 0x07, 0x00, 0x00};
  269. SHAR_EOF
  270. chmod 0644 qdown.xbm ||
  271. echo 'restore of qdown.xbm failed'
  272. Wc_c="`wc -c < 'qdown.xbm'`"
  273. test 322 -eq "$Wc_c" ||
  274.     echo 'qdown.xbm: original size 322, current size' "$Wc_c"
  275. rm -f _shar_wnt_.tmp
  276. fi
  277. # ============= qdownm.xbm ==============
  278. if test -f 'qdownm.xbm' -a X"$1" != X"-c"; then
  279.     echo 'x - skipping qdownm.xbm (File already exists)'
  280.     rm -f _shar_wnt_.tmp
  281. else
  282. > _shar_wnt_.tmp
  283. echo 'x - extracting qdownm.xbm (Text)'
  284. sed 's/^X//' << 'SHAR_EOF' > 'qdownm.xbm' &&
  285. #define qdownmask_width 16
  286. #define qdownmask_height 16
  287. static char qdownmask_bits[] = {
  288. X   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
  289. X   0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x3d, 0xf8, 0x3c, 0x78, 0x3c,
  290. X   0xf8, 0x3e, 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x0f};
  291. SHAR_EOF
  292. chmod 0644 qdownm.xbm ||
  293. echo 'restore of qdownm.xbm failed'
  294. Wc_c="`wc -c < 'qdownm.xbm'`"
  295. test 290 -eq "$Wc_c" ||
  296.     echo 'qdownm.xbm: original size 290, current size' "$Wc_c"
  297. rm -f _shar_wnt_.tmp
  298. fi
  299. # ============= qleft.xbm ==============
  300. if test -f 'qleft.xbm' -a X"$1" != X"-c"; then
  301.     echo 'x - skipping qleft.xbm (File already exists)'
  302.     rm -f _shar_wnt_.tmp
  303. else
  304. > _shar_wnt_.tmp
  305. echo 'x - extracting qleft.xbm (Text)'
  306. sed 's/^X//' << 'SHAR_EOF' > 'qleft.xbm' &&
  307. #define qleft_width 16
  308. #define qleft_height 16
  309. #define qleft_x_hot 7
  310. #define qleft_y_hot 8
  311. static char qleft_bits[] = {
  312. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x7c, 0x00,
  313. X   0xc6, 0x00, 0x82, 0x67, 0x02, 0x67, 0x02, 0x00, 0x06, 0x00, 0x3c, 0x00,
  314. X   0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  315. SHAR_EOF
  316. chmod 0644 qleft.xbm ||
  317. echo 'restore of qleft.xbm failed'
  318. Wc_c="`wc -c < 'qleft.xbm'`"
  319. test 322 -eq "$Wc_c" ||
  320.     echo 'qleft.xbm: original size 322, current size' "$Wc_c"
  321. rm -f _shar_wnt_.tmp
  322. fi
  323. # ============= qleftm.xbm ==============
  324. if test -f 'qleftm.xbm' -a X"$1" != X"-c"; then
  325.     echo 'x - skipping qleftm.xbm (File already exists)'
  326.     rm -f _shar_wnt_.tmp
  327. else
  328. > _shar_wnt_.tmp
  329. echo 'x - extracting qleftm.xbm (Text)'
  330. sed 's/^X//' << 'SHAR_EOF' > 'qleftm.xbm' &&
  331. #define qleftmask_width 16
  332. #define qleftmask_height 16
  333. static char qleftmask_bits[] = {
  334. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01,
  335. X   0xff, 0xff, 0xef, 0xff, 0xc7, 0xff, 0x8f, 0xff, 0x7f, 0x00, 0x7f, 0x00,
  336. X   0x7e, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00};
  337. SHAR_EOF
  338. chmod 0644 qleftm.xbm ||
  339. echo 'restore of qleftm.xbm failed'
  340. Wc_c="`wc -c < 'qleftm.xbm'`"
  341. test 290 -eq "$Wc_c" ||
  342.     echo 'qleftm.xbm: original size 290, current size' "$Wc_c"
  343. rm -f _shar_wnt_.tmp
  344. fi
  345. # ============= qright.xbm ==============
  346. if test -f 'qright.xbm' -a X"$1" != X"-c"; then
  347.     echo 'x - skipping qright.xbm (File already exists)'
  348.     rm -f _shar_wnt_.tmp
  349. else
  350. > _shar_wnt_.tmp
  351. echo 'x - extracting qright.xbm (Text)'
  352. sed 's/^X//' << 'SHAR_EOF' > 'qright.xbm' &&
  353. #define qright_width 16
  354. #define qright_height 16
  355. #define qright_x_hot 8
  356. #define qright_y_hot 7
  357. static char qright_bits[] = {
  358. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x60,
  359. X   0x00, 0x40, 0xe6, 0x40, 0xe6, 0x41, 0x00, 0x63, 0x00, 0x3e, 0x00, 0x1c,
  360. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  361. SHAR_EOF
  362. chmod 0644 qright.xbm ||
  363. echo 'restore of qright.xbm failed'
  364. Wc_c="`wc -c < 'qright.xbm'`"
  365. test 327 -eq "$Wc_c" ||
  366.     echo 'qright.xbm: original size 327, current size' "$Wc_c"
  367. rm -f _shar_wnt_.tmp
  368. fi
  369. # ============= qrightm.xbm ==============
  370. if test -f 'qrightm.xbm' -a X"$1" != X"-c"; then
  371.     echo 'x - skipping qrightm.xbm (File already exists)'
  372.     rm -f _shar_wnt_.tmp
  373. else
  374. > _shar_wnt_.tmp
  375. echo 'x - extracting qrightm.xbm (Text)'
  376. sed 's/^X//' << 'SHAR_EOF' > 'qrightm.xbm' &&
  377. #define qrightmask_width 16
  378. #define qrightmask_height 16
  379. static char qrightmask_bits[] = {
  380. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00, 0xfe,
  381. X   0xff, 0xf1, 0xff, 0xe3, 0xff, 0xf7, 0xff, 0xff, 0x80, 0xff, 0x00, 0x7f,
  382. X   0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  383. SHAR_EOF
  384. chmod 0644 qrightm.xbm ||
  385. echo 'restore of qrightm.xbm failed'
  386. Wc_c="`wc -c < 'qrightm.xbm'`"
  387. test 293 -eq "$Wc_c" ||
  388.     echo 'qrightm.xbm: original size 293, current size' "$Wc_c"
  389. rm -f _shar_wnt_.tmp
  390. fi
  391. # ============= qup.xbm ==============
  392. if test -f 'qup.xbm' -a X"$1" != X"-c"; then
  393.     echo 'x - skipping qup.xbm (File already exists)'
  394.     rm -f _shar_wnt_.tmp
  395. else
  396. > _shar_wnt_.tmp
  397. echo 'x - extracting qup.xbm (Text)'
  398. sed 's/^X//' << 'SHAR_EOF' > 'qup.xbm' &&
  399. #define qup_width 16
  400. #define qup_height 16
  401. #define qup_x_hot 7
  402. #define qup_y_hot 7
  403. static char qup_bits[] = {
  404. X   0x00, 0x00, 0xe0, 0x03, 0x30, 0x06, 0x18, 0x0c, 0x18, 0x0c, 0x18, 0x0c,
  405. X   0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00,
  406. X   0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00};
  407. SHAR_EOF
  408. chmod 0644 qup.xbm ||
  409. echo 'restore of qup.xbm failed'
  410. Wc_c="`wc -c < 'qup.xbm'`"
  411. test 312 -eq "$Wc_c" ||
  412.     echo 'qup.xbm: original size 312, current size' "$Wc_c"
  413. rm -f _shar_wnt_.tmp
  414. fi
  415. # ============= qupm.xbm ==============
  416. if test -f 'qupm.xbm' -a X"$1" != X"-c"; then
  417.     echo 'x - skipping qupm.xbm (File already exists)'
  418.     rm -f _shar_wnt_.tmp
  419. else
  420. > _shar_wnt_.tmp
  421. echo 'x - extracting qupm.xbm (Text)'
  422. sed 's/^X//' << 'SHAR_EOF' > 'qupm.xbm' &&
  423. #define qupmask_width 16
  424. #define qupmask_height 16
  425. static char qupmask_bits[] = {
  426. X   0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f, 0x7c, 0x1f, 0x3c, 0x1e, 0x3c, 0x1f,
  427. X   0xbc, 0x1f, 0xc0, 0x0f, 0xc0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
  428. X   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03};
  429. SHAR_EOF
  430. chmod 0644 qupm.xbm ||
  431. echo 'restore of qupm.xbm failed'
  432. Wc_c="`wc -c < 'qupm.xbm'`"
  433. test 284 -eq "$Wc_c" ||
  434.     echo 'qupm.xbm: original size 284, current size' "$Wc_c"
  435. rm -f _shar_wnt_.tmp
  436. fi
  437. # ============= vier.c ==============
  438. if test -f 'vier.c' -a X"$1" != X"-c"; then
  439.     echo 'x - skipping vier.c (File already exists)'
  440.     rm -f _shar_wnt_.tmp
  441. else
  442. > _shar_wnt_.tmp
  443. echo 'x - extracting vier.c (Text)'
  444. sed 's/^X//' << 'SHAR_EOF' > 'vier.c' &&
  445. #include <stdio.h>
  446. #include <sys/types.h>
  447. #include <sys/time.h>
  448. X
  449. time_t time();
  450. X
  451. #include "vier.h"
  452. #include "xvier.h"
  453. X
  454. int rows, columns, vnum;
  455. int row_col, row_1_col, row_2_col;
  456. int *brett, *weiss, *schwarz, **freip, **doublesp;
  457. int frei[MAXRC], reihenfolge[MAXRC], doubles[MAXRC];
  458. int (*pu)[4];
  459. int *_p_h_, **pp;
  460. struct oldv *stack, *sp, **zugstack;
  461. int bewertung = 0;
  462. X
  463. int zugstackp = 0, level = 2;
  464. X
  465. #define WEISS    1
  466. #define SCHWARZ  2
  467. #define W_WINS   4
  468. #define S_WINS   8
  469. #define USELESS 16
  470. X
  471. char read_char(ch)
  472. char *ch;
  473. {
  474. X  if (read(0, ch, 1) < 1) {
  475. X    perror("xvier_prog read failed");
  476. X    exit(1);
  477. X  }
  478. X  return *ch;
  479. }
  480. X
  481. void write_char(ch)
  482. char ch;
  483. {
  484. X  if (write(1, &ch, 1) < 1) {
  485. X    perror("xvier_prog write failed");
  486. X    exit(1);
  487. X  }
  488. }
  489. X
  490. void w_test(pos)
  491. int pos;
  492. {
  493. X  register int *p, j;
  494. X  int oben;
  495. X
  496. X  /* leere Position suchen */
  497. X  for (p = pu[pos]; brett[*p] & (WEISS | SCHWARZ); p++);
  498. X  if (brett[j = *p] & (W_WINS | USELESS))
  499. X    return;
  500. X  sp -> pos = brett + j;
  501. X  sp++ -> value = brett[j];
  502. X  brett[j] |= W_WINS;
  503. X  if (*doublesp[j] == SCHWARZ &&
  504. X      j > *freip[j] &&
  505. X      j < row_1_col &&
  506. X      !(brett[j+columns] & USELESS)) {
  507. X    sp -> pos = doublesp[j];
  508. X    sp++ -> value = SCHWARZ;
  509. X    *doublesp[j] = 0;
  510. X  }
  511. X  if (!*doublesp[j] &&
  512. X      ((j > *freip[j] + columns &&
  513. X    (brett[(oben = j) - columns] & W_WINS)) ||
  514. X       (j > *freip[j] && j < row_1_col &&
  515. X    (brett[oben = j + columns] & W_WINS)))) {
  516. X    register int k;
  517. X
  518. X    for (k = *freip[j]; k < oben; k += columns)
  519. X      if (brett[k] & S_WINS)
  520. X    goto no_double;
  521. X    sp -> pos = doublesp[j];
  522. X    sp++ -> value = 0;
  523. X    *doublesp[j] = WEISS;
  524. X  }
  525. X no_double:
  526. X  if (j < row_1_col &&
  527. X      ((brett[oben = j] & S_WINS) ||
  528. X       (j > *freip[j] && (brett[j - columns] & W_WINS)) ||
  529. X       (j < row_2_col &&
  530. X    (brett[oben = j + columns] & W_WINS))))
  531. X    for (j = oben + columns;
  532. X     j < row_col && !(brett[j] & USELESS);
  533. X     j += columns) {
  534. X      register int h1, h2;
  535. X
  536. X      /* Vierer darueber sind nutzlos */
  537. X      sp -> pos = brett + j;
  538. X      sp++ -> value = brett[j];
  539. X      brett[j] |= USELESS;
  540. X      p = pp[j];
  541. X      while ((h1 = *(p++)) >= 0) {
  542. X    if ((h2 = weiss[h1]) >= 0) {
  543. X      sp -> pos = &weiss[h1];
  544. X      sp++ -> value = h2;
  545. X      weiss[h1] = -1;
  546. X      bewertung -= h2;
  547. X    }
  548. X    if ((h2 = schwarz[h1]) >= 0) {
  549. X      sp -> pos = &schwarz[h1];
  550. X      sp++ -> value = h2;
  551. X      schwarz[h1] = -1;
  552. X      bewertung += h2;
  553. X    }
  554. X      }
  555. X    }
  556. }
  557. void s_test(pos)
  558. int pos;
  559. {
  560. X  register int *p, j;
  561. X  int oben;
  562. X
  563. X  /* leere Position suchen */
  564. X  for (p = pu[pos]; brett[*p] & (WEISS | SCHWARZ); p++);
  565. X  if (brett[j = *p] & (S_WINS | USELESS))
  566. X    return;
  567. X  sp -> pos = brett + j;
  568. X  sp++ -> value = brett[j];
  569. X  brett[j] |= S_WINS;
  570. X  if (*doublesp[j] == WEISS &&
  571. X      j > *freip[j] &&
  572. X      j < row_1_col &&
  573. X      !(brett[j+columns] & USELESS)) {
  574. X    sp -> pos = doublesp[j];
  575. X    sp++ -> value = WEISS;
  576. X    *doublesp[j] = 0;
  577. X  }
  578. X  if (!*doublesp[j] &&
  579. X      ((j > *freip[j] + columns &&
  580. X    (brett[(oben = j) - columns] & S_WINS)) ||
  581. X       (j > *freip[j] && j < row_1_col &&
  582. X    (brett[oben = j + columns] & S_WINS)))) {
  583. X    register int k;
  584. X
  585. X    for (k = *freip[j]; k < oben; k += columns)
  586. X      if (brett[k] & W_WINS)
  587. X    goto no_double;
  588. X    sp -> pos = doublesp[j];
  589. X    sp++ -> value = 0;
  590. X    *doublesp[j] = SCHWARZ;
  591. X  }
  592. X no_double:
  593. X  if (j < row_1_col &&
  594. X      ((brett[oben = j] & W_WINS) ||
  595. X       (j > *freip[j] && (brett[j - columns] & S_WINS)) ||
  596. X       (j < row_2_col &&
  597. X    (brett[oben = j + columns] & S_WINS))))
  598. X    for (j = oben + columns;
  599. X     j < row_col && !(brett[j] & USELESS);
  600. X     j += columns) {
  601. X      register int h1, h2;
  602. X
  603. X      /* Vierer darueber sind nutzlos */
  604. X      sp -> pos = brett + j;
  605. X      sp++ -> value = brett[j];
  606. X      brett[j] |= USELESS;
  607. X      p = pp[j];
  608. X      while ((h1 = *(p++)) >= 0) {
  609. X    if ((h2 = weiss[h1]) >= 0) {
  610. X      sp -> pos = &weiss[h1];
  611. X      sp++ -> value = h2;
  612. X      weiss[h1] = -1;
  613. X      bewertung -= h2;
  614. X    }
  615. X    if ((h2 = schwarz[h1]) >= 0) {
  616. X      sp -> pos = &schwarz[h1];
  617. X      sp++ -> value = h2;
  618. X      schwarz[h1] = -1;
  619. X      bewertung += h2;
  620. X    }
  621. X      }
  622. X    }
  623. }
  624. X
  625. int w_zugzwang(remain)
  626. int remain;
  627. {
  628. X  register int i, pos, poslev = 7, p_s_p = 0;
  629. X  int p_stack[MAXRC];
  630. X
  631. X  for (i = 0; i < columns; i++) {
  632. X    register int f = frei[i];
  633. X
  634. X    if (f < row_col) {
  635. X      if (brett[f] & W_WINS)
  636. X    return 8 + 8 * remain;
  637. X      if (brett[f] & S_WINS) {
  638. X    pos = i;
  639. X    poslev = 1;
  640. X      } else if (poslev > 2) {
  641. X    if (doubles[i] == WEISS) {
  642. X      pos = i;
  643. X      poslev = 2;
  644. X    } else if (poslev > 3) {
  645. X      if (f >= row_1_col ||
  646. X          ((brett[f + columns] & (W_WINS | S_WINS)) == 0 &&
  647. X           !doubles[i])) {
  648. X        pos = i;
  649. X        poslev = 3;
  650. X      } else if (poslev > 4) {
  651. X        if ((brett[f + columns] & (W_WINS | S_WINS)) == 0) {
  652. X          pos = i;
  653. X          poslev = 4;
  654. X        } else if ((brett[f + columns] & S_WINS) == 0) {
  655. X          p_stack[p_s_p++] = pos = i;
  656. X          poslev = 5;
  657. X        } else if (poslev > 6) {
  658. X          pos = i;
  659. X          poslev = 6;
  660. X        }
  661. X      }
  662. X    }
  663. X      }
  664. X    }
  665. X  }
  666. X  if (poslev == 7)
  667. X    return 0;
  668. X  if (poslev == 5 && p_s_p > 1) {
  669. X    int m;
  670. X
  671. X    frei[p_stack[0]] += columns;
  672. X    m = s_zugzwang(remain-1);
  673. X    frei[p_stack[0]] -= columns;
  674. X    for (i = 1; i < p_s_p; i++) {
  675. X      register int tmp;
  676. X
  677. X      frei[p_stack[i]] += columns;
  678. X      if ((tmp = s_zugzwang(remain-1)) > m)
  679. X    m = tmp;
  680. X      frei[p_stack[i]] -= columns;
  681. X    }
  682. X    return m;
  683. X  } else {
  684. X    frei[pos] += columns;
  685. X    i = s_zugzwang(remain-1);
  686. X    frei[pos] -= columns;
  687. X    return i;
  688. X  }
  689. }
  690. X
  691. int s_zugzwang(remain)
  692. int remain;
  693. {
  694. X  register int i, pos, poslev = 7, p_s_p = 0;
  695. X  int p_stack[MAXRC];
  696. X
  697. X  for (i = 0; i < columns; i++) {
  698. X    register int f = frei[i];
  699. X
  700. X    if (f < row_col) {
  701. X      if (brett[f] & S_WINS)
  702. X    return -8 - 8 * remain;
  703. X      if (brett[f] & W_WINS) {
  704. X    pos = i;
  705. X    poslev = 1;
  706. X      } else if (poslev > 2) {
  707. X    if (doubles[i] == SCHWARZ) {
  708. X      pos = i;
  709. X      poslev = 2;
  710. X    } else if (poslev > 3) {
  711. X      if (f >= row_1_col ||
  712. X          ((brett[f + columns] & (W_WINS | S_WINS)) == 0 &&
  713. X           !doubles[i])) {
  714. X        pos = i;
  715. X        poslev = 3;
  716. X      } else if (poslev > 4) {
  717. X        if ((brett[f + columns] & (W_WINS | S_WINS)) == 0) {
  718. X          pos = i;
  719. X          poslev = 4;
  720. X        } else if ((brett[f + columns] & W_WINS) == 0) {
  721. X          p_stack[p_s_p++] = pos = i;
  722. X          poslev = 5;
  723. X        } else if (poslev > 6) {
  724. X          pos = i;
  725. X          poslev = 6;
  726. X        }
  727. X      }
  728. X    }
  729. X      }
  730. X    }
  731. X  }
  732. X  if (poslev == 7)
  733. X    return 0;
  734. X  if (poslev == 5 && p_s_p > 1) {
  735. X    int m;
  736. X
  737. X    frei[p_stack[0]] += columns;
  738. X    m = w_zugzwang(remain-1);
  739. X    frei[p_stack[0]] -= columns;
  740. X    for (i = 1; i < p_s_p; i++) {
  741. X      register int tmp;
  742. X
  743. X      frei[p_stack[i]] += columns;
  744. X      if ((tmp = w_zugzwang(remain-1)) < m)
  745. X    m = tmp;
  746. X      frei[p_stack[i]] -= columns;
  747. X    }
  748. X    return m;
  749. X  } else {
  750. X    frei[pos] += columns;
  751. X    i = w_zugzwang(remain-1);
  752. X    frei[pos] -= columns;
  753. X    return i;
  754. X  }
  755. }
  756. X
  757. int comp_weiss(pos, lev, limit)
  758. int pos, lev, limit;
  759. {
  760. X  register int  h1, h2, i, j, *p;
  761. X  int   *frp, wert;
  762. X  struct oldv *sold;
  763. X
  764. X  if (brett[pos] & W_WINS)
  765. X    return 50000 - lev;
  766. X  /* Zug fuer Weiss ausfuehren */
  767. X  sold = sp;
  768. X  sp -> pos = frp = freip[pos];
  769. X  sp++ -> value = *frp;
  770. X  sp -> pos = brett + pos;
  771. X  sp++ -> value = brett[pos];
  772. X  sp -> pos = &bewertung;
  773. X  sp++ -> value = bewertung;
  774. X  *frp += columns;
  775. X  brett[pos] |= WEISS;
  776. X  p = pp[pos];
  777. X  while ((h1 = *(p++)) >= 0) {
  778. X    if ((h2 = weiss[h1]) >= 0) {
  779. X      sp -> pos = &weiss[h1];
  780. X      sp++ -> value = h2;
  781. X      weiss[h1]++;
  782. X      bewertung++;
  783. X      if (h2 == 3)
  784. X    w_test (h1);
  785. X    }
  786. X    if ((h2 = schwarz[h1]) >= 0) {
  787. X      sp -> pos = &schwarz[h1];
  788. X      sp++ -> value = h2;
  789. X      schwarz[h1] = -1;
  790. X      bewertung += h2;
  791. X    }
  792. X  }
  793. X  h1 = -1;
  794. X  for (i = 0; i < columns; i++) {
  795. X    register int f = frei[i];
  796. X
  797. X    if (f < row_col) {
  798. X      if (brett[f] & S_WINS) {
  799. X    wert = -49999 + lev;
  800. X    goto end;
  801. X      }
  802. X      if (brett[f] & W_WINS)
  803. X    h1 = f;
  804. X    }
  805. X  }
  806. X  if (h1 >= 0) {
  807. X    level++;
  808. X    wert = comp_schwarz(h1, lev + 1, 100000);
  809. X    level--;
  810. X  } else if (lev >= level)
  811. X    wert = bewertung + s_zugzwang(40 - lev - zugstackp);
  812. X  else {
  813. X    register int    zw;
  814. X
  815. X    wert = 100000;
  816. X    for (i = 0; i < columns; i++) {
  817. X      j = frei[reihenfolge[i]];
  818. X      if (j < row_col)
  819. X    if ((zw = comp_schwarz (j, lev + 1, wert)) < wert)
  820. X      if ((wert = zw) <= limit)
  821. X        break;
  822. X      /* Schwarz wird wohl den fuer ihn guenstigsten Zug auswaehlen */
  823. X    }
  824. X    if (wert == 100000)
  825. X      wert = 0;        /* unentschieden */
  826. X  }
  827. X end:
  828. X  while (sp != sold) {
  829. X    sp--;
  830. X    *(sp -> pos) = sp -> value;
  831. X  }
  832. X  return (wert);
  833. }
  834. X
  835. int comp_schwarz(pos, lev, limit)
  836. int pos, lev, limit;
  837. {
  838. X  register int  h1, h2, i, j, *p;
  839. X  int   *frp, wert;
  840. X  struct oldv *sold;
  841. X
  842. X  if (brett[pos] & S_WINS)
  843. X    return -50000 + lev;
  844. X  /* Zug fuer Schwarz ausfuehren */
  845. X  sold = sp;
  846. X  sp -> pos = frp = freip[pos];
  847. X  sp++ -> value = *frp;
  848. X  sp -> pos = brett + pos;
  849. X  sp++ -> value = brett[pos];
  850. X  sp -> pos = &bewertung;
  851. X  sp++ -> value = bewertung;
  852. X  *frp += columns;
  853. X  brett[pos] |= SCHWARZ;
  854. X  p = pp[pos];
  855. X  while ((h1 = *(p++)) >= 0) {
  856. X    if ((h2 = schwarz[h1]) >= 0) {
  857. X      sp -> pos = &schwarz[h1];
  858. X      sp++ -> value = h2;
  859. X      schwarz[h1]++;
  860. X      bewertung--;
  861. X      if (h2 == 3)
  862. X    s_test (h1);
  863. X    }
  864. X    if ((h2 = weiss[h1]) >= 0) {
  865. X      sp -> pos = &weiss[h1];
  866. X      sp++ -> value = h2;
  867. X      weiss[h1] = -1;
  868. X      bewertung -= h2;
  869. X    }
  870. X  }
  871. X  h1 = -1;
  872. X  for (i = 0; i < columns; i++) {
  873. X    register int f = frei[i];
  874. X
  875. X    if (f < row_col) {
  876. X      if (brett[f] & W_WINS) {
  877. X    wert = 49999 - lev;
  878. X    goto end;
  879. X      }
  880. X      if (brett[f] & S_WINS)
  881. X    h1 = f;
  882. X    }
  883. X  }
  884. X  if (h1 >= 0) {
  885. X    level++;
  886. X    wert = comp_weiss(h1, lev + 1, -100000);
  887. X    level--;
  888. X  } else if (lev >= level)
  889. X    wert = bewertung + w_zugzwang(40 - lev - zugstackp);
  890. X  else {
  891. X    register int    zw;
  892. X
  893. X    wert = -100000;
  894. X    for (i = 0; i < columns; i++) {
  895. X      j = frei[reihenfolge[i]];
  896. X      if (j < row_col)
  897. X    if ((zw = comp_weiss (j, lev + 1, wert)) > wert)
  898. X      if ((wert = zw) >= limit)
  899. X        break;
  900. X    }
  901. X    if (wert == -100000)
  902. X      wert = 0;        /* unentschieden */
  903. X  }
  904. X end:
  905. X  while (sp != sold) {
  906. X    sp--;
  907. X    *(sp -> pos) = sp -> value;
  908. X  }
  909. X  return (wert);
  910. }
  911. X
  912. int main(argc, argv)
  913. int argc;
  914. char **argv;
  915. {
  916. X  int  i, j, h1, zj, *p, wert, zi;
  917. X  char ch, buf[10];
  918. X  int  same[MAXRC], same_n;
  919. X
  920. X  if (argc != 3 ||
  921. X      (rows = atoi(argv[1])) < 4 || rows > MAXRC ||
  922. X      (columns = atoi(argv[2])) < 4 || columns > MAXRC) {
  923. X    fprintf(stderr, "Usage: %s <rows> <columns>\n", *argv);
  924. X    exit(1);
  925. X  }
  926. X  vierinit();
  927. X  sprintf(buf, "%dR%dC", rows, columns);
  928. X  for (i = 0; buf[i] != '\0'; i++)
  929. X    write_char(buf[i]);
  930. X  srand((int) time(NULL));
  931. X  while (1) {
  932. X  mensch:
  933. X    read_char(&ch);
  934. X    switch (ch) {
  935. X    case '0': case '1': case '2': case '3': case '4':
  936. X    case '5': case '6': case '7': case '8': case '9':
  937. X      write_char(ch);
  938. X      level = ch - '0' + 2;
  939. X      break;
  940. X    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
  941. X    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm':
  942. X      if (ch - 'a' >= columns ||
  943. X      (j = frei[ch - 'a']) >= row_col) {
  944. X    write_char('x');
  945. X    break;
  946. X      }
  947. X      if (brett[j] & W_WINS) {
  948. X    write_char('w');
  949. X    while (read_char(&ch) != 'u')
  950. X      switch (ch) {
  951. X      case '0': case '1': case '2': case '3': case '4':
  952. X      case '5': case '6': case '7': case '8': case '9':
  953. X        write_char(ch);
  954. X        level = ch - '0' + 2;
  955. X        break;
  956. X      case 'n':
  957. X        goto newgame;
  958. X      default:
  959. X        write_char('x');
  960. X        break;
  961. X      }
  962. X    write_char('v');
  963. X    break;
  964. X      }
  965. X      zugstack[zugstackp++] = sp;
  966. X      sp -> pos = brett + j;
  967. X      sp++ -> value = brett[j];
  968. X      sp -> pos = frei + ch - 'a';
  969. X      sp++ -> value = frei[ch - 'a'];
  970. X      sp -> pos = &bewertung;
  971. X      sp++ -> value = bewertung;
  972. X      brett[j] |= WEISS;
  973. X      frei[ch - 'a'] += columns;
  974. X      p = pp[j];
  975. X      while ((h1 = *(p++)) >= 0) {
  976. X    if ((weiss[h1]) >= 0) {
  977. X      sp -> pos = weiss + h1;
  978. X      sp++ -> value = weiss[h1];
  979. X      weiss[h1]++;
  980. X      bewertung++;
  981. X      if (weiss[h1] == 4)
  982. X        w_test(h1);
  983. X    }
  984. X    if ((schwarz[h1]) >= 0) {
  985. X      sp -> pos = schwarz + h1;
  986. X      sp++ -> value = schwarz[h1];
  987. X      bewertung += schwarz[h1];
  988. X      schwarz[h1] = -1;
  989. X    }
  990. X      }
  991. X    computer:
  992. X      same_n = 0;
  993. X      for (i = 0; i < columns; i++) {
  994. X    int f = frei[i];
  995. X    
  996. X    if (f < row_col) {
  997. X      if (brett[f] & S_WINS) {
  998. X        zi = i;
  999. X        goto calculate_end;
  1000. X      }
  1001. X      if (brett[f] & W_WINS)
  1002. X        same[same_n++] = i;
  1003. X    }
  1004. X      }
  1005. X      if (same_n == 0) {
  1006. X    wert = 100000;
  1007. X    for (i = 0; i < columns; i++) {
  1008. X      register int zw;
  1009. X      
  1010. X      if ((j = frei[reihenfolge[i]]) < row_col)
  1011. X        if ((zw = comp_schwarz (j, 0, wert + 1)) < wert) {
  1012. X          wert = zw;
  1013. X          same_n = 1;
  1014. X          same[0] = reihenfolge[i];
  1015. X        } else if (zw == wert)
  1016. X          same[same_n++] = reihenfolge[i];
  1017. X    }
  1018. X      }
  1019. X      if (same_n == 0) {
  1020. X    write_char('z');
  1021. X    while (read_char(&ch) != 'u')
  1022. X      switch (ch) {
  1023. X      case '0': case '1': case '2': case '3': case '4':
  1024. X      case '5': case '6': case '7': case '8': case '9':
  1025. X        write_char(ch);
  1026. X        level = ch - '0' + 2;
  1027. X        break;
  1028. X      case 'n':
  1029. X        goto newgame;
  1030. X      default:
  1031. X        write_char('x');
  1032. X        break;
  1033. X      }
  1034. X    write_char('v');
  1035. X    zugstackp--;
  1036. X    while (sp != zugstack[zugstackp]) {
  1037. X      sp--;
  1038. X      *(sp -> pos) = sp -> value;
  1039. X    }
  1040. X    break;
  1041. X      }
  1042. X      if (same_n == 1)
  1043. X    zi = same[0];
  1044. X      else
  1045. X    zi = same[rand() % same_n];
  1046. X    calculate_end:
  1047. X      zj = frei[zi];
  1048. X      if (brett[zj] & S_WINS) {
  1049. X    write_char('A' + zi);
  1050. X    while (read_char(&ch) != 'u')
  1051. X      switch (ch) {
  1052. X      case '0': case '1': case '2': case '3': case '4':
  1053. X      case '5': case '6': case '7': case '8': case '9':
  1054. X        write_char(ch);
  1055. X        level = ch - '0' + 2;
  1056. X        break;
  1057. X      case 'n':
  1058. X        goto newgame;
  1059. X      default:
  1060. X        write_char('x');
  1061. X        break;
  1062. X      }
  1063. X    write_char('u');
  1064. X    zugstackp--;
  1065. X    while (sp != zugstack[zugstackp]) {
  1066. X      sp--;
  1067. X      *(sp -> pos) = sp -> value;
  1068. X    }
  1069. X    break;
  1070. X      }
  1071. X      zugstack[zugstackp++] = sp;
  1072. X      sp -> pos = brett + zj;
  1073. X      sp++ -> value = brett[zj];
  1074. X      sp -> pos = frei + zi;
  1075. X      sp++ -> value = zj;
  1076. X      sp -> pos = &bewertung;
  1077. X      sp++ -> value = bewertung;
  1078. X      brett[zj] |= SCHWARZ;
  1079. X      frei[zi] += columns;
  1080. X      p = pp[zj];
  1081. X      while ((h1 = *(p++)) >= 0) {
  1082. X    if ((schwarz[h1]) >= 0) {
  1083. X      sp -> pos = schwarz + h1;
  1084. X      sp++ -> value = schwarz[h1];
  1085. X      schwarz[h1]++;
  1086. X      bewertung--;
  1087. X      if (schwarz[h1] == 4)
  1088. X        s_test(h1);
  1089. X    }
  1090. X    if ((weiss[h1]) >= 0) {
  1091. X      sp -> pos = weiss + h1;
  1092. X      sp++ -> value = weiss[h1];
  1093. X      bewertung -= weiss[h1];
  1094. X      weiss[h1] = -1;
  1095. X    }
  1096. X      }
  1097. X      if (frei[zi] < row_col && (brett[frei[zi]] & USELESS)) {
  1098. X    /* user didn't recognize a double */
  1099. X    for (i = frei[zi]; i < row_col; i+= columns) {
  1100. X      int w_wins = 0, s_wins = 0;
  1101. X
  1102. X      sp -> pos = brett + i;
  1103. X      sp++ -> value = brett[i];
  1104. X      brett[i] = 0;
  1105. X      p = pp[i];
  1106. X      while ((h1 = *(p++)) >= 0) {
  1107. X        int wval = 1, sval = 1;
  1108. X
  1109. X        for (j = 0; j < 4; j++) {
  1110. X          if (brett[pu[h1][j]] & USELESS) {
  1111. X        wval = -1;
  1112. X        sval = -1;
  1113. X          } else if (brett[pu[h1][j]] & WEISS) {
  1114. X        if (wval > 0)
  1115. X          wval++;
  1116. X          } else if (brett[pu[h1][j]] & SCHWARZ) {
  1117. X        if (sval > 0)
  1118. X          sval++;
  1119. X          }
  1120. X        }
  1121. X        if (wval > 0) {
  1122. X          bewertung += wval;
  1123. X          sp -> pos = weiss + h1;
  1124. X          sp++ -> value = weiss[h1];
  1125. X          weiss[h1] = wval;
  1126. X          if (wval == 4)
  1127. X        w_wins = 1;
  1128. X        }
  1129. X        if (sval > 0) {
  1130. X          bewertung -= sval;
  1131. X          sp -> pos = schwarz + h1;
  1132. X          sp++ -> value = schwarz[h1];
  1133. X          schwarz[h1] = sval;
  1134. X          if (sval == 4)
  1135. X        s_wins = 1;
  1136. X        }
  1137. X      }
  1138. X      if (w_wins && s_wins) {
  1139. X        brett[i] |= (W_WINS | S_WINS);
  1140. X        if (i > frei[zi] + columns) {
  1141. X          if (brett[i - columns] & W_WINS) {
  1142. X        if (*doublesp[i] != WEISS) {
  1143. X          sp -> pos = doublesp[i];
  1144. X          sp++ -> value = *doublesp[i];
  1145. X          *doublesp[i] = WEISS;
  1146. X        }
  1147. X          } else if (brett[i - columns] & S_WINS) {
  1148. X        if (*doublesp[i] != SCHWARZ) {
  1149. X          sp -> pos = doublesp[i];
  1150. X          sp++ -> value = *doublesp[i];
  1151. X          *doublesp[i] = SCHWARZ;
  1152. X        }
  1153. X          }
  1154. X        }
  1155. X        break;
  1156. X      } else if (w_wins) {
  1157. X        brett[i] |= W_WINS;
  1158. X        if (i > frei[zi] + columns && (brett[i - columns] & W_WINS)) {
  1159. X          if (*doublesp[i] != WEISS) {
  1160. X        sp -> pos = doublesp[i];
  1161. X        sp++ -> value = *doublesp[i];
  1162. X        *doublesp[i] = WEISS;
  1163. X          }
  1164. X          break;
  1165. X        }
  1166. X      } else if (s_wins) {
  1167. X        brett[i] |= S_WINS;
  1168. X        if (i > frei[zi] + columns  && (brett[i - columns] & S_WINS)) {
  1169. X          if (*doublesp[i] != SCHWARZ) {
  1170. X        sp -> pos = doublesp[i];
  1171. X        sp++ -> value = *doublesp[i];
  1172. X        *doublesp[i] = SCHWARZ;
  1173. X          }
  1174. X          break;
  1175. X        }
  1176. X      }
  1177. X    }
  1178. X      }
  1179. X      for (i = 0; i < columns; i++)
  1180. X    if (frei[i] < row_col) {
  1181. X      write_char('a' + zi);
  1182. X      goto mensch;
  1183. X    }
  1184. X      /* unentschieden */
  1185. X      write_char('N' + zi);
  1186. X      while (read_char(&ch) != 'u')
  1187. X    switch (ch) {
  1188. X    case '0': case '1': case '2': case '3': case '4':
  1189. X    case '5': case '6': case '7': case '8': case '9':
  1190. X      write_char(ch);
  1191. X      level = ch - '0' + 2;
  1192. X      break;
  1193. X    case 'n':
  1194. X      goto newgame;
  1195. X    default:
  1196. X      write_char('x');
  1197. X      break;
  1198. X    }
  1199. X      write_char('u');
  1200. X      zugstackp -= 2;
  1201. X      while (sp != zugstack[zugstackp]) {
  1202. X    sp--;
  1203. X    *(sp -> pos) = sp -> value;
  1204. X      }
  1205. X      break;
  1206. X    case 'n':
  1207. X    newgame:
  1208. X      write_char('n');
  1209. X      zugstackp = 0;
  1210. X      while (sp != stack) {
  1211. X    sp--;
  1212. X    *(sp -> pos) = sp -> value;
  1213. X      }
  1214. X      break;
  1215. X    case 'u':
  1216. X      if (zugstackp < 2)
  1217. X    goto newgame;
  1218. X      write_char('u');
  1219. X      zugstackp -= 2;
  1220. X      while (sp != zugstack[zugstackp]) {
  1221. X    sp--;
  1222. X    *(sp -> pos) = sp -> value;
  1223. X      }
  1224. X      break;
  1225. X    case 's':
  1226. X      if (zugstackp == 0)
  1227. X    goto computer;
  1228. X      /* else fall through */
  1229. X    default:
  1230. X      write_char('x');
  1231. X      break;
  1232. X    }
  1233. X  }
  1234. }
  1235. SHAR_EOF
  1236. chmod 0644 vier.c ||
  1237. echo 'restore of vier.c failed'
  1238. Wc_c="`wc -c < 'vier.c'`"
  1239. test 17343 -eq "$Wc_c" ||
  1240.     echo 'vier.c: original size 17343, current size' "$Wc_c"
  1241. rm -f _shar_wnt_.tmp
  1242. fi
  1243. # ============= vier.h ==============
  1244. if test -f 'vier.h' -a X"$1" != X"-c"; then
  1245.     echo 'x - skipping vier.h (File already exists)'
  1246.     rm -f _shar_wnt_.tmp
  1247. else
  1248. > _shar_wnt_.tmp
  1249. echo 'x - extracting vier.h (Text)'
  1250. sed 's/^X//' << 'SHAR_EOF' > 'vier.h' &&
  1251. char *malloc();
  1252. X
  1253. extern int rows, columns, vnum;
  1254. extern int row_col, row_1_col, row_2_col;
  1255. extern int *brett, *weiss, *schwarz, **freip, **doublesp;
  1256. extern int frei[], reihenfolge[], doubles[];
  1257. extern int (*pu)[4];
  1258. extern int *_p_h_, **pp;
  1259. extern struct oldv {
  1260. X  int *pos, value;
  1261. } *stack, *sp, **zugstack;
  1262. SHAR_EOF
  1263. chmod 0644 vier.h ||
  1264. echo 'restore of vier.h failed'
  1265. Wc_c="`wc -c < 'vier.h'`"
  1266. test 307 -eq "$Wc_c" ||
  1267.     echo 'vier.h: original size 307, current size' "$Wc_c"
  1268. rm -f _shar_wnt_.tmp
  1269. fi
  1270. # ============= vierinit.c ==============
  1271. if test -f 'vierinit.c' -a X"$1" != X"-c"; then
  1272.     echo 'x - skipping vierinit.c (File already exists)'
  1273.     rm -f _shar_wnt_.tmp
  1274. else
  1275. > _shar_wnt_.tmp
  1276. echo 'x - extracting vierinit.c (Text)'
  1277. sed 's/^X//' << 'SHAR_EOF' > 'vierinit.c' &&
  1278. #include <stdio.h>
  1279. X
  1280. #include "xvier.h"
  1281. #include "vier.h"
  1282. X
  1283. void vierinit()
  1284. {
  1285. X  int i, j, pui;
  1286. X
  1287. X  vnum = rows * (columns - 3) + columns * (rows - 3) +
  1288. X    2 * (columns - 3) * (rows - 3);
  1289. X  row_col = rows * columns;
  1290. X  row_1_col = row_col - columns;
  1291. X  row_2_col = row_1_col - columns;
  1292. X  brett = (int *)malloc(row_col * sizeof(int));
  1293. X  for (i = 0; i < (row_col); i++)
  1294. X    brett[i] = 0;
  1295. X  weiss = (int *)malloc(vnum * sizeof(int));
  1296. X  schwarz = (int *)malloc(vnum * sizeof(int));
  1297. X  for (i = 0; i < vnum; i++)
  1298. X    weiss[i] = schwarz[i] = 1;
  1299. X  for (i = 0; i < columns; i++) {
  1300. X    frei[i] = i;
  1301. X    doubles[i] = 0;
  1302. X  }
  1303. X  freip = (int **)malloc(row_col * sizeof(int *));
  1304. X  for (j = 0; j < rows; j++)
  1305. X    for (i = 0; i < columns; i++)
  1306. X      freip[j * columns + i] = frei + i;
  1307. X  doublesp = (int **)malloc(row_col * sizeof(int *));
  1308. X  for (j = 0; j < rows; j++)
  1309. X    for (i = 0; i < columns; i++)
  1310. X      doublesp[j * columns + i] = doubles + i;
  1311. X  j = 0;
  1312. X  i = ((columns - 1) >> 1);
  1313. X  if (columns & 1)
  1314. X    reihenfolge[j++] = i;
  1315. X  else {
  1316. X    reihenfolge[j++] = i;
  1317. X    reihenfolge[j++] = i + 1;
  1318. X  }
  1319. X  for (i--; i >= 0; i--) {
  1320. X    reihenfolge[j++] = i;
  1321. X    reihenfolge[j++] = columns - 1 - i;
  1322. X  }
  1323. X  pu = (int (*)[4])malloc(vnum * sizeof(*pu));
  1324. X  pui = 0;
  1325. X  for (i = (rows - 1) * columns; i >= 0; i -= columns)
  1326. X    for (j = 0; j <= columns - 4; j++) {
  1327. X      pu[pui][0] = i + j;
  1328. X      pu[pui][1] = i + j + 1;
  1329. X      pu[pui][2] = i + j + 2;
  1330. X      pu[pui][3] = i + j + 3;
  1331. X      pui++;
  1332. X    }
  1333. X  for (i = (rows - 4) * columns; i >= 0; i -= columns)
  1334. X    for (j = 0; j < columns; j++) {
  1335. X      pu[pui][0] = i + j;
  1336. X      pu[pui][1] = i + j + columns;
  1337. X      pu[pui][2] = i + j + 2 * columns;
  1338. X      pu[pui][3] = i + j + 3 * columns;
  1339. X      pui++;
  1340. X    }
  1341. X  for (i = (rows - 4) * columns; i >= 0; i -= columns)
  1342. X    for (j = 3; j < columns; j++) {
  1343. X      pu[pui][0] = i + j;
  1344. X      pu[pui][1] = i + j + columns - 1;
  1345. X      pu[pui][2] = i + j + 2 * (columns - 1);
  1346. X      pu[pui][3] = i + j + 3 * (columns - 1);
  1347. X      pui++;
  1348. X    }
  1349. X  for (i = (rows - 4) * columns; i >= 0; i -= columns)
  1350. X    for (j = 0; j <= columns - 4; j++) {
  1351. X      pu[pui][0] = i + j;
  1352. X      pu[pui][1] = i + j + columns + 1;
  1353. X      pu[pui][2] = i + j + 2 * (columns + 1);
  1354. X      pu[pui][3] = i + j + 3 * (columns + 1);
  1355. X      pui++;
  1356. X    }
  1357. X  _p_h_ = (int *)malloc((row_col + 4 * vnum) * sizeof(int));
  1358. X  pp = (int **)malloc(row_col * sizeof(int));
  1359. X  for (pui = i = 0; i < row_col; i++) {
  1360. X    pp[i] = _p_h_ + pui;
  1361. X    for (j = 0; j < vnum; j++)
  1362. X      if (pu[j][0] == i || pu[j][1] == i || pu[j][2] == i || pu[j][3] == i)
  1363. X    _p_h_[pui++] = j;
  1364. X    _p_h_[pui++] = -1;
  1365. X  }
  1366. X  sp = stack = (struct oldv *)
  1367. X    malloc(4 * (vnum + row_col) * sizeof(struct oldv));
  1368. X  zugstack = (struct oldv **)malloc(row_col * sizeof(struct oldv *));
  1369. }
  1370. SHAR_EOF
  1371. chmod 0644 vierinit.c ||
  1372. echo 'restore of vierinit.c failed'
  1373. Wc_c="`wc -c < 'vierinit.c'`"
  1374. test 2741 -eq "$Wc_c" ||
  1375.     echo 'vierinit.c: original size 2741, current size' "$Wc_c"
  1376. rm -f _shar_wnt_.tmp
  1377. fi
  1378. # ============= xvier.c ==============
  1379. if test -f 'xvier.c' -a X"$1" != X"-c"; then
  1380.     echo 'x - skipping xvier.c (File already exists)'
  1381.     rm -f _shar_wnt_.tmp
  1382. else
  1383. > _shar_wnt_.tmp
  1384. echo 'x - extracting xvier.c (Text)'
  1385. sed 's/^X//' << 'SHAR_EOF' > 'xvier.c' &&
  1386. #include <X11/Xlib.h>
  1387. #include <X11/Xutil.h>
  1388. #include <X11/cursorfont.h>
  1389. #include <stdio.h>
  1390. #include <signal.h>
  1391. #include <sys/types.h>
  1392. #include <sys/time.h>
  1393. X
  1394. #include "xvier.h"
  1395. X
  1396. char *malloc();
  1397. X
  1398. char *displayname = NULL, *geostring = NULL, *fontpattern = NULL;
  1399. int iconic = 0, level = 0;
  1400. int rows = 6, columns = 7;
  1401. Display *mydisplay;
  1402. int myscreen;
  1403. Window topwindow, boardwindow, quitwindow,
  1404. X       newwindow, undowindow, startwindow, changewindow;
  1405. #define TOPBORDERWIDTH 5
  1406. #define DEFAULTWIDTH    (((10 + 50 * columns) * 5 + 3) / 4)
  1407. #define DEFAULTHEIGHT    (10 + 50 * rows)
  1408. #define MINWIDTH    ((DEFAULTWIDTH * 2) / 5)
  1409. #define MINHEIGHT    ((DEFAULTHEIGHT * 2) / 5)
  1410. #ifndef XVIER_WM_ASPECT_BUG
  1411. #define MINASPECTWIDTH    DEFAULTWIDTH
  1412. #define MINASPECTHEIGHT    (2 * DEFAULTHEIGHT)
  1413. #define MAXASPECTWIDTH    (2 * DEFAULTWIDTH)
  1414. #define MAXASPECTHEIGHT    DEFAULTHEIGHT
  1415. #endif
  1416. GC stonegc[2], buttongc, textgc;
  1417. XXEvent myevent;
  1418. KeySym mykey;
  1419. XXSizeHints myhint;
  1420. XXClassHint myclass;
  1421. XXWMHints *mywmhints;
  1422. unsigned long PixelArray[5];
  1423. #define WHITE  PixelArray[0]
  1424. #define BLACK  PixelArray[1]
  1425. #define BLUE   PixelArray[2]
  1426. #define YELLOW PixelArray[3]
  1427. #define RED    PixelArray[4]
  1428. Colormap cmap;
  1429. int private_cmap = 0;
  1430. Cursor cursor_normal, cursor_q[4];
  1431. #include "qup.xbm"
  1432. #include "qupm.xbm"
  1433. #include "qright.xbm"
  1434. #include "qrightm.xbm"
  1435. #include "qdown.xbm"
  1436. #include "qdownm.xbm"
  1437. #include "qleft.xbm"
  1438. #include "qleftm.xbm"
  1439. Pixmap qup, qupmask, qright, qrightmask, qdown, qdownmask, qleft, qleftmask;
  1440. XXColor cursorforeground, cursorbackground;
  1441. int cursor_num;
  1442. #ifndef NO_SELECT
  1443. struct timeval selectval;
  1444. #endif
  1445. unsigned long valuemask;
  1446. XXSetWindowAttributes attributes;
  1447. Pixmap bgpixmap, iconpixmap;
  1448. int icon_w_x[6] = {0, 0, 1, 1, 2, 3},
  1449. X    icon_w_y[6] = {1, 3, 1, 2, 1, 3},
  1450. X    icon_b_x[6] = {0, 1, 1, 2, 2, 3},
  1451. X    icon_b_y[6] = {2, 0, 3, 2, 3, 2};
  1452. #define DEFAULTICONSIZE 64
  1453. #include "patchlevel.h"
  1454. char Title[] = XVIER_VERSION;
  1455. int c_index = 1, message_index = 0;
  1456. char *playercolor[2], levelnumstring[2] = "0",
  1457. X     *messagestring[5], yellowmovestring[20],
  1458. X     redmovestring[20];
  1459. #define DEFAULTFONTPATTERN "*-Helvetica-Medium-R-Normal-*"
  1460. #define MAXFONTS 100
  1461. XXFontStruct *fontstructarray[MAXFONTS];
  1462. int fontnum, quitposx, quitposy, newposx, newposy,
  1463. X    undoposx, undoposy, startposx, startposy, changeposx, changeposy;
  1464. int text1x, text2x, levely, humany, compy, movey;
  1465. int topwidth = 0, topheight = 0, boardwidth,
  1466. X    buttonwidth, buttonheight, buttonspace,
  1467. X    piece_dx, piece_dy, piece_width, piece_height,
  1468. X    *stone_x[2], *stone_y[2], stone_n[2] = {0, 0};
  1469. XXArc *stone[2], *holes;
  1470. int pipei[2], pipeo[2], pid, processing;
  1471. char *progname = PROGNAME;
  1472. #ifdef NO_SELECT
  1473. #include <poll.h>
  1474. struct pollfd pfd[2];
  1475. unsigned long npfd;
  1476. #else
  1477. #ifdef NO_FD_SET
  1478. int readfds, fullfds;
  1479. #else
  1480. fd_set readfds, fullfds;
  1481. #endif
  1482. #endif
  1483. int *columnfill;
  1484. X
  1485. struct _rgb_vals {
  1486. X  unsigned short red, green, blue;
  1487. } color_values[5] = {
  1488. X    { 65535, 65535, 65535 },
  1489. X    {     0,     0,     0 },
  1490. X    {     0,     0, 65535 },
  1491. X    { 65535, 65535,     0 },
  1492. X    { 65535,     0,     0 }},
  1493. X  gray_values[5] = {
  1494. X    { 65535, 65535, 65535 },
  1495. X    {     0,     0,     0 },
  1496. X    { 32767, 32767, 32767 },
  1497. X    { 65535, 65535, 65535 },
  1498. X    {     0,     0,     0 }},
  1499. X  *rgb_values;
  1500. X
  1501. int font_cmp(p1, p2)
  1502. XXFontStruct **p1, **p2;
  1503. {
  1504. X  int ret = ((*p1)->max_bounds.rbearing + (*p1)->max_bounds.lbearing) -
  1505. X        ((*p2)->max_bounds.rbearing + (*p2)->max_bounds.lbearing);
  1506. X
  1507. X  if (ret == 0)
  1508. X    ret = ((*p1)->max_bounds.ascent + (*p1)->max_bounds.descent) -
  1509. X      ((*p2)->max_bounds.ascent + (*p2)->max_bounds.descent);
  1510. X  return ret;
  1511. }
  1512. X
  1513. void change_cursor()
  1514. {
  1515. X  if (cursor_num == 3)
  1516. X    cursor_num = 0;
  1517. X  else
  1518. X    cursor_num++;
  1519. X  XDefineCursor(mydisplay, topwindow, cursor_q[cursor_num]);
  1520. }
  1521. X
  1522. void write_prog(ch)
  1523. char ch;
  1524. {
  1525. X  if (processing)
  1526. X    XBell(mydisplay, 0);
  1527. X  else {
  1528. X    if (write(pipeo[1], &ch, 1) < 1) {
  1529. X      perror("write to xvier_prog failed");
  1530. X      exit(1);
  1531. X    }
  1532. X    processing = 1;
  1533. X    cursor_num = 0;
  1534. X    XDefineCursor(mydisplay, topwindow, cursor_q[0]);
  1535. X  }
  1536. }
  1537. X
  1538. void message(newindex)
  1539. int newindex;
  1540. {
  1541. X  message_index = newindex;
  1542. X  XClearArea(mydisplay, topwindow, boardwidth,
  1543. X         topheight - movey + compy, 0, 0, False);
  1544. X  XDrawImageString(mydisplay, topwindow, textgc, text1x, movey,
  1545. X           messagestring[newindex], strlen(messagestring[newindex]));
  1546. }
  1547. X
  1548. void domove(ind, col)
  1549. int ind, col;
  1550. {
  1551. X  int n = stone_n[ind]++;
  1552. X
  1553. X  stone_x[ind][n] = col;
  1554. X  stone_y[ind][n] = columnfill[col]++;
  1555. X  stone[ind][n].x = piece_dx + stone_x[ind][n] * (piece_dx + piece_width);
  1556. X  stone[ind][n].y = piece_dy +
  1557. X    (rows - 1 - stone_y[ind][n]) * (piece_dy + piece_height);
  1558. X  stone[ind][n].width = piece_width;
  1559. X  stone[ind][n].height = piece_height;
  1560. X  XFillArc(mydisplay, boardwindow, stonegc[ind], stone[ind][n].x,
  1561. X       stone[ind][n].y, piece_width, piece_height, 0, 360 * 64);
  1562. }
  1563. X
  1564. void undomove(ind)
  1565. int ind;
  1566. {
  1567. X  int n = --stone_n[ind], col = stone_x[ind][n];
  1568. X
  1569. X  columnfill[col]--;
  1570. X  XClearArea(mydisplay, boardwindow, piece_dx / 2 +
  1571. X         col * (piece_dx + piece_width), piece_dy / 2 +
  1572. X         (rows - 1 - stone_y[ind][n]) * (piece_dy + piece_height),
  1573. X         piece_dx + piece_width, piece_dy + piece_height, False);
  1574. X  XDrawArc(mydisplay, boardwindow, textgc, 1 + piece_dx +
  1575. X       col * (piece_dx + piece_width), 1 + piece_dy +
  1576. X       (rows - 1 - stone_y[ind][n]) * (piece_dy + piece_height),
  1577. X       piece_width - 2, piece_height - 2, 0, 360 * 64);
  1578. }
  1579. X
  1580. void recalculate(width, height)
  1581. int width, height;
  1582. {
  1583. X  int i, j, fontid, d1, d2, d3, maxtextwidth, maxtextheight;
  1584. X  XCharStruct tmpsize;
  1585. X
  1586. X  if (width == topwidth && height == topheight)
  1587. X    return;
  1588. X  topwidth = width;
  1589. X  topheight = height;
  1590. X  boardwidth = (topwidth * 4) / 5;
  1591. X  buttonspace = (topwidth - boardwidth) / 10;
  1592. X  buttonwidth = (topwidth - boardwidth) - 2 * buttonspace;
  1593. X  buttonheight = (topheight / 2 - 4 * buttonspace) / 4;
  1594. X  if (buttonheight < 2 * buttonspace) {
  1595. X    buttonspace = topheight / 24;
  1596. X    buttonwidth = (topwidth - boardwidth) - 2 * buttonspace;
  1597. X    buttonheight = (topheight / 2 - 4 * buttonspace) / 4;
  1598. X  }
  1599. X  for (i = 0; i < fontnum; i++) {
  1600. X    int cpx, cpy, qpx, qpy, npx, npy, upx, upy;
  1601. X
  1602. X    XTextExtents(fontstructarray[i], "Change", 6, &d1, &d2, &d3, &tmpsize);
  1603. X    if (i > 0 && (tmpsize.rbearing + tmpsize.lbearing > buttonwidth - 2 ||
  1604. X          tmpsize.ascent + tmpsize.descent > buttonheight - 2))
  1605. X      continue;
  1606. X    cpx = (buttonwidth - tmpsize.lbearing - tmpsize.rbearing) / 2 +
  1607. X      tmpsize.lbearing;
  1608. X    cpy = (buttonheight - tmpsize.ascent - tmpsize.descent) / 2 +
  1609. X      tmpsize.ascent;
  1610. X    XTextExtents(fontstructarray[i], "Quit", 4, &d1, &d2, &d3, &tmpsize);
  1611. X    if (i > 0 && (tmpsize.rbearing + tmpsize.lbearing > buttonwidth - 2 ||
  1612. X          tmpsize.ascent + tmpsize.descent > buttonheight - 2))
  1613. X      continue;
  1614. X    qpx = (buttonwidth - tmpsize.lbearing - tmpsize.rbearing) / 2 +
  1615. X      tmpsize.lbearing;
  1616. X    qpy = (buttonheight - tmpsize.ascent - tmpsize.descent) / 2 +
  1617. X      tmpsize.ascent;
  1618. X    XTextExtents(fontstructarray[i], "New", 3, &d1, &d2, &d3, &tmpsize);
  1619. X    if (i > 0 && (tmpsize.rbearing + tmpsize.lbearing > buttonwidth - 2 ||
  1620. X          tmpsize.ascent + tmpsize.descent > buttonheight - 2))
  1621. X      continue;
  1622. X    npx = (buttonwidth - tmpsize.lbearing - tmpsize.rbearing) / 2 +
  1623. X      tmpsize.lbearing;
  1624. X    npy = (buttonheight - tmpsize.ascent - tmpsize.descent) / 2 +
  1625. X      tmpsize.ascent;
  1626. X    XTextExtents(fontstructarray[i], "Undo", 4, &d1, &d2, &d3, &tmpsize);
  1627. X    if (i > 0 && (tmpsize.rbearing + tmpsize.lbearing > buttonwidth - 2 ||
  1628. X          tmpsize.ascent + tmpsize.descent > buttonheight - 2))
  1629. X      continue;
  1630. X    upx = (buttonwidth - tmpsize.lbearing - tmpsize.rbearing) / 2 +
  1631. X      tmpsize.lbearing;
  1632. X    upy = (buttonheight - tmpsize.ascent - tmpsize.descent) / 2 +
  1633. X      tmpsize.ascent;
  1634. X    XTextExtents(fontstructarray[i], "Start", 5, &d1, &d2, &d3, &tmpsize);
  1635. X    if (i > 0 && (tmpsize.rbearing + tmpsize.lbearing > buttonwidth - 2 ||
  1636. X          tmpsize.ascent + tmpsize.descent > buttonheight - 2))
  1637. X      continue;
  1638. X    changeposx = cpx; changeposy = cpy;
  1639. X    quitposx = qpx; quitposy = qpy;
  1640. X    newposx = npx; newposy = npy;
  1641. X    undoposx = upx; undoposy = upy;
  1642. X    startposx = (buttonwidth - tmpsize.lbearing - tmpsize.rbearing) / 2 +
  1643. X      tmpsize.lbearing;
  1644. X    startposy = (buttonheight - tmpsize.ascent - tmpsize.descent) / 2 +
  1645. X      tmpsize.ascent;
  1646. X    fontid = fontstructarray[i]->fid;
  1647. X  }
  1648. X  XSetFont(mydisplay, buttongc, fontid);
  1649. X  maxtextheight = (topheight  - 5 * (buttonspace + buttonheight)) / 5;
  1650. X  maxtextwidth = topwidth - boardwidth - maxtextheight / 4;
  1651. X  for (i = 0; i < fontnum; i++) {
  1652. X    int max1x = 0, max2x = 0, j;
  1653. X
  1654. X    if (i > 0) {
  1655. X      if (fontstructarray[i]->max_bounds.ascent +
  1656. X      fontstructarray[i]->max_bounds.descent > maxtextheight)
  1657. X    goto next_font;
  1658. X      for (j = 0; j < 5; j++) {
  1659. X    XTextExtents(fontstructarray[i], messagestring[j],
  1660. X             strlen(messagestring[j]), &d1, &d2, &d3, &tmpsize);
  1661. X    if (tmpsize.rbearing +
  1662. X        fontstructarray[i]->max_bounds.lbearing > maxtextwidth)
  1663. X      goto next_font;
  1664. X      }
  1665. X    }
  1666. X    XTextExtents(fontstructarray[i], "Level: ", 7,
  1667. X         &d1, &d2, &d3, &tmpsize);
  1668. X    if (tmpsize.rbearing > max1x)
  1669. X      max1x = tmpsize.rbearing;
  1670. X    XTextExtents(fontstructarray[i], "You: ", 5,
  1671. X         &d1, &d2, &d3, &tmpsize);
  1672. X    if (tmpsize.rbearing > max1x)
  1673. X      max1x = tmpsize.rbearing;
  1674. X    XTextExtents(fontstructarray[i], "Me: ", 4,
  1675. X         &d1, &d2, &d3, &tmpsize);
  1676. X    if (tmpsize.rbearing > max1x)
  1677. X      max1x = tmpsize.rbearing;
  1678. X    XTextExtents(fontstructarray[i], playercolor[0], strlen(playercolor[0]),
  1679. X         &d1, &d2, &d3, &tmpsize);
  1680. X    if (tmpsize.rbearing > max2x)
  1681. X      max2x = tmpsize.rbearing;
  1682. X    XTextExtents(fontstructarray[i], playercolor[1], strlen(playercolor[1]),
  1683. X         &d1, &d2, &d3, &tmpsize);
  1684. X    if (tmpsize.rbearing > max2x)
  1685. X      max2x = tmpsize.rbearing;
  1686. X    if (i > 0 && max1x + max2x +
  1687. X    2 * fontstructarray[i]->max_bounds.lbearing > maxtextwidth)
  1688. X      goto next_font;
  1689. X    fontid = fontstructarray[i]->fid;
  1690. X    text1x  = boardwidth + fontstructarray[i]->max_bounds.lbearing +
  1691. X      (topwidth - boardwidth - maxtextwidth) / 2;
  1692. X    text2x = text1x + max1x  + fontstructarray[i]->max_bounds.lbearing;
  1693. X    movey = topheight - maxtextheight / 8 -
  1694. X      fontstructarray[i]->max_bounds.descent -
  1695. X    (maxtextheight - fontstructarray[i]->max_bounds.ascent -
  1696. X     fontstructarray[i]->max_bounds.descent) / 2;
  1697. X    compy = movey - maxtextheight - maxtextheight / 4;
  1698. X    humany = compy - maxtextheight - maxtextheight / 4;
  1699. X    levely = humany - maxtextheight - maxtextheight / 4;
  1700. X  next_font:
  1701. X    ;
  1702. X  }
  1703. X  XSetFont(mydisplay, textgc, fontid);
  1704. X  piece_dx = boardwidth / (columns * 5 + 1);
  1705. X  piece_width = (boardwidth - (columns + 1) * piece_dx) / columns;
  1706. X  piece_dy = topheight / (rows * 5 + 1);
  1707. X  piece_height = (topheight - (rows + 1) * piece_dy) / rows;
  1708. X  for (i = 0; i < stone_n[0]; i++) {
  1709. X    stone[0][i].x = piece_dx + stone_x[0][i] * (piece_dx + piece_width);
  1710. X    stone[0][i].y = piece_dy +
  1711. X      (rows - 1 - stone_y[0][i]) * (piece_dy + piece_height);
  1712. X    stone[0][i].width = piece_width;
  1713. X    stone[0][i].height = piece_height;
  1714. X  }
  1715. X  for (i = 0; i < stone_n[1]; i++) {
  1716. X    stone[1][i].x = piece_dx + stone_x[1][i] * (piece_dx + piece_width);
  1717. X    stone[1][i].y = piece_dy +
  1718. X      (rows - 1 - stone_y[1][i]) * (piece_dy + piece_height);
  1719. X    stone[1][i].width = piece_width;
  1720. X    stone[1][i].height = piece_height;
  1721. X  }
  1722. X  for (i = 0; i < rows; i++)
  1723. X    for (j = 0; j < columns; j++) {
  1724. X      holes[i*columns+j].x = 1 + piece_dx + j * (piece_dx + piece_width);
  1725. X      holes[i*columns+j].y = 1 + piece_dy + i * (piece_dy + piece_height);
  1726. X      holes[i*columns+j].width = piece_width - 2;
  1727. X      holes[i*columns+j].height = piece_height - 2;
  1728. X    }
  1729. X  XResizeWindow(mydisplay, boardwindow, boardwidth, topheight);
  1730. X  XMoveResizeWindow(mydisplay, quitwindow, boardwidth + buttonspace,
  1731. X            buttonspace, buttonwidth, buttonheight);
  1732. X  XMoveResizeWindow(mydisplay, newwindow, boardwidth + buttonspace,
  1733. X            2 * buttonspace + buttonheight,
  1734. X            buttonwidth, buttonheight);
  1735. X  XMoveResizeWindow(mydisplay, undowindow, boardwidth + buttonspace,
  1736. X            buttonspace + 2 * (buttonheight + buttonspace),
  1737. X            buttonwidth, buttonheight);
  1738. X  XMoveResizeWindow(mydisplay, startwindow, boardwidth + buttonspace,
  1739. X            buttonspace + 3 * (buttonheight + buttonspace),
  1740. X            buttonwidth, buttonheight);
  1741. X  XMoveResizeWindow(mydisplay, changewindow, boardwidth + buttonspace,
  1742. X            buttonspace + 4 * (buttonheight + buttonspace),
  1743. X            buttonwidth, buttonheight);
  1744. X  XSetWindowBorderWidth(mydisplay, quitwindow,
  1745. X            ((buttonspace / 8 < 1) ? 1 : buttonspace / 8));
  1746. X  XSetWindowBorderWidth(mydisplay, newwindow,
  1747. X            ((buttonspace / 8 < 1) ? 1 : buttonspace / 8));
  1748. X  XSetWindowBorderWidth(mydisplay, undowindow,
  1749. X            ((buttonspace / 8 < 1) ? 1 : buttonspace / 8));
  1750. X  XSetWindowBorderWidth(mydisplay, startwindow,
  1751. X            ((buttonspace / 8 < 1) ? 1 : buttonspace / 8));
  1752. X  XSetWindowBorderWidth(mydisplay, changewindow,
  1753. X            ((buttonspace / 8 < 1) ? 1 : buttonspace / 8));
  1754. }
  1755. X
  1756. #define Repaint_topwindow() XClearArea(mydisplay, topwindow, boardwidth,\
  1757. X                  5 * (buttonspace + buttonheight), 0, 0, True)
  1758. X
  1759. int main(argc, argv)
  1760. int    argc;
  1761. char **argv;
  1762. {
  1763. X  char text[10], **fontnames, *av[4], row_string[3], column_string[3];
  1764. X  int i, j, geo_ret, userx, usery, userwidth, userheight;
  1765. X  int iconsize, Ilistsize;
  1766. X  XIconSize *Ilist;
  1767. X
  1768. X  for (i = 1; i < argc; i++) {
  1769. X    if (strcmp(argv[i], "-display") == 0)
  1770. X      if (++i == argc)
  1771. X    goto usage;
  1772. X      else
  1773. X    displayname = argv[i];
  1774. X    else if (strcmp(argv[i], "-geometry") == 0)
  1775. X      if (++i == argc)
  1776. X    goto usage;
  1777. X      else
  1778. X    geostring = argv[i];
  1779. X    else if (strcmp(argv[i], "-fn") == 0)
  1780. X      if (++i == argc)
  1781. X    goto usage;
  1782. X      else
  1783. X    fontpattern = argv[i];
  1784. X    else if (strcmp(argv[i], "-prog") == 0)
  1785. X      if (++i == argc)
  1786. X    goto usage;
  1787. X      else
  1788. X    progname = argv[i];
  1789. X    else if (strcmp(argv[i], "-rows") == 0)
  1790. X      if (++i == argc)
  1791. X    goto usage;
  1792. X      else {
  1793. X    if ((rows = atoi(argv[i])) < 4 || rows > MAXRC)
  1794. X      goto usage;
  1795. X      }
  1796. X    else if (strcmp(argv[i], "-columns") == 0)
  1797. X      if (++i == argc)
  1798. X    goto usage;
  1799. X      else {
  1800. X    if ((columns = atoi(argv[i])) < 4 || columns > MAXRC)
  1801. SHAR_EOF
  1802. true || echo 'restore of xvier.c failed'
  1803. fi
  1804. echo 'End of  part 1'
  1805. echo 'File xvier.c is continued in part 2'
  1806. echo 2 > _shar_seq_.tmp
  1807. exit 0
  1808. -- 
  1809. ---
  1810. Senior Systems Scientist        mail: dcmartin@msi.com
  1811. Molecular Simulations, Inc.        uucp: uunet!dcmartin
  1812. 796 North Pastoria Avenue        at&t: 408/522-9236
  1813.