最終構成 |
アイテム
- ニーコにタンクアイテム(※)
- ソルにモレロが必須
オプショナル
- フローズンハート → フィズ/エコー
- アイオニックスパーク → フィズ/エコー
- プロテクター → ソル
- スタガ → ソル
- ショウジン → ジャンナ/ルル
プレイ方法
- 3-6まではとにかく柔軟にプレイしHPを高く保つ
- 4-1くらいからHPを失いながらお金を貯めることになる (周りが構成だしてくるので)
- 5-1前後もしくはHP20-30くらいになったらLv9へ
- Lv9でオールインして構成を出す
プログラミング、映画、ゲームなど。
最終構成 |
試してみたらパワーを感じたので書きます。
Reddit記事の意訳・要約です。(この記事)
https://www.reddit.com/r/CompetitiveTFT/comments/dhbcft/how_to_rush_level_8_and_abuse_it/
レベル8まで耐えて節約して高コストユニット盛り盛りの超強い構成を一気に完成させる。
ナイト4/ドラゴン/ガーディアン/ソーサラー3 を目指します。
具体的には、
https://lolchess.gg/builder?deck=08f594e0edb711e9a9119f5014f5248d
こんな感じです。
この構成の強いところはパンテオンとオレリオン・ソルが非常にタフになるところです。
ドラゴンとガーディアンとナイトによってスキルと通常攻撃の両方を大きく軽減します。
この構成には コスト5が3体、コスト4が3体が必要 なので一見集めるのが非常に困難に感じると思います。
しかし、パッチ9.20でレベル8のときのコスト5ユニットの出現率が1.6倍(5%→8%)になったので、レベル8でまとまったリロールを行うことで集めることが可能になりました。
レベル8まで極力リロールせず、お金を節約し続けてください。
50G以上のお金は基本的に経験値に使用し、レベル8を急ぎます。
目安としては狼ラウンド(3-6)のあと2ラウンドほど待って、レベル8にあげてリロールを開始します。
このときHPは30以上、ゴールドは50G以上あるのが理想ですが、状況が悪ければもう少し早くリロールを開始してください。
序盤はとにかく低コストの星2ユニットを作ります。ついでにナイトも集めます。
理想はナイト4(モルデカイザー、ガレン、ダリウス、ポッピー)ですが、あまりこだわらずに星2ユニットを作って中盤に備えます。
最も重要で、一番面白いのがこの中盤です。
早いプレイヤーはこの辺りからお金を使って構成を強化し始めるので、HPを一気に失う恐れがあります。
そのため、お金を節約しつつも限られたリソースを最大限活用してHPを守ります。ここをどのように乗り切るかがポイントです。
(元記事で紹介されているのは以下の構成です。)
レベル8まで上げてリロールします。
リロール中は理想の構成にこだわりすぎず、柔軟に対応しましょう。
例えばカーサスがでなければ、別のソーサラーでもいいし、ファントムのためにキンドレッドでもいいです。ケイルがでなければ別のナイトで代用できます。
カイサやヤスオの星2を見つけたらそれを使っても強いです。この時点でコスト5の星2を持っているのはたぶんあなただけなので、シナジーが無くても使う価値があります。
リロールして構成が整ったら、HPに余裕があればもう一度エコノミーしてもいいですが、後がない場合は毎ラウンドリロールして少しでもユニットを星2にできないか試してください。
特に重要なのは ユーミ と 騎士の誓い です。どちらかがあれば構成を完成させられます。(騎士の誓いを利用する場合の構成例)
https://lolchess.gg/builder?deck=a089d2d0edc511e98c3025d32449d700
アイオニックスパーク も可能なら入手したいアイテムです。防御力に優れた構成のため、とても有効に機能します。
回転寿司では ヘラ もしくは ムダニデカイロッド を狙うのがオススメです。特に中盤はHPが減ってくるはずなので必要なアイテムを狙うチャンスです。
中盤を乗り切るためにはアイテムはできるだけ積極的に使う必要があります。最終的な構成に多少マッチしなくてもいいのでアイテムを活用してください。
このガイドを読んで早速4試合やってみました。結果は8-1-1-1でした。(プラチナ帯)
最初の一戦は要領がつかめず中盤でHPが無くなりましたが、中盤を上手く乗り切ると物凄く強いです。コスト5が本当に揃うのかなーと思いましたがたくさん出ました。
以前(2013年頃)自分が設計した内容のメモです。
今はASP.NETの世界から離れて久しい。
CQRS(コマンドクエリ責務分離)という考え方を使って、参照系と更新系でORMとSQLを使い分けていいとこ取りするという趣旨です。
サンプルを作りました。
https://github.com/herara-ofnir3/cqrs-sample
CQRSについて詳しくはぜひこちらをどうぞ。
[Greg Young流CQRS - Mark Nijhof]
http://d.hatena.ne.jp/digitalsoul/20100712/1278886009
※ 上記記事のサンプル
https://github.com/MarkNijhof/Fohjin
煩雑なSQLの発行処理を書かずとも、エンティティの状態を変化させ、永続化してやればうまいこと更新してくれます。
特に one-to-many や many-to-many の関係をカスケードしてうまく処理してくれるのは、とても素晴らしいメカニズムです。
バッチ処理的な一括更新や大量データを高速に更新するのには向いていませんが、業務アプリケーションの通常の更新処理なら非常にマッチします。
参照系の処理がやりにくいです。
普通なら簡単なSQLを投げてそのまま結果を表示するだけ、みたいな画面ですら、気にすることが多すぎます。
みたいな調子です。
どうしてもデータの取得が冗長になりがちです。
特にHQLでSQLを再現していると泣けてきます。
よく言われるORMの問題点はこの参照系の問題に集中している気がします。
どう考えてもシンプルにSQL書いたほうがはやくて確実ですし。
ORMの得意な更新系の処理だけORM使って、参照系はSQLを書けばいい、という考えに至りました。
そして、参照系と更新系の分割と一貫性のために、CQRSを適用しました。
CQRSはイベントソーシングとセットで語られることが多いのですが、イベントソーシングはスルーします。
データアクセスがクエリ(参照系)とコマンド(更新系)で違うだけの実装です。
実際やってみると色々いいところがありました。
コマンドの発行は全てコマンドバスに投げるだけになるので、
コントローラが依存するのはコマンドバスといくつかのクエリだけとなります。
そのため、アンチパターンとしてありがちなファットコントローラに陥りにくくなります。
依存関係が絞られますし、トランザクションなどの煩雑な処理が隠蔽されるため、テストが非常に簡潔になります。
自然に結合度が下がり、構造がシンプルになります。
おかげでメンバが積極的にテストを書いてくれました。
全てのコマンド(更新操作)はコマンドバスを通して発行されるので、更新処理を簡単に確実にログできます。(コマンドバスにログ処理を挟むだけ)
このあたりの機構にイベントソーシングを組み合わせると強力ですが、ログをとれるだけでも大きな恩恵を得られました。
運用・保守をする上で、現状のデータに至るまでの経緯が全て記録されているというのは、極めて有効でした。
Dapper を使っていたらハマったので。(Dapper っていうより LINQ ?)
以下のように Dapper で Single/First メソッドを使うと例外が起きることがあるようです。
var user = connection.Query<User>("select * from Users where UserName = @userName", new { userName = "hoge" }).Single();
System.InvalidOperationException: シーケンスに要素が含まれていません
クエリの結果が必ず1件あるにも関わらず、起きることがあります。また、常になるというわけではありませんでした。(環境にもよる...?)
私が遭遇したケースでは、数十回から数百回に一度程度再現しました。
原因と理由はよくわかりませんが SingleOrDefault/FirstOrDefault に変更すると発生しなくなります。
var user = connection.Query<User>("select * from Users where UserName = @userName", new { userName = "hoge" }).SingleOrDefault();
最近ハマったのでメモ。解決策は以下の記事を参考にしました。
jquery.validate.unobtrusive を IE10の互換モードで利用するとこんなエラーが出ることがあります。
行: 2699 エラー: メンバーが見つかりません。
どうやらページ内に form
があるだけで起こるようで、jQuery その他のスクリプトが全滅して全く動かなくなります。怖い。
なんとなく IE10 の互換モードのバグっぽい雰囲気ですが、時間がなかったためあまり詳しく調べることができませんでした。(いいわけ)
jQuery の以下の set メソッド呼び出しで、novalidate
という属性を設定しようとしてエラーが発生しているようです。
nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret; ret = elem.getAttributeNode( name ); return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? ret.nodeValue : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { ret = document.createAttribute( name ); elem.setAttributeNode( ret ); } return ( ret.nodeValue = value + "" ); } };
いろいろな記事を見て回ると、jQuery の中身を書き換えたりする方法もありましたが、ちょっと怖いので互換モードの指定で逃げました。
以下のように X-UA-Compatible
で IE が利用可能な最新のレンダリングモードを指定します。
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
いろいろなところでこの問題がおきてテンション下がりました。
jquery.validate.unobtrusive は ASP.NET MVC のテンプレートに入っているし、form
がページ内にあるだけでエラーが起こるので、結構影響大きいのではと思うのですが、全然日本語の記事がなかったので書いてみました。
単一の値を表すオブジェクトのことで、いわいる不変オブジェクトのことです。(イミュータブルってやつですね)
例えばこんな感じのヤツですね。
public class Version { public Version(int major, int minor) { Major = major; Minor = minor; } public int Major { get; private set; } public int Minor { get; private set; } public override string ToString() { return string.Format("{0}.{1}", Major, Minor); } }
Major, Minor といったプリミティブ値を Version という型にまとめ、状態を変えれないようにすることで扱いがシンプルになります。
これはオブジェクト指向プログラミングのプラクティスとしてよく言われるものですが、ASP.NET MVC で不変オブジェクトを扱うと困ることがあります。
例えばこんなURLを使いたいと思って、アクションを用意するとします。
/Home/SomeAction?version=1.2
public ActionResult SomeAction(Models.Version version) { ViewBag.Version = version; // version は null で、ModelState にもエラーが入る return View("SomeView"); }
当然 version
引数にはクエリパラメータで指定した "1.2" が Major と Minor に入ってきてほしいと思うわけですが、これはうまくいきません。
それもそのはずで、Version という型にどのように値を入れていいか、モデルバインダが知らないからです。
せっかく値オブジェクトをコツコツ作っても、モデルバインダで使えないのでは寂しいので、カスタムのモデルバインダを作りましょう。
上記の Version 型の場合はこんな感じのモデルバインダを作ります。
public class VersionBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var valueKey = bindingContext.ModelName; var valueResult = bindingContext.ValueProvider.GetValue(valueKey); string rawValue = null; if (valueResult != null) rawValue = valueResult.AttemptedValue; if (string.IsNullOrEmpty(rawValue)) return null; Version result; if (Version.TryParse(rawValue, out result)) { return result; } else { bindingContext.ModelState.AddModelError( valueKey, string.Format("'{0}' は無効な値です。", rawValue) ); return null; } } }
実際の文字列からの変換は TryParse パターン とかで適当に実装します。
上記のように作ったモデルバインダを、Application_Start 時に登録します。
App_Start ディレクトリに、以下の様な起動用クラスをまとめるといいと思います。
public class BinderConfig { public static void RegisterBinders(ModelBinderDictionary binders) { binders.Add(typeof(Models.Version), new VersionBinder()); } }
これを Global.asax の Application_Start メソッドで呼んであげます。
protected void Application_Start() { // その他いろいろな起動設定... BinderConfig.RegisterBinders(ModelBinders.Binders); // その他いろいろな起動設定... }
これで Version 型の値がしっかりモデルバインディングされます。
モデルバインディングしたい値オブジェクトがたくさんあったら、一つ一つカスタムのモデルバインダを実装するのは恐ろしく面倒です。
コードも定形なのでスーパークラスにまとめると楽です。
public abstract class ValueObjectBinder<T> : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var valueKey = bindingContext.ModelName; var valueResult = bindingContext.ValueProvider.GetValue(valueKey); string rawValue = null; if (valueResult != null) rawValue = valueResult.AttemptedValue; if (string.IsNullOrEmpty(rawValue)) return null; T result; if (TryParse(rawValue, out result)) { return result; } else { bindingContext.ModelState.AddModelError( valueKey, GetParseErrorMessage(rawValue) ); return null; } } protected abstract bool TryParse(string input, out T result); protected virtual string GetParseErrorMessage(string rawValue) { return string.Format("'{0}' は無効な値です。", rawValue); } }
さっきの Version 型の場合、コレを使うとこうなります。
public class VersionBinder : ValueObjectBinder<Version> { protected override bool TryParse(string input, out Version result) { return Version.TryParse(input, out result); } }
これならまあ作ってもいいかなってレベルじゃないでしょうか。もし大規模なアプリケーションでこれでも大変なら、T4 とか使う手もありそうです。
これで値オブジェクトをたくさん使えるよ。
こちらのガイドの自分用まとめです。 https://www.reddit.com/r/CompetitiveTFT/comments/hraunp/tft_1014_break_the_meta_new_peeba_comp_set_35/ 難しいですが完成すると非常に強く、プレ...