So I'm supposed to create a program that sets temperatures to celsius and farenheit. In it I create an equals method. Then I'm to create a driver that runs it and tests temperatures to see if they are equal, or not, using the equals method. I cannot get the correct boolean values, it just keeps spitting out false. Hitting a wall here. Code is as follows:
public class Temperature
{
public enum Scale{ CELSIUS, FARENHEIT};
public static final double DEFAULT_DEGREES = 0.0;
private double temperature;
private Scale scale;
public Temperature()
{
this(Temperature.DEFAULT_DEGREES);
}//default
public Temperature(double newTemperature)
{
this(newTemperature, Scale.CELSIUS);
}//ending bracket of constructor double
public Temperature(Scale newScale)
{
this(0, newScale);
}//end of constructor scale
public Temperature(double newTemperature, Scale newScale)
{
this.setTemperature(newTemperature);
this.setScale(newScale);
}//end bracket of constructor degrees and scale
public Scale getScale()
{
return this.scale;
}//end of method getScale
public void setScale(Scale newScale)
{
this.scale=newScale;
}//end of method setScale
public double getTemperature()
{
return this.temperature;
}//ending bracket of metho getTemperature
public void setTemperature(double newTemperature)
{
if(newTemperature < Temperature.DEFAULT_DEGREES)
{
this.temperature=Temperature.DEFAULT_DEGREES;
}
else
{
this.temperature = newTemperature;
}//ending of if
}//ending bracket of method setTemperature
public double getTemperatureInFarenheit()
{
double rv;
if(this.getScale() == Scale.CELSIUS)
{
rv= this.getTemperature();
}
else
{
rv = ((this.getTemperature()* 1.8) + 32);
}//end of if
return rv;
}//end of bracket of method getweightinfarenheit
public double getTemperatureInCelsius()
{
double rv;
if(this.getScale() == Scale.FARENHEIT)
{
rv = this.getTemperature();
}
else
{
rv= ((this.getTemperature()- 32) * 0.5556);
}
return rv;
}//end of method gettemperatureincelsius
public boolean equals(Object otherObject)
{
boolean rv = false;
if(otherObject instanceof Temperature)
{
Temperature otherTemperature = (Temperature)otherObject;
if((this.getTemperature()== otherTemperature.getTemperature())
&&(this.getScale()== otherTemperature.getScale()))
{
rv = true;
}//end of nested if
}//end of if
return rv;
}//end of bracket method equals
}//ending of class
This is my driver:
public class TemperatureDriver
{
public static void main(String[]args)
{
Temperature w1 = new Temperature();
w1.setTemperature(32);
w1.setScale(Temperature.Scale.FARENHEIT);
Temperature w2 = new Temperature();
w2.setTemperature(0);
w2.setScale(Temperature.Scale.CELSIUS);
System.out.println(w1.equals(w2));
Temperature w3 = new Temperature();
w3.setTemperature(-40.0);
w3.setScale(Temperature.Scale.FARENHEIT);
Temperature w4 = new Temperature();
w4.setTemperature(-40.0);
w4.setScale(Temperature.Scale.CELSIUS);
System.out.println(w3.equals(w4));
Temperature w5 = new Temperature();
w5.setTemperature(212);
w5.setScale(Temperature.Scale.FARENHEIT);
Temperature w6 = new Temperature();
w6.setTemperature(100);
w6.setScale(Temperature.Scale.CELSIUS);
System.out.println(w5.equals(w6));
}//end of method main
}//end of class Temperaturedriver
So there are a couple of issues I see. First, in your implementation of
getTemperatureInCelsius()
if(this.getScale() == Scale.FARENHEIT)
should be, I think,
if(this.getScale() == Scale.CELSIUS)
and vice versa for your implementation of getTemperatureInFarenheit.
Once those are fixed, I think the primary issue with your equals is it insists scales be the same. Where you have
if((this.getTemperature()== otherTemperature.getTemperature())
&&(this.getScale()== otherTemperature.getScale()))
instead should be
if(this.getTemperatureInFarenheit()== otherTemperature.getTemperatureInFahrenheit())
where I am deliberately comparing in Farenheit to avoid the rounding in your celsius conversion factor. That will probably make equals work (once the fix I mentioned for getTemperatureInFarenheit is made).
I still think I would feel better about saying something like
if(Math.abs(this.getTemperatureInFarenheit()-otherTemperature.getTemperatureInFahrenheit())<0.001)
than what I suggested above, and I would try that if the above fails.
Related
I have a strange case of EXC_BAD_ACCESS occurring in some KdTree implementation I have. This implementation works on all .net platforms (Framework, core etc.), it also runs in the Unity editor just fine. However, when I run this code on the phone itself via XCode, I get
0x11e96521c <+80>: add x1, x9, #0x8 ; =0x8
0x11e965220 <+84>: add x24, x8, x23
-> 0x11e965224 <+88>: ldr x0, [x24, #0x8] // HERE - EXEC_BAD_ACCESS (code=1, address=0x8)
0x11e965228 <+92>: mov w2, #0x0
0x11e96522c <+96>: bl 0x11e91f358 ; il2cpp::metadata::GenericMetadata::InflateIfNeeded at GenericMetadata.cpp:76
I have made the unity implementation available here. This is called like this
public List<Models.Point> GetBestFeaturePointCluster(IEnumerable<Models.Point> featurePoints, float radius = 1)
{
Console.Log("GetBestFeaturePointCluster");
var kdTree = KdTree.FromData(
featurePoints.Select(p => new double[] { p.X, p.Y, p.Z }).ToArray(),
featurePoints.ToArray(),
true);
where featurePoints is an IEnumerable<Point> and Point is
public class Point : IPoint<float>
{
public Point(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != GetType())
{
return false;
}
return Equals(obj as Point);
}
public override int GetHashCode()
{
unchecked
{
int hash = (int)2_166_136_261;
hash = (hash * 16_777_619) ^ X.GetHashCode();
hash = (hash * 16_777_619) ^ Y.GetHashCode();
hash = (hash * 16_777_619) ^ Z.GetHashCode();
return hash;
}
}
public bool Equals(Point other)
{
if (other is null)
{
return false;
}
if (ReferenceEquals(other, this))
{
return true;
}
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
}
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
}
I have attempted to debug using NS_ZOMBIE_ENABLED=YES and enabling ZombieObjects. This has not really supplied and additional information.
For the case in question, there should be 47 nodes and the Create method should be called 47 times, on the Unity editor run this is what happens - on iOS it is called once and then this error is thrown.
The debugger shows that at the end of the create method is where this is thrown from, but I cannot work out why. I use no reflection and no expression lambdas - these were all stripped out.
Can any one shed some light on why this is occurring?
Thanks very much for your time.
One up on the call stack shows this
Any advice would be massively appreciated as this is very painful at this point.
I'm developing game like Hitman Go , and I need to find which waypoints are closest to my target(specific waypoint ) when enemy has alerted by rock or sound and etc.
I set some point for enemy and My enemy patrolling between waypoints ( 8 -> 6 -> 1-> 2-> 3-> 4-> 5 ) then reveres his path.
so, when I throw rock in waypoint number 18, I need to move enemy to this waypoint, but with closest way. imaging enemy can be any this waypoint when he get aleret ( 8,6,1,2,3,4,5 points).
Note 1: The distance between two points is same.
Note2: My game is in 3d not 2d.
I use this code to move my enemy step by step ( turn base ).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaypointController : MonoBehaviour
{
public List<Transform> waypoints = new List<Transform>();
private Transform targetWaypoint;
private int targetWaypointIndex = 0;
private float minDistance = 0.1f;
private int lastWaypointIndex;
public bool reversePath;
// what easetype to use for iTweening
public iTween.EaseType easeType = iTween.EaseType.easeInOutExpo;
// how fast we move
public float moveSpeed = 1.5f;
// time to rotate to face destination
public float rotateTime = 0.5f;
// delay to use before any call to iTween
public float iTweenDelay = 0f;
// Use this for initialization
void Start()
{
lastWaypointIndex = waypoints.Count - 1;
targetWaypoint = waypoints[targetWaypointIndex];
}
public void EnemyTurn()
{
float distance = Vector3.Distance(transform.position, targetWaypoint.position);
CheckDistanceToWaypoint(distance);
// move toward the destinationPos using the easeType and moveSpeed variables
iTween.MoveTo(gameObject, iTween.Hash(
"x", targetWaypoint.position.x,
"y", targetWaypoint.position.y,
"z", targetWaypoint.position.z,
"delay", iTweenDelay,
"easetype", easeType,
"speed", moveSpeed
));
}
void CheckDistanceToWaypoint(float currentDistance)
{
if (currentDistance <= minDistance)
{
targetWaypointIndex++;
UpdateTargetWaypoint();
}
}
void UpdateTargetWaypoint()
{
if (targetWaypointIndex > lastWaypointIndex)
{
if (reversePath)
{
waypoints.Reverse();
}
targetWaypointIndex = 1;
}
targetWaypoint = waypoints[targetWaypointIndex];
}
}
Since you asked in the comments for a non-A* solution & I was bored :)
Naive DFS pathfinder with very simple pruning.
Brute force and very wasteful both memory & CPU wise.
For a game similar to Hitman Go / Lara Croft Go - I would use this code and not a navmesh / A*.
For a RTS / FPS or any AI intensive games, I would definitely not use this solution.
public class GridPathfinder
{
// Not thread safe
private int? _currentShortestPath;
/// <summary>
/// Finds shortest path from cell A to B
/// </summary>
/// <returns>Shortest found path; null if found no path.</returns>
public IList<Node> GetShortestPath(Node a, Node b)
{
_currentShortestPath = null;
return GetShortestPathInternal(a, b, new List<Node>());
}
private IList<Node> GetShortestPathInternal(Node #from, Node to, List<Node> currentPath)
{
// Sanity
if (currentPath.Contains(from))
{
return null;
}
// Prune
if (_currentShortestPath.HasValue && currentPath.Count + 1 >= _currentShortestPath)
{
return null;
}
currentPath.Add(from);
if (from == to)
{
return currentPath;
}
// Check neighbors recursively
IList<Node> foundShortestPath = null;
foreach (var connectedCell in from.ConnectedCells)
{
var cellPath = GetShortestPathInternal(connectedCell, to, new List<Node>(currentPath));
if (cellPath == null || foundShortestPath != null && cellPath.Count >= foundShortestPath.Count)
{
continue;
}
foundShortestPath = cellPath;
}
// Update shortest path for future pruning
if (foundShortestPath != null && (!_currentShortestPath.HasValue || _currentShortestPath > foundShortestPath.Count))
{
_currentShortestPath = foundShortestPath.Count;
}
return foundShortestPath;
}
}
public class Node
{
private readonly HashSet<Node> _connectedCells = new HashSet<Node>();
public IEnumerable<Node> ConnectedCells => _connectedCells;
/// <summary>
/// Add a connection
/// </summary>
/// <param name="toAdd">Node to add</param>
/// <param name="isTwoWay">Should add a connection from target node to this node</param>
public void AddConnection(Node toAdd, bool isTwoWay=true)
{
if (toAdd == null || toAdd == this)
{
throw new Exception("Invalid connection attempted");
}
// Attempt to add
if (!_connectedCells.Add(toAdd))
{
return;
}
if (!isTwoWay) return;
toAdd.AddConnection(this);
}
}
I am new to Unity, but not to C#, so I would love to avoid using Bolt. I don't mind spending the extra time making sure that my animations are correct.
I am trying to get a gun to shoot (the animation part [aka recoil])
As you probably can see that there are no parameters (in the first image). In the parameter box (where it says list is empty in the animator window), I clicked on the '+' to create a new parameter trigger (called it "M1911SHOOT")
However it does resolve the Parameter does not exist error message but nothing happens afterwards
Here is my code
M1911.cs
public class M1911 : Weapons
{
private const string IDLE = "M1911IDLE";
private const string BASIC = "M1911SHOOT";
// Start is called before the first frame update
void Start()
{
IDLEANIM = IDLE;
BASICATKANIM = BASIC;
weaponName = "Weapon";
damage = 15;
heavyDamage = 35;
weight = 5;
staminaCost = 5;
range = 3.5f;
atkDelay = .7f;
type = WEAPONTYPE.MELEE;
Init();
}
}
Weapons.cs
public class Weapons : MonoBehaviour
{
protected enum WEAPONTYPE
{
NONE,
RANGED,
MELEE
}
protected string weaponName;
protected int damage;
protected int heavyDamage;
protected int weight;
protected int staminaCost;
protected float range;
protected WEAPONTYPE type;
protected bool isAtking;
protected float atkDelay;
protected string BASICATKANIM;
protected string HEAVYATKANIM;
protected string IDLEANIM;
protected string CURRENTANIMATION;
private Animator _animator;
protected void Init()
{
CURRENTANIMATION = IDLEANIM;
_animator = GetComponent<Animator>();
isAtking = false;
}
public int Attack()
{
if (!isAtking)
{
isAtking = true;
ChangeAnimation(BASICATKANIM);
return damage;
}
return 0;
}
void AttackComplete()
{
isAtking = false;
}
public void ChangeAnimation(string newAnimationState)
{
if(newAnimationState == CURRENTANIMATION)
return;
if (isAtking)
{
CURRENTANIMATION = newAnimationState;
Invoke("AttackComplete", atkDelay);
}
_animator.SetBool(BASICATKANIM, true);
_animator.SetBool(IDLEANIM, false);
CURRENTANIMATION = newAnimationState;
}
}
Player.cs
public class Player : CharacterAttributes
{
public Weapons weapon;
// Start is called before the first frame update
void Start()
{
Init();
}
// Update is called once per frame
void Update()
{
Move();
if (Input.GetMouseButtonDown(0))
Attack();
}
void Move()
{
//Movement stuff
}
void Attack()
{
weapon.Attack();
}
}
Wrong method in Weapon.cs
Needed
_animator.Play(BASICATKANIM);
instead of
_animator.SetBool(IDLEANIM, false);
I wanted to play an animation, not play around with the parameters for the animator
I'm busy with creating a school project where I need to integrate wave spawners.
For now, I used this video as an example and implemented it in my project.https://www.youtube.com/watch?v=q0SBfDFn2Bs
Everything is spawning fine and I also get my debug logs. The main problem is: I can't see my enemies. (not John Cena guys hahah, in that case it would be logic ;) )
I'm new to Unity and I like the interface and workflow but I have a lot to learn. I hope someone can help me out! :)
Source WaveSpawner.cs:
using UnityEngine;
using System.Collections;
public class WaveSpawner : MonoBehaviour
{
public enum SpawnState { SPAWNING, WAITING, COUNTING };
[System.Serializable]
public class Wave
{
public string name;
public Transform enemy;
public int count;
public float rate;
}
public Wave[] waves;
private int nextWave = 0;
public int NextWave
{
get { return nextWave + 1; }
}
public Transform[] spawnPoints;
public float timeBetweenWaves = 5f;
private float waveCountdown;
public float WaveCountdown
{
get { return waveCountdown; }
}
private float searchCountdown = 1f;
private SpawnState state = SpawnState.COUNTING;
public SpawnState State
{
get { return state; }
}
void Start()
{
if (spawnPoints.Length == 0)
{
Debug.LogError("No spawn points referenced.");
}
waveCountdown = timeBetweenWaves;
}
void Update()
{
if (state == SpawnState.WAITING)
{
if (!EnemyIsAlive())
{
WaveCompleted();
}
else
{
return;
}
}
if (waveCountdown <= 0)
{
if (state != SpawnState.SPAWNING)
{
StartCoroutine( SpawnWave ( waves[nextWave] ) );
}
}
else
{
waveCountdown -= Time.deltaTime;
}
}
void WaveCompleted()
{
Debug.Log("Wave Completed!");
state = SpawnState.COUNTING;
waveCountdown = timeBetweenWaves;
if (nextWave + 1 > waves.Length - 1)
{
nextWave = 0;
Debug.Log("ALL WAVES COMPLETE! Looping...");
}
else
{
nextWave++;
}
}
bool EnemyIsAlive()
{
searchCountdown -= Time.deltaTime;
if (searchCountdown <= 0f)
{
searchCountdown = 1f;
if (GameObject.FindGameObjectWithTag("Enemy") == null)
{
return false;
}
}
return true;
}
IEnumerator SpawnWave(Wave _wave)
{
Debug.Log("Spawning Wave: " + _wave.name);
state = SpawnState.SPAWNING;
for (int i = 0; i < _wave.count; i++)
{
SpawnEnemy(_wave.enemy);
yield return new WaitForSeconds( 1f/_wave.rate );
}
state = SpawnState.WAITING;
yield break;
}
void SpawnEnemy(Transform _enemy)
{
Debug.Log("Spawning Enemy: " + _enemy.name);
Transform _sp = spawnPoints[ Random.Range (0, spawnPoints.Length) ];
Instantiate(_enemy, _sp.position, _sp.rotation);
}
}
From what I can see is you're also changing the Z position of the bat. Generally you would not want to do that in a 2D game cause it can go behind stuff as is happening there. In the code I did notice that you are using random points in the world so you would want to check the Z position of those points and change them to 0 or 1.Here's the Image of what you need to change on the points! Hope this helps!
So, my assignment was to create a class with multiple animals that each moved in a certain way as practice for working with multiple objects. One that has stumped me to no end, is the "Turtle" class. The Turtle is supposed to move in a clockwise motion in a 5x5 square, first going south, then west, then north then east. It goes in one direction for 5 "steps" and then switches. so it would go south for 5 steps and then go west for 5 steps, etc. My problem right now is that it only goes in a diagonal line going northeast whenever I try to run the code.Anyway, here's the code I needed to work with:
This is the main method:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
public class AnimalSimulator {
public static void main(String[] args) {
DrawingPanel forest = new DrawingPanel(720, 640);
Graphics2D pen = forest.getGraphics();
Animal [] animals = new Animal[15];
for (int i = 0; i < animals.length;i++){
//int selection = (int) (Math.random()*6+1);
int randX = (int) (Math.random()*720+1);
int randY = (int) (Math.random()*640+1);
Turtle t = new Turtle("Reptile", "Tortoise", new Point(randX, randY), Color.CYAN);
animals [i] = t;
}
for (int time = 1; time <= 100; time++){
for (int i = 0; i < animals.length; i++){
//System.out.println(animals[i]);
//Graphics.drawString(animals[i].toString(), animals[i].getLocation().x, animals[i].getLocation().y);
pen.setColor(animals[i].getColor());
pen.fillRect(animals[i].getLocation().x, animals[i].getLocation().y, 10,10);
animals[i].move();
for (int a = 0; a< animals.length; a++){
if(a!= i){
//if (animals[i].equals(animals[a])){
//animals[a] = null;
}
}
}
forest.sleep(50);
}
}
}
this is the turtle method:
import java.awt.Color;
import java.awt.Point;
public class Turtle extends Animal {
public Turtle(String type, String name, Point location, Color color) {
super(type, name, location, color);
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
return "T";
}
#Override
public void move() {
int newX = getLocation().x+3;
int negX = getLocation().x-3;
int newY = getLocation().y+3;
int negY = getLocation().y-3;
for(int i = 1; i <= 5; i++){
setLocation(new Point(getLocation().x, newY));
}
for(int i = 1; i <= 5; i++){
setLocation(new Point(negX, getLocation().y));
}
for(int i = 1; i <= 5; i++){
setLocation(new Point(getLocation().x, negY));
}
for(int i = 1; i <= 5; i++){
setLocation(new Point(newX, getLocation().y));
}
}
}
and finally, we have the animal class that turtle extends into:
import java.awt.Color;
import java.awt.Point;
public abstract class Animal {
private String type;
public Animal(String type, String name, Point location, Color color) {
super();
this.type = type;
this.name = name;
this.location = location;
this.color = color;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
private String name;
private Point location;
private Color color;
public abstract String toString();
public abstract void move ();
public Point getLocation() {
return location;
}
public void setLocation(Point location) {
this.location = location;
}
}
I know that's a lot to sift through and I'm sorry if I'm not allowed to post questions about something this complex. I've just been running around in circles inside my head and I decided to ask other peoples opinions. Oh yeah, I'm using eclipse as well. Thank you for taking a look!
The problem is with your move method. All the new points are being set before the image can be repainted. Add the following to the Turtle class.
public class Turtle extends Animal {
private int steps=0;
And then replace the move method with:
#Override
public void move() {
if(steps<5)
setLocation(new Point(getLocation().x+3, getLocation().y));
else if(steps<10)
setLocation(new Point(getLocation().x, getLocation().y+3));
else if(steps<15)
setLocation(new Point(getLocation().x-3, getLocation().y));
else
setLocation(new Point(getLocation().x, getLocation().y-3));
steps++;
if(steps>=20)
steps=0;
}
Here, the position is only being re-evaluated every time the repaint function is called.