|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 8116 (0x1fb4)
Types: TextFile
Names: »comp.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Dots/comp.c«
/* 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);
}