【SwiftUI】ダビスタの完璧な配合アプリを作成してみた(面白い配合×見事な配合)

あけましておめでとうございます!

プログラミングを始めて2年目なので、技術的な記事を書いていけたらと思います。

今回は前回の続きからです。

いまだにダビスタやっています!
自分の牝馬から完璧な配合を生み出す方法を書いていきたいと思います

ですが、swiftでやってしまい、共有が難しいのが難点です。
アプリとして登録しようと思ってないし、やり方わかんないし。。。

とりあえず、完璧な配合を目指していきたいと思います!
実は私は牧場経営50年目にいきましたが、いまだに完璧な配合を作れていません笑

今回は前回の続きからで、見事な配合の計算方法を紹介したいと思います。
正直、無理やりやったので合ってるか不安な部分もあります。。

完璧な配合とは

前回も説明したのですが、ダビスタ(switch)の完璧な配合とは、面白い配合+見事な配合です。
前回は約150頭の繁殖オス馬から面白い配合の馬を厳選する方法を紹介しました。
今回は、自分の繁殖牝馬と見事な配合になるオス馬(面白い配合を持っている)を3世代に渡って計算してみたので、それを紹介したいと思います

見事な配合とは

見事な配合とは、父方の対象馬の系統構成と母方の対象馬の系統構成に大系統が3種類以上あり、一致している場合に成立する配合。
らしいです。

