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

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

C

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

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

curses

cursesは、 UNIX 系列で使用される端末制御ライブラリです。CUI アプリケーションを作成するために使用されます。表示端末は多くの制御コードをサポートしており、カーソル移動や画面のスクロール、領域消去といった一般的な操作の実行が可能です。

意見交換

23回答

871閲覧

C言語の将棋のゲームでシェルスクリプト、bashなどを使いたい。

todasan

総合スコア94

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

C

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

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

curses

cursesは、 UNIX 系列で使用される端末制御ライブラリです。CUI アプリケーションを作成するために使用されます。表示端末は多くの制御コードをサポートしており、カーソル移動や画面のスクロール、領域消去といった一般的な操作の実行が可能です。

0グッド

1クリップ

投稿2025/10/17 01:24

編集2025/10/17 04:09

0

1

C言語で、将棋のゲームを作成しています。VSCODEとucrt64のgcc、makeの
環境で作成しています。
先手、後手を上、下釦で、選択して、エンター釦を押し、先手か後手かを
画面に表示するまで、以下のソースで再現しました。先手なのに、後手の
駒を動かすと、動かないところまでも再現しました。
これから勉強のためシェルスクリプト、bashなどを取り入れていきたいです。
開発環境、どのような実装で、シェルスクリプト、bashを使うのかを
お聞きしてもいいですか。この既存のソースで、シェルスクリプト、bashの
使いどころもお聞きしたいです。理由として、シェルスクリプト、bashは、
C言語を使う時の常識と思っているため、使いどころが分からず
お聞きしたいです。これから棋譜の保存、棋譜の表示の機能も追加しようと思い、
そこらへんでもシェルスクリプト、bashの使いどころがあるかをお聞きしたいです。

・Makefile
https://www.mycompiler.io/view/Ag90sG2vfY2
・shougi_data.h
https://www.mycompiler.io/view/BHObuhYhjvS
・shougi_main.c
https://www.mycompiler.io/view/A7LTZUU4htK
・shougi_input.c
https://www.mycompiler.io/view/7ZSQIgfPioK
・shougi_boad.c
https://www.mycompiler.io/view/K0moOdsQ3y6
・shougi_highlight.c
https://www.mycompiler.io/view/EzCWLrLfWkT

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

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

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

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

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

回答23

#1

maisumakun

総合スコア146822

投稿2025/10/17 01:32

まず、シェルスクリプトというのは、シェルで実行するコマンドを書き連ねて、まとめて実行するためのものです。

C言語で作ったプログラムでも、「フィルタ」と呼ばれるような、標準入力・標準出力で動作するようなプログラムであれば、シェルスクリプトの1要素として組み込むこむことも珍しくありません。

ただ、今回のようなcursesでインタラクティブにユーザーが操作することを前提としたコンソールプログラムでは、シェルスクリプトと合わせてもうまみはあまりありません

これから棋譜の保存、棋譜の表示の機能も追加しようと思い、
そこらへんでもシェルスクリプト、bashの使いどころがあるかをお聞きしたいです。

棋譜を読み込んでユーザーの操作なしに評価値を出力するような機能があれば別ですが、読み込んだ後にユーザー操作で使うような状況では特にないです。

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

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

#2

maisumakun

総合スコア146822

投稿2025/10/17 01:33

なお、作るプログラムそのものを動かす話とは別問題として、ビルドプロセスが複雑化してきた場合に、ビルドをシェルスクリプトで自動化するということは考えられます。

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

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

#3

raccy

総合スコア21823

投稿2025/10/17 01:48

理由として、シェルスクリプト、bashは、
C言語を使う時の常識と思っている

そのような常識はありません。ですので、必要かどうかわからないのに無理に使う必要はありません。

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

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

#4

melian

総合スコア21502

投稿2025/10/17 02:39

本題とは無関係ですが、気が付いた事があります。

先手、後手を上、下釦で、選択して、エンター釦を押し、先手か後手かを画面に表示するまで、以下のソースで再現しました。先手なのに、後手の駒を動かすと、動かないところまでも再現しました。

掲示されているソースコードをビルドして実行してみましたが、

  • 先手・後手を選択すると、再度先手・後手の選択場面が表示される
  • 2度目の選択画面で先手・後手を選ぶと盤面が表示されるが、キー入力を行うと先手・後手の選択画面へ戻る

という動作になっています。これはdraw_board()関数(shougi_boad.c)にdraw_selection()関数(shougi_main.c)と同じ処理(先手・後手の選択する処理)があるためですが、ソースコードを確認するとdraw_board()のプロトタイプ宣言が一致していません。

