cat catch mouse

猫捉老鼠


一只猫和一只老鼠在一个矩形的迷宫中。迷宫中的每个方格可以是空的,或者含有障碍。
猫和老鼠可以进入任意一个空的方格中。但是,无论猫或老鼠都不能进入有障碍的方格。
我们可以用字符组成的二维数组表示迷宫,如下图所示。
    *...*.....
    ......*...
    ...*...*..
    ..........
    ...*.c....
    *.....*...
    ...*......
    ..m......*
    ...*.*....
    .*.*......
其中
"." : 空方格:
"*" : 障碍
"m" : 老鼠
"c" : 猫

现在,猫想捉到老鼠,它首先去计算如何才能最快走到老鼠的地方.我们帮它计算一下吧.
下面是猫可以走的一个路线, 猫走6步可以到达老鼠的位置, 这里路线用"@"表示.
        *...*.....
        ......*...
        ...*...*..
        ..........
        ...*.c....
        *....@*...
        ...*.@....
        ..m@@@...*
        ...*.*....
        .*.*......

要求:
    . 控制台程序.
    . 控制台输入:
        . 地图大小(长宽)
        . 障碍的出现的几率.
        . 猫的位置/老鼠的位置
    . 控制台输出:
        . 原始的地图(格式参考上面)
        . 猫最少要走多步可以到达老鼠的位置.
        . 猫走的路径(用地图表示)

/**

**@Author:  xuwf
**@Desc:    猫捉老鼠,求最短路径
**/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


#define BAR_CHAR        ('*')
#define CAT_CHAR        ('c')
#define MOUSE_CHAR      ('m')
#define ROUTE_CHAR      ('@')
#define EMPTY_CHAR      ('.')
#define CHILD_MAX_NUM   (4) //最多子节点数目


typedef struct pos {
    int x;
    int y;
}pos_t;


/**
**@Name:    pos_equal
**@In:      pos_t *a
            pos_t *b
**@Out:
**@Ret:     int, 相同返回0, 否则返回-1
**@Desc:    比较两坐标是否相同
**@Author:  xuwf
**@Date:    2012-3-5
**/
int pos_equal(pos_t *a, pos_t *b)
{
    if (!a || !b) {
        return -1;
    }


    if (a->x == b->x && a->y == b->y) {
        return 0;
    }
    return -1;
}


/***********************************************************
*node and operate
***********************************************************/
typedef struct node node_t;
struct node {
    pos_t pos;
    node_t *parent;
    node_t *next;
};


node_t *node_new(node_t *parent, pos_t *pos)
{
    node_t *node = NULL;


    node = (node_t *)calloc(1, sizeof(node_t));
    if (!node) {
        return NULL;
    }


    node->parent = parent;
    node->pos = *pos;


    return node;
}


int node_add(node_t *node, node_t *new_node)
{
    if (!node || !new_node) {
        return -1;
    }
    node->next = new_node;
    return 0;
}


void node_delete(node_t *node)
{
    if (!node) {
        return;
    }


    free(node);
}


/***********************************************************
*map and operate
***********************************************************/
typedef struct map_info{
    char **map;
    int map_w;
    int map_h;
    int bar_num;
}map_info_t;


int destructor_map(map_info_t *info);


int contruct_map(map_info_t *info)
{
    int i;
    pos_t bar_pos;


    if (!info) {
        return -1;
    }


    //清空
    info->map = NULL;


    //申请map空间
    info->map = (char **)calloc(info->map_h, sizeof(char *));
    if (!info->map) {
        goto _err;
    }


    for (i = 0; i < info->map_h; i++) {
        info->map[i] = (char *)calloc(info->map_w, sizeof(char));
        if (!info->map[i]) {
            printf("malloc error\n");
            goto _err;
        }
    }


    //初始化map
    for (i = 0; i < info->map_h; i++) {
        memset(info->map[i], EMPTY_CHAR, info->map_w);
    }


    //放置障碍物
    srand(unsigned(time(0)));
    for (i = 0; i < info->bar_num; i++) {
        bar_pos.x = rand()%info->map_w;
        bar_pos.y = rand()%info->map_h;
        info->map[bar_pos.y][bar_pos.x] = BAR_CHAR;
    }
    return 0;


_err:
    destructor_map(info);
    return -1;
}


int destructor_map(map_info_t *info)
{
    int i = 0;


    if(!info || !info->map) {
        return -1;
    }


    for (i = 0; i < info->map_h; i++) {
        if (info->map[i]) {
            free(info->map[i]);
        }
    }


    free(info->map);
    info->map = NULL;


    return 0;
}


