DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦059561407⟧ TextFile

    Length: 8116 (0x1fb4)
    Types: TextFile
    Names: »comp.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Dots/comp.c« 

TextFile

/*    COMP.C    */

#include "dots.h"

compmove()
{
    bottom_line();
    close_boxes();
    if (!board_is_full())
	if (!find_good_move(GOOD))
	    force_move();
}

close_boxes()
{
    Bingo.x = Bingo.y = 0;
    dX_found = 0;
    if (level == DUMB || cntrl_not_established() || find_good_move(BAD))
	close_EVERYTHING();
    else
	first_pass();
}

find_good_move(BorG)
int BorG;
{
    int x, y, xcount, ycount, x1, y1, x2, y2;

    if (no_good_moves)
	return (0);
    if (BorG == GOOD && level == KILLER && kill_4_loops())
	return (1);
    for (xcount = 1, x = random() % (2 * Length - 1) + 1; xcount < Length * 2;
	xcount++, x = x % (2 * Length - 1) + 1)
	for (ycount = 1, y = random() % (2 * Width - 1) + 1; ycount < Width * 2;
	    ycount++, y = y % (2 * Width - 1) + 1) {
	    if (iseven(x + y))
		continue;
	    if (board[x][y] == USED)
		continue;
	    find_adj_squares(x, y, &x1, &y1, &x2, &y2);
	    if (closure(GOOD, x1, y1) == 2)
		continue;
	    if (closure(GOOD, x2, y2) == 2)
		continue;
	    if (BorG == GOOD) {
		xposit = x, yposit = y;
		(void) entermove();
	    }
	    return (1);
	}
    no_good_moves = 1;
    return (0);
}

/********************************************************************\
|*   check all dots and ruins potential 4 loops.                    *|
|*                                                                  *|
|*      Want to prevent:      Find these:   Before they turn into:  *|
|*         *---*---*	        *---*   *         *---*   *         *|
|*         |       |	        |      		  |                 *|
|*         *   *   *            *   *   *         *   *   *         *|
|*         |       |					  |	    *|
|*         *---*---*            *   *---*         *   *---*         *|
|*   Because 4 loops lose points and #3 guarantees 4-loops          *|
\********************************************************************/

kill_4_loops()
{
    int x, y, x1, y1, x2, y2, dx, dy, xcheck, ycheck;

    for (x = 3; x <= 2 * Length - 3; x += 2)
	for (y = 3; y <= 2 * Width - 3; y += 2) {
	    if (closure(GOOD, x, y))
		continue;	/* a line is connected to dot */
	    for (dx = -1; dx <= 1; dx += 2)
		for (dy = -1; dy <= 1; dy += 2)
		    if (closure(GOOD, x + dx, y + dy) == 2)
			if (closure(GOOD, x - dx, y - dy) == 1) {
			    xcheck = x - dx, ycheck = y;
			    do_twice
			    {
				find_adj_squares(xcheck, ycheck, &x1, &y1, &x2, &y2);
				if (closure(GOOD, x1, y1) != 2 && closure(GOOD, x2, y2) != 2) {
				    xposit = xcheck, yposit = ycheck;
				    (void) entermove();
				    return (1);
				} else
				    xcheck = x, ycheck = y - dy;
			    }
			}
	}
    return (0);
}

force_move()
{
    int x, y, xcount, ycount, x1, y1, x2, y2;
    int Badness, bestx, besty, Bestbad = 1000, Besttype;

    if (dX_found) {
	if (comptally + persontally + segflag == OPENEND ? 2 : 4 == (Length - 1) * (Width - 1)) {
	    Bingo.x = Bingo.y = dX_found = 0;
	    close_EVERYTHING();
	    return;
	}
	if (segflag == OPENEND) {
	    find_adj_squares(Bingo.x, Bingo.y, &x1, &y1, &x2, &y2);
	    if (closure(GOOD, x1, y1) == 2 && closure(GOOD, x2, y2) == 2) {
		close_boxes();
		if (!board_is_full())
		    force_move();
		return;
	    }
	}
	xposit = Bingo.x;
	yposit = Bingo.y;
	(void) entermove();
	return;
    }
    for (xcount = 1, x = random() % (2 * Length - 1) + 1; xcount < Length * 2;
	xcount++, x = x % (2 * Length - 1) + 1)
	for (ycount = 1, y = random() % (2 * Width - 1) + 1; ycount < Width * 2;
	    ycount++, y = y % (2 * Width - 1) + 1)
	    if (isodd(x + y) && board[x][y] == FREE) {
		find_adj_squares(x, y, &x1, &y1, &x2, &y2);
		if (closure(GOOD, x1, y1) != 3 && closure(GOOD, x2, y2) != 3)
		    if ((Badness = Howbad(GOOD, Bestbad, x, y)) < Bestbad) {
			Bestbad = Badness;
			bestx = x;
			besty = y;
			Besttype = segtype;
		    }
	    }
    if (Bestbad >= 2 && Besttype == OPENEND)
	goto_middle_of_path(GOOD, &bestx, &besty);
    xposit = bestx;
    yposit = besty;
    (void) entermove();
}

