Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Custom Woody AI by Nucleargod
#1
Vigo(aka FonixS, one of the best players in Taiwan) introduced me to this pretty tough custom Woody AI that he "downloaded from a forum BBS". I've no idea who the creator is, but Vigo assured me that its okay to post it here.

edit: @richardfat7 pointed out that this AI is made by "nucleargod" from the official lf2 ztage forums.

This Woody AI tends to run and aggressively uses a mix of D^A >JA or D^J D>J.
    AI-Code:
//int ego(){
void id(){
	clr();
	person me = person(true);
	person@ competitor = null;
	//*
	print("me:" + " hp=" + self.hp + ", mp=" + self.mp + "\n");
	me.toScreen();
	print("\n");
	//*/
	//array<person> teammates;
	bool hasTeammate = false;
	array<person> enemies;
	array<oobject> things;
	for(int i=0; i<400; i++){
		//剔除自己
		if(loadTarget(i) != -1 && target.num != self.num ){
			float dx = (self.facing ? self.x - target.x : target.x - self.x);
			if(target.type == 0){								//人
				if(target.team == self.team && target.hp > 0){	//友方
					//teammates.insertLast( person(false));
					hasTeammate = true;
				}
				else //if(dx < 1000 && dx > -800){//敵方
				{
					enemies.insertLast( person(false));
					if( <DVZ_ME#1> == null || (competitor.state == 14 && target.state != 14) || 
						(competitor.absDx() > abs(dx) && target.state != 14)){
						<DVZ_ME#1> = enemies[enemies.length()-1];
					}
				}
			}
			/*else if(dx < 1000 && dx > -800){					//物件
				things.insertLast( oobject());
			}//*/
		}
	}
 
	//*清除所有已按下的按鍵
	D(0,0);
    A(0,0);
    J(0,0);
    if(!me.isWalking()) right(0,0);
    if(!me.isWalking()) down(0,0);
    if(!me.isWalking()) left(0,0);
    if(!me.isWalking()) up(0,0);
	//*/
 
	fuzzyValue x_near("near",-1,0,50,90);
	fuzzyValue x_mid_near("mid_near",50,80,100,140);
	fuzzyValue x_mid_far("mid_far",100, 150, 300,350);
	fuzzyValue x_far("far",320, 400, 3000, 5000);
	fuzzySet x_dis("x distance");
	x_dis.push(x_near);
	x_dis.push(x_mid_near);
	x_dis.push(x_mid_far);
	x_dis.push(x_far);
 
	fuzzyValue z_near("near",-1,0,20,40);
	fuzzyValue z_mid("mid",25,40,60,80);
	fuzzyValue z_far("far",70, 85, 3000, 5000);
	fuzzySet z_dis("z distance");
	z_dis.push(z_near);
	z_dis.push(z_mid);
	z_dis.push(z_far);
 
	fuzzyValue y_near("near",-1,0,70,100);
	fuzzyValue y_far("far",80, 120, 3000, 5000);
	fuzzySet y_dis("y distance");
	y_dis.push(y_near);
	y_dis.push(y_far);
 
	/* 測試輸出
	x_dis.toScreen();
	y_dis.toScreen();
	z_dis.toScreen();
	//*/
 
	if( <DVZ_ME#1> == null){
		print("can't find competitor\n");
		if(self.mp > rand(200) + 150 && self.hp > rand(200) + 150){
			DuJ();}
		//else 
		return ;
	}
	//判斷自己與對方的距離
	float[] dx = x_dis.fuzzify(competitor.absDx());
	float[] dy = y_dis.fuzzify(competitor.absDy());
	float[] dz = z_dis.fuzzify(competitor.absDz());
	//*
	print("competitor:\n");
	competitor.toScreen();
	print("x_dis: ");
	for(uint i=0;i<dx.length(); i++){
		if(dx[i] > 0){
			print(x_dis[i].name + "*" + dx[i] + " ");
		}
	}
	print("\ny_dis: ");
	for(uint i=0;i<dy.length(); i++){
		if(dy[i] > 0){
			print(y_dis[i].name + "*" + dy[i] + " ");
		}
	}
	print("\nz_dis: ");
	for(uint i=0;i<dz.length(); i++){
		if(dz[i] > 0){
			print(z_dis[i].name + "*" + dz[i] + " ");
		}
	}
	print("\n");
	//*/
 
	//*未判斷風險,不要命打法/
	float seed = rand(100);
	seed /= 100;
	print("seed = " + seed + "\n");
	if( competitor.state == 14 || competitor.blink > 5){
		print("competitor is unhurtable\n");
		if(competitor.dx > 0) left();
		else right();
		if(competitor.dz > 0) down();
		else up();
	}
	else if(self.y == 0){	//地面上
		print("on groung\n");
		if(me.isRunning()){
			float _up = 0;
			float _down = 0;
			float _d = 0;
			float _j = 0;
			float _a = 0;
			float _stop = 0;
			float[] com_zd = z_dis.fuzzify(abs(competitor.z-bg_zwidth1));
			float[] com_zu = z_dis.fuzzify(abs(competitor.z-bg_zwidth2));
			print("isRunning, com_zd=" + com_zd[0] + ", com_zu=" + com_zu[0] + "\n");
			//上下移動
			if(dx[3] > seed){		//當作遠,避免同排
				if(competitor.dz > 0){
					_up = com_zu[0];
					_down = _up >= dx[3] ? 0 : dx[3];
				}
				else{
					_down = com_zd[0];
					_up = _down >= dx[3] ? 0 : dx[3];
				}
			}
			else{						//當作不遠,朝對方接近
				if(competitor.dz > 0) _up = 1 - dx[3];
				else if(competitor.dz < 0) _down = 1- dx[3];
			}
 
			//敵人接近,攻擊,取交集
			_a = (dx[0] < dy[0] ? (dx[0] < dz[0] ? dx[0] : dz[0]) : (dy[0] < dz[0] ? dy[0] : dz[0]));
			//敵人x中遠程且z不遠,起跳準備攻擊,取交集
			_j = dx[2] < 1 - dz[2] ? dx[2] : 1 - dz[2];
			//敵人很遠//但Z軸相近
			//if(dx[3] < dz[0]){
				if(dx[3] > _j) _j = dx[3];
			//}
			//else{
			//	if(dz[0] > _j) _j = dz[0];
			//}
			//敵人X接近但Z保持上下不接近,煞車
			_stop = dx[0] < 1 - dz[0] ? dx[0] : 1 - dz[0];
			//敵人在X中近程以及Z不遠且攻擊中,滾地迴避
			if(competitor.isAttacking()) _d = dx[1] < 1 - dz[0] ? dx[1] : 1 - dz[0];
			//目標在後方,滾地
			else if(competitor.dx * me.facing < 0) _d = 1 - dx[0];
			//危險接近,未判定
 
			if(_up > _down && _up > seed) up();		//執行動作
			else if(_down > seed) down();
 
			if(_d > seed) D();
			else if(_j > seed) J();
			else if(_a > seed) A();
			else if(_stop > seed){
				if(self.facing) right();
				else left();
			}
		}
		else if(me.isRolling()){	//滾地,前方有人可以打,自己有氣就使用鬼車腿
			if(self.mp > 50 && !competitor.isAttacking() && dx[1] > seed && competitor.absDz() < 25) DdA();
		}
		else if(me.isCatching()){
			if(self.hp > rand(500) && self.ctimer < 30 + rand(40)) {
				rand(10) > 5 ? right() : left();
			}
			A();
		}
		else if(self.frame == 215){	//一般著地,危險時滾,只要敵人不遠,有氣就虎翔霸,否則飛踢
			if(dx[0] > seed && dz[0] > seed && dy[1] > seed) DuA();
			else if(dx[0] > seed && dz[0] > seed && competitor.isAttacking()) D();
			else if((1 - dx[3] > seed) && (1 - dz[2] > seed)){
				if(self.mp > 200 && (dx[0] > seed || competitor.isAttacking() || rand(500) > self.mp)){
					if(competitor.dx > 0) DrJ();
					else DlJ();
				}
				else {
					if(competitor.dz > 25) up(1,1);
					else if(competitor.dz < 25) down(1,1);
					if(competitor.dx > 0){
						right(1,1);
						J();
					}
					else {
						left(1,1);
						J();
					}
				}
			}
		}
		else if(self.frame == 219){	//衝跳著地或者滾地起身,有機會就虎翔霸
			if((1 - dx[3] > seed) && (1 - dz[2] > seed)){
				if(self.mp > 200 && (dx[0] > seed || competitor.isAttacking() || rand(500) > self.mp)){
					if(competitor.dx > 0) DrJ();
					else DlJ();
				}
			}
		}
		else if(me.isObjing()){		//負重,馬上丟
			if(competitor.dx > 0) right(1,1);
			else left(1,1);
			if(competitor.dz > 20) up(1,1);
			else if(competitor.dz < -20) down(1,1);
			A();
		}
		else if(me.isDrinking()){	//喝飲料,有威脅就閃
			if((dx[0] > seed || dx[1] > seed) && dz[0] > seed){
				if(self.mp > 50 && (dx[0] > dx[1] || competitor.dx * me.facing > 0)) DdA();
				else DuA();
			}
			else if(dx[2] > seed && 1 - dz[2] > seed && abs(competitor.vx) > 10 &&
					competitor.dx * competitor.vx < 0 && competitor.vz * competitor.dz <= 0){
				DuA();
			}
		}
		else if(self.frame == 111){	//防住一次攻擊
			DuA();
		}
		else if(self.frame == 245){	//發完波
			if(self.mp > 200 && (dx[0] > seed || dx[1] > seed) && dz[0] > seed){
				if(competitor.dx > 0) DrJ();
				else DlJ();
			}
		}
		else if(self.frame >= 250 && self.frame <= 253){					//虎翔霸調整方向
			if(competitor.dz > 25) up(1,1);
			else if(competitor.dz < -25) down(1,1);
		}
		else if((self.frame >= 286 && self.frame <= 288) || (self.frame >= 301 && self.frame <= 303)){
			//剛傳送到目的地
			if(dx[0] > seed && dz[0] > seed){								//極接近目標
				if(self.mp > 325 && (competitor.isFainting() || competitor.isDrinking())){
					if(competitor.dx > 30) DrA();
					else if(competitor.dx < -30) DlA();
					else DuA();
				}
				else DuA();
			}
			else if(self.mp > 200 && 1 - dx[3] > seed && 1 - dz[2] > seed){	//與目標有段距離但不遠
				if((competitor.isFainting() || competitor.isDrinking()) && dx[1] > seed){	//發現暈眩目標,準備連技
					if( self.mp > 325){				//D>AJ
						if(competitor.dx > 0) DrA();
						else DlA();
					}								//DvA + D^A
					else if(competitor.dx > 0){
						DdA();
					}
				}
				else{
					if(competitor.dx > 0) DrJ();
					else DlJ();
				}
			}
		}
		else{						//其他地面狀態,如站立、行走
			float _up = 0;
			float _down = 0;
			float _left = 0;
			float _right = 0;
			float _run = 0;
			float _d = 0;
			float _j = 0;
			float _a = 0;
			float _dua = 0;
			//float _duj = 0;
			float _dfa = 0;		//波
			float _dfj = 0;		//虎翔霸
			float _dda = 0;
			//float _ddj = 0;
			float _catch = 0;
 
			//移動方向決策
			if( competitor.dx > 0 ){
				_right = 1;
			}
			else{
				_left = 1;
			}
			if(competitor.dz > 0) _up = 1;
			else _down = 1;
			_run = dx[2] > dx[3] ? dx[2] : dx[3];
			//敵人接近,暈眩則抓,否則攻擊,取交集
			if(competitor.isFainting()){
				_catch = (dx[0] < dy[0] ? (dx[0] < dz[0] ? dx[0] : dz[0]) : (dy[0] < dz[0] ? dy[0] : dz[0]));
			}
			else {
				_a = (dx[0] < dy[0] ? (dx[0] < dz[0] ? dx[0] : dz[0]) : (dy[0] < dz[0] ? dy[0] : dz[0]));
			}
			//敵人從空中接近,腳刀,取交集
			_dua = (dx[0] < dy[1] ? (dx[0] < dz[0] ? dx[0] : dz[0]) : (dy[1] < dz[0] ? dy[1] : dz[0]));
			//敵人暈眩且自己氣很多,D>AJ 連技
			if((competitor.isFainting()  || competitor.isDrinking()) && self.mp > 325){
				_dfa = dx[1];
			}
			//敵人在X中近程或近程且在Z中程,跳
			if(dx[0] > dx[1]) _j = dx[0] < dz[1] ? dx[0] : dz[1];
			else _j = dx[1] < dz[1] ? dx[1] : dz[1];
			//敵人在X中近程且暈眩或負重,鬼車腿或者衝過去
			if(competitor.isFainting() || competitor.isObjing() || competitor.isDrinking()){
				if(self.mp > 50 && competitor.absDz() < 25) _dda = dx[1];
				else if(_run < dx[1]) _run = dx[1];
			}
			//敵人在X中遠程且Z不遠,虎翔霸或者跑步準備飛踢
			if(self.mp > 200 && rand(400) > self.hp){
				_dfj = dx[2] < 1 - dz[2] ? dx[2] : 1 - dz[2];
			}
			else{
				float tmp = dx[2] < 1 - dz[2] ? dx[2] : 1 - dz[2];
				if(tmp > _run) _run = tmp;
			}
 
			//敵我距離遙遠,瞬間移動或者發波或者跑步
			if(self.hp > 250 && self.mp > 250 && dx[3] > seed){		//血多氣足,瞬移敵方
				left(0,0);
				right(0,0);
				if(me.facing == competitor.facing) DuJ();
				else if(self.facing) right();
				else left();
				return ;
			}
			else if(hasTeammate && self.hp < 150 && self.mp > 50 &&	//血少,瞬移己方
					rand(500) < self.hp && dx[3] > seed){
				DdJ();
				return ;
			}
			else if(self.mp > 125 && _dfa < dx[3] && rand(500) < self.mp){	//遠程發波
				_dfa = dx[3];
			}
			else if(_run < dx[3]) _run = dx[3];
 
			//開始按方向鍵
			if(_right > _left && _right > seed){
				right();
				_right = 2;
				if( _run > _dfj && _run > seed){
					right();
					return ;
				}
			}
			else if(_left > seed){
				left();
				_left = 2;
				if( _run > _dfj && _run > seed){
					left();
					return ;
				}
			}
			if(_up > _down) up();
			else down();
			//開始按招式
			if(_dfj > seed){
				if(competitor.dx > 0) DrJ();
				else DlJ();
			}
			else if(_dfa > seed){
				if(competitor.dx > 0) DrA();
				else DlA();
			}
			else if(_dda > seed) DdA();
			else if(_dua > seed) DuA();
			else if(_catch > seed){
				if(_left != 2 && _right != 2 ){
					if(competitor.dx > 10) right();
					else if(competitor.dx < 10) left();
				}
			}
			else if(_a > seed) A();
			else if(_d > seed) D();
			else if(_j > seed) J();
		}
	}
	else{				//空中
		print("in the air\n");
		if(me.isDashing()){
			if(dx[0] > seed) A();
			else if(competitor.dx > 0 && competitor.nextDx() < 200 ) A();
		}
		else if(me.isFalling()){
			if(competitor.state == 301) J();
		}
		else if(me.isJumping()){
			float _a = 0;
			float _duj = 0;
			float _ddj = 0;
			//敵人接近,攻擊
			if(dx[0] < dz[0]) _a = dx[0] < dy[0] ? dx[0] : dy[0];
			else _a = dz[0] < dy[0] ? dz[0] : dy[0];
			//敵人很遠,傳送
			if(self.mp > 50){
				if(self.hp > rand(300) + 100 && self.mp > rand(125) + 50){
					if(dx[3] > dx[2]) _duj = dx[3] > dz[2] ? dx[3] : dz[2];
					else _duj = dx[2] > dz[2] ? dx[2] : dz[2];
				}
				if(hasTeammate && self.hp < rand(100) + 50){
					if(dx[3] > dx[2]) _ddj = dx[3] > dz[2] ? dx[3] : dz[2];
					else _ddj = dx[2] > dz[2] ? dx[2] : dz[2];
				}
			}
 
			if(_a > seed && (me.vy * competitor.dy > -rand(10))){
				if(competitor.dx > 0) right();
				else left();
				A();
			}
			else if(_duj > seed) DuJ();
			else if(_ddj > seed) DdJ();
			else{
				if(competitor.dx > 0) right();
				else left();
			}
		}
	}
	//*/
 
	//return 0;
}
 
