這一篇我們來討論討論牛。
牛的性狀有:牛的初始位置,牛的速度,牛的強壯度,牛的血量。
牛的強壯度在直觀表現上會體現出Cube的大小,同時也會影響減血的速度,越強壯,每秒減血的就越慢。
CowObject.class:
public class CowObject:GAObject
{
public float mStrongRate;
public float mVelocity;
public int mLife;
public int mTempLife;
public static Vector3 mpos_leftdown;
public static Vector3 mpos_rightup;
public float timer = 0.0f;
public SimpleAI mGlassTarget = null;
public float RoundTimer = 0.0f;
public float EatTimer = 0.0f;
public int lastTime = 0;
public Vector3 RoundTarget = Vector3.zero;
public override void Decode ()
{
bool[][] mAllBitBunch = FreedomAIEncoderAndDecoder.BreakBitBunch (mbitbunch,mBreakPoint);
string s = "";
mStrongRate = FreedomAIEncoderAndDecoder.BitBunch2float (mAllBitBunch[0],0.0f,1.0f);
mVelocity = FreedomAIEncoderAndDecoder.BitBunch2float (mAllBitBunch[1],1.5f,6.0f);
mLife = FreedomAIEncoderAndDecoder.BitBunch2int (mAllBitBunch[2],100,1000);mTempLife = mLife;
float tx = FreedomAIEncoderAndDecoder.BitBunch2float (mAllBitBunch[3],0.0f,1.0f);tx = (mpos_rightup.x - mpos_leftdown.x) * tx + mpos_leftdown.x;
float ty = FreedomAIEncoderAndDecoder.BitBunch2float (mAllBitBunch[4],0.0f,1.0f);ty = (mpos_rightup.y - mpos_leftdown.y) * ty + mpos_leftdown.y;
float tz = FreedomAIEncoderAndDecoder.BitBunch2float (mAllBitBunch [5], 0.0f, 1.0f);tz = (mpos_rightup.z - mpos_leftdown.z) * tz + mpos_leftdown.z;
mPosition = new Vector3 (tx,ty,tz);
}
public override void Encode ()
{
bool[] tStrongRate_bit = FreedomAIEncoderAndDecoder.float2BitBunch (mStrongRate,0.0f,1.0f,10);
bool[] tVelocity_bit = FreedomAIEncoderAndDecoder.float2BitBunch (mVelocity,1.5f,6.0f,10);
bool[] tLife = FreedomAIEncoderAndDecoder.int2BitBunch (mLife,100,1000,10);
bool[] mPosition_X = FreedomAIEncoderAndDecoder.float2BitBunch ((mPosition.x-mpos_leftdown.x)/(mpos_rightup.x-mpos_leftdown.x),0.0f,1.0f,11);
bool[] mPosition_Y = FreedomAIEncoderAndDecoder.float2BitBunch ((mPosition.y-mpos_leftdown.y)/(mpos_rightup.y-mpos_leftdown.y),0.0f,1.0f,11);
bool[] mPosition_Z = FreedomAIEncoderAndDecoder.float2BitBunch ((mPosition.z-mpos_leftdown.z)/(mpos_rightup.z-mpos_leftdown.z),0.0f,1.0f,11);
mbitbunch = FreedomAIEncoderAndDecoder.JointBitBunch (tStrongRate_bit,tVelocity_bit,tLife,mPosition_X,mPosition_Y,mPosition_Z);
}
public override void InitBreakPoint ()
{
mBreakPoint.Clear ();
mBreakPoint.Add (10);
mBreakPoint.Add (10);
mBreakPoint.Add (10);
mBreakPoint.Add (11);
mBreakPoint.Add (11);
mBreakPoint.Add (11);
}
public override float Evaluate ()
{
return (float)mTempLife / (float)1000;
}
public override void RandomData ()
{
System.Random srd = new System.Random ();
mStrongRate = Random.Range (0.0f,1.0f);
mVelocity = Random.Range (3.0f,6.5f);
mLife = Random.Range (0,1000);mTempLife = mLife;
mPosition = new Vector3 ();
mPosition.x = Random.Range (mpos_leftdown.x,mpos_rightup.x);
mPosition.y = Random.Range (mpos_leftdown.y,mpos_rightup.y);
mPosition.z = Random.Range (mpos_leftdown.z,mpos_rightup.z);
}
public override string ToString ()
{
return mStrongRate.ToString () + " " + mVelocity.ToString () + " " + mLife.ToString() + " " + mPosition.ToString();
}
}
牛的行爲會相對稍微複雜一些,牛有三種狀態,一種是死亡,血量低於0就有消亡。第二種是巡邏,閒逛,吃飽了就會去閒逛。第三種是吃草,首先是對草的選擇,會優先選擇近的且高的草。
public class CowRunner:SimpleAIRunner
{
public void DoRun(SimpleAI sAI,string code)
{
string s = code;
((CowObject)sAI.mCharacter).timer += Time.deltaTime;
if (((int)((CowObject)sAI.mCharacter).timer) - ((CowObject)sAI.mCharacter).lastTime > 0)
{
((CowObject)sAI.mCharacter).mTempLife -= 30 + (int)(15*((CowObject)sAI.mCharacter).mStrongRate);
((CowObject)sAI.mCharacter).lastTime = ((int)((CowObject)sAI.mCharacter).timer);
}
if (code == "Die")
{
sAI.Destroy ();
}
else if (code == "Round")
{
((CowObject)sAI.mCharacter).mGlassTarget = null;
if (((CowObject)sAI.mCharacter).RoundTimer > 0.0f && (((CowObject)sAI.mCharacter)).RoundTarget != Vector3.zero)
{
float distance = Vector3.Distance(sAI.mAIRT.transform.position,((CowObject)sAI.mCharacter).RoundTarget);
if (distance > 1.5f)
{
sAI.GetComponent<AIMove> ().mDirection = ((CowObject)sAI.mCharacter).RoundTarget - sAI.mAIRT.transform.position;
sAI.GetComponent<AIMove> ().mDirection.y = 0.0f;
sAI.GetComponent<AIMove> ().mVelocity = ((CowObject)sAI.mCharacter).mVelocity;
}
else
{
sAI.GetComponent<AIMove> ().mVelocity = 0.0f;
}
((CowObject)sAI.mCharacter).RoundTimer -= Time.deltaTime;
}
else
{
((CowObject)sAI.mCharacter).RoundTimer = 2.5f;
((CowObject)sAI.mCharacter).RoundTarget = sAI.GeneratePos + new Vector3 (Random.Range(-10,10),0,Random.Range(-10,10));
}
}
else
{
((CowObject)sAI.mCharacter).RoundTarget = Vector3.zero;
((CowObject)sAI.mCharacter).RoundTimer = 0.0f;
if (((CowObject)sAI.mCharacter).mGlassTarget == null||((CowObject)sAI.mCharacter).mGlassTarget.mAIRT==null)
{
SimpleAI[] SimpleAIs = SimpleAISetSingleton.getInstance ().GetComponent<SimpleAISet> ().FindAIsWithRiaus (sAI.mAIRT.transform.position,20.0f,1<<LayerMask.NameToLayer("Default"),"Glass");
int startIndex = Random.Range (0,SimpleAIs.Length);
for (int i = startIndex; i < SimpleAIs.Length; i++)
{
float f2 = ((glassObject)SimpleAIs [i].mCharacter).mHeight;
f2 = (f2 - 1.0f) / 1.5f;
if (Random.Range (0.0f, 1.0f) < f2)
{
((CowObject)sAI.mCharacter).mGlassTarget = SimpleAIs [i];
break;
}
}
s+="Finding";
}
else
{
float distance = Vector3.Distance(sAI.mAIRT.transform.position,((CowObject)sAI.mCharacter).mGlassTarget.mAIRT.transform.position);
if (distance>1.5f)
{
sAI.GetComponent<AIMove> ().mDirection = ((CowObject)sAI.mCharacter).mGlassTarget.mAIRT.transform.position - sAI.mAIRT.transform.position;
sAI.GetComponent<AIMove> ().mDirection.y = 0.0f;
sAI.GetComponent<AIMove> ().mVelocity = ((CowObject)sAI.mCharacter).mVelocity;
}
else
{
sAI.GetComponent<AIMove> ().mVelocity = 0.0f;
if (((CowObject)sAI.mCharacter).EatTimer < 1.0f)
{
((CowObject)sAI.mCharacter).EatTimer += Time.deltaTime;
}
else
{
((CowObject)sAI.mCharacter).mTempLife += 40;
((CowObject)sAI.mCharacter).mTempLife = Mathf.Min (((CowObject)sAI.mCharacter).mTempLife,((CowObject)sAI.mCharacter).mLife);
((glassObject)((CowObject)sAI.mCharacter).mGlassTarget.mCharacter).mHp -= 40;
}
}
}
}
}
};
運行結果:
第一代:
第二代:
第三代:
我們可以注意到,首先是草的生長位置向左下偏移,草的高度,草的顏色偏接近矮綠,這是因爲,綠的加血更多,活的更健康,高的更容易被吃掉,而右上的草裏牛羣近,也容易被吃掉,所以就進化出了這樣的結果。
而我們可以把玩家當作這裏的牛,不同的是,玩家的選擇是不固定的,他可能選擇砍任何位置的草,可能旋轉砍任何顏色的草,可能選擇砍任何高矮的草,也就是草進化空間是我們事先未設置好的由玩家做了什麼來決定,也就是給到了玩家事先未設置好的遊戲機制反饋。