#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;
}
To embed this project on your website, copy the following code and paste it into your website's HTML: