ここには、工学演習の参考になる、 あるいは講義で使用するサンプルバッチファイルを置きます。
情報電子工学演習の「バッチプログラミングによるタイプ練習ソフトの作成」で、 実際に受けた質問や、落ちいりやすい間違いなどを QandA の形に適宜まとめあげたものです。
この工学演習 II の期間に、随時質問を更新/追加していく予定です。
(07/20 2013: shige)簡単にやるには、代わりに「set /p」を使うのがいいでしょう。
set /p dummy=[任意のメッセージ文字列]
dummy は使用しない変数にすればいいわけです。
(12/19 2014: shige)
いくつか方法があります。
ただし、この方法は、実行してもコマンドプロンプト画面が 一瞬で消える可能性があります。
ディレクトリの移動は「cd」で行います。例えば、 「Z:\ensyu」というフォルダに「test1.bat」を保存した場合、 「cd ensyu」として「Z:\ensyu」に移動してから「test1.bat」と実行します。 「cd \」とすれば元の場所 (トップディレクトリ) に戻ります。
ファイルをコピーするにはエクスプローラでやるのが便利でしょう。 最初にいる場所は「Z:\」(Z ドライブのトップディレクトリ) なので、 そこにコピーすればそこで実行できるようになります。 ファイルを保存するときに、「Z:\」に保存するようにするのが無難です。
ほかにも方法はありますが、多分このあたりがやりやすい方法だと思います。
(10/09 2013: shige)otbedit の「ファイルを開く」(Ctrl-O) のメニュー画面で、 そのファイルの置かれている場所を順にたどってみてください。
(10/09 2013: shige)全体の文字の色、および背景色を変えるには、資料にも説明がありますが、 color コマンドを使用します。 また、デフォルトの色を変えるには、コマンドプロンプトの [プロパティ] からでも変更できます。これはより細かい色の指定が可能です。
全体の文字ではなく、個別に文字の色を変えるのは、 ANSI.SYS とエスケープシーケンスを使えばできなくはないのですが、 今回はそれは使用しないでください。 制約のある状態で、いかにアイデアを出すかが勝負です。
(10/25 2013: shige)全体の文字の大きさや書体を変えるには、 コマンドプロンプトの [プロパティ] から変更できます。
個別に文字を大きくするのはコマンドプロンプトではできませんが、 いわゆるアスキーアートのようなもので大きな文字らしきものを 書くことはできます:
# ##### ### # # # # # # # # ##### # ####### # # # # # # ##### ###このような物を書く場合、otbedit では「Insert」キーを押して 「上書きモード」にするといいでしょう。 「上書きモード」にする前に、1 行 60 文字位の空白だけの行を何行か作っておいて それを「画用紙」がわりにします。
「上書きモード」では、スペースや文字を打っても、 その行の文字が増えることはなく、下にあった文字が上書きされていまいます。 上下左右に適当に文字を入力する場合には「上書きモード」が有効です。
(10/25 2013: shige)対話的に解除するようなストップモーションは、 サンプルでも使用している pause か set /p を使用します。
そうでなくて、一定時間で自動的に解除するストップモーションを作るには、 以下の方法があるようです。
timeout は、Vista 以降導入されたコマンドのようですので XP などでは使えませんが、整数単位の秒のストップモーションでいいなら、 これが一番楽でしょう。
ping は、元々ネットワークの状態を調べるコマンドで、 1 秒おきに -n の後ろに指定する数字の回数分、 指定したホストへの問い合わせ (ping) を行います。 localhost は自分が使っているコンピュータ自身なので、 すぐに反応が帰ってきますので、 これも整数秒の待ち時間を作るのに利用できますが、 「(待ちたい秒数) + 1」の秒数を指定する必要があります (最初の問い合わせはすぐに戻るため)。
timeout や ping は、整数秒の待ち時間を作るにはいいのですが、 0.5 秒などを作ることはできません。 0.5 秒の待ち時間を作るには、ループの空回しがいいでしょう。 ただし、これはコンピュータの計算速度によって 待ち時間が変わってしまいますので、 調整が必要になります。
rem ### 空回しのサブルーチン ###
rem ### 使用法: call :wait [n] ###
:wait
set waitx=0
set delta=1000
rem この delta の値を調整する
set /a lastx=delta * %1
:startwait
if %waitx% gtr %lastx% goto exit/b
set /a waitx+=1
goto startwait
:endwait
これをサブルーチンとして、
これを「call :wait 3」のように呼び出します。
このサブルーチンでは、「3」のように指定した数に delta (=1000)
をかけた数 (=lastx) の回数分 waitx に 1 を足し続ける、
ということを行います。
このサブルーチンを後ろに置いて、
@echo off
echo %time%
call :wait 1
echo %time%
exit /b
のようにして呼び出してみると
何秒くらいかかっているのかわかります。
それで適宜 lastx の値 (1000) を調整してください。
空ループを利用したサンプルは、 「サンプルバッチファイル」 を参照してください。
(10/25 2013: shige, 10/29 2013, 11/14 2013 修正: shige)できれば色々自分で工夫して欲しいと思いますが、 「Q 4.1: ストップモーションの時間を作るには」 で書いたストップモーションを使えば、 多少のアニメーション効果を作れます。 ただ、表示は、
ことしかできませんので、その制約の元で考えることになります。
簡単なサンプルは、 「サンプルバッチファイル」 を参照してください。
(10/25 2013: shige, 11/14 2013 修正: shige)資料 11 ページには、0, 1, 2 がランダムに現れる例が書いてありますが、 このように、環境変数 %random% と剰余演算 % (バッチファイル内では %%) を組み合わせるのが常套策です。 乱数値を 3 で割った余りは、ほぼ 1/3 ずつの確率で 0, 1, 2 となりますので、それに 1 を足せばいいでしょう。 例えばバッチファイルでは、以下のように書きます。
@echo off
set /a x=%random% %% 3 + 1
echo %x%
(10/29 2013: shige)
数字の 0, 1, 2 をランダムに生成するのは、 「Q 4.3 乱数を利用して変数 x に 1/3 ずつの確率で 1, 2, 3 の値を代入するには」 のようにすればできるのですが、 バッチファイルには「配列変数」がありませんので、 それらを a, b, c に割り当てるのは簡単ではありませんが、 例えば以下のような方法があります。
@echo off
set /a r=%random% %% 3
if %r%==0 ( set x=a) else (
if %r%==1 ( set x=b) else ( set x=c)
)
echo %x%
ただし、これは場合分けが増えてくると少し面倒です。
これも面倒ですが、 「setlocal enabledelayedexpansion」をバッチファイルに書くと、 「遅延展開」という機能が有効になり、 変数値の置き換えを少し遅くできる (それが参照されたときに始めて展開する) 変数展開が利用できます。 遅延展開させる変数は、% % の代わりに ! ! で囲みます。例:
@echo off
setlocal enabledelayedexpansion
set str0=a
set str1=b
set str2=c
set /a r=%random% %% 3
set x=!str%r%!
echo %x%
この、下から 2 行目のところで遅延展開を利用していますが、
ここでは「先に」% % で囲んだ変数が展開され、
その「後で」! ! で囲んだ変数が展開されるので、
例えば r が 1 の場合には、
「set x=!str%r%!」→「set x=!str1!」→「set x=b」
のように変数展開が行われ、結局 x には b が代入されることになります。
バッチファイルでは、C で利用できるような配列変数は使えませんが、 この方法は、str0, str1, str2 という「疑似配列」 を使ったようなものになっています。
この方法も、場合分けが増えてくると str0, str1, str2 のようなものを たくさん定義しないといけないので面倒ですが、 すべて 1 文字 (あるいは同じ長さの文字列) を割り当てればいい場合は、 遅延展開と環境変数の文字列処理を組み合わせる方法があります。
@echo off
setlocal enabledelayedexpansion
set str=abc
set /a r=%random% %% 3
set x=!str:~%r%,1!
echo %x%
「:」を利用した環境変数の文字列処理
(資料 11 ページ) でも遅延展開は利用でき、
この「set x=!str:~%r%,1!
」により、
変数 str の r 番目の文字 1 文字が x に代入されるようになります。
これなら、場合分けが増えても、
それに応じて str に 1 文字を追加していくだけでいいわけです。
ただし、乱数の値に応じて割り当てる文字列の長さが異なる場合は、
この方法は使えず、疑似配列を利用しないといけません。
これらを利用すると、例えばタイプ練習ソフトの初歩の段階でよく行われる 「r, u のタイプ練習のために、r と u がランダムに 10 個並んだ文字列」 なんてのを作ることができるようになります。
このサンプルについては、 「サンプルバッチファイル」 を参照してください。
(10/29 2013: shige)追加ですが、もう一つ思いつきました。 引数付きのサブルーチン呼び出しを利用する、 という方法があります。
call でサブルーチンを呼びだす場合、 「call :[ラベル] [引数1] [引数2] ...」 のように引数を付けて呼びだすことができ、 その引数はサブルーチン側では %1, %2, ... のようにして参照できます。 しかも、これらは shift コマンドで順繰りにシフト、 すなわち、%2 は %1 に、%3 は %2 に、... という作業が行えますので、 以下のようなサブルーチンを使えばいいわけです。
rem 引数として指定した文字列から (r + 1) 番目の引数を s に保存して帰る
:selectstr
set subj=1
:substart1
if %subj% gtr %r% goto subend1
shift
set /a subj+=1
goto substart1
:subend4
set s=%1
exit /b
これは、サブルーチン内部で r 回 shift を行うことで、
目的とする (r + 1) 番目の引数を %1 にして、
それを s に保存して帰るだけです。
@echo off
set /a r=%random% %% 3
call :selectstr a b c
echo %s%
exit /b
のようにこのサブルーチンを呼び出す部分を書いて、
この下に上のサブルーチンを書いていけば、
目的とするバッチファイルができます。
この方法なら、選び出す文字列の長さがバラバラでも利用できますから、
遅延展開を使うよりも楽かもしれません。
(11/14 2013 修正: shige)
あまり固定観念にとらわれずに自由に発想してもらいたいので、 できればあまりこちらがイメージ付けはしたくないところですが、 いくつか私が考えられるヒントのようなものを示しましょう。
例えば、サンプルバッチファイル で示したように、 一定時間間隔のストップモーションや簡単なアニメーション、 背景色の変更などは使うことができます。 それを工夫することで、プログラムの見た目を変えることができ、 だいぶ印象が変わると思います。
また、プログラムが提示する文体を変更することでもだいぶ雰囲気が変わります。 ゲームなどでは独自の世界を持つものがありますが、自分なりのシナリオを構築し、 単純なタイプ練習に面白そうな世界観を持たせることも可能だろうと思います。 単純に結果を表示するのではなく、 ゲームのようにある面をクリアして次の面へ進む、 という表現もありうるでしょう。
この課題の主な目標はタイプ練習ですから、 難易度を設定した課題を色々提示するのが一つの工夫です。 その課題の難易度の設定の仕方にも工夫が考えられます。
市販のタイプ練習教則本などは、キーボードに対するホームポジション (調べてみてください) を基準に、各キーに担当の指を決めて その指とキーの対応を習うことを目標にしていて、 まずは F と J のキーから始めることが多いようです。 その場合も、シフトキーを押さない小文字の f と j、 f と j のみからなるランダムな文字列などが一番簡単な課題となるでしょう。 そこから指を段々増やしていく、 他の段のキーに増やしていく、と進んでいるものが多いようです。 シフトキーを必要とする大文字のアルファベットも混ぜると 難易度は少し上がります。 このような難易度を徐々に上げるような課題を検討することも、 正しい独自の方向だと思います。
また、ランダムな課題文字列よりも、 例えば英単語であるとか、日本語をローマ字にしたものであるとか、 多少頭に入りやすい文字列の方が 目で確認しなくていい分打ちやすいものです。 それも難易度の設定としてはありうると思います。
難易度という点では、文字列の長さ、あるいは打鍵の速さ、 なども対象になりうると思います。 それらの変更による難易度の設定もありうるでしょう。
昨年 (2013) は、課題をクイズのように出すようにした学生がいました。 また、市販のタイプ練習ソフトではシューティングゲームのように、 一文字ずつ、あるいは短かい文字列を打ってクリアするものなどがありますが、 そのような出し方もあると思います。
バッチファイルではグラフィカルな画面は作れませんが、 工夫次第でそれなりに色々な出し方はあるのではないかと思います。
タイプ練習は、同じことの繰り返しが多く、 本来は地味で退屈な訓練なのですが、 そこにゲーム性を持たせることでやる気を出させることが可能になります。 その点で、このソフトに関してはゲーム性は有益と言えます。 色々オリジナルなプログラムを検討してみてください。
(12/18 2014 修正: shige)