44、探索Shell脚本的奇妙应用:太空游戏与HTML解析

探索Shell脚本的奇妙应用:太空游戏与HTML解析

在计算机编程的世界里,Shell脚本有着独特的魅力和广泛的用途。今天,我们将深入探讨两个有趣的Shell脚本应用:太空游戏和HTML解析。

太空游戏:一场刺激的星际对抗

这个太空游戏脚本为我们展示了如何利用Shell脚本创建一个交互式的游戏体验。以下是这个游戏的详细介绍:

游戏规则与控制
  • 控制方式 :玩家可以通过键盘上的特定按键来控制飞船的移动和射击。具体按键如下:
    • 向左移动:按下 a 键。
    • 向右移动:按下 l 键。
    • 发射激光:按下 f 键。
    • 退出游戏:按下 q 键。
  • 游戏目标 :玩家需要操控飞船,发射激光消灭不断移动的外星飞船。如果外星飞船到达飞船所在的位置,游戏失败;如果成功消灭所有外星飞船,玩家获胜。
代码实现与关键函数

以下是完整的游戏代码:

#!/bin/bash
stty -echo
# Make the cursor invisible (man terminfo)
tput civis
clear
cat - << EOF
           SPACE
   LEFT:      a
   RIGHT:     l
   FIRE:      f
   QUIT:      q
                            Press any key.
