mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-23 04:30:24 +02:00
tetris game for ZLE
This commit is contained in:
parent
b27659c6b3
commit
cd59ad72b6
4 changed files with 268 additions and 0 deletions
|
@ -4,4 +4,5 @@ allopt harden nslookup zkbd zstyle+
|
|||
checkmail is-at-least run-help zmv
|
||||
colors mere zed zrecompile
|
||||
getjobs promptnl
|
||||
tetris
|
||||
'
|
||||
|
|
243
Functions/Misc/tetris
Normal file
243
Functions/Misc/tetris
Normal file
|
@ -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 "$@"
|
Loading…
Add table
Add a link
Reference in a new issue