bash 做了个贪吃蛇

sh/bash/dash/ksh/zsh等Shell脚本
头像
O_O_BOT
帖子: 2461
注册时间: 2009-05-20 19:32

bash 做了个贪吃蛇

#1

帖子 O_O_BOT » 2009-08-11 17:52

没什么事做了个贪吃蛇

代码: 全选

#!/bin/bash
#O_O learn2
#fvw vimtexhappy@gmail.com
#setting
game_with=15
game_height=25
game_top=2
game_left=10
game_no_wall=1

#tmp
game_id=0
game_sig=0
game_start=0

#Signal
sig_up=25
sig_left=26
sig_right=27
sig_down=28
sig_exit=30

#direction
dirt_up=0
dirt_down=1
dirt_left=2
dirt_right=3

#map data
var_init(){
    usr_level=0
    usr_score=0

    snake_color=4
    snake_head=0
    snake_end=0
    snake_len=1
    snake_cur_x=0
    snake_cur_y=0
    snake_move_dirt=0

    dot_color=3
    dot_cur_x=0
    dot_cur_y=0
}

show_frame() {
    #make game frame
    local i x1 x2 y1 y2
    ((x1 = game_left))
    ((y1 = game_top))
    ((y2 = game_top+game_height+1))
    for ((i=0; i<game_with+2; i++));do
        echo -ne "\033[$y1;${x1}H\033[44;32m==\033[0m"
        echo -ne "\033[$y2;${x1}H\033[44;32m==\033[0m"
        ((x1 += 2))
    done

    ((x1 = game_left))
    ((x2 = game_left+game_with*2+2))
    ((y1 = game_top+1))
    for ((i=0; i<game_height; i++));do
        echo -ne "\033[$y1;${x1}H\033[44;32m||\033[0m"
        echo -ne "\033[$y1;${x2}H\033[44;32m||\033[0m"
        ((y1++))
    done
}

show_txt() {
    local x y 
    local score level
    score=${1:-$usr_score}
    level=${2:-$usr_level}
    ((x = game_left + game_with*2 + 4 + 6))
    ((y = game_top + game_height/3))
    echo -ne "\033[${y};${x}H\033[40;36mScore\033[0m"
    ((y++))
    echo -ne "\033[${y};${x}H\033[40;37m${score}\033[0m"
    ((y+=2))
    echo -ne "\033[${y};${x}H\033[40;36mLevel\033[0m"
    ((y++))
    echo -ne "\033[${y};${x}H\033[40;37m${level}\033[0m"
}

