オフトピック
・良いクラス名が思いつかなかった
・良いアルゴリズムが思いつかなかった
・英語のセンスが無かった
GachaItem.java
CODE:
/**
* ガチャアイテム
* @param 要素の型
*/
public abstract class GachaItem {
private T element;
/**
* ガチャアイテム
* @param element 要素
*/
public GachaItem(T element) {
this.element = element;
}
/**
* 要素の取得
* @return 要素
*/
public T getElement() {
return element;
}
/**
* 割合の取得 (0.0~1.0)
* @return 割合
*/
public abstract double getRate();
}
RatedGachaItem.java
CODE:
/**
* 割合確定済みのガチャアイテム
* @param 要素の型
*/
public class RatedGachaItem extends GachaItem {
private double rate;
/**
* レート決定済みのガチャアイテム
* @param element 要素
* @param rate 割合
*/
public RatedGachaItem(T element, double rate) {
super(element);
this.rate = rate;
}
@Override
public double getRate() {
return rate;
}
}
RateSuppliedGachaItem.java
CODE:
import java.util.function.Supplier;
/**
* 割合を頂くガチャアイテム
* @param 要素の型
*/
public class RateSuppliedGachaItem extends GachaItem {
private Supplier rateSupplier;
/**
* 割合を頂くガチャアイテム
* @param element 要素
* @param rateSupplier 割合の提供者
*/
public RateSuppliedGachaItem(T element, Supplier rateSupplier) {
super(element);
this.rateSupplier = rateSupplier;
}
@Override
public double getRate() {
return rateSupplier.get();
}
}
Gacha.java
CODE:
import java.util.Optional;
/**
* ガチャのインタフェース
* @param 要素の型
*/
public interface Gacha {
/**
* 自動で確率を割り当てるアイテムの追加
* @param element 要素
*/
void add(T element);
/**
* 指定された確率で出現するアイテムの追加
* @param element 要素
* @param percentage 確率 [%]
*/
void add(T element, double percentage);
/**
* ガチャを回し、当選アイテムの要素を返す。
* @return 当選アイテムの要素
*/
Optional roll();
}
CompleteGacha.java
CODE:
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* ソーシャルゲーム等でよくあるコンプリートガチャのクラス
* @param 要素の型
*/
public class CompleteGacha implements Gacha {
private List> ratedItems = new ArrayList();
private List> rateSuppliedItems = new ArrayList();
private final Supplier rateSupplier = () -> {
double used = ratedItems.stream().mapToDouble(GachaItem::getRate).sum();
double remain = 1.0 - used;
double divNum = rateSuppliedItems.size();
return remain / divNum;
};
@Override
public void add(T content) {
rateSuppliedItems.add(new RateSuppliedGachaItem(content, rateSupplier));
}
@Override
public void add(T content, double percentage) {
double rate = percentage / 100;
ratedItems.add(new RatedGachaItem(content, rate));
}
@Override
public Optional roll() {
List> items = getItems();
double r = Math.random();
for (GachaItem item : items) {
r -= item.getRate();
if (r > getItems() {
return Stream.concat(ratedItems.stream(), rateSuppliedItems.stream()).collect(Collectors.toList());
}
/**
* 要素のリストを取得
* @return
*/
public List getElements() {
return getItems().stream().map(GachaItem::getElement).collect(Collectors.toList());
}
}
GachaHelper.java
CODE:
import java.util.Arrays;
public class GachaHelper {
public static Gacha create(T... elements) {
Gacha gacha = new CompleteGacha();
Arrays.asList(elements).forEach(gacha::add);
return gacha;
}
}