Bashでターミナル上で動くタイピングゲームを作ってみた(シェルスクリプト)




まずは全体のコードです。

#!/bin/bash
content=("cherry pear banana grape peach apple")
ESC=$(printf '\033')

typingGame() {
	element=$1
	typed=$element
	n=0
	clear
	echo "${ESC}[33m$element${ESC}[m"
	while true; do
		if [ ${#element} -eq 0 ]; then
			break
		fi
		read -s -n 1 a
		if [ $a == ${element:0:1} ]; then
			clear
			n=$((n + 1))
			typed_element=${typed:0:n}
			element=${element:1}
			echo -n "${ESC}[34m$typed_element${ESC}[m"
			echo -n -e "${ESC}[33m$element\n${ESC}[m"
		fi
	done
}

for value in ${content[@]}; do
	typingGame $value
done




ゲームの仕様

  • タイピングした文字の色が変わる
  • ターミナルの背景が白、黒のどちらでも見やすい文字色にした
  • clearコマンドを使い、タイピング対象の文字列の位置を固定した




解説

入力された文字列の色を変更するための処理を行います。
以下を実行すると黄色の”hoge”が表示されます。

#!/bin/bash
ESC=$(printf '\033')
echo "${ESC}[33mhoge${ESC}[m"




ユーザーが押したキーの値取得するには、エンターキーを押す必要があります。これでは、1文字入力するたびにエンターキーを押す必要があり、タイピングゲームとは言えなくなってしまいます。

そこで、以下のように標準入力を受け取ります。
-n 1で入力できる文字数を指定します。1文字に指定するとエンターキーを押さずに反映されます。
-sは入力されたキーの値を表示しないというオプションです。

read -s -n 1 a




タイピング対象の文字列の先頭が、入力されたキーと一致した時にタイピングの処理を行います。
変数nを用意し、文字列の入力された部分と残っている部分に分けます。それぞれを別の色に分けて出力します。
改行を入れずに連結して出力する必要があるので、echoに-nオプションをつけます。

if [ $a == ${element:0:1} ]; then
	n=$((n + 1))
	typed_element=${typed:0:n}
	element=${element:1}
	echo -n "${ESC}[34m$typed_element${ESC}[m"
	echo -n -e "${ESC}[33m$element\n${ESC}[m"
fi




タイピング対象の文字列を同じ場所に表示し続けるために、clearコマンドを使います。
whileループの前とwhileループの中に記述します。

typingGame() {
	element=$1
	typed=$element
	n=0
	clear
	echo "${ESC}[33m$element${ESC}[m"
	while true; do
		if [ ${#element} -eq 0 ]; then
			break
		fi
		read -s -n 1 a
		if [ $a == ${element:0:1} ]; then
			clear
			n=$((n + 1))
			typed_element=${typed:0:n}
			element=${element:1}
			echo -n "${ESC}[34m$typed_element${ESC}[m"
			echo -n -e "${ESC}[33m$element\n${ESC}[m"
		fi
	done
}


これで以上となります。