show_end_text(){
    local x y
    len=${#1}
    ((x = game_left + game_with-len/2))
    ((y = game_top + game_height/2 - 1))
    echo -ne "\033[${y};${x}H$1"
    game_start=0
}

show_dot() {
    local show index x y color
    show=$1
    x=${2:-$snake_cur_x}
    y=${3:-$snake_cur_y}
    color=${4:-$snake_color}
    ((x= game_left + 2 + x* 2 ))
    ((y= game_top + 1 + y))
    echo -ne "\033[${y};${x}H"
    if (($show == 1)); then
        echo -ne "\033[1;7;4${color};3${color}m[]\033[0m"
    else
        echo -ne "  "
    fi
}

make_map() {
    local i x y
    ((x = game_left + 2))
    ((y = game_top + 1))
    for ((i=0; i<game_height; i++));do
        echo -ne "\033[$((y+i));${x}H"
        for ((j=0; j<game_with; j++));do
            echo -ne "  "
        done
    done
    snake_color=4
    snake_head=0
    snake_end=0
    snake_len=1
    ((snake_cur_x=RANDOM%(game_with/2)+game_with/4))
    ((snake_cur_y=RANDOM%(game_height/2)+game_height/4))
    snakes=($snake_cur_x $snake_cur_y)
    ((snake_move_dirt=RANDOM % 4))
    show_dot 1
}

dot_new(){
    local dot_x dot_y
    local max_try i
    max_try=200
    while ((max_try--));do
        ((dot_x=RANDOM%game_with))
        ((dot_y=RANDOM%game_height))
        for ((i=snake_end; i<=snake_head; i+=2));do
            ((snakes[i]==dot_x && snakes[i+1]==dot_y)) && break
        done
        ((i>snake_head)) && break 
    done
    if ((max_try>=0));then
        dot_cur_x=$dot_x
        dot_cur_y=$dot_y
        show_dot 1 $dot_x $dot_y $dot_color
    else
        show_end_text "Very good!"
    fi
}

snake_go() {
    local go_x go_y
    go_x=$snake_cur_x
    go_y=$snake_cur_y
    try_move=$1
    case $try_move in
        $dirt_up) ((go_y--));;
        $dirt_down) ((go_y++));;
        $dirt_left) ((go_x--));;
        $dirt_right) ((go_x++));;
    esac
    if ((snake_len != 1)) && ((snakes[snake_head-2]==go_x && snakes[snake_head-1]== go_y));then
        #don't move
        return
    fi
    #hold move dirt
    snake_move_dirt=$try_move
    if ((game_no_wall == 1));then
        ((go_x<0)) && ((go_x+=game_with))
        ((go_x>=game_with)) && ((go_x-=game_with))
        ((go_y<0)) && ((go_y+=game_height))
        ((go_y>=game_height)) && ((go_y-=game_height))
    else
        if ((go_x<0 || go_x>=game_with || go_y<0 || go_y>=game_height));then
            show_end_text "Game over!"
            return
        fi
    fi

    #local i index
    ##snake_end over max->0 is ok too.
    #((index=snake_end))
    #for ((i=0; i<snake_len; i++));do
        #((snakes[index]==go_x && snakes[index+1]==go_y)) && break
        #((index+=2))
    #done
    #if ((i<snake_len));then
        #show_end_text "Game over!"
        #return
    #fi
    #array index very long 2^6x
    local i
    for ((i=snake_end; i<=snake_head; i+=2));do
        ((snakes[i]==go_x && snakes[i+1]==go_y)) && break
    done
    if ((i<=snake_head));then
        show_end_text "Game over!"
        return
    fi
    ((snake_head+=2))
    snakes[snake_head]=$go_x
    snakes[snake_head+1]=$go_y
    snake_cur_x=$go_x
    snake_cur_y=$go_y
    show_dot 1
    if ((go_x == dot_cur_x && go_y == dot_cur_y));then
        ((snake_len++))
        ((usr_score++))
        ((usr_level=usr_score/10))
        ((usr_level>20)) && ((usr_level=20))
        show_txt
        dot_new
    else
        show_dot 0 ${snakes[$snake_end]} $((snakes[snake_end+1]))
        unset snakes[snake_end]
        unset snakes[$((snake_end+1))]
        ((snake_end+=2))
    fi
}

init_game(){
    clear
    var_init
    show_frame
    show_txt 
    make_map
    dot_new
}

exit_game(){
    exit 0
}


game_routine(){
    local i
    trap "game_sig=$sig_down"    $sig_down
    trap "game_sig=$sig_left"    $sig_left
    trap "game_sig=$sig_right"   $sig_right
    trap "game_sig=$sig_up"      $sig_up
    trap "game_sig=$sig_exit"    $sig_exit
    init_game
    while ((game_sig == 0));do
        sleep 0.02
    done
    game_start=1
    while :;do
        while ((game_start));do
            for ((i=20-usr_level; i>=0; i--));do
                case $game_sig in
                    $sig_down ) snake_go $dirt_down;;
                    $sig_left ) snake_go $dirt_left;;
                    $sig_right) snake_go $dirt_right;;
                    $sig_up   ) snake_go $dirt_up;;
                    $sig_exit ) exit_game;;
                esac
                if ((game_sig != 0));then
                    game_sig=0
                    break
                fi
                sleep 0.02
            done
            if ((i<0));then
                snake_go $snake_move_dirt
            fi
        done
        while ((game_sig == 0));do
            sleep 0.02
        done
        game_start=1
        init_game
    done
}


