質問するログイン新規登録
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio Code

Visual Studio Codeとは、Microsoft社が開発したマルチプラットフォーム対応のテキストエディタです。Visual Studioファミリーの一員でもあります。拡張性とカスタマイズ性が高く、テキストエディタでありながら、IDEと遜色ない機能を備えることができます。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

Q&A

解決済

2回答

628閲覧

C言語とmingw64とgccによる将棋ゲームの作成

todasan

総合スコア87

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio Code

Visual Studio Codeとは、Microsoft社が開発したマルチプラットフォーム対応のテキストエディタです。Visual Studioファミリーの一員でもあります。拡張性とカスタマイズ性が高く、テキストエディタでありながら、IDEと遜色ない機能を備えることができます。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

0グッド

0クリップ

投稿2025/10/02 08:56

編集2025/10/02 11:52

0

0

実現したいこと

以下のソースで将棋盤の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等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

質問に詳細を記載した。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2025/10/02 11:20

「駒を描画」の部分で、変数 sx と sy が使われていません。これらは描画位置を指定するための座標値でしょうから、以下の様にするのではないでしょうか。 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; mvprintw(sy, sx, "%s", board[y][x] ? board[y][x] : " ");
jimbe

2025/10/02 11:46

ソースコードに対しては、コードのマークダウンの最初の「```」に言語名(件ではc言語ですので 'c')を付けて「```c」とすると、キーワードに色が付いたり行番号が付いたりしますので、ご活用ください。
todasan

2025/10/02 11:53

jimbeさん 了解しました。
todasan

2025/10/02 11:56

melian さん ご指摘通りに直したら、歩は意図通りに直りました。ありがとうございます。 質問内容を編集して、再度、投稿しましたが、カーソルを歩につけても歩は白に囲まれて、 色が変わりません。何か分かればご指摘は可能でしょうか。
thkana

2025/10/02 23:03

> 質問内容を編集して、再度、投稿しました あとから読む人には、それまでおこなわれたやりとりの意味が不明になります。修正や追記はいいですけれど、改変はやめてください。 修正、追記の範囲を超えるなら、新しい質問にしてください。質問が消費ポイント制だったりとか質問回数に制限があったりするわけではないですから。それによって回答者からみたあなたの評価が「質問を乱発する人」になる危険はありますが、もう遅いかと思いますのでいまさら恐れることはないでしょう。
thkana

2025/10/02 23:46

ぱっと見る限り、 ``` if (cursor_y - 1 == y && cursor_x - 1 == x) { attron(COLOR_PAIR(2)); // カーソル位置反転 <略> } else { <略> } ``` の部分でカーソル位置の文字を反転表示しているので、 > 画像のように歩が白くなり はプログラムに書いてある動作かと思います。 これはこれでそれっぽい動作なので、そうなるとあなたの期待する動作とあなたの書いたプログラムの動作が異なっているのでは...という話になるわけですが「どうなればあなたの期待通りなのか」が実は書かれていません。ひとこと「色が変わるつもり」とあるだけ。 コマがカーソル位置のとき、カーソル位置でないとき、それぞれどうなるのが期待値なのか教えてください。 また、あなたの意図したように「色を変える」処理はソースコードのどの部分ですか?
todasan

2025/10/03 01:08 編集

thkana さん コマがカーソル位置の時が、白の背面に黒文字を期待していました。画像のように。 それはそのようになっています。 コマがカーソル位置でない時は、白文字と黒の背景であってほしいですが、 上記と同じままです。 ソースコードでは以下の部分です。 ------------------------------------------------------------------------------------ init_pair(1, COLOR_WHITE, COLOR_BLACK); // 白文字+黒背景 init_pair(2, COLOR_BLACK, COLOR_WHITE); // 黒文字+白背景(反転用) 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)); } ------------------------------------------------------------------------------------
thkana

2025/10/03 03:52

ふ~ん、そうなんだ... こないだの質問/回答みたいに、そこで意図通りに切り替えの分岐をしているかどうか、printf()でも埋め込んで様子を覗いてみたらどうなっているかしら?9x9回繰り返すところなので改行しないとかの気遣いがないと画面が流れちゃうかもしれないけれど。 (前回の回答で、思い通りじゃありません->教えて、に直行しないで自分で調べる話をしたつもりだったのだけどなぁ)
thkana