void print_map(map_info_t *info)
{
    int i,j;


    if (!info || !info->map) {
        return;
    }


    printf("map width=%d, height=%d, barriers num=%d\n", info->map_w, info->map_h, info->bar_num);


    for (i = 0; i < info->map_h; i++) {
        for (j = 0; j < info->map_w; j++) {
            printf("%c", info->map[i][j]);
        }
        printf("\n");
    }
}


//检查位置是否合法
int check_pos(map_info_t *info, pos_t *pos)
{
     if (!info || !info->map || !pos) {
        return -1;
    }


    //x
    if (pos->x < 0 || pos->x >= info->map_w) {
        return -1;
    }


    //y
    if (pos->y < 0 || pos->y >= info->map_h) {
        return -1;
    }


    //if there has barrier
    if (BAR_CHAR == info->map[pos->x][pos->y]) {
        return -1;
    }


    return 0;
}


//放置猫和鼠
int put_cat_and_mouse(map_info_t *info, pos_t *cat_pos, pos_t *mouse_pos)
{
    if (!info || !info->map) {
        return -1;
    }


    if (!cat_pos || !mouse_pos) {
        return -1;
    }


    //check cat pos
    if (check_pos(info, cat_pos) < 0) {
        printf("cat pos is err\n");
        return -1;
    }


    info->map[cat_pos->x][cat_pos->y] = CAT_CHAR;


    //check mouse pos
     if (check_pos(info, mouse_pos) < 0) {
        printf("mounse pos is err\n");
        return -1;
    }
    info->map[mouse_pos->x][mouse_pos->y] = MOUSE_CHAR;
    return 0;
}


//核心算法,采用广度优先遍历,思路:不断将子节点添加到链表后
int find_route(map_info_t *info, pos_t *cat_pos, pos_t *mouse_pos)
{
    node_t *cat_node = NULL;
    node_t *child_node = NULL;
    node_t *p = NULL;
    node_t *tail = NULL;
    pos_t child_pos;
    static int dir_array[4][2] = {
                            {0, -1},//上
                            {-1, 0},//左
                            {0, 1},//下
                            {1, 0}};//右
    int i = 0;


    cat_node = node_new(NULL, cat_pos);
    tail = p = cat_node;
    while (p) {
        for (i = 0; i < 4; i++) {
            child_pos.x = p->pos.x + dir_array[i][0];
            child_pos.y = p->pos.y + dir_array[i][1];
            if (check_pos(info, &child_pos) < 0) {
                continue;
            }
            if (p->parent && (0 == pos_equal(&child_pos, &p->parent->pos))) {//父节点除外
                continue;
            }


            //add node
            child_node = node_new(p, &child_pos);
            if (!child_node) {
                printf("new node fail\n");
                return -1;
            }


            node_add(tail, child_node);
            tail = child_node;


            if (0 == pos_equal(&child_pos, mouse_pos)) {
                goto _found;
            }
        }
        p = p->next;
    }


    printf("can't find route\n");
    goto _free;
_found:
    //print route
    while (p->parent) {
        info->map[p->pos.x][p->pos.y] = ROUTE_CHAR;
        p = p->parent;
    }


_free:
    p = cat_node;
    while (p) {
        child_node = p->next;
        node_delete(p);
        p = child_node;
    }
    return 0;
}


int main(int argc, char *argv[])
{
    map_info_t info;
    float bar_pro = 0;//概率
    pos_t cat_pos, mouse_pos;


    //memset
    memset(&info, 0, sizeof(info));


    printf("please input map width and height:");
    scanf("%d %d", &info.map_w, &info.map_h);


    printf("plese input the probability of barriers:");
    scanf("%f", &bar_pro);


    if (bar_pro >= 1) {
        printf("probability of barriers must less then 1\n");
        return -1;
    }


    info.bar_num = (info.map_w*info.map_h)*bar_pro;


    //contruct map
    contruct_map(&info);
    print_map(&info);


    while (1) {
        printf("please input cat and mouse pos:\n");
        scanf("%d %d %d %d", &cat_pos.x, &cat_pos.y, &mouse_pos.x, &mouse_pos.y);
        if (put_cat_and_mouse(&info, &cat_pos, &mouse_pos) < 0) {
            continue;
        }
        print_map(&info);
        printf("find route ...\n");
        find_route(&info, &cat_pos, &mouse_pos);
        print_map(&info);
    }


    destructor_map(&info);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值