diff options
Diffstat (limited to 'src/core/chess_cmd.c')
| -rw-r--r-- | src/core/chess_cmd.c | 397 |
1 files changed, 0 insertions, 397 deletions
diff --git a/src/core/chess_cmd.c b/src/core/chess_cmd.c deleted file mode 100644 index 6ad1058..0000000 --- a/src/core/chess_cmd.c +++ /dev/null @@ -1,397 +0,0 @@ -/* ── Chess command handler ──────────────────────────────────── */ - -#include "hybbx/chess.h" -#include "hybbx/session.h" -#include "hybbx/service.h" -#include "hybbx/hybbx.h" - -#include <string.h> -#include <strings.h> -#include <stdio.h> -#include <ctype.h> - -static int str_ieq(const char *a, const char *b) -{ - if (a == NULL || b == NULL) return 0; - while (*a != '\0' && *b != '\0') { - char ca = (char)(*a >= 'A' && *a <= 'Z' ? *a + 32 : *a); - char cb = (char)(*b >= 'A' && *b <= 'Z' ? *b + 32 : *b); - if (ca != cb) return 0; - a++; b++; - } - return *a == '\0' && *b == '\0'; -} - -hybbx_result_t cmd_chess(hybbx_service_t *service, - hybbx_session_t *session, - const hybbx_parsed_command_t *cmd) -{ - const char *sub; - chess_game_t *game; - char line[128]; - - (void)service; - - if (!hybbx_session_logged_in(session)) { - hybbx_session_write_line(session, "Log in to play chess."); - return HYBBX_ERR_DENIED; - } - - sub = (cmd->argc >= 1) ? cmd->argv[0] : "help"; - - /* ── /chess help ───────────────────────────────────────── */ - if (str_ieq(sub, "help") || str_ieq(sub, "?")) { - hybbx_session_write_line(session, "Chess commands:"); - hybbx_session_write_line(session, - " /chess new - Create a new game (you are White)"); - hybbx_session_write_line(session, - " /chess join - Join an open game as Black"); - hybbx_session_write_line(session, - " /chess join G2 - Join a specific game by ID"); - hybbx_session_write_line(session, - " /chess watch - Watch a game as spectator"); - hybbx_session_write_line(session, - " /chess watch G2 - Watch a specific game"); - hybbx_session_write_line(session, - " /chess board - Show current board"); - hybbx_session_write_line(session, - " /chess move e2 e4 - Move piece (alias: /mv e2 e4)"); - hybbx_session_write_line(session, - " /chess resign - Resign the game"); - hybbx_session_write_line(session, - " /chess draw - Offer/accept draw"); - hybbx_session_write_line(session, - " /chess list - List games with board + spectators"); - hybbx_session_write_line(session, - " /chess leave - Stop watching"); - hybbx_session_write_line(session, - "Board auto-refreshes every 15 seconds for all."); - return HYBBX_OK; - } - - /* ── /chess list ───────────────────────────────────────── */ - if (str_ieq(sub, "list") || str_ieq(sub, "ls")) { - unsigned found = 0; - unsigned i; - for (i = 0; i < hybbx_chess_max_games(); i++) { - game = hybbx_chess_get_game(i); - if (game == NULL || !game->active) continue; - - /* Header: game id, players, state */ - { - const char *state = - (game->result != CHESS_RESULT_NONE) ? "finished" : - (game->black_session == NULL) ? "waiting for Black" : "playing"; - snprintf(line, sizeof(line), - "[%s] %s(W) vs %s(B) %s move %u", - game->game_id, game->white_name, - game->black_session ? game->black_name : "...", - state, game->move_number); - } - hybbx_session_write_line(session, line); - - /* Board */ - hybbx_chess_send_board(game, session); - - /* Spectators */ - if (game->spectator_count > 0) { - unsigned j; - int n = snprintf(line, sizeof(line), " Spectators (%u): ", - game->spectator_count); - for (j = 0; j < game->spectator_count; j++) { - const char *sname = hybbx_session_display_name( - game->spectators[j]); - if (j > 0) - n += snprintf(line + n, sizeof(line) - (size_t)n, ", "); - n += snprintf(line + n, sizeof(line) - (size_t)n, "%s", - sname ? sname : "?"); - } - hybbx_session_write_line(session, line); - } - - hybbx_session_write_line(session, ""); - found++; - } - if (!found) - hybbx_session_write_line(session, " No active games."); - return HYBBX_OK; - } - - /* ── /chess new ────────────────────────────────────────── */ - if (str_ieq(sub, "new") || str_ieq(sub, "create")) { - unsigned i; - for (i = 0; i < hybbx_chess_max_games(); i++) { - game = hybbx_chess_get_game(i); - if (game && game->active && - hybbx_chess_is_player(game, session)) { - hybbx_session_write_line(session, - "You are already in a game. /chess resign first."); - return HYBBX_ERR_DENIED; - } - } - game = hybbx_chess_create_game(session, - hybbx_session_username(session)); - if (game == NULL) { - hybbx_session_write_line(session, "No free game slots."); - return HYBBX_ERR_DENIED; - } - snprintf(line, sizeof(line), "Game %s created. You are White.", - game->game_id); - hybbx_session_write_line(session, line); - hybbx_session_write_line(session, - "Waiting for Black to /chess join..."); - hybbx_chess_send_board(game, session); - return HYBBX_OK; - } - - /* ── /chess join [id] ──────────────────────────────────── */ - if (str_ieq(sub, "join")) { - const char *id = (cmd->argc >= 2) ? cmd->argv[1] : NULL; - unsigned i; - - for (i = 0; i < hybbx_chess_max_games(); i++) { - game = hybbx_chess_get_game(i); - if (game && game->active && - hybbx_chess_is_player(game, session)) { - hybbx_session_write_line(session, - "You are already in a game. /chess resign first."); - return HYBBX_ERR_DENIED; - } - } - - if (id) { - game = hybbx_chess_find_game_by_id(id); - if (game == NULL || !game->active) { - hybbx_session_write_line(session, "Game not found."); - return HYBBX_ERR_NOT_FOUND; - } - if (game->black_session != NULL) { - hybbx_session_write_line(session, "Game is full."); - return HYBBX_ERR_DENIED; - } - } else { - game = hybbx_chess_find_open_game(); - if (game == NULL) { - hybbx_session_write_line(session, - "No open games. /chess new to create one."); - return HYBBX_ERR_NOT_FOUND; - } - } - - hybbx_chess_join_game(game, session, - hybbx_session_username(session)); - snprintf(line, sizeof(line), "Joined %s as Black. Game on!", - game->game_id); - hybbx_session_write_line(session, line); - hybbx_chess_send_board(game, game->white_session); - hybbx_chess_send_board(game, session); - return HYBBX_OK; - } - - /* ── /chess watch [id] ─────────────────────────────────── */ - if (str_ieq(sub, "watch") || str_ieq(sub, "spectate")) { - const char *id = (cmd->argc >= 2) ? cmd->argv[1] : NULL; - unsigned i; - - if (id) { - game = hybbx_chess_find_game_by_id(id); - } else { - game = NULL; - for (i = 0; i < hybbx_chess_max_games(); i++) { - chess_game_t *g = hybbx_chess_get_game(i); - if (g && g->active && g->black_session != NULL) { - game = g; - break; - } - } - } - if (game == NULL || !game->active) { - hybbx_session_write_line(session, "No game to watch."); - return HYBBX_ERR_NOT_FOUND; - } - if (!hybbx_chess_add_spectator(game, session)) { - hybbx_session_write_line(session, "Spectator list full."); - return HYBBX_ERR_DENIED; - } - snprintf(line, sizeof(line), - "Watching %s. Board refreshes every %ds.", - game->game_id, CHESS_REFRESH_SEC); - hybbx_session_write_line(session, line); - hybbx_chess_send_board(game, session); - return HYBBX_OK; - } - - /* ── /chess leave ──────────────────────────────────────── */ - if (str_ieq(sub, "leave") || str_ieq(sub, "unwatch")) { - unsigned i; - for (i = 0; i < hybbx_chess_max_games(); i++) { - game = hybbx_chess_get_game(i); - if (game && game->active && - hybbx_chess_is_spectator(game, session)) { - hybbx_chess_remove_spectator(game, session); - hybbx_session_write_line(session, "Stopped watching."); - return HYBBX_OK; - } - } - hybbx_session_write_line(session, - "You are not watching any game."); - return HYBBX_ERR_NOT_FOUND; - } - - /* ── /chess board ──────────────────────────────────────── */ - if (str_ieq(sub, "board") || str_ieq(sub, "show")) { - unsigned i; - game = NULL; - for (i = 0; i < hybbx_chess_max_games(); i++) { - chess_game_t *g = hybbx_chess_get_game(i); - if (g && g->active && - (hybbx_chess_is_player(g, session) || - hybbx_chess_is_spectator(g, session))) { - game = g; - break; - } - } - if (game == NULL) { - hybbx_session_write_line(session, - "Not in a game. /chess new, join, or watch."); - return HYBBX_ERR_NOT_FOUND; - } - hybbx_chess_send_board(game, session); - return HYBBX_OK; - } - - /* ── /chess move e2 e4 ─────────────────────────────────── */ - if (str_ieq(sub, "move") || str_ieq(sub, "mv") || str_ieq(sub, "m")) { - const char *from, *to; - char err[64]; - unsigned i; - - if (cmd->argc < 3) { - hybbx_session_write_line(session, - "Usage: /chess move e2 e4"); - return HYBBX_ERR_INVALID; - } - from = cmd->argv[1]; - to = cmd->argv[2]; - - game = NULL; - for (i = 0; i < hybbx_chess_max_games(); i++) { - chess_game_t *g = hybbx_chess_get_game(i); - if (g && g->active && g->result == CHESS_RESULT_NONE && - hybbx_chess_is_player(g, session)) { - chess_color_t color = hybbx_chess_player_color(g, session); - if (color == g->turn) { - game = g; - break; - } - } - } - if (game == NULL) { - hybbx_session_write_line(session, - "Not your turn or no active game."); - return HYBBX_ERR_DENIED; - } - - if (!hybbx_chess_make_move(game, from, to, 0, err, sizeof(err))) { - snprintf(line, sizeof(line), "Illegal: %s", err); - hybbx_session_write_line(session, line); - return HYBBX_ERR_INVALID; - } - - /* Broadcast to all */ - if (game->white_session) - hybbx_chess_send_board(game, game->white_session); - if (game->black_session) - hybbx_chess_send_board(game, game->black_session); - { - unsigned j; - for (j = 0; j < game->spectator_count; j++) - hybbx_chess_send_board(game, game->spectators[j]); - } - - if (game->result != CHESS_RESULT_NONE) { - const char *res; - unsigned j; - switch (game->result) { - case CHESS_WHITE_WINS: res = "White wins!"; break; - case CHESS_BLACK_WINS: res = "Black wins!"; break; - case CHESS_DRAW_STALEMATE: res = "Stalemate!"; break; - case CHESS_DRAW_AGREEMENT: res = "Draw!"; break; - default: res = "Game over."; break; - } - snprintf(line, sizeof(line), "[%s] %s", game->game_id, res); - if (game->white_session) - hybbx_session_write_line(game->white_session, line); - if (game->black_session) - hybbx_session_write_line(game->black_session, line); - for (j = 0; j < game->spectator_count; j++) - hybbx_session_write_line(game->spectators[j], line); - } - - return HYBBX_OK; - } - - /* ── /chess resign ─────────────────────────────────────── */ - if (str_ieq(sub, "resign")) { - unsigned i; - game = NULL; - for (i = 0; i < hybbx_chess_max_games(); i++) { - chess_game_t *g = hybbx_chess_get_game(i); - if (g && g->active && hybbx_chess_is_player(g, session)) { - game = g; - break; - } - } - if (game == NULL) { - hybbx_session_write_line(session, "You are not in a game."); - return HYBBX_ERR_NOT_FOUND; - } - hybbx_chess_resign(game, session); - snprintf(line, sizeof(line), "[%s] %s resigned.", - game->game_id, hybbx_session_username(session)); - if (game->white_session) - hybbx_session_write_line(game->white_session, line); - if (game->black_session) - hybbx_session_write_line(game->black_session, line); - { - unsigned j; - for (j = 0; j < game->spectator_count; j++) - hybbx_session_write_line(game->spectators[j], line); - } - return HYBBX_OK; - } - - /* ── /chess draw ───────────────────────────────────────── */ - if (str_ieq(sub, "draw")) { - unsigned i; - game = NULL; - for (i = 0; i < hybbx_chess_max_games(); i++) { - chess_game_t *g = hybbx_chess_get_game(i); - if (g && g->active && hybbx_chess_is_player(g, session)) { - game = g; - break; - } - } - if (game == NULL) { - hybbx_session_write_line(session, "You are not in a game."); - return HYBBX_ERR_NOT_FOUND; - } - hybbx_chess_offer_draw(game, session); - snprintf(line, sizeof(line), "[%s] Draw agreed.", - game->game_id); - if (game->white_session) - hybbx_session_write_line(game->white_session, line); - if (game->black_session) - hybbx_session_write_line(game->black_session, line); - { - unsigned j; - for (j = 0; j < game->spectator_count; j++) - hybbx_session_write_line(game->spectators[j], line); - } - return HYBBX_OK; - } - - hybbx_session_write_line(session, - "Unknown chess command. /chess help for list."); - return HYBBX_ERR_NOT_FOUND; -} |
