一,需求
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);
}