2025/10/03 05:34 編集

[修正あり] あと、そこの2カ所のmvprintwを両方 mvprintw(sy, sx, "%s", "歩"); //修正 とでもしてその結果について考察してみてください。 (私だったら、同じのを2度書くのいやだから ```C int tmp_col = 1; if (cursor_y - 1 == y && cursor_x - 1 == x) { tmp_col=2;// カーソル位置表示色反転(なにを反転するのか明示する書き方を) } attron(COLOR_PAIR(tmp_col)); mvprintw(sy, sx, "%s", board[y][x] ? board[y][x] : " "); attroff(COLOR_PAIR(tmp_col)); ``` とか書きそうだけどそれはまた別の話)
jimbe

2025/10/03 16:03

ちなみに、反転なら A_REVERSE を(色も必要なら | で繋げて) attr に設定すれば(わざわざ反転した COLOR_PAIR を用意しなくても)いいんじゃないでしょうか。
jimbe

2025/10/04 14:35

編集履歴を見ましたら、melian さんのコメントのご指摘の後の編集で、 addstr → mvprintw の変更の他に attron/off に付いていた |A_REVERSE を取り除いていたんですね。 それによってカーソル位置の表示が(本来の想定通りに?)変わったはずなのですが、それを確認せずに書かれてしまったように見えます。
guest

回答2

0

ベストアンサー

コマがカーソル位置でない時は、白文字と黒の背景であってほしい

Windows11 に(MSYS2 で)インストールしている C コンパイラは gcc ではなく clang なので御参考です。

Makefile で CC=clang に設定し make すれば,特に問題なくコンパイルできました。
また,実行すると提示されている画面で起動できました。

PowerShell

1PS > clang --version 2clang version 21.1.1 3PS > make 4clang -c shougi_test.c -I. -Wall 5clang -c explode.c -I. -Wall 6clang -o myapp.exe shougi_test.o explode.o -lpdcurses 7PS > .\myapp.exe 8

次に,下向きの矢印キー(↓)を押すと下の画面となりますので意図(コマがカーソル位置でない時は白文字と黒の背景)どおりに動いていると思われます。

参考画面

なお,今回の質問内容とは関係ありませんが,文字の上で2回続けて Enter キーを押すと文字が消えてしまうので,下記の修正を加えた方が良いかもしれません。

C

1 // 移動先に置く 2 board[cursor_y-1][cursor_x-1] = board[from_y-1][from_x-1]; 3 board[from_y-1][from_x-1] = NULL; 4 is_selected = 0; 5 6 // カーソルが移動した場合のみ NULL に書き換えるように if 文を追加 7 8 // 移動先に置く 9 board[cursor_y-1][cursor_x-1] = board[from_y-1][from_x-1]; 10 if (cursor_y != from_y || cursor_x != from_x) 11 board[from_y-1][from_x-1] = NULL; 12 is_selected = 0;

投稿2025/10/04 09:18

編集2025/10/04 14:15
little_street

総合スコア528

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

todasan

2025/10/05 05:55

little_street さん ---------------------------------- 次に,下向きの矢印キー(↓)を押すと下の画面となりますので意図(コマがカーソル位置でない時は白文字と黒の背景)どおりに動いていると思われます。 ---------------------------------- カーソルは白地の正方形だったという事ですか。ありがとうございます。 駒の上に、エンター釦を2回押すと、消える事も解決しました。
thkana

2025/10/05 10:13

> コマがカーソル位置の時が、白の背面に黒文字を期待していました。 空白文字だから黒の部分がなくて背景が全部白。 > カーソルは白地の正方形だったという事ですか。 だから、「どうなることを期待しているのか」を言葉にしてみて欲しかったのだけれど。
todasan

2025/10/05 12:54

little_street さん 以下の線の部分で、白文字に黒背景という事で、カーソルに駒がない部分は、その部分が全て黒になると、 思っていました。でも白の正方形が残っていたのでそれがカーソルなのかと思いました。 しかし、この部分はまた改良して、問題はなくなりました。 ---------------------------------- 次に,下向きの矢印キー(↓)を押すと下の画面となりますので意図(コマがカーソル位置でない時は白文字と黒の背景)どおりに動いていると思われます。 ---------------------------------- 指摘を受けて改良して、問題もなくなりましたので、助かりました。
guest

