マイクロ将棋コード
chessはマイクロコードの文化があるので、
http://home.hccnet.nl/h.g.muller/max-src2.html
将棋はどうだろう?と思って
急に超短い将棋のコードを書きたくなったので、
書いてたんですが、
まだバグがあってまともに動きませんが、
今日の所は作業中止。
飽きなければ、明日もデバッグを続けます。
ただし、今のところ歩と王しかないです。まだ作りかけなのでと金の動きとか無し
現在218行
こういうのこそtempleteでさらに短くなりそう
http://props.at.infoseek.co.jp/microshogi.cpp
#include <stdio.h> #include <stdlib.h> #define flip(a) ((a)^0x10) enum { MUGEN=30000, PROMOTE=0x08, WALL=0xff, SELF=0x00, ENEMY=0x10, FU=1,KY=2,KE=3,GI=4,KI=5,OU=6,KA=7,HI=8, TO=FU|PROMOTE,UM=KA|PROMOTE,RY=HI|PROMOTE, SFU=SELF|FU,SOU=SELF|OU,STO=SELF|TO,SRY=SELF|RY, EFU=ENEMY|FU,EOU=ENEMY|OU,ETO=ENEMY|TO,ERY=ENEMY|RY }; typedef struct { int to;int from;char koma;char promote;char capture; } Te; Te GoodTe[32][32]; char ban[13*16]; char hand[16*2]; char snifu[16]; char enifu[16]; int komav[16*2]; int teban=0; char csa[16][4]={ "・","歩","","","","","王","","","","","","","","","" }; void init() { komav[SFU]=100;komav[EFU]=-100; komav[SOU]=15000;komav[EOU]=-15000; teban=0; for(int y=0;y<13;y++) for(int x=0;x<16;x++) ban[y*16+x]=WALL; for(int y=2;y<=10;y++) for(int x=1;x<=9;x++) ban[y*16+x]=0; for(int x=1;x<=9;x++) ban[4*16+x]=EFU; for(int x=1;x<=9;x++) ban[8*16+x]=SFU; ban[2*16+5]=EOU; ban[10*16+5]=SOU; for(int i=SFU;i<=ERY;i++) hand[i]=0; for(int i=1;i<=9;i++) snifu[i]=enifu[i]=1; } int generate(char turn,Te t[]) { int tp=0; if(turn==SELF) { for(int y=2;y<=10;y++) for(int x=1;x<=9;x++) { int pos=x+y*16; if(ban[pos]==SFU) { if( ban[pos-16]&SELF ) continue; t[tp].from=pos;t[tp].to=pos-16;t[tp].koma=SFU; t[tp].promote=0; if(t[tp].to<5*16 || t[tp].from<5*16) t[tp].promote=1; tp++; } else if( ban[pos]==0 ) { for(int i=SFU;i<=SRY;i++) { if( i==SFU && snifu[x] ) continue; if(hand[i]) { t[tp].from=0;t[tp].to=pos;t[tp].koma=i; t[tp].promote=0;tp++; } } } } } else { for(int y=2;y<=10;y++) for(int x=1;x<=9;x++) { int pos=x+y*16; if(ban[pos]==EFU) { if( ban[pos+16]&ENEMY ) continue; t[tp].from=pos;t[tp].to=pos+16;t[tp].koma=EFU; t[tp].promote=0; if(t[tp].to>7*16 || t[tp].from>7*16) t[tp].promote=1; tp++; } else if( ban[pos]==0 ) { for(int i=EFU;i<=ERY;i++) { if( i==EFU && enifu[x] ) continue; if(hand[i]) { t[tp].from=0;t[tp].to=pos;t[tp].koma=i; t[tp].promote=0;tp++; } } } } } return tp; } void move(int turn,Te t) { if( t.from==0 && hand[t.koma]<=0 ) exit(1); if( t.from && ban[t.from]!=t.koma ) exit(1); teban++; if( t.from==0 ) { hand[ t.koma ]--; ban[ t.to ]=t.koma; if( t.koma==SFU ) snifu[t.to%16]=1; if( t.koma==EFU ) enifu[t.to%16]=1; } else { t.capture=ban[t.to]; if(t.capture) { hand[ flip(t.capture) ]++; if( t.capture==SFU ) snifu[t.to%16]=0; if( t.capture==EFU ) enifu[t.to%16]=0; } if(t.promote) ban[t.to]=t.koma|PROMOTE; else ban[t.to]=t.koma; ban[t.from]=0; } } void undo(int turn,Te t) { teban--; if( t.from==0 ) { hand[ t.koma ]++; ban[ t.to ]=0; if( t.koma==SFU ) snifu[t.to%16]=0; if( t.koma==EFU ) enifu[t.to%16]=0; } else { ban[t.from]=t.koma; if(t.capture) { hand[ flip(t.capture) ]--; if( t.capture==SFU ) snifu[t.to%16]=1; if( t.capture==EFU ) enifu[t.to%16]=1; ban[t.to]=t.capture; } else ban[t.to]=0; } } int eval(char turn) { int score=0; for(int y=2;y<=10;y++) for(int x=1;x<=9;x++) { score += komav[ ban[y*16+x] ]; } for(int i=SFU;i<=ERY;i++) score += hand[i]*komav[i]; return (turn==SELF)? score : -score; } int search(char turn,int alpha,int beta,int depth) { if(depth<=0) return eval(turn); int v; Te t[700]; int tp=generate(turn,t); GoodTe[depth][depth].to=0; for(int i=0;i<tp;i++) { // printf("[%d:from=%d to=%d] ",i,t[i].from,t[i].to); move(turn,t[i]); v=-search( flip(turn),-beta,-alpha,depth-1 ); undo(turn,t[i]); if(v>alpha) { GoodTe[depth][depth]=t[i]; // if(depth==5) printf("score=%d \n",v); alpha=v; if(v>=beta) return beta; } } return alpha; } void printban(char turn) { printf("%d手目 eval=%d \n",teban+1,eval(SELF) ); printf("後手:"); for(int i=EFU;i<=ERY;i++) if(hand[i]) printf("%s%d ",csa[ i&0x0f ],hand[i] ); printf("\n"); printf(" 1 2 3 4 5 6 7 8 9 \n"); for(int y=2;y<=10;y++) { for(int x=1;x<=9;x++) { if( ban[x+y*16]==0 ) printf(" ・"); else if( ban[x+y*16]&ENEMY) printf("v%s",csa[ ban[x+y*16]&0x0f ]); else printf(" %s",csa[ ban[x+y*16]&0x0f ]); } printf(" %d\n",y-1); } printf("先手:"); for(int i=SFU;i<=SRY;i++) if(hand[i]) printf("%s%d ",csa[ i&0x0f ],hand[i] ); printf("\n"); } void main() { init(); int depth=2; for( int turn=SELF ;;turn=flip(turn) ) { printban(turn); int v=search(turn,-MUGEN,MUGEN,depth ); move(turn,GoodTe[depth][depth]); if(teban>=10) break; } }