shougi_boad

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

void draw_board();
void set_board_from_dataretu();

extern void highlight_moves(int y, int x, const char *piece, int is_gote);
extern person dataretu[81];  // 駒のデータの読み込み
extern int is_selected;  // 駒を選択中かどうか
extern int from_x;  // 選択した位置x
extern int from_y;  // 選択した位置y

// 盤面を管理する2次元配列
// NULLなら空マス、文字列なら駒
extern const char *board[BOARD_SIZE][BOARD_SIZE];

extern const char *selected_piece; // 動かす対象の駒の種類

int start_y = 2;   // 盤面の開始位置(縦方向)
int start_x = 4;   // 盤面の開始位置(横方向)
int cursor_x = 5; // 初期カーソル位置(ファイル)
int cursor_y = 5; // 初期カーソル位置(段)

void draw_board() {

    int is_gote;
    clear();
    // タイトル
    const char *title = "将棋ゲーム";
    mvprintw(0, (COLS - strlen(title)) / 2, "%s", title);

    const char *kansuji[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九"};
    // 枠を描画
    for (int y = 0; y <= BOARD_SIZE; y++) {
        for (int x = 0; x <= BOARD_SIZE; x++) {
            int py = start_y + y * CELL_H;
            int px = start_x + x * CELL_W;
            mvaddch(py, px, '+');   // 交点

            if (x < BOARD_SIZE) { // 横線
                for (int i = 1; i < CELL_W; i++) {
                    mvaddch(py, px + i, '-');
                }
            }
            if (y < BOARD_SIZE) { // 縦線
                for (int j = 1; j < CELL_H; j++) {
                    mvaddch(py + j, px, '|');
                }
            }
        }
    }

    // 筋(上) — 右から左に 9 〜 1
    for (int x = 0; x < BOARD_SIZE; x++) {
        int px = start_x + x * CELL_W + CELL_W / 2;
        mvprintw(start_y - 1, px, "%d", 9 - x);
    }

    // 段(右) — 上から下に 一〜九
    for (int y = 0; y < BOARD_SIZE; y++) {
        int py = start_y + y * CELL_H + CELL_H / 2;
        int px = start_x + BOARD_SIZE * CELL_W + 2; // 右側に表示
        mvprintw(py, px, "%s", kansuji[y]);
    }

    // 駒描画
    for (int y = 0; y < BOARD_SIZE; y++) {
        for (int x = 0; x < BOARD_SIZE; x++) {
            int sy = ORIGIN_Y + y * CELL_H;
            int sx = ORIGIN_X + x * CELL_W;
            
            if (cursor_y - 1 == y && cursor_x - 1 == x) {
                attrset(COLOR_PAIR(2));  // 黒字+黄色背景
            } else {
                attrset(COLOR_PAIR(1));  // 白字+黒背景
            }

            // もし選択中で、元のマスがここなら空白(持ち上げ済み)
            if (is_selected && (from_y - 1) == y && (from_x - 1) == x) {
                mvaddstr(sy, sx, "  "); // 元マスは空に見せる
            } else {
                // 通常はボード上の文字を出す
                mvaddstr(sy, sx, board[y][x] ? board[y][x] : "  ");
            }
        }
    }

    // もし駒を選択中なら、カーソル位置に選択中の駒を描画して追従表示(選択の視認性向上)
    if (is_selected && selected_piece != NULL) {

        // 後手かどうか
        is_gote = (strstr(selected_piece, "後") != NULL);

        highlight_moves(from_y - 1, from_x - 1, selected_piece, is_gote);

        // 選択中の駒(例:「歩」)を元の位置に再描画して見えるようにする
        attron(COLOR_PAIR(3));  // 少し強調した色でもOK
        mvaddstr(ORIGIN_Y + (cursor_y - 1) * CELL_H, ORIGIN_X + (cursor_x - 1) * CELL_W, selected_piece);
        attroff(COLOR_PAIR(3));
    }

    attrset(A_NORMAL); // 属性をリセット
    refresh();
}

void set_board_from_dataretu() {
    for (int y = 0; y < BOARD_SIZE; y++) {
        for (int x = 0; x < BOARD_SIZE; x++) {
            int index = y * BOARD_SIZE + x;  // 0〜80の通し番号
            if (strlen(dataretu[index].koma) > 0) {
                // dataretu[index].moji が駒文字(例:"歩")なら代入
                board[y][x] = dataretu[index].koma; // malloc確保してコピー
            } else {
                board[y][x] = NULL; // 空マス
            }
        }
    }
}

Output

Comments

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