wchess: off/on prompt

This commit is contained in:
Fraxy V 2023-11-30 01:17:29 +02:00
parent dc5513a709
commit bb723282cc
3 changed files with 89 additions and 64 deletions

View File

@ -16,11 +16,13 @@ static constexpr std::array<const char*, 64> positions = {
};
constexpr auto INVALID_POS = positions.size();
static constexpr int R = 0; // rank index
static constexpr int F = 1; // file index
constexpr int operator ""_P(const char * c, size_t size) {
if (size < 2) return INVALID_POS;
int file = c[0] - 'a';
int rank = c[1] - '1';
int file = c[R] - 'a';
int rank = c[F] - '1';
int pos = rank * 8 + file;
if (pos < 0 || pos >= int(INVALID_POS)) return INVALID_POS;
return pos;
@ -113,10 +115,17 @@ std::string Chessboard::getRules(const std::string& prompt) const {
std::string result =
"\n"
"# leading space is very important!\n"
"\n"
"move ::= prompt \" \" ((piece | frompos) \" \" \"to \"?)? topos\n"
"\n"
"prompt ::= \" " + prompt + "\"\n";
"\n";
if (prompt.empty()) {
// result += "move ::= \" \" ((piece | frompos) \" \" \"to \"?)? topos\n";
result += "move ::= \" \" frompos \" \" \"to \"? topos\n";
}
else {
// result += "move ::= prompt \" \" ((piece | frompos) \" \" \"to \"?)? topos\n"
result += "move ::= prompt \" \" frompos \" \" \"to \"? topos\n"
"\n"
"prompt ::= \" " + prompt + "\"\n";
}
std::set<std::string> pieces;
std::set<std::string> from_pos;
@ -127,12 +136,12 @@ std::string Chessboard::getRules(const std::string& prompt) const {
from_pos.insert(positions[m.first]);
to_pos.insert(positions[m.second]);
}
if (!pieces.empty()) {
result += "piece ::= (";
for (auto& p : pieces) result += " \"" + p + "\" |";
result.pop_back();
result += ")\n\n";
}
// if (!pieces.empty()) {
// result += "piece ::= (";
// for (auto& p : pieces) result += " \"" + p + "\" |";
// result.pop_back();
// result += ")\n\n";
// }
if (!from_pos.empty()) {
result += "frompos ::= (";
for (auto& p : from_pos) result += " \"" + p + "\" |";
@ -213,7 +222,7 @@ std::string Chessboard::process(const std::string& command) {
auto pos_to = INVALID_POS;
if (tokens.size() == 1) {
type = Piece::Types::Pawn;
pos_to = tokenToPos(tokens[0]);
pos_to = tokenToPos(tokens.front());
}
else {
pos_from = tokenToPos(tokens.front());
@ -290,59 +299,60 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
switch (piece.type) {
case Piece::Pawn: {
std::string next = cur;
piece.color ? --next[1] : ++next[1]; // one down / up
std::string left = { char(next[0] - 1), next[1]};
piece.color ? --next[F] : ++next[F]; // one down / up
std::string left = { char(next[R] - 1), next[F]};
auto pos = tokenToPos(left);
if (pos != INVALID_POS && board[pos] && board[pos]->color != piece.color) result.emplace_back(piece.pos, pos);
std::string right = { char(next[0] + 1), next[1]};
std::string right = { char(next[R] + 1), next[F]};
pos = tokenToPos(right);
if (pos != INVALID_POS && board[pos] && board[pos]->color != piece.color) result.emplace_back(piece.pos, pos);
pos = tokenToPos(next);
if (pos != INVALID_POS && !board[pos]) result.emplace_back(piece.pos, pos);
else break;
piece.color ? --next[1] : ++next[1]; // one down / up
if (piece.color ? cur[F] != '7' : cur[F] != '2') break;
piece.color ? --next[F] : ++next[F]; // one down / up
pos = tokenToPos(next);
if (pos != INVALID_POS && !board[pos]) result.emplace_back(piece.pos, pos);
break;
}
case Piece::Knight: {
std::string next = cur;
--next[1]; --next[1]; --next[0];
--next[F]; --next[F]; --next[R];
auto pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[1]; --next[1]; ++next[0];
--next[F]; --next[F]; ++next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[1]; ++next[1]; --next[0];
++next[F]; ++next[F]; --next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[1]; ++next[1]; ++next[0];
++next[F]; ++next[F]; ++next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[1]; --next[0]; --next[0];
--next[F]; --next[R]; --next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[1]; --next[0]; --next[0];
++next[F]; --next[R]; --next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[1]; ++next[0]; ++next[0];
--next[F]; ++next[R]; ++next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[1]; ++next[0]; ++next[0];
++next[F]; ++next[R]; ++next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
break;
@ -350,7 +360,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
case Piece::Bishop: {
std::string next = cur;
while (true) {
--next[0]; --next[1];
--next[R]; --next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -361,7 +371,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
--next[0]; ++next[1];
--next[R]; ++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -372,7 +382,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0]; --next[1];
++next[R]; --next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -383,7 +393,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0]; ++next[1];
++next[R]; ++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -397,7 +407,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
case Piece::Rook: {
std::string next = cur;
while (true) {
--next[0];
--next[R];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -408,7 +418,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0];
++next[R];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -419,7 +429,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
--next[1];
--next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -430,7 +440,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[1];
++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -444,7 +454,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
case Piece::Queen: {
std::string next = cur;
while (true) {
--next[0]; --next[1];
--next[R]; --next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -455,7 +465,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
--next[0]; ++next[1];
--next[R]; ++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -466,7 +476,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0]; --next[1];
++next[R]; --next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -477,7 +487,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0]; ++next[1];
++next[R]; ++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -488,7 +498,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
--next[0];
--next[R];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -499,7 +509,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[0];
++next[R];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -510,7 +520,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
--next[1];
--next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -521,7 +531,7 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
next = cur;
while (true) {
++next[1];
++next[F];
auto pos = tokenToPos(next);
if (pos == INVALID_POS) break;
else if (board[pos]) {
@ -534,42 +544,42 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
}
case Piece::King: {
std::string next = cur;
--next[0]; --next[1];
--next[R]; --next[F];
auto pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[0]; ++next[1];
--next[R]; ++next[F];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[0]; --next[1];
++next[R]; --next[F];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[0]; ++next[1];
++next[R]; ++next[F];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[0];
--next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[0];
++next[R];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
--next[1];
--next[F];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
next = cur;
++next[1];
++next[F];
pos = tokenToPos(next);
if (pos != INVALID_POS && !(board[pos] && board[pos]->color == piece.color)) result.emplace_back(piece.pos, pos);
@ -582,9 +592,10 @@ void Chessboard::getValidMoves(const Piece& piece, std::vector<Move>& result) {
bool Chessboard::validatePawnMove(Piece::Colors color, int from_rank, int from_file, int to_rank, int to_file) {
int direction = color == Piece::White ? 1 : -1;
bool two_ranks = color == Piece::White ? from_rank == 1 : from_rank == 6;
if (from_file == to_file) {
if (from_rank == to_rank - direction) return board[to_rank * 8 + to_file] == nullptr;
if (from_rank == to_rank - direction * 2) return board[(to_rank - direction) * 8 + to_file] == nullptr && board[to_rank * 8 + to_file] == nullptr;
if (two_ranks && from_rank == to_rank - direction * 2) return board[(to_rank - direction) * 8 + to_file] == nullptr && board[to_rank * 8 + to_file] == nullptr;
}
else if (from_file + 1 == to_file || from_file - 1 == to_file) {
if (from_rank == to_rank - direction) return board[to_rank * 8 + to_file] != nullptr && board[to_rank * 8 + to_file]->color != color;

View File

@ -45,8 +45,8 @@ std::string WChess::stringify_board() const {
void WChess::run() {
set_status("loading data ...");
bool have_prompt = false;
bool ask_prompt = true;
bool have_prompt = true;
bool ask_prompt = !have_prompt;
float logprob_min0 = 0.0f;
float logprob_min = 0.0f;
@ -60,7 +60,7 @@ void WChess::run() {
std::vector<float> pcmf32_cur;
std::vector<float> pcmf32_prompt;
const std::string k_prompt = "King bishop rook queen knight";
const std::string k_prompt = have_prompt ? "" : "checkmate";
while (check_running()) {
// delay
@ -116,8 +116,9 @@ void WChess::run() {
have_prompt = true;
}
} else {
pcmf32_cur.insert(pcmf32_cur.begin(), WHISPER_SAMPLE_RATE, 0.0f);
if (!pcmf32_prompt.empty()) pcmf32_cur.insert(pcmf32_cur.begin(), pcmf32_prompt.begin(), pcmf32_prompt.end());
static const size_t MIN_SIZE = 1.2 * WHISPER_SAMPLE_RATE;
if (MIN_SIZE > pcmf32_cur.size()) pcmf32_cur.insert(pcmf32_cur.begin(), MIN_SIZE - pcmf32_cur.size(), 0.0f);
std::string rules = m_board->getRules(k_prompt);
fprintf(stdout, "%s: grammar rules:\n'%s'\n", __func__, rules.c_str());

View File

@ -131,7 +131,15 @@
printTextarea('js: Preparing ...');
},
postRun: function() {
printTextarea('js: Initialized successfully!');
printTextarea('js: Module initialized successfully!');
instance = Module.init('whisper.bin');
if (instance) {
printTextarea("js: whisper initialized, instance: " + instance);
}
else {
printTextarea("js: failed to initialize whisper");
}
}
};
@ -297,6 +305,20 @@
var intervalUpdate = null;
var movesAll = '';
document.body.addEventListener('keydown', function(event) {
if (event.keyCode === 32) {
document.getElementById('toggler').innerText = "Release";
onStart();
}
}, true);
document.body.addEventListener('keyup', function(event) {
if (event.keyCode === 32) {
document.getElementById('toggler').innerText = "Hold";
onStop();
}
}, true);
document.getElementById('toggler').addEventListener('mousedown', function(event) {
this.innerText = "Release";
onStart();
@ -309,15 +331,6 @@
function onStart() {
if (!instance) {
instance = Module.init('whisper.bin');
if (instance) {
printTextarea("js: whisper initialized, instance: " + instance);
}
}
if (!instance) {
printTextarea("js: failed to initialize whisper");
return;
}