マイクロ将棋コード

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;
	}
}