现在的位置: 首页 > 综合 > 正文

cat catch mouse

2014年01月17日 ⁄ 综合 ⁄ 共 5951字 ⁄ 字号 评论关闭

猫捉老鼠

一只猫和一只老鼠在一个矩形的迷宫中。迷宫中的每个方格可以是空的,或者含有障碍。
猫和老鼠可以进入任意一个空的方格中。但是,无论猫或老鼠都不能进入有障碍的方格。
我们可以用字符组成的二维数组表示迷宫,如下图所示。
    *...*.....
    ......*...
    ...*...*..
    ..........
    ...*.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;
}

抱歉!评论已关闭.