↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > 遺伝的アルゴリズムで四角を区切る

遺伝的アルゴリズムで四角を区切る

ランダムの領域をUIViewの中につくれないかと調査をしていたのですが、 行き着いたのが遺伝的アルゴリズム。どうやら自動でランダムに領域を変化させることができそうだと各資料を読んで、 ほんのりと理解はできたのですが、プログラムの方法が正直わからない。ということで、これを機にSwiftで簡単なものを自作してみようと思います。

↓やりたいのは以下のような流れ。

サンプル画像

参考:実践遺伝的アルゴリズム
参考:商用パズルの作成支援および自動生成 四角に切れ・橋をかけろ
参考:交叉だけでは進化が止まるので、突然変異を実装しよう。
参考:遺伝的アルゴリズムを楽しく理解できるサイトをまとめてみた

上のいろいろみてみると遺伝的アルゴリズムで球体が連結した物体に「歩く」動きを覚えさせたりできるようです。凄い、、、キモい、、、。 本気で理解すればなんだか面白いことが起こるのだなと感じておりました。今回は領域をいじるだけですので、複雑ではないことを願います。 自動で「学習」して歩くようなアルゴリズムも作ってみたいな。。。

準備。見積もり

さて、ほとんど理解していないこのアルゴリズム。大雑把ですが、ある程度整理しつつ進みながら理解していけたらと思います。上記のリンクの タイムインターメディア知識工学センター様のPDFにある常務取締役 藤原博文様の方法をSwiftで僕なりに作成して学んでいけたらと思っております。

サンプル画像

引用:実践遺伝的アルゴリズム

以下の二つのクラスを作成して動作検証してみます。すんなり行かないと思いますが、、、

メインのマス目View(MainView.swift)を作成する

参考:Swiftでオセロを作る (Part2)
参考:Swiftでオセロを作る (Part1)

10x10のマス目を描画する。と、マス目の情報を保存する配列を用意する。を進めます

10x10のマス目を描画する

この方法ですが、一つの四角をそれぞれ該当個数分並べて描画していきます。

サンプル画像


import UIKit

//マス目を表示
class SquaresView: UIView {
    
    var side:CGFloat = 0
    var top:CGFloat = 0
    let left:CGFloat = 0
    
    let white = UIColor.whiteColor().CGColor
    let black = UIColor.blackColor().CGColor
    
    let cellLength:Int = 10;//マス目個数
    
    init(){
        let appFrame = UIScreen.mainScreen().applicationFrame
        side = appFrame.size.width / CGFloat(cellLength);
        top = (appFrame.size.height - (side * CGFloat(cellLength))) / 2;
        super.init(frame: appFrame);
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func drawRect(rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        
        CGContextSetStrokeColorWithColor(context, black)//枠の色
        CGContextSetLineWidth(context, 1.5)
        
        for y in 1...cellLength {
            for x in 1...cellLength {
                let rx = left + side * CGFloat(x-1)
                let ry = top + side * CGFloat(y-1)
                let rect = CGRectMake(rx, ry, side, side)
                CGContextSetFillColorWithColor(context, white)//塗りつぶし色
                CGContextFillRect(context, rect)
                CGContextStrokeRect(context, rect)
                
            }
        }
    }
    
}

上記SquaresViewを作成しました。こちらをメインのViewControllerから作成してsubviewすれば以下のように表示されます。まずはマス目まで、、、

サンプル画像


マス目の配列を用意して、部分的に描画する

マスの情報の初期値を仮にセットしてみます



import UIKit

//マス目を表示
class SquaresView: UIView {
    
    var side:CGFloat = 0
    var top:CGFloat = 0
    let left:CGFloat = 0
    
    let white = UIColor.whiteColor().CGColor
    let black = UIColor.blackColor().CGColor
    
    let cellLength:Int = 9;//マス目個数
    
    var board:[[Int]]
    let initboard = [
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,1,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
    ];
    
    let FILLED = 1
    
    init(){
        let appFrame = UIScreen.mainScreen().applicationFrame
        side = appFrame.size.width / CGFloat(cellLength);
        top = (appFrame.size.height - (side * CGFloat(cellLength))) / 2;
        board = initboard;
        super.init(frame: appFrame);
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func drawRect(rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        
        CGContextSetStrokeColorWithColor(context, black)//枠の色
        CGContextSetLineWidth(context, 1.5)
        
        for y in 1...cellLength {
            for x in 1...cellLength {
                let rx = left + side * CGFloat(x-1)
                let ry = top + side * CGFloat(y-1)
                let rect = CGRectMake(rx, ry, side, side)
                CGContextSetFillColorWithColor(context, white)//塗りつぶし色
                CGContextFillRect(context, rect)
                CGContextStrokeRect(context, rect)
                
                if board[y][x] == FILLED {
                    //1であれば色をつける
                    CGContextSetFillColorWithColor(context, black)
                    CGContextFillEllipseInRect(context, rect)
                }
                
            }
        }
    }
    
}

サンプル画像

配列の1部分だけを黒く塗りつぶしています


初期位置、成長した位置の配列、ID、を格納するCircleChildVO.swiftを追加しました。 このクラスに必要な情報を複数格納しつつ、SquresViewで成長させていくように進めてみます。


import UIKit

class CircleChildVO : NSObject {
    
    var id:Int;//識別ID
    var initPos:CGPoint;//初期位置座業(マス目の縦横の位置を保存)
    var posArr:Array;//遺伝していくポジション座標(CGPointの配列)
    
    //コンストラクタ
    init(id:Int,location:CGPoint){
        //初期化
        self.id = id;
        self.initPos = location;
        self.posArr = Array();
        println("\(id)/\(location)");
    }
    
}


足あとを残しながら少しずつでも進んでいけたらと思います。今日はここまで!

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!