diff --git a/src/Graphwar/Function.java b/src/Graphwar/Function.java index 30bddaf..b6e8354 100644 --- a/src/Graphwar/Function.java +++ b/src/Graphwar/Function.java @@ -1,5 +1,5 @@ // Copyright (C) 2011 Lucas Catabriga Rocha -// +// // This file is part of Graphwar. // // Graphwar is free software: you can redistribute it and/or modify @@ -23,295 +23,146 @@ public class Function private String strFunc; private PolishNotationFunction polishFunc; private double offSet; - + private double fireAngle; private double[] valuesX; private double[] valuesY; private double[] valuesDY; private int numSteps; - + private int[] playersHit; private int[] soldiersHit; private int[] soldierHitPosition; private int numPlayersHit; - + private double lastX; private double lastY; - - Function(String str) throws MalformedFunction - { - strFunc = str; - - polishFunc = new PolishNotationFunction(strFunc); - + + private void init() + { offSet = 0; - + fireAngle = 0; valuesX = null; valuesY = null; valuesDY = null; numSteps = 0; - + playersHit = null; soldiersHit = null; + soldierHitPosition = null; numPlayersHit = 0; - + lastX = 0; lastY = 0; - } - + + Function(String str) throws MalformedFunction + { + strFunc = str; + polishFunc = new PolishNotationFunction(strFunc); + + init(); + + } + Function(PolishNotationFunction polishNotationFunction) { strFunc = ""; - polishFunc = polishNotationFunction; - - offSet = 0; - - fireAngle = 0; - valuesX = null; - valuesY = null; - valuesDY = null; - numSteps = 0; - - playersHit = null; - soldiersHit = null; - soldierHitPosition = null; - numPlayersHit = 0; - - lastX = 0; - lastY = 0; - + + init(); + } - + public int getNumPlayersHit() { return numPlayersHit; } - + public int getPlayerHit(int index) { return playersHit[index]; } - + public int getSoldierHit(int index) { return soldiersHit[index]; } - + public int getSoldierHitPosition(int index) { return soldierHitPosition[index]; } - + public double getFireAngle() { return fireAngle; - } - + } + public double getX(int index) { return valuesX[index]; } - + public double getY(int index) { return valuesY[index]; } - + public int getNumSteps() { return numSteps; } - + public String getStringFunc() { return strFunc; } - + private double getStartAngle(double x, double radius) { double angle = 0; - + double startAngleTangent = (polishFunc.evaluateFunction(x+Constants.STEP_SIZE,0,0) - polishFunc.evaluateFunction(x,0,0))/Constants.STEP_SIZE; angle = Math.atan(startAngleTangent); - + double finalX; double error = 10000; for(int i=0; error > Constants.ANGLE_ERROR && i Constants.FUNC_MAX_STEP_DISTANCE_SQUARED;j++) - { - if(valuesX[i]-valuesX[i-1]>Constants.FUNC_MIN_X_STEP_DISTANCE) - { - tempStepSize = tempStepSize/2; - - valuesX[i] = valuesX[i-1] + tempStepSize; - valuesY[i] = polishFunc.evaluateFunction(valuesX[i],0,0)+offSet; - } - else - { - endFunc = true; - break; - } - } - - if(endFunc) - { - numSteps = i; - break; - } - - double x = Constants.PLANE_LENGTH*valuesX[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_LENGTH/2; - double y = -Constants.PLANE_LENGTH*valuesY[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_HEIGHT/2; - - - if(inverted) - { - x = Constants.PLANE_LENGTH - x; - } - - for(int j=0; j Constants.FUNC_MAX_STEP_DISTANCE_SQUARED && valuesX[i]-valuesX[i-1]>Constants.FUNC_MIN_X_STEP_DISTANCE;j++) - { - if(valuesX[i]-valuesX[i-1]>Constants.FUNC_MIN_X_STEP_DISTANCE) - { - tempStepSize = tempStepSize/2; - - k1 = polishFunc.evaluateFunction( valuesX[i-1], valuesY[i-1], 0); - k2 = polishFunc.evaluateFunction( valuesX[i-1] + 0.5*tempStepSize, valuesY[i-1] + 0.5*tempStepSize*k1, 0); - k3 = polishFunc.evaluateFunction( valuesX[i-1] + 0.5*tempStepSize, valuesY[i-1] + 0.5*tempStepSize*k2, 0); - k4 = polishFunc.evaluateFunction( valuesX[i-1] + tempStepSize, valuesY[i-1] + tempStepSize*k3, 0); - - valuesY[i] = valuesY[i-1] + (tempStepSize/6)*(k1 + 2*k2 + 2*k3 + k4); - valuesX[i] = valuesX[i-1] + tempStepSize; - } - else - { - endFunc = true; - break; - } - } - - if(endFunc) - { - numSteps = i; - break; - } - - double x = Constants.PLANE_LENGTH*valuesX[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_LENGTH/2; - double y = -Constants.PLANE_LENGTH*valuesY[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_HEIGHT/2; - - - if(inverted) - { - x = Constants.PLANE_LENGTH - x; - } - - for(int j=0; j Constants.FUNC_MAX_STEP_DISTANCE_SQUARED && valuesX[i]-valuesX[i-1]>Constants.FUNC_MIN_X_STEP_DISTANCE;j++) - { - if(valuesX[i]-valuesX[i-1]>Constants.FUNC_MIN_X_STEP_DISTANCE) - { - - tempStepSize = tempStepSize/2; - - x1 = valuesX[i-1]; - y1 = valuesY[i-1]; - y2 = valuesDY[i-1]; - - k11 = y2; - k12 = polishFunc.evaluateFunction( x1, y1, y2); - - x1 = valuesX[i-1] + tempStepSize/2; - y1 = valuesY[i-1] + (tempStepSize/2)*k11; - y2 = valuesDY[i-1] + (tempStepSize/2)*k12; - - k21 = y2; - k22 = polishFunc.evaluateFunction( x1, y1, y2); - - y1 = valuesY[i-1] + (tempStepSize/2)*k21; - y2 = valuesDY[i-1] + (tempStepSize/2)*k22; - - k31 = y2; - k32 = polishFunc.evaluateFunction( x1, y1, y2); - - x1 = valuesX[i-1] + tempStepSize; - y1 = valuesY[i-1] + (tempStepSize)*k31; - y2 = valuesDY[i-1] + (tempStepSize)*k32; - - k41 = y2; - k42 = polishFunc.evaluateFunction( x1, y1, y2); - - - valuesX[i] = valuesX[i-1] + tempStepSize; - valuesY[i] = valuesY[i-1] + (tempStepSize/6)*(k11 + 2*k21 + 2*k31 + k41); - valuesDY[i] = valuesDY[i-1] + (tempStepSize/6)*(k12 + 2*k22 + 2*k32 + k42); - } - else + + for(int j = 0; Math.pow(valuesX[i]-valuesX[i-1], 2) + Math.pow(valuesY[i]-valuesY[i-1], 2) > Constants.FUNC_MAX_STEP_DISTANCE_SQUARED; j++) + { // If the step is too big, halve it + if (valuesX[i] - valuesX[i-1] <= Constants.FUNC_MIN_X_STEP_DISTANCE) { - endFunc = true; + if (gameMode == Constants.NORMAL_FUNC) + endFunc = true; break; } - + tempStepSize = tempStepSize/2; + + setNextValues(valuesX, valuesY, valuesDY, tempStepSize, i, gameMode); } - if(endFunc) { numSteps = i; break; } - - + double x = Constants.PLANE_LENGTH*valuesX[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_LENGTH/2; double y = -Constants.PLANE_LENGTH*valuesY[i]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_HEIGHT/2; - - - if(inverted) - { - x = Constants.PLANE_LENGTH - x; - } - - for(int j=0; j= Constants.SOLDIER_RADIUS*Constants.SOLDIER_RADIUS) // The soldier is too far + continue; + if(Double.isNaN(distSquared)) // The illegal case + continue; + if(playerAlreadyHit(j,k)) // The player has already been hit + continue; + + playersHit[numPlayersHit] = j; + soldiersHit[numPlayersHit] = k; + soldierHitPosition[numPlayersHit] = i; + numPlayersHit++; } } - - - if(obstacle.collidePoint((int)x, (int)y)) - { - numSteps = i; - break; - } - - if(Double.isNaN(y) || Double.isInfinite(y)) + + + if(obstacle.collidePoint((int)x, (int)y) || Double.isNaN(y) || Double.isInfinite(y)) { numSteps = i; break; } - - } - - lastX = Constants.PLANE_LENGTH*valuesX[numSteps-1]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_LENGTH/2;; + + lastX = Constants.PLANE_LENGTH*valuesX[numSteps-1]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_LENGTH/2; lastY = -Constants.PLANE_LENGTH*valuesY[numSteps-1]/Constants.PLANE_GAME_LENGTH + Constants.PLANE_HEIGHT/2; + } + + public void processFunctionRange(Obstacle obstacle, Player players[], int numPlayers, int currentTurn, boolean inverted) + { + processRange(obstacle, players, numPlayers, currentTurn, inverted, Constants.NORMAL_FUNC, 0); + } - + public void processRK4Range(Obstacle obstacle, Player players[], int numPlayers, int currentTurn, boolean inverted) + { + processRange(obstacle, players, numPlayers, currentTurn, inverted, Constants.FST_ODE, 0); + } + + public void processRK42Range(Obstacle obstacle, Player players[], int numPlayers, int currentTurn, double angle ,boolean inverted) + { + processRange(obstacle, players, numPlayers, currentTurn, inverted, Constants.SND_ODE, angle); } - + public double getLastX() { return lastX; } - + public double getLastY() { return lastY; } - }