キーボードによる微妙な制御が私の時間の多くを費やしたので、私は互換性の微妙なことを気にしませんでした。したがって、ゲームはMac OS Xでのみテストされました。
動作させるには、ゲームにnc(別名Netcat )と256色をサポートする端末が必要です(Mac OSの場合はiTerm2をお勧めします )。 ゲームに興味があれば、16色と/ dev / tcpで端末を仕上げます。 ところで、すべてのシェルクラフトをGithubにアップロードし始めました。

ゲームはネットワーク化されているため、2つのパラメーターを指定する必要があります。パラメーターを指定せずに起動するかどうかを通知します。 最初は敵のマシンのアドレス、2番目はポートです。 ポートは両方のマシンで同じように選択されます。 ゲームは、同じマシンで2つのコンソールで実行できます(スクリーンショットはそのような場合です)。
プレイするのは簡単です-各瞬間にアクティブなボードは1つだけです(スクリーンショット-右のボードでは、ボードの周りに明るい文字と数字があります)、アクティブなボードではカーソルキーでカーソルが移動します-←、→、↑、↓ -スペースバーまたはEnterを押します。 ボードに駒を置くとすぐに、相手に動きが移ります。 対戦相手の作品を「食べる」のは簡単です-自分の作品を他の人の作品に置くだけです。 ゲームには保護があります。フィギュアを「食べる」ことはできません。
ゲームにはこれ以外に何もありません-移動の制御が正しく行われず、ゲームを完了するためのチェックがありません。対戦相手の駒を歩くことさえできます。 シェルでクリックを処理する方法を理解することは非常に困難でした。そのため、残りの時間はありませんでした。「夕方のおもちゃ」の形式には収まりませんでした。
すべてを独立して動作させる方法を理解できるように、コードにコメントを付けて構造化された方法で記述しようとしました。
#!/bin/bash # Network chess by Evgeny Stepanischev http://bolknote.ru 2011 if [ $# -ne 2 ]; then echo Usage: $0 host-of-opponent port exit fi # HOST="$1" # PORT="$2" # SEQLEN=(1b5b4. [2-7]. [cd]... [89ab].{5} f.{7}) # WHITE=(♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖) BLACK=(♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟) # ? OURMOVE= # ? MYCOLOR= # declare -a XY # CX=1 CY=7 TAKEN= # KUP=1b5b41 KDOWN=1b5b42 KLEFT=1b5b44 KRIGHT=1b5b43 KSPACE=20 # function Restore { echo -ne "\033[5B\033[5B\033[?25h\033[m" stty "$ORIG" 2>/dev/null (bind '"\r":accept-line' 2>/dev/null) } trap Restore EXIT # Enter (bind -r '\r' 2>/dev/null) # ORIG=`stty -g` stty -echo # echo -e "\033[?25l" # function ToNet { echo $1 | nc "$HOST" "$PORT" } # function React { case $1 in $KLEFT) if [ $CX -gt 1 ]; then CX=$(($CX-1)) PrintBoard fi ;; $KRIGHT) if [ $CX -lt 8 ]; then CX=$(($CX+1)) PrintBoard fi ;; $KUP) if [ $CY -gt 1 ]; then CY=$(($CY-1)) PrintBoard fi ;; $KDOWN) if [ $CY -lt 8 ]; then CY=$(($CY+1)) PrintBoard fi esac # [ "$OURMOVE" ] && ToNet $1 } # function CheckCons { local i for i in ${SEQLEN[@]}; do if [[ $1 =~ ^$i ]]; then return 0 fi done return 1 } # , React , # KSPACE — function PressEvents { local real code action # , , # # while true; do # read # akw NR==1||NR==4 №1 ( real) №4 ( ) eval $( (time -p read -r -s -n1 ch; printf 'code %d\n' "'$ch") 2>&1 | awk 'NR==1||NR==4 {print $1 "=" $2}' | tr '\r\n' ' ') # read Enter , 20, # UTF8 if [ "$code" = 0 ]; then code=20 else [ $code -lt 0 ] && code=$((256+$code)) code=$(printf '%02x' $code) fi if [ $code = $KSPACE ]; then [ "$OURMOVE" ] && ToNet $KSPACE SpaceEvent && return continue fi # ( ) if [ $real = 0.00 ]; then seq="$seq$code" if CheckCons $seq; then React $seq seq= fi # ( ), # , else [ "$seq" ] && React $seq seq=$code # if CheckCons $seq; then React $seq seq= fi fi done } # function CheckColor { echo -n ${1:0:1} } # function FillBoard { local xy ch for y in {1..8}; do for x in {1..8}; do ch='S ' if [ $y -le 2 ]; then ch=B${BLACK[$x+8*$y-9]} else if [ $y -ge 7 ]; then ch=W${WHITE[$x+8*$y-57]} fi fi XY[$x+100*$y]=$ch done done } # function PrintBoardLetters { local letters=abcdefgh [ -z "$OURMOVE" ] && echo -ne "\033[30m" || echo -ne "\033[0m" echo -n ' ' for x in {0..7}; do echo -n "${letters:$x:1} " done echo } # function PrintBoardDigit { [ -z "$OURMOVE" ] && echo -ne "\033[30m" echo -en " $((9-$1))\033[0m " } # function PrintBoard { local xyc ch local colors=('48;5;209;37;1' '48;5;94;37;1') PrintBoardLetters for y in {1..8}; do PrintBoardDigit $y for x in {1..8}; do c=${colors[($x+$y) & 1]} ch=${XY[$x+100*$y]} if [[ $CX == $x && $CY == $y ]]; then c="$c;7" [ "$TAKEN" ] && ch=$TAKEN [ $MYCOLOR == B ] && c="$c;38;5;16" fi [[ $(CheckColor "$ch") == "B" ]] && c="$c;38;5;16" echo -en "\033[${c}m${ch:1:1} \033[m" done PrintBoardDigit $y echo done PrintBoardLetters echo -e "\033[11A" } # function NetListen { nc -l $PORT } # function NetEvents { local code while true; do code=$(NetListen) [[ "$code" == "$KSPACE" ]] && SpaceEvent && return React $code done } # Space Enter — function SpaceEvent { local xy # , let xy="$CX+$CY*100" # if [ "${XY[$xy]:-S }" = "S " ]; then if [ -z "$TAKEN" ]; then echo -en "\007" else # XY[$xy]=$TAKEN TAKEN= return 0 fi # else # «» if [[ $(CheckColor "$TAKEN") == $(CheckColor "${XY[$xy]}") ]]; then echo -en "\007" else # « », «» if [ "$TAKEN" ]; then XY[$xy]=$TAKEN TAKEN= return 0 else # « » , TAKEN=${XY[$xy]} XY[$xy]="S " fi fi fi return 1 } # function ClearKeyboardBuffer { # — zsh which zsh &>/dev/null && zsh -c 'while {} {read -rstk1 || break}' && return # — bash local delta while true; do delta=`(time -p read -rs -n1 -t1) 2>&1 | awk 'NR==1{print $2}'` [[ "$delta" == "0.00" ]] || break done } FillBoard # ToNet HI [[ "$(NetListen)" == "HI" ]] && OURMOVE=1 sleep 0.2 ToNet ULOOSE [ "$OURMOVE" ] && MYCOLOR=W || MYCOLOR=B PrintBoard # — while true; do if [ -n "$OURMOVE" ]; then ClearKeyboardBuffer PressEvents OURMOVE= else NetEvents OURMOVE=1 fi PrintBoard done
残念ながら、すべてのレコーダーはコンピューター上で非常に重く、ゲームの速度が低下し始めますが、一般的なアイデアを得ることができます。