#include <sys/bios.h>
#include <stdlib.h>
#include "KSFont.h"
#include "KSKey.h"
#include "chuka.h"
#include "data.h"
#include "GChara.h"
#include "GameBall.h"

extern int g_nGameFinish;
extern int g_nGamePlayer;	/* 攻撃プレイヤー（0.1P 1.2P） */
extern int g_nTargetX;		/* ターゲットのxパネル座標(0-6) */


int	g_nGameAI[2];		/* 操縦者(0.Human  1.Computer) */
int	g_nMode[2];
int	g_nTarget[2];
int	g_nCount[2];
int	g_nWait[2];

CBattlePoint player[7];
CBattlePoint enemy[7][7];
CBattlePoint player2[7];







/*=================================================================*/
/* キャラクタの初期化 */
/*=================================================================*/
int CGameChara_Init( void )
{


	/* 正常終了 */
	return FUNC_TRUE;
}



/*=================================================================*/
/* キャラクタの表示 */
/*=================================================================*/
int CGameChara_View( void )
{
	/* ライカ・ライチ表示 */
	KSScreenSet( 21, SCREEN2, 21, 8 ); /* ライカ(1P) */
	KSScreenSet( 25, SCREEN2,  0, 8 ); /* ライチ(2P) */

	/* 正常終了 */
	return FUNC_TRUE;
}






/*=================================================================*/
/* 人工知能初期化 */
/*=================================================================*/
int CGameAI_Init( void )
{
	/* 操縦者初期化 */
	g_nGameAI[0] = 0;
	g_nGameAI[1] = 0;

	/* 思考モード初期化 */
	g_nMode[0] = 0;
	g_nMode[1] = 0;
	if( g_nGamePlayer == 0 ) g_nMode[0] = 1;
	if( g_nGamePlayer == 1 ) g_nMode[1] = 1;

	g_nTarget[0] = 0;
	g_nTarget[1] = 0;

	g_nCount[0] = 0;
	g_nCount[1] = 0;

	g_nWait[0] = 0;
	g_nWait[1] = 0;

	return FUNC_TRUE;
}



/*=================================================================*/
/* モード設定 */
/*=================================================================*/
int CGameAI_SetMode( int p_nPlayer, int p_nMode )
{
	g_nMode[p_nPlayer] = p_nMode;

	return FUNC_TRUE;
}



/*=================================================================*/
/* 人工知能 */
/*=================================================================*/
int CGameAI_Action( int player )
{
	int target;

	/* ゲームが終了しているなら戻る */
	if( g_nGameFinish > 0 ) return FUNC_TRUE;

	/* 操縦者が人間なら戻る */
	if( g_nGameAI[player] == 0 ) return FUNC_TRUE;

	/* 思考処理 */
	switch( g_nMode[player] ){
	case 1: /* 記憶との照合 */
		/* 落下位置決定 */
		g_nTarget[player] = CGameAI_Think( player, -1 );
		/* その他 */
		g_nMode[player] = 2;
		g_nWait[player] = 15 + rand()%30;
		g_nCount[player] = 0;
		break;
	
	case 2:	/* カーソル制御 */
		if( g_nWait[player] > 0 ) g_nWait[player]--;
		if( ++g_nCount[player] > 8 ){
			g_nCount[player] = 0;
			if( g_nWait[player] == 0 ){
				target = g_nTargetX;
				if( target == g_nTarget[player] ) KSKey_Set( KEY_A, 1 );
				if( target < g_nTarget[player] )  KSKey_SetX( 1 );
				if( target > g_nTarget[player] )  KSKey_SetX( -1 );
			}else{
				KSKey_Set( KEY_A, 0 );
				if( rand()%2 == 0 ) KSKey_SetX( -1 );
				else				KSKey_SetX( 1 );
			}
		}
		break;

	default:
		break;
	}

	return FUNC_TRUE;
}




/*=================================================================*/
/* 確率決定 */
/*=================================================================*/
int CGameAI_Think( int player, int adr )
{
	int target, x;

	/* 記憶データがない？ */
	if( adr == -1 ){
		/* 基本思考 */
		target = CGameAI_WinNext( player );
		while( target == -1 ){
			x = rand()%7;
			if( CGameBall_GetBallColor( x, 0 ) == 0 ) target = x;
		}
		return( target );
	}
	return( -1 );
}



/*=================================================================*/
/* 基本ルーチン */
/*=================================================================*/
void CGameAI_Basic( int ZX, int ZY, int COLOR, CBattlePoint far *BP )
{
	int vx[8]={ 1, 1, 0,-1,-1,-1, 0, 1};
	int vy[8]={ 0, 1, 1, 1, 0,-1,-1,-1};
	int x,y,n,n2;

	/* 8方向繰り返し */
	for(n=0; n<8; n++){
		x = ZX;
		y = ZY;
		for(n2=0; n2<3; n2++){
			x += vx[n];
			y += vy[n];
			if( x < 0 || x > 6 ) break;
			if( y < 0 || y > 5 ) break;
			if( CGameBall_GetBallColor( x, y ) == COLOR ){
				/* 自分の珠の場合 */
				BP->space[n]++;
				BP->ball[n]++;
				if( BP->linkflag[n] ){
					BP->link[n]++;
					BP->linkspace[n]++;
				}
			}else if( CGameBall_GetBallColor( x, y ) == 0 ){
				/* 空白の場合 */
				BP->space[n]++;
				BP->linkflag[n] = 0;
				if( y+1 > 5 || CGameBall_GetBallColor( x, y+1 ) != 0 ){
					if( BP->linkspaceflag[n] ) BP->linkspace[n]++;
				}else{
					BP->linkspaceflag[n] = 0;
				}
			}else{
				/* 敵の珠の場合は終了 */
				break;
			}
		}
	}
	/* 珠数判定 */
	for(n=0; n<4; n++){
		if( (1 + BP->link[n] + BP->link[n+4]) >= 4 ) BP->win++;
		if( (1 + BP->link[n] + BP->link[n+4]) == 3
		&& (BP->linkspace[n] > BP->link[n])
		&& (BP->linkspace[n+4]) > BP->link[n+4]) BP->next++;
		/* ﾊﾞﾄﾙﾎﾟｲﾝﾄ計算 */
		if( (1 + BP->space[n] + BP->space[n+4]) >= 4 ){
			BP->point += 2+rand()%5;
			BP->point += ( BP->ball[n] + BP->ball[n+4] )*3;
			BP->point += ( BP->link[n] + BP->link[n+4] )*2;
		}
	}
}



