Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Tetris
- X-seq: zsh-workers 15733
- From: Zefram <zefram@xxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Tetris
- Date: Mon, 3 Sep 2001 01:03:35 +0100 (BST)
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
A friend of mine complained that zsh isn't as complete as Emacs because
it lacks Tetris and an adventure game. Below is half of the fix.
Writing this showed up a couple of features lacking in ZLE, for which I
will be providing patches shortly. I also discovered a bug, which I'm
trying to pin down now. On the upside, Geoff's display code is doing
sterling service in conditions it was never meant for.
Improvements are welcome. A simple one in particular, I haven't
implemented automatic game speed variation, which can be done by varying
KEYTIMEOUT (the default 0.4s wait makes the game about difficult enough
for me). Also I'm not sure of the best way to package this for the
distribution, suggestions welcome.
-zefram
# source me then do M-x tetris
# quit with "q", NOT with ^C
tetris_hsz=11
tetris_vsz=20
tetris_shapes=(0x0f00 0x4e00 0x6600 0x4620 0x2640 0x2260 0x4460)
typeset -A 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
0x2260 0x0e20 0x0e20 0x0644 0x0644 0x0470 0x0470 0x2260
0x4460 0x02e0 0x02e0 0x0622 0x0622 0x0740 0x0740 0x4460
)
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
zle -N tetris
function tetris {
tetris_save_buffer=$BUFFER
tetris_save_cursor=$CURSOR
local i
bindkey -A main tetris-save-main
bindkey -N main
zle .vi-insert
bindkey -R '\000-\377' tetris-timeout
for ((i=256; i--; )); do
bindkey 'T\'$(([##8]i)) tetris-timeout
done
bindkey Ta tetris-left
bindkey Ts tetris-rotate
bindkey Td tetris-right
bindkey 'T ' tetris-drop
bindkey Tq tetris-quit
tetris_board=$tetris_blankboard
tetris_score=0
tetris-new-block
}
function tetris-new-block {
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
tetris-quit
return
fi
tetris-place-block "*"
tetris-timed-move
}
zle -N tetris-left
function tetris-left {
tetris-place-block " "
(( tetris_block_x-- ))
tetris-block-fits || (( tetris_block_x++ ))
tetris-place-block "*"
tetris-timeout
}
zle -N tetris-right
function tetris-right {
tetris-place-block " "
(( tetris_block_x++ ))
tetris-block-fits || (( tetris_block_x-- ))
tetris-place-block "*"
tetris-timeout
}
zle -N tetris-rotate
function tetris-rotate {
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 {
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 {
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 {
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 {
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 {
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-render-screen {
local s i extras
extras=(
"Score: $tetris_score"
"Keys: a=left, d=right"
" s=rotate, space=drop"
" q=quit"
)
for ((i=0; i!=tetris_vsz; i++)); do
s="$s|${tetris_board[1+i*tetris_hsz,(i+1)*tetris_hsz]}|"
s=$s" "$extras[1]$'\n'
extras[1]=()
done
s="$s+${tetris_blankline// /-}+"
tetris_screen=$s
}
function tetris-timed-move {
tetris-render-screen
LBUFFER=
RBUFFER=$'\n'$tetris_screen
zle -R
zle -U T
}
zle -N tetris-quit
function tetris-quit {
if [[ ! -o always_last_prompt ]]; then
BUFFER=
zle -M $tetris_screen
fi
BUFFER=$tetris_save_buffer
CURSOR=$tetris_save_cursor
if [[ -o always_last_prompt ]]; then
zle -M $tetris_screen
fi
bindkey -A tetris-save-main main
bindkey -D tetris-save-main
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author