ひよっこゲームブログ

なにもかも初心者のひよっこがゆったりと何かする

去年買った本の話

去年プログラマーとして社会に飛び立ったので流石に色々と本を買って勉強したりした
全部は読めてないんだけど、経験として晒してみる

books.rakuten.co.jp プログラマーとして入社したのが2018の12月
それより前の無職期間で作ってたUnityのゲームで散々なコードを書いて
昨日の自分を恨みながらコードを読むことが多かったので反省しながら読んだ

会社の人のコードはめちゃくちゃで頭を抱えたのはまた別の話


books.rakuten.co.jp AndroidエンジニアとなりJavaからKotlinにしよーぜって感じで唐突に始まったので読んだ
Kotlin楽しいです
新機能など追加の流れが速いので、基本で読むといいです


books.rakuten.co.jp 実際コード改修しようとしてもどうしたらいいのか分からんということで買ってきた
そしたら「テストコード書こうぜ」って書いてあって
違うんだテストが書けないくらいこんがらがってるんだ、ってことで必要な部分だけ読んでスルー


books.rakuten.co.jp 入社してちょっとしたら中途の新人の面倒を見ることになって頭を抱えて読み始めた
こいついつも頭抱えてんな

ストーリーテリングで解説してくれていて、読み物として普通に面白い
基本的にはアジャイルの話だけど、普通に組織に役に立つ考えとかあるので良い
今年に同シリーズの本がまた出るとかなんとか


books.rakuten.co.jp カイゼン・ジャーニーでふんわりと学んだことに一歩踏み込んで読める本
アジャイル銀の弾丸じゃねーぞ!って歴史的背景から解説してくれたり
ちょっと堅苦しいけどこれも面白い本でした


books.rakuten.co.jp 急にテストが欲しいとか言われたので書くことになったが知識がない
知りたいことが解説されているとこがいまいち無いので買ってきた
JUnitの他にもテストについて書いてあってためになるなぁという感じ


books.rakuten.co.jp UIテストは書けた。んでUnitテストって何ですかという疑問を抱え
和田卓人の名前を知ってそのまま買ってきた
途中まで読んだ。手を動かしながら読むのが正解かもってなって放置中・・・


books.rakuten.co.jp 古本屋でくっそ安かったので購入した
プログラマーとしてどうやっていったらいいの?みたいな本
皮肉とか満載で楽しく読める。時間が取れなくて途中までしか読んでない・・・


books.rakuten.co.jp RxJavaを学ぼうとして、デザインパターンって何?分かんねぇ!ってなって買ってきた
実際は言語やライブラリに実装されているので一から書くことはないなーって

覚えるのではなく、考え方を学べと大学の先輩に助言をもらった


番外編
books.rakuten.co.jp 組織の話やメタ認知の話が非常に役に立った

Androidの音声認識を使ってみたけど上手くいかなかった話

[ 解決 ] 停止時に

speechRecognizer.setRecognitionListener(null)

 

//---------

 

Android音声認識を使ってみたという日記

結果からいうとあんまり上手くいかなかった

