組合せのパターン数を3Dでなんとなく体感するiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@import SpriteKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic) NSTimeInterval start;
@property (nonatomic) int count;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createBoard];
[self createConsole];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.backgroundColor = [self color:0];
sv.scene = [SCNScene scene];
sv.delegate = self;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createBoard {
SCNBox *box = [SCNBox boxWithWidth:20 height:1 length:20 chamferRadius:0];
box.firstMaterial.diffuse.contents = [self color:1];
SCNNode *boxNode = [SCNNode nodeWithGeometry:box];
boxNode.physicsBody = [SCNPhysicsBody staticBody];
[self.sceneView.scene.rootNode addChildNode:boxNode];
for (int i=0; i<22; i++) {
SCNBox *line = [SCNBox boxWithWidth:20 height:0.1 length:0.1 chamferRadius:0];
line.firstMaterial.diffuse.contents = [self color:2];
SCNNode *lineNode = [SCNNode nodeWithGeometry:line];
float a = (i % 11) * 2 – 10;
if ((i / 11) > 0) {
lineNode.position = SCNVector3Make(a, 0.6, 0);
lineNode.rotation = SCNVector4Make(0, 1, 0, M_PI * 0.5);
} else {
lineNode.position = SCNVector3Make(0, 0.6, a);
}
[self.sceneView.scene.rootNode addChildNode:lineNode];
}
}
– (void)createConsole {
self.sceneView.overlaySKScene = [SKScene sceneWithSize:self.view.bounds.size];
SKSpriteNode *console = [SKSpriteNode spriteNodeWithColor:[[self color:3] colorWithAlphaComponent:0.3] size:CGSizeMake(100, 100)];
console.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMaxY(self.view.bounds) – 80);
[self.sceneView.overlaySKScene addChild:console];
NSArray *words = @[@”(“, @”n”, @”m”, @”)”];
CGPoint pts[] = {CGPointMake(-30, 0), CGPointMake(0, 20), CGPointMake(0, –20), CGPointMake(30, 0)};
for (int i=0; i<4; i++) {
SKLabelNode *l = [SKLabelNode labelNodeWithText:words[i]];
l.position = pts[i];
[console addChild:l];
}
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 15, 30);
camera.rotation = SCNVector4Make(1, 0, 0, –0.3);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.start = time;
});
if (time – self.start > 0.4 && self.count < 10) {
self.start = time;
[self createBallAt:self.count m:0];
self.count++;
}
}
– (void)createBallAt:(int)n m:(int)m{
int c = 0;
if (m <= n && m != 0) {
// combination (n, m)
c =(^{
int result = 1;
for(int i=n; i>n-m; i–) result *= i;
return result;}())
/
(^{
int result = 1;
for(int i=m; i>0; i–) result *= i;
return result;}());
}
NSLog(@”n:%d m:%d c:%d”, n, m ,c);
float x = n * 2 – 9.0;
float z = m * 2 – 9.0;
SCNSphere *sphere = [SCNSphere sphereWithRadius:0.2];
sphere.firstMaterial.diffuse.contents = (c==0) ? [UIColor blackColor] : [self color:4];
SCNNode *sphereNode = [SCNNode nodeWithGeometry:sphere];
sphereNode.position = SCNVector3Make(x, 20, z);
sphereNode.physicsBody = [SCNPhysicsBody dynamicBody];
sphereNode.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);
sphereNode.physicsBody.angularVelocityFactor = SCNVector3Zero;
[self.sceneView.scene.rootNode addChildNode:sphereNode];
for (int i=1; i<c; i++) {
SCNSphere *sphere = [SCNSphere sphereWithRadius:0.2];
sphere.firstMaterial.diffuse.contents = [self color:4];
SCNNode *sphereNode = [SCNNode nodeWithGeometry:sphere];
sphereNode.position = SCNVector3Make(x, 20 + i * 20, z);
sphereNode.physicsBody = [SCNPhysicsBody dynamicBody];
sphereNode.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);
sphereNode.physicsBody.angularVelocityFactor = SCNVector3Zero;
[self.sceneView.scene.rootNode addChildNode:sphereNode];
}
if (m<9) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self createBallAt:n m:m+1];
});
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self createBallAt:self.count m:0];
self.count++;
}
#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000)>>16)/255.0 green:((rgb & 0xFF00)>>8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1.0]
– (UIColor *)color:(int)i {
if (i>4) return nil;
int colorCodes[] = {0xBFAAAA, 0x9086A6, 0xF2F2E9, 0xF2EFBB, 0x735D36};
return ColorHex(colorCodes[i]);
}
@end