zsh-workers
 help / color / mirror / code / Atom feed
* Tetris
@ 2001-09-03  0:03 Zefram
  2001-09-03  6:08 ` Tetris Wayne Davison
  2001-09-03 17:14 ` Tetris Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: Zefram @ 2001-09-03  0:03 UTC (permalink / raw)
  To: zsh-workers

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
}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Tetris
  2001-09-03  0:03 Tetris Zefram
@ 2001-09-03  6:08 ` Wayne Davison
  2001-09-03  9:50   ` Tetris Zefram
  2001-09-03 17:14 ` Tetris Bart Schaefer
  1 sibling, 1 reply; 5+ messages in thread
From: Wayne Davison @ 2001-09-03  6:08 UTC (permalink / raw)
  To: Zefram; +Cc: zsh-workers

On Mon, 3 Sep 2001, Zefram wrote:
> function tetris-render-screen {

I had to add the following line to the above function in order to get
it to work:

	setopt localoptions unset

After that, things worked quite nicely.  Impressive.

..wayne..


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Tetris
  2001-09-03  6:08 ` Tetris Wayne Davison
@ 2001-09-03  9:50   ` Zefram
  0 siblings, 0 replies; 5+ messages in thread
From: Zefram @ 2001-09-03  9:50 UTC (permalink / raw)
  To: zsh-workers

Wayne Davison wrote:
>	setopt localoptions unset

Ah, I thought I'd written it for zsh native mode, but there I actually
wrote it for my interactive setup.  Here's the proper fix.

--- tetris.zsh	Mon Sep  3 01:45:35 2001
+++ tetris.zsh	Mon Sep  3 10:46:46 2001
@@ -23,6 +23,7 @@
 
 zle -N tetris
 function tetris {
+	emulate -L zsh
 	tetris_save_buffer=$BUFFER
 	tetris_save_cursor=$CURSOR
 	local i
@@ -44,6 +45,7 @@
 }
 
 function tetris-new-block {
+	emulate -L zsh
 	tetris_block=$tetris_shapes[1+RANDOM%$#tetris_shapes]
 	tetris_block_y=0
 	tetris_block_x=4
@@ -59,6 +61,7 @@
 
 zle -N tetris-left
 function tetris-left {
+	emulate -L zsh
 	tetris-place-block " "
 	(( tetris_block_x-- ))
 	tetris-block-fits || (( tetris_block_x++ ))
@@ -68,6 +71,7 @@
 
 zle -N tetris-right
 function tetris-right {
+	emulate -L zsh
 	tetris-place-block " "
 	(( tetris_block_x++ ))
 	tetris-block-fits || (( tetris_block_x-- ))
@@ -77,6 +81,7 @@
 
 zle -N tetris-rotate
 function tetris-rotate {
+	emulate -L zsh
 	tetris-place-block " "
 	local save_block=$tetris_block
 	tetris_block=$tetris_rotations[$tetris_block]
@@ -87,6 +92,7 @@
 
 zle -N tetris-drop
 function tetris-drop {
+	emulate -L zsh
 	tetris-place-block " "
 	((tetris_block_y++))
 	while tetris-block-fits; do
@@ -98,6 +104,7 @@
 
 zle -N tetris-timeout
 function tetris-timeout {
+	emulate -L zsh
 	tetris-place-block " "
 	((tetris_block_y++))
 	if tetris-block-fits; then
@@ -110,6 +117,7 @@
 }
 
 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
@@ -124,6 +132,7 @@
 }
 
 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
@@ -143,6 +152,7 @@
 }
 
 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
@@ -155,6 +165,7 @@
 }
 
 function tetris-render-screen {
+	emulate -L zsh
 	local s i extras
 	extras=(
 		"Score: $tetris_score"
@@ -164,7 +175,7 @@
 	)
 	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'
+		s=$s${extras[1]+   $extras[1]}$'\n'
 		extras[1]=()
 	done
 	s="$s+${tetris_blankline// /-}+"
@@ -172,6 +183,7 @@
 }
 
 function tetris-timed-move {
+	emulate -L zsh
 	tetris-render-screen
 	LBUFFER=
 	RBUFFER=$'\n'$tetris_screen
@@ -181,6 +193,7 @@
 
 zle -N tetris-quit
 function tetris-quit {
+	emulate -L zsh
 	if [[ ! -o always_last_prompt ]]; then
 		BUFFER=
 		zle -M $tetris_screen


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Tetris
  2001-09-03  0:03 Tetris Zefram
  2001-09-03  6:08 ` Tetris Wayne Davison
@ 2001-09-03 17:14 ` Bart Schaefer
  2001-09-03 17:43   ` Tetris Bart Schaefer
  1 sibling, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2001-09-03 17:14 UTC (permalink / raw)
  To: Zefram, zsh-workers

On Sep 3,  1:03am, Zefram wrote:
}
} Improvements are welcome.

You're left-handed, aren't you.

For some reason the 's' key to rotate is not working for me.  I end up (I
think, I'm not sure) in vi insert mode when I press 's'.  Moving blocks
right and left with 'a' and 'd' works fine.

A little more error checking would be nice.

--- tetris.0	Mon Sep  3 09:38:55 2001
+++ tetris	Mon Sep  3 10:07:29 2001
@@ -27,6 +27,10 @@
 zle -N tetris
 function tetris {
 	emulate -L zsh
+	if ! zle ; then
+	    print -u2 "Use M-x tetris RET to play tetris."
+	    return 1
+	fi
 	tetris_save_buffer=$BUFFER
 	tetris_save_cursor=$CURSOR
 	local i

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Tetris
  2001-09-03 17:14 ` Tetris Bart Schaefer
@ 2001-09-03 17:43   ` Bart Schaefer
  0 siblings, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2001-09-03 17:43 UTC (permalink / raw)
  To: Zefram, zsh-workers

On Sep 3,  5:14pm, Bart Schaefer wrote:
}
} I end up (I think, I'm not sure) in vi insert mode when I press 's'.

I figured it out.  I set up the entire file as an autoloadable function,
so the tetris_rotations array became a local.  Might be useful to protect
against that:

--- tetris.0	Mon Sep  3 09:38:55 2001
+++ tetris	Mon Sep  3 10:39:54 2001
@@ -4,7 +4,7 @@
 tetris_hsz=11
 tetris_vsz=20
 tetris_shapes=(0x0f00 0x4e00 0x6600 0x4620 0x2640 0x2260 0x4460)
-typeset -A tetris_rotations
+typeset -gA tetris_rotations
 tetris_rotations=(
 	0x0f00 0x4444 0x4444 0x0f00
 	0x4e00 0x4c40 0x4c40 0x0e40 0x0e40 0x4640 0x4640 0x4e00

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-09-03 17:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-03  0:03 Tetris Zefram
2001-09-03  6:08 ` Tetris Wayne Davison
2001-09-03  9:50   ` Tetris Zefram
2001-09-03 17:14 ` Tetris Bart Schaefer
2001-09-03 17:43   ` Tetris Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).