
給油しながら車が進む感じの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, 20–2, 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, 20–2, 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, 20–2, 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, 20–2, 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, 20–2, (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