推箱子游戏

使用C来实现一个简单的推箱子游戏..

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main(){
    char a[50][50]={
    "   ###     ",
    "   #*#     ",
    "   # #     ",
    "####O######",
    "#*  OS O *#",
    "#####O#####",
    "    # #    ",
    "    #*#    ",
    "    ###    ",
    };

    int i,f=0; //控制变量 
    int x=4,y=5; //控制点坐标 

    char ch; //定义控制输入端

    //打印输出地图
    for(i=0;i<12;i++){
        puts(a[i]);
    }
    puts("游戏尚未开始,请按键……");

    //f标记值0.1.2.3共计4次循环 
    while(f<4)//开始循环
    {
        ch=getch();

        if(ch=='s') //按下s键
        { 
            if(a[x+1][y]!='#'&&a[x+1][y]!='@')//未碰墙未达目的地 
            {
                if(a[x+1][y]!='O') //前面没有O的时候 
                {
                    a[x][y]=' ';    //现坐标为空 
                    x++;            //x坐标向下移动一位 
                    a[x][y]='S';    //新坐标标记为S 
                }
                else    //前面有O标记时 
                {
                    if(a[x+2][y]!='#')  //前面两坐标有墙 
                    {
                        if(a[x+2][y]!='*')  //O前面没有目的地时 
                        {
                            a[x][y]=' ';    //现坐标为空     
                            x++;            //x坐标向下移动 
                            a[x][y]='S';    //新坐标标记为S 
                            a[x+1][y]='O';  //前面一个坐标为O 
                        }
                        else    //O前面有目的地坐标时 
                        {
                            a[x][y]=' ';    //现坐标为空 
                            x++;            //x坐标向下移动 
                            a[x][y]='S';    //新坐标标记为S 
                            a[x+1][y]='@';  //目的地坐标改为@ 
                            f=f+1;          //f标记值增加1 
                        }
                    }
                }
            }
        }

        if(ch=='w') //按下w键
        { 
            if(a[x-1][y]!='#'&&a[x-1][y]!='@')
            {
                if(a[x-1][y]!='O') 
                {
                    a[x][y]=' ';
                    x--;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x-2][y]!='#')
                    {
                        if(a[x-2][y]!='*')
                        {
                            a[x][y]=' ';                            
                            x--;
                            a[x][y]='S';
                            a[x-1][y]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            x--;
                            a[x][y]='S';
                            a[x-1][y]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

        if(ch=='d') //按下d键
        { 
            if(a[x][y+1]!='#'&&a[x][y+1]!='@')
            {
                if(a[x][y+1]!='O') 
                {
                    a[x][y]=' ';
                    y++;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x][y+2]!='#')
                    {
                        if(a[x][y+2]!='*')
                        {
                            a[x][y]=' ';                            
                            y++;
                            a[x][y]='S';
                            a[x][y+1]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            y++;
                            a[x][y]='S';
                            a[x][y+1]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

        if(ch=='a') //按下a键
        { 
            if(a[x][y-1]!='#'&&a[x][y-1]!='@')
            {
                if(a[x][y-1]!='O') 
                {
                    a[x][y]=' ';
                    y--;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x][y-2]!='#')
                    {
                        if(a[x][y-2]!='*')
                        {
                            a[x][y]=' ';                            
                            y--;
                            a[x][y]='S';
                            a[x][y-1]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            y--;
                            a[x][y]='S';
                            a[x][y-1]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

    system("cls"); //清屏
    for(i=0;i<12;i++)
        {
        //输出变量变更之后的地图 
        puts(a[i]);
        }
    printf("\n已达成:%d 颗星。",f);
    }


    Sleep(500);  
    system("cls"); //清屏
    puts("恭喜,你赢了!");
    return 0;
} 

Shell的循环与函数函数

循环结构


for循环

语法结构以及特点

for 变量名 in 值列表
do
    命令序列
done

for循环的执行流程

脚本应用示例

C语言风格的for循环 cfor.sh

#!/bin/bash
for ((i=1;i<=5;i+=2))
do
    echo $i
done

chkhosts.sh
批量检测多个主机的存活状态:
1. 多个目标IP地址,存放在ipadds.txt;
2. ping检测;
3. 脚本遍历主机,并反馈存活状态;

#!/bin/bash
HLIST=$(cat ./ipadds.txt)
for IP in $HLIST
do
        ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
        if [ $? -eq 0 ] ;then
                echo "Host $IP is up."
        else
                echo "Host $IP is down."
        fi
done

while循环

语法结构以及特点

while 条件测试
do
    命令序列
done

while循环的执行流程

脚本应用示例

检测192.168.4.0/24网段,列出不在线的主机地址
whilechkhosts.sh

#!/bin/bash
PREFIX="192.168.4." ; i=0
while [ $i -le 255 ]
do
        IP=${PREFIX}$i
        ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
        if [ $? -eq 0 ];then
                echo "Host $IP  is up."
        else
                echo "Host $IP is down."
        fi
        let i++
done

服务脚本设计

case分支结构

语法结构以及特点

case 变量值 in
模式1)
    命令序列1 ;;
模式2)
    命令序列2 ;;
 .......
*)
    默认命令序列 ;;
esac

case分支的执行流程

脚本应用示例

判断用户输入键位类型
hitkey.sh

#!/bin/bash
read -p "请输入一个字符: " KEY
case "$KEY" in
        [a-z]|[A-Z])
                echo "字母。 " ;;
        [0-9])
                echo "数字。 " ;;
        *)
                echo "空格、功能键或者其他控制字符。"
        esac

编写服务脚本

系统服务控制

  • 查看服务列表、自启状态 chkconfig
  • 服务控制 service、/etc/init.d/服务名

服务脚本的case分支用法

自建系统服务

?????


函数以及中断控制

shell函数

关于函数的认识

  • 将一些需要重复使用的操作定义为公共的语句块,即可成为函数;
  • 使脚本代码简洁、增强易读性;
  • 提高效率

函数的定义与调用

function 函数名{
    命令序列
    ......
}

  • 调用已定义的函数
  • 函数传值

函数应用示例

针对给定两个整数,依次负责加减乘除结果并输出。
funexpr.sh

#!/bin/bash
myexpr(){
        echo "$1 + $2 = $[$1 + $2]"
        echo "$1 - $2 = $[$1 - $2]"
        echo "$1 * $2 = $[$1 * $2]"
        echo "$1 / $2 = $[$1 / $2]"
}
myexpr $1 $2

中断以及退出

中断/退出以及相关指令

  • 中断 break
  • 继续 continue
  • 退出 exit

脚本中断示例

脚本退出示例

Shell运算与if结构

整数运算


基本运算类别

  • 四则运算;
  • 取余运算;

expr运算工具

计算指定的表达式,并输出

$[]算式替换

  • 使用$[] $(())
  • 引用变量可省略$
  • 计算结果替换表达式本身,echo输出

变量的自增、自减

  • let命令
  • 使用$(());

小数运算

整数运算的局限性

shell默认不支持小数运算

使用bc实现小数运算

  • bc
  • scale=n 约束小数位

小数值的比较

  • 管道
  • echo输出

条件测试

测试操作概述

脚本智能化

  • 脚本识别能力;
  • 识别依据;

测试操作

常见测试操作

整数值比较

  • -eq 等于 equl
  • -ne 不等于 Not equl
  • -ge 大于或者等于 Great or Equal
  • -le 小于或者等于 Lesser or Equal
  • -gt 大于 Greater Than
  • -lt 小于 Lesser Than

字符串比较

[ $(who|wc -l) -le 5 ] && echo "OK"
tips:
+ []外部前后不需要空格、内部前后需要空格;
+ echo后需要空格

文件状态测试

  • -e 对象是否存在
  • -d 是否为目录
  • -f 是否为一般文件
  • -r 是否有可读权限
  • -w 是否有可写权限
  • -x 是否有可执行权限

组合多个条件

逻辑分隔操作

  • && 逻辑与,给定条件必须全为真,否则结果为假;
  • || 逻辑或,给定条件只要有一个为真,则结果为真

条件组合应用

if选择结构


单分支结构

语法格式以及特点

if 条件测试
    then 命令序列
fi

if单分支的执行流程

脚本应用示例

shell
#!/bin/bash
mount_dir="/media/cdrom"
if[ !-d $mount_dir ];then
    mkdir -p $mount_dir
fi

双分支结构

语法格式以及特点

fi 条件测试
   then 命令序列1
    else 命令序列2
fi

if双分支的执行流程

脚本应用示例

#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &>/dev/null
if[ $? -eq 0 ];then
    echo "Host $1 is up."
else
    echo "Host $1 is down."
fi

多分支结构

语法格式以及特点

if 条件测试
    then 命令序列1
elif 条件测试2
    then 命令序列2
    else 命令序列n
fi

if多分支的执行流程

脚本应用示例

示例:gradediv.sh

#!/bin/bash
read -p "请输入分数(0~100): " FS
if [ $FS -ge 85 ] && [ $FS -le 100 ];then
    ehco "$FS 分,优秀!"
elif [ $FS -ge 70 ] && [ $FS -le 84 ];then
    echo "$FS 分,合格!"
else
    echo "$FS 分,不合格!"
fi

Shell基础概念

Shell环境以及特性


什么是Shell

  • 解释器;
  • 操作系统的外壳

使用方式

  • 交互式——命令行
  • 非交互式——脚本

常见Shell程序种类

  • /etc/shells
  • 切换shell环境(chsh、usermod)

Bash基本特性

  • 快捷键、补全
  • 历史、别名
  • 标准输入输出
  • 重定向
  • 管道

历史命令

history

I/O设备与重定向

  • 标准输入 0 /dev/stdin
  • 标准输出 1 /dev/stdout
  • 标准错误 2 /dev/stderr

编写以及执行脚本

第一个Shell脚本

  • 什么是shell脚本;
    提前写好可顺序执行语句,能够完成特定任务
  • Shell脚本Helloworld的诞生
#!/bin/bash
echo "Hello world!"

脚本的构成以及执行

规范的脚本构成;

  • 脚本申明;
  • 注释;
  • 可执行语句

脚本的执行方式;

  • 命令
  • 参数

调试

  • 观察
  • sh -x开启调试模式
  • 在可能出错的地方设置echo

变量

变量的设置和取消

什么市变量

  • 固定名称存放;
  • 可能会变化的值;

定义、赋值、查看变量

  • 变量名=变量值;
  • 等号两边不能有空格;
  • 变量名由字母、数字、下划线组成,区分大小写;
  • 变量名不能以数字开头,不要使用关键字和特殊字符;

取消变量

  • 自动失效;
  • unset;

变量的种类

  • 存储类型;
  • 使用类型;

变量的分类

环境变量

  • /etc/profile
  • ~/.bash_profile
  • env\set
  • PWD\PATH\USER\LOGNAME\UID\SHELL\HOME

预定义变量

  • $0 当前所在进程或者脚本名;
  • $$ 当前PID号;
  • $?命令执行的返回状态,0正常、1异常;
  • $# 已加载的位置变量的个数;
  • $* 所有位置变量的值;

位置变量

  • 命令行参数
  • 表示为$n,n为序号;
  • $1 ${11};

变量值以及范围控制

扩展赋值操作

区分三种定界符 “” ’‘ ``

read标准输入取值

read

变量的作用范围

  • 局部变量
  • 全局变量