EOF
read -s -n 1
row0=( 0 30 30 30 30 30 30 30 30 )
row1=( 0 20 20 20 20 20 20 20 20 )
row2=( 0 15 15 15 15 15 15 15 15 )
row3=( 0 10 10 10 10 10 10 10 10 )
row4=( 0 5 5 5 5 5 5 5 5 )
row5=( 0 1 1 1 1 1 1 1 1 )
aliens1=( ‘\033[1;32m|0|\033[0m’ ‘\033[1;34m\-/\033[0m’
          ‘\033[1;35m:x:\033[0m’ ‘\033[1;38m:#:\033[0m’
          ‘\033[1;33m!|!\033[0m’ ‘\033[1;39m:-:\033[0m’ )
aliens2=( ‘\033[1;32m:0:\033[0m’ ‘\033[1;34m/-\\\033[0m’
          ‘\033[1;35m-x-\033[0m’ ‘\033[1;38m-#-\033[0m’
          ‘\033[1;33m:|:\033[0m’ ‘\033[1;39m-:-\033[0m’ )
score=0
# farthest right that the *leftmost* alien can go to
MAXRIGHT=46
# furthest right that the ship can go to
FARRIGHT=73
# Ship’s current position (x-axis)
ship=30
# Cannon column; remains the same even if ship moves
cannonX=$ship
# Cannon height; 0 means it’s ready to fire
cannonY=0
# Positive direction to right, Negative to left
direction=1
offset=20
bottom=20
ceiling=4
MAXCEILING=6
DELAY=0.4
function drawrow
{
  # draw a row of aliens; return the index of any alien killed
  # note that only one alien can be killed at any time.
  alientype=$1
  shift
  let row=”$alientype * 2 + $ceiling”
  aliensonrow=`echo $@ | tr ‘ ‘ ‘+’ | bc`
  if [ $aliensonrow -eq 0 ]; then
    # Nothing to do here. In particular, do not detect failure.
    # Just clear the previous line (it may contain the final explosion
    # on that row) and return.
    tput cup $row 0
    printf “%80s” “ “
    return 0
  fi
  if [ $row -eq $bottom ]; then
    tput cup `expr $bottom - 4` 6
    trap exit ALRM
    echo “YOU LOSE”
    sleep $DELAY
    stty echo
    tput cvvis
    exit 1
  fi
  declare -a thisrow
  thisrow=( `echo $@` )
  tput cup 0 0
  printf “Score: %-80d” $score
  killed=0
  # Clear the previous line
  tput cup `expr $row - 1` 0
  printf “%80s” “ “
  tput cup $row 0
  printf “%80s” “ “
  tput cup $row 0
  printf “%-${offset}s”
  # Don’t do this calculation in the for loop, it is slow even without expr
  if (( $offset % 2 == 0 )); then
    thisalien=${aliens1[$alientype]}
  else
    thisalien=${aliens2[$alientype]}
  fi
  # there are 8 aliens per row.
  for i in `seq 1 8`
  do
    value=${thisrow[$i]}
    avatar=$thisalien
    if [ $value -gt 0 ]; then
      # detect and mark a collision
      if [ $row -eq $cannonY ]; then
        let LEFT=”$i * 4 + $offset - 4”
        let RIGHT=”$i * 4 + $offset - 1”
        if [ $cannonX -ge $LEFT ] && [ $cannonX -le $RIGHT ]; then
          killed=$i
          avatar=’\033[1;31m***\033[0m’
          ((score=$score + $value))
          cannonY=0
        fi
      fi
    fi
    if [ $value -eq 0 ]; then
      printf “    “
    else
        echo -en “${avatar} “
    fi
  done
  return $killed
}
function drawcannon
{
  # move the cannon up one
  if [ $cannonY -eq 0 ]; then
    # fell off the top of the screen
    return
  fi
  tput cup $cannonY $cannonX
  printf “ “
  ((cannonY=cannonY-1))
  tput cup $cannonY $cannonX
  echo -en “\033[1;31m*\033[0m”
}
function drawship
{
  tput cup $bottom 0
  printf “%80s” “ “
  tput cup $bottom $ship
  # Show cannon state by its color in the spaceship
  if [ $cannonY -eq 0 ]; then
    col=31
  else
    col=30
  fi
  echo -en “|--\033[1;${col}m*\033[0m--|”
}
function move
{
  # shift aliens left or right
  # move cannon, check for collision
  (sleep $DELAY && kill -ALRM $$) &
  # Change direction if hit the side of the screen
  if [ $offset -gt $MAXRIGHT ] && [ $direction -eq 1 ]; then
    # speed up if hit the right side of the screen
    DELAY=`echo $DELAY \* 0.90 | bc`
    direction=-1
    ((ceiling++))
  elif [ $offset -eq 0 ] && [ $direction -eq -1 ]; then
    direction=1
  fi
  ((offset=offset+direction))
  drawrow 0 ${row0[@]}
  row0[$?]=0
  drawrow 1 ${row1[@]}
  row1[$?]=0
  drawrow 2 ${row2[@]}
  row2[$?]=0
  drawrow 3 ${row3[@]}
  row3[$?]=0
  drawrow 4 ${row4[@]}
  row4[$?]=0
  drawrow 5 ${row5[@]}
  row5[$?]=0
  aliensleft=`echo ${row0[@]} ${row1[@]} ${row2[@]} ${row3[@]}\
         ${row4[@]} ${row5[@]} \
      | tr ‘ ‘ ‘+’ | bc`
  if [ $aliensleft -eq 0 ]; then
    tput cup 5 5
    trap exit ALRM
    echo “YOU WIN”sleep $DELAY    tput echo
    tput cvvis
    echo; echo; echo
    exit 0
  fi
  drawcannon
  drawship
}
trap move ALRM
clear
drawship
# Start the aliens moving...
move
while :
do
  read -s -n 1 key
  case “$key” in
    a)
       [ $ship -gt 0 ] && ((ship=ship-1))
        drawship
        ;;
    l)
       [ $ship -lt $FARRIGHT ] && ((ship=ship+1))
        drawship
        ;;
    f)
        if [ $cannonY -eq 0 ]; then
          let cannonX=”$ship + 3”
          cannonY=$bottom
        fi
        ;;
    q)
        echo “Goodbye!”
        tput cvvis
        stty echo
        trap exit ALRM
        sleep $DELAY
        exit 0
        ;;
  esac
done

关键函数解释:
- drawrow 函数 :用于绘制一行外星飞船,并检测是否有外星飞船被激光击中。如果有外星飞船被击中,返回其在数组中的索引。
- drawcannon 函数 :控制激光的移动,将激光向上移动一格。
- drawship 函数 :绘制飞船,并根据激光的状态显示不同颜色的激光指示器。
- move 函数 :控制外星飞船的左右移动,调用 drawrow 函数绘制外星飞船,检测是否有外星飞船被击中,并更新游戏状态。

游戏流程

下面是游戏的主要流程:

graph TD;
    A[开始游戏] --> B[初始化游戏参数];
    B --> C[显示游戏界面];
    C --> D[等待玩家输入];
    D --> E{输入是否为退出?};
    E -- 是 --> F[退出游戏];
    E -- 否 --> G{输入是否为移动?};
    G -- 是 --> H[更新飞船位置并绘制];
    G -- 否 --> I{输入是否为发射?};
    I -- 是 --> J[发射激光并更新状态];
    I -- 否 --> D;
    H --> D;
    J --> D;
    D --> K[移动外星飞船并检测碰撞];
    K --> L{是否有外星飞船到达底部?};
    L -- 是 --> M[游戏失败,退出游戏];
    L -- 否 --> N{是否所有外星飞船被消灭?};
    N -- 是 --> O[游戏胜利,退出游戏];
    N -- 否 --> D;
HTML解析:提取链接并下载页面

除了太空游戏,我们还将介绍一个用于解析HTML文件并提取链接的脚本。这个脚本可以帮助我们从HTML文件中提取所有链接,并将链接对应的页面下载到本地。

解析原理与关键概念
  • HTML术语 :在HTML中, <a> 标签用于定义超链接。例如, <a href="/eg.shtml">example pages</a> 中, /eg.shtml 是链接, example pages 是锚文本。
  • 状态机 :脚本使用一个简单的状态机来跟踪解析过程中的状态。通过状态机,脚本可以准确地识别链接和锚文本。
代码实现与操作步骤

以下是完整的HTML解析脚本:

#!/bin/bash
INFILE=${1:-${HOME}/.mozilla/firefox/*/bookmarks.html}
state=
link=
download=/tmp/download
mkdir -p “$download” 2>/dev/null
BASE_URL=http://steve-parker.org
cat $INFILE | \
    tr ‘\n’ ‘ ‘ | tr ‘<’ ‘\n’ | tr ‘>’ ‘\n’ | tr ‘\t’ ‘ ‘ | tr -s ‘ ‘  | \
    while read tag label
do
  if [ “$state” == “anchor” ] && [ ! -z “$tag” ]; then
    if [ “$tag” == “img” ]; then
      label=
    fi
    if [ -z “$label” ]; then
      filename=$tag
    else
      filename=”$tag $label”
    fi
    origname=$filename
    suffix=1
    while [ -f “${download}/${filename}” ]
    do
      filename=”${origname}.${suffix}”
      ((suffix++))
    done
    echo “Retrieving $link as $filename”
   # Prepend BASE_URL if not otherwise valid
   firstchar=`echo $link | cut -c1`
   case “$firstchar” in
     “/”) link=${BASE_URL}$link ;;
     “#”) link=${BASE_URL}/$link ;;
   esac
    wget -O “${download}/${filename}” “$link” > /tmp/wget.$$ 2>&1
    if [ “$?” -eq “0” ]; then
      ls -ld “${download}/${filename}”
    else
      echo “Retrieving $link failed.”
      cat /tmp/wget.$$
    fi
    state=
  else
    if [ “$tag” == “A” ] || [ “$tag” == “a” ]; then
      # Only do this if not already in an anchor;
      #  <a href=”#”>a href</a> is valid!
      if [ “$state” != “anchor” ]; then
        link=`echo $label| grep -i “href=” |tr [:blank:] ‘\n’| \
            grep -io “href.*”|cut -c6- | tr -d ‘“‘ |tr -d “‘“`
        [ ! -z “$link” ] && state=anchor
      fi
    fi
  fi
done
rm /tmp/wget.$$ 2>/dev/null

操作步骤如下:
1. 准备HTML文件 :可以使用默认的Firefox书签文件,也可以提供自定义的HTML文件作为输入。
2. 运行脚本 :在终端中运行脚本,指定HTML文件的路径。例如:

./downloader.sh eg.html
  1. 查看下载结果 :脚本会将提取的链接对应的页面下载到 /tmp/download 目录下,并根据锚文本命名文件。
解析流程

下面是HTML解析的主要流程:

graph TD;
    A[开始解析] --> B[读取HTML文件];
    B --> C[处理HTML文本,转换为单行并分割标签];
    C --> D[逐行读取处理后的文本];
    D --> E{当前行是否为 <a> 标签?};
    E -- 是 --> F{是否已经在处理锚文本?};
    F -- 否 --> G[提取链接并设置状态为锚文本];
    F -- 是 --> D;
    E -- 否 --> H{当前状态是否为锚文本?};
    H -- 是 --> I{标签是否为 img?};
    I -- 是 --> J[设置文件名前缀为 img];
    I -- 否 --> K[设置文件名];
    J --> L[检查文件名是否已存在];
    K --> L;
    L -- 是 --> M[生成新的文件名];
    L -- 否 --> N[使用当前文件名];
    M --> N;
    N --> O[下载链接对应的页面];
    O --> P{下载是否成功?};
    P -- 是 --> Q[显示文件信息];
    P -- 否 --> R[显示错误信息];
    Q --> S[重置状态];
    R --> S;
    S --> D;
    H -- 否 --> D;
    D --> T[解析结束];

通过这两个示例,我们可以看到Shell脚本在创建交互式应用和数据处理方面的强大能力。无论是开发简单的游戏,还是解析复杂的HTML文件,Shell脚本都能发挥重要作用。希望这些内容能激发你对Shell脚本编程的兴趣,探索更多有趣的应用场景。

探索Shell脚本的奇妙应用:太空游戏与HTML解析

太空游戏与HTML解析的技术细节分析
太空游戏技术细节
  • 数组的使用 :在太空游戏中,使用了多个数组来存储外星飞船的信息。例如, row0 row5 数组分别存储了每一行外星飞船的分值, aliens1 aliens2 数组存储了不同样式的外星飞船图标。通过数组,我们可以方便地管理和更新外星飞船的状态。
  • 状态管理 :游戏中使用了多个变量来管理游戏状态,如 score 记录玩家得分, ship 记录飞船的位置, cannonX cannonY 记录激光的位置。这些变量的合理使用使得游戏逻辑清晰,易于维护。
  • 碰撞检测 :在 drawrow 函数中,通过比较激光的位置和外星飞船的位置,实现了碰撞检测。当激光与外星飞船重叠时,将外星飞船标记为被击中,并更新玩家得分和游戏状态。
HTML解析技术细节
  • 文本处理 :脚本使用了多个 tr 命令对HTML文本进行处理,将换行符、 < > 符号转换为换行符,将制表符转换为空格,并压缩连续的空格。这样处理后,HTML文本被分割成多行,便于逐行解析。
  • 状态机的实现 :通过 state 变量实现了一个简单的状态机,用于跟踪解析过程中的状态。当遇到 <a> 标签时,将状态设置为 anchor ,表示正在处理锚文本;当处理完锚文本后,将状态重置。
  • 链接提取与下载 :在解析过程中,通过 grep cut 命令提取链接,并使用 wget 命令下载链接对应的页面。同时,脚本还处理了文件名冲突的问题,确保每个下载的文件都有唯一的文件名。
应用场景与拓展思路
太空游戏的应用场景与拓展
  • 教育用途 :太空游戏可以作为编程教育的示例,帮助初学者理解变量、函数、循环和条件语句的使用。通过修改游戏代码,学生可以学习如何实现不同的游戏规则和功能。
  • 拓展功能 :可以对太空游戏进行拓展,增加更多的关卡、道具和敌人类型。例如,添加不同速度和移动方式的外星飞船,或者增加护盾、加速道具等。
HTML解析的应用场景与拓展
  • 数据采集 :HTML解析脚本可以用于采集网页上的信息,如新闻文章、商品信息等。通过提取链接并下载页面,可以将网页内容保存到本地,方便后续分析和处理。
  • 拓展功能 :可以对HTML解析脚本进行拓展,支持解析其他类型的标签,如 <img> 标签用于提取图片链接, <script> 标签用于提取脚本链接。同时,可以增加对链接的过滤和筛选功能,只下载符合特定条件的页面。
总结与展望

通过太空游戏和HTML解析这两个示例,我们展示了Shell脚本在交互式应用和数据处理方面的强大能力。Shell脚本不仅可以用于简单的系统管理任务,还可以开发出复杂的应用程序。

在未来的开发中,我们可以进一步探索Shell脚本的更多功能和应用场景。例如,结合其他工具和技术,如数据库、网络编程等,开发出更加复杂和实用的应用程序。同时,我们也可以关注Shell脚本的性能优化和安全性问题,确保开发出的应用程序高效、稳定和安全。

希望本文能够激发你对Shell脚本编程的兴趣,让你在编程的道路上不断探索和创新。如果你对本文中的内容有任何疑问或建议,欢迎留言讨论。

以下是一个总结表格,对比了太空游戏和HTML解析的关键信息:
| 项目 | 太空游戏 | HTML解析 |
| — | — | — |
| 功能 | 创建交互式太空游戏 | 解析HTML文件并下载链接页面 |
| 关键技术 | 数组、状态管理、碰撞检测 | 文本处理、状态机、链接提取与下载 |
| 应用场景 | 教育、娱乐 | 数据采集、信息提取 |
| 拓展方向 | 增加关卡、道具和敌人类型 | 支持更多标签解析、增加链接过滤功能 |

通过这个表格,我们可以更清晰地看到太空游戏和HTML解析的异同点,以及它们的应用场景和拓展方向。

源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值