二次元配列を適用して抽選機能を実現します。


一.需要紹介:二次元配列を使って物品のパーティションを分けます。アイテムの出現の順番はパーティションの順序で、パーティション内のアイテムは重み付けランダムです。例えば、パーティション内に「アイテム1:10」があり、アイテム2:20’はアイテム1が出現する確率を10/30と表します。
二.九宮格類(コード)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/** *      * * @author insping * */
public class SudokuBody {
    String[][] sudokuItems = new String[9][9]; //       
    List<SudokuInfo> sudokuInfos = new ArrayList<>(); //           

    public SudokuBody() {

    }

    public String[][] getSudokuItems() {
        return sudokuItems;
    }

    public void setSudokuItems(String[][] sudokuItems) {
        this.sudokuItems = sudokuItems;
    }

    public List<SudokuInfo> getSudokuInfos() {
        return sudokuInfos;
    }

    public void setSudokuInfos(List<SudokuInfo> sudokuInfos) {
        this.sudokuInfos = sudokuInfos;
    }

    /** *      ItemID      * * @param totle * @param string * @return */
    private boolean SudokuInfoIsExist(int start, String string) {
        if (start >= sudokuInfos.size()) {
            return false;
        }
        for (int index = start; index < sudokuInfos.size(); index++) {
            SudokuInfo sudokuInfo = sudokuInfos.get(index);
            if (sudokuInfo == null) {
                continue;
            }
            if (sudokuInfo.getItemId().equals(string)) {
                return true;
            }
        }
        return false;
    }

    /** *           Id * * @return */
    public String randomItemFromSudokuItems() {
        String result = "";
        int size = sudokuInfos.size();
        String[] vaList = null;
        int totle = 0;
        //             
        for (int index = 0; index < sudokuItems.length; index++) {
            if (size < sudokuItems[index].length + totle) {
                vaList = sudokuItems[index];
                break;
            }
            totle += sudokuItems[index].length;
        }
        String[] values = new String[vaList.length];
        int[] rates = new int[vaList.length];
        for (int i = 0; i < vaList.length; i++) {
            String[] string = vaList[i].split(":");
            if (string.length < 1) {
                continue;
            }
            values[i] = string[0];
            if (SudokuInfoIsExist(totle, string[0])) {
                rates[i] = 0;
            } else {
                rates[i] = Integer.parseInt(string[1]);
            }
        }
        result = getRandomObj(values, rates);//   values       rates, values      
        return result;
    }

    /*************************           *************************/
    @SuppressWarnings("unchecked")
    public <T> T getRandomObj(T[] objs, int[] rates) {
        int total = 0;
        List<RateComparator> datas = new ArrayList<RateComparator>();
        for (int i = 0; i < rates.length; i++) {
            total += rates[i];
            RateComparator data = new RateComparator(objs[i], rates[i]);
            datas.add(data);
        }
        Collections.sort(datas);
        int random = random(total) + 1;
        int r = 0;
        for (RateComparator data : datas) {
            r += data.rate;
            if (random <= r) {
                return (T) data.value;
            }
        }
        return null;
    }

    private final Random RND = new Random(System.currentTimeMillis());

    static class RateComparator implements Comparable<RateComparator> {
        public Object value;
        public int rate;

        public RateComparator(Object value, int rate) {
            this.value = value;
            this.rate = rate;
        }

        @Override
        public int compareTo(RateComparator o) {
            return rate - o.rate;
        }
    };

    public int random(int size) {
        return RND.nextInt(size);
    }
}
三.テスト
//             
        SudokuBody sudokuBody = new SudokuBody();
        String[][] sudokuData = { { "item1:10", "item11:20", "item111:300" }, { "item2:10" },
                { "item3:10", "item33:20" }, { "item4:10" }, { "item5:10", "item55:10" } };
        sudokuBody.setSudokuItems(sudokuData);

        //         ,          
        int[] poses = { 5, 6, 7, 8, 9, 1, 2, 3, 4 ,3};//       
        for (int i = 0; i < poses.length; i++) {
            String id = sudokuBody.randomItemFromSudokuItems();
            //        list
            SudokuInfo info = new SudokuInfo(poses[i], id);
            sudokuBody.getSudokuInfos().add(info);
            //      
            System.out.println(" " + (i + 1) + "   :" + id);
            //       
            if (sudokuBody.getSudokuInfos().size() >= 9) {
                System.out.println("      !");
                break;
            }
        }
その中の一つの結果:第1回めくり:item 111第2回めくり札:item 11第3回めくり札:item 1第4回めくり札:item 1第5回めくり札:item 3第6回めくり札:item 33第7回めくり札:item 4第8回めくり札:item 55第9回めくり札:item 5は全部開きました!
四.重大な修正(テストしたら、一つのバグが発見されます。異なるパーティションのitemidが同じである場合、SudokuInfoIs Exist()の時にエラーが発生します。)
方法:各itemidの前に標識を付けて、itemidが唯一であることを保証します。上の例もみんなに提供して、上のによってもっと良い解決方法を提供します。
SudokuBody sudokuBody = new SudokuBody();
        String[][] sudokuData = { { "00item1:10", "01item11:20", "02item111:300" }, { "10item1:10" },
                { "20item3:10", "21item33:20" }, { "30item4:10" }, { "40item5:10", "41item55:10" } };
        sudokuBody.setSudokuItems(sudokuData);

        //         ,          
        int[] poses = { 5, 6, 7, 8, 9, 1, 2, 3, 4 ,3};
        for (int i = 0; i < poses.length; i++) {
            String id = sudokuBody.randomItemFromSudokuItems();
            //        list
            SudokuInfo info = new SudokuInfo(poses[i], id);
            sudokuBody.getSudokuInfos().add(info);
            //      
            System.out.println(" " + (i + 1) + "   :" + id.substring(2, id.length()));
            //       
            if (sudokuBody.getSudokuInfos().size() >= 9) {
                System.out.println("      !");
                break;
            }
        }
その中の一つの結果:第1回めくり:item 111第2回めくり札:item 11第3回めくり札:item 1第4回めくり札:item 1第5回めくり札:item 33第6回めくり札:item 3第7回めくり札:item 4第8回めくり札:item 5第9回めくり札:item 55は全部開きました!
五.まとめ
上記では、限定条件(九宮格)のブロック順にランダムにする方法だけを示しており、これにより、任意のトランプの抽選機能に拡張することができる。