ここのサイトが分かりやすかったです!(https://gamerch.com/derby/entry/208593
つまり
オス馬の父
オス馬の父
オス馬の母
オス馬の母
の系統が

繁殖牝馬




の系統と同じなら見事な配合です(順番は問わず)

方法

先にソースコードです

func checkKanpekiHorse(b: Array<String>) -> [(Int, String)] {
    var kanpekiHorse: [(No: Int, name: String)] = []
    var checking = 0
    var multipleLines: Array<String> = []
    var multipleLine: String = ""
    for i in 0..<4 {
        for j in i + 1..<4 {
            if i != j {
                if b[i] == b[j] {
                    checking += 1
                    multipleLines.append(b[i])
                }
            }
        }
    }
    if checking == 1 {
        multipleLine = multipleLines[0]
    }
    
    if checking < 2 {
    
        for k in 0..<omoshiroHorses.count {
            var checkCount = 0
            var check2 = 0
            var omoshiroArray: Array<String> = []
            omoshiroArray = [omoshiroHorses[k].2,
                             omoshiroHorses[k].3,
                             omoshiroHorses[k].4,
                             omoshiroHorses[k].5]
            
            for l in 0..<4 {
                var doubleCheck = 0
                for m in 0..<4 {
                    if b[l] == omoshiroArray[m] {

                        checkCount += 1
                        doubleCheck += 1
                    }
                    if omoshiroArray[m] == multipleLine {
                        check2 += 1
                    }
                }
                if doubleCheck == 2 {
                    checkCount -= 1
                }
            }
            if multipleLine != "" && check2 != 8 {
                checkCount = 0
            }
            if checkCount == 4 {
                kanpekiHorse.append((No: omoshiroHorses[k].0,
                                     name: omoshiroHorses[k].1))
            }
        }
        return kanpekiHorse
    }
    return []
}

何をしているかと言うと、 まず繁殖牝馬




の系統の被りが2以上じゃないことを確認しています。

ここの系統は1回だけなら被っても良いのですが、2回以上だとおもしろ配合になりません。
ただ、2回以上被っても見事な配合にはなります。 今回は、完璧な配合を作るので除外しました!

その後, おもしろ配合のオス馬と比較し、 オス馬の父
オス馬の父
オス馬の母
オス馬の母
の系統が

繁殖牝馬




と全て合っていたら、完璧な配合としています。

今回は繁殖牝馬の系統がオス馬の系統と一致していたら、checkCountという変数の値を+1して、
checkCountが合計4になったら、完璧な配合とみなしています。

ただ、いろいろfor文を回すと条件があり。。 例えば、牝馬の方の系統でが被っているものがあったりすると、計算がおかしくなります。 また、オス馬の方で被っている系統があると、完璧な配合ではないのに、完璧な配合とされてしまう場合があるので、 その場合はcheckCountを-1にしています。

そのあとは、この関数を最大で3回、回すだけです 1回目の繁殖で完璧な配合ができなかった場合、 繁殖牝馬の 父
母 の部分を150頭ほどいる、オス馬の 父
母 に変えます。 そのあと、23頭ほどいる面白い配合のオス馬と比較して、完璧な配合かどうかを見極めます。

つまり何が言いたいかというと、めちゃめちゃ計算量半端ないっす。。

2頭までですめば、まあちょっと多いかなという感じですが、 3頭目までいくと、 繁殖牝馬
父 => 2頭目のオス馬の父 父母 => 2頭目のオス馬の母 母父 => 1頭目のオス馬の父 母
という風になるので、 150×150= 22,500通りくらいを計算しないといけません。。

なので、計算し終わるのが10秒くらいかかりました。。

でも計算が楽になったので、ダビスタ活動が進んでいます! ただ完璧な配合の馬を作っても、全然勝てませんw

意地になってダビスタしてたら投稿間隔が空いてしまいました。。。

最近ラズパイ買ったので、そちらの投稿を今後はしていきたいと思います。!

今年もよろしくお願いいたします!!

【SwiftUI】ダビスタの完璧な配合アプリを作成してみた(面白い配合まで)

 

最近switchのダビスタにはまりました。

 

競馬は馬券を買うことはなかったのですが、よくテレビでみていました。

今回ダビスタの最新作が出るということなので、ダビスタデビューしました!

 

買ってからはもうずっっと、良い配合のことを調べています。

が。。

種付けの作業が面倒臭い。。

 

オスの馬150頭くらいいるので、一つずつ見ていくのが本当に時間がかかる。。

 

最初は楽しかったんですけど、どんどんどうでもよくなってきちゃいました笑

 

このままでは僕の大事な牝馬達に悪い!!とういことで、完璧な配合一覧を取得できるアプリを作成しました。

(そういう風なアプリは探せばあるのかもしれないが、それすら探すのが面倒くさくなってきたので、気合入れるために作ることにしました。。)

 

今回は完璧な配合の馬だけ探してくるアプリです。

完璧な配合の説明はこちらを参考にしました!。

https://www.youtube.com/watch?v=4HCZHn661kg

いろいろなサイトを見たけど、このyoutubeの動画が一番解りやすかったです。

 

つまりオスの馬150頭の中から、一番良い感じになる馬一頭と

自分の牧場の牝馬の組み合わせを選べば良いってことです。

 

f:id:disuke:20201228232852p:plain

例えばこの様な系統の牝馬で完璧な配合を目指すとすると

f:id:disuke:20201228233042p:plain

この様に入力して、左下に小さくある計算するボタンを押すと

f:id:disuke:20201228233259p:plain

この様に完璧な配合となる組み合わせを表示してくれます!

(今回は早くダビスタに戻りたかったので、動けば良いやと思って作りました。。)

 

作り方は、まず全部のオスの馬の系統が書いてあるjsonファイルを作りました。

これが一番辛かったです。。

 

f:id:disuke:20201228233938p:plain

この様な感じで全部。。

faが父

moが毋

fa_faが父の父(父の方のおじいちゃん)

fa_moが父の母(父の方のあばあちゃん)

ma_faが母の父(母の方のおじいちゃん)

という風に3世代まで書きます

 

この次はこのオス馬の中から、面白い配合の馬を見つけます。

面白い配合じゃないと完璧な配合にはなりません。

面白い配合というのは、

おじいちゃんとおばあちゃん達の父と母達の系統が7種類ある状態です。

先ほどの写真で言うと

f:id:disuke:20201228235034p:plain

ここの赤い部分が7種類あれば良いと言うことです。

ちなみにここのNaとかが系統です。

詳しくはこちらを参考にしてください

https://gamerch.com/derby/entry/208599

 

上の写真の場合、ディープインパクトは7種類あるので、面白い配合なのですが、

ロードカナリアの場合6種類しかないので、完璧な配合が作れません。

 

この面白い配合を確認するコードがこちらです

f:id:disuke:20201228235725p:plain

このcalculateOmoshiro関数で面白い配合の馬をチョイスしていきます。

62行目に出てくるformulationsと言うのが先ほどのオス馬のjsonファイルです。

for文で1頭ずつ確認していきます。

84行目で1頭ずつ面白い配合に必要な系統を集めて、

checkOmoshiro関数に渡しています。

checkOmoshiro関数はこんな感じです。

f:id:disuke:20201228235547p:plain

calculateOmoshiro関数から受け取った8個の系統を順番に見ていっています。

受け取った系統をa, b, c, d, e, f, g, aだとすると、

a-b, a-c, a-d, a-e, a-f, a-g, a-a,

b-c, b-d, b-e, b-f, b-g, b-a,

c-d, c-e, c-f, c-g, c-a,

d-e, d-f, d-g, d-a,

e-f, e-g, e-a,

f-g, f-a,

g-a

と言う風に確認して行っています。

そして文字が一緒だったらcheckCountに数字が一つプラスされます。

上記の場合、a-aのパターンしかないのでcheckCountは1です。

このcheckCountが2未満なら面白い配合なのでtrueを返しています。

 

疲れたので今回はここまでにします。。

次に見事な配合をどうやってチェックしたか書こうと思います。

(かなり強引にやりました。なのでめちゃめちゃ処理遅いです。。)



 

噂のブリを買ってみた

1月前くらいに話題になっていた、養殖のブリを買ってみました。

これです

https://kochi-kawauso.com/products/ootsukiburi-1hiki

 

一回こんな大きな魚食べてみたかったんです!

だけどどのくらいの量かよくわかりませんでした。

12~16人前とは書いてあったけど、まだまだ食べ盛りの20代なので全然行けるかなと思いました。

 

先に結論から書くと、男子3人で食べて、少し余って満腹でした。

なので、もうちょっと人数がいた方がよかったです。

 

届いた日付はバッチリでした!

 

f:id:disuke:20201223233524p:plain

このくらいの大きさでした。

いつかこんなのを釣ってみたいですね 

 

次に捌いていったのですが、今回は寿司屋で働いている友人がいたので、ほぼ全てお任せしました!ありがたい。。

 

 

捌き方はyoutubeにいっぱいあるので、割愛させていただきます。。

 

ではどのくらいの量ができるのかというと

 

f:id:disuke:20201223234018p:plain

刺身一皿と

f:id:disuke:20201223234225p:plain

しゃぶしゃぶ用二皿と

f:id:disuke:20201223234357p:plain

頭と背骨を煮たやつと

f:id:disuke:20201223234545p:plain

寿司が18貫できました。

ちなみに右側3つが寿司屋の友人の作ったもので、他は素人が作りました。

僕らが作ったのは明らかにご飯が多く、しかもご飯が硬くなってしまい、おにぎりを食べている様でした。。

全部作って貰えばよかったです笑

 

昼から食べ始めましたが、桃鉄とかもしながら4時間くらいで食べ終わりました。

かなり満腹でした。。

やっぱり4人か5人が良い様な気がします

 

ちなみに一番美味しかったのは、ぶりしゃぶでした!

作り方は気まぐれクック方式です!

 

ぜひブリパーティーやる時の参考になったら良いなーと思います。

春になったら釣り系の記事も書こうかな



 

 

【SwiftUI】pickerの選択肢ごとに色を変えたかった

あまりプログラミングをしないエンジニアなのですが、SwiftUIが良さそうというのを聞いたので最近趣味感覚で書いています。

今回はpickerの選択肢ごとに色を変えたかったのでやってみました。

完成形はこんな感じです。

f:id:disuke:20201216225918p:plain

どうやるかなのですが、今回はjsonファイルで色を設定してみました。(もっと良い方法あるかもしれないです。。)

まずこんな感じのjsonファイルを用意します。idとname以外は色の設定値です。 ファイル名はAlphabets.jsonにします

{
    "alphabets":[
        {
            "id": 1,
            "name": "A",
            "hue": 0.476,
            "saturation": 0.075,
            "brightness": 0.041,
            "opacity": 0.227
        },
        {
            "id": 2,
            "name": "B",
            "hue": 0.476,
            "saturation": 0.78,
            "brightness": 0.929,
            "opacity": 0.532
        },
        {
            "id": 3,
            "name": "C",
            "hue": 0.32,
            "saturation": 0.751,
            "brightness": 0.565,
            "opacity": 0.962
        },
        {
            "id": 4,
            "name": "D",
            "hue": 0.845,
            "saturation": 0.961,
            "brightness": 0.952,
            "opacity": 0.962
        },
        {
            "id": 5,
            "name": "E",
            "hue": 0.177,
            "saturation": 0.921,
            "brightness": 0.977,
            "opacity": 0.962
        },

次はjsonデータをデコードします。

新たに下記のswiftファイルを作成します。

import Foundation

let mojis:[Alphabet] = getJson()

struct Mojis: Codable {
    var alphabets: [Alphabet]
    
}

struct Alphabet: Codable {
    var id: Int
    var name: String
    var hue: Double
    var saturation: Double
    var brightness: Double
    var opacity: Double
}

func getJson() -> [Alphabet] {
    guard let path = Bundle.main.path(
        forResource: "Alphabets", 
        ofType: "json") 
    else {
        fatalError("Couldn't find json file")
    }
    let url = URL(fileURLWithPath: path)
    
    guard let json = try? Data(contentsOf: url) 
    else {
        fatalError("parse error")
    }
    
    let decoder = JSONDecoder()
    let decodeData: Mojis
    do {
        decodeData = try decoder.decode(Mojis.self, from: json)
    }
    catch {
        fatalError("decode error")
    }
    return decodeData.alphabets
}

何をしているかというと まず、上の2つのstructはjsonファイルに合わせて作成します

そして次に、下記の様にjsonファイルを読み込んでいます

guard let path = Bundle.main.path(
        forResource: "Alphabets", 
        ofType: "json") 

次にjsonデータをデコードしています

guard let json = try? Data(contentsOf: url) 
    else {
        fatalError("parse error")
    }
    
    let decoder = JSONDecoder()
    let decodeData: Mojis
    do {
        decodeData = try decoder.decode(Mojis.self, from: json)
    }
    catch {
        fatalError("decode error")
    }

これでデータを加工できたので、次に表示していきます。

XcodeでSwiftUIのプロダクトを作成するとContentView.swiftファイルが作成されていると思うので、そこを編集していきます。
最初はこの様な感じになっています。 f:id:disuke:20201216231941p:plain ContentView.swift

なので下記の様に修正しました

import SwiftUI

struct ContentView: View {

    @State private var selected = ""

    var body: some View {
        VStack {
            Picker(selection: $selected, label: Text("アルファベット")) {
                ForEach(0..<15) { num in
                    Text(mojis[num].name)
                            .font(.body)
                        .frame(width: 200.0, height: 20.0)
                        .background(Color(
                             hue: mojis[num].hue, 
                             saturation: mojis[num].saturation, 
                             brightness: mojis[num].brightness, 
                             opacity: mojis[num].opacity))
                        .tag(mojis[num].name)
                }
            }
            Text("選択した文字: \(selected)")
        }
    }

この@Stateをつけると値を監視して、変更されると更新してくれます

@State private var selected = ""

そしてあとはPickerの使い方ですがこちらのサイトを参考にしました。

capibara1969.com

こんな感じで作成しました。

説明が雑になってしまったのですが、アドベントカレンダーで今日までということを忘れていました。。
SwiftUIは書いてて楽しいので、また書いていきたいです!

ちなみにこちらの本を参考にしました。

SwiftUIではじめるiPhoneアプリプログラミング入門 | 大津 真 |本 | 通販 | Amazon

それでは〜

まだClustalWって使われているのかな

学生の時ClustalWというDNA配列等を比較するサイトを使っていました。

最初使ったとき結構感動したので、今回久しぶりに使ってみようとなりました。

 

今年の4月くらいの話ですが、4月くらいはコロナって何物?!って感じだったので、自分で色々調べていました。

 

春のころの話で今更なのですが、年末なので今年調べたものを整理してみてこんなことやってたなーという感じになった次第です

 

調べたことは遺伝子の配列の比較です。

 

 

調べた経緯なのですが、もう半年以上も昔の話なので、調べた経緯に自信が無いのですが、

コロナウイルスウイルス表面にあるスパイクタンパク質がヒトの細胞にあるACE2に結合することで感染するみたいなので、ウイルスの遺伝子配列を比較してみるかという感じで調べてみました。

(今回は比較方法の紹介です。。結果はふーんくらいでお願いします。。)

 

学生時代に使っていたCluatalWで比較してみました。

https://clustalw.ddbj.nig.ac.jp/

f:id:disuke:20201210183516p:plain

CluatalW

Sequencesの丸の部分でDNAかたんぱく質か選べます。

今回はDNAにしました。

 

次に調べるDNAを探すのですが、NCBIのサイトで2つ探してきました

1つは↓の2017年のコウモリのコロナウイルスです

https://www.ncbi.nlm.nih.gov/nuccore/KY417144.1

 

もう1つは2020年4月くらいにでた論文のコロナウイルスです

https://www.ncbi.nlm.nih.gov/nuccore/NC_045512

 

↑のページの最後の方にDNA情報が乗っています

f:id:disuke:20201210190631p:plain


この黒枠の部分をコピーして、メモ帳などに貼り付けます。

メモ帳の置換機能を使ってスペースと数字1,2,3,4,5,6,7,8,9,0を取り除きます

 

そしてClustalWに貼り付けます

f:id:disuke:20201210191028p:plain

「>」のあとに好きな名前をつけて、その下にDNAを貼り付けます

そして一行開けて、比較するDNAを貼ります

Send to ClustalWを押すと比較してくれます

 

f:id:disuke:20201210191244p:plain

するとこんな感じで結果が返ってきます!が、見ても全然わかりません(笑)

ずっとみていたら差分が大きい場所を発見しました

f:id:disuke:20201210193409p:plain

これがスパイクたんぱく質か?ってなり、今度はこれをBlastX検索してみました

下のやつです

https://blast.ncbi.nlm.nih.gov/Blast.cgi?LINK_LOC=blasthome&PAGE_TYPE=BlastSearch&PROGRAM=blastx

BlastX検索はDNA配列からたんぱく質を検索してくれるみたいなものです。

2020年のコロナウイルスの21603番目から21827番目くらいの配列を取り出して、これをアミノ酸配列に変換してみました

f:id:disuke:20201210193817p:plain


そしたら、なんとやっぱりウイルス表面たんぱく質の配列だと分かりました。

f:id:disuke:20201210194224p:plain

ただ、ここが関係しているかどうかは分からないです。

自分の中でニュースで言われてたことが少し信ぴょう性があがったなーって感じでした。あと、学生時代を思い出して楽しかったです。