summaryrefslogtreecommitdiff
path: root/Functions/Misc/tetris
diff options
context:
space:
mode:
authorAndrew Main <zefram@users.sourceforge.net>2001-09-21 02:40:38 +0000
committerAndrew Main <zefram@users.sourceforge.net>2001-09-21 02:40:38 +0000
commitcd59ad72b6466bad25dc1fd9441d8ce30c741af0 (patch)
tree1ebf251fb9e0126961c2a6d2b4c5841db473c5d4 /Functions/Misc/tetris
parentb27659c6b38285247ca9d5ad93a7718feed7563e (diff)
downloadzsh-cd59ad72b6466bad25dc1fd9441d8ce30c741af0.tar.gz
zsh-cd59ad72b6466bad25dc1fd9441d8ce30c741af0.zip
tetris game for ZLE
Diffstat (limited to 'Functions/Misc/tetris')
-rw-r--r--Functions/Misc/tetris243
1 files changed, 243 insertions, 0 deletions
diff --git a/Functions/Misc/tetris b/Functions/Misc/tetris
new file mode 100644
index 000000000..a9d367964
--- /dev/null
+++ b/Functions/Misc/tetris
@@ -0,0 +1,243 @@
+# Someone once accused zsh of not being as complete as Emacs, because it
+# lacks Tetris and an adventure game.
+#
+# autoload -U tetris
+# zle -N tetris
+# bindkey '...' tetris
+
+emulate -L zsh
+
+tetris_hsz=11
+tetris_vsz=20
+typeset -ga tetris_shapes
+tetris_shapes=(
+ 0x0f00 0x4444 0x0f00 0x4444
+ 0x4e00 0x4c40 0x0e40 0x4640
+ 0x6600 0x6600 0x6600 0x6600
+ 0x4620 0x6c00 0x4620 0x6c00
+ 0x2640 0x6300 0x2640 0x6300
+ 0x6440 0x8e00 0x44c0 0x0e20
+ 0xc440 0x0e80 0x4460 0x2e00
+)
+typeset -gA tetris_rotations
+tetris_rotations=(
+ 0x0f00 0x4444 0x4444 0x0f00
+ 0x4e00 0x4c40 0x4c40 0x0e40 0x0e40 0x4640 0x4640 0x4e00
+ 0x6600 0x6600
+ 0x4620 0x6c00 0x6c00 0x4620
+ 0x2640 0x6300 0x6300 0x2640
+ 0x6440 0x8e00 0x8e00 0x44c0 0x44c0 0x0e20 0x0e20 0x6440
+ 0xc440 0x0e80 0x0e80 0x4460 0x4460 0x2e00 0x2e00 0xc440
+)
+
+tetris_blankline=
+for ((tetris_i=tetris_hsz; tetris_i--; )); do
+ tetris_blankline="$tetris_blankline "
+done
+tetris_blankboard=
+for ((tetris_i=tetris_vsz; tetris_i--; )); do
+ tetris_blankboard="$tetris_blankboard$tetris_blankline"
+done
+
+bindkey -N tetris
+bindkey -R -M tetris '\000-\377' tetris-timeout
+for ((tetris_i=256; tetris_i--; )); do
+ bindkey -M tetris 'T\'$(([##8]tetris_i)) tetris-timeout
+done
+bindkey -M tetris Ta tetris-left
+bindkey -M tetris Tj tetris-left
+bindkey -M tetris Ts tetris-rotate
+bindkey -M tetris Tk tetris-rotate
+bindkey -M tetris Td tetris-right
+bindkey -M tetris Tl tetris-right
+bindkey -M tetris 'T ' tetris-drop
+bindkey -M tetris Tq tetris-quit
+
+unset tetris_board tetris_score
+
+zle -N tetris
+function tetris {
+ emulate -L zsh
+ if ! zle; then
+ print -u2 "Use M-x tetris RET to play tetris."
+ return 2
+ fi
+ tetris_saved_state="BUFFER=${BUFFER:q};CURSOR=${CURSOR:q};MARK=${MARK:q};zle -K ${KEYMAP:q}"
+ tetris_speed=$((100.0/KEYTIMEOUT))
+ zle -K tetris
+ if [[ ${tetris_board+set} == set ]]; then
+ tetris-timeout
+ else
+ tetris_board=$tetris_blankboard
+ tetris_score=0
+ tetris-new-block
+ fi
+}
+
+function tetris-new-block {
+ emulate -L zsh
+ tetris_block=$tetris_shapes[1+RANDOM%$#tetris_shapes]
+ tetris_block_y=0
+ tetris_block_x=4
+ if ! tetris-block-fits; then
+ tetris-place-block "#"
+ tetris-render-screen
+ unset tetris_board tetris_score
+ tetris-quit
+ return
+ fi
+ tetris-place-block "*"
+ tetris-timed-move
+}
+
+zle -N tetris-left
+function tetris-left {
+ emulate -L zsh
+ tetris-place-block " "
+ (( tetris_block_x-- ))
+ tetris-block-fits || (( tetris_block_x++ ))
+ tetris-place-block "*"
+ tetris-timeout
+}
+
+zle -N tetris-right
+function tetris-right {
+ emulate -L zsh
+ tetris-place-block " "
+ (( tetris_block_x++ ))
+ tetris-block-fits || (( tetris_block_x-- ))
+ tetris-place-block "*"
+ tetris-timeout
+}
+
+zle -N tetris-rotate
+function tetris-rotate {
+ emulate -L zsh
+ tetris-place-block " "
+ local save_block=$tetris_block
+ tetris_block=$tetris_rotations[$tetris_block]
+ tetris-block-fits || tetris_block=$save_block
+ tetris-place-block "*"
+ tetris-timeout
+}
+
+zle -N tetris-drop
+function tetris-drop {
+ emulate -L zsh
+ tetris-place-block " "
+ ((tetris_block_y++))
+ while tetris-block-fits; do
+ ((tetris_block_y++))
+ done
+ ((tetris_block_y--))
+ tetris-block-dropped
+}
+
+zle -N tetris-timeout
+function tetris-timeout {
+ emulate -L zsh
+ tetris-place-block " "
+ ((tetris_block_y++))
+ if tetris-block-fits; then
+ tetris-place-block "*"
+ tetris-timed-move
+ return
+ fi
+ ((tetris_block_y--))
+ tetris-block-dropped
+}
+
+function tetris-block-dropped {
+ emulate -L zsh
+ tetris-place-block "O"
+ local fl=${tetris_blankline// /O} i=$((tetris_block_y*tetris_hsz)) y
+ for ((y=0; y!=4; y++)); do
+ if [[ $tetris_board[i+1,i+tetris_hsz] == $fl ]]; then
+ tetris_board[i+1,i+tetris_hsz]=
+ tetris_board=$tetris_blankline$tetris_board
+ ((tetris_score++))
+ fi
+ ((i += tetris_hsz))
+ done
+ tetris-new-block
+}
+
+function tetris-block-fits {
+ emulate -L zsh
+ local y x i=$((1+tetris_block_y*tetris_hsz+tetris_block_x)) b=0x8000
+ for ((y=0; y!=4; y++)); do
+ for ((x=0; x!=4; x++)); do
+ if ((tetris_block&b)); then
+ ((x+tetris_block_x >= 0)) || return 1
+ ((x+tetris_block_x < tetris_hsz)) || return 1
+ ((y+tetris_block_y >= 0)) || return 1
+ ((y+tetris_block_y < tetris_vsz)) || return 1
+ [[ $tetris_board[i] == " " ]] || return 1
+ fi
+ ((b >>= 1))
+ ((i++))
+ done
+ ((i+=tetris_hsz-4))
+ done
+ return 0
+}
+
+function tetris-place-block {
+ emulate -L zsh
+ local y x i=$((1+tetris_block_y*tetris_hsz+tetris_block_x)) b=0x8000
+ for ((y=0; y!=4; y++)); do
+ for ((x=0; x!=4; x++)); do
+ ((tetris_block&b)) && tetris_board[i]=$1
+ ((b >>= 1))
+ ((i++))
+ done
+ ((i+=tetris_hsz-4))
+ done
+}
+
+function tetris-timed-move {
+ emulate -L zsh
+ tetris-render-screen
+ LBUFFER=
+ RBUFFER=$'\n'$tetris_screen
+ zle -R
+ zle -U T
+}
+
+function tetris-render-screen {
+ emulate -L zsh
+ setopt extendedglob
+ local s i extras
+ extras=(
+ "Score: $tetris_score"
+ ""
+ "Game parameters: ${tetris_hsz}x$tetris_vsz, ${tetris_speed}Hz"
+ ""
+ "Keys: left: a j"
+ " rotate: s k"
+ " right: d l"
+ " drop: space"
+ " quit: q"
+ )
+ for ((i=0; i!=tetris_vsz; i++)); do
+ s="$s|${${${${${tetris_board[1+i*tetris_hsz,(i+1)*tetris_hsz]}//O/()}//\*/**}// / }//\#/##}|"${extras[1]+ $extras[1]}$'\n'
+ extras[1]=()
+ done
+ s="$s+${tetris_blankline// /--}+"
+ tetris_screen=$s
+}
+
+zle -N tetris-quit
+function tetris-quit {
+ emulate -L zsh
+ if [[ ! -o always_last_prompt ]]; then
+ BUFFER=
+ zle -M $tetris_screen
+ fi
+ eval $tetris_saved_state
+ if [[ -o always_last_prompt ]]; then
+ zle -M $tetris_screen
+ fi
+}
+
+tetris "$@"