多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > 互聯(lián)網(wǎng) > 我的游戲服務(wù)器類(lèi)庫(kù) -- 按權(quán)重隨機(jī)選擇1個(gè)或n個(gè)對(duì)象

我的游戲服務(wù)器類(lèi)庫(kù) -- 按權(quán)重隨機(jī)選擇1個(gè)或n個(gè)對(duì)象

來(lái)源:程序員人生   發(fā)布時(shí)間:2014-10-02 08:00:01 閱讀次數(shù):3342次

按權(quán)重選擇

在編寫(xiě)游戲服務(wù)器的時(shí)候,經(jīng)常會(huì)遇到類(lèi)似的需求:從列表中隨機(jī)選出1個(gè)或多個(gè)條目,且條目是有權(quán)重的(權(quán)重越大,選中它的可能性就越大)。比如說(shuō),砍死一個(gè)怪物可以從一個(gè)裝備列表里掉一個(gè)裝備。這種需求,和現(xiàn)實(shí)生活中的幸運(yùn)大轉(zhuǎn)盤(pán)很類(lèi)似:

算法實(shí)現(xiàn)

因?yàn)檫@種需求很常見(jiàn),所以我想把它寫(xiě)的通用一點(diǎn)。首先,接口Weighted表示有權(quán)重值的對(duì)象,getWeight()方法返回權(quán)重值:

public interface Weighted { public int getWeight(); }
WeightedBase是Weighted接口的抽象實(shí)現(xiàn):

public abstract class WeightedBase implements Weighted { private final int weight; public WeightedBase(int weight) { if (weight <= 0) { throw new IllegalArgumentException("weight <= 0!"); } this.weight = weight; } @Override public int getWeight() { return weight; } }
WeightedInt表示擁有權(quán)重值的整數(shù):

public class WeightedInt extends WeightedBase { private final int value; public WeightedInt(int weight, int value) { super(weight); this.value = value; } /** * 返回整數(shù)值. * @return */ public int getValue() { return value; } }

因?yàn)椴⒉皇敲總€(gè)類(lèi)都可以實(shí)現(xiàn)Weighted接口或繼承WeightedBase(比如第三方庫(kù)里的類(lèi)),所以增添了WeightFunction接口來(lái)表示權(quán)重計(jì)算函數(shù),apply()方法根據(jù)給定對(duì)象,計(jì)算出其權(quán)重值:

public interface WeightFunction<T> { public int apply(T t); }
最后是工具類(lèi)WeightUtil,具體的選擇算法在這個(gè)類(lèi)中實(shí)現(xiàn),下面是這個(gè)類(lèi)的方法列表:

public class WeightUtil { public static <T extends Weighted> List<T> select(List<T> list, int n) public static <T> List<T> select(List<T> list, int n, WeightFunction<T> wf) public static <T extends Weighted> T selectOne(List<T> list) public static <T extends Weighted> T selectOne(List<T> list, int randomInt) public static <T> T selectOne(List<T> list, WeightFunction<T> wf) public static <T> T selectOne(List<T> list, int randomInt, WeightFunction<T> wf) }
其中最重要的一個(gè)方法是接收三個(gè)參數(shù)的selectOne()方法,其他方法都依賴這個(gè)方法,其代碼如下所示:

public static <T> T selectOne(List<T> list, int randomInt, WeightFunction<T> wf) { if (list.isEmpty()) { throw new IllegalArgumentException("empty list!"); } if (randomInt < 0) { throw new IllegalArgumentException("negative randomInt: " + randomInt); } if (list.size() == 1) { return list.get(0); } int weightSum = 0; for (T obj : list) { weightSum += wf.apply(obj); if (weightSum > randomInt) { return obj; } } String msg = String.format("total weight (%d) <= randomInt (%d)", weightSum, randomInt); throw new IllegalArgumentException(msg); }

GitHub項(xiàng)目

想要完整的代碼,可以clone我的GitHub項(xiàng)目。此文章只是一個(gè)開(kāi)始,希望以后可以把更多的代碼放到這個(gè)項(xiàng)目里。


生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 韩国片在线观看 | 欧美另类videosbestse | 日韩一级片在线免费观看 | 亚洲伊人成人网 | 色操网| 欧美亚洲另类一区中文字幕 | 日产一区二区三区四区 | yy6080私人影院理论 | 国产精品国产三级国产a | 国产福利一区二区精品免费 | 中文国产成人精品久久一区 | 99福利网| 最近免费的中文字幕一 | 亚洲图片小说综合 | 国产三级观看久久 | 最新的国产成人精品2022 | 欧美成人黄色小说 | 不卡精品国产_亚洲人成在线 | 亚洲精品国产精品国自产网站 | 国产20岁美女一级毛片 | 欧美一级三级 | 亚洲国产成人久久一区www妖精 | 国产精品一区欧美激情 | 亚洲一级在线 | 国产成人麻豆精品 | 午夜肉伦伦影院在线观看 | 亚洲人xxx| 亚洲精品国产第一区二区三区 | 亚洲欧美另类视频 | 天堂在线视频观看 | 欧美一区二区三区国产精品 | 性国产videofree另类 | 精品一区二区三区 不卡高清 | 国产日产高清欧美一区二区三区 | 看日本黄色大片 | 久久综合九色综合欧洲色 | 最新欧美日韩 | 国产精品久久久久国产精品 | 一级毛片特级毛片国产 | 日韩精品网站 | 成人中文字幕在线观看 |