4x4の魔方陣を自動生成するアプリを作ってみた。
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・マトリクス4×4はGLKitを利用
・A ~ Eまでの6種類のマトリクスを以下の式で計算
・問題を作る式は:「8 * matrixX + 4 * matrixX + 2 * matrixX + matrixX」
サンプルコード
#import “ViewController.h”
#import <GLKit/GLKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
GLKMatrix4 mAll;
GLKMatrix4 matA;
GLKMatrix4 matB;
GLKMatrix4 matC;
GLKMatrix4 matD;
GLKMatrix4 matE;
GLKMatrix4 question;
GLKMatrix4 answer;
UILabel *selectedAnswer;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
}
– (void)viewDidAppear:(BOOL)animated
{
[self initMatrix];
[self createQuestion];
[self showQuestion];
[self initAnswers];
[self retryBtn];
}
– (void)initMatrix
{
// 4×4 matrixの種となるマトリクスを6個, 用意
mAll = GLKMatrix4Make(1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1);
matA = GLKMatrix4Make(1, 1, 0, 0,
0, 0, 1, 1,
1, 1, 0, 0,
0, 0, 1, 1);
matB = GLKMatrix4Make(1, 0, 1, 0,
0, 1, 0, 1,
0, 1, 0, 1,
1, 0, 1, 0);
matC = GLKMatrix4Make(1, 1, 0, 0,
0, 0, 1, 1,
0, 0, 1, 1,
1, 1, 0, 0);
matD = GLKMatrix4Make(1, 1, 0, 0,
1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 1);
matE = GLKMatrix4Make(0, 1, 0, 1,
1, 1, 0, 0,
0, 0, 1, 1,
1, 0, 1, 0);
}
– (void)createQuestion
{
// 1 ~ 16 で構成された魔方陣にする
GLKMatrix4 result = mAll;
// 次の式で作る(2進数4桁にはめる)
// 8 * matrixX + 4 * matrixX + 2 * matrixX + matrixX
GLKMatrix4 matArr[] = {matA, matB, matC, matD, matE};
for (int i=0; i<4; i++) {
int random = arc4random() % (sizeof(matArr) / sizeof(GLKMatrix4));
GLKMatrix4 choice = [self multipltiply:pow(2, i) matrix:matArr[random]];
result = GLKMatrix4Add(result, choice);
}
question = result;
}
– (GLKMatrix4)multipltiply:(int)coefficient matrix:(GLKMatrix4)mat
{
for (int a=0; a<16; a++) {
mat.m[a] = coefficient * mat.m[a];
}
return mat;
}
#define NumberView 10
– (void)showQuestion
{
// 前のラベルを消す
for (int i=0; i<[self.view.subviews count]; i++) {
UIView *v = [self.view.subviews objectAtIndex:i];
if (v.tag == NumberView) {
v.layer.zPosition = 100 – i;
[UIView animateWithDuration:0.3 delay:i * 0.05 options:UIViewAnimationOptionCurveEaseIn animations:^{
v.center = CGPointMake(160, 800);
} completion:^(BOOL finished) {
[v removeFromSuperview];
}];
}
}
for (int i=0; i<16; i++) {
float size = 60.0;
float x = (i % 4) * size + 70;
float y = (i / 4) * size + 100;
UILabel *number = [[UILabel alloc] init];
number.font = [UIFont systemFontOfSize:50];
number.text = [NSString stringWithFormat:@”%d”, (int)question.m[i]];
number.textAlignment = 1; // center
number.bounds = CGRectMake(0,0,size,size);
number.center = CGPointMake(x, y);
number.layer.borderWidth = 2.0;
number.layer.borderColor = [UIColor lightGrayColor].CGColor;
number.tag = NumberView;
int blank = arc4random() % 3;
if (blank == 0) {
number.text = @”?”;
number.textColor = [UIColor darkGrayColor];
number.backgroundColor = [UIColor yellowColor];
}
[self.view addSubview:number];
}
}
– (void)retryBtn
{
// リトライ用のボタンを用意
UIView *retry = [[UIView alloc] initWithFrame:CGRectMake(280, 10, 30, 30)];
retry.backgroundColor = [UIColor greenColor];
retry.layer.cornerRadius = 15.0;
retry.layer.borderColor = [UIColor lightGrayColor].CGColor;
retry.layer.borderWidth = 3.0;
[self.view addSubview:retry];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(retry)];
[retry addGestureRecognizer:tap];
}
– (void)initAnswers
{
for (int i=0; i<16; i++) {
float size = 35;
float x = size * (i / 2) + 40;
float y = size * (i % 2) + 350;
UILabel *ans = [[UILabel alloc] init];
ans.backgroundColor = [UIColor clearColor];
ans.text = [NSString stringWithFormat:@”%d”, i+1];
ans.frame = CGRectMake(0, 0, size, size);
ans.center = CGPointMake(x,y);
ans.backgroundColor = [UIColor yellowColor];
ans.textAlignment = 1; //center
ans.layer.cornerRadius = 5.0;
ans.layer.borderWidth = 4.0;
ans.layer.borderColor = [UIColor darkGrayColor].CGColor;
ans.userInteractionEnabled = YES;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
[ans addGestureRecognizer:pan];
[self.view addSubview:ans];
}
}
– (void)move:(UIPanGestureRecognizer*)gr
{
CGPoint p = [gr locationInView:self.view];
if (gr.state == UIGestureRecognizerStateBegan) {
UILabel *label = [[UILabel alloc] init];
label.text = ((UILabel*)gr.view).text;
label.textAlignment = 1;
label.font = [UIFont boldSystemFontOfSize:30];
label.bounds = CGRectMake(0,0,50,50);
label.layer.cornerRadius = 10.0;
label.layer.borderColor = [UIColor yellowColor].CGColor;
label.layer.borderWidth = 4.0;
label.alpha = 0.9;
label.tag = NumberView;
[self.view addSubview:label];
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(removeTappedPanel:)];
[label addGestureRecognizer:tap];
selectedAnswer = label;
}
selectedAnswer.center = p;
}
– (void)removeTappedPanel:(UIGestureRecognizer*)gr
{
[UIView animateWithDuration:0.3 animations:^{
gr.view.center = CGPointMake(160, 800);
}];
}
– (void)retry
{
[self createQuestion];
[self showQuestion];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end