実現したいこと
以下のソースで将棋盤の5の5に歩を表示して、カーソルに歩を合わせると、
色が変わるつもりで、プログラムを作成しました。
しかし画像のように歩が白くなり、カーソルをつけても、色が変わりません。
何か解決方法があれば、お聞きしたいです。
・Makefile
# コンパイラの指定 CC=gcc # コンパイル時のオプション CFLAGS=-I. -Wall # 最終的な実行ファイル名 TARGET=myapp.exe LIBS = -lpdcurses # 最終ターゲット $(TARGET): shougi_test.o explode.o $(CC) -o $(TARGET) shougi_test.o explode.o $(LIBS) # main.cからmain.oを生成 shougi_test.o: shougi_test.c $(CC) -c shougi_test.c $(CFLAGS) # sub.cからsub.oを生成 explode.o: explode.c $(CC) -c explode.c $(CFLAGS) # 'make clean' を実行した時に実行ファイルとオブジェクトファイルを削除 clean: rm -f $(TARGET) shougi_test.o explode.o
shougi_test.c
#include <pdcurses.h> #include <stdio.h> #include <locale.h> #include <string.h> #include <windows.h> // SetConsoleOutputCP #include "shougi_shisaku.h" extern void explode(const char*, char*, int); // 項目を取り出す person data[81]; // 駒のデータの読み込み person dataretu[81]; // 駒のデータのコピー先 motikoma sente[20]; //先手の持ち駒 motikoma gote[20]; //先手の持ち駒 #define BOARD_SIZE 9 // 将棋は9x9 #define CELL_W 4 #define CELL_H 2 int start_y = 2; // 盤面の開始位置(縦方向) int start_x = 4; // 盤面の開始位置(横方向) // 画面上の盤左上のオフセット #define ORIGIN_Y (start_y + 1) #define ORIGIN_X (start_x + 2) int cursor_x = 5; // 初期カーソル位置(ファイル) int cursor_y = 5; // 初期カーソル位置(段) // 盤面を管理する2次元配列 // NULLなら空マス、文字列なら駒 const char *board[BOARD_SIZE][BOARD_SIZE]; // 駒を選択中かどうか int is_selected = 0; int from_x, from_y; // 選択した位置 void csv_read(){ FILE* fp; char buf[512], * cp; int tatehoukou; fp = fopen("shougi_banmen.csv", "r"); // 将棋のファイルを開く if (fp == NULL) goto END; // ファイルを開けない tatehoukou = 0; memset(&data[0], '\0', sizeof(data)); // データの全文字をNULLに memset(&sente[0], '\0', sizeof(sente)); // データの全文字をNULLに memset(&gote[0], '\0', sizeof(gote)); // データの全文字をNULLに while (1) { cp = fgets(buf, 256, fp); // 1レコードを読む if (cp == NULL) break; // EOF explode(",", buf, tatehoukou); // csvデータを1行ずつ、項目を取り出す tatehoukou = tatehoukou + 1; if (tatehoukou == 9) break; } fclose(fp); // 将棋のファイルを閉じる // memcpyを使ったコピー memcpy(&dataretu, &data, sizeof(person)*81); END:; } void place_piece(int file, int rank, const char *piece) { // file: 1..9 (左から1列目を1とする) // rank: 1..9 (上から1行目を1とする) if (file < 1 || file > BOARD_SIZE || rank < 1 || rank > BOARD_SIZE) return; int Screen_y = ORIGIN_Y + (rank - 1) * CELL_H; int Screen_x = ORIGIN_X + (file - 1) * CELL_W; // 少し中央寄せ mvaddstr(Screen_y, Screen_x, piece); } void draw_board() { // タイトル 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) { attron(COLOR_PAIR(2)); // カーソル位置反転 mvprintw(sy, sx, "%s", board[y][x] ? board[y][x] : " "); attroff(COLOR_PAIR(2)); } else { attron(COLOR_PAIR(1)); mvprintw(sy, sx, "%s", board[y][x] ? board[y][x] : " "); attroff(COLOR_PAIR(1)); } } } } int main(void) { setlocale(LC_ALL, ""); SetConsoleOutputCP(CP_UTF8); initscr(); start_color(); // 色機能を有効化 init_pair(1, COLOR_WHITE, COLOR_BLACK); // 白文字+黒背景 init_pair(2, COLOR_BLACK, COLOR_WHITE); // 黒文字+白背景(反転用) noecho(); cbreak(); keypad(stdscr, TRUE); csv_read(); // 盤面初期化(5五に歩を置く) memset(board, 0, sizeof(board)); board[4][4] = "歩"; while (1) { clear(); draw_board(); refresh(); 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) { is_selected = 1; from_x = cursor_x; from_y = cursor_y; } } else { // 移動先に置く board[cursor_y-1][cursor_x-1] = board[from_y-1][from_x-1]; board[from_y-1][from_x-1] = NULL; is_selected = 0; } break; } } } endwin(); return 0; }
shougi_shisaku.h
#pragma once typedef struct koma_info { int tate; // 位置_縦 int yoko; // 位置_横 int sente; // 先手_後手 char koma[10]; // 駒の種類 } person; typedef struct koma_shurui { char koma[10]; // 駒の種類 } motikoma;
・shougi_banmen.csv
後香,後桂,後銀,後金,後王,後金,後銀,後桂,後香, ,後飛,,,,,,後角,, 後歩,後歩,後歩,後歩,後歩,後歩,後歩,後歩,後歩, ,,,,,,,,, ,,,,,,,,, ,,,,,,,,, 先歩,先歩,先歩,先歩,先歩,先歩,先歩,先歩,先歩, ,先角,,,,,,先飛,, 先香,先桂,先銀,先金,先王,先金,先銀,先桂,先香,
explode.c
#include <stdio.h> #include <string.h> #include "shougi_shisaku.h" void explode(const char*, char*, int); // 項目を取り出す extern person data[81]; // 駒のデータの読み込み int koma_cnt = 0; void explode( /*----------------------------------*/ /* CSVデータから項目を取り出す */ /*----------------------------------*/ const char* kugiri, // 区切り文字 char* buf, // CSVの1レコード int tatehoukou) { char* cp0, * cp; int yokohoukou = 0, len; cp0 = buf; // CSVデータの先頭アドレス for (yokohoukou = 0; yokohoukou < 9; yokohoukou++) { if (*cp0 == 0x22) cp0++; // 最初の"(0x22)を除く cp = strstr(cp0, kugiri); // 区切り文字を検索 if (cp == NULL) break; // 区切り文字なし len = cp - cp0; // 項目の文字数 if (*(cp - 1) == 0x22) len--; // 最後の"(0x22)を除く if (len > 0) // 項目あり { memcpy(&data[koma_cnt].koma[0], cp0, len); // 項目の文字列をコピー data[koma_cnt].tate = tatehoukou + 1; data[koma_cnt].yoko = 9 - yokohoukou; if (strncmp(data[koma_cnt].koma, "先", 2) == 0){ data[koma_cnt].sente = 1; } else { data[koma_cnt].sente = 2; } koma_cnt = koma_cnt + 1; }else{ data[koma_cnt].tate = tatehoukou + 1; data[koma_cnt].yoko = 9 - yokohoukou; koma_cnt = koma_cnt + 1; } cp0 = cp + 1; // 次の文字のアドレス } }
発生している問題・分からないこと
質問に詳細を記載した。
該当のソースコード
特になし
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
質問に詳細を記載した。
補足
特になし

回答2件
あなたの回答
tips
プレビュー