#include <pdcurses.h>
#include <locale.h>
#include <string.h>
#include <windows.h> // SetConsoleOutputCP
#include "shougi_data.h"

extern void set_board_from_dataretu();
extern void draw_board(int is_turn);
extern void csv_read();

void draw_board(int is_turn);

extern int cursor_x; // 初期カーソル位置(ファイル)
extern int cursor_y; // 初期カーソル位置(段)

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

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

int is_selected = 0;  // 駒を選択中かどうか
int from_x = -1;  // 選択した位置x
int from_y = -1;  // 選択した位置y
int is_turn;  // グローバルまたは main で宣言

int draw_selection() {
    const char *options[] = {"先手", "後手"};
    int choice = 0;
    int ch;


    curs_set(0);
    keypad(stdscr, TRUE);

    int base_y = 2;
    int base_x = 4;

    // タイトル
    const char *title = "将棋ゲーム";

    while (1) {
        clear();
        mvprintw(base_y, (COLS - strlen(title)) / 2, "%s", title);
        mvprintw(base_y + 2, base_x, "=== 先手・後手を選択してください ===");

        for (int i = 0; i < 2; i++) {
            move(base_y + 4 + i * 2, base_x);
            clrtoeol();
            if (i == choice) attron(A_REVERSE);
            mvprintw(base_y + 4 + i * 2, base_x + 5, "%s", options[i]);
            if (i == choice) attroff(A_REVERSE);
        }

        mvprintw(base_y + 10, base_x, "↑↓で選択、Enterで決定");
        refresh();

        ch = getch();
        if (ch == KEY_UP || ch == 'w') {
            // 上キーまたは 'w' で選択を上へ
            if (choice > 0) {
                choice--;
            } else {
                choice = 1; // 上端を超えたら下へ(ループ)
            }
        }
        else if (ch == KEY_DOWN || ch == 's') {
            // 下キーまたは 's' で選択を下へ
            if (choice < 1) {
                choice++;
            } else {
                choice = 0; // 下端を超えたら上へ(ループ)
            }
        }
        else if (ch == 10 || ch == KEY_ENTER) {
            // Enterキーで決定
            break;
        }
    }

    is_turn = choice;

    mvprintw(base_y + 8, base_x, "選択: %s", is_turn == 0 ? "先手" : "後手");
    refresh();
    napms(1000); // 1秒待機
    clear();     // ここで画面をクリアして盤描画へ
    return is_turn;
}

int main(void) {

    initscr();
    noecho();
    cbreak();
    keypad(stdscr, TRUE);
    curs_set(0);

    setlocale(LC_ALL, "");
    SetConsoleOutputCP(CP_UTF8);

    start_color();                           // 色機能を有効化
    init_pair(1, COLOR_WHITE, COLOR_BLACK);  // 通常
    init_pair(2, COLOR_BLACK, COLOR_YELLOW); // カーソル位置(背景を黄色に)
    init_pair(3, COLOR_WHITE, COLOR_BLUE);   // 選択中の駒(追従表示)
    init_pair(4, COLOR_BLACK, COLOR_GREEN);   // 移動可能範囲

    keypad(stdscr, TRUE);

    csv_read();

    // 盤面初期化
    memset(board, 0, sizeof(board));

    set_board_from_dataretu();

    is_turn = draw_selection();  // 先手・後手選択

    while (1) {

        draw_board(is_turn);

        int ch = getch();
        if (ch == 'q') break;

        switch (ch) {
            case KEY_UP:    if (cursor_y > 1) cursor_y--; break;
            case KEY_DOWN:  if (cursor_y < BOARD_SIZE) cursor_y++; break;
            case KEY_LEFT:  if (cursor_x > 1) cursor_x--; break;
            case KEY_RIGHT: if (cursor_x < BOARD_SIZE) cursor_x++; break;
            case '\n':   // UNIX系
            case '\r':   // Windows系
            case KEY_ENTER: // PDCurses用
            {
                if (!is_selected) {
                    // まだ選択していない -> カーソル位置の駒を選ぶ(あれば)
                    if (board[cursor_y - 1][cursor_x - 1] != NULL) {
                        char owner = board[cursor_y-1][cursor_x-1][0]; // 先頭文字を取得
                        if ((is_turn == 0 && owner != 'v') || (is_turn == 1 && owner == 'v')) {
                            is_selected = 1;
                            from_x = cursor_x;
                            from_y = cursor_y;
                            selected_piece = board[from_y - 1][from_x - 1]; // ポインタだけ保持
                            board[from_y - 1][from_x - 1] = NULL; // 見た目上は持ち上げる
                        }else{
                            // 手番に合わない駒は選択不可
                            beep(); // 簡単に警告音
                        }
                    }
                } else {
                    // 既に選択中 -> 現在カーソル位置に置く(同じマスならキャンセル扱い)
                    if (cursor_x == from_x && cursor_y == from_y) {
                        // 同じマスに戻す(キャンセル)
                        board[from_y - 1][from_x - 1] = selected_piece;
                    } else {
                        // 上書きして置く(取る処理はここで入れられます)
                        board[cursor_y - 1][cursor_x - 1] = selected_piece;
                        // ← ここで手番交代
                        is_turn = (is_turn + 1) % 2;
                    }
                    // リセット
                    selected_piece = NULL;
                    is_selected = 0;
                    from_x = from_y = -1;
                }
                break;
            }
        }
    }

    endwin();
    return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: