演进式设计——扫地机器人

一,需求

1,迭代1

设置指定位置(x, y, heading)
获取当前位置(x, y, heading)
右转90度,位置不变
左转90度,位置不变

2, 迭代2

前进一步,方向不变
后退一步,方向不变
转180度 位置不变

3,迭代3

右转45度,位置不变
左转45度,位置不变
注解:当角度为45 奇数倍时,前进一步需要向x y轴都需要变化

4,迭代4

forward n step 沿当前方向前进n步, 方向不变
backward n setp 沿当前方向后退n步, 方向不变
repet command n time:将指定的动作(左转右转前进后退,一共8个动作)重复执行N次

二,实现

头文件:

enum {
    NORTH,
    NORTHEAST,
    EAST,
    EASTSOUTH,
    SOUTH,
    SOUTHWEST,
    WEST,
    WESTNORTH
};

typedef struct Position {
    int locx, locy;
    int direc; // 方向,0,1,2,3对应北东南西
} position;

typedef enum Command{
    FORWARD,
    BACKWARD,
    TURNRIGHT,
    TURNLEFT,
    TURNROUND,
    TURNRIGHT45DEG,
    TURNLEFT45DEG,
    COMMAND_ONE_BUT,
    FORWARDN,
    BACKWARDN,
    COMMAND_TWO_BUT
}Command;

void Create();
void Init(int x, int y, int heading);
position GetPosition();
void Forward();
void Backward();
void TurnRight();
void TurnLeft();
void TurnRound();
void TurnRight45deg();
void TurnLeft45deg();
void ForwardN(int n);
void BackwardN(int n);
void Repeat(int m,Command command, ...);

源代码:

#include <stdarg.h>

const int dx[]={ -1, -1, 0, 1, 1, 1, 0 , -1};
const int dy[]={ 0, 1, 1, 1, 0, -1, -1, -1 };
static position sp;

void Init(int x, int y, int heading)
{
    sp.locx = x;
    sp.locy = y;
    sp.direc = heading;
}

void Create()
{
    Init(0,0,NORTH);
}

position GetPosition()
{
    return sp;
}

static void Move(int dis)
{
    sp.locx += dx[sp.direc] * dis;
    sp.locy += dy[sp.direc] * dis;
}

void Forward()
{
    Move(1);
}

void Backward()
{
    Move(-1);
}

void ForwardN(int n)
{
    Move(n);
}

void BackwardN(int n)
{
    Move(-n);
}

static void Turn(int d)
{
    sp.direc += d;
    sp.direc %= 8;
}

void TurnRight()
{
    Turn(2);
}

void TurnLeft()
{
    Turn(6);
}

void TurnRound()
{
    Turn(4);
}

void TurnRight45deg()
{
    Turn(1);
}

void TurnLeft45deg()
{
    Turn(7);
}

int isOneParaCommand(Command command)
{
    return command<COMMAND_ONE_BUT;
}

void ExecutCommand(Command command, int n)
{
    switch(command)
    {
        case FORWARD:
            return Forward();
        case BACKWARD:
            return Backward();
        case TURNLEFT:
            return TurnLeft();
        case TURNRIGHT:
            return TurnRight();
        case TURNROUND:
            return TurnRound();
        case TURNLEFT45DEG:
            return TurnLeft45deg();
        case TURNRIGHT45DEG:
            return TurnRight45deg();
        case FORWARDN:
            return ForwardN(n);
        case BACKWARDN:
            return BackwardN(n);
    }
}

void Execut(Command command, va_list arg)
{
    int n=0;
    if (!isOneParaCommand(command)) {
        n = va_arg(arg, int);
    }
    ExecutCommand(command,n);
    va_end(arg);
}

void Repeat(int m,Command command, ...)
{
    va_list arg;
    va_start(arg, command);
    while(m--){
        Execut(command,arg);
    }
    va_end(arg);
}

三,测试用例

#define ASSERT_POSITION(x,y,h)  position sp = GetPosition();\
    GTEST_ASSERT_EQ((x),sp.locx);\
    GTEST_ASSERT_EQ((y),sp.locy);\
    GTEST_ASSERT_EQ((h),sp.direc);

TEST_F(MockCppTest, get_default_location)
{
    ASSERT_POSITION(0, 0, NORTH);
}

TEST_F(MockCppTest, init_config)
{
    Init(1, 2, WEST);
    ASSERT_POSITION(1, 2, WEST);
}

TEST_F(MockCppTest, turn_left)
{
    Init(1, 2, WEST);
    TurnLeft();
    ASSERT_POSITION(1, 2, SOUTH);
}

TEST_F(MockCppTest, turn_right)
{
    Init(1, 2, WEST);
    TurnRight();
    ASSERT_POSITION(1, 2, NORTH);
}


TEST_F(MockCppTest, forward)
{
    Init(0, 0, WEST);
    Forward();
    ASSERT_POSITION(0, -1, WEST);
}

TEST_F(MockCppTest, backward)
{
    Init(0, 0, WEST);
    Backward();
    ASSERT_POSITION(0, 1, WEST);
}

TEST_F(MockCppTest, turn_round)
{
    Init(0, 0, WEST);
    TurnRound();
    ASSERT_POSITION(0, 0, EAST);
}

TEST_F(MockCppTest, turn_left_45degree)
{
    Init(1, 2, WEST);
    TurnLeft45deg();
    ASSERT_POSITION(1, 2, SOUTHWEST);
}

TEST_F(MockCppTest, turn_right_45degree)
{
    Init(1, 2, WEST);
    TurnRight45deg();
    ASSERT_POSITION(1, 2, WESTNORTH);
}

TEST_F(MockCppTest, forward_to_WESTNORTH)
{
    Init(0, 0, WESTNORTH);
    Forward();
    ASSERT_POSITION(-1, -1, WESTNORTH);
}

TEST_F(MockCppTest, forwardN)
{
    Init(0, 0, WEST);
    ForwardN(3);
    ASSERT_POSITION(0, -3, WEST);
}

TEST_F(MockCppTest, backwardN)
{
    Init(0, 0, WEST);
    BackwardN(5);
    ASSERT_POSITION(0, 5, WEST);
}

TEST_F(MockCppTest, repeat_forward)
{
    Init(0, 0, WEST);
    Repeat(10,FORWARD);
    ASSERT_POSITION(0, -10, WEST);
}

TEST_F(MockCppTest, repeat_forward_N)
{
    Init(0, 0, WEST);
    Repeat(10,FORWARDN, 5);
    ASSERT_POSITION(0, -50, WEST);
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值