/// <summary> /// Return the result of Conditional with some input /// </summary> /// <param name="yourTank"></param> /// <param name="enemyTank"></param> /// <param name="enemyBullet"></param> /// <returns></returns> public bool GetResult(Tank yourTank, Tank enemyTank, Bullet enemyBullet) { if (Type == TypeCondition.And) { return Children.All(t => t.GetResult(yourTank, enemyTank, enemyBullet)); } if (Type == TypeCondition.Or) { return Children.Any(t => t.GetResult(yourTank, enemyTank, enemyBullet)); } return Comparision.GetResult(yourTank, enemyTank, enemyBullet); }
/// <summary> /// The turn the result of the Comparison /// </summary> /// <param name="yourTank"></param> /// <param name="enemyTank"></param> /// <param name="enemyBullet"></param> /// <returns></returns> public bool GetResult(Tank yourTank, Tank enemyTank, Bullet enemyBullet) { float par = 0; switch (Parameter) { case TypeParameter.GetPositionX: par = yourTank.Position.X; break; case TypeParameter.GetPositionY: par = yourTank.Position.Y; break; case TypeParameter.GetDirection: par = MathProcessor.CalDifferentAngle(yourTank.Direction, 0); break; case TypeParameter.GetCurrentHeal: par = yourTank.HealCur; break; case TypeParameter.GetEnemyDistance: par = MathProcessor.CalDistance(yourTank.Position, enemyTank.Position); break; case TypeParameter.GetEnemyDifferentAngle: par = MathProcessor.CalDifferentAngle(yourTank.Direction, MathProcessor.CalPointAngle(yourTank.Position, enemyTank.Position)); break; case TypeParameter.GetEnemyCurrentHeal: par = enemyTank.HealCur; break; case TypeParameter.GetBulletDifferentAngle: par = MathProcessor.CalDifferentAngle(yourTank.Direction, enemyBullet.Direction); break; } const float epsilon = 1e-6f; switch (Operator) { case TypeOperator.GreaterEqual: if (par >= Value) { return true; } break; case TypeOperator.Greater: if (par > Value) { return true; } break; case TypeOperator.Equal: if (Math.Abs(par - Value) < epsilon) { return true; } break; case TypeOperator.Lower: if (par < Value) { return true; } break; case TypeOperator.LowerEqual: if (par <= Value) { return true; } break; case TypeOperator.NotEqual: if (Math.Abs(par - Value) > epsilon) { return true; } break; } return false; }
/// <summary> /// Execute some change of object in a frame in battlefield /// </summary> /// <param name="objects">Objects are battlefield</param> /// <returns>Result of that frame</returns> public override TypeResult NextFrame(List<ObjectGame> objects) { if (NewResult == TypeResult.BeDestroyed) { return TypeResult.BeDestroyed; } DetectedEnemy(objects); if (EnemyTank != null) { NewResult = TypeResult.Detected; } if (Instruction == null || Instruction.Interruptible) { SetListInstructions(); while (Instruction == null) { if (ListInstructions.Count == 0) { break; } else { if (ListInstructions[0].Condition == null || ListInstructions[0].Condition.GetResult(this, EnemyTank, EnemyBullet)) { Instruction = ListInstructions[0].Clone(); } else { ListInstructions.RemoveAt(0); } } } } NewResult = TypeResult.Normal; ExecuteInstruction(objects); EnemyTank = null; EnemyBullet = null; return TypeResult.Nothing; }
public void ExecuteInstruction(List<ObjectGame> objects) { if (Instruction == null) { return; } const float epsilon = 1e-6f; float value; var oldPosition = Position; switch (Instruction.Type) { case TypeInstruction.MoveForward: value = Math.Min(Instruction.Value, SpeedMove); Instruction.Value -= value; MoveForward(value); if (IsInvalidPosition(objects)) { Position = oldPosition; NewResult = TypeResult.CannotMoveForward; } break; case TypeInstruction.MoveBackward: value = Math.Min(Instruction.Value, SpeedMove); Instruction.Value -= value; MoveBackward(value); if (IsInvalidPosition(objects)) { Position = oldPosition; NewResult = TypeResult.CannotMoveBackward; } break; case TypeInstruction.RotateRight: value = Math.Min(Instruction.Value, SpeedRotate); Instruction.Value -= value; RotateRight(value); break; case TypeInstruction.RotateLeft: value = Math.Min(Instruction.Value, SpeedRotate); Instruction.Value -= value; RotateLeft(value); break; case TypeInstruction.Fire: value = Math.Min(Instruction.Value, SpeedFire); Instruction.Value -= value; _damageCur += value; if (Math.Abs(Instruction.Value) < epsilon) { var bullet = new Bullet(Properties.Resources.Bullet_A) { Position = MathProcessor.CalPointPosition(Position, 0.5f * Image.Width, Direction), Direction = Direction, Damage = _damageCur }; _damageCur = 0; objects.Add(bullet); } break; default: break; } if (Math.Abs(Instruction.Value) < epsilon) { Instruction = null; ListInstructions.RemoveAt(0); } }