shougi_main.c

c

1extern void draw_board(int is_turn);

shougi_boad.c

c

1void draw_board();

もしかして、掲示されているshougi_boad.cが以前のバージョンのままなのではないでしょうか?

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

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

#5

todasan

総合スコア94

投稿2025/10/17 02:55

melian さん
すみません。質問欄のソースを最新のものにしました。

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

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

#6

TakaiY

総合スコア14644

投稿2025/10/17 02:57

理由として、シェルスクリプト、bashは、C言語を使う時の常識と思っている

これをどういうニュアンスで書いているのかわかりませんが、「シェルスクリプト・bashは、UNIX上で作業する時の基礎スキル」なので、作業を効率化するために、sedやawkを始めとするいろいろなコマンドを使えるようにするとか、ファイルやディレクトリの操作のためにの提携業務をスクリプト化するなどは習得しておくといいでしょう。

そうでなく、「C言語のプログラムの中にBashのスクリプトを混ぜて1つのものを作る」ということを指しているのであればそれは一般的ではありませんが、連携させて使うというのはよくやることです。
Bashはディレクトリやファイルを操作するのが得意ですから、将棋プログラムの実行にあたって必要な処理をBashで書くというのはありでしょう。たとえば、現在のプログラムを実行するときに、いつもやっていること(ログファイル更新とか必要ファイルの確認とか)があれば、それをBashスクリプトで自動化し、準備できたらそのスクリプトから本体を呼ぶなどでしょうか。

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

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

#7

todasan

総合スコア94

投稿2025/10/17 03:01

maisumakun さん
例えば棋譜の保存で、シェルとbashを使い、csvファイルなどに保存する時などは、
使えそうでしょうか。シェルとbashは使ってみたい機能なので、言っています。
C言語とシェル、bashを使ったコード例等はありますでしょうか。
あまりネットでも見かけないです。

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

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

#8

todasan

総合スコア94

投稿2025/10/17 03:06

TakaiY さん

たとえば、現在のプログラムを実行するときに、いつもやっていること(ログファイル更新とか必要ファイルの確認とか)があれば、それをBashスクリプトで自動化し、準備できたらそのスクリプトから本体を呼ぶなどでしょうか。
Bashスクリプトから本体を呼ぶというのは、コンパイル後のexeファイルを呼ぶという事ですか。

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

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

#9

melian

総合スコア21502

投稿2025/10/17 03:12

#5
ありがとうございます。おそらくですが、shougi_highlight.c も以前のままの様です。

先手なのに、後手の駒を動かすと、動かないところまでも再現しました。

この部分を別質問として投稿するとよいかと思います。

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

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

#10

jimbe

総合スコア13429

投稿2025/10/17 03:45

現状のプログラムでシェルスクリプトを使う必要は全く無いと思います。
興味があるからやってみたいというのは分かりますが、シェルは OS とユーザの仲を取り持つプログラムであって(bash はその中の一つに過ぎません)、OS と(直接もしくはライブラリを通して間接的に)やり取りしている c プログラムとは直接関係ありません。

どうしても何かやってみたいということなら、c や将棋は一旦置いておいて、他の人はシェルスクリプトで何をしているかから調べられては如何でしょう。

もっとも、今はシェルよりも将棋プログラムを( c だけで)完成させる方に力を注いだ方が良いと思います。
元々は『c を苦手に思うから』と苦手を克服?するために作り始められたと記憶しています。
もう苦手意識は無くなったのでしょうか。

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

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

#11

maisumakun

総合スコア146822

投稿2025/10/17 04:09

編集2025/10/17 04:11

例えば棋譜の保存で、シェルとbashを使い、csvファイルなどに保存する時などは、
使えそうでしょうか。

現状のプログラムのような、cursesを使ったユーザーが画面変化に応じて操作するプログラムでは、シェルスクリプトと合わせても仕方ないです。

今のプログラムをシェルスクリプトから呼び出したところで、「タイミングに合わせたキー操作」を送信するという、シェルスクリプトに全く向かない操作が必要となって、ただ煩雑になるだけです。

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

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

#12

todasan

総合スコア94

投稿2025/10/17 04:11

melian さん
質問欄のshougi_highlight.cを直しました。

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

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

#13

TakaiY

総合スコア14644

投稿2025/10/17 04:56

#8

コンパイル後のexeファイルを呼ぶという事

