Annotation of 43BSDReno/games/hunt/NEW/otto.c, revision 1.1

1.1     ! root        1: # ifdef OTTO
        !             2: /*
        !             3:  *     otto    - a hunt otto-matic player
        !             4:  *
        !             5:  *             This guy is buggy, unfair, stupid, and not extensible.
        !             6:  *     Future versions of hunt will have a subroutine library for
        !             7:  *     automatic players to link to.  If you write your own "otto"
        !             8:  *     please let us know what subroutines you would expect in the
        !             9:  *     subroutine library.
        !            10:  *
        !            11:  *     $Header: otto.c,v 1.8 89/04/19 19:52:39 gregc Exp $
        !            12:  */
        !            13: 
        !            14: # include      <curses.h>
        !            15: # include      <ctype.h>
        !            16: # include      "hunt.h"
        !            17: # include      <sys/time.h>
        !            18: # include      <signal.h>
        !            19: # undef                WALL
        !            20: # undef                NORTH
        !            21: # undef                SOUTH
        !            22: # undef                WEST
        !            23: # undef                EAST
        !            24: # undef                FRONT
        !            25: # undef                LEFT
        !            26: # undef                BACK
        !            27: # undef                RIGHT
        !            28: 
        !            29: extern char    *index();
        !            30: 
        !            31: extern char    screen[SCREEN_HEIGHT][SCREEN_WIDTH2];
        !            32: 
        !            33: # ifndef DEBUG
        !            34: # define       STATIC          static
        !            35: # else
        !            36: # define       STATIC
        !            37: # endif DEBUG
        !            38: 
        !            39: # define       OPPONENT        "{}i!"
        !            40: # define       PROPONENT       "^v<>"
        !            41: # define       WALL            "+\\/#*-|"
        !            42: # define       PUSHOVER        " bg;*#&"
        !            43: # define       SHOTS           "$@Oo:"
        !            44: 
        !            45: /* number of "directions" */
        !            46: # define       NUMDIRECTIONS   4
        !            47: 
        !            48: /* absolute directions (facings) - counterclockwise */
        !            49: # define       NORTH           0
        !            50: # define       WEST            1
        !            51: # define       SOUTH           2
        !            52: # define       EAST            3
        !            53: # define       ALLDIRS         0xf
        !            54: 
        !            55: /* relative directions - counterclockwise */
        !            56: # define       FRONT           0
        !            57: # define       LEFT            1
        !            58: # define       BACK            2
        !            59: # define       RIGHT           3
        !            60: 
        !            61: # define       ABSCHARS        "NWSE"
        !            62: # define       RELCHARS        "FLBR"
        !            63: # define       DIRKEYS         "khjl"
        !            64: 
        !            65: STATIC char    command[BUFSIZ];
        !            66: STATIC int     comlen;
        !            67: 
        !            68: # ifdef        DEBUG
        !            69: STATIC FILE    *debug = NULL;
        !            70: # endif        DEBUG
        !            71: 
        !            72: # define       DEADEND         0x1
        !            73: # define       ON_LEFT         0x2
        !            74: # define       ON_RIGHT        0x4
        !            75: # define       ON_SIDE         (ON_LEFT|ON_RIGHT)
        !            76: # define       BEEN            0x8
        !            77: # define       BEEN_SAME       0x10
        !            78: 
        !            79: struct item    {
        !            80:        char    what;
        !            81:        int     distance;
        !            82:        int     flags;
        !            83: };
        !            84: 
        !            85: STATIC struct  item    flbr[NUMDIRECTIONS];
        !            86: 
        !            87: # define       fitem   flbr[FRONT]
        !            88: # define       litem   flbr[LEFT]
        !            89: # define       bitem   flbr[BACK]
        !            90: # define       ritem   flbr[RIGHT]
        !            91: 
        !            92: STATIC int             facing;
        !            93: STATIC int             row, col;
        !            94: STATIC int             num_turns;              /* for wandering */
        !            95: STATIC char            been_there[HEIGHT][WIDTH2];
        !            96: STATIC struct itimerval        pause_time      = { { 0, 0 }, { 0, 55000 }};
        !            97: 
        !            98: STATIC
        !            99: nothing()
        !           100: {
        !           101: }
        !           102: 
        !           103: otto(y, x, face)
        !           104:        int     y, x;
        !           105:        char    face;
        !           106: {
        !           107:        register int    i;
        !           108:        extern  int     Otto_count;
        !           109:        int             old_mask;
        !           110: 
        !           111: # ifdef        DEBUG
        !           112:        if (debug == NULL) {
        !           113:                debug = fopen("bug", "w");
        !           114:                setbuf(debug, NULL);
        !           115:        }
        !           116:        fprintf(debug, "\n%c(%d,%d)", face, y, x);
        !           117: # endif        DEBUG
        !           118:        (void) signal(SIGALRM, nothing);
        !           119:        old_mask = sigblock(sigmask(SIGALRM));
        !           120:        setitimer(ITIMER_REAL, &pause_time, NULL);
        !           121:        sigpause(old_mask);
        !           122:        sigsetmask(old_mask);
        !           123: 
        !           124:        /* save away parameters so other functions may use/update info */
        !           125:        switch (face) {
        !           126:        case '^':       facing = NORTH; break;
        !           127:        case '<':       facing = WEST; break;
        !           128:        case 'v':       facing = SOUTH; break;
        !           129:        case '>':       facing = EAST; break;
        !           130:        default:        abort();
        !           131:        }
        !           132:        row = y; col = x;
        !           133:        been_there[row][col] |= 1 << facing;
        !           134: 
        !           135:        /* initially no commands to be sent */
        !           136:        comlen = 0;
        !           137: 
        !           138:        /* find something to do */
        !           139:        look_around();
        !           140:        for (i = 0; i < NUMDIRECTIONS; i++) {
        !           141:                if (index(OPPONENT, flbr[i].what) != NULL) {
        !           142:                        attack(i, &flbr[i]);
        !           143:                        bzero(been_there, sizeof been_there);
        !           144:                        goto done;
        !           145:                }
        !           146:        }
        !           147: 
        !           148:        if (index(SHOTS, bitem.what) != NULL && !(bitem.what & ON_SIDE)) {
        !           149:                duck(BACK);
        !           150:                bzero(been_there, sizeof been_there);
        !           151: # ifdef BOOTS
        !           152:        } else if (go_for_ammo(BOOT_PAIR)) {
        !           153:                bzero(been_there, sizeof been_there);
        !           154:        } else if (go_for_ammo(BOOT)) {
        !           155:                bzero(been_there, sizeof been_there);
        !           156: # endif
        !           157:        } else if (go_for_ammo(GMINE))
        !           158:                bzero(been_there, sizeof been_there);
        !           159:        else if (go_for_ammo(MINE))
        !           160:                bzero(been_there, sizeof been_there);
        !           161:        else
        !           162:                wander();
        !           163: 
        !           164: done:
        !           165:        (void) write(Socket, command, comlen);
        !           166:        Otto_count += comlen;
        !           167: # ifdef        DEBUG
        !           168:        (void) fwrite(command, 1, comlen, debug);
        !           169: # endif        DEBUG
        !           170: }
        !           171: 
        !           172: # define       direction(abs,rel)      (((abs) + (rel)) % NUMDIRECTIONS)
        !           173: 
        !           174: STATIC
        !           175: stop_look(itemp, c, dist, side)
        !           176:        struct  item    *itemp;
        !           177:        char    c;
        !           178:        int     dist;
        !           179:        int     side;
        !           180: {
        !           181:        switch (c) {
        !           182: 
        !           183:        case SPACE:
        !           184:                if (side)
        !           185:                        itemp->flags &= ~DEADEND;
        !           186:                return 0;
        !           187: 
        !           188:        case MINE:
        !           189:        case GMINE:
        !           190: # ifdef BOOTS
        !           191:        case BOOT:
        !           192:        case BOOT_PAIR:
        !           193: # endif
        !           194:                if (itemp->distance == -1) {
        !           195:                        itemp->distance = dist;
        !           196:                        itemp->what = c;
        !           197:                        if (side < 0)
        !           198:                                itemp->flags |= ON_LEFT;
        !           199:                        else if (side > 0)
        !           200:                                itemp->flags |= ON_RIGHT;
        !           201:                }
        !           202:                return 0;
        !           203: 
        !           204:        case SHOT:
        !           205:        case GRENADE:
        !           206:        case SATCHEL:
        !           207:        case BOMB:
        !           208: # ifdef OOZE
        !           209:        case SLIME:
        !           210: # endif OOZE
        !           211:                if (itemp->distance == -1 || (!side
        !           212:                    && (itemp->flags & ON_SIDE
        !           213:                    || itemp->what == GMINE || itemp->what == MINE))) {
        !           214:                        itemp->distance = dist;
        !           215:                        itemp->what = c;
        !           216:                        itemp->flags &= ~ON_SIDE;
        !           217:                        if (side < 0)
        !           218:                                itemp->flags |= ON_LEFT;
        !           219:                        else if (side > 0)
        !           220:                                itemp->flags |= ON_RIGHT;
        !           221:                }
        !           222:                return 0;
        !           223: 
        !           224:        case '{':
        !           225:        case '}':
        !           226:        case 'i':
        !           227:        case '!':
        !           228:                itemp->distance = dist;
        !           229:                itemp->what = c;
        !           230:                itemp->flags &= ~(ON_SIDE|DEADEND);
        !           231:                if (side < 0)
        !           232:                        itemp->flags |= ON_LEFT;
        !           233:                else if (side > 0)
        !           234:                        itemp->flags |= ON_RIGHT;
        !           235:                return 1;
        !           236: 
        !           237:        default:
        !           238:                /* a wall or unknown object */
        !           239:                if (side)
        !           240:                        return 0;
        !           241:                if (itemp->distance == -1) {
        !           242:                        itemp->distance = dist;
        !           243:                        itemp->what = c;
        !           244:                }
        !           245:                return 1;
        !           246:        }
        !           247: }
        !           248: 
        !           249: look(rel_dir, itemp)
        !           250:        int             rel_dir;
        !           251:        struct  item    *itemp;
        !           252: {
        !           253:        register int            r, c;
        !           254:        register char           ch;
        !           255: 
        !           256:        itemp->what = 0;
        !           257:        itemp->distance = -1;
        !           258:        itemp->flags = DEADEND|BEEN;            /* true until proven false */
        !           259: 
        !           260:        switch (direction(facing, rel_dir)) {
        !           261: 
        !           262:        case NORTH:
        !           263:                if (been_there[row - 1][col] & NORTH)
        !           264:                        itemp->flags |= BEEN_SAME;
        !           265:                for (r = row - 1; r >= 0; r--)
        !           266:                        for (c = col - 1; c < col + 2; c++) {
        !           267:                                ch = screen[r][c];
        !           268:                                if (stop_look(itemp, ch, row - r, c - col))
        !           269:                                        goto cont_north;
        !           270:                                if (c == col && !been_there[r][c])
        !           271:                                        itemp->flags &= ~BEEN;
        !           272:                        }
        !           273:        cont_north:
        !           274:                if (itemp->flags & DEADEND) {
        !           275:                        itemp->flags |= BEEN;
        !           276:                        been_there[r][col] |= NORTH;
        !           277:                        for (r = row - 1; r > row - itemp->distance; r--)
        !           278:                                been_there[r][col] = ALLDIRS;
        !           279:                }
        !           280:                break;
        !           281: 
        !           282:        case SOUTH:
        !           283:                if (been_there[row + 1][col] & SOUTH)
        !           284:                        itemp->flags |= BEEN_SAME;
        !           285:                for (r = row + 1; r < HEIGHT; r++)
        !           286:                        for (c = col - 1; c < col + 2; c++) {
        !           287:                                ch = screen[r][c];
        !           288:                                if (stop_look(itemp, ch, r - row, col - c))
        !           289:                                        goto cont_south;
        !           290:                                if (c == col && !been_there[r][c])
        !           291:                                        itemp->flags &= ~BEEN;
        !           292:                        }
        !           293:        cont_south:
        !           294:                if (itemp->flags & DEADEND) {
        !           295:                        itemp->flags |= BEEN;
        !           296:                        been_there[r][col] |= SOUTH;
        !           297:                        for (r = row + 1; r < row + itemp->distance; r++)
        !           298:                                been_there[r][col] = ALLDIRS;
        !           299:                }
        !           300:                break;
        !           301: 
        !           302:        case WEST:
        !           303:                if (been_there[row][col - 1] & WEST)
        !           304:                        itemp->flags |= BEEN_SAME;
        !           305:                for (c = col - 1; c >= 0; c--)
        !           306:                        for (r = row - 1; r < row + 2; r++) {
        !           307:                                ch = screen[r][c];
        !           308:                                if (stop_look(itemp, ch, col - c, row - r))
        !           309:                                        goto cont_east;
        !           310:                                if (r == row && !been_there[r][c])
        !           311:                                        itemp->flags &= ~BEEN;
        !           312:                        }
        !           313:        cont_west:
        !           314:                if (itemp->flags & DEADEND) {
        !           315:                        itemp->flags |= BEEN;
        !           316:                        been_there[r][col] |= WEST;
        !           317:                        for (c = col - 1; c > col - itemp->distance; c--)
        !           318:                                been_there[row][c] = ALLDIRS;
        !           319:                }
        !           320:                break;
        !           321: 
        !           322:        case EAST:
        !           323:                if (been_there[row][col + 1] & EAST)
        !           324:                        itemp->flags |= BEEN_SAME;
        !           325:                for (c = col + 1; c < WIDTH; c++)
        !           326:                        for (r = row - 1; r < row + 2; r++) {
        !           327:                                ch = screen[r][c];
        !           328:                                if (stop_look(itemp, ch, c - col, r - row))
        !           329:                                        goto cont_east;
        !           330:                                if (r == row && !been_there[r][c])
        !           331:                                        itemp->flags &= ~BEEN;
        !           332:                        }
        !           333:        cont_east:
        !           334:                if (itemp->flags & DEADEND) {
        !           335:                        itemp->flags |= BEEN;
        !           336:                        been_there[r][col] |= EAST;
        !           337:                        for (c = col + 1; c < col + itemp->distance; c++)
        !           338:                                been_there[row][c] = ALLDIRS;
        !           339:                }
        !           340:                break;
        !           341: 
        !           342:        default:
        !           343:                abort();
        !           344:        }
        !           345: }
        !           346: 
        !           347: STATIC
        !           348: look_around()
        !           349: {
        !           350:        register int    i;
        !           351: 
        !           352:        for (i = 0; i < NUMDIRECTIONS; i++) {
        !           353:                look(i, &flbr[i]);
        !           354: # ifdef        DEBUG
        !           355:                fprintf(debug, " look(%c)=%c(%d)(0x%x)",
        !           356:                        RELCHARS[i], flbr[i].what, flbr[i].distance, flbr[i].flags);
        !           357: # endif        DEBUG
        !           358:        }
        !           359: }
        !           360: 
        !           361: /*
        !           362:  *     as a side effect modifies facing and location (row, col)
        !           363:  */
        !           364: 
        !           365: STATIC
        !           366: face_and_move_direction(rel_dir, distance)
        !           367:        int     rel_dir, distance;
        !           368: {
        !           369:        register int    old_facing;
        !           370:        register char   cmd;
        !           371: 
        !           372:        old_facing = facing;
        !           373:        cmd = DIRKEYS[facing = direction(facing, rel_dir)];
        !           374: 
        !           375:        if (rel_dir != FRONT) {
        !           376:                register int    i;
        !           377:                struct  item    items[NUMDIRECTIONS];
        !           378: 
        !           379:                command[comlen++] = toupper(cmd);
        !           380:                if (distance == 0) {
        !           381:                        /* rotate look's to be in right position */
        !           382:                        for (i = 0; i < NUMDIRECTIONS; i++)
        !           383:                                items[i] =
        !           384:                                        flbr[(i + old_facing) % NUMDIRECTIONS];
        !           385:                        bcopy(items, flbr, sizeof flbr);
        !           386:                }
        !           387:        }
        !           388:        while (distance--) {
        !           389:                command[comlen++] = cmd;
        !           390:                switch (facing) {
        !           391: 
        !           392:                case NORTH:     row--; break;
        !           393:                case WEST:      col--; break;
        !           394:                case SOUTH:     row++; break;
        !           395:                case EAST:      col++; break;
        !           396:                }
        !           397:                if (distance == 0)
        !           398:                        look_around();
        !           399:        }
        !           400: }
        !           401: 
        !           402: STATIC
        !           403: attack(rel_dir, itemp)
        !           404:        int             rel_dir;
        !           405:        struct  item    *itemp;
        !           406: {
        !           407:        if (!(itemp->flags & ON_SIDE)) {
        !           408:                face_and_move_direction(rel_dir, 0);
        !           409:                command[comlen++] = 'o';
        !           410:                command[comlen++] = 'o';
        !           411:                duck(FRONT);
        !           412:                command[comlen++] = ' ';
        !           413:        } else if (itemp->distance > 1) {
        !           414:                face_and_move_direction(rel_dir, 2);
        !           415:                duck(FRONT);
        !           416:        } else {
        !           417:                face_and_move_direction(rel_dir, 1);
        !           418:                if (itemp->flags & ON_LEFT)
        !           419:                        rel_dir = LEFT;
        !           420:                else
        !           421:                        rel_dir = RIGHT;
        !           422:                (void) face_and_move_direction(rel_dir, 0);
        !           423:                command[comlen++] = 'f';
        !           424:                command[comlen++] = 'f';
        !           425:                duck(FRONT);
        !           426:                command[comlen++] = ' ';
        !           427:        }
        !           428: }
        !           429: 
        !           430: STATIC
        !           431: duck(rel_dir)
        !           432:        int     rel_dir;
        !           433: {
        !           434:        int     dir;
        !           435: 
        !           436:        switch (dir = direction(facing, rel_dir)) {
        !           437: 
        !           438:        case NORTH:
        !           439:        case SOUTH:
        !           440:                if (index(PUSHOVER, screen[row][col - 1]) != NULL)
        !           441:                        command[comlen++] = 'h';
        !           442:                else if (index(PUSHOVER, screen[row][col + 1]) != NULL)
        !           443:                        command[comlen++] = 'l';
        !           444:                else if (dir == NORTH
        !           445:                        && index(PUSHOVER, screen[row + 1][col]) != NULL)
        !           446:                                command[comlen++] = 'j';
        !           447:                else if (dir == SOUTH
        !           448:                        && index(PUSHOVER, screen[row - 1][col]) != NULL)
        !           449:                                command[comlen++] = 'k';
        !           450:                else if (dir == NORTH)
        !           451:                        command[comlen++] = 'k';
        !           452:                else
        !           453:                        command[comlen++] = 'j';
        !           454:                break;
        !           455: 
        !           456:        case WEST:
        !           457:        case EAST:
        !           458:                if (index(PUSHOVER, screen[row - 1][col]) != NULL)
        !           459:                        command[comlen++] = 'k';
        !           460:                else if (index(PUSHOVER, screen[row + 1][col]) != NULL)
        !           461:                        command[comlen++] = 'j';
        !           462:                else if (dir == WEST
        !           463:                        && index(PUSHOVER, screen[row][col + 1]) != NULL)
        !           464:                                command[comlen++] = 'l';
        !           465:                else if (dir == EAST
        !           466:                        && index(PUSHOVER, screen[row][col - 1]) != NULL)
        !           467:                                command[comlen++] = 'h';
        !           468:                else if (dir == WEST)
        !           469:                        command[comlen++] = 'h';
        !           470:                else
        !           471:                        command[comlen++] = 'l';
        !           472:                break;
        !           473:        }
        !           474: }
        !           475: 
        !           476: /*
        !           477:  *     go for the closest mine if possible
        !           478:  */
        !           479: 
        !           480: STATIC
        !           481: go_for_ammo(mine)
        !           482:        char    mine;
        !           483: {
        !           484:        register int    i, rel_dir, dist;
        !           485: 
        !           486:        rel_dir = -1;
        !           487:        dist = WIDTH;
        !           488:        for (i = 0; i < NUMDIRECTIONS; i++) {
        !           489:                if (flbr[i].what == mine && flbr[i].distance < dist) {
        !           490:                        rel_dir = i;
        !           491:                        dist = flbr[i].distance;
        !           492:                }
        !           493:        }
        !           494:        if (rel_dir == -1)
        !           495:                return FALSE;
        !           496: 
        !           497:        if (!(flbr[rel_dir].flags & ON_SIDE)
        !           498:        || flbr[rel_dir].distance > 1) {
        !           499:                if (dist > 4)
        !           500:                        dist = 4;
        !           501:                face_and_move_direction(rel_dir, dist);
        !           502:        } else
        !           503:                return FALSE;           /* until it's done right */
        !           504:        return TRUE;
        !           505: }
        !           506: 
        !           507: STATIC
        !           508: wander()
        !           509: {
        !           510:        register int    i, j, rel_dir, dir_mask, dir_count;
        !           511: 
        !           512:        for (i = 0; i < NUMDIRECTIONS; i++)
        !           513:                if (!(flbr[i].flags & BEEN) || flbr[i].distance <= 1)
        !           514:                        break;
        !           515:        if (i == NUMDIRECTIONS)
        !           516:                bzero(been_there, sizeof been_there);
        !           517:        dir_mask = dir_count = 0;
        !           518:        for (i = 0; i < NUMDIRECTIONS; i++) {
        !           519:                j = (RIGHT + i) % NUMDIRECTIONS;
        !           520:                if (flbr[j].distance <= 1 || flbr[j].flags & DEADEND)
        !           521:                        continue;
        !           522:                if (!(flbr[j].flags & BEEN_SAME)) {
        !           523:                        dir_mask = 1 << j;
        !           524:                        dir_count = 1;
        !           525:                        break;
        !           526:                }
        !           527:                if (j == FRONT
        !           528:                && num_turns > 4 + (random() %
        !           529:                                ((flbr[FRONT].flags & BEEN) ? 7 : HEIGHT)))
        !           530:                        continue;
        !           531:                dir_mask |= 1 << j;
        !           532: # ifdef notdef
        !           533:                dir_count++;
        !           534: # else
        !           535:                dir_count = 1;
        !           536:                break;
        !           537: # endif
        !           538:        }
        !           539:        if (dir_count == 0) {
        !           540:                duck(random() % NUMDIRECTIONS);
        !           541:                num_turns = 0;
        !           542:                return;
        !           543:        } else if (dir_count == 1)
        !           544:                rel_dir = ffs(dir_mask) - 1;
        !           545:        else {
        !           546:                rel_dir = ffs(dir_mask) - 1;
        !           547:                dir_mask &= ~(1 << rel_dir);
        !           548:                while (dir_mask != 0) {
        !           549:                        i = ffs(dir_mask) - 1;
        !           550:                        if (random() % 5 == 0)
        !           551:                                rel_dir = i;
        !           552:                        dir_mask &= ~(1 << i);
        !           553:                }
        !           554:        }
        !           555:        if (rel_dir == FRONT)
        !           556:                num_turns++;
        !           557:        else
        !           558:                num_turns = 0;
        !           559: 
        !           560: # ifdef DEBUG
        !           561:        fprintf(debug, " w(%c)", RELCHARS[rel_dir]);
        !           562: # endif DEBUG
        !           563:        face_and_move_direction(rel_dir, 1);
        !           564: }
        !           565: 
        !           566: # endif OTTO

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.