進化の可否を判定する
キャラが進化可能かを判定する。
判定ルールは、前回内容を参照してください。
https://qiita.com/puyon/items/3343f1b0850bcacda66e
判定ルールをチェックするうえで必要になるのは以下の条件
・自身を除く、キャラが必要数あるか
【例】
キャラA(レアリティSR)が2個ある場合⇒進化可能(同一キャラあり)
キャラA(レアリティSR)が1個、キャラB(レアリティSR)が1個ある場合⇒進化不可(同一キャラなし)
ということで、判定チェックを実装するために以下の実装が必要になりそうなのがわかった。
・自身かどうか
・必要数あるか
自身かの判定
自身かの判定というのは、2個のインスタンスが同じものかを判定するわけなのだが、インスタンスが所持しているプロパティの値を比較したい。
こぱちゃんに「インスタンスを比較したい」と聞いてみたら、「IEquatable」インターフェースから派生させたクラスを作ったらいいと教えてもらった。
「IEquatable」インターフェースから派生させたクラスでは、以下のオーバーライドメソッドを実装する必要があるとのこと。
ちょっと解説
メソッド | 役割 |
---|---|
override bool Equals(...) | 指定インスタンスと「型と値」が一致しているか |
override int GetHashCode() | 同じかどうかの判定値(ハッシュ)を生成 |
ということで、判定用クラスを用意
※キャラ管理で利用したクラスと同じプロパティを用意
/// <summary>
/// キャラ管理
/// </summary>
public class MemeMoriCharRecepter : IEquatable<MemeMoriCharRecepter>
{
:
: キャラ管理で利用したクラスと同じプロパティを用意
:
このクラスに、オーバーライドメソッドを追加
public bool Equals(MemeMoriCharRecepter other)
{
return this.Attr == other.Attr &&
this.CharID == other.CharID &&
this.AuxName == other.AuxName &&
this.Name == other.Name &&
this.Rarity == other.Rarity &&
this.Armor.Equals(other.Armor)
;
}
public override bool Equals(object obj)
{
return obj is MemeMoriCharRecepter other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + Attr.GetHashCode();
hash = hash * 31 + CharID.GetHashCode();
if (AuxName != null)
hash = hash * 31 + AuxName.GetHashCode();
hash = hash * 31 + Name.GetHashCode();
hash = hash * 31 + Rarity.GetHashCode();
hash = hash * 31 + Armor.GetHashCode();
return hash;
}
}
※「unchecked」はC#の文法で、演算結果オーバーフローを無視するらしい。
※ハッシュ値の算出方法は、ここでの手法が高速でお手軽とのこと。
必要数の判定:同一キャラ
必要数の判定には、特定の属性として登録されたキャラ情報が必要になる。
それ用のクラスを用意して、チェックメソッドを作ろうと思った。
/// <summary>
/// 1段階進化チェック
/// </summary>
public class EvoCheckResultRarity
{
private int sumSameRarity(MemeMoriRarity rarity, List<MemeMoriCharRecepter> chList, MemeMoriCharRecepter chExcl)
{
return chList.Count(ch => !chExcl.Equals(ch) && ch.Rarity == rarity);
}
/// <summary>
/// 同じキャラの指定レアリティ(下位レアリティ)のキャラ数を確認する
/// </summary>
public void checkSameChars(MemeMoriRarity rarity, int need, List<MemeMoriCharRecepter> chList, MemeMoriCharRecepter chExcl)
{
//同一キャラID内の、指定レアリティの所持数を合算
int sum = sumSameRarity(rarity, chList, chExcl);
if (sum >= need)
{
//一致したレアリティのキャラ全てが進化可能
}
else
{
//一致したレアリティのキャラ全てが進化不可
}
}
}
ちょっと解説
メソッド | 役割 |
---|---|
sumSameRarity | 必要数あるかの確認 |
checkSameChars | 同一キャラ進化チェック |
※List<MemeMoriCharRecepter> chList:チェック対象キャラを含む属性の全キャラ
※MemeMoriCharRecepter chExcl:チェック対象キャラ
チェック呼び出しの例(SR → SR+ 進化チェック)
//SR → SR+:同じキャラ,2枚必要
var evoSRP = new EvoCheckResultRarity();
evoSRP.checkSameChars(MemeMoriRarity.SR, 1, makeSameIds(), ch);
※makeSameIds():同一IDを持つ属性内キャラ
必要数の判定:同一属性、レアリティ
おなじノリで、他の進化チェックも実装
/// <summary>
/// 同じ属性の指定レアリティ(下位レアリティ)のキャラ数を確認する
/// </summary>
public void checkSameAttrs(MemeMoriRarity rarity, int need, MemeMoriCharsMap charList, MemeMoriCharRecepter chExcl)
{
//指定属性内の、全キャラ
int sum = 0;
foreach (var chKvp in charList)
{
var chID = chKvp.Key;
var chList = chKvp.Value;
sum += sumSameRarity(rarity, chList, chExcl);
}
if (sum >= need)
{
//一致したレアリティのキャラ全てが進化可能
}
else
{
//不足している
}
}
/// <summary>
/// 同じキャラの指定レアリティ(下位レアリティ)と
/// 指定下位レアリティ(さらに下位レアリティ)のキャラ数を確認する
/// </summary>
public void checkSameChars2(MemeMoriRarity rarity, MemeMoriRarity rarityLow, int needLow, MemeMoriCharsMap charList, MemeMoriCharRecepter chExcl)
{
//指定属性内の、全キャラ
foreach (var chKvp in charList)
{
var chID = chKvp.Key;
var chList = chKvp.Value;
//チェック対象レアリティか?
if (chExcl.Rarity != rarity)
continue;
//下位キャラ数をチェック
var numsLow = sumSameRarity(rarityLow, chList, chExcl);
if (numsLow >= needLow)
{
//進化可能数が揃っている
}
else
{
//不足している
}
}
}
次は、進化判定結果の表示
進化判定の結果をUI表示したい。
1つ上位へのレアリティ進化チェック結果なのだが。
もう少し発展させて、本家アプリにはない「もっと上位の進化判定」を考えたいと思う。
つづく。
https://qiita.com/puyon/items/af05014b9a235f5e7aa0