数牌?

by uwi
♥0 | Line 198 | Modified 2009-06-27 02:57:50 | MIT License
play

ActionScript3 source code

/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ocsy
 */

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" 
creationComplete="onCreationComplete()"
>
    <mx:Script>
        <![CDATA[
            import mx.collections.*;
            
            [Bindable]
            private var _result : ArrayCollection = new ArrayCollection();
            
            private var _targs : Array;
            
            private function onCreationComplete() : void
            {
                var sort : Sort = new Sort();
                sort.fields = [new SortField("point", true, true, true)];
                _result.sort = sort;
                
                _targs = makeTargs();
            }
            
            private function onSubmit() : void 
            {
                var cts : Array = [0, 0, 0, 0, 0, 0, 0, 0, 0];
                var i : int;
                for(i = 0;i < code.text.length;i++){
                    var ct : int = int(code.text.charAt(i)) - 1;
                    cts[ct]++;
                    if(cts[ct] > 4)return;
                }
                
                _result.disableAutoUpdate();
                _result.removeAll();
                for each(var targ : Array in _targs){
                    if(minus(targ, cts) > 2)continue;
                    if(minus(cts, targ) > 2)continue;
                    var d : Object = diff(targ, cts);
                    d.point = calcPoint(cts, d.picks);
                    d.picks = plus1(d.picks);
                    d.drops = plus1(d.drops);
                    d.arrangement = countToArrangement(targ).join("");
                    _result.addItem(d);
                }
                hits.text = _result.length.toString() + " hits!";
                _result.enableAutoUpdate();
                _result.refresh();
            }
            
            // 実現確率を計算。分母はいい加減
            private static function calcPoint(cts : Array, picks : Array) : Number
            {
                var v : int;
                
                var left : Array = [];
                for each(v in cts)left.push(4 - v);
                
                var ret : Number = 1;
                for each(v in picks){
                    ret *= left[v];
                    left[v]--;
                }
                return ret / Math.pow(100, picks.length);
            }
            
            // 全要素を+1する
            private static function plus1(src : Array) : Array
            {
                var ret : Array = [];
                for each(var v : int in src){
                    ret.push(v + 1);
                }
                return ret;
            }
            
            // 具体的にどの牌が必要でどの牌を捨てればいいかを得る
            private static function diff(targ : Array, src : Array) : Object
            {
                var picks: Array = [];
                var drops : Array = [];
                var j : int;
                for(var i : int = 0;i < 9;i++){
                    if(targ[i] == src[i])continue;
                    if(targ[i] < src[i]){
                        for(j = targ[i]; j < src[i];j++){
                            drops.push(i);
                        }
                    }else{
                        for(j = src[i]; j < targ[i];j++){
                            picks.push(i);
                        }
                    }
                }
                return {picks : picks, drops : drops};
            }
            
            // 目標まで必要な牌の数
            private static function minus(targ : Array, src : Array) : int
            {
                var sum : int = 0;
                for(var i : int = 0;i < 9;i++){
                    var v : int = targ[i] - src[i];
                    if(v > 0)sum += v;
                }
                return sum;
            }
            
            // カウントを並びに変換
            private static function countToArrangement(src : Array) : Array
            {
                var ret : Array = [];
                for(var i : int = 0;i < 9;i++){
                    for(var j : int = 0;j < src[i];j++){
                        ret.push(i + 1);
                    }
                }
                return ret;
            }
            
            // 全通り列挙 10000前後だと思う
            private function makeTargs() : Array
            {
                var targs : Object = {}
                
                var targ : Array = [0, 0, 0, 0, 0, 0, 0, 0, 0];
                targs[targ.toString()] = targ.concat();
                for(var i : int = 0;i <= 15;i++){
                    for(var a : int = 0;a < 9;a++){
                        if((i & 1) == 0){
                            if(a >= 7)break;
                            targ[a]++; targ[a + 1]++; targ[a + 2]++;
                        }else{
                            targ[a] += 3;
                        }
                        if(isValid(targ))targs[targ.toString()] = targ.concat();
                        for(var b : int = a + (i & 1);b < 9;b++){
                            if((i & 2) == 0){
                                if(b >= 7)break;
                                targ[b]++; targ[b + 1]++; targ[b + 2]++;
                            }else{
                                targ[b] += 3;
                            }
                            if(isValid(targ))targs[targ.toString()] = targ.concat();
                            for(var c : int = b + ((i >> 1) & 1);c < 9;c++){
                                if((i & 4) == 0){
                                    if(c >= 7)break;
                                    targ[c]++; targ[c + 1]++; targ[c + 2]++;
                                }else{
                                    targ[c] += 3;
                                }
                                if(isValid(targ))targs[targ.toString()] = targ.concat();
                                for(var d : int = c + ((i >> 2) & 1);d < 9;d++){
                                    if((i & 8) == 0){
                                        if(d >= 7)break;
                                        targ[d]++; targ[d + 1]++; targ[d + 2]++;
                                    }else{
                                        targ[d] += 3;
                                    }
                                    if(isValid(targ))targs[targ.toString()] = targ.concat();
                                    if((i & 8) == 0){
                                        targ[d]--; targ[d + 1]--; targ[d + 2]--;
                                    }else{
                                        targ[d] -= 3;
                                    }
                                }
                                if((i & 4) == 0){
                                    targ[c]--; targ[c + 1]--; targ[c + 2]--;
                                }else{
                                    targ[c] -= 3;
                                }
                            }
                            if((i & 2) == 0){
                                targ[b]--; targ[b + 1]--; targ[b + 2]--;
                            }else{
                                targ[b] -= 3;
                            }
                        }
                        if((i & 1) == 0){
                            targ[a]--; targ[a + 1]--; targ[a + 2]--;
                        }else{
                            targ[a] -= 3;
                        }
                    }
		}

                var targs2 : Array = [];
                for each(targ in targs){
                    targs2.push(targ.concat());
                    for(var e : int = 0;e < 9;e++){
                        targ[e] += 2;
                        if(isValid(targ))targs2.push(targ.concat());
                        targ[e] -= 2;
                    }
                }
                
                return targs2;
            }
            
            // 1種5枚以上になってないか
            private static function isValid(targ : Array) : Boolean
            {
                for each(var v : int in targ){
                    if(v > 4)return false;
                }
                return true;
            }
        ]]>
    </mx:Script>
    
    <mx:HBox width="100%">
        <mx:TextInput id="code" text="123456789" restrict="1-9" maxChars="14" />
        <mx:Button label="けいさん!" click="onSubmit()" />
        <mx:Label id="hits" />
    </mx:HBox>
    <mx:DataGrid dataProvider="{_result}" width="100%" height="100%">
        <mx:columns>
            <mx:DataGridColumn dataField="arrangement" />
            <mx:DataGridColumn dataField="picks" />
            <mx:DataGridColumn dataField="drops" />
            <mx:DataGridColumn dataField="point" />
        </mx:columns>
    </mx:DataGrid>
</mx:Application>