0

※回答ではありません
Cygwin なので MinGW とは一部違うと思いますが、自分側の駒選択・移動先候補表示・移動が出来るものを作ってみました。
あまり整理されていませんし curses を良く知っている訳でもありませんが、色とか反転・点滅を使ってみましたので1つサンプル的に見て頂ければ。

test.c

c

1//#define PDCURSES //PDCursesを使う場合はコレを有効に 2 3#include <stdio.h> 4#include <unistd.h> 5#include <string.h> 6#include <time.h> 7#include <locale.h> 8 9#ifdef PDCURSES 10#include <pdcurses.h> 11#include <windows.h> 12#else 13#include <ncurses.h> 14#endif 15 16#define BOARD_XOFF 2 17#define BOARD_YOFF 1 18 19#define lengthof(array) (sizeof(array)/sizeof((array)[0])) 20#define dirsign(side) ((side)==1?-1:(side)==2?1:0) 21 22void init() { 23 setlocale(LC_ALL, ""); //日本語の化け対策 24#ifdef PDCURSES 25 SetConsoleOutputCP(CP_UTF8); 26#endif 27 initscr(); 28 noecho(); 29 cbreak(); 30 timeout(0); 31 curs_set(0); 32 keypad(stdscr, TRUE); 33 34 start_color(); 35 init_pair(1, COLOR_BLUE, COLOR_BLACK); 36 //init_pair(2, COLOR_RED, COLOR_BLACK); 37 init_pair(3, COLOR_MAGENTA, COLOR_BLACK); 38 //init_pair(4, COLOR_GREEN, COLOR_BLACK); 39 init_pair(5, COLOR_CYAN, COLOR_BLACK); 40 //init_pair(6, COLOR_YELLOW, COLOR_BLACK); 41 init_pair(7, COLOR_WHITE, COLOR_BLACK); 42 bkgd(COLOR_PAIR(7)); 43} 44 45void term() { 46 echo(); 47 timeout(-1); 48 endwin(); 49} 50 51void print_surface() { 52 const char *r[] = {"一","二","三","四","五","六","七","八","九"}; 53 54 attrset(COLOR_PAIR(1)); 55 int y = BOARD_YOFF; 56 mvaddstr(y++, BOARD_XOFF+1, "9 8 7 6 5 4 3 2 1"); 57 for(int i=0; ; ++i) { 58 mvaddstr(y++, BOARD_XOFF, "+"); 59 for(int j=0; j<9; ++j) addstr("--+"); 60 if(i >= 9) break; 61 mvaddstr(y++, BOARD_XOFF, "|"); 62 for(int j=0; j<9; ++j) addstr(" |"); 63 addstr(r[i]); 64 } 65} 66 67struct _game; 68 69typedef struct { 70 char *face; 71 int (*mm_func)(struct _game*,int,int); 72 int promoted; 73 int original; 74} PIECE; 75 76typedef struct _game { 77 const PIECE *piece[9][9]; 78 int side[9][9]; 79 int movable[9][9]; 80 int cx, cy; //カーソル位置 81 int sx, sy; //選択中駒位置 82} GAME; 83 84const char *get_face(GAME *game, int y, int x) { 85 if(game->piece[y][x]) return game->piece[y][x]->face; 86 return game->movable[y][x] ? "〇" : " "; 87} 88 89const int COLOR[] = { 7, 5, 3 }; 90 91int get_attr(GAME *game, int y, int x) { 92 return (game->movable[y][x] ? A_BLINK : 0) | //移動可 93 (game->cx==x&&game->cy==y ? A_REVERSE : 0) | //カーソル 94 COLOR_PAIR(COLOR[game->side[y][x]]); //陣営別色 95} 96 97void print_game(GAME *game) { 98 for(int y=0, yy=BOARD_YOFF+2; y<9; ++y, yy+=2) { 99 for(int x=0, xx=BOARD_XOFF+1; x<9; ++x, xx+=3) { 100 attrset(get_attr(game,y,x)); 101 mvaddstr(yy, xx, get_face(game,y,x)); 102 } 103 } 104} 105 106int on_board(int y, int x) { 107 return (0 <= y && y <= 8) && (0 <= x && x <= 8); 108} 109 110int mm_pattern(GAME *game, int y, int x, const int *d, int size) { 111 int side = game->side[y][x]; 112 int ds = dirsign(side); 113 int count = 0; 114 for(int i=0; i<size; i+=2) { 115 int yy = y + d[i] * ds; 116 int xx = x + d[i+1] * ds; 117 if(!on_board(yy,xx) || game->side[yy][xx]==side) continue; 118 game->movable[yy][xx] = 1; 119 ++count; 120 } 121 return count; 122} 123 124int mm_line(GAME *game, int y, int x, int dy, int dx) { 125 int side = game->side[y][x]; 126 int ds = dirsign(side); 127 int count = 0; 128 while(1) { 129 y += dy * ds; 130 x += dx * ds; 131 if(!on_board(y,x) || game->side[y][x]==side) break; 132 game->movable[y][x] = 1; 133 ++count; 134 if(game->side[y][x]) break; 135 } 136 return count; 137} 138 139//marking_movable functions 140//王/玉 141int mm_0(GAME *game, int y, int x) { 142 const int d[] = { 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1 }; //8方向 143 return mm_pattern(game, y, x, d, lengthof(d)); 144} 145//金 146int mm_1(GAME *game, int y, int x) { 147 const int d[] = { 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,0 }; //斜め後ろ以外 148 return mm_pattern(game, y, x, d, lengthof(d)); 149} 150//銀 151int mm_2(GAME *game, int y, int x) { 152 const int d[] = { 1,1, 1,0, 1,-1, -1,-1, -1,1 }; //横後ろ以外 153 return mm_pattern(game, y, x, d, lengthof(d)); 154} 155//桂 156int mm_3(GAME *game, int y, int x) { 157 const int d[] = { 2,1, 2,-1 }; //二つ前の左右 158 return mm_pattern(game, y, x, d, lengthof(d)); 159} 160//香 161int mm_4(GAME *game, int y, int x) { 162 return mm_line(game, y, x, 1, 0); 163} 164const int DIR_STRAIGHT[] = { 0,1, 1,0, 0,-1, -1,0 }; //前後左右 165const int DIR_STRAIGHT_SIZE = lengthof(DIR_STRAIGHT); 166const int DIR_DIAGONAL[] = { 1,1, 1,-1, -1,-1, -1,1 }; //斜め 167const int DIR_DIAGONAL_SIZE = lengthof(DIR_DIAGONAL); 168//角 169int mm_5(GAME *game, int y, int x) { 170 int count = 0; 171 for(int i=0; i<DIR_DIAGONAL_SIZE; i+=2) { 172 count += mm_line(game, y, x, DIR_DIAGONAL[i], DIR_DIAGONAL[i+1]); 173 } 174 return count; 175} 176//飛 177int mm_6(GAME *game, int y, int x) { 178 int count = 0; 179 for(int i=0; i<DIR_STRAIGHT_SIZE; i+=2) { 180 count += mm_line(game, y, x, DIR_STRAIGHT[i], DIR_STRAIGHT[i+1]); 181 } 182 return count; 183} 184//歩 185int mm_7(GAME *game, int y, int x) { 186 int side = game->side[y][x]; 187 y += dirsign(side); 188 if(!on_board(y, x) || game->side[y][x]==side) return 0; 189 game->movable[y][x] = 1; 190 return 1; 191} 192//馬 193int mm_8(GAME *game, int y, int x) { 194 return mm_5(game, y, x) + 195 mm_pattern(game, y, x, DIR_STRAIGHT, DIR_STRAIGHT_SIZE); 196} 197//龍 198int mm_9(GAME *game, int y, int x) { 199 return mm_6(game, y, x) + 200 mm_pattern(game, y, x, DIR_DIAGONAL, DIR_DIAGONAL_SIZE); 201} 202 203const PIECE PIECES[] = { 204 { "王", mm_0, -1, -1 }, 205 { "玉", mm_0, -1, -1 }, 206 { "金", mm_1, -1, 2 }, 207 { "銀", mm_2, 9, 3 }, 208 { "桂", mm_3, 10, 4 }, 209 { "香", mm_4, 11, 5 }, 210 { "角", mm_5, 12, 6 }, 211 { "飛", mm_6, 13, 7 }, 212 { "歩", mm_7, 14, 8 }, 213 { "き", mm_1, -1, 3 }, 214 { "き", mm_1, -1, 4 }, 215 { "き", mm_1, -1, 5 }, 216 { "馬", mm_8, -1, 6 }, 217 { "龍", mm_9, -1, 7 }, 218 { "と", mm_1, -1, 8 }, 219}; 220 221const int INIT_PIECES[] = { 222 //y,x,PIECES_index 223 0,0,5, 0,1,4, 0,2,3, 0,3,2, 0,4,1, 0,5,2, 0,6,3, 0,7,4, 0,8,5, 224 1,1,6, 1,7,7, 225 2,0,8, 2,1,8, 2,2,8, 2,3,8, 2,4,8, 2,5,8, 2,6,8, 2,7,8, 2,8,8, 226 6,0,8, 6,1,8, 6,2,8, 6,3,8, 6,4,8, 6,5,8, 6,6,8, 6,7,8, 6,8,8, 227 7,1,7, 7,7,6, 228 8,0,5, 8,1,4, 8,2,3, 8,3,2, 8,4,0, 8,5,2, 8,6,3, 8,7,4, 8,8,5, 229}; 230 231void clear_select(GAME *game) { 232 memset(game->movable, 0, sizeof(game->movable)); 233 game->sy = -1; 234 game->sx = -1; 235} 236 237void init_game(GAME *game) { 238 memset(game, 0, sizeof(GAME)); 239 for(int i=0; i<lengthof(INIT_PIECES); ) { 240 int y = INIT_PIECES[i++]; 241 int x = INIT_PIECES[i++]; 242 int j = INIT_PIECES[i++]; 243 game->piece[y][x] = &PIECES[j]; 244 game->side[y][x] = y<=2 ? 2 : 1; 245 } 246 clear_select(game); 247 game->cx = 4; 248 game->cy = 8; 249} 250 251void move_cursor(GAME *game, int y, int x) { 252 if(game->cy == y && game->cx == x) return; 253 game->cy = y; game->cx = x; 254 print_game(game); 255} 256 257void select_piece(GAME *game) { 258 int cancel = game->cy==game->sy && game->cx==game->sx; 259 clear_select(game); 260 if(!cancel) { 261 int y = game->cy, x = game->cx; 262 if((*game->piece[y][x]->mm_func)(game,y,x) > 0) { 263 game->sy = y; 264 game->sx = x; 265 } 266 } 267 print_game(game); 268} 269 270void move_piece(GAME *game) { 271 int cy = game->cy, cx = game->cx; 272 int sy = game->sy, sx = game->sx; 273 game->piece[cy][cx] = game->piece[sy][sx]; 274 game->piece[sy][sx] = NULL; 275 game->side[cy][cx] = game->side[sy][sx]; 276 game->side[sy][sx] = 0; 277 clear_select(game); 278 print_game(game); 279} 280 281int main(int argc, char *argv[]) { 282 init(); 283 284 GAME game; 285 init_game(&game); 286 287 print_surface(); 288 print_game(&game); 289 refresh(); 290 291 int turn = 1; 292 for(int key; (key=getch())!='q'; usleep(200)) { 293 int y = game.cy, x = game.cx; 294 switch(key) { 295 case KEY_UP: if(y > 0) move_cursor(&game, y-1, x); break; 296 case KEY_DOWN: if(y < 8) move_cursor(&game, y+1, x); break; 297 case KEY_LEFT: if(x > 0) move_cursor(&game, y, x-1); break; 298 case KEY_RIGHT: if(x < 8) move_cursor(&game, y, x+1); break; 299 case ' ': if(game.side[y][x] == turn) select_piece(&game); 300 else if(game.movable[y][x]) move_piece(&game); 301 break; 302 } 303 } 304 305 term(); 306 307 return 0; 308}

投稿2025/10/04 07:45

編集2025/10/06 08:40
jimbe

総合スコア13415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

todasan

2025/10/05 05:47

jimbe さん ありがとうございます。参考にしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問