key_exit(){
    stty $tty
    echo -ne "\033[?25h"
    kill -$sig_exit $game_pid
    clear
    exit
}

key_rountine(){
    game_pid=$1
    tty=$(stty -g)
    echo -ne "\033[?25l"
    trap "key_exit;" INT TERM
    trap "key_exit;" $sig_exit

    local key keys sig
    local ESC 
    #ESC=$(echo -ne "\033")
    ESC=$'\033'
    keys=(0 0 0)
    while :;do
        sig=0
        read -s -n 1 key
        keys[0]=${keys[1]}
        keys[1]=${keys[2]}
        keys[2]=$key
        if [[ ${keys[0]} == $ESC && ${keys[1]} == "[" ]] ;then
            case ${keys[2]} in
                "A") sig=$sig_up;;
                "B") sig=$sig_down;;
                "D") sig=$sig_left;;
                "C") sig=$sig_right;;
            esac
        elif [[ ${keys[2]} == "q" ]];then
            key_exit 
        fi
        if (($sig != 0));then
            kill -$sig $1
        fi
    done
}

if [ "$1" == "game" ] ;then
    game_routine
else
    bash $0 game &
    key_rountine $!
fi

附件
2009-08-11-17-53-45.png
2009-08-11-17-53-45.png (6.37 KiB) 查看 2441 次
上次由 O_O_BOT 在 2009-08-19 17:59,总共编辑 5 次。
irc 聊天室
ubuntu-cn 的irc 频道为
irc.ubuntu.com 8001 #ubuntu-cn
UTF8编码 可用 irssi xchat pidgin weechat 登录

http://webchat.freenode.net/?channels=ubuntu-cn
[url]irc://irc.freenode.net/ubuntu-cn[/url]
tune
帖子: 135
注册时间: 2009-04-28 21:47

Re: bash 做了个贪吃蛇

#2

帖子 tune » 2009-08-11 17:53

顶起 :em04
头像
leeaman
帖子: 30702
注册时间: 2007-02-02 18:14
系统: debian sid

Re: bash 做了个贪吃蛇

#3

帖子 leeaman » 2009-08-11 17:54

作者是...
醉了星星,醉月亮●●●●●The Long Way To Go(*^_^*)
tune
帖子: 135
注册时间: 2009-04-28 21:47

Re: bash 做了个贪吃蛇

#4

帖子 tune » 2009-08-11 17:58

执行不了??
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: bash 做了个贪吃蛇

#5

帖子 xiooli » 2009-08-11 17:58

收藏。很有那个bash 俄罗斯方块的风格。
头像
O_O_BOT
帖子: 2461
注册时间: 2009-05-20 19:32

Re: bash 做了个贪吃蛇

#6

帖子 O_O_BOT » 2009-08-11 18:03

就是看了那个学的
irc 聊天室
ubuntu-cn 的irc 频道为
irc.ubuntu.com 8001 #ubuntu-cn
UTF8编码 可用 irssi xchat pidgin weechat 登录

http://webchat.freenode.net/?channels=ubuntu-cn
[url]irc://irc.freenode.net/ubuntu-cn[/url]
头像
nuanhuai
帖子: 7813
注册时间: 2009-03-10 13:04

Re: bash 做了个贪吃蛇

#7

帖子 nuanhuai » 2009-08-11 18:08

BOT发贴~~~~~~~
头像
careone
帖子: 839
注册时间: 2007-12-17 21:41

Re: bash 做了个贪吃蛇

#8

帖子 careone » 2009-08-11 18:51

运行方法:
1 把楼主的代码,另存为 /usr/games/snake.sh 文件

代码: 全选

