【競プロ】どのディレクトリからでもすぐに競プロできるようなシェルスクリプトを書いた
いつでもどこでもすぐに競プロの問題解き始められるようなシェルスクリプトを書きました。イメージとしては、サイト名、コンテスト名、問題名を入力すると対応するディレクトリに移動して、テンプレファイルからC++ファイルを作成、問題のサンプルテストケースを取得してinファイルに書き込む、といった感じです。
コードはこちら
https://github.com/hpano/CompetitiveProgramming/blob/master/compp.sh
実際の動作はこんな感じ。全然関係ないディレクトリから、AtcoderのABC173のディレクトリに移り、A問題とB問題のサンプルテストケースを取得しています。
この問題のコンテストページはこちら
さてコードを見ていきましょう。まずは入力部分です。
ここでは、-dオプションの後に続けられたものをディレクトリ名として配列directorys、-fオプションの後に続けられたものを作成したいファイル名として配列filesに突っ込んでいます。
while test "$1" != ""; do case $1 in -*) if [[ "$1" =~ 'h' ]] || [[ "$1" =~ '-help' ]]; then hflag=true elif [[ "$1" =~ 'd' ]] || [[ "$1" =~ '-directory' ]]; then while [[ $2 != -* ]] && [[ $2 != "" ]]; do directorys+=($2) shift done elif [[ "$1" =~ 'f' ]] || [[ "$1" =~ '-file' ]]; then while [[ $2 != -* ]] && [[ $2 != "" ]]; do if [[ $2 =~ "." ]] && [[ $2 != *.cpp ]]; then echo "[compp] Invalid file $2 !" echo " You can input *.cpp or *" exit 1 fi files+=(${2%.cpp}) shift done else echo "[compp] Invalid option $1 !" usage exit 1 fi shift ;; *) echo "[compp] Invalid input $1 !" usage exit 1 ;; esac done directorys=(${directorys[@]//// })
続いて競プロ用のルートディレクトリのパスを調べます。どこからでもbashファイル実行できるようにこのディレクトリのパスを通してあるので、whichコマンドでパスを取得します。一応パスを通していなくても使えるよう、その場合はパスの入力を求めます。ここで"n"を入力すると、今いるディレクトリを競プロ用のルートディレクトリとみなします。
declare rootpath=$(which compp.sh) if [[ ${rootpath} == "" ]]; then read -p "[compp] Input competitive programing directory's root path or 'n' to give up cd: " rootpath fi if [[ ${rootpath} == "n" ]]; then rootpath=$(pwd) elif [[ ${rootpath: -3} == ".sh" ]]; then rootpath=${rootpath%\/*} fi
そしてそのディレクトリに移動し、目的のディレクトリまでさらに移動します。競プロ用のルートディレクトリから順に、directorysに入っているディレクトリを辿っていき(なければ作成するか選択でき)、たどり着いた場所にファイルを作成するといった感じです。
declare yn cd ${rootpath} for dir in ${directorys[@]}; do if [[ -d ${dir} ]]; then cd ${dir} else read -p "[compp] Directory '${dir}' not exists. make? [y/n]: " yn if [[ ${yn} == "y" ]]; then mkdir ${dir} && cd ${dir} fi fi done echo "[compp] Now at $(pwd)"
最後に前回の記事で作成したadd.shを使い、配列filesに入っているファイルを作成します。こちらもパスが通っていなければ、add.shのパスの入力を求めます。
declare addpath=$(which add.sh) if [[ ${addpath} == "" ]]; then read -p "[compp] Input add.sh path or 'n' to give up add file: " addpath fi if [[ ${addpath} == "n" ]]; then exit 1 elif [[ ${addpath: -3} != ".sh" ]]; then if [[ ${addpath: -1} != "/" ]]; then addpath+="/" fi addpath+="add.sh" fi ${addpath} ${files[@]}
このシェルスクリプトの中でcdをしてディレクトリの移動をしているのですが、シェルスクリプトは基本的には現在のシェルとは別のシェルで実行されるので、普通に実行しただけだと現在のシェルを移動させることはできません。実行する際に.コマンドかsourceコマンドを使用する必要があります。
こちらのサイトが参考になりました。
毎回.を打つのも忘れそうだしめんどくさいので、~/.bashrcに.コマンドありでこのシェルスクリプトを実行する関数を用意しました。
# competitive programing by hpano compp(){ . compp.sh $@ }
これで実行する際にはcompp -d [ディレクトリ] -f [ファイル]
と入力することで、どこからでも実行できるようになりました。
また、ここまでで色々パスを通したり、.bashrcに書き込んだり、シェルスクリプトのパーミッションを変更したりと色々設定があって忘れそうなので、それら設定を一括で行えるsetting.shを作成しました。
https://github.com/hpano/CompetitiveProgramming/blob/master/setting.sh
#/bin/bash function write2bash_profile() { local bashpro=$(cat ~/.bash_profile) if [[ !(${bashpro} =~ "# competitive programing by hpano") ]]; then local yn read -p "[setting] Write PATHs to ~/.bash_profile now? [y/n]: " yn while [[ ${yn} != "y" ]] && [[ ${yn} != "n" ]]; do read -p "Answer only y or n [y/n]: " yn done if [[ ${yn} == "y" ]]; then echo "# competitive programing by hpano" >> ~/.bash_profile echo "export PATH=\$PATH:${dirpath}" >> ~/.bash_profile source ~/.bash_profile echo "[setting] Wrote PATHs to ~/.bash_profile" fi fi } function write2bashrc() { local bashrc=$(cat ~/.bashrc) if [[ !(${bashrc} =~ "# competitive programing by hpano") ]]; then local yn read -p "[setting] Write functions to ~/.bashrc now? [y/n]: " yn while [[ ${yn} != "y" ]] && [[ ${yn} != "n" ]]; do read -p "Answer only y or n [y/n]: " yn done if [[ ${yn} == "y" ]]; then echo "# competitive programing by hpano" >> ~/.bashrc echo "compp(){" >> ~/.bashrc echo " . compp.sh $@" >> ~/.bashrc echo "}" >> ~/.bashrc source ~/.bashrc echo "[setting] Wrote functions to ~/.bashrc" fi fi } declare dirpath=$(dirname $0) write2bash_profile write2bashrc chmod +x ${dirpath}/setting.sh chmod +x ${dirpath}/add.sh chmod +x ${dirpath}/compile.sh chmod +x ${dirpath}/compp.sh chmod +x ${dirpath}/remove.sh chmod +x ${dirpath}/run.sh echo "[setting] Finish setting"
これでますます競プロが捗るはずです。頑張って精進します。
【競プロ】サンプルテストケースを取得してくるシェルスクリプトを書いた
前の記事でinファイルにサンプルテストケースの入力例と出力例を自動で書き込めるようにしたいと書きましたが、できるようになりました。 現時点ではAtcoder、AOJ(Arenaを除く)、yukicoderに対応しています。今回のも前回と同様githubに上げてあります。
https://github.com/hpano/CompetitiveProgramming/blob/master/add.sh
動作はこんな感じ。例としてAtcoderのABC173のA問題とB問題のサンプルテストケースを取得してきています。
コンテストページはこちら
さて順番にコードを見ていきましょう。
まず、-rオプションがある場合はすでにあるinファイルを削除するので、フラグを立てます。そして作りたいファイル名を順に配列に突っ込んでいきます。
declare -a argv=() declare rflag=false while test "$1" != ""; do case $1 in -*) if [[ "$1" =~ 'r' ]] || [[ "$1" =~ '-remove' ]]; then rflag=true fi shift ;; *) argv=("${argv[@]}" "${1%.cpp}") shift ;; esac done
そして各ファイル名のC++ファイルを、テンプレートC++ファイルをコピーして作成します。またinファイル用のデータを取得するために、パスのディレクトリ名から競プロサイトを判断して後の処理につなげます。
この先はどのサイトでも大筋は同じなので、例としてAtcoderの場合を見ていきましょう。
for name in ${argv[@]}; do if [ -f ${name}.cpp ]; then echo "[add] ${name}.cpp already exists" continue fi cp $(dirname $0)/template.cpp ${name}.cpp && \ echo "[add] Added ${name}.cpp" done declare path=( $(pwd | sed -e "s/.*competitive_programming\///g" | tr "/" " ") ) case ${path[0]} in "atcoder") get_atcoder ;; "AOJ") get_aoj ;; "yukicoder") get_yukicoder ;; *) echo "[add] ${path[0]} is unsupported" exit 1 ;; esac
まず実行ディレクトリまでのパスからコンテスト名を判断していき、URLに足していきます。例えばABC173の場合は次のような感じです。
"https://atcoder.jp/contests/" + "abc" + "173" + "/tasks/" + "abc" + "173_" + "問題ID[a-f]"
Atcoderの場合はABC、ARC、AGCは概ねこの規則通りなのでいいのですが、企業コンなどそれ以外の場合はちょっと異なるので、上記と異なる処理が必要です。
まずは上記と同じように処理していき、curlを使って一度HTTPリクエストを投げます。これでデータが取得できればそれでOKなのですが、できなかった場合、URLの最後に付いてるbeginnerを除去してもう一度curlします。URL構築の方法上、コンテスト名と同じものが"/tasks/"の後に追加されるのですが、コンテスト名にbeginnerが付いている場合でもURLの"/tasks/"の後には付いていないので(例えば下のコンテストなど)。
それでも404が返ってくる場合、readコマンドでURLの最後の部分を直接入力させます。
function get_atcoder() { local url_pre="https://atcoder.jp/contests/" # URLの前処理 企業コンなどotherの場合は特別 if [ ${path[1]} = "other" ]; then url_pre+=$(echo ${path[2]} | tr "[A-Z]" "[a-z]") url_pre+="/tasks/" url_pre+=$(echo ${path[2]}_ | tr "[A-Z-]" "[a-z_]") local tmp_status=$(curl -Ls ${url_pre}a -o /dev/null -w '%{http_code}\n') if [ ${tmp_status} -eq 404 ]; then if [[ ${url_pre} =~ "beginner" ]]; then url_pre=${url_pre%%_beginner*} url_pre+="_" fi tmp_status=$(curl -Ls ${url_pre}a -o /dev/null -w '%{http_code}\n') fi if [ ${tmp_status} -eq 404 ]; then local url_in url_pre="${url_pre%\/*}/" read -p "URL? > ${url_pre}" url_in if [ "${url_in: -1}" != "_" ]; then if [[ "${url_in: -2}" =~ _[a-z] ]]; then url_in=${url_in%_*} fi url_in+="_" fi url_pre+=${url_in} fi else url_pre+=$(echo ${path[1]} | tr "[A-Z]" "[a-z]") url_pre+=$(echo "${path[2]}/tasks/") url_pre+=$(echo ${path[1]} | tr "[A-Z]" "[a-z]") url_pre+=$(echo "${path[2]}_") fi
ここから入力された各ファイル名について処理していきます。
まず、すでにinファイルが存在する場合、-rオプションが入力されていればそのinファイルを削除し、入力されていなければcontinueして次のファイルに移ります。
# 各問題に対してデータ取得とinファイル作成 for name in ${argv[@]}; do if [ -f ${name}.in ]; then if "${rflag}"; then rm ${name}.in else echo "[add] ${name}.in already exists" continue fi fi
続いてURLの最終決定です。昔のABCとかだと問題IDが[a-f]ではなく[1-6]になっていたりするので、それに対応するためにurl2として用意します。urlを試して404の場合url2を試すといった感じですね。それでもステータスが200でなかった場合、最終的にここでURLを全て入力してもらいます。もしくは、"n"を入力するとその問題を飛ばすことができます。
local url=${url_pre} url+=${name} local url2=${url_pre} url2+=$(echo ${name} | tr "[a-f]" "[1-6]") local url2flag=false local continue_flag=false local status=$(curl -Ls ${url} -o /dev/null -w '%{http_code}\n') if [ ${status} -eq 404 ]; then url2flag=true sleep 0.5 status=$(curl -Ls ${url2} -o /dev/null -w '%{http_code}\n') fi while [ ${status} -ne 200 ]; do echo "[add] Cannot recieve contents from ${url} (code: ${status})" read -p "Input correct URL or 'n' to give up getting: " url status=$(curl -Ls ${url} -o /dev/null -w '%{http_code}\n') url2flag=false if [[ ${url} == "n" ]]; then continue_flag=true break fi done if "${continue_flag}"; then continue fi if "${url2flag}"; then url=${url2} fi
そして得られたHTMLから必要な範囲だけを抽出します。どの部分が必要かは各競プロサイトのソースを見てみましょう。
local data=$(curl -Lso- ${url}) data=${data#*<span class=\"lang-ja\">} data=${data%%</span>*} local inflag=false local outflag=false touch ${name}.in echo "[add] Get from ${url}"
最後に残ったHTMLを1行ずつ見ていき、入力例or出力例の部分かを判断して、各テストケース毎に次のようにinファイルに書き込んで終わりです。
<in> 入力例1 </in> <out> 出力例1 </out>
while read line; do line=`echo ${line} | tr -d "\r"` if "${inflag}"; then if [[ ${line} =~ "</pre>" ]]; then inflag=false echo "</in>" >> ${name}.in else echo ${line} >> ${name}.in fi elif "${outflag}"; then if [[ ${line} =~ "</pre>" ]]; then outflag=false echo "</out>" >> ${name}.in else echo ${line} >> ${name}.in fi elif [[ ${line} =~ "<h3>入力例" ]]; then echo "<in>" >> ${name}.in inflag=true echo ${line#*<pre>} >> ${name}.in elif [[ ${line} =~ "<h3>出力例" ]]; then echo "<out>" >> ${name}.in outflag=true echo ${line#*<pre>} >> ${name}.in fi done << END ${data} END echo "[add] Added ${name}.in" done }
サンプルテストケースをコピペする手間が省けてかなり便利になりました。
【競プロ】コンパイルとテストケースの確認できるシェルスクリプトを書いた
タイトルの通りです。競プロでコード書いていていちいちコンパイルしたりテストケース試したりってのがめんどくさいなと思ったので、書いてみました。
以下全文です。githubにも上げてあります。(途中からシンタックスハイライトがおかしくなってるのは気にしないでください)
https://github.com/hpano/CompetitiveProgramming/blob/master/run.sh
まあこんなことをしなくてもonline-judge-toolsという便利なツールがあるので、特にこだわりがなければこれを使うのがいいでしょう。
online-judge-tools.readthedocs.io
#!/bin/bash function usage() { echo "Usage: $0 [OPTIONS] FILE" echo echo "Options:" echo " -h, --help Display available options." echo " -c, --compile Compile the FILE." echo " -i, --input INPUT Specify input file as INPUT." echo " -n, --norun Not run code test." echo " -r, --remove Remove the existing executable file." echo exit 1 } declare -i argc=0 declare -a argv=() declare hflag=false declare cflag=false declare iflag=false declare nflag=false declare rflag=false declare in_file while test "$1" != ""; do case $1 in -*) if [[ "$1" =~ 'h' ]] || [[ "$1" =~ '-help' ]]; then hflag=true fi if [[ "$1" =~ 'c' ]] || [[ "$1" =~ '-compile' ]]; then cflag=true fi if [[ "$1" =~ 'n' ]] || [[ "$1" =~ '-norun' ]]; then nflag=true fi if [[ "$1" =~ 'r' ]] || [[ "$1" =~ '-remove' ]]; then rflag=true fi if [[ "$1" =~ 'i' ]] || [[ "$1" =~ '-input' ]]; then iflag=true in_file=$2 shift fi shift ;; *) ((++argc)) argv=("${argv[@]}" "${1%.cpp}") shift ;; esac done for i in ${argv[@]}; do declare eval cmissflag_${i}=false done if "${hflag}"; then usage exit fi if "${rflag}"; then $(dirname $0)/remove.sh ${argv[@]} fi if "${cflag}"; then for i in ${argv[@]}; do $(dirname $0)/compile.sh ${i} || eval cmissflag_${i}=true done fi if "${nflag}"; then exit fi for i in ${argv[@]}; do if eval '$cmissflag_'${i}; then continue fi if ! "${iflag}"; then in_file=${i}.in fi declare -a input=() declare -a output=() declare inflag=false declare outflag=false declare case_count=0 declare ac_count=0 declare wa_count=0 declare slowest_time=0 declare slowest_case echo "[run] Run ${i}.out < ${in_file}" # echo while read line; do if [ "${line}" == "<in>" ]; then inflag=true continue elif [ "${line}" == "</in>" ]; then inflag=false continue elif [ "${line}" == "<out>" ]; then outflag=true continue elif [ "${line}" == "</out>" ]; then outflag=false output[${case_count}]=`echo -e "${output[${case_count}]}"` case_count=$(( case_count + 1 )) continue fi if "${inflag}"; then input[${case_count}]+="${line}"" " elif "${outflag}"; then output[${case_count}]+="${line}""\n" fi done < ./${in_file} for j in `seq 0 $(( case_count - 1))`; do echo "[run] *** case `expr ${j} + 1` ***" # echo "[run] input:" # echo -e "${input[${j}]}" # echo "[run] output:" # echo -e "${output[${j}]}" declare start_time=`gdate +%s.%6N` declare result=$(./${i}.out << EOT ${input[${j}]} EOT) declare end_time=`gdate +%s.%6N` declare process_time=`echo "scale=6; (${end_time} - ${start_time})" | bc` if [ `echo "${process_time} > ${slowest_time}" | bc` == 1 ]; then slowest_time=${process_time} slowest_case=${j} fi echo "[run] time: ${process_time} sec" if [ "${output[${j}]}" = "${result}" ]; then ac_count=$(( ac_count + 1 )) echo -e "[run] \033[0;37;42m AC \033[0;39m" else wa_count=$(( wa_count + 1 )) echo -e "[run] \033[0;37;43m WA \033[0;39m" echo "output:" echo -e "${result}" echo "expected:" echo -e "${output[${j}]}" fi done echo "[run] slowest: ${slowest_time} sec (case ${slowest_case})" echo "[run] AC rate: ${ac_count} / $(( ac_count + wa_count )) (AC / cases)" done
コンパイルして欲しいことがあったりなかったり、あらかじめ用意したテストケースを試して欲しかったり欲しくなかったりすることがあると思うので、オプションで指定できるようにしました。まずこの部分でどのオプションが指定されているかフラグを立てています。-iオプションの場合はファイル指定があるので後に続くファイル名を読み取っています。オプション文字列にそのオプションに対応する文字が含まれているのかどうかで判定しているので、複数オプションをつなげて書いても認識できます(-cn など)。
また、オプション以外は全てテストしたいプログラムのファイル名として受け取り、一応複数ファイル同時にテストできるようにしてあります(実際にすることはなさそう)。
while test "$1" != ""; do case $1 in -*) if [[ "$1" =~ 'h' ]] || [[ "$1" =~ '-help' ]]; then hflag=true fi if [[ "$1" =~ 'c' ]] || [[ "$1" =~ '-compile' ]]; then cflag=true fi if [[ "$1" =~ 'n' ]] || [[ "$1" =~ '-norun' ]]; then nflag=true fi if [[ "$1" =~ 'r' ]] || [[ "$1" =~ '-remove' ]]; then rflag=true fi if [[ "$1" =~ 'i' ]] || [[ "$1" =~ '-input' ]]; then iflag=true in_file=$2 shift fi shift ;; *) ((++argc)) argv=("${argv[@]}" "${1%.cpp}") shift ;; esac done
続いてこの部分で各フラグに対応する処理をしています。-rオプションの場合は実行ファイルを削除するシェルスクリプト remove.shを実行、-cオプションの場合はコンパイルを行うシェルスクリプト compile.shを全ての入力プログラムに対して実行します。ここでコンパイルに失敗した場合は、それぞれのプログラムに対応したコンパイル失敗フラグを立てておきます。
for i in ${argv[@]}; do declare eval cmissflag_${i}=false done if "${hflag}"; then usage exit fi if "${rflag}"; then $(dirname $0)/remove.sh ${argv[@]} fi if "${cflag}"; then for i in ${argv[@]}; do $(dirname $0)/compile.sh ${i} || eval cmissflag_${i}=true done fi if "${nflag}"; then exit fi
その後の部分でコンパイルに成功した(orコンパイル済みの)各プログラムを実行していきます。
まずはこの部分でテストケースの入力ファイルを解析。
while read line; do if [ "${line}" == "<in>" ]; then inflag=true continue elif [ "${line}" == "</in>" ]; then inflag=false continue elif [ "${line}" == "<out>" ]; then outflag=true continue elif [ "${line}" == "</out>" ]; then outflag=false output[${case_count}]=`echo -e "${output[${case_count}]}"` case_count=$(( case_count + 1 )) continue fi if "${inflag}"; then input[${case_count}]+="${line}"" " elif "${outflag}"; then output[${case_count}]+="${line}""\n" fi done < ./${in_file}
続く部分でプログラムを実行。配列につっこんだ各テストケースの入力を取り出してプログラムに渡し、出力結果を受け取ります。結果が期待する出力と等しければAC、違っていればWAとして、結果と期待する出力を表示します。また、計測した実行時間も表示します。
for j in `seq 0 $(( case_count - 1))`; do echo "[run] *** case `expr ${j} + 1` ***" # echo "[run] input:" # echo -e "${input[${j}]}" # echo "[run] output:" # echo -e "${output[${j}]}" declare start_time=`gdate +%s.%6N` declare result=$(./${i}.out << EOT ${input[${j}]} EOT) declare end_time=`gdate +%s.%6N` declare process_time=`echo "scale=6; (${end_time} - ${start_time})" | bc` if [ `echo "${process_time} > ${slowest_time}" | bc` == 1 ]; then slowest_time=${process_time} slowest_case=${j} fi echo "[run] time: ${process_time} sec" if [ "${output[${j}]}" = "${result}" ]; then ac_count=$(( ac_count + 1 )) echo -e "[run] \033[0;37;42m AC \033[0;39m" else wa_count=$(( wa_count + 1 )) echo -e "[run] \033[0;37;43m WA \033[0;39m" echo "output:" echo -e "${result}" echo "expected:" echo -e "${output[${j}]}" fi done
最後に最遅だったテストケースとその実行時間、AC数とWA数を表示して終了です。
echo "[run] slowest: ${slowest_time} sec (case ${slowest_case})" echo "[run] AC rate: ${ac_count} / $(( ac_count + wa_count )) (AC / cases)"
実行するとこんな感じになります。
これでまあまあ便利に競プロやれるようになりました。あとは、inファイルのテストケースの入力と出力を手でコピペしているので、そこを自動でやってくれるようにしたいですね。
時が経つのは早いもので
久しぶりの更新です。得意の三日坊主が発動して、しばらく更新していませんでした。
さて、時が経つのは早いもので、気付いたら大学院1年になってしまいました。あっという間ですね。この春学期も、研究したり、授業受けたり、課題をやったりしていたら終わってしまいました。普通にいけばあと1年半で社会人になっているはずですが、まずいですね。学生生活が終わってしまいます。幸いにもあと取らないといけない授業は最低限1つなので、今後はもうちょっと他のことにも取り組めるでしょう、きっと。というか取り組みたい。サークルを去年で引退して今までよりは時間に余裕ができたこともあり、7月頃から今までやろうと思っていたけどできなかったことに手を出し始めました。ということで、今回はそれらについて軽く書こうかな。(そのうち研究についても書こうと思ってます。)
競プロ
去年まではサークルの都合で土日がほとんど埋まっていたのですが、今年はコンテストに参加できるということで始めました。あと研究室の先輩の影響もあります。とりあえずAtCoderの問題を解いててABCレベルのコンテストにも2回参加したのですが、まだまだですね。D問題までなら解けますが、解く時間が遅いし、EF問題には全然手が出ません。AtCoder Problemsなどを活用して精進します。
競プロの入門については、これを読むのがいいと思います。
ゲーム開発
前からやりたかったゲーム開発をちょこちょこやっています。といってもまあUnityの勉強が大半を占めていますが。色々と作りたいゲームは頭の中にあるので、完成までもっていきたいです。(ゲーム開発は完成しないことがほとんどなので。。。)そうそう、ついでにだいぶ前に買ったこの本を一通り読みました。元々5年前くらいにMinecraft PEのMod開発をしていた頃に買ったやつだったのですが、ちゃんと読んでいなかったので。Minecraft PEのMod開発はプログラミングを始めたきっかけなので、ちゃんと読もうと思って5年の時を経て読みました。
では今回はこの辺で。
Windows10でプログラミング環境を整える
新しいPCでもプログラミングできるように、色々と環境を整えました。とりあえず学校の授業でもよく使う、CとJavaを使えるようにします。
Chocolatey
Macでいうhomebrewのようなパッケージ管理ソフトがあると聞いて入れました。それがこのChocolatey。
サイトを見てみると、かなりのソフトをインストールできるみたいですね。
chocolatey.org
インストール
インストールはとても簡単です。まず、コマンドプロンプトまたはPowerShellを管理者権限で起動します。つぎにChocolateyのサイトに行き、コマンドプロンプト or PowerShellに適したコマンドをコピーしてきます。それを貼り付けて実行すれば、あとはインストールされるのを待つだけです。
よく使う機能
パッケージの検索
choco list
インストール済みパッケージの検索
choco list -localonly
パッケージのインストール
choco install <パッケージ名>
パッケージのアップデード
choco update <パッケージ名>
パッケージのアンインストール
choco uninstall <パッケージ名>
Git
Bash環境としてGitを使いたいので、インストールします。
Git
公式サイトからダウンロードしてきてもいいですが、今回は管理者権限のコマンドプロンプトでchocolateyを用いてインストールします。
choco install -y git
Cmder
コンソールとしてCmderをインストールします。chocolateyでもインストールできますが、最新版を使いたい場合は公式サイトからインストールするのがいいでしょう。
cmder.net
PATHの設定
cmder.exeのあるディレクトリをPATHに追加します。
Cmderの設定
Cmderをより便利にするために色々と設定していきます。
日本語文字がつぶれて表示されるのを防ぐために、General>fontsにある"Monospace"のチェックを外します。
新しいタブを作るときに指定できるタスクを増やします。Startup>Tasksにある"Add/refuresh..."をクリックすると、いい感じの設定が自動で作成されます。ここでは、追加されたGit bashを選択して、default taskにしましょう。右下のウィンドウでは赤線で引いた形でタスク開始時のディレクトリを指定できます。この例ではホームディレクトリにしてあります。
ついでにStartupのSpecified named taskもGit bashにしておきましょう。
General>Tab barにある"Tab bar on bottom"のチェックを外すことで、タブバーをウィンドウ上部にもってきます。こっちの方がMacに近くて個人的にすきです。
カラースキームは"Twilight"にしました。自分の好みになるようにいじることもできます。
Features>Transparencyで、ウィンドウの透明度を設定できます。
Key & Macro>Keyboardの中にある、"[Inselection] Copy: Current selection as plain text: Copy(0,0)"の"Choose hotkey"を"なし"にします。こうすることで、「Ctrl」+「c」で割り込みシグナルを送ることができるようになります。
.bash_profileの設定
ホームディレクトリに追加される.bash_profileに日本語環境で使うためのLANG環境変数を追記します。
# generated by Git for Windows test -f ~/.profile && . ~/.profile test -f ~/.bashrc && . ~/.bashrc export LANG=ja_JP.UTF-8
.bashrcの設定
エイリアスの設定をします。
alias ls='ls --show-control-chars -F --color --ignore={NTUSER.*,ntuser.*}' alias activate='source activate' alias deactivate='source deactivate'
日本語のファイル名やディレクトリ名が表示されるようにしました。また、ホームディレクトリにNTUSER.DAT{.....という長い名前の隠しファイルがあり、lsを実行するたびに表示されると邪魔なので表示されないようにしました。
Conda環境を切り替えるのに、bashだとsource activate [環境名]と打つ必要があります。面倒なのでactivate [環境名]だけで実行できるようにしました。deactivateも同様です。
MinGW
C言語等をコンパイルできるようにするために、GNUツールチェインであるMinGWをインストールします。
choco install mingw
gcc --version
としてバージョン情報が表示されれば無事インストールされています。
JDK8
Javaを使えるようにするためにJDK8をインストールします。
choco install jdk8
java -version
としてバージョン情報が表示されれば無事インストールされています。
その他
テキストエディタなどは好きなものを入れればいいでしょう。僕はとりあえずVisual Studio Codeを入れてみました。
CygwinやらMSYS2やらいろいろあってどうしようか迷いましたが、とりあえずこんな感じで構築してみました。しばらくこれで使ってみようと思います。
PCを組んでみた
導入
・今使ってるMBAがMid 2011モデルで古すぎる
・お金が貯まった
・色々やりたいゲームがある
・PC組んでみたい
ということで、初めて自作PCに挑戦してみました。
構成はこちら。Amazonで全部買えそう&色々なところで買うのも面倒だったので、パーツは全部Amazonで注文しました。
(※価格は購入時のものです 2018年11月ごろ)
CPU | Intel Core i5 9600K BOX | ¥34,980 |
CPUクーラー | サイズ 無限五 リビジョンB SCMG-5100 | ¥5,038 |
メモリ | Corsair CMK16GX4M2A2666C16 [DDR4 PC4-21300 8GB 2枚組] | ¥18,435 |
マザーボード | ASUS TUF H370-PRO GAMING | ¥12,841 |
ビデオカード | ASUS TURBO-GTX1070Ti-8G | ¥50,998 |
SSD | Intel SSD 760p SSDPEKKW256GBXT | ¥8,478 |
HDD | SEAGATE ST4000DM004 [4TB SATA600 7200] | ¥9,117 |
ケース | Thermaltake Versa H26 Black /w casefan CA-1 J5-00M1WN-01 [ブラック] | ¥4,300 |
電源 | 玄人志向 KRPW-N600W/85+ | ¥5,378 |
合計 | ¥149,565 |
現在の価格はこちら
niku.webcrow.jp
これに加えて、今までデスクトップPCがなかったので以下のものも購入。
モニタ | Dell SE2416H 23.8インチ/フルHD・IPS非光沢/6ms/VGA,HDMI | ¥12,360 |
キーボード | Logicool K120 | ¥811 |
マウス | Logicool G300s | ¥1,809 |
LANケーブル | UGREEN カテゴリー7 RJ45 | ¥1,098 |
マウスはゲームもやるのでボタンがいくつかついてるやつ、キーボードはとりあえずあればいいので安いやつを選びました。
組み立て
11月某日
全パーツが到着。なんか浮かれてたので並べて撮ってみました。
CPUを載せていきます。ここでミスったら壊れるという話を聞いていたので、緊張しながら載せました。
グリスを塗って
ここまできてミスに気づいた pic.twitter.com/Jv24EjHIbW
— ぱの (@N1101H) November 1, 2018
CPUクーラーを載せるためのマウンティングプレートが内外逆でした。
プレートを付けなおしてCPUクーラーを載せます。
メモリを開封
マザボのA1とA2スロットに差していきます。メーカーや型番によって並び順が違うみたいなのでちょっと戸惑いました。
あとはマザボにGPUをつけて、ケースのファンや電源やHDDなどの配線をして、モニタ、キーボード、マウスを接続して完成です。(夢中になってたので写真が残ってなかった)
電源を入れると無事起動しました。
メモリ、SSD、HDDも認識され、ファンも問題なく動いています。
OSのインストール
OSはWindows10 Educationを選択。大学の関係で無料でインストールできるものがあったので、それを使います。
手元にWindows8.1の入ったノートPCがあったので、メディア作成ツールを用いてインストールするためのUSBメモリを作りました。
https://www.microsoft.com/ja-jp/software-download/windows10
Windows10無事起動
あとはデバイスマネージャーを開いて足りてないものをネットから拾ってきます。
諸々の設定を終えて試しにMinecraftを動かしてみたところ、なかなかのfpsが出ています。
これで快適なゲームライフをおくれそうです。