/* 相對於自己的座標方位
 *           /----/----/
 *          /   z>0   /|
 *         /    /    / |
 *        /----/----/  /
 *       /    /    /| /|
 *      /   z<0   / |/ |
 * y>0 /----/----/  /  /
 *     |    |    | /| /
 *     |    |    |/ |/
 * x<0 |---------/  /   x>0
 *     |    |    | /
 *     |    |    |/
 * y<0 |---------/
 */
 
class person{
	int blink;		//是否閃爍
	int id;			//物件識別碼
	int team;		//隊伍
	int frame;		//在第幾影格
	int holding;	//持有何種武器,-1表示空手,否則為所持武器type
	int armor;		//目標盔甲型態,0無盔甲,1一般盔甲,2魔王盔甲(防冰火)
	int state;		//目標狀態
	int facing;		//目標面向,-1 向左,1向右
	float x;		//目標位置
	float y;
	float z;
	float dx;		//以自己為原點的目標位置
	float dy;
	float dz;
	float vx;		//目標移動向量
	float vy;
	float vz;
 
	person(){
		dx=0;dy=0;dz=0;
	}
 
	//d=true,取自己的資料建構
	//d=false,取目標的資料建構
	person(bool d){
		if(d){
			blink = self.blink;
			id = self.id;
			team = self.team;
			frame = self.frame;
			if(id == 52) armor = 2;
			else if(id == 37 || id == 6) armor = 1;
			else armor = 0;
			state = self.state;
			facing = self.facing ? -1 : 1;
			x = self.x;
			y = self.y;
			z = self.z;
			dx = 0;
			dy = 0;
			dz = 0;
			vx = self.x_velocity;
			vy = -self.y_velocity;
			vz = -self.z_velocity;
			holding = (self.weapon_held == -1 ? -1 : self.weapon_type);
		}
		else{
			blink = target.blink;
			id = target.id;
			team = target.team;
			frame = target.frame;
			if(id == 52) armor = 2;
			else if(id == 37 || id == 6) armor = 1;
			else armor = 0;
			state = target.state;
			facing = target.facing ? -1 : 1;
			x = target.x;
			y = target.y;
			z = target.z;
			dx = target.x - self.x;
			dy = self.y - target.y;
			dz = self.z - target.z;
			vx = target.x_velocity;
			vy = -target.y_velocity;
			vz = -target.z_velocity;
			holding = (target.weapon_held == -1 ? -1 : target.weapon_type);
		}
	}
 
