|
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); }