数牌?
♥0 |
Line 198 |
Modified 2009-06-27 02:57:50 |
MIT License
archived:2017-03-30 04:56:45
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>