	person(float rx,float ry, float rz){
		dx=rx;dy=ry;dz=rz;
	}
 
	float absDx(){
		return abs(dx);
	}
 
	float absDy(){
		return abs(dy);
	}
 
	float absDz(){
		return abs(dz);
	}
 
	float nextDx(){
		return dx + vx;
	}
 
	float nextDy(){
		return dy + vy;
	}
 
	float nextDz(){
		return dz + vz;
	}
 
	void toScreen(){
		print("id=" + id + ", team=" + team +  "\n");
		print("pos=(" + x + ", " + y + ", " + z + ")\n");
		print("dpos=(" + dx + ", " + dy + ", " + dz + ")\n");
		print("vel=(" + vx + ", " + vy + ", " + vz + ")\n");
		print("frame=" + frame + ", state=" + state + ", facing=" + facing + ", hlding=" + holding + "\n");
	}
 
	bool isAttacking(){
		if(state == 3) return true;
		else if(state == 301) return true;		//鬼哭斬
		else if(state == 100) return true;		//落雷霸
		else if(state == 19) return true;		//烈火焚身
		else return false;
	}
 
	bool isDefending(){
		return state == 7;
	}
 
	bool isBrokenDenfending(){
		return state == 8;
	}
 
	//bool isHoldingWeapon(){}
 
	bool isLying(){
		return state == 14;
	}
 
	bool isDrinking(){
		return state == 17;
	}
 
	bool isSkilling(){
		return frame > 234;
	}
 
	bool isFalling(){
		return state == 12;
	}
 
	bool isStanding(){
		return state == 0;
	}
 
	bool isWalking(){
		return state == 1;
	}
 
	bool isRunning(){
		return state == 2;
	}
 
	bool isDashing(){
		return state == 5;
	}
 
	bool isJumping(){
		return state == 4;
	}
 
	bool isRolling(){
		return state == 6;
	}
 
	bool isFliping(){
		return (frame==100 || frame==101 || frame==108 || frame==109);
	}
 
	bool isObjing(){
		return (frame > 11 && frame < 20);
	}
 
	bool isFainting(){
		return state == 16;
	}
 
	bool isCatching(){
		return state == 9;
	}
 
	bool isCaught(){
		return state == 10;
	}
 
	bool isFreezing(){
		return frame == 200;
	}
 
	bool isFrozen(){
		return state == 13;
	}
 
	bool isOnFire(){
		return state == 18;
	}
 
	bool isOnGround(){
		if(self.y == 0) return dy==0;
		else return dy!=0;
	}
};
 
class oobject{
	int id;			//物件識別碼
	int type;		//物件類別
	int team;		//隊伍
	int frame;		//在第幾影格
	int state;		//目標狀態
	float x;		//目標位置
	float y;
	float z;
	float dx;		//以自己為原點的目標位置
	float dy;
	float dz;
	float vx;		//目標移動向量
	float vy;
	float vz;
 
	oobject(){
		id = target.id;
		type = target.type;
		team = target.team;
		frame = target.frame;
		state = target.state;
		x = target.x;
		y = target.y;
		z = target.z;
		dx = target.x - self.x;
		dy = self.y - target.y;
		dz = self.z - target.z;
		vx = target.x_velocity;
		vy = target.y_velocity;
		vz = target.z_velocity;
	}
 
	float absDx(){
		return abs(dx);
	}
 
	float absDy(){
		return abs(dy);
	}
 
	float absDz(){
		return abs(dz);
	}
 
	void toScreen(){
		print("id=" + id + ", team=" + team + ", type=" + type + "\n");
		print("pos=(" + x + ", " + y + ", " + z + ")\n");
		print("dpos=(" + dx + ", " + dy + ", " + dz + ")\n");
		print("vel=(" + vx + ", " + vy + ", " + vz + ")\n");
		print("frame=" + frame + ", state=" + state + "\n");
	}
 
	bool isDrink(){
		return type == 6;
	}
 
	bool isCriminal(){
		return type == 5;
	}
 
	bool isChee(){
		return type == 3;
	}
 
	bool isWeapon(){
		return type == 1;
	}
 
	bool isHeavy(){
		return type == 2;
	}
 
	bool isBall(){
		return type == 4;
	}
 
	bool isLying(){
		if(!isChee() && (isHeavy() ? state == 2004 : state == 1004)) return true;
		else return false;
	}
 
	bool isFalling(){
		if(!isChee() && (isHeavy() ? state == 2000 : state == 1000)) return true;
		else return false;
	}
 
	bool isOnHand(){
		if(isChee()) return false;
		else if(isHeavy()){
			if(state == 2001) return true;
			else return false;
		}
		else if(state == 1001) return true;
		else return false;
	}
 
	//the same as isThrowing
	bool isFlying(){
		if(isChee()){
			if(state == 3000) return true;
			else return false;
		}
		else if(isHeavy()){
			if(state == 2000) return true;
			else return false;
		}
		else if(state == 1002) return true;
		else return false;
	}
 
	bool isChasing(){
		if(isFlying()){
			if(id == 215) return true;						//Dennis
			else if(id == 214) return true;					//John
			else if(id == 219 || id == 220) return true;	//Jan
			else if(id == 221 || id == 222) return true;	//Firzen
			else if(id == 225) return true;					//Julian
			else if(id == 228) return true;					//Bat
			else return false;
		}
		else return false;
	}
 
	bool isCure(){
		if(id == 200 && frame >= 50 && frame < 55) return true;	//John
		else if(id == 220 && isFlying()) return true;			//Jan
		else return false;
	}
 
	bool isWall(){	//John ForceField
		if(id == 200 && frame >= 60 && frame <= 65) return true;
		else return false;
	}
 
	bool isPassable(){
		if(isHeavy() && isLying()) return false;			//heavy Object
		else if(id == 212 && state == 3000) return false;	//Freeze colume
		else return true;
	}
 
	bool isPickable(){
		if(!isChee() && isLying())return true;
		else return false;
	}
 
	bool isHitBreakable(){
		if(!isChee()) return true;
		else if(state == 3005 || state == 3006) return false;
		else if(id == 211) return false;					//Fire
		else if(isWall()) return false;						//John ForceField
		else if(id == 212 && frame > 100) return false;		//Freeze whirlwind
		else if(id == 229) return false;					//Julian col & exp & Bomb
		else return true;
	}
 
	bool isWind(){
		if(state == 3006) return true;
		else return false;
	}
 
	bool isBreakable(){
		if(id == 211) return false;							//Fire
		else if(id == 212 && frame > 100) return false;		//Freeze whirlwind
		else if(id == 229 && frame > 5) return false;		//Julian col & exp
		else return true;
	}
 
	bool isDefendable(){
		if(id == 212 && frame >= 150) return false;			//Freeze whirlwind
		else if(id == 229 && frame < 100) return false;		//Julian col & Bomb
		else return true;
	}
 
	bool isFire(){
		if(id == 210 || id == 211 || id == 221) return true;
		else return false;
	}
 
	bool isIce(){
		if(id == 209 || id == 212 || id == 213 || id == 222) return true;
		else return false;
	}
}
 
//使用梯形
class fuzzyValue{
	string name;
	float height;	//最大值
	float begin;	//起點,此點以下皆為0
	float lb;		//值 = hight 的下限
	float hb;		//值 = hight 的上限
	float end;		//終點,此點以上皆為0
 
	//輸入值必須滿足: rb < rlb < rhb < re
	fuzzyValue(string rn, float rb, float rlb, float rhb, float re, float rh=1.0f){
		name = rn;
		height = rh;
		begin = rb;
		lb = rlb;
		hb = rhb;
		end = re;
	}
 
	/* Implement the copy constructor
    fuzzyValue@ opAssign(const fuzzyValue &in other)
    {
      // Copy the value of the other instance
	  height = other.height;
	  begin = other.begin;
	  end = other.end;
	  lb = other.lb;
	  hb = other.hb;
	  return this;
    }//*/
 
	float fuzzify(float r){
		if(r < begin) return 0;
		else if(r < lb){
			return (r-begin) * height / (lb-begin);
		}
		else if(r < hb) return height;
		else if(r < end){
			return (end-r) * height / (end-hb);
		}
		else return 0;
	}
 
	float deFuzzify(){
		return (begin + lb + hb + end) / 4;
	}
 
	void toScreen(){
		print("fuzzyValue " + name + ": h=" + height + ",\t" + begin + ", " + lb + ", " + hb + ", " + end + "\n");
	}
}
 
class fuzzySet{
	string name;
	fuzzyValue@[] value;
	//uint top;
 
	fuzzySet(string rn){
		name = rn;
		//value.resize(5);
		//top = 0;
	}
 
	fuzzySet(string rn, fuzzyValue@ r){
		name = rn;
		//value.resize(5);
		//value[0] = r;
		//top = 1;
		value.insertLast(r);
	}
 
	void push(fuzzyValue@ r){
		value.insertLast(r);
	}
 
	float[] fuzzify(float r){
		float[] d;
		for(uint i=0;i<value.length(); i++){
			d.insertLast(value[i].fuzzify(r));
		}
		return d;
	}
 
	float deFuzzify(){
		float d=0;
		float hh=0;
		for(uint i=0;i<value.length(); i++){
			d += value[i].deFuzzify() * value[i].height;
			hh += value[i].height;
		}
		return d/hh;
	}
 
	void toScreen(){
		print("fuzzySet " + name + "{\n");
		for(uint i=0;i<value.length(); i++){
			value[i].toScreen();
		}
		print("}\n");
	}
 
	fuzzyValue@ opIndex(uint r){
		return value[r];
	}
 
	fuzzyValue@ opIndex(string r){
		for(uint i=0; i<value.length(); i++){
			if(value[i].name == r){
				return value[i];
			}
		}
		return null;
	}
 
	uint indexOf(string r){
		for(uint i=0; i<value.length(); i++){
			if(value[i].name == r){
				return i;
			}
		}
		return 2147483647;
	}
}

Here's a video from Vigo taking on 4 of these Woody AIs at once:


And here's the attachment complete with other stuff in case you don't want to copy paste the above as an .as file or have issues viewing the chinese text annotations:

.zip   LF2_ai.zip (Size: 1.04 MB / Downloads: 280)
[Image: uMSShyX.png]
~Spy_The_Man1993~
Steiner v3.00 (outdated), Challenge Stage v1.51
Luigi's Easier Data-Editor, A-Man's Sprite Mirrorer
Working on the LF2 Rebalance mod.
Avatar styled by: prince_freeza
Reply
Thanks given by: A-Man


Messages In This Thread
Custom Woody AI by Nucleargod - by STM1993 - 08-25-2016, 03:20 PM
RE: Custom Woody AI - by A-Man - 08-25-2016, 03:44 PM
RE: Custom Woody AI - by richardfat7 - 12-09-2016, 10:06 AM
RE: Custom Woody AI - by AmadisLFE - 12-22-2016, 09:29 PM



Users browsing this thread: 1 Guest(s)