home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v15i049: xbomb - minesweeper game with extra features, Part02/04
- Message-ID: <4224@master.CNA.TEK.COM>
- Date: 18 Jan 93 20:09:04 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2295
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1548
-
- Submitted-by: johnh@FICUS.CS.UCLA.EDU (John Heidemann)
- Posting-number: Volume 15, Issue 49
- Archive-name: xbomb/Part02
- Environment: X11, Xlib
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 4)."
- # Contents: Imakefile actions.c bitmap.files infer_solver.c main.c
- # pattern_solver.c score.c solver_io.c solvers.c
- # Wrapped by billr@saab on Mon Jan 18 12:03:06 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Imakefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Imakefile'\"
- else
- echo shar: Extracting \"'Imakefile'\" \(4916 characters\)
- sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
- X
- X/**/#
- X/**/# xbomb imakefile
- X/**/#
- X/**/# @(#)Imakefile 1.16 (UCLA) 10/22/92
- X/**/#
- X
- X
- X
- X
- X/**/#
- X/**/# BEGIN: User customizable things.
- X/**/#
- X
- X/**/# You probably want to change where things go
- X EXEDIR = /usr/dist/games
- X XBLIBDIR = /usr/dist/games/lib/xbomb
- X SCOREFILE = $(XBLIBDIR)/xbomb_score
- X BITMAPDIR = $(XBLIBDIR)/bitmaps
- X/* solverdir will contain executables */
- X SOLVERDIR = $(XBLIBDIR)/solvers
- X
- X/**/# You may want to make things not-setuid.
- X/**/# If so, scores must be world-writable.
- X XBOMBFLAGS = -o games -m 4755
- X SOLVERFLAGS = -o games
- X BITMAPFLAGS = -o games -m 644
- X SCOREFLAGS = -o games -m 644
- X CDEBUGFLAGS = -g
- X
- X/*
- X * You may not have perl, or wish to install the perl solvers.
- X * If you don't have perl, comment out the next line in the Imakefile.
- X */
- X#define INSTALLPERLSOLVERS 1
- X PERL = /usr/local/bin/perl
- X
- X/**/# Your man pages may have funny endings.
- X GAMESMANSUFFIX = 6
- X
- X/**/# Things for various kinds of system brain-damange.
- X/*
- X * If your make doesn't have +=, uncomment this line.
- X * (It seems like this should be in Imake somewhere.)
- X * Or get GNU Make or pmake, a real persons make.
- X */
- X/* #define StupidMakeLacksPlusEquals */
- X
- X/**/# If your C libraries lack strdup, define LACKS_STRDUP.
- X/**/# (It's such a hard thing to QA, I can see why they don't provide it.)
- X/* Uncomment the following line, if necessary. */
- X/* #define StupidLibcLacksStrdup */
- X
- X/**/#
- X/**/# END: User customizable things.
- X/**/#
- X
- X
- X
- X#ifdef StupidLibcLacksStrdup
- X#define ProvideStrdup -DLACKS_STRDUP
- X#else
- X#define ProvideStrdup
- X#endif
- X
- XDEFINES = -D_PATH_SCORE='"$(SCOREFILE)"' -D_PATH_SOLVERS='"$(SOLVERDIR)"' -D_PATH_BITMAPS='"$(BITMAPDIR)"' ProvideStrdup
- X
- X
- X/*
- X * Some helpful targets
- X */
- X#ifdef StupidMakeLacksPlusEquals
- X#define SharFiles(files)
- X#else
- X#define SharFiles(files) TOSHAR += files
- X#endif
- X
- X#define SolverTarget(EXE,OBJS) @@\
- X @@\
- XAllTarget(EXE) @@\
- X @@\
- XNormalProgramTarget(EXE,OBJS solver_io.o,/**/,/**/,/**/) @@\
- XInstallProgramWithFlags(EXE,$(SOLVERDIR),$(SOLVERFLAGS)) @@\
- X @@\
- Xclean:: @@\
- X $(RM) $(PROGRAM)
- X
- X#define PerlifyScript(src,dest) @@\
- X
- X
- X#define PerlSolverTarget(exe) @@\
- X @@\
- Xexe.script: exe @@\
- X sed "s;/usr/.*/perl;$(PERL);" <exe >exe.script @@\
- X @@\
- XSharFiles(exe) @@\
- X @@\
- XInstallScript(exe,$(SOLVERDIR))
- X
- X/*
- X * We have our own InstallManPage so that we can put things
- X * in the games directory. What a pain. Don't those people
- X * at MIT play any games?
- X */
- X#define InstallGamesManPage(file) @@\
- Xinstall.man:: file.man @@\
- X MakeDir($(DESTDIR)$(OURMANSUFFIX)) @@\
- X $(INSTALL) -c $(INSTMANFLAGS) file.man $(MANSOURCEPATH)$(GAMESMANSUFFIX)/file.$(GAMESMANSUFFIX)
- X
- X
- X/*
- X * The real work
- X */
- X
- XSRCS = $(XBOMB_SRCS) pattern_solver.c forced_solver.c prob_solver.c \
- X solver_io.c infer_solver.c
- XSharFiles($(SRCS))
- X
- XHFILES = patchlevel.h solver_io.h xbomb.h icon.bit
- XSharFiles($(HFILES))
- X
- XMANPAGE = xbomb.man
- X
- XSharFiles($(MANPAGE))
- X
- X
- X/**/#
- X/**/# xbomb is done by hand
- X/**/#
- XXBOMB_SRCS = main.c map.c applications.c actions.c graphics.c solvers.c score.c
- XXBOMB_OBJS = main.o map.o applications.o actions.o graphics.o solvers.o score.o
- X
- XAllTarget(xbomb)
- XNormalProgramTarget(xbomb,$(XBOMB_OBJS),/**/,/**/,$(XLIB))
- XInstallProgramWithFlags(xbomb,$(EXEDIR),$(XBOMBFLAGS))
- X
- XInstallGamesManPage(xbomb)
- X
- Xclean::
- X $(RM) xbomb
- X
- X
- X/**/#
- X/**/# solvers follow
- X/**/#
- XSolverTarget(pattern_solver,pattern_solver.o)
- X
- XSolverTarget(forced_solver,forced_solver.o)
- X
- XSolverTarget(prob_solver,prob_solver.o)
- X
- XSolverTarget(infer_solver,infer_solver.o)
- X
- X#ifdef INSTALLPERLSOLVERS
- XPerlSolverTarget(statistics)
- X
- XPerlSolverTarget(debug_solver)
- X#endif
- X
- X
- X/**/#
- X/**/# administrative stuff
- X/**/#
- X
- XDependTarget()
- X
- X/**/# scorefile installation
- Xinstall.scorefile:
- X install $(SCOREFLAGS) /dev/null $(SCOREFILE)
- X
- Xinstall:: install.scorefile
- X
- X/**/# bitmap installation
- X
- Xinstall:: install.bitmaps
- X
- X/* This bogosity is my fault. -JSH */
- Xinstall.bitmaps: bitmap.files
- X MakeDir($(BITMAPDIR))
- X for i in `cat bitmap.files`; \
- X do \
- X j=`echo $$i|sed 's:^./bitmaps:./:'`; \
- X if [ "$$j" != "./" ]; then \
- X if [ -d $$i ]; then \
- X echo Installing dir $$i...; \
- X test -d $(BITMAPDIR)/$$j || $(MKDIRHIER) $(BITMAPDIR)/$$j; \
- X else \
- X echo Installing bitmap $$i...; \
- X $(INSTALL) -c $(BITMAPFLAGS) $$i $(BITMAPDIR)/`dirname $$j`; \
- X fi; \
- X fi; \
- X done
- X @echo Bitmaps installed.
- X
- X/**/#
- X/**/# distribution
- X/**/#
- X
- XSharFiles(README TODO Imakefile Makefile.std)
- X
- Xbitmap.files:
- X find ./bitmaps \( -name \*.bit -o -type d \) -print >bitmap.files
- X
- X#ifdef StupidMakeLacksPlusEquals
- Xkit:
- X @echo 'Your make lacks +=, so make kit is disabled.'
- X
- Xshar:
- X @echo 'Your make lacks +=, so make shar is disabled.'
- X#else
- Xkit: Makefile.std
- X makekit $(TOSHAR) `cat bitmap.files`
- X
- Xshar: Makefile.std
- X shar $(TOSHAR) `cat bitmap.files` >xbomb.shar
- X#endif
- X
- XMakefile.std:
- X cp Makefile Makefile.std
- X
- END_OF_FILE
- if test 4916 -ne `wc -c <'Imakefile'`; then
- echo shar: \"'Imakefile'\" unpacked with wrong size!
- fi
- # end of 'Imakefile'
- fi
- if test -f 'actions.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'actions.c'\"
- else
- echo shar: Extracting \"'actions.c'\" \(3046 characters\)
- sed "s/^X//" >'actions.c' <<'END_OF_FILE'
- X
- X/*
- X * actions.c
- X * @(#)actions.c 1.4 (UCLA) 10/15/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include "xbomb.h"
- X
- X
- Xvoid
- Xmove_somewhere(column, row)
- Xint column, row;
- X{
- X if (map[column][row].status == EMPTY) {
- X if (map[column][row].flag) numflags++;
- X map[column][row].status = KEMPTY;
- X numempty--;
- X if (shouldfollow(column, row)) {
- X if (follow(column,row))
- X dead = 1;
- X };
- X }
- X if (map[column][row].status == BOMB)
- X dead = 1;
- X}
- X
- Xvoid
- Xplace_flag(column, row)
- Xint column, row;
- X{
- X if ((map[column][row].status == EMPTY) ||
- X (map[column][row].status == BOMB)) {
- X if (map[column][row].flag) {
- X numflags++;
- X map[column][row].flag = 0;
- X }
- X else {
- X numflags--;
- X map[column][row].flag = 1;
- X }
- X }
- X}
- X
- X
- Xint
- Xplace_em()
- X{
- X int x, y, ret = 0;
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X map[x][y].neighbor_unknowns = 0;
- X apply_neighbor(x,y,apply_inc_if_unknown,&map[x][y].neighbor_unknowns);
- X };
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++)
- X if (map[x][y].status==KEMPTY &&
- X map[x][y].neighbors - map[x][y].neighbor_kbombs ==
- X map[x][y].neighbor_unknowns) {
- X ret |= apply_neighbor(x,y,apply_flag_if_unknown, NULL);
- X };
- X return(ret);
- X}
- X
- Xint scan_em()
- X{
- X int c, r, ret = 0;
- X
- X for (c = 1; c <= width; c++)
- X for (r = 1; r <= height; r++)
- X if (map[c][r].flag &&
- X map[c][r].status == EMPTY) {
- X dead = 1;
- X return(0);
- X }
- X
- X for (c = 1; c <= width; c++)
- X for (r = 1; r <= height; r++)
- X if (map[c][r].flag && map[c][r].status == BOMB) {
- X map[c][r].status = KBOMB;
- X ret |= apply_neighbor(c,r,apply_add_neighbor_kbombs, (void*)1);
- X putpix(c,r);
- X }
- X return(ret);
- X}
- X
- Xshouldfollow(x, y)
- X int x, y;
- X{
- X return (map[x][y].neighbors == 0 ||
- X (betterfollow && map[x][y].neighbors - map[x][y].neighbor_kbombs == 0));
- X}
- X
- Xfollow(c,r)
- X int c, r;
- X{
- X int x, y;
- X
- X for (x = c-1; x <= c+1; x++)
- X for (y = r-1; y <= r+1; y++) {
- X if (map[x][y].status == EMPTY) {
- X if (map[x][y].flag) numflags++;
- X map[x][y].status = KEMPTY;
- X numempty--;
- X putpix(x, y);
- X if (shouldfollow(x,y))
- X follow(x,y);
- X }
- X }
- X return 0; /* OK */
- X}
- X
- X
- X
- X
- Xint
- Xplace_random(what)
- X int what;
- X{
- X int numct, row, column;
- X
- X numct = (numempty + numflags - 1);
- X if (numct == 0) /* already solved */
- X return(1);
- X
- X numct = lrand48()%numct + 1;
- X
- X for (row = 1; row <= height; row++) {
- X for (column = 1; column <= width; column++) {
- X if (is_unknown(map[column][row].status)) numct--;
- X if (numct == 0) {
- X if (what == BOMB) place_flag(column, row);
- X else if (what == EMPTY) move_somewhere(column, row);
- X else bail("invalid what in place_random");
- X
- X putpix(column,row);
- X return(0);
- X }
- X }
- X }
- X fprintf(stderr, "This message shouldn't happen (but it does)!\n");
- X return(0);
- X}
- X
- END_OF_FILE
- if test 3046 -ne `wc -c <'actions.c'`; then
- echo shar: \"'actions.c'\" unpacked with wrong size!
- fi
- # end of 'actions.c'
- fi
- if test -f 'bitmap.files' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bitmap.files'\"
- else
- echo shar: Extracting \"'bitmap.files'\" \(1168 characters\)
- sed "s/^X//" >'bitmap.files' <<'END_OF_FILE'
- X./bitmaps
- X./bitmaps/old
- X./bitmaps/old/bomb.bit
- X./bitmaps/old/ebomb.bit
- X./bitmaps/old/empty.bit
- X./bitmaps/old/flag.bit
- X./bitmaps/old/icon.bit
- X./bitmaps/old/known0.bit
- X./bitmaps/old/known1.bit
- X./bitmaps/old/known2.bit
- X./bitmaps/old/known3.bit
- X./bitmaps/old/known4.bit
- X./bitmaps/old/known5.bit
- X./bitmaps/old/known6.bit
- X./bitmaps/old/known7.bit
- X./bitmaps/old/known8.bit
- X./bitmaps/old/known9.bit
- X./bitmaps/roman
- X./bitmaps/roman/known0.bit
- X./bitmaps/roman/known1.bit
- X./bitmaps/roman/known2.bit
- X./bitmaps/roman/known3.bit
- X./bitmaps/roman/known4.bit
- X./bitmaps/roman/known5.bit
- X./bitmaps/roman/known6.bit
- X./bitmaps/roman/known7.bit
- X./bitmaps/roman/known8.bit
- X./bitmaps/roman/known9.bit
- X./bitmaps/standard
- X./bitmaps/standard/blank.bit
- X./bitmaps/standard/bomb.bit
- X./bitmaps/standard/ebomb.bit
- X./bitmaps/standard/empty.bit
- X./bitmaps/standard/flag.bit
- X./bitmaps/standard/known0.bit
- X./bitmaps/standard/known1.bit
- X./bitmaps/standard/known2.bit
- X./bitmaps/standard/known3.bit
- X./bitmaps/standard/known4.bit
- X./bitmaps/standard/known5.bit
- X./bitmaps/standard/known6.bit
- X./bitmaps/standard/known7.bit
- X./bitmaps/standard/known8.bit
- X./bitmaps/standard/known9.bit
- X./bitmaps/standard/think.bit
- END_OF_FILE
- if test 1168 -ne `wc -c <'bitmap.files'`; then
- echo shar: \"'bitmap.files'\" unpacked with wrong size!
- fi
- # end of 'bitmap.files'
- fi
- if test -f 'infer_solver.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'infer_solver.c'\"
- else
- echo shar: Extracting \"'infer_solver.c'\" \(7830 characters\)
- sed "s/^X//" >'infer_solver.c' <<'END_OF_FILE'
- X
- X/*
- X * infer_solver
- X * %W% (UCLA) %G%
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include <sys/wait.h>
- X#include "solver_io.h"
- X
- X#ifndef _PATH_SOLVERS
- X#ifdef DEBUG
- X#define _PATH_SOLVERS "."
- X#else
- X#define _PATH_SOLVERS "/usr/dist/games/lib/xbomb"
- X#endif
- X#endif
- X
- X
- X#define KNOWN(s) ((s == empty) || (s == bomb) || (s == edge))
- X
- Xstruct point {
- X int x, y;
- X };
- X
- Xstruct neighbor_set {
- X int size;
- X struct point points[8];
- X };
- X
- Xstruct neighbor_set mymap[MAXWIDTH][MAXHEIGHT];
- X
- Xstruct act {
- X int x, y;
- X char action;
- X struct act *next;
- X };
- X
- Xstruct act *acts[8];
- X
- Xint solver_pid = 0;
- XFILE *solver_rfps, *solver_wfps;
- X
- X
- Xadd_em(i, x, y, action)
- Xint i, x, y;
- Xchar action;
- X{
- X struct act *newact;
- X
- X newact = (struct act *) (malloc(sizeof(struct act)));
- X
- X newact->x = x;
- X newact->y = y;
- X newact->action = action;
- X newact->next = acts[i];
- X acts[i] = newact;
- X#ifdef DEBUG
- X fprintf(stderr," adding... %d %d %c\n", x, y, action);
- X#endif DEBUG
- X }
- X
- Xcompare_em(n)
- Xint n;
- X{
- X int i;
- X struct act *cur, *cp;
- X int same, found;
- X
- X for (cur = acts[0]; cur != NULL; cur = cur->next) {
- X same = 1;
- X for (i = 1; same && (i < n); i++) {
- X found = 0;
- X for (cp = acts[i]; !found && cp != NULL; cp = cp->next) {
- X if ((cur->x == cp->x) &&
- X (cur->y == cp->y) &&
- X (cur->action == cp->action)) found = 1;
- X }
- X same = found;
- X }
- X if (same)
- X fprintf(stderr, "%d %d %c\n", cur->x, cur->y, cur->action);
- X }
- X
- X for (i = 0; i < n; i++) {
- X cur = acts[i];
- X while (cur != NULL) {
- X cp = cur->next;
- X free(cur);
- X cur = cp;
- X }
- X }
- X}
- X
- X
- X
- Xint
- Xapply_empty_if_unknown(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X if (map[x][y].status==unknown) {
- X printf ("%d %d e\n", x, y);
- X };
- X}
- X
- Xint
- Xapply_flag_if_unknown(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X if (map[x][y].status==unknown) {
- X map[x][y].status = bomb_flag;
- X printf ("%d %d f\n", x, y);
- X return(1);
- X };
- X return(0);
- X}
- X
- Xint
- Xrun4(x, y, dx, dy)
- X{
- X int ct = 0;
- X
- X if (map[x][y].status == unknown) ct++;
- X if (map[x+dx][y].status == unknown) ct++;
- X if (map[x][y+dy].status == unknown) ct++;
- X if (map[x+dx][y+dy].status == unknown) ct++;
- X
- X return(ct);
- X}
- X
- Xvoid
- Xadd_neighbor(x, y, dx, dy)
- Xint x, y, dx, dy;
- X{
- X int s;
- X
- X s = mymap[x][y].size;
- X mymap[x][y].points[s].x = x+dx;
- X mymap[x][y].points[s].y = y+dy;
- X mymap[x][y].size ++;
- X }
- X
- Xvoid
- Xmake_neighbors(status, x, y, dx, dy)
- Xint status, x, y;
- X{
- X int i, j, fix;
- X
- X for (j = 0; j < mymap[x+dx][y+dy].size; j++) {
- X fix = 1;
- X for (i = 0; fix && (i < mymap[x][y].size); i++) {
- X if ((mymap[x][y].points[i].x == mymap[x+dx][y+dy].points[j].x) &&
- X (mymap[x][y].points[i].y == mymap[x+dx][y+dy].points[j].y)) {
- X fix = 0;
- X }
- X }
- X if (fix) {
- X printf ("%d %d %c\n", mymap[x+dx][y+dy].points[j].x, mymap[x+dx][y+dy].points[j].y, (status == empty)?'m':'f');
- X }
- X }
- X}
- X
- Xint
- Xsubset_of(x1, y1, x2, y2)
- Xint x1, y1, x2, y2;
- X{
- X int i, j, found;
- X
- X for (i = 0; i < mymap[x1][y1].size; i++) {
- X found = 0;
- X for (j = 0; !found && j < mymap[x2][y2].size; j++) {
- X if ((mymap[x1][y1].points[i].x == mymap[x2][y2].points[j].x) &&
- X (mymap[x1][y1].points[i].y == mymap[x2][y2].points[j].y))
- X found = 1;
- X }
- X if (!found) return(0);
- X }
- X
- X return(1);
- X }
- X
- Xint
- Xplace_em()
- X{
- X int x, y, i, ret = 0, dx, dy, nx, ny;
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X mymap[x][y].size = 0;
- X if (map[x][y].status == empty &&
- X map[x][y].ted >= 1)
- X for (dx = -1; dx <= 1; dx++)
- X for (dy = -1; dy <= 1; dy++)
- X if (((dx != 0) || (dy != 0)) &&
- X (! KNOWN(map[x+dx][y+dy].status)))
- X add_neighbor(x, y, dx, dy);
- X }
- X
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X if (map[x][y].status == empty &&
- X map[x][y].ted >= 1)
- X {
- X#ifdef DEBUG
- X fprintf(stderr, "Inferring %d, %d\n", x, y);
- X#endif DEBUG
- X for (i = 0; i < mymap[x][y].size; i++) {
- X#ifdef DEBUG
- X fprintf(stderr," start of %d\n", i);
- X#endif DEBUG
- X acts[i] = NULL;
- X nx = mymap[x][y].points[i].x;
- X ny = mymap[x][y].points[i].y;
- X map[nx][ny].status = bomb;
- X invoke_solver(i);
- X map[nx][ny].status = empty;
- X#ifdef DEBUG
- X fprintf(stderr," end of %d\n", i);
- X#endif DEBUG
- X }
- X compare_em(mymap[x][y].size);
- X }
- X }
- X
- X return(ret);
- X
- X }
- X
- X
- X
- X
- Xvoid
- Xrevoke_solvers() /* Kill them ALL! Yeah! Slaughter! */
- X{
- X int i;
- X
- X if (solver_pid) {
- X fclose(solver_rfps);
- X fclose(solver_wfps);
- X };
- X}
- X
- X
- Xvoid
- Xdump_map(fp)
- X FILE *fp;
- X{
- X int x, y;
- X char ch;
- X
- X fprintf (fp, "%d\n", numbombs);
- X for (y = 1; y <= height; y++) {
- X for (x = 1; x <= width; x++) {
- X if (map[x][y].status == bomb)
- X ch = 'X';
- X else if (map[x][y].status == bomb_flag)
- X ch = 'f';
- X else if (! KNOWN(map[x][y].status))
- X ch = '.';
- X else ch = map[x][y].neighbors + '0';
- X fprintf (fp, "%c", ch);
- X };
- X fprintf (fp, "\n");
- X };
- X fprintf (fp, "\n"); /* blank line==end of dataset */
- X fflush(fp);
- X}
- X
- X
- Xvoid
- Xreap_children()
- X{
- X int pid, status;
- X int i;
- X
- X for (;;) {
- X pid = waitpid(-1, &status, WNOHANG);
- X if (pid==-1 || pid==0) return; /* no children */
- X
- X if (solver_pid == pid) {
- X fclose(solver_rfps);
- X fclose(solver_wfps);
- X solver_rfps = solver_wfps = NULL;
- X solver_pid = 0;
- X break;
- X };
- X }
- X}
- X
- X
- Xint
- Xinvoke_solver(i)
- X int i;
- X{
- X int subproc;
- X int rp[2], wp[2];
- X FILE *rfp, *wfp;
- X int ret;
- X int error, status;
- X
- X reap_children();
- X
- X if (solver_pid == 0) {
- X if (-1==pipe(rp))
- X bail("pipe");
- X if (-1==pipe(wp))
- X bail("pipe");
- X if (0==(subproc=fork())) {
- X if (-1==dup2 (wp[0], 0))
- X bail ("dup2-a");
- X if (-1==dup2 (rp[1], 1))
- X bail ("dup2-b");
- X close (rp[0]);
- X close (rp[1]);
- X close (wp[0]);
- X close (wp[1]);
- X /*
- X * Plug the security hole.
- X */
- X if (-1==seteuid(getuid()))
- X bail("seteuid");
- X if (-1==setegid(getgid()))
- X bail("setegid");
- X if (-1==exec_solver("pattern_solver")) {
- X char tmps[80];
- X sprintf (tmps, "cannot invoke solver\n");
- X bail (tmps);
- X };
- X /*NOTREACHED*/
- X };
- X if (subproc == -1)
- X bail ("fork");
- X solver_pid = subproc;
- X close (rp[1]);
- X close (wp[0]);
- X solver_rfps = fdopen (rp[0], "r");
- X solver_wfps = fdopen (wp[1], "w");
- X };
- X dump_map(solver_wfps);
- X ret = read_response(i, solver_rfps);
- X reap_children();
- X return(ret);
- X}
- X
- X
- X
- Xint
- Xread_response(i, fp)
- X FILE *fp;
- X int i;
- X{
- X int x, y, ret = 0;
- X char action;
- X#define SLEN 80
- X char s[SLEN];
- X
- X for (;;) {
- X if (NULL==fgets (s, SLEN, fp))
- X break;
- X if (s[0] == 0 || s[0] =='\n')
- X break;
- X if (3 != sscanf (s, "%d %d %c", &x, &y, &action))
- X break;
- X ret = 1;
- X
- X add_em(i, x, y, action);
- X };
- X
- X
- X return(ret);
- X
- X}
- X
- Xexec_solver(s)
- X char *s;
- X{
- X char tmps[512];
- X int error;
- X if (-1==(error = execl (s, s, NULL))) {
- X sprintf (tmps, "%s/%s", _PATH_SOLVERS, s);
- X error = execl(tmps,tmps,NULL);
- X if (error)
- X fprintf (stderr, "Solver not found as either %s or %s.\n", s, tmps);
- X };
- X return error;
- X}
- X
- X
- X
- Xmain()
- X{
- X int ret; int x, y;
- X
- X while (!feof(stdin)) {
- X read_data();
- X if (counts[bomb_flag])
- X exit (1); /* we don't allow flags, yet */
- X calc_em();
- X ret = place_em();
- X printf ("\n"); /* terminate output */
- X fflush(stdout);
- X };
- X exit (0);
- X}
- END_OF_FILE
- if test 7830 -ne `wc -c <'infer_solver.c'`; then
- echo shar: \"'infer_solver.c'\" unpacked with wrong size!
- fi
- # end of 'infer_solver.c'
- fi
- if test -f 'main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'main.c'\"
- else
- echo shar: Extracting \"'main.c'\" \(9883 characters\)
- sed "s/^X//" >'main.c' <<'END_OF_FILE'
- X
- X/*
- X * main.c
- X * @(#)main.c 1.32 (UCLA) 10/22/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include "xbomb.h"
- X#include "patchlevel.h"
- X
- Xint dead = 0, /* true if you won or lost */
- X numflags, /* number of bombs left to place */
- X emptylen, /* number of places reserved for printing numflags */
- X numempty, /* number of empty spaces */
- X button, /* current button pressed */
- X shifted, /* was the shift key down? */
- X numbombs = -1, /* number of bombs placed */
- X width = -1, /* width of puzzle */
- X height = -1, /* height of puzzle */
- X ted = -1, /* ted mode = reduce nums when bomb detected */
- X onlyprint = -1; /* print scores, but don't update 'em */
- X randomE = -1, /* random number of empties */
- X randomB = -1, /* random number of bombs */
- X seed = -1; /* seed to pass to srand48 */
- X showscore = -1, /* should the score be shown? */
- X betterfollow = -1, /* use advanced following algorithm */
- X startwithzero = -1, /* start with a (almost) guaranteed zero */
- X playagain = -1; /* should we automatically restart */
- X
- X#define MAX_SOLVERS 10
- Xchar *solvers[MAX_SOLVERS];
- XFILE *solver_rfps[MAX_SOLVERS], *solver_wfps[MAX_SOLVERS];
- Xint solver_pids[MAX_SOLVERS];
- X
- X
- X#define is_bomb(s) ((s == BOMB)?1:0)
- X#define is_bomb_or_flag(s) ((s==BOMB || s==FLAG)?1:0)
- X#define is_unknown(s) ((s==BOMB || s==EMPTY)?1:0)
- X
- Xstruct cell map[MAXWIDTH+2][MAXHEIGHT+2];
- X
- X
- Xvoid
- Xcleanup()
- X{
- X cleanup_pixmaps();
- X revoke_solvers();
- X}
- X
- X
- Xvoid
- Xfinish()
- X{
- X cleanup();
- X log_score();
- X
- X exit(0);
- X}
- X
- X
- Xvoid
- Xbail(s)
- X char *s;
- X{
- X perror (s);
- X cleanup();
- X exit(1);
- X}
- X
- X
- X#ifdef LACKS_STRDUP
- Xchar *
- Xstrdup(s)
- X char *s;
- X{
- X char *ss = NULL;
- X if (s) {
- X if (ss = malloc(strlen(s)+1)) {
- X strcpy(ss, s);
- X };
- X };
- X return ss;
- X}
- X#endif
- X
- X
- X
- Xstatic char *help_message[] = {
- X "where options include:",
- X " -d host:display Specify which X server to use",
- X " -g +x+y Upper left-hand corner of puzzle",
- X " -fg color Color for bombs and numbers",
- X " -bg color Color for background",
- X " -bd color Color for border",
- X " -bw width Width of border (in pixels)",
- X " ",
- X " -A AutoPlay - default is to play again",
- X " -bitmaps bitdir Use bitmaps found in bitdir subdirectory",
- X " -h height Bomb layout height (default 20)",
- X " -w width Bomb layout width (default 20)",
- X " -n numberBombs Number of bombs (default h*w/4)",
- X " -name player Play with a different name",
- X " -f Make obvious moves (follow)",
- X " -q Only print scores when changed (quiet)",
- X " -r seed Specify the seed (no highscore)",
- X " -Rb b randomly select b bombed squares at start",
- X " -Re e randomly select e empty squares at start",
- X " -s show scorefile",
- X " -S N Solver Assign Solver #N",
- X " -t Deduct numbers for placed bombs (ted mode)",
- X " -z Start with a zero, instead of upper left",
- X " ",
- X "The authors recommend: -h 24 -w 34 -f -t -q -A",
- X NULL
- X};
- X
- Xvoid
- Xusage(name)
- X char *name;
- X{
- X char **cpp;
- X
- X fprintf(stderr, "usage: %s [-options ...]\n(Version %d.%d)\n", name,
- X VERSION, PATCHLEVEL);
- X for (cpp = help_message; *cpp; cpp++) {
- X fprintf(stderr, "%s\n", *cpp);
- X }
- X fprintf(stderr, "\n");
- X exit(1);
- X}
- X
- X
- XParseAndStart(argc, argv)
- X int argc;
- X char *argv[];
- X{
- X char *ProgName, *server, *borderColor;
- X char *foreGround, *backGround;
- X int i, temp;
- X int num_solvers = 0;
- X char *def;
- X char solve_str[80];
- X char *solve_num = solve_str + 6;
- X
- X strcpy (solve_str, "Solver0");
- X
- X server = "";
- X borderColor = "";
- X foreGround = "";
- X backGround = "";
- X
- X ProgName = argv[0];
- X
- X /* parse command line options */
- X
- X for (i=1; i<argc; i++) {
- X char *arg = argv[i];
- X
- X if (arg[0] == '-') {
- X switch (arg[1]) {
- X case 'A':
- X playagain = 1;
- X continue;
- X case 'b':
- X if (arg[2] == 'g') {
- X if (++i >= argc) usage(ProgName);
- X backGround = argv[i];
- X continue;
- X }
- X else if (arg[2] == 'w') {
- X if (++i >= argc) usage(ProgName);
- X borderWidth = atoi(argv[i]);
- X continue;
- X }
- X else if (arg[2] == 'd') {
- X if (++i >= argc) usage(ProgName);
- X borderColor = argv[i];
- X continue;
- X }
- X else if (arg[2] == 'i') {
- X if (++i >= argc) usage(ProgName);
- X bitdir = argv[i];
- X continue;
- X }
- X else usage(ProgName);
- X break;
- X case 'd':
- X if (++i >= argc) usage(ProgName);
- X server = argv[i];
- X continue;
- X case 'f':
- X if (arg[2] == 'g') {
- X if (++i >= argc) usage(ProgName);
- X foreGround = argv[i];
- X continue;
- X }
- X else if (arg[2] == 0) {
- X betterfollow = 1;
- X continue;
- X }
- X else usage(ProgName);
- X break;
- X case 'g':
- X if (++i >= argc) usage(ProgName);
- X geom = argv[i];
- X continue;
- X case 'h':
- X if (++i >= argc) usage(ProgName);
- X height = atoi(argv[i]);
- X continue;
- X case 'n':
- X if (arg[2] == 0) {
- X if (++i >= argc) usage(ProgName);
- X numbombs = atoi(argv[i]);
- X continue;
- X }
- X else if (arg[2] == 'a') {
- X if (++i >= argc) usage(ProgName);
- X name = argv[i];
- X continue;
- X }
- X case 'q':
- X showscore = 0;
- X continue;
- X case 'r':
- X if (++i >= argc) usage(ProgName);
- X seed = atoi(argv[i]);
- X continue;
- X case 'R':
- X if (arg[2] == 'e') {
- X if (++i >= argc) usage(ProgName);
- X randomE = atoi(argv[i]);
- X continue;
- X }
- X else if (arg[2] == 'b') {
- X if (++i >= argc) usage(ProgName);
- X randomB = atoi(argv[i]);
- X continue;
- X }
- X else usage(ProgName);
- X break;
- X case 's':
- X /* so score won't be updated */
- X onlyprint = 1;
- X log_score();
- X exit(0);
- X case 'S':
- X if (++i >= argc) usage(ProgName);
- X if (isdigit(arg[2])) {
- X temp = arg[2] - '0';
- X temp = (temp + 9) % 10;
- X solvers[temp] = strdup(argv[i]);
- X num_solvers = temp + 1;
- X }
- X else {
- X solvers[num_solvers++] = strdup(argv[i]);
- X }
- X continue;
- X case 't':
- X ted = 1;
- X continue;
- X case 'w':
- X if (++i >= argc) usage(ProgName);
- X width = atoi(argv[i]);
- X continue;
- X case 'z':
- X startwithzero = 1;
- X onlyprint = 1;
- X continue;
- X default:
- X usage(ProgName);
- X continue;
- X }
- X }
- X else
- X usage(ProgName);
- X }
- X
- X dpy = XOpenDisplay(server);
- X if (dpy == NULL) {
- X fprintf(stderr, "can't open display \"%s\"\n",server);
- X exit(1);
- X }
- X screen = DefaultScreen(dpy);
- X
- X if (backGround[0] == '\0') {
- X def = XGetDefault(dpy, "xbomb", "Background");
- X backGround = def ? def: "white";
- X }
- X if (foreGround[0] == '\0') {
- X def = XGetDefault(dpy, "xbomb", "Foreground");
- X foreGround = def ? def: "black";
- X }
- X if (borderWidth < 0) {
- X def = XGetDefault(dpy, "xbomb", "BorderWidth");
- X borderWidth = def ? atoi(def) : 1;
- X }
- X if (borderColor[0] == '\0') {
- X def = XGetDefault(dpy, "xbomb", "BorderColor");
- X borderColor = def ? def: "black";
- X }
- X if (server[0] == '\0') {
- X def = XGetDefault(dpy, "xbomb", "Display");
- X server = def ? def: "black";
- X }
- X if (betterfollow < 0) {
- X def = XGetDefault(dpy, "xbomb", "Follow");
- X betterfollow = def ? 1 : 0;
- X }
- X if (bitdir == NULL) {
- X if (def = XGetDefault(dpy, "xbomb", "Bitmaps"))
- X bitdir = def;
- X }
- X if (geom[0] == '\0') {
- X if (def = XGetDefault(dpy, "xbomb", "Geometry"))
- X geom = def;
- X }
- X if (width < 0) {
- X def = XGetDefault(dpy, "xbomb", "Width");
- X width = def ? atoi(def) : 20;
- X }
- X if (height < 0) {
- X def = XGetDefault(dpy, "xbomb", "Height");
- X height = def ? atoi(def) : 20;
- X }
- X if (numbombs < 0) {
- X def = XGetDefault(dpy, "xbomb", "NumberBombs");
- X numbombs = def ? atoi(def) : 0;
- X }
- X if (name == NULL) {
- X def = XGetDefault(dpy, "xbomb", "Name");
- X if (def) name = def;
- X }
- X if (randomE < 0) {
- X def = XGetDefault(dpy, "xbomb", "RandomEmpty");
- X randomE = def ? atoi(def) : 0;
- X }
- X if (randomB < 0) {
- X def = XGetDefault(dpy, "xbomb", "RandomBombs");
- X randomB = def ? atoi(def) : 0;
- X }
- X if (playagain < 0) {
- X def = XGetDefault(dpy, "xbomb", "PlayAgain");
- X playagain = def ? 1 : 0;
- X }
- X if (showscore < 0) {
- X def = XGetDefault(dpy, "xbomb", "Quiet");
- X showscore = def ? 0 : 1;
- X }
- X for (i = 0; i <= 9; i++) {
- X if (solvers[i] == NULL) {
- X solve_num[0] = (i+1)%10 + '0';
- X if (def = XGetDefault(dpy, "xbomb", solve_str))
- X solvers[i] = def;
- X }
- X }
- X if (ted < 0) {
- X def = XGetDefault(dpy, "xbomb", "TedMode");
- X ted = def ? 1 : 0;
- X }
- X if (startwithzero < 0) {
- X def = XGetDefault(dpy, "xbomb", "StartWithZero");
- X onlyprint = startwithzero = def ? 1 : 0;
- X }
- X
- X if (startwithzero && showscore)
- X printf("Warning: starting with zero means no high score\n");
- X
- X FgPixel = requestColor(foreGround);
- X BgPixel = requestColor(backGround);
- X BdPixel = requestColor(borderColor);
- X}
- X
- X
- X
- Xmain(argc,argv)
- X int argc;
- X char **argv;
- X{
- X int i, ret, temp;
- X
- X ParseAndStart(argc, argv);
- X
- X graphics_main(argc, argv);
- X
- X if (seed==-1) {
- X seed=time(NULL) + getpid();
- X } else {
- X onlyprint=1;
- X }
- X
- X /*
- X * Pass an int instead of 48 bit number to srand48 so we can easily use
- X * atoi to read in the number if given as an argument
- X */
- X srand48(seed);
- X
- X do {
- X
- X create_map();
- X
- X for (temp = numflags, emptylen = 1; temp > 0;
- X temp/=10,emptylen++);
- X
- X
- X if (dead) {
- X dead = 0;
- X repaint();
- X
- X }
- X
- X for (i = 0; i < randomB + randomE; i++)
- X place_random((i < randomB)?BOMB:EMPTY);
- X
- X ret = eventloop();
- X
- X log_score();
- X } while (ret == 1);
- X
- X cleanup();
- X exit(0) ;
- X}
- X
- X
- END_OF_FILE
- if test 9883 -ne `wc -c <'main.c'`; then
- echo shar: \"'main.c'\" unpacked with wrong size!
- fi
- # end of 'main.c'
- fi
- if test -f 'pattern_solver.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pattern_solver.c'\"
- else
- echo shar: Extracting \"'pattern_solver.c'\" \(5407 characters\)
- sed "s/^X//" >'pattern_solver.c' <<'END_OF_FILE'
- X
- X/*
- X * pattern_solver
- X * @(#)pattern_solver.c 1.7 (UCLA) 10/6/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include <stdio.h>
- X#include "solver_io.h"
- X
- X
- X#define KNOWN(s) ((s == empty) || (s == bomb) || (s == edge))
- X
- Xstruct point {
- X int x, y;
- X };
- X
- Xstruct neighbor_set {
- X int size;
- X struct point points[8];
- X };
- X
- Xstruct neighbor_set mymap[MAXWIDTH][MAXHEIGHT];
- X
- Xint
- Xapply_empty_if_unknown(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X if (map[x][y].status==unknown) {
- X printf ("%d %d e\n", x, y);
- X };
- X}
- X
- Xint
- Xapply_flag_if_unknown(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X if (map[x][y].status==unknown) {
- X map[x][y].status = bomb_flag;
- X printf ("%d %d f\n", x, y);
- X return(1);
- X };
- X return(0);
- X}
- X
- Xint
- Xrun4(x, y, dx, dy)
- X{
- X int ct = 0;
- X
- X if (map[x][y].status == unknown) ct++;
- X if (map[x+dx][y].status == unknown) ct++;
- X if (map[x][y+dy].status == unknown) ct++;
- X if (map[x+dx][y+dy].status == unknown) ct++;
- X
- X return(ct);
- X}
- X
- Xvoid
- Xadd_neighbor(x, y, dx, dy)
- Xint x, y, dx, dy;
- X{
- X int s;
- X
- X s = mymap[x][y].size;
- X mymap[x][y].points[s].x = x+dx;
- X mymap[x][y].points[s].y = y+dy;
- X mymap[x][y].size ++;
- X }
- X
- Xvoid
- Xmake_neighbors(status, x, y, dx, dy)
- Xint status, x, y;
- X{
- X int i, j, fix;
- X
- X for (j = 0; j < mymap[x+dx][y+dy].size; j++) {
- X fix = 1;
- X for (i = 0; fix && (i < mymap[x][y].size); i++) {
- X if ((mymap[x][y].points[i].x == mymap[x+dx][y+dy].points[j].x) &&
- X (mymap[x][y].points[i].y == mymap[x+dx][y+dy].points[j].y)) {
- X fix = 0;
- X }
- X }
- X if (fix) {
- X printf ("%d %d %c\n", mymap[x+dx][y+dy].points[j].x, mymap[x+dx][y+dy].points[j].y, (status == empty)?'m':'f');
- X }
- X }
- X}
- X
- Xint
- Xsubset_of(x1, y1, x2, y2)
- Xint x1, y1, x2, y2;
- X{
- X int i, j, found;
- X
- X for (i = 0; i < mymap[x1][y1].size; i++) {
- X found = 0;
- X for (j = 0; !found && j < mymap[x2][y2].size; j++) {
- X if ((mymap[x1][y1].points[i].x == mymap[x2][y2].points[j].x) &&
- X (mymap[x1][y1].points[i].y == mymap[x2][y2].points[j].y))
- X found = 1;
- X }
- X if (!found) return(0);
- X }
- X
- X return(1);
- X }
- X
- Xint
- Xplace_em()
- X{
- X int x, y, ret = 0, dx, dy;
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X mymap[x][y].size = 0;
- X if (map[x][y].status == empty &&
- X map[x][y].ted >= 1)
- X for (dx = -1; dx <= 1; dx++)
- X for (dy = -1; dy <= 1; dy++)
- X if (((dx != 0) || (dy != 0)) &&
- X (! KNOWN(map[x+dx][y+dy].status)))
- X add_neighbor(x, y, dx, dy);
- X }
- X
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X
- X/***
- X if (map[x][y].status == empty &&
- X map[x][y].ted == 1)
- X {
- X for (dx = -1; dx <= 1; dx += 2)
- X if (map[x+dx][y].status == empty &&
- X map[x+dx][y].ted == 1 &&
- X KNOWN(map[x-dx][y-1].status) &&
- X KNOWN(map[x-dx][y].status) &&
- X KNOWN(map[x-dx][y+1].status)) {
- X apply_empty_if_unknown(x+2*dx,
- X y+1,NULL);
- X apply_empty_if_unknown(x+2*dx,
- X y,NULL);
- X apply_empty_if_unknown(x+2*dx,
- X y-1,NULL);
- X };
- X
- X for (dy = -1; dy <= 1; dy += 2)
- X if (map[x][y+dy].status==empty &&
- X map[x][y+dy].ted == 1 &&
- X KNOWN(map[x-1][y-dy].status) &&
- X KNOWN(map[x][y-dy].status) &&
- X KNOWN(map[x+1][y-dy].status)) {
- X apply_empty_if_unknown(x+1,y+2*dy,NULL);
- X apply_empty_if_unknown(x,y+2*dy,NULL);
- X apply_empty_if_unknown(x-1,y+2*dy,NULL);
- X };
- X };
- X
- X***/
- X
- X if (map[x][y].status == empty &&
- X map[x][y].ted > 1 &&
- X map[x][y].neighbor_unknowns - map[x][y].ted == 1
- X )
- X {
- X for (dx = -1; dx <= 1; dx += 2)
- X if (map[x-dx][y].status == empty &&
- X map[x-dx][y].ted == 1 &&
- X run4(x-dx, y-1, dx, 2) == 2
- X )
- X {
- X apply_flag_if_unknown(x+dx,
- X y-1,NULL);
- X apply_flag_if_unknown(x+dx,
- X y,NULL);
- X apply_flag_if_unknown(x+dx,
- X y+1,NULL);
- X }
- X
- X for (dy = -1; dy <= 1; dy += 2)
- X if (map[x][y-dy].status == empty &&
- X map[x][y-dy].ted == 1 &&
- X run4(x-1, y-dy, 2, dy) == 2
- X )
- X {
- X apply_flag_if_unknown(x-1,
- X y+dy,NULL);
- X apply_flag_if_unknown(x,
- X y+dy,NULL);
- X apply_flag_if_unknown(x+1,
- X y+dy,NULL);
- X }
- X
- X };
- X };
- X
- X
- X for (x = 1; x <= width; x++) for (y = 1; y <= height; y++)
- X if (map[x][y].status == empty &&
- X map[x][y].ted >= 1)
- X for (dx = -2; dx <= 2; dx++)
- X for (dy = -2; dy <= 2; dy++)
- X if (((dx != 0) || (dy != 0)) &&
- X (x+dx <= width) &&
- X (x+dx >= 1) &&
- X (y+dy <= height) &&
- X (y+dy >= 1) &&
- X (map[x+dx][y+dy].status == empty) &&
- X (map[x+dx][y+dy].ted >= 1) &&
- X subset_of(x, y, x+dx, y+dy)) {
- X if (map[x][y].ted == map[x+dx][y+dy].ted)
- X make_neighbors(empty, x, y, dx, dy);
- X if (map[x][y].ted == map[x+dx][y+dy].ted + mymap[x][y].size - mymap[x+dx][y+dy].size)
- X make_neighbors(bomb, x, y, dx, dy);
- X }
- X
- X return(ret);
- X}
- X
- Xmain()
- X{
- X int ret; int x, y;
- X
- X while (!feof(stdin)) {
- X read_data();
- X if (counts[bomb_flag])
- X exit (1); /* we don't allow flags, yet */
- X calc_em();
- X ret = place_em();
- X printf ("\n"); /* terminate output */
- X fflush(stdout);
- X };
- X exit (0);
- X}
- END_OF_FILE
- if test 5407 -ne `wc -c <'pattern_solver.c'`; then
- echo shar: \"'pattern_solver.c'\" unpacked with wrong size!
- fi
- # end of 'pattern_solver.c'
- fi
- if test -f 'score.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'score.c'\"
- else
- echo shar: Extracting \"'score.c'\" \(6614 characters\)
- sed "s/^X//" >'score.c' <<'END_OF_FILE'
- X
- X/*
- X * score.c
- X * @(#)score.c 1.29 (UCLA) 10/13/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X * This scoring code is completely Matthew's thieving fault
- X * (thanks to the authors of ATC).
- X */
- X
- X#include "xbomb.h"
- X
- Xchar *name = NULL; /* the player's name */
- X
- Xint
- Xcompar(a, b)
- X struct score *a, *b;
- X{
- X return (b->score - a->score);
- X}
- X
- Xprint_score()
- X{
- X int cf, d, ct;
- X
- X ct = emptylen;
- X cf = numflags;
- X if (cf < 0) cf = 0;
- X
- X while (ct > 1) {
- X d = cf%10;
- X if ((d == 0) && (cf == 0) && (numflags > 0)) {
- X XCopyPlane(dpy, pixmaps[BLANK], puzzleWindow, gc,
- X 0, 0, WIDTH, HEIGHT, ct*WIDTH, 0, 1);
- X }
- X else {
- X XCopyPlane(dpy, pixmaps[d], puzzleWindow, gc,
- X 0, 0, WIDTH, HEIGHT, ct*WIDTH, 0, 1);
- X }
- X ct--;
- X cf = cf/10;
- X }
- X}
- X
- Xint
- Xfigure_score()
- X{
- X int s, x, y;
- X s=0;
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++)
- X if (map[x][y].status == KEMPTY)
- X s += map[x][y].neighbors * map[x][y].neighbors;
- X return s;
- X}
- X
- Xchar *
- Xformattime(t)
- X time_t *t;
- X{
- X#define SLEN 80
- X static char s[SLEN];
- X strftime(s, SLEN, "%e-%b-%y", localtime(t));
- X return s;
- X
- X}
- X
- Xlog_score()
- X{
- X register int c, r, place, change = 0, ct, i, fd, nnum_scores = 0,
- X num_scores = 0, good, nscoreid = -1;
- X int botscore;
- X struct passwd *pw;
- X FILE *fp;
- X char *cp, *index(), *rindex();
- X struct score nscore[NUM_SCORES + 1], score[NUM_SCORES + 1], thisscore;
- X char *tmp, s[101];
- X char scorechar;
- X struct score ascore;
- X
- X umask(0);
- X fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644);
- X if (fd < 0) {
- X perror(_PATH_SCORE);
- X return (-1);
- X }
- X /*
- X * This is done to take advantage of stdio, while still
- X * allowing a O_CREAT during the open(2) of the log file.
- X */
- X fp = fdopen(fd, "r+");
- X if (fp == NULL) {
- X perror(_PATH_SCORE);
- X return (-1);
- X }
- X if (flock(fileno(fp), LOCK_EX) < 0)
- X {
- X perror("flock");
- X return (-1);
- X }
- X
- X for (;;) {
- X if (fgets(s, 100, fp) == NULL) break;
- X
- X#define REQFIELDS 8
- X good = sscanf(s, "%c %s %d %d %d %d %d %d",
- X &scorechar,
- X ascore.name,
- X &ascore.size,
- X &ascore.bombs,
- X &ascore.defused,
- X &ascore.won,
- X &ascore.score,
- X &ascore.time);
- X if (good == REQFIELDS-1)
- X ascore.time = 717701220; /* when the time field was added */
- X ascore.mine = 0;
- X if (scorechar == 'P') {
- X nscore[nnum_scores] = ascore;
- X if (ascore.bombs == numbombs)
- X nscoreid = nnum_scores;
- X if (good != REQFIELDS || ++nnum_scores >= NUM_SCORES)
- X break;
- X } else if (scorechar == 'H') {
- X score[num_scores] = ascore;
- X if (good != REQFIELDS || ++num_scores >= NUM_SCORES)
- X break;
- X } else {
- X bail("Corrupt score file.");
- X };
- X };
- X
- X if (name == NULL) {
- X if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
- X fprintf(stderr,
- X "getpwuid failed for uid %d. Who are you?\n",
- X getuid());
- X return (-1);
- X }
- X strcpy(thisscore.name, pw->pw_name);
- X }
- X else {
- X strncpy(thisscore.name, name, 8);
- X thisscore.name[8] = '\0';
- X }
- X
- X thisscore.size = width * height;
- X thisscore.bombs = numbombs;
- X thisscore.defused = numbombs - numflags;
- X for (c = 1; c <= width; c++)
- X for (r = 1; r <= height; r++)
- X if (map[c][r].flag &&
- X ((map[c][r].status == EMPTY) ||
- X (map[c][r].status == KEMPTY)))
- X thisscore.defused--;
- X thisscore.won = dead?0:1;
- X thisscore.score = figure_score();
- X/* Old scoring function:
- X * thisscore.score =
- X * (thisscore.won + 1)*(thisscore.size * thisscore.defused);
- X */
- X thisscore.time = time(NULL);
- X thisscore.mine = 1;
- X
- X ct = 0;
- X botscore = 0;
- X for (i = 0; i < num_scores; i++) {
- X if (strcmp(thisscore.name, score[i].name) == 0) {
- X botscore = score[i].score;
- X ct++;
- X place = i;
- X }
- X }
- X
- X if (ct >= MAX_PER_PLAYER) {
- X if (thisscore.score > botscore) {
- X bcopy(&thisscore, &score[place], sizeof (score[place]));
- X qsort(score, num_scores, sizeof (*score), compar);
- X change = 1;
- X }
- X }
- X else {
- X bcopy(&thisscore, &score[num_scores], sizeof (score[place]));
- X qsort(score, num_scores + 1, sizeof (*score), compar);
- X if (thisscore.score >= score[num_scores].score) change = 1;
- X if (num_scores < NUM_SCORES) num_scores++;
- X }
- X
- X if (nscoreid == -1) {
- X bcopy(&thisscore, &nscore[nnum_scores++], sizeof (nscore[0]));
- X change = 1;
- X nscoreid = nnum_scores;
- X }
- X
- X if (nscore[nscoreid].defused < thisscore.defused) {
- X bcopy(&thisscore, &nscore[nscoreid], sizeof (nscore[nscoreid]));
- X change = 1;
- X }
- X
- X if (change && !onlyprint) {
- X rewind(fp);
- X for (i = 0; i < num_scores; i++)
- X fprintf(fp, "H %s %d %d %d %d %d %d\n",
- X score[i].name, score[i].size,
- X score[i].bombs, score[i].defused,
- X score[i].won, score[i].score,
- X score[i].time);
- X for (i = 0; i < nnum_scores; i++)
- X fprintf(fp, "P %s %d %d %d %d %d %d\n",
- X nscore[i].name, nscore[i].size,
- X nscore[i].bombs, nscore[i].defused,
- X nscore[i].won, nscore[i].score,
- X nscore[i].time);
- X }
- X
- X flock(fileno(fp), LOCK_UN);
- X fclose(fp);
- X
- X if (showscore || change) {
- X printf("%2s: %-8s %-9s %7s %4s %5s %5s %3s\n",
- X "#", "name", "date",
- X "score", "size", "bombs", "flags", "won");
- X printf("---------------------------------------------------------\n");
- X for (i = 0; i < num_scores; i++) {
- X if (i <= TOP_PRINT ||
- X (strcmp(thisscore.name, score[i].name) == 0) || onlyprint)
- X printf("%2d: %-8s %-9s %7d %4d %5d %5d %3s %6s\n",
- X i + 1,
- X score[i].name, formattime(&score[i].time),
- X score[i].score,
- X score[i].size, score[i].bombs,
- X score[i].defused,
- X (score[i].won)?" Y":" N",
- X (score[i].mine)?" <---":" ");
- X }
- X
- X if (!onlyprint) {
- X printf("\nYour stats:\n %-8s %-9s %7d %4d %5d %5d %3s %6s\n",
- X thisscore.name,
- X formattime(&thisscore.time),
- X thisscore.score,
- X thisscore.size,
- X thisscore.bombs,
- X thisscore.defused,
- X (thisscore.won)?" Y":" N",
- X (thisscore.mine)?" <---":" ");
- X
- X printf("\nMost defused with %d bombs\n %-8s %-9s %7d %4d %5d %5d %3s %6s\n",
- X nscore[nscoreid].bombs,
- X nscore[nscoreid].name,
- X formattime(&nscore[nscoreid].time),
- X nscore[nscoreid].score,
- X nscore[nscoreid].size,
- X nscore[nscoreid].bombs,
- X nscore[nscoreid].defused,
- X (nscore[nscoreid].won)?" Y":" N",
- X (nscore[nscoreid].mine)?" <---":" ");
- X }
- X }
- X return (0);
- X}
- END_OF_FILE
- if test 6614 -ne `wc -c <'score.c'`; then
- echo shar: \"'score.c'\" unpacked with wrong size!
- fi
- # end of 'score.c'
- fi
- if test -f 'solver_io.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'solver_io.c'\"
- else
- echo shar: Extracting \"'solver_io.c'\" \(3128 characters\)
- sed "s/^X//" >'solver_io.c' <<'END_OF_FILE'
- X
- X/*
- X * solver_io.c
- X * @(#)solver_io.c 1.3 (UCLA) 10/6/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include <stdio.h>
- X#include "solver_io.h"
- X
- Xstruct generic_cell map[MAXWIDTH+2][MAXHEIGHT+2];
- X
- Xint numbombs;
- Xint width, height;
- X
- Xint mouse_x, mouse_y;
- X
- X
- Xint counts[(int)last_status];
- X
- X
- Xvoid
- Xbail(s)
- X char *s;
- X{
- X perror (s);
- X exit(1);
- X}
- X
- X
- Xvoid
- Xread_data()
- X{
- X char s[MAXWIDTH+3];
- X int x, y;
- X char *p;
- X static char *delimiters = " \t\n";
- X extern char *strtok();
- X
- X for (x=0; x<=MAXWIDTH+1; x++)
- X for (y=0; y<=MAXHEIGHT+1; y++)
- X map[x][y].status = edge;
- X
- X for (;;) {
- X if (NULL==fgets (s, MAXWIDTH+3, stdin))
- X break;
- X if (s[0] == '\n' || s[0] == 0)
- X break;
- X s[strlen(s)-1] = 0; /* chop newline */
- X p = strtok(s, delimiters); /* get & terminate first word */
- X if (strcmp(s,"numbombs")==0) {
- X sscanf(p, "%d", &numbombs);
- X } else if (strcmp(s,"mouse")==0) {
- X sscanf(p, "%d %d", &mouse_x, &mouse_y);
- X } else if (strcmp(s,"map")==0) {
- X break;
- X };
- X };
- X for (y=1;;y++) {
- X if (NULL==fgets (s, MAXWIDTH+3, stdin))
- X break;
- X /* emtpy line terminates input */
- X if (s[0] == '\n' || s[0] == 0)
- X break;
- X width = strlen(s) - 1;
- X for (x=1, p=s; *p && *p != '\n'; p++, x++) {
- X switch (*p) {
- X case 'X':
- X map[x][y].status = bomb;
- X break;
- X case 'f':
- X map[x][y].status = bomb_flag;
- X break;
- X case 'e':
- X bail("Known empty squares not yet handled.");
- X break;
- X case '0':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X map[x][y].status = empty;
- X map[x][y].neighbors = *p - '0';
- X break;
- X case '.':
- X map[x][y].status = unknown;
- X break;
- X default:
- X bail("Bad square value.");
- X };
- X counts[map[x][y].status]++;
- X };
- X };
- X height = y-1;
- X}
- X
- X
- Xint
- Xapply_inc_if_unknown(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X int *ip = (int*)ptr;
- X if (map[x][y].status==unknown)
- X (*ip)++;
- X return(0);
- X}
- X
- Xint
- Xapply_inc_if_bomb(x, y, ptr)
- X int x, y;
- X void *ptr;
- X{
- X int *ip = (int*)ptr;
- X if (map[x][y].status==bomb)
- X (*ip)++;
- X return(0);
- X}
- X
- Xint
- Xapply_neighbor(c,r, f, ptr)
- X int c,r;
- X int (*f)();
- X void *ptr;
- X{
- X int x, y, ret = 0;
- X
- X for (x = c-1; x <= c+1; x++)
- X for (y = r-1; y <= r+1; y++) {
- X if (x==c && y==r)
- X continue;
- X ret |= (*f)(x, y, ptr);
- X };
- X
- X return(ret);
- X}
- X
- X
- Xint
- Xcalc_em()
- X{
- X int x, y, ret = 0, dx, dy;
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X map[x][y].neighbor_unknowns = 0;
- X apply_neighbor(x,y,apply_inc_if_unknown,&map[x][y].neighbor_unknowns);
- X };
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++) {
- X map[x][y].neighbor_bombs = 0;
- X apply_neighbor(x,y,apply_inc_if_bomb,&map[x][y].neighbor_bombs);
- X };
- X
- X for (x = 1; x <= width; x++)
- X for (y = 1; y <= height; y++)
- X if (map[x][y].status == empty)
- X map[x][y].ted = map[x][y].neighbors -
- X map[x][y].neighbor_bombs;
- X
- X}
- END_OF_FILE
- if test 3128 -ne `wc -c <'solver_io.c'`; then
- echo shar: \"'solver_io.c'\" unpacked with wrong size!
- fi
- # end of 'solver_io.c'
- fi
- if test -f 'solvers.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'solvers.c'\"
- else
- echo shar: Extracting \"'solvers.c'\" \(4137 characters\)
- sed "s/^X//" >'solvers.c' <<'END_OF_FILE'
- X
- X/*
- X * solvers.c
- X * @(#)solvers.c 1.29 (UCLA) 10/15/92
- X *
- X * xbomb is Copyright (C) 1992 by Matthew Merzbacher, Los Angeles, CA.
- X * All rights reserved. Permission is granted to freely distribute
- X * this as long as this copyright message is retained intact.
- X * Permission to distribute this as part of a commerical product
- X * requires explicit permission of the author.
- X *
- X */
- X
- X#include "xbomb.h"
- X
- X
- X#define MAX_SOLVERS 10
- Xchar *solvers[MAX_SOLVERS];
- XFILE *solver_rfps[MAX_SOLVERS], *solver_wfps[MAX_SOLVERS];
- Xint solver_pids[MAX_SOLVERS];
- X
- X
- X
- Xvoid
- Xrevoke_solvers() /* Kill them ALL! Yeah! Slaughter! */
- X{
- X int i;
- X for (i=0; i<MAX_SOLVERS; i++)
- X if (solver_pids[i]) {
- X fclose(solver_rfps[i]);
- X fclose(solver_wfps[i]);
- X };
- X}
- X
- X
- Xvoid
- Xdump_map(fp, column, row)
- X FILE *fp;
- X int column, row;
- X{
- X int x, y;
- X char ch;
- X
- X fprintf (fp, "numbombs %d\n", numbombs);
- X fprintf (fp, "mouse %d %d\n", column, row);
- X fprintf (fp, "map\n");
- X for (y = 1; y <= height; y++) {
- X for (x = 1; x <= width; x++) {
- X if (map[x][y].status == KBOMB)
- X ch = 'X';
- X else if (map[x][y].flag)
- X ch = 'f';
- X else if (is_unknown(map[x][y].status))
- X ch = '.';
- X else ch = map[x][y].neighbors + '0';
- X fprintf (fp, "%c", ch);
- X };
- X fprintf (fp, "\n");
- X };
- X fprintf (fp, "\n"); /* blank line==end of dataset */
- X fflush(fp);
- X}
- X
- X
- Xvoid
- Xreap_children()
- X{
- X int pid, status;
- X int i;
- X
- X for (;;) {
- X pid = waitpid(-1, &status, WNOHANG);
- X if (pid==-1 || pid==0)
- X return; /* no children */
- X for (i=0; i<MAX_SOLVERS; i++)
- X if ((solvers[i] != NULL) && (solver_pids[i] == pid)) {
- X fclose(solver_rfps[i]);
- X fclose(solver_wfps[i]);
- X solver_rfps[i] = solver_wfps[i] = NULL;
- X solver_pids[i] = 0;
- X break;
- X };
- X if (i >= MAX_SOLVERS)
- X fprintf(stderr,"warning: %d reaped, but not sown\n",
- X pid);
- X };
- X}
- X
- X
- X
- Xint
- Xexec_solver(s)
- X char *s;
- X{
- X char tmps[512];
- X int error;
- X if (-1==(error = execl (s, s, NULL))) {
- X sprintf (tmps, "%s/%s", _PATH_SOLVERS, s);
- X error = execl(tmps,tmps,NULL);
- X if (error)
- X fprintf (stderr, "Solver not found as either %s or %s.\n",
- X s, tmps);
- X };
- X return error;
- X}
- X
- X
- Xint
- Xread_response(fp)
- X FILE *fp;
- X{
- X int x, y, ret = 0;
- X char action;
- X#define SLEN 80
- X char s[SLEN];
- X
- X for (;;) {
- X if (NULL==fgets (s, SLEN, fp))
- X break;
- X if (s[0] == 0 || s[0] =='\n')
- X break;
- X if (3 != sscanf (s, "%d %d %c", &x, &y, &action))
- X break;
- X ret = 1;
- X switch (action) {
- X case 'f':
- X if (! map[x][y].flag)
- X place_flag(x,y);
- X break;
- X case 'm':
- X move_somewhere(x,y);
- X break;
- X case 'e':
- X fprintf (stderr, "Flagging empties not yet implemented.\n");
- X break;
- X default:
- X fprintf (stderr, "unknown action '%c'\n", action);
- X break;
- X };
- X putpix(x,y);
- X };
- X
- X return(ret);
- X
- X}
- X
- X
- Xint
- Xinvoke_solvers(n, column, row)
- X int n;
- X int column, row;
- X{
- X int subproc;
- X int rp[2], wp[2];
- X FILE *rfp, *wfp;
- X int ret;
- X int error, status;
- X
- X if (solvers[n] == NULL) {
- X fprintf (stderr, "No solver #%d\n", n+1);
- X return 0;
- X };
- X
- X reap_children();
- X
- X /* put up a thinking light */
- X XCopyPlane(dpy, pixmaps[THINK], puzzleWindow, gc,
- X 0, 0, WIDTH, HEIGHT, 5, 5, 1);
- X XFlush(dpy);
- X
- X if (solver_pids[n] == 0) {
- X if (-1==pipe(rp))
- X bail("pipe");
- X if (-1==pipe(wp))
- X bail("pipe");
- X if (0==(subproc=fork())) {
- X if (-1==dup2 (wp[0], 0))
- X bail ("dup2-a");
- X if (-1==dup2 (rp[1], 1))
- X bail ("dup2-b");
- X close (rp[0]);
- X close (rp[1]);
- X close (wp[0]);
- X close (wp[1]);
- X /*
- X * Plug the security hole.
- X */
- X if (-1==seteuid(getuid()))
- X bail("seteuid");
- X if (-1==setegid(getgid()))
- X bail("setegid");
- X if (-1==exec_solver(solvers[n])) {
- X char tmps[80];
- X sprintf (tmps, "cannot invoke solver: %s\n", solvers[n]);
- X bail (tmps);
- X };
- X /*NOTREACHED*/
- X };
- X if (subproc == -1)
- X bail ("fork");
- X solver_pids[n] = subproc;
- X close (rp[1]);
- X close (wp[0]);
- X solver_rfps[n] = fdopen (rp[0], "r");
- X solver_wfps[n] = fdopen (wp[1], "w");
- X };
- X dump_map(solver_wfps[n], column, row);
- X ret = read_response(solver_rfps[n]);
- X reap_children();
- X
- X /* take down thinking light */
- X XCopyPlane(dpy, pixmaps[BLANK], puzzleWindow, gc,
- X 0, 0, WIDTH, HEIGHT, 5, 5, 1);
- X XFlush(dpy);
- X
- X return(ret);
- X}
- X
- END_OF_FILE
- if test 4137 -ne `wc -c <'solvers.c'`; then
- echo shar: \"'solvers.c'\" unpacked with wrong size!
- fi
- # end of 'solvers.c'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-