iPhone給油する

給油しながら車が進む感じのiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#include <queue>

#include <vector>

#include <memory>

using namespace std;

typedef struct Station {

    int position;

    int fuel;

    int carFuel;

    bool operator<(const Station &o) const

    {

        return fuel < o.fuel;

    }

} Station;

class RefuelPointNav {

public:

    int solve(vector<Station>, int, int);

private:

    void notify(Station);

};

int RefuelPointNav::solve(vector<Station> stations, int fuel, int goalPosition) {

    int supplyCount = 0;

    int currentPosition=0;

    priority_queue<Station> queue;

    

    for (Station st : stations) {

        float dl = st.position – currentPosition;

        

        vector<Station> queueForNotify;

        

        while (fuel – dl < 0) {

            Station sp = queue.top();

            sp.carFuel = fuel – (sp.position – currentPosition);

            

            fuel += sp.fuel;

            queue.pop();

            supplyCount++;

            

            queueForNotify.insert(queueForNotify.begin(), sp);

        }

        fuel -= dl;

        currentPosition = st.position;

        queue.push(st);

        

        for (Station s : queueForNotify) {

            notify(s);

        }

    }

    

    notify({.position=goalPosition, .fuel=fuel});

    return supplyCount;

};

void RefuelPointNav::notify(Station s) {

    [[NSNotificationCenter defaultCenter] postNotificationName:@”supply” object:[NSValue value:&s withObjCType:@encode(Station)]];

}

#define InitFuel 3

#define GoalPosition 10

@interface ViewController () {

    vector<Station> stations;

    int count;

}

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor colorWithHue:0.5 saturation:0.05 brightness:1 alpha:1];

    

    UIView *road = [[UIView alloc] initWithFrame:CGRectMake(0, 250, CGRectGetMaxX(self.view.bounds), 40)];

    road.backgroundColor = [UIColor grayColor];

    [self.view addSubview:road];

    

    for (int i=0; i < 10; i++) {

        int fuel = arc4random() % 4 + 1;

        stations.push_back({.position = i, .fuel = fuel});

        

        UIView *stationView = [[UIView alloc] initWithFrame:CGRectMake((i + 1) * 60, 210, 20, 40)];

        stationView.tag = i + 1;

        stationView.backgroundColor = [UIColor clearColor];

        stationView.layer.borderWidth = 2;

        stationView.layer.borderColor = [UIColor darkGrayColor].CGColor;

        [self.view addSubview:stationView];

        

        

        UIView *fuelView = [[UIView alloc] initWithFrame:CGRectMake(1, 40 – fuel * 8, 202, fuel * 8)];

        fuelView.backgroundColor = [UIColor greenColor];

        [stationView addSubview:fuelView];

    }

    

    UIView *goal = [[UIView alloc] initWithFrame:CGRectMake((10 + 1) * 60, 210, 20, 40)];

    goal.tag = 11;

    [self.view addSubview:goal];

    

    UIView *car = [[UIView alloc] initWithFrame:CGRectMake(10, 245, 40, 20)];

    car.tag = 100;

    car.backgroundColor = [UIColor redColor];

    for (int i=0; i<2; i++) {

        UIView *tire = [[UIView alloc] initWithFrame:CGRectMake(i == 0 ? 5 : 25, 15, 10, 10)];

        tire.backgroundColor = [UIColor blackColor];

        tire.layer.cornerRadius = 5;

        [car addSubview:tire];

    }

    

    UIView *initFuelView = [[UIView alloc] initWithFrame:CGRectMake(1, –InitFuel * 8, 202, InitFuel * 8)];

    initFuelView.tag = 101;

    initFuelView.backgroundColor = [UIColor greenColor];

    [car addSubview:initFuelView];

    

    [self.view addSubview:car];

    

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(supply:) name:@”supply” object:nil];

}

– (void)supply:(NSNotification *)note {

    

    Station s;

    [note.object getValue:&s];

    

    

    UIView *car = [self.view viewWithTag:100];

    UIView *carfuel = [car viewWithTag:101];

    UIView *next = [self.view viewWithTag:s.position + 1];

    

    if (s.position == 10) {

        // goal

        [UIView animateWithDuration:1.5 delay:count * 3 options:0 animations:^{

            car.center = CGPointMake(next.center.x, car.center.y);

            carfuel.frame = CGRectMake(1, -s.carFuel * 8, 202, s.carFuel * 8);

        } completion:nil];

        return;

    }

    

    UIView *nextfuel = next.subviews[0];

    

    [UIView animateWithDuration:1.5 delay:count * 3 options:0 animations:^{

        car.center = CGPointMake(next.center.x, car.center.y);

        carfuel.frame = CGRectMake(1, -s.carFuel * 8, 202, s.carFuel * 8);

    } completion:^(BOOL finished) {

        nextfuel.transform = CGAffineTransformMakeScale(1, 0);

    }];

    

    [UIView animateWithDuration:0.5 delay:count * 3 + 1.2 options:0 animations:^{

        carfuel.frame = CGRectMake(1, -(s.fuel + s.carFuel) * 8, 202, (s.fuel + s.carFuel) * 8);

    } completion:nil];

    

    ++count;

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    shared_ptr<RefuelPointNav> cppClass(new RefuelPointNav());

    cppClass->solve(stations, InitFuel, GoalPosition);

    

}

@end