sudo gedit /usr/games/snake.sh&
2 新建一个 /usr/games/snake 文件,用于在终端启动游戏

代码: 全选

sudo gedit /usr/games/snake&
文件内容如下

代码: 全选

#! /bin/sh
gnome-terminal -x /usr/games/snake.sh
3 给这两个文件执行权限

代码: 全选

sudo chmod -v 755 /usr/games/snake.sh
sudo chmod -v 755 /usr/games/snake
4 运行方式:
* 直接以普通用户(不要用 root用户)运行 snake 命令;
* 在终端中运行 snake 或 snake.sh 命令均可;
* 如果非要以 root 用户运行也是可以的,但要输入完整路径

代码: 全选

/usr/games/snake
魁拔不死,天下不宁。
魁拔既死,天下不平。
--------------
Careone <emacslocale^126.com>
https://sourceforge.net/projects/emacslocale/files/
wyddr
帖子: 38
注册时间: 2008-07-25 22:04

Re: bash 做了个贪吃蛇

#9

帖子 wyddr » 2009-08-11 18:56

:em66
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: bash 做了个贪吃蛇

#10

帖子 eexpress » 2009-08-11 20:14

记得看到过。
● 鸣学
头像
dengroj
帖子: 39
注册时间: 2009-06-06 8:57

Re: bash 做了个贪吃蛇

#11

帖子 dengroj » 2009-08-11 22:55

你好强。。我严重顶你。。。。 :em11
本人花580元从国嵌淘宝店上购买的正版,现在尝试创业,低价转让。qq:1531267696
头像
O_O_BOT
帖子: 2461
注册时间: 2009-05-20 19:32

Re: bash 做了个贪吃蛇

#12

帖子 O_O_BOT » 2009-08-11 22:56

看了那个俄罗斯方块弄得
irc 聊天室
ubuntu-cn 的irc 频道为
irc.ubuntu.com 8001 #ubuntu-cn
UTF8编码 可用 irssi xchat pidgin weechat 登录

http://webchat.freenode.net/?channels=ubuntu-cn
[url]irc://irc.freenode.net/ubuntu-cn[/url]
expipi
帖子: 27
注册时间: 2008-04-15 14:57
来自: sdust.B14.603

Re: bash 做了个贪吃蛇

#13

帖子 expipi » 2009-08-11 23:06

学习了 呵呵 :em11
头像
dengroj
帖子: 39
注册时间: 2009-06-06 8:57

Re: bash 做了个贪吃蛇

#14

帖子 dengroj » 2009-08-11 23:08

careone 写了:运行方法:
1 把楼主的代码,另存为 /usr/games/snake.sh 文件

代码: 全选

sudo gedit /usr/games/snake.sh&
2 新建一个 /usr/games/snake 文件,用于在终端启动游戏

代码: 全选

sudo gedit /usr/games/snake&
文件内容如下

代码: 全选

#! /bin/sh
gnome-terminal -x /usr/games/snake.sh
3 给这两个文件执行权限

代码: 全选

sudo chmod -v 755 /usr/games/snake.sh
sudo chmod -v 755 /usr/games/snake
4 运行方式:
* 直接以普通用户(不要用 root用户)运行 snake 命令;
* 在终端中运行 snake 或 snake.sh 命令均可;
* 如果非要以 root 用户运行也是可以的,但要输入完整路径

代码: 全选

/usr/games/snake
第一步,我就不行了。。
本人花580元从国嵌淘宝店上购买的正版,现在尝试创业,低价转让。qq:1531267696
头像
wangdu2002
帖子: 13284
注册时间: 2008-12-13 19:39
来自: 物华天宝人杰地灵

Re: bash 做了个贪吃蛇

#15

帖子 wangdu2002 » 2009-08-11 23:08

顶之。 :em11
行到水穷处,坐看云起时。
海内生明月,天涯共此夕。
--------------------吾本独!
回复