终于写了人生第一个MVC的电梯算法。

[ RUN      ] ElevatorTest.basic_test
 1 3 9 12 2 32[2]
 1 3 9 12 2 32[3]
 1 3 9 12 2 32[4]
 1 3 9 12 2 32[5]
 1 3 9 12 2 32[6]
 1 3 9 12 2 32[7]
 1 3 9 12 2 32[8]
 1 3 9 12 2 32[9]
 1 3 9 12 2 32[10]
 1 3 9 12 2 32[11]
 1 3 9 12 2 32[12]
 1 3 9 12 2 32[13]
 1 3 9 12 2 32[14]
 1 3 9 12 2 32[15]
 1 3 9 12 2 32[16]
 1 3 9 12 2 32[17]
 1 3 9 12 2 32[18]
 1 3 9 12 2 32[19]
 1 3 9 12 2 32[20]
 1 3 9 12 2 32[21]
 1 3 9 12 2 32[22]
 1 3 9 12 2 32[23]
 1 3 9 12 2 32[24]
 1 3 9 12 2 32[25]
 1 3 9 12 2 32[26]
 1 3 9 12 2 32[27]
 1 3 9 12 2 32[28]
 1 3 9 12 2 32[29]
 1 3 9 12 2 32[30]
 1 3 9 12 2 32[31]
 1 3 9 12 2 32[32]
 1 3 9 12 2[32]
 1 3 9 12 2[31]
 1 3 9 12 2[30]
 1 3 9 12 2[29]
 1 3 9 12 2[28]
 1 3 9 12 2[27]
 1 3 9 12 2[26]
 1 3 9 12 2[25]
 1 3 9 12 2[24]
 1 3 9 12 2[23]
 1 3 9 12 2[22]
 1 3 9 12 2[21]
 1 3 9 12 2[20]
 1 3 9 12 2[19]
 1 3 9 12 2[18]
 1 3 9 12 2[17]
 1 3 9 12 2[16]
 1 3 9 12 2[15]
 1 3 9 12 2[14]
 1 3 9 12 2[13]
 1 3 9 12 2[12]
 1 3 9 12 2[11]
 1 3 9 12 2[10]
 1 3 9 12 2[9]
 1 3 9 12 2[8]
 1 3 9 12 2[7]
 1 3 9 12 2[6]
 1 3 9 12 2[5]
 1 3 9 12 2[4]
 1 3 9 12 2[3]
 1 3 9 12 2[2]
 1 3 9 12[2]
 1 3 9 12[3]
 1 3 9 12[4]
 1 3 9 12[5]
 1 3 9 12[6]
 1 3 9 12[7]
 1 3 9 12[8]
 1 3 9 12[9]
 1 3 9 12[10]
 1 3 9 12[11]
 1 3 9 12[12]
 1 3 9[12]
 1 3 9[11]
 1 3 9[10]
 1 3 9[9]
 1 3[9]
 1 3[8]
 1 3[7]
 1 3[6]
 1 3[5]
 1 3[4]
 1 3[3]
 1[3]
 1[2]
 1[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]

方括号[]里表示当前楼层,前面的数据表示将要去的楼层。这叫一个笨哦!

class EView {
  public:
    EView(){};
    ~EView() {};
    void set_state(EState &state) { s_ = &state; }
    void update()
    {
      for_each(s_->get_vector().begin(), s_->get_vector().end(), func);
      std::cout << "[" << s_->get_cur_floor() << "]" << endl;
    }
  private:
    static void func(int i) {
      std::cout << ' ' << i;
    }
  public:
    EState *s_;
};

虽然笨,但只需要修改EState类即可让算法变聪明。MVC的威力。改进后的输出:


从1楼走起

 3 9 12 2 32[1]
 3 9 12 2 32[2]
 3 9 12 32[2]
 3 9 12 32[3]
 9 12 32[3]
 9 12 32[4]
 9 12 32[5]
 9 12 32[6]
 9 12 32[7]
 9 12 32[8]
 9 12 32[9]
 12 32[9]
 12 32[10]
 12 32[11]
 12 32[12]
 32[12]
 32[13]
 32[14]
 32[15]
 32[16]
 32[17]
 32[18]
 32[19]
 32[20]
 32[21]
 32[22]
 32[23]
 32[24]
 32[25]
 32[26]
 32[27]
 32[28]
 32[29]
 32[30]
 32[31]
 32[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]
[32]

从9楼走起:

 1 3 9 12 2 32[8]
 1 3 9 12 2 32[7]
 1 3 9 12 2 32[6]
 1 3 9 12 2 32[5]
 1 3 9 12 2 32[4]
 1 3 9 12 2 32[3]
 1 3 9 12 2 32[2]
 1 3 9 12 2 32[1]
 3 9 12 2 32[1]
 3 9 12 2 32[2]
 3 9 12 32[2]
 3 9 12 32[3]
 9 12 32[3]
 9 12 32[4]
 9 12 32[5]
 9 12 32[6]
 9 12 32[7]
 9 12 32[8]
 9 12 32[9]
 12 32[9]
 12 32[10]
 12 32[11]
 12 32[12]
 32[12]
 32[13]
 32[14]
 32[15]
 32[16]
 32[17]
 32[18]
 32[19]
 32[20]
 32[21]
 32[22]
 32[23]
 32[24]
 32[25]
 32[26]
 32[27]
 32[28]
 32[29]
 32[30]
 32[31]
 32[32]
[32]
[32]
[32]
[32]
[32]
[32]


全部代码如下:

/*
 * (C) 1999-2013 Alibaba Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *
 * Version:  elevator.cpp,  04/18/2014 03:41:33 PM Yu Huang Exp $
 *
 * Author:
 *   Huang Yu <xiaochu.yh@alipay.com>
 * Description:
 *   
 *
 */

#include <gtest/gtest.h>
#include "tbsys.h"
#include <vector>
#include <algorithm>    // std::for_each

using namespace std;;
using namespace tbsys;;

/*
   Elevator

M: IState
C: EControl
V: EView
*/
class IState;
class EView;
class EControl;

class IState {
  public:
    IState() : cur_floor_(9) {}
    virtual bool need_stop() = 0;
    virtual bool need_open() = 0;
    virtual void move() = 0;
    virtual void open() = 0;
    int get_cur_floor() { return cur_floor_; }
    vector<int> & get_vector() { return targets_;}
    void set_speed(int speed) { speed_ = speed; }
    int get_speed() { return speed_; }
    void push_floor(int floor) { targets_.push_back(floor); }
  protected:
    int cur_floor_;
    int speed_;
    std::vector<int> targets_;
};

class ESimpleState : public IState {
  public:
    bool need_stop()
    {
      return targets_.empty();
    }
    bool need_open()
    {
      bool open = false;
      if ((!targets_.empty()) && targets_.back() == cur_floor_)
      {
        open = true;
      }
      return open;
    }
    void move()
    {
      if (targets_.empty())
      {
      }
      else if (targets_.back() > cur_floor_)
      {
        cur_floor_++;
      }
      else if (targets_.back() < cur_floor_)
      {
        cur_floor_--;
      }
    }
    void open()
    {
      targets_.pop_back();
    }
};

class EBetterState : public IState {
  public:
    bool need_stop()
    {
      return targets_.empty();
    }
    bool need_open()
    {
      bool open = false;
      pair<vector<int>::iterator,vector<int>::iterator> p = minmax_element(targets_.begin(), targets_.end());
      if ((!targets_.empty()) && (*p.first == cur_floor_ || *p.second == cur_floor_))
      {
        open = true;
      }
      return open;
    }
    void move()
    {
      if (targets_.empty())
      {
      }
      else
      {
        pair<vector<int>::iterator,vector<int>::iterator> p = minmax_element(targets_.begin(), targets_.end());
        if (*p.first > cur_floor_)
        {
          cur_floor_++;
        }
        else if (*p.second < cur_floor_)
        {
          cur_floor_--;
        }
        else
        {
          cur_floor_--;
        }
      }
    }
    void open()
    {
      pair<vector<int>::iterator,vector<int>::iterator> p = minmax_element(targets_.begin(), targets_.end());
      if (*p.first == cur_floor_)
      {
        targets_.erase(p.first);
      }
      else if (*p.second == cur_floor_)
      {
        targets_.erase(p.second);
      }
    }
};



class EView {
  public:
    EView(){};
    ~EView() {};
    void set_state(IState &state) { s_ = &state; }
    void update()
    {
      for_each(s_->get_vector().begin(), s_->get_vector().end(), func);
      std::cout << "[" << s_->get_cur_floor() << "]" << endl;
    }
  private:
    static void func(int i) {
      std::cout << ' ' << i;
    }
  public:
    IState *s_;
};

class EControl : public tbsys::CDefaultRunnable
{
  public:
    virtual void run(tbsys::CThread *thread, void *arg)
    {
      UNUSED(thread);
      UNUSED(arg);
      int tick = 100;
      while (tick--)
      {
        if (s_->need_stop())
        {
        }
        else if (s_->need_open())
        {
          s_->open();
        }
        else
        {
          s_->move();
        }
        update_view();
        sleep(1);
      }
    }
    void set_state(IState &state) { s_ = &state; }
    void set_view(EView &view) { v_ = &view; }
  private:
    void update_view()
    {
      v_->update();
    }
  private:
    EView *v_;
    IState *s_;
};



class ElevatorTest : public ::testing::Test
{
  public:
    ElevatorTest();
    virtual ~ElevatorTest();
    virtual void SetUp();
    virtual void TearDown();
  private:
    // disallow copy
    ElevatorTest(const ElevatorTest &other);
    ElevatorTest& operator=(const ElevatorTest &other);
  private:
    // data members
};
ElevatorTest::ElevatorTest()
{
}

ElevatorTest::~ElevatorTest()
{
}

void ElevatorTest::SetUp()
{
}

void ElevatorTest::TearDown()
{
}

TEST_F(ElevatorTest, basic_test)
{
  EBetterState m;
  //ESimpleState m;
  EControl c;
  EView v;
  c.set_state(m);
  v.set_state(m);
  c.set_view(v);
  m.push_floor(1);
  m.push_floor(3);
  m.push_floor(9);
  m.push_floor(12);
  m.push_floor(2);
  m.push_floor(32);
  c.start();
  c.wait();
  TBSYS_LOG(INFO, "end exec");
}

int main(int argc, char **argv)
{
  TBSYS_LOGGER.setLogLevel("INFO");
  ::testing::InitGoogleTest(&argc,argv);
  return RUN_ALL_TESTS();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值