Message AIInterface::makeMove() { vector<Message> m = getValidMoves(duel); if (m.size() == 0) { return Message("AI: NO VALID MOVES ERROR"); } if (m.size() == 1) //only 1 valid move { cout << "AI: only 1 legal move" << endl; return m.at(0); } if (duel->castingcard != -1) //auto-tap { return m.at(0); } int max = -10000; Message maxmove("AI: DEFAULT MOVE ERROR"); duel->isSimulation = 1; for (vector<Message>::iterator i = m.begin(); i != m.end(); i++) { duel->handleInterfaceInput(*i); duel->dispatchAllMessages(); int x = -AlphaBeta(duel, 4, duel->turn); duel->undoLastMove(); vector<Message> m2 = getValidMoves(duel); if (m2.size() != m.size()) { cout << "AI: ERROR: moves size mismatch" << endl; } cout << "AI: value " << x << " for move: " << (*i).getType() << endl; /*if (duel->hands[0].cards.size() != duel->hands[0].cards.size()) { cout << "AI: undo failed " << i->getType() << duel->hands[0].cards.size() << " " << duel->hands[0].cards.size() << endl; }*/ if (x > max) { maxmove = *i; max = x; } } cout << "AI: maxmove value: " << max << endl; duel->isSimulation = 0; return maxmove; }
void draw_stat(void) { wmove(stat_w, STAT_1, 0); wprintw(stat_w, "Points %3d\n", mf->points); wprintw(stat_w, "Fouls %2d\n", fouled(ms)); wprintw(stat_w, "Grapples %2d\n", grappled(ms)); wmove(stat_w, STAT_2, 0); wprintw(stat_w, " 0 %c(%c)\n", maxmove(ms, winddir + 3, -1) + '0', maxmove(ms, winddir + 3, 1) + '0'); waddstr(stat_w, " \\|/\n"); wprintw(stat_w, " -^-%c(%c)\n", maxmove(ms, winddir + 2, -1) + '0', maxmove(ms, winddir + 2, 1) + '0'); waddstr(stat_w, " /|\\\n"); wprintw(stat_w, " | %c(%c)\n", maxmove(ms, winddir + 1, -1) + '0', maxmove(ms, winddir + 1, 1) + '0'); wprintw(stat_w, " %c(%c)\n", maxmove(ms, winddir, -1) + '0', maxmove(ms, winddir, 1) + '0'); wmove(stat_w, STAT_3, 0); wprintw(stat_w, "Load %c%c %c%c\n", loadname[mf->loadL], readyname(mf->readyL), loadname[mf->loadR], readyname(mf->readyR)); wprintw(stat_w, "Hull %2d\n", mc->hull); wprintw(stat_w, "Crew %2d %2d %2d\n", mc->crew1, mc->crew2, mc->crew3); wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR); wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR); wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3); if (mc->rig4 < 0) waddch(stat_w, '-'); else wprintw(stat_w, "%d", mc->rig4); wrefresh(stat_w); }
void acceptmove(void) { int ta; int ma; char af; int moved = 0; int vma, dir; char prompt[60]; char buf[60], last = '\0'; char *p; if (!mc->crew3 || snagged(ms) || !windspeed) { Msg("Unable to move"); return; } ta = maxturns(ms, &af); ma = maxmove(ms, mf->dir, 0); sprintf(prompt, "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta); sgetstr(prompt, buf, sizeof buf); dir = mf->dir; vma = ma; for (p = buf; *p; p++) switch (*p) { case 'l': dir -= 2; case 'r': if (++dir == 0) dir = 8; else if (dir == 9) dir = 1; if (last == 't') { Msg("Ship can't turn that fast."); *p-- = '\0'; } last = 't'; ma--; ta--; vma = min(ma, maxmove(ms, dir, 0)); if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; case 'b': ma--; vma--; last = 'b'; if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; case '0': case 'd': *p-- = '\0'; break; case '\n': *p-- = '\0'; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (last == '0') { Msg("Can't move that fast."); *p-- = '\0'; } last = '0'; moved = 1; ma -= *p - '0'; vma -= *p - '0'; if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; default: if (!isspace((unsigned char) *p)) { Msg("Input error."); *p-- = '\0'; } } if ((ta < 0 && moved) || (vma < 0 && moved) || (af && turnfirst(buf) && moved)) { Msg("Movement error."); if (ta < 0 && moved) { if (mf->FS == 1) { Write(W_FS, ms, 0, 0, 0, 0); Msg("No hands to set full sails."); } } else if (ma >= 0) buf[1] = '\0'; } if (af && !moved) { if (mf->FS == 1) { Write(W_FS, ms, 0, 0, 0, 0); Msg("No hands to set full sails."); } } if (*buf) strcpy(movebuf, buf); else strcpy(movebuf, "d"); Writestr(W_MOVE, ms, movebuf); Msg("Helm: %s.", movebuf); }
void moveall() /* move all comp ships */ { struct ship *sp, *sq; /* r11, r10 */ int n; /* r9 */ int k, l; /* r8, r7 */ int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; char moved[NSHIP]; /* * first try to create moves for OUR ships */ foreachship(sp) { struct ship *closest; int ma, ta; char af; if (sp->file->captain[0] || sp->file->dir == 0) continue; if (!sp->file->struck && windspeed && !snagged(sp) && sp->specs->crew3) { ta = maxturns(sp, &af); ma = maxmove(sp, sp->file->dir, 0); closest = closestenemy(sp, 0, 0); if (closest == 0) *sp->file->movebuf = '\0'; else closeon(sp, closest, sp->file->movebuf, sizeof sp->file->movebuf, ta, ma, af); } else *sp->file->movebuf = '\0'; } /* * Then execute the moves for ALL ships (dead ones too), * checking for collisions and snags at each step. * The old positions are saved in row[], col[], dir[]. * At the end, we compare and write out the changes. */ n = 0; foreachship(sp) { if (snagged(sp)) (void) strlcpy(sp->file->movebuf, "d", sizeof sp->file->movebuf); else if (*sp->file->movebuf != 'd') (void) strlcat(sp->file->movebuf, "d", sizeof sp->file->movebuf); row[n] = sp->file->row; col[n] = sp->file->col; dir[n] = sp->file->dir; drift[n] = sp->file->drift; moved[n] = 0; n++; } /* * Now resolve collisions. * This is the tough part. */ for (k = 0; stillmoving(k); k++) { /* * Step once. * And propagate the nulls at the end of sp->file->movebuf. */ n = 0; foreachship(sp) { if (!sp->file->movebuf[k]) sp->file->movebuf[k+1] = '\0'; else if (sp->file->dir) step(sp->file->movebuf[k], sp, &moved[n]); n++; } /* * The real stuff. */ n = 0; foreachship(sp) { if (sp->file->dir == 0 || is_isolated(sp)) goto cont1; l = 0; foreachship(sq) { char snap = 0; if (sp == sq) goto cont2; if (sq->file->dir == 0) goto cont2; if (!push(sp, sq)) goto cont2; if (snagged2(sp, sq) && range(sp, sq) > 1) snap++; if (!range(sp, sq) && !fouled2(sp, sq)) { makesignal(sp, "collision with $$", sq); if (die() < 4) { makesignal(sp, "fouled with $$", sq); Write(W_FOUL, sp, l, 0, 0, 0); Write(W_FOUL, sq, n, 0, 0, 0); } snap++; } if (snap) { sp->file->movebuf[k + 1] = 0; sq->file->movebuf[k + 1] = 0; sq->file->row = sp->file->row - 1; if (sp->file->dir == 1 || sp->file->dir == 5) sq->file->col = sp->file->col - 1; else sq->file->col = sp->file->col; sq->file->dir = sp->file->dir; } cont2: l++; } cont1: n++; } } /* * Clear old moves. And write out new pos. */ n = 0; foreachship(sp) { if (sp->file->dir != 0) { *sp->file->movebuf = 0; if (row[n] != sp->file->row) Write(W_ROW, sp, sp->file->row, 0, 0, 0); if (col[n] != sp->file->col) Write(W_COL, sp, sp->file->col, 0, 0, 0); if (dir[n] != sp->file->dir) Write(W_DIR, sp, sp->file->dir, 0, 0, 0); if (drift[n] != sp->file->drift) Write(W_DRIFT, sp, sp->file->drift, 0, 0, 0); } n++; } }