/*=================================================================*/
/* 設置有利度判定 */
/*=================================================================*/
int CGameAI_WinNext( int PlayerNum )
{
	int lPlayerColor, lEnemyColor;
	int x, x2, y, y2, po1, po2, target;

	for( x=0; x<7; x++ ){
		CGameAI_CBattlePointInit( &player[x] );
		for( y=0; y<7; y++ ){
			CGameAI_CBattlePointInit( &enemy[x][y] );
		}
		CGameAI_CBattlePointInit( &player2[x] );
	}

	/* 自分と敵の色設定 */
	lPlayerColor = PlayerNum + 1;
	if( lPlayerColor == 1 ) lEnemyColor = 2;
	else				    lEnemyColor = 1;

	/* 設置判定 */
	for(x=0; x<7; x++){
		for(y=5; y>=0; y--){
			if(CGameBall_GetBallColor( x, y ) == 0) break;
		}
		if(y < 0) continue;
		/* 基本思考 */
		player[x].flag = 1;
		CGameAI_Basic( x, y, lPlayerColor, &player[x] );
		if( y-1 >= 0 ){
			player2[x].flag = 1;
			CGameAI_Basic( x, y-1, lPlayerColor, &player2[x] );
		}
		/* 敵思考 */
		CGameBall_SetBallColor( x, y, lPlayerColor );
		for(x2=0; x2<7; x2++){
			for(y2=5; y2>=0; y2--){
				if(CGameBall_GetBallColor( x2, y2 ) == 0) break;
			}
			if(y2 < 0) continue;
			enemy[x][x2].flag = 1;
			CGameAI_Basic(x2, y2, lEnemyColor, &enemy[x][x2]);
		}
		CGameBall_SetBallColor( x, y, 0 );
	}
	/* 敵の有利度設定 */
	for(x=0; x<7; x++){
		for(x2=0; x2<7; x2++){
			if(enemy[x][x2].win  > 0) player[x].denger_win++;
			if(enemy[x][x2].next > 0) player[x].denger_next++;
			player[x].denger_point += enemy[x][x2].point;
		}
	}

	/* ﾌﾟﾚｲﾔ勝ち */
	for(x=0; x<7; x++)
	{
		if(player[x].win > 0) return(x);
	}

	/* ﾌﾟﾚｲﾔ勝ちNEXT */
	for(x=0; x<7; x++)
	{
		if(player[x].next > 0 && player[x].denger_win == 0) return(x);
	}

	/* ﾌﾟﾚｲﾔﾎﾟｲﾝﾄ判定(有利圏) */
	target = -1;
	for(x=0; x<7; x++){
		if(player[x].flag == 0
		|| player[x].denger_win > 0
		|| player[x].denger_next > 0
		|| player2[x].win > 0 ) continue;
		if(target == -1){
			target = x;
		}else{
			po1 = player[x].point;
			po2 = player[target].point;
			if( po1 > po2 ) target = x;
		}
	}
	if(target != -1) return(target);

	/*ﾌﾟﾚｲﾔﾎﾟｲﾝﾄ判定(安全圏) */
	for(x=0; x<7; x++){
		if(player[x].flag == 0
		|| player[x].denger_win > 0
		|| player[x].denger_next > 0) continue;
		if(target == -1){
			target = x;
		}else{
			po1 = player[x].point;
			po2 = player[target].point;
			if( po1 > po2 ) target = x;
		}
	}
	/*ﾌﾟﾚｲﾔﾎﾟｲﾝﾄ判定(危険圏)*/
	if(target != -1) return(target);
	for(x=0; x<7; x++){
		if(player[x].flag == 0
		|| player[x].denger_win > 0) continue;
		if(target == -1){
			target = x;
		}else{
			po1 = player[x].point;
			po2 = player[target].point;
			if( po1 > po2 ) target = x;
		}
	}

	return( target );
}



int CGameAI_CBattlePointInit( CBattlePoint far *bp )
{
	int n;

	bp->flag = 0;				/* 0.False 1.True */
	for( n=0; n<8; n++ ) bp->space[n] = 0;
	for( n=0; n<8; n++ ) bp->ball[n] = 0;
	for( n=0; n<8; n++ ) bp->link[n] = 0;
	for( n=0; n<8; n++ ) bp->linkflag[n] = 0;
	for( n=0; n<8; n++ ) bp->linkspace[n] = 0;
	for( n=0; n<8; n++ ) bp->linkspaceflag[n] = 0;
	bp->win = 0;
	bp->next = 0;
	bp->point = 0;
	bp->denger_win = 0;			/* 敵の勝ち */
	bp->denger_next = 0;		/* 敵の勝ちNEXT */
	bp->denger_point = 0;		/* 敵のﾎﾟｲﾝﾄ */

	return FUNC_TRUE;
}
