Comment detail
マルバツゲーム (Nested Flatten)This comment is reply for 6191 yuin: お昼休みにさくっとやってみました。 ...(マルバツゲーム). Go to thread root.
出題者です。統計的には試行回数が多いほど誤差が小さくなるので、試しに100万×5回ほどやってみました。
その結果、
先攻勝ち:先攻負け:引き分け ≒ 58.5:28.8:12.7
と出ました。 そこらへんの数字の人は正解と思われます。
乱数は素直につかえば問題ないのですが、変なロジックをとおした結果、かたよりが出たりすると怖いです。 処理系によって乱数の癖が見れたりしたら面白かったかも??
全局面を探索したところ、 先攻:51.4%、後攻:30.4%、引き分け18.1% が正解のようですね。
syatさんの結果でいいのではないでしょうか。 全局面の意味がよくわかりませんが、 途中で終わったりもするので、 すべての局面が等確率で出現するわけではありません。
結果の検証用に打ち筋をすべてたどってみました。 先攻勝ち:131184(51.4%) 後攻勝ち:77904(30.5%) 引き分け:46080(18.1%) の255168通りでした。 乱数で勝負させたものは確かにsyatさんの数字に近くなったんですが・・・。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #include <stdio.h>
#include <stdlib.h>
typedef struct {
int data;
int turn;
} CELL;
/*
[0][1][2]
[3][4][5]
[6][7][8]
cell
data cellの内容
0:空白
1:o
2:x
turn 打たれたターン数
*/
//勝敗チェック
// 0 :決着まだ
// not 0:勝負あり
int check(CELL a[],int w){
int i;
//縦横
for(i=0;i<3;i++){
if((a[i*3].data==w)&&(a[i*3+1].data==w)&&(a[i*3+2].data==w)||
(a[i].data==w)&&(a[i+3].data==w)&&(a[i+6].data==w)) return -1;
}
//斜め
if((a[0].data==w)&&(a[4].data==w)&&(a[8].data==w)||
(a[2].data==w)&&(a[4].data==w)&&(a[6].data==w)) return -1;
return 0;
}
int result[3];
int analyze(CELL a[],int t,int turn){
int i;
if(turn==10){
//引き分け
result[0]++;
return -1;
}
//進行
for(i=0;i<9;i++){
if(a[i].data==0){
//置けるなら置く
a[i].data=t;
a[i].turn=turn;
//勝負判定
if(check(a,t)){
//決着
result[t]++;
}else{
//続行
analyze(a,3-t,turn+1);
}
//一手戻す
a[i].data=0;
a[i].turn=0;
}
}
return 0;
}
int main(){
int i;
CELL a[9];
//盤面初期化
for(i=0;i<9;i++){
a[i].data=0;
a[i].turn=0;
}
for(i=0;i<3;i++){
result[i]=0;
}
analyze(a,1,1);
i=result[0]+result[1]+result[2];
printf("o win:%d(%2.1f%%) x win:%d(%2.1f%%) draw:%d(%2.1f%%)\n",
result[1],100.0*result[1]/i,
result[2],100.0*result[2]/i,
result[0],100.0*result[0]/i);
return 0;
}
|
ちと違うみたいです。 58行目、 result[t]+=weight(9-turn); に直して下記コードを追加 で、 o win:212256(58.5%) x win:104544(28.8%) draw:46080(12.7%) だと思います。
1 2 3 4 | int weight(int i) {
if (i<=1) return 1;
return i*weight(i-1);
}
|
なるほど・・・ ようやく理解しました。






yuin
#6199()
[
diff
]
Rating0/0=0.00
1行ミスってました。コピペはいけませんね・・・。あらためて
という感じです。
Rating0/0=0.00-0+