support reverting multiple turns at once

This commit is contained in:
Maximilian Keßler 2023-08-12 10:50:16 +02:00
parent f137f9f67c
commit 76c10dc381
Signed by: max
GPG key ID: BCC5A619923C0BA5

View file

@ -140,24 +140,28 @@ namespace Hanabi {
}
void cli(const std::shared_ptr<HanabiStateIF>& game) {
// Set up GNU readline
rl_attempted_completion_function = cli_command_completion;
using_history();
// Tracks the depth of the replay the user explores. We have to ensure that we don't revert too much.
unsigned depth = 0;
while (true) {
const std::string prompt = read_line_memory_safe("> ");
add_history(prompt.c_str());
if (prompt.starts_with("help")) {
std::cout << "state: print information on current game state." << std::endl;
std::cout << "clue: give a clue." << std::endl;
std::cout << "play <card>: play specified card." << std::endl;
std::cout << "discard: discard trash from hand." << std::endl;
std::cout << "opt: take optimal action. In case of ties, prefers plays and discards in that order." << std::endl;
std::cout << "revert: revert last turn of game." << std::endl;
std::cout << "actions: display list of reasonable actions to take and their winning chances." << std::endl;
std::cout << "evaluate: evaluate current game state recursively. Potentially runtime-expensive." << std::endl;
std::cout << "id: display id of state. Has no inherent meaning, useful for debugging." << std::endl;
std::cout << "quit: Quit this interactive shell." << std::endl;
std::cout << "state: print information on current game state." << std::endl;
std::cout << "clue: give a clue." << std::endl;
std::cout << "play <card>: play specified card." << std::endl;
std::cout << "discard: discard trash from hand." << std::endl;
std::cout << "opt: take optimal action. In case of ties, prefers plays and discards in that order." << std::endl;
std::cout << "revert <turns>: revert specified number of turns (default 1)." << std::endl;
std::cout << "actions: display list of reasonable actions to take and their winning chances." << std::endl;
std::cout << "evaluate: evaluate current game state recursively. Potentially runtime-expensive." << std::endl;
std::cout << "id: display id of state. Has no inherent meaning, useful for debugging." << std::endl;
std::cout << "quit: Quit this interactive shell." << std::endl;
continue;
}
@ -203,9 +207,24 @@ namespace Hanabi {
std::cout << "Cannot revert more than base state." << std::endl;
continue;
}
std::cout << "Reverting one turn" << std::endl;
game->revert();
depth--;
unsigned turns_to_revert = 1;
if(prompt.length() > 7) {
try {
turns_to_revert = std::stoi(prompt.substr(7));
} catch(const std::invalid_argument&) {
std::cout << "Could not parse number of turns to revert." << std::endl;
continue;
}
}
if (turns_to_revert > depth) {
turns_to_revert = depth;
std::cout << "Only revererting " << depth << " turns, since this is already the base state." << std::endl;
}
std::cout << "Reverting " << turns_to_revert << " turn(s)." << std::endl;
while(turns_to_revert--) {
game->revert();
depth--;
}
continue;
}
@ -323,6 +342,7 @@ namespace Hanabi {
default:
break;
}
depth++;
continue;
}