shougi_highlight.c

an anonymous user · October 12, 2025
#include <string.h>
#include <pdcurses.h>
#include "shougi_data.h"

void highlight_moves(int y, int x, const char *piece, int is_gote);

typedef struct {
    int dx;
    int dy;
} Direction;

const Direction HO[]  = { {0, -1} };  // 歩
const Direction KYO[] = { {0, -1} };  // 香
const Direction KEI[] = { {-1, -2}, {1, -2} }; // 桂
const Direction GIN[] = { {-1,-1}, {0,-1}, {1,-1}, {-1,1}, {1,1} };
const Direction KIN[] = { {-1,-1}, {0,-1}, {1,-1}, {-1,0}, {1,0}, {0,1} };
const Direction OU[]  = { {-1,-1}, {0,-1}, {1,-1}, {-1,0}, {1,0}, {-1,1}, {0,1}, {1,1} };
const Direction KAKU[]= { {-1,-1}, {1,-1}, {-1,1}, {1,1} };
const Direction HI[]  = { {0,-1}, {0,1}, {-1,0}, {1,0} };

int get_moves(const char *piece, int is_gote, Direction moves[], int *max_steps, int *dir_count) {
    const Direction *src = NULL;
    int count = 0;

    const char *pname = piece;
    if (piece[0] == 'v') pname = piece + 1;
    // const char *pname = piece;
    // pname = piece + 3;
    if (strcmp(pname, "歩") == 0) {
        src = HO;  count = sizeof(HO) / sizeof(Direction); *max_steps = 1;
    } else if (strcmp(pname, "香") == 0) {
        src = KYO; count = sizeof(KYO) / sizeof(Direction); *max_steps = 8;
    } else if (strcmp(pname, "桂") == 0) {
        src = KEI; count = sizeof(KEI) / sizeof(Direction); *max_steps = 1;
    } else if (strcmp(pname, "銀") == 0) {
        src = GIN; count = sizeof(GIN) / sizeof(Direction); *max_steps = 1;
    } else if (strcmp(pname, "金") == 0) {
        src = KIN; count = sizeof(KIN) / sizeof(Direction); *max_steps = 1;
    } else if (strcmp(pname, "王") == 0) {
        src = OU;  count = sizeof(OU) / sizeof(Direction); *max_steps = 1;
    } else if (strcmp(pname, "角") == 0) {
        src = KAKU; count = sizeof(KAKU) / sizeof(Direction); *max_steps = 8;
    } else if (strcmp(pname, "飛") == 0) {
        src = HI;  count = sizeof(HI) / sizeof(Direction); *max_steps = 8;
    } else {
        return 0;
    }

    memcpy(moves, src, sizeof(Direction) * count);
    *dir_count = count;

    // 後手なら縦方向反転
    if (is_gote) {
        for (int i = 0; i < count; i++) {
            moves[i].dy = -moves[i].dy;
        }
    }

    return 1;
}

void highlight_moves(int y, int x, const char *piece, int is_gote) {
    Direction dirs[8];
    int max_steps, dir_count;
    if (!get_moves(piece, is_gote, dirs, &max_steps, &dir_count)) return;

    for (int i = 0; i < dir_count; i++) {
        for (int step = 1; step <= max_steps; step++) {
            int ny = y + dirs[i].dy * step;
            int nx = x + dirs[i].dx * step;
            if (ny < 0 || ny >= BOARD_SIZE || nx < 0 || nx >= BOARD_SIZE)
                break;

            // スペース文字(0x20)でセルの表示領域をクリア
            mvprintw(ORIGIN_Y + ny * CELL_H, ORIGIN_X + nx * CELL_W, "%*s", CELL_W - 2, " ");
            // ここでハイライト表示(PDCursesなら背景色変更)
            attron(COLOR_PAIR(4));
            mvaddstr(ORIGIN_Y + ny * CELL_H, ORIGIN_X + nx * CELL_W, " ");
            attroff(COLOR_PAIR(4));
        }
    }
}
Output

Comments

Please sign up or log in to contribute to the discussion.