#!/usr/bin/tclsh # 名稱: randwalk # 作者: 洪朝貴 http://www.cyut.edu.tw/~ckhung/ # 初版日期: 1999 年 3 月 # 功能: 從命令列上讀入 delay 與 step, 隨機移動遊標, 並隨意亂走 step 步, # 每走一步休息 delay 毫秒 # 需求: 螢幕必須支援 ANSI escape sequence # 清除螢幕 proc clearscr {} { puts -nonewline "\x1b\[2J" } # 將遊標移到第 r 列, 第 c 行 proc gotorc {r c} { puts -nonewline [format "\x1b\[%d;%dH" $r $c] } proc randwalk { {delay 50} {step 100} } { ;# 檢查參數是否正確 if {$delay < 0} { error "delay should be >= 0" } if {$step < 0} { error "step should be >= 0" } set max_row 25 ;# 設定螢幕的寬度與高度 set max_col 80 clearscr ;# 清除螢幕 expr srand( [clock clicks] ) ;# 用系統目前的時間起始亂數 set row [expr 1 + int(rand()*$max_row)] ;# 用亂數隨機決定遊標的起始坐標 set col [expr 1 + int(rand()*$max_col)] set last_dir -3 while {$step >= 0} { ;# 偷懶法: 用上限當做註標變數 ... set col_new -1 ;# 不斷地試, 直到決定下一步該怎麼走為止 while {$col_new <=0 || $col_new > $max_col || $row_new <= 0 || $row_new > $max_row} { set dir [expr int(rand()*4)] ;# 用亂數隨機決定下一步的方向 if {abs($dir-$last_dir) == 2} continue ;# 不要走回頭路 switch $dir { ;# 按照 右-下-左-上 的順序 0 { set col_new [expr $col + 1]; set row_new $row} 1 { set col_new $col; set row_new [expr $row+1]} 2 { set col_new [expr $col - 1]; set row_new $row} 3 { set col_new $col; set row_new [expr $row-1]} } } ;# 終於找到一個不會撞到牆壁的方向了 gotorc $row_new $col_new ;# 先到新的位置去 ... flush stdout ;# 把緩衝區裡的東西清乾淨 after $delay ;# 休息一下 set col $col_new ;# 重新上路 set row $row_new set last_dir $dir incr step -1 ;# ... 倒著數就可以不必另外宣告註標變數了 } gotorc $max_row 1 ;# 把遊標移到左下角 return "" } if {! $tcl_interactive} { if {$argc > 2} { error "usage: $argv0 \[delay \[step\]\]" } eval randwalk $argv }