はい。そういうことです。
exeの中にbashのスクリプトの処理を盛り込むということではありません。

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

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

#14

melian

総合スコア21502

投稿2025/10/17 05:37

これから棋譜の保存、棋譜の表示の機能も追加しようと思い、そこらへんでもシェルスクリプト、bashの使いどころがあるかをお聞きしたいです。

PDCursesではputwin()という関数が提供されています。(他のcursesライブラリにもあります) これは画面への表示内容をバイナリ形式でファイルに保存します。そして、getwin()関数を使用して画面の表示状態をダンプ時に戻すことができます。
以下はsを入力することでスクリーンダンプを行い、rでリストアする処理の例です。ですが、ファイル名を決め打ちにしていますので保存するファイル名を入力させる処理と、内部で使用しているboard配列とdataretu配列へ表示内容を反映させる処理が必要になるでしょう。

c

1void screen_dump() { 2 FILE *file = fopen("screen.dump", "w"); 3 if (file != NULL) { 4 putwin(stdscr, file); 5 fclose(file); 6 } 7} 8 9void restore_data() { 10 FILE *fp; 11 if ((fp = fopen("screen.dump", "r")) == NULL) { 12 endwin(); 13 perror("Can't restore dump file"); 14 exit(EXIT_FAILURE); 15 } 16 17 WINDOW *win = getwin(fp); 18 fclose(fp); 19 touchwin(win); 20 wrefresh(win); 21} 22 23int main(void) { 24 : 25 while (1) { 26 : 27 switch (ch) { 28 : 29 case 's': screen_dump(); break; 30 case 'r': restore_data(); break; 31

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

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

#15

fana

総合スコア12299

投稿2025/10/17 09:44

PDCursesではputwin()という関数が提供されています。(他のcursesライブラリにもあります) これは画面への表示内容をバイナリ形式でファイルに保存します。そして、getwin()関数を使用して画面の表示状態をダンプ時に戻すことができます。

(話がわかってないんですが)「棋譜」っていうと,両者がどういう手を指していったかという履歴みたいなやつのことですよね?
画面表示内容の保存/復元 という話とはちょっと違ったりしないのかな? と.

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

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

#16

todasan

総合スコア94

投稿2025/10/17 22:06

melian さん
参考にします。

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

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

#17

todasan

総合スコア94

投稿2025/10/17 22:09

fana さん

(話がわかってないんですが)「棋譜」っていうと,両者がどういう手を指していったかという履歴みたいなやつのことですよね?
画面表示内容の保存/復元 という話とはちょっと違ったりしないのかな? と.
対局中の棋譜は対局中に、横に画面で表示しようと思います。
表示内容の保存は将棋ゲームに、対局を保存して、再生する機能があるので、
それを作ってみようかと思っているので、話は合っています。

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

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

#18

jimbe

総合スコア13429

投稿2025/10/18 02:07

編集2025/10/18 02:22

棋譜いうと↓ですかね。

日本将棋連盟>よくある質問>棋譜の表記方法
https://www.shogi.or.jp/faq/kihuhyouki.html

省略とか、思ったより複雑でした。
これをログとしてセーブや、ロードしてゆっくり再生出来るようになれば、プレイの記録にも新聞・雑誌の対局再現にも良さそうですが、シェルの出番は無さそうです…。

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

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

#19

fana

総合スコア12299

投稿2025/10/20 04:50

編集2025/10/20 05:08

対局中の棋譜は対局中に、横に画面で表示しようと思います。

一度の対局が何手かかるかは一般的には不明なのでは…?
すなわち,棋譜の全てを画面内に一度に表示しきれるとは想定できないと思うのです.

画面表示内容の保存と復元なる機能を用いて本当にやれる話なのでしょうか?
(そりゃまぁ,「各時刻において表示されている棋譜の一部」みたいなのを都度保存していけばそれらから「棋譜全体」を構成できるぞ…とかなんとか,「やる方法」はあるのかもしれませんが……なんというか,こう,もっと「普通に」やらない理由がわからないというか?)


なんだろう? 想像している物が違うのかな?
まず「棋譜というデータ」があって→そのデータに基づいて何かしらの「今現在の表示」というのが成される…のだと思うんだけど,
結果たる「今現在の表示」というのが「棋譜というデータ」 の全て を含んでいるとは限らないよね.
(すなわち,ある時点における表示内容だけからその時点におけるデータというのを完全復元できるとは限らないのでは? っていう)

仮に,「表示内容は常にデータを完全に表現しきっている」という物を作っているのだとしても,
表示からデータを復元する処理というのは,表示方法をちょっと変える度にそれに合わせた修正が必要になるだろうし,とても面倒なんじゃないかなと思う.

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

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

#20

todasan

総合スコア94

投稿2025/10/21 01:40

fana さん
一度には表示できないですが、スクロールなどで、棋譜が全部、見れれば、
いいと思っています。
cursesでできるかは、不明ですが。とりあえずC言語の学習が目的ですが。
その棋譜から先手、後手の有利かどうかをグラフで表示というのもありますが、
それは難易度が高い気がします。

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

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

#21

fana

総合スコア12299

投稿2025/10/21 04:10

編集2025/10/21 04:29

「何か特別なライブラリ(?)を使えばできるかも」という話だと,それをやってみることの意味合いというのは「その特定のライブラリの使い方 の学び」みたいなのになるように思う.
(そのこと自体が 良い とか 悪い とかいうことではないけども)

C言語の学習が目的

という話であれば,自分ならまずは「 C言語で データをファイルに保存したりそのファイルを読み込んでデータを復元したりするには?」という話を調べたら普通に出てくるようなこと(: C言語でやるとしたらまぁこうだよねっていうような一般的な話)からチャレンジするかなぁ,と.


まぁそういう話とは全く別のところで
「便利なことがあるか否か とか 一般的なやりかたか否か とか 目的に合ってるか 等々いう話は度外視して,とにかく一度 やってみる んだよ!」っていう勢いというかそういうのはアリだと思います.

本題の「シェルがどうの~」いう話について言えば,
(私はそういうことをあまりやったことは無いのですが)C言語だと system() なる関数を使えばシェルのコマンドやらを実行できるのではないかと思います.
例えば何か「C言語で実装するよりもシェルスクリプトで実装したほうが楽」みたいな処理が存在している場合,その処理を実装したシェルスクリプトをC言語で作ったプログラム側から利用する的な話になるんでしょうかね.

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

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

#22

melian

総合スコア21502

投稿2025/10/21 09:16

編集2025/10/21 09:33

#19

表示からデータを復元する処理というのは,表示方法をちょっと変える度にそれに合わせた修正が必要になるだろうし,とても面倒なんじゃないかなと思う.

mvwinnwstr() で画面上の表示内容(ワイド文字列)を取得して、wcstombs()でマルチバイト文字列に変換します。現状、駒データ(名前と盤上の位置)をboard配列(char *)とdataretu配列(person構造体)で二重管理してしまっているので、それらのつじつまを合わせることが少し面倒です。

c

1void restore_data() { 2 int result = scr_restore("screen.dump"); 3 if (result == ERR) { 4 perror("Can't restore dump file"); 5 return; 6 } 7 touchwin(curscr); 8 wrefresh(curscr); 9 10 extern person dataretu[]; 11 int disp_size = CELL_W - 2; 12 int nbytes, index; 13 wchar_t wcs[disp_size + 1]; 14 char mbcs[MB_CUR_MAX * disp_size + 1]; 15 for (int y = 0; y < BOARD_SIZE; ++y) { 16 for (int x = 0; x < BOARD_SIZE; ++x) { 17 mvwinnwstr(curscr, ORIGIN_Y + y * CELL_H, ORIGIN_X + x * CELL_W, wcs, disp_size); 18 nbytes = wcstombs(mbcs, wcs, sizeof(mbcs)); 19 mbcs[nbytes] = '\0'; 20 index = y * BOARD_SIZE + x; 21 if (wcsncmp(wcs, L" ", 1)) 22 strcpy(dataretu[index].koma, mbcs); 23 else 24 dataretu[index].koma[0] = '\0'; 25 } 26 } 27 set_board_from_dataretu(); 28}

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

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

#23

thkana

総合スコア7770

投稿2025/10/21 14:02

スクロールなどで、棋譜が全部、見れれば、
いい

Windows前夜の、MS-DOS時代にはそれこそエスケープシーケンスで画面の一部でスクロール、とかよくやっていた気がします(VRAM直書きのほうが普通だったかも)。まぁ、学習段階で「歴史を辿る」のはよくある話。

当時のコンピュータではしばしばカタツムリが這うような速度になっていましたが、今どきならよほど下手くそなプログラムにしない限りそんなこともないのでしょうね。

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

この意見交換はまだ受付中です。

会員登録して回答してみよう

アカウントをお持ちの方は

関連した質問