first_pass()
{
    int x, y, x1, y1, doubleX, doubleY;
    int Badness;
    int start_over;

    do {
	start_over = 0;
	for (x = 2; x <= 2 * Length - 2 && !start_over; x += 2)
	    for (y = 2; y <= 2 * Width - 2 && !start_over; y += 2)
		if (closure(GOOD, x, y) == 3) {
		    x1 = x, y1 = y;
		    goto_adj_free_line(GOOD, &x1, &y1);
		    if (((Badness = Howbad(BAD, 1000, x1, y1)) == 2 &&
			    segtype == OPENEND)
			|| (Badness == 4 && segtype == CLOSEDEND)) {
			segflag = segtype;
			dX_found = 1;
			doubleX = x1;
			doubleY = y1;
			board[x1][y1] = USED;	/* temporarily */
			goto_next_square(GOOD, &doubleX, &doubleY);
			goto_adj_free_line(GOOD, &doubleX, &doubleY);
			Bingo.x = doubleX;
			Bingo.y = doubleY;
			board[x1][y1] = FREE;	/* SIGH */
			close_EVERYTHING();
			return;
		    } else if (Badness <= 2) {
			xposit = x1, yposit = y1;
			entermove();
		    } else {
			xposit = x1, yposit = y1;
			entermove();
			start_over = 1;
		    }
		}
    }
    while (start_over);
}

close_EVERYTHING()
{
    int x, y, x_check, y_check, moved;

    do {
	moved = 0;
	for (x = 2; x <= 2 * Length - 2; x += 2)
	    for (y = 2; y <= 2 * Width - 2; y += 2)
		if (closure(GOOD, x, y) == 3) {
		    x_check = x, y_check = y;
		    goto_adj_free_line(GOOD, &x_check, &y_check);
		    /* at the end of the game, ignore this line! */
		    if (!board_is_almost_full() && too_close(x_check, y_check))
			continue;
		    xposit = x_check;
		    yposit = y_check;
		    entermove();
		    moved = 1;
		}
    }
    while (moved);
}

Howbad(BorG, Max, xmove, ymove)
int BorG, Max, xmove, ymove;
{
    int x, y, x1, y1, x2, y2, moved, badtotal = 0;

    for (x = 1; x < 2 * Length; x++)
	for (y = isodd(x) ? 2 : 1; y < 2 * Width; y += 2)
	    badboard[x][y] = board[x][y];
    if (BorG == GOOD)
	badboard[xmove][ymove] = USED;
    segtype = OPENEND;

    do_twice {
	x = xmove;
	y = ymove;
	do {
	    moved = 0;
	    if (!goto_next_square(BAD, &x, &y))
		break;
	    goto_adj_free_line(BAD, &x, &y);
	    badboard[x][y] = USED;
	    moved = 1;
	    find_adj_squares(x, y, &x1, &y1, &x2, &y2);
	    if (closure(BAD, x1, y1) == 4 && closure(BAD, x2, y2) == 4)
		badtotal++, segtype = CLOSEDEND;	/* add extra for two
							 * sides */
	    badtotal++;
	    if (badtotal >= Max)
		return (Max);
	}
	while (moved == 1);
    }
    return (badtotal);
}

/***********************************************************************\
|*  This procedure returns true if the line passed is on either of the *|
|*  boxes next to Bingo.                                               *|
\***********************************************************************/

too_close(x, y)
int x, y;
{
    if (abs(x - Bingo.x) == 1 && abs(y - Bingo.y) == 1) {	/* REAL close */
	if (isodd(Bingo.x)) {	/* Bingo is vertical  */
	    if (closure(GOOD, x, Bingo.y) == 2)
		return (1);
	} else {	/* Bingo is horizontal */
	    if (closure(GOOD, Bingo.x, y) == 2)
		return (1);
	}
    }
    if (isodd(Bingo.x)) {	/* Bingo is vertical  */
	if ((abs(x - Bingo.x) == 2 && y == Bingo.y)
	    && (closure(GOOD, (x + Bingo.x) / 2, y) == 2))
	    return (1);
    } else {		/* Bingo is horizontal */
	if ((abs(y - Bingo.y) == 2 && x == Bingo.x)
	    && (closure(GOOD, x, (y + Bingo.y) / 2) == 2))
	    return (1);
    }
    return (0);
}

/***************************************************************************\
|* This function decides if there are still more open-ended paths of       *|
|* length two or less still on the board. If there are, it returns 1, else *|
|* 0.                                                                      *|
\***************************************************************************/

cntrl_not_established()
{
    int x, y, x1, y1, x2, y2;

    if (control_already_established)
	return (0);
    for (x = 1; x < 2 * Length; x++)
	for (y = isodd(x) ? 2 : 1; y < 2 * Width; y += 2)
	    if (board[x][y] == FREE)
		if (Howbad(GOOD, 3, x, y) <= 2 && segtype == OPENEND) {
		    find_adj_squares(x, y, &x1, &y1, &x2, &y2);
		    if (closure(GOOD, x1, y1) <= 2 && closure(GOOD, x2, y2) <= 2)
			return (1);
		}
    control_already_established = 1;
    return (0);
}