Comment detail
マルバツゲーム:賢いプレイヤー (Nested Flatten)This comment is reply for 6244 syat: AIぽい解だと思います。この方法を使えば...(マルバツゲーム:賢いプレイヤー). Go to thread root.
できるとわかっていても結構骨が折れますね。大分思考のコードが変わってしまいました。はぁ~。限界!
色々考えながら、みながら、こねていった感じです。5時間くらいかかりましたよ。 データテーブルたくさん書いたので読みにくいと思います。自分でも明日になったらよめないとおもいます。orz
結果は重要でない奴は適当に端折っています。
Result:
Random Player.[36] BetterThinkPlayer.[882] Draw[82]
Random Player.[40] BetterThinkKiller.[870] Draw[90]
BetterThinkKiller.[1] BetterThinkPlayer.[0] Draw[0] ランダム要素なし
BetterThinkPlayer.[0] MoreBetterPlayer.[0] Draw[1] ランダム要素なし
BetterThinkKiller.[0] MoreBetterPlayer.[0] Draw[1] ランダム要素なし
MoreBetterPlayer.[0] BetterThinkKiller.[0] Draw[1] ランダム要素なし
MoreBetterPlayer.[953] Random Player.[0] Draw[47]
Random Player.[0] MoreBetterPlayer.[8331] Draw[1669]
システムのコードをさらにマイナーアップデートしましたが、長すぎるので省略します。アップローダがあれば融通きくんですけどねぇ。プロジェクトをZip圧縮して8kbくらいでした。おっと。これはいいか。
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 | #pragma once
#include "Player.h"
class MoreBetterPlayer:public Player{//長さ3専用っていうか最適化しちゃった。。。
public:
char*GetName(){ return "MoreBetterPlayer.";}
void Play(MBGame& in){
if(in.HasEmpty() && in.Length()>3) {
while(in.SetStone(rand()%in.Length(),rand()%in.Length(),Mark_));
return;
}
//マスの重み
short Point[]={ 31,26 ,31,
26,100,30,
31,27 ,32,
};
int op=0;
think(in,Point,9);
do{
if(!in.HasEmpty()) return;
for(int i=0;i<9;i++){
if(Point[i] >Point[op]){
op=i;
}
}
Point[op]=-30000;
}while(!in.SetStone(op%3,op/3,Mark_));
}
protected:
void think(MBGame& in,short Point[],int N){
const short Posi = 10;
const short Nega = -10;
const short danger =999;
char Lines[8][3]={
{0,1,2},{3,4,5},{6,7,8},//横
{0,3,6},{1,4,7},{2,5,8},//縦
{0,4,8},{2,4,6},//斜め
};
char Corner[4] = {0,2,6,8};//角
char Hole[4] = {1,3,5,7};//変の真ん中。
char Line2[4][3] = { {0,1,2},{0,3,6},{6,7,8},{2,5,8},};//辺のライン
char Line3[4][2] ={ {0,1},{0,3},{1,2},{2,3}};//ラインの組み合わせ。
char Corner2[2][2]={{0,8},{2,6}};
for(int i=0;i<2;i++){//死にパターンつぶし2。角とその対角にコマがおかれてしまったら、さらに別の角にコマを置かれて死んでしまう。
Mark M1 = in.At(Corner2[i][0]);
Mark M2 = in.At(Corner2[i][1]);
if(M1 == M2 && M1 != Mark_ && M1!= None){
for(int j=0;j<4;j++){
Point[Hole[i]]+= Posi;
}
}
}
for(int i=0;i<4;i++){//死にパターンつぶし。ある角で繋がっている二辺に一個ずつコマがあって、次その接点である角にコマをおかれると死んでしまう。
int P=0;
for(int j=0;j<2;j++){
for(int k=0;k<3;k++){
int N = Line2[Line3[i][j]][k];
Mark M = in.At(N);
if(M == Mark_ ) P++;
if(M != Mark_ && M != None ) P--;
}
}
if(P <= -2) {
Point[Corner[i]] += Posi;
}
}
if(in.At(1,1) == Mark_){//真ん中を自分がとってる場合、敵の4隅の重要性はほぼ他のマスと同じなので急がなくてもよい。って考えた。
for(int i=0;i<4;i++){
Point[Corner[i]]+=Nega;
}
}
for(int i=0;i<8;i++){//超危ない時の判定
int P=0;
int x=0,y=0;
for(int j=0;j<3;j++){
int N= Lines[i][j];
Mark M = in.At(N);
if(M == Mark_) P++;
if(M != None && M != Mark_) P--;
}
for(int j=0;j<3;j++){
if(P == 2) Point[Lines[i][j]]+=danger+100;
if(P == -2) Point[Lines[i][j]]+=danger-100;
}
}
}
};
|





匿名
#6251()
Rating0/0=0.00
すごい面白いです。 自分はデバッグ時には思いつきませんでした。orz
割り切り方で負けちゃうんですね。 対策したいと思います。