(実用的じゃない気がする


ここのブログを参考にした

http://kivantium.hateblo.jp/entry/2016/02/29/191901

 

あとAndroidDeveloper

https://developer.android.com/reference/android/speech/SpeechRecognizer


SpeechRecgnizerを利用して音声認識用のクラスを作ってみたんだけど

外部からstartListening() を呼び出したあとにバックグラウンドに行くと

音声準備処理し終えたあとonRmsChanges() の処理が永久に続いてどっかいった

(なんか1回だけ上手くいったけど奇跡的で分からんかった)

 

呼び出し元のActivityのonStop() で制御したりできないかなーと思ったけどダメ

 

なんかライフサイクルに振り回されている気がするんだよなー・・・

どこかの実装が間違ってるのかなぁ

 

ちなみにForegroundServiceで実装するしないに関わらずどっかいった

 


南無三

 


そもそも音声認識を実行する時間とか一切設定できなくて

(昔はできたっぽいんだけど、現在はその操作自体が非推奨でRecognizerIntentのリファレンスに「使うな」って明記されている)


しかも 認識開始 -> 認識終了(動作終了) -> (仕方ないのでdestory()の後に再起動させる)

みたいな実装じゃないと数秒しか動かないし

(これは音声認識できたできないに関わらず終了する)


上記の実装をすると音声認識開始時にAndroidのシステム上

録音開始音が鳴るんですよね、うるさいねーん

 

そのためstartListening() の前にシステムの音量を0にして

onReadyForSpeech() が呼ばれた時点でシステム音量を復帰させる

みたいな処理じゃないといけない


そもそもGoogle的にはこの辺スパイアプリの実装っぽいので

あまりやらせたくないみたいだしー・・・


音声認識の呼び出しとかはぱっとできるし、認識の制度はいいんだけど

実装してみた感じではあまり実用的ではないかなぁみたいな・・・

 

実際使ってる人も少ないし

アプリがバックグラウンドにいっても音声認識させたいみたいな需要がない

 


設計的には

1.SpeechRecgnizerの音声認識処理を呼ぶ

2.音声認識の結果を返す

3.結果から文字列のマッチでパターンを分けて処理

でコールバックでどうにかしたいんだけど

 

その場合はSpeechRecgnizerのリスナーでonResult()に入った時

初めて動作させないといけないのでObserverパターンがいいのかしら

 

となったがデザインパターンとか全然知らんかったんで

増補改訂版Java言語で学ぶデザインパターン入門 結城 浩

https://www.amazon.co.jp/dp/4797327030/ref=cm_sw_r_tw_dp_U_x_I3E9Db9MTMA6C

これを買った。読む本だけが増えていく


動作のトリガーさえうまく掴めれば

LiveDataとかDataBindingとかその辺でうまくできそう


コールバックについて調べていたら、RxKotlinなるものがあることを知った

https://github.com/ReactiveX/RxKotlin

JVMしたいらしくて、名前の通りRxJavaのKotlin版みたい

 


学ぶことが多すぎるっぴ

Androidで使う技術の話

つよつよAndroidエンジニアになるためには
必要なんじゃねーかなぁという技術を列挙してみる


Android Jetpack
DataBinding ⇒ findViewById() 使わずレイアウトにぶち込んで同期する
LiveData ⇒ ライフサイクルに振り回されないようにするやつ
Navigation ⇒ Activity遷移の監視
Paging ⇒ リストビューとか
Room ⇒ DBにぶち込む
ViewModel ⇒ LiveDataとかDataBindingとかと一緒につかう(管理)
WorkManager ⇒ タスクの実行の管理(だったっけ


ライブラリ
RxJava ⇒ 同期処理とか(だった気がする
RxLifecycle ⇒ ライフサイクルの監視系(だった気がする
Retrofit2(okHttp) ⇒ APIめっちゃ楽
Dagger2 ⇒ 依存性注入奴。Koinってどうなんでしょうね
moshi ⇒ jsonとか使うときに
AndroidKTX ⇒ 忘れた


テスト
JUnit ⇒ この辺は前に書いた
JUnitRunner ⇒ この
Espresso ⇒ 辺
UIAutomator ⇒ 前
Robolectric ⇒ 書いた
mockito ⇒ モックのやつ


Androidの基礎とか設計とか
ライフサイクルの理解
アプリのコンポーネント
・アクティビティ ⇒ 要は画面
・サービス ⇒ 裏で動くやつな!音楽プレーヤーとかいい例
・ブロードキャストレシーバー ⇒ サービス側で受け取ったのをなんとやら
・コンテンツプロバイダ ⇒ まだ理解できてない
MVVM / クリーンアーキテクチャ ⇒ 綺麗に分離させて書けない・・・


Android周辺の知識
Firebase (FCM) ⇒ PUSH通知とかで使う
GooglePlayConsole ⇒ テストユーザーにアプリのCloserdβとか公開できる
リリース周りのあれこれ ⇒ リジェクトされたときめんどいぞ!


そのほか
Kotlin ⇒ まだまだJavaライクにしか書けてないので反省
xml ⇒ ガワ書くのめんどい
Git ⇒ まぁ
GitHub ⇒ 業務で使ってないので知識が不安すぎる
CI / CD ⇒ 業務で(略)


結構多いな
1/3くらいは使ったり理解したりできてると思う・・・

これ全部きちんと使えたら、まぁ間違いないと思う
なんかあったら誰か補足してくれ

AndroidのUIテストの話とかふんわり

denden-kata.hatenablog.com


前は軽い説明だけ書いたので、UIテストのコードとか
UIAutomatorの一部記載がdeprecatedなんだけどまぁそのうち
早く自動で動くテストが見たくてそのまま実装してしまった


これでJUnit4使える

@RunWith(AndroidJUnit4::class)
class hoge {
    // いえーい
}


実際にはこんな感じ

// ぱっけーじ
// いんぽーと

@LargeTest
@RunWith(AndroidJUnit4::class)
class testCode {

    @Rule
    @JvmField
    // テスト時に最初にいるActivity(= hogeActivity)
    // Espressoでの自動生成時にmActivityTestRuleって名前だった。変えてもいいのかしら
    var mActivityTestRule = ActivityTestRule(hogeActivity::class.java)

    @Before
    fun setUp() {
        // テストが走る前に動くのでデータの初期化とかしとけばいいんじゃない?
    }

    // UI Automator
    private val uiDevice: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

    @Test
    fun hoge() {
        // 自動生成で出てくるボタン指定クリックはクッソ長いけど1行でまとまる
        // なんか適当なボタンのid = buttonid
        // 指定したidを見つけ次第(isDisplayed())クリック
        onView(allOf(withId(R.id.buttonid), isDisplayed())).perform(click())

        // UI Automator系はR.idを直接指定できないので文字列に直す必要がある
        // -> convertToString()

        // 指定したidが表示されるまで5000ミリ秒待ってくれる 
        uiDevice.wait(Until.hasObject(By.res(convertToString(R.id.button))), 5000)
        val button = UiSelector().resourceId(convertToString(R.id.button))
        
        // UiObject Deprecated なおそうね!
        UiObject(button).click()
    }

    // idを文字列に変換するメソッドをホイ!
    private fun convertToString(resourceID: Int): String {
        return InstrumentationRegistry.getInstrumentation()
                .targetContext
                .resources
                .getResourceName(resourceID)
    }
}


UIテストのコードはだいたいこんな感じだと思う。待つのは通信時とか
あとはperform()で使ったのはこの辺

scrollTo()
スクロールする

replaceText() 
テキストボックスに文字を入力(正確には置き換え)
(直接入力する書き方もあるけど、こっちの方が正確)

closeSoftKeyboard()
そのまま。邪魔で不具合起きたりするのでキーボード閉じる


UIテストはボタンと画面があればひとまずテストとして成り立つのでしあわせ
ボタンの生成とか画面の生成を変な方法でやるのはやめようね(嗚咽)

あと自動で動くの眺めてるの楽しい


AndroidのUIテスト書くにあたって参考にした本
peaks.cc

2018年の本だけどほぼすべてこれで網羅されてる。あとは公式見る
正直定期的に出してほしいレベル。マジ

ぶっちゃけAndroidテスト本って無い。全く無い

実はO'Reillyにあるんだけど
www.oreilly.co.jp
2013年5月発行・・・
つまるとこ、Androidアプリ開発Eclipseが主体だったころですね、うむ。


Androidのテストって色んなもの使わないといけないんですけど他の分野ってどうなんですかね
テストコード書くの初めてだったもんで勝手がわからん

UnitテストはRobolectrics(実際サンプルのプロジェクトでしっかり書いてある
Retrofit2の MockWebServer, moshi
Mockito kotlinと
あとRoomとかもモック入れるためのなんかあった気がするしもうなんか色々

多い!

っていうか今のAndroidテストってどういう流れなん?
教えてすごい人!

JUnit4でなんやかんやするのはそのうちなくなりそう・・・
もうJUnit5だしね、そもそも自動生成がJUnitでJUnit4に手直ししないといかんし


最近はプライベートで勉強したことを
職場になんとか反映させよう一人で転がってる日々が続いてます

つらい


特にオチはないです

UIテストを書いたりした話

仕事暇になってテストがなかったのでAndroidのUIテストを書いてる

 

Espresso

https://developer.android.com/training/testing/espresso

 

UIAutomator

https://developer.android.com/training/testing/ui-automator

 

この2つ使っておけば何とかなる感じ

 

AndroidStudioのEspressoRecorder使ってからの手動修正

からの指定しにくいやつとかちょっと動的なやつはUIAutomatorで書いた

 

1回書き方わかるとRecorderいらなくなるくらいシンプルに書ける

というかいらない記載が多すぎる

 

Recoderで生成するとJUnitが古いバージョンなので

JUnit4で適当に手直ししていけばおっけーな感じ

 

JUnitのあんまりはっきりとした資料がなかったので本を買った(中古)

https://www.amazon.co.jp/dp/477415377X

 

概要とかテストの概念とかは今もそんなに変わらないから

読むとこ読んで普通に役に立つ感じ

 

テスト書くと分かるんだけどテスト前提になってないコードは扱いに悩む・・・

実際にユニットテスト書こうと思ったら難しすぎて吐いた

 

Bitrise使ってみる

CI/CDの知見を得るためにBitriseに手を出してみた

https://app.bitrise.io/dashboard/builds

 

CIツールだとAndroidならBitriseが良さそう

アプリの配布がdeploygateからGooglePlayConsoleに移行して

CircleCIから環境を移行させた企業も多いっすね

 

yml書かなくても全部GUIでポチポチやるだけでいいのも良い

お手軽!

 

そして実際に使ってみる

 

Githubのアカウントがあれば流れで適当に設定してOK

ブランチの名前さえ間違えなければ普通に紐づく

 

SSHの設定だけ後から行ってひとまずビルド

 

f:id:denden_kata:20191110113119p:plain

失敗しとる

 

んで、調べたらAndroidのKeyStoreファイルをアップロードしろとな

からの設定したけどビルドが通らず

 

そしてビルドの結果がメールで届く。おもろい

 

f:id:denden_kata:20191110113549p:plain

 

ビルドのログ見る限り、キャッシュを初期化しろとか書いてあった

調べると同じとこで躓いている外人兄貴も多いみたい。早くBuild Sucessが見てぇ

 

一番上は指定したブランチにPUSHしたとき自動でビルドしてくれたやつ

コミットメッセージが雑

デフォルトで設定されてるっぽい

f:id:denden_kata:20191110113420p:plain

 

ちなみにビルド失敗しまくるとヘルプチャットみたいなの飛んできて草ってなった

おもしろ

 

今日中にビルド通ればいいなぁ(他人事

 

 

アサクリ4BFが微妙だったので、ステルスについて考えてみた

なぜこんな文章を書こうと思ったかというと
Assassin's Creed 4 BlackFlag が予想以上に面白くなかったからです
まぁ無料でもらったやつなんですけどね・・・
面白くないなと思った理由は様々にあるのだけれど、ステルスが割と苦痛だった

ステルスをするゲームは結構楽しくやれたので
なんでかなぁと思いそれぞれ要素を砕きながら書きました

タイトルの選択は、自分のやったゲームってだけです

後半は文章が力尽きてます(
これだけ文章書くの疲れるんだ



■ ゲーム中に「ステルス」を行うこと


■ ステルスの面白さとは何か
リスクとリターン、緊迫感
フィールドの配置と自分の位置の関係性から次の行動を模索し、目的を達成する


■ ステルス要素のあるゲームで比較してみる(自分がやったことあるやつ)
1.METAL GEAR PW, Ground Zero
2.WATCH DOGS 2
3.Assassin's Creed 4 BlackFlag
4.PAYDAY2

・着目すべき点
a.ステルスの仕組み
b.ステルスが失敗してもリカバリーがきく仕様になっているか
c.解法が複数あるか(クリア方法の多様性)
d.ステルスの難易度をどうやって上げているか



a.ステルスの仕組み
1.METAL GEAR PW, Ground Zero
敵の視界に入らなければOK、カメラなどもある
プレイヤーが比較的安全に敵のアクションを誘発できる
(物を投げて移動させる、音を出して視線を逸らさせる、など)

2.WATCH DOGS 2
特定の領域で敵の視界に入らなければOK
ラジコンやドローンを使って潜入することができ
それらが見つかっても警戒が強化されたりするだけでプレイヤーに支障はほとんどない
(見つかったら壊されるが一定時間たてば再び使えるようになるので、あまりデメリットはない)
セーフティにステルス行為が可能
大抵はラジコンとドローンで終えることができるが
自身でオブジェクトにハッキングを行わなければいけない場合はプレイヤーが動く必要がある
基本的にはリスクが低い行動が多い

3.Assassin's Creed 4 BlackFlag
特定の領域で敵の視界に入らなければOK
プレイヤーは敵の近くにいる場合のみ敵を暗殺できる(暗殺アクション中は見つからない)
茂みに隠れている際は近くの敵をおびき寄せるアクションがある
プレイヤー側は大抵の建物は登れるので壁は無いに等しいルート取りができる

4.PAYDAY2
プレイヤーはステルス時には視認されても通報はされないがやれることが少ない
(しかし不審な行為をしていると通報される)
マスクをかぶるとアクションが増えるが銃を構える状態になるので、視認された時点で通報される
ステルス状態を利用して、現場の下見を行える



b.ステルスが失敗してもリカバリーがきく仕様になっているか
1.METAL GEAR PW, Ground Zero
GZの場合だと見つかった瞬間スローモーションになり、その間に解決できれば大丈夫になっている
見つかった場合は敵の視覚外に逃げ、一定時間隠れることができれば状況をリセットすることができる
そのかわりに増援を呼ばれる可能性がある

結論:武器が豊富なので戦うことに問題はないが、ステルスを行った方がゲームとしては楽
(武器自体の火力は高いが、弾数の問題や体力があまり高くないのでリスクの方が高い)


2.WATCH DOGS 2
基本的にはリカバーはきかず、敵を全滅させるか相手側から特定の距離をつけなければ一生追跡される
敵は素早く全滅をさせられる数でなければ永遠と増援が来る仕組みになっており
逃げた先の道から増援が来たりする
逃走を素早く行うためにはハッキングを上手く使う必要がある
真正面から戦うには火力不足であり、リスクの方が大きい

一度見つかると遮蔽物などは無意味になる(視界外へ逃げても位置を検出される仕組み)
視界外へ逃亡し、かつ相手側から一定の距離を離せば逃亡成功となる
が、逃げた先の道の真正面から車で追跡されるので振り切るにはコツがいる(難しい)

結論:逃げ切れないことはないが、時間と手間がすごい(ゲームを終了させ、再開した方が早い)
マップ攻略の場合はほぼやり直し or ますます手間がかかる


3.Assassin's Creed 4 BlackFlag
基本的にリカバーはきかない。ミッションによっては見つかった瞬間アウト。
発見されたところから一定の距離を離れるか敵を全滅させるかの2択だが
攻撃手段がタイマン形式のため戦うと不利。囲まれると無理。
マップによっては増援があるが、オブジェクトを破壊することで事前に防ぐことができる

結論:リカバーがききにくく、逃げ切れないこともないがその後にほぼ初期配置からのやり直しになる。
1発アウトもあり


4.PAYDAY2
見つかった場合は通報されれば強制的に戦闘状態フェーズに移行する
リカバリーはできないが、普通に戦えるのであまり問題はない
各ミッションをステルスで攻略するか、戦闘(ラウド)で攻略するかを選択するゲームなので問題ない

結論:ミッションによってはステルスが楽でラウドが極端に難しい場合もあるので一概には言えない
(逆もまたしかり)




c.解法が複数あるか(クリア方法の多様性)
1.METAL GEAR PW, Ground Zero
自身が使うアイテムの選択やマップのオブジェクトを利用することで、様々な方法でクリアが可能
敵に見つからずにステルスを行う
敵を各個撃破で全滅させ無力化する
武器などを用い、真正面から無力化し突破する

2.WATCH DOGS 2
自身のスキルビルドの育ち具合で難易度が変わるが、複数の方法でクリアが可能
自身が使えるスキルに応じてドローンなどの遠隔操作を利用し、ほぼ移動せずにリスクを最低限に抑える
マップ上のオブジェクトにハッキングを行い、敵を誘導させたりして無力化する
武器を利用して敵を気絶させて無力化する
武器を利用して敵を全滅させて無力化する
スキルを用いて第3者を敵を戦わせて、ほぼ無力化させて突破する

3.Assassin's Creed 4 BlackFlag
敵の数が多く敵に行えるアプローチも少ないため、マップが広い場合でも基本的には同じことをする
基本的には安全な位置からの非殺傷を繰り返すのは難しいため
見つからないように最低限殺害し無力化しながら進む
複数の敵と同時に戦う手段を持たないため、正面突破の難易度は高すぎるのであまり選択肢にはならない
敵の数が多いため完全な非殺傷を行う場合は、マップ内における高台にいる敵の位置や数に依存する

4.PAYDAY2
各ミッションやその難易度、自身のスキルビルドによって変化する
プレイ人数に応じて楽なクリア方法なども変化する
マップもランダムに変更されるので、プレイするたびに解法を変える必要がある
ミッションによって ステルス or ラウド(戦う) or どちらか選択 と幅が広い


d.ステルスの難易度をどうやって上げているか
プレイしたのが結構前なのでこの項目だけかなりお粗末です・・・
1.METAL GEAR PW, Ground Zero
敵の数
マップの複雑化

2.WATCH DOGS 2
敵の数
マップの複雑化
リスクの高い場所に自分でハッキングをする必要のあるオブジェクトが配置される
安置の数が減る

3.Assassin's Creed 4 BlackFlag
敵の数
高台に敵を多く配置することで発見されやすくなる
敵をペアで行動させている

4.PAYDAY2
敵の数
敵のステータスの強化
マップの複雑化
オブジェクトやマップのランダム性(逆に簡単になる場合もある)



■ なぜ「Assassin's Creed 4 BlackFlag」のステルスが微妙なのか
他のステルス作品と比べると1ステージごとの回答が極端に少ない
回答が少ない上に一部のステージでは見つかったら1発アウトのところもあり
とにかくリカバリーがきかない
正解にチャレンジするトライ&エラーではなく
まず正解を見つけるためのトライ&エラーを繰り返す必要がある
正解のルートを強要されているように感じた

ステルスの内容が序盤から最後までだいたい同じである (やれることが限られている)
他に挙げた作品はゲームの進行度でアイテムやスキルの強化により
ステルス中にやれることが増えていくが、このゲームは終始同じアクションを繰り返し要求される
見つかったあとのリカバリーがききにくいので
とにかく慎重に同じことを繰り返さなければいけないのもストレス

フィールドに多様性がないため、ステルスを楽しむためのアプローチの種類が少ない
そのため、何かに干渉するための回答が極端になりがち
隠れるためのオブジェクトなども最初からほぼ同じもので代り映えがない



おわり