Modifying ArrayList object values from another class - java

I have two classes: class Creature which contains ArrayList boids, and class Food.
Boids have a few parameters:
Creature(float posX, float posY, int t, int bth, int ah) {
location = new PVector(posX, posY);
vel = new PVector(random(-5,5), random(-5, 5));
acc = new PVector();
type = t;
if (t == 1) { btype = bth; }
else { health = bth; }
if (t == 1) { age = ah; }
else { hunger = ah; }
wdelta = 0.0;
action = 0;
if (btype == 1) { mass = 5.0; }
else { mass = 7.0; }
}
Food class has this method:
void foodtime(ArrayList boids) {
for (int i = 0; i < boids.size(); i++) {
Creature boid = (Creature) boids.get(i);
float distance = PVector.dist(location, boid.location);
if (distance < 0.5) {
bnumadj = i;
count++;
if (count == quantity) {
planet.food.remove(this);
count = 0;
bnumadj = -1;
}
}
}
}
What I'm trying to achieve is that if a boid "eats" the food, their boid type (btype) changes from 2 to 1.
I'm trying to use bnumadj variable to feed it back to the boid in this method:
void boid(ArrayList boids) {
for (int i = 0; i < boids.size(); i++) {
if (i == bnumadj) {
this.btype = 1;
bnumadj = -1;
}
}
}
Where am I going wrong?

This seems like a very convoluted way to do this, so I'm not surprised you're having issues. You're comparing values to indexes, which doesn't make a ton of sense to me.
Instead, try using a simple nested loop to do what you want. You can use an Iterator to make it easier to remove items while iterating.
ArrayList<Creature> boids = new ArrayList<Creature>();
ArrayList<Food> food = new ArrayList<Food>();
//populate ArrayLists
void draw(){
for(Creature boid : boids){
Iterator<Food> foodIter = food.iterator();
while(foodIter.hasNext()){
Food f = foodIter.next();
float distance = PVector.dist(boid.location, food.location);
if (distance < 0.5) {
boid.btype = 1;
foodIter.remove(); //removes the food
}
}
}
//draw the scene
}
I suppose you could move the second iteration using the Iterator inside the Creature type, but the basic idea is this: keep it simple by using an Iterator to remove the Food instead of trying to match indexes.

Related

From String to Integer Functions

I am trying to write a program that will receive a function as a String and solve it. For ex. "5*5+2/2-8+5*5-2" should return 41
I wrote the code for multiplication and divisions and it works perfectly:
public class Solver
{
public static void operationS(String m)
{
ArrayList<String> z = new ArrayList<String>();
char e= ' ';
String x= " ";
for (int i =0; i<m.length();i++)
{
e= m.charAt(i);
x= Character.toString(e);
z.add(x);
}
for (int i =0; i<z.size();i++)
{
System.out.print(z.get(i));
}
other(z);
}
public static void other(ArrayList<String> j)
{
int n1=0;
int n2=0;
int f=0;
String n= " ";
for (int m=0; m<j.size();m++)
{
if ((j.get(m)).equals("*"))
{
n1 = Integer.parseInt(j.get(m-1));
n2 = Integer.parseInt(j.get(m+1));
f= n1*n2;
n = Integer.toString(f);
j.set(m,n);
j.remove(m+1);
j.remove(m-1);
m=0;
}
for (int e=0; e<j.size();e++)
{
if ((j.get(e)).equals("/"))
{
n1 = Integer.parseInt(j.get(e-1));
n2 = Integer.parseInt(j.get(e+1));
f= n1/n2;
n = Integer.toString(f);
j.set(e,n);
j.remove(e+1);
j.remove(e-1);
e=0;
}
}
}
System.out.println();
for (int i1 =0; i1<j.size();i1++)
{
System.out.print(j.get(i1)+",");
}
However, for adding and subtracting, since there isnt an order for adding and subtracting, just whichever comes first, I wrote the following:
int x1=0;
int x2=0;
int x3=0;
String z = " ";
for (int g=0; g<j.size();g++)
{
if ((j.get(g)).equals("+"))
{
x1= Integer.parseInt(j.get(g-1));
x2= Integer.parseInt(j.get(g+1));
x3= x1+x2;
z = Integer.toString(x3);
j.set(g,z);
j.remove(g+1);
j.remove(g-1);
g=0;
}
g=0;
if ((j.get(g)).equals("-"))
{
x1= Integer.parseInt(j.get(g-1));
x2= Integer.parseInt(j.get(g+1));
x3= x1-x2;
z = Integer.toString(x3);
j.set(g,z);
j.remove(g+1);
j.remove(g-1);
g=0;
}
g=0;
}
System.out.println();
for (int i1 =0; i1<j.size();i1++)
{
System.out.print(j.get(i1)+",");
}
After this, it prints:
25,+,1,-,8,+,25,–,2,
. What am I doing wrong? Multiplication and dividing seem to be working perfectly
You have 2 problems:
1) g=0; statements after if and else blocks will make you go into an infinite loop.
2) From the output you gave, the first minus (-) is Unicode character HYPHEN-MINUS (U+002D), while the second minus (–) is Unicode character EN DASH (U+2013), so (j.get(g)).equals("-") fails for the second minus as they are not equal.
Going for an answer that doesn't help with your exact specific problem, but that hopefully helps you much further than that.
On a first glance, there are various problems with your code:
Your are using super-short variable names all over the place. That saves you maybe 1 minute of typing overall; and costs you 5, 10, x minutes every time you read your code; or show it to other people. So: dont do that. Use names that say what the thing behind that name is about.
You are using a lot of low-level code. You use a "couting-for" loop to iterate a list (called j, that is really really horrible!) for example. Meaning: you make your code much more complicated to read than it ought to be.
In that way, it looks like nobody told you so far, but the idea of code is: it should be easy to read and understand. Probably you dont get grades for that, but believe me: in the long run, learning to write readable code is a super-important skill. If that got you curious, see if you can get a hand on "Clean code" by Robert Martin. And study that book. Then study it again. And again.
But the real problem is your approach to solve this problem. As I assume: this is some part of study assignment. And the next step will be that you don't have simple expressions such as "1+2*3"; but that you are asked to deal with something like "sqrt(2) + 3" and so on. Then you will be asked to add variables, etc. And then your whole approach breaks apart. Because your simple string operations won't do it any more.
In that sense: you should look into this question, and carefully study the 2nd answer by Boann to understand how to create a parser that dissects your input string into expressions that are then evaluated. Your code does both things "together"; thus making it super-hard to enhance the provided functionality.
You can use the built-in Javascript engine
public static void main(String[] args) throws Exception{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String code = "5*5+2/2-8+5*5-2";
System.out.println(engine.eval(code));
}
Primarily Don't Repeat Yourself (the DRY principle). And use abstractions (full names, extracting methods when sensible). Static methods are a bit cumbersome, when using several methods. Here it is handy to use separate methods.
Maybe you want something like:
Solver solver = new Solver();
List<String> expr = solver.expression("5*5+2/2-8+5*5-2");
String result = solver.solve(expr);
A more abstract Solver class would do:
class Solver {
List<String> expression(String expr) {
String[] args = expr.split("\\b");
List<String> result = new ArrayList<>();
Collections.addAll(result, args);
return result;
}
String solve(List<String> args) {
solveBinaryOps(args, "[*/]");
solveBinaryOps(args, "[-+]");
return args.stream().collect(Collectors.joining(""));
}
The above solveBinaryOps receives a regular expression pattern or alternatively simply in some form the operators you want to tackle.
It takes care of operator precedence.
private void solveBinaryOps(List<String> args, String opPattern) {
for (int i = 1; i + 1 < args.length; ++i) {
if (args.get(i).matches(opPattern)) {
String value = evalBinaryOp(args.get(i - 1), args.get(i), args.get(i + 1));
args.set(i, value);
args.remove(i + 1);
args.remove(i - 1);
--i; // Continue from here.
}
}
}
private String evalBinaryOp(String lhs, String op, String rhs) {
int x = Integer.parseInt(lhs);
int y = Integer.parseInt(rhs);
int z = 0;
switch (op) {
case "*":
z = x * y;
break;
case "/":
z = x / y;
break;
case "+":
z = x + y;
break;
case "-":
z = x - y;
break;
}
return Integer.toString(z);
}
}
The above can be improved at several points. But it is readable, and rewritable.
public class Solver {
public static void main(String args[]) {
operation("5+2*5-6/2+1+5*12/3");
}
public static void operation(String m) {
ArrayList<Object> expressions = new ArrayList<Object>();
String e;
String x = "";
for (int i = 0; i < m.length(); i++) {
e = m.substring(i, i + 1);
if (!(e.equals("*") || e.equals("/") || e.equals("+") || e
.equals("-"))) {
x += e;
continue;
} else {
if (!x.equals("") && x.matches("[0-9]+")) {
int oper = Integer.parseInt(x);
expressions.add(oper);
expressions.add(m.charAt(i));
x = "";
}
}
}
if (!x.equals("") && x.matches("[0-9]+")) {
int oper = Integer.parseInt(x);
expressions.add(oper);
x = "";
}
for (int i = 0; i < expressions.size(); i++) {
System.out.println(expressions.get(i));
}
evaluateExpression(expressions);
}
public static void evaluateExpression(ArrayList<Object> exp) {
//Considering priorities we calculate * and / first and put them in a list mulDivList
ArrayList<Object> mulDivList=new ArrayList<Object>();
for (int i = 0; i < exp.size(); i++) {
if (exp.get(i) instanceof Character) {
if ((exp.get(i)).equals('*')) {
int tempRes = (int) exp.get(i - 1) * (int) exp.get(i + 1);
exp.set(i - 1, null);
exp.set(i, null);
exp.set(i + 1, tempRes);
}
else if ((exp.get(i)).equals('/')) {
int tempRes = (int) exp.get(i - 1) / (int) exp.get(i + 1);
exp.set(i - 1, null);
exp.set(i, null);
exp.set(i + 1, tempRes);
}
}
}
//Create new list with only + and - operations
for(int i=0;i<exp.size();i++)
{
if(exp.get(i)!=null)
mulDivList.add(exp.get(i));
}
//Calculate + and - .
for(int i=0;i<mulDivList.size();i++)
{
if ((mulDivList.get(i)).equals('+')) {
int tempRes = (int) mulDivList.get(i - 1) + (int) mulDivList.get(i + 1);
mulDivList.set(i - 1, null);
mulDivList.set(i, null);
mulDivList.set(i + 1, tempRes);
}
else if ((mulDivList.get(i)).equals('-')) {
int tempRes = (int) mulDivList.get(i - 1) - (int) mulDivList.get(i + 1);
mulDivList.set(i - 1, null);
mulDivList.set(i, null);
mulDivList.set(i + 1, tempRes);
}
}
System.out.println("Result is : " + mulDivList.get(mulDivList.size() - 1));
}
}

Stack overflow error in minimax algorim

Hi so I've recently started programming in java and I've set myself a task of making an AI for a tic tac toe game I've made
However the minmax algorithm is throwing a Stack Overflow error and I cant see in the error or the program where the problem is.
Here's the program:
public State minmax(boolean max, State currentState)
{
if (currentState.getNull() == 0) {
return currentState;
}
else {
State[] successorStates = currentState.getSuccessorStates(aiPlayer);
ArrayList<Integer> scoresTemp = new ArrayList<>();
for (State state : successorStates) {
scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));
}
Integer[] scores = (Integer[]) scoresTemp.toArray();
if (max) {
State maxState = successorStates[0];
int maxScore = evaluate(aiPlayer, maxState);
for (int score : scores) {
if (scores[0] > maxScore) {
maxScore = score;
maxState = successorStates[score];
}
}
return maxState;
}
else
{
State minState = successorStates[0];
int minScore = evaluate(aiPlayer, minState);
for (int score : scores) {
if (scores[0] > minScore) {
minScore = score;
}
}
return minState;
}
}
}
It returns the state which is the best move to make.
getNull() returns the amount of spaces left that can be played on.
getSuccesorStates(Player) returns all of the succeeding states of that state by making a new state of which contains the old moves and a new one of the Player.
evaluate() returns the value -1, 0 or 1 depending on a win, draw or loss in that state. None returns 0
edit:
public int getNull()
{
int amount = 0;
for (int x =0; x<9; x++)
{
if (getAllCells()[x]==null)
{
amount++;
}
}
return amount;
}
public State[] getSuccessorStates(Player player)
{
State[] states = new State[getNull()];
Player[][] stateCells = cells.clone();
int[][] nullPositions = getNulls();
for (int x=0; x<getNull(); x++)
{
stateCells[nullPositions[x][0]][nullPositions[x][1]] = player;
states[x] = new State(player, stateCells);
stateCells = cells.clone();
}
return states;
}
Caused by: java.lang.StackOverflowError
at sample.AI.minmax(AI.java:23)
at sample.AI.minmax(AI.java:32)
at sample.AI.minmax(AI.java:32)
.
.
.
23: if (currentState.getNull() == 0)
32: scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));
public Player[] getAllCells()
{
Player[] cellList = new Player[9];
for (int x = 0; x<3; x++)
{
for (int y = 0; y<3; y++)
{
cellList[y*3+x] = cells[x][y];
}
}
return cellList;
}
minmax is called in:
public Ply getPly(State state)
{
State bestState = minmax(true, state);
State[] successorStates = state.getSuccessorStates(aiPlayer);
ArrayList<State> states = new ArrayList<State>();
for (int x=0; x<successorStates.length; x++)
{
states.add(successorStates[x]);
}
int[][] nulls = state.getNulls();
Ply bestPly = new Ply(aiPlayer, nulls[states.indexOf(bestState)][0], nulls[states.indexOf(bestState)][1]);
return bestPly;
}
Thankyou if anyone could help:)
Your problem is here:
scoresTemp.add(evaluate(aiPlayer, minmax(!max, state)));
When you call the minmax method you create a bunch of data that uses up the memory ( java allows a certain amount of the computers memory to be used ).
You then inside minmax call minmax again making it create even more data and this is happening infinitely until there is no more memory left and Java throws the StackOverflow exception.

traversing a 2d array and adding indexs to a stack

I have a project for school to take my current pacman program and have pacman traverse the 2-d char array to find a pattern to complete the maze.
I am trying to use a stack and add specific index of my maze to the stack so when pacman reaches the index it pops off and he chooses a direction randomly to another index and so forth until all dots are eaten. My issue is taking my 2d array and finding the index values of the intersections and then adding them to a stack.
I am new to java and not really sure how to approach this I posted my maze I have and some code that will use the stack to find the sequence. Thanks in advanced.
private void create() {
String[] tier = new String[tall];
tier[0] = "|======================================|";
tier[1] = "|......................................|";
tier[2] = "|.====.==========================.====.|";
tier[3] = "|.||||............................||||.|";
tier[4] = "|.====.==========================.====.|";
tier[5] = "|......................................|";
tier[6] = "|.====================================.|";
tier[7] = "|......................................|";
tier[8] = "|.====.======.====----====.======.====.|";
tier[9] = "|.||||........|| ||........||||.|";
tier[10] = "|.||||.======.|| ||.======.||||.|";
tier[11] = "|.||||........|| ||....... ||||.|";
tier[12] = "|.====.======.============.======.====.|";
tier[13] = "|......................................|";
tier[14] = "|.===========..............===========.|";
tier[15] = "|.............===== =====.............|";
tier[16] = "|.=======.===.||$ $||.===.=======.|";
tier[17] = "|.|||||||.===.===== =====.===.|||||||.|";
tier[18] = "|.|||||||......................|||||||.|";
tier[19] = "|.|||||||.====================.|||||||.|";
tier[20] = "|.=======......................=======.|";
tier[21] = "|.==......====================......==.|";
tier[22] = "|.==.====.======........======.====.==.|";
tier[23] = "|....====........======........====....|";
tier[24] = "|======================================|";
for (int i = 0; i < tall; i++) {
array[i] = tier[i].toCharArray();
}
}
public boolean isPattern(Spot b, Spot e) {
Stack<Spot> ss = new Stack<Spot>();
Spot topPost, nextPost;
allOld();
ss.push(b);
markOld(b);
topPost = ss.peek();
while (!ss.empty() && (topPost.compareTo(e) != 0)) {
nextPost = getNextSpot(topPost);
if (nextPost == null) {
ss.pop();
} else {
ss.push(nextPost);
markOld(nextPost);
}
topPost = ss.peek();
}
if (ss.empty()) {
return false;
} else {
return true;
}
}
public void index(int x, int y, int dx, int dy){
x=array.length;
y=array[x].length;
for( int i=0;i <x;i++){
for(int j =0; j<y;j++){
if(array[i].get(i))//this should determine if its aninersection and then add to the stack
}
}
}
}
the last method is where i am getting stuck. I dont know how to get the specific index values. I guess i can enter them manually but I am sure there is an easier way. Please comment if need more context on the problem and Thanks again.

XYPlot doesn't draw all points correctly

I'm trying to display 550 data points with periodic peaks (the flat line is 61). The problem is, that androidplot isn't drawing all the points correctly! From my log:
ECG I values 61,61,62,63,62,61,61,61,61,67,71,68,61,53,61,61,61,61,61,61,61,61,62,63,64,64,64,63,62,61,61,61
I've got the rangeboundaries set to plot.setRangeBoundaries(0,100, BoundaryMode.AUTO);, but as you can see, the peaks never drop to the 53 data point. I can see this lower point sometimes, but it gets smoothed out a fraction of a second later (as you can see in the screenshot).
My line and point formatter is:
LineAndPointFormatter lapf = new LineAndPointFormatter(p.color, null, null, null);
lapf.getLinePaint().setStrokeJoin(Paint.Join.MITER);
lapf.getLinePaint().setStrokeWidth(1);
I've tried with the both Paint.Join.ROUND and Paint.Join.BEVEL and got the same effect. I've also used the debugger to check that 53 is being inserted into the series.
EDIT
After some debugging, it looks like my pulse loop thread is wrong:
while (keepRunning) {
for (PulseXYSeries j : series) {
for (int k = 0; k < j.plotStep; k++) {
int at = (j.position + k) % j.getSize();
if (j.pulsing) {
if (j.pulsePosition == j.pulseValues.size() - 1) {
j.pulsing = false;
j.pulsePosition = 0;
} else {
try {
int pulseVal = j.pulseValues.get(j.pulsePosition);
j.setY(pulseVal,at);
j.pulsePosition += 1;
} catch(IndexOutOfBoundsException e) {
j.pulsePosition = 0;
}
}
} else {
j.setY(j.pulseValues.get(0), at);
long currTime = SystemClock.elapsedRealtime();
if (currTime - j.getLastPulse() >= j.getPulseDelay()) {
j.pulsing = true;
j.setLastPulse(currTime);
}
}
j.remove(((at + j.eraserSize) % j.getSize()));
}
j.position = (j.position + 1) % j.getSize(); // fixed it by changing +1 to + j.plotStep
}
Thread.sleep(delay);
}
My custom series looks like:
private class PulseXYSeries implements XYSeries {
private List<Integer> pulseValues = new ArrayList<Integer>();
private int pulsePerMinute;
public int pulsePosition;
public int position;
private ArrayList<Integer> values;
private String title;
private long lastPulse;
public boolean pulsing = false;
public int eraserSize = 20;
public int plotStep = 3;
}

JTable table.getSelectedRows() issue

I create a JTable with a customized model and characteristics. I have a long written class that carries out the set up and rendering properly. I see that the .getSelectedRows() method is not working and never evaluates to a value. I was trying to get the index of the first row selected and the last. Here is my code.
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
rows = table.getSelectedRows();
firstRow = rows[0];
int rowCount = rows.length;
lastRow = rows[(rowCount - 1)];
if (command.equals("Run Threw")) {
}else if (command.equals("Shield Bash")) {
this.attack(firstRow, lastRow, command);
}
public boolean block (int defendersRow) {
}
public boolean fumble (int attackersRow) {
}
public boolean dodge (int defendersRow) {
}
public boolean critical (int attackersRow, int attackRoll) {
}
public void attack(int firstRow, int lastRow, String command) {
command = this.command;
firstRow = this.firstRow;
lastRow = this.lastRow;
if (command == "Bludgeon" || command == "React" || command == "ShieldBash") {
attackersRow = this.lastRow;
defendersRow = this.firstRow;
}else if(command == "Attack" || command == "Skill") {
attackersRow = this.firstRow;
defendersRow = this.lastRow;
}else {
}
table.setValueAt(true, attackersRow, 16);
fumbled = this.fumble(attackersRow);
if (fumbled == true) {
outputString = "fumbled";
}
Object maxDamageObject = table.getValueAt(attackersRow, 10);
int maxDamage = (Integer) maxDamageObject;
attackRoll = generator.nextInt(100) + 1;
this.critical(attackersRow, attackRoll);
if (criticaled == true) {
outputString = "criticaled";
}
dodged = this.dodge(defendersRow);
if (dodged == true) {
outputString = "dodged";
}
blocked = this.block(defendersRow);
if (blocked == true) {
outputString = "blocked";
}
int defenseRoll = generator.nextInt(100) + 1;
Object attackBaseObject = table.getValueAt(attackersRow, 6);
Object defenseBaseObject = table.getValueAt(defendersRow, 11);
int attackBase = (Integer) attackBaseObject;
int defenseBase = (Integer) defenseBaseObject;
int attack = attackRoll + attackBase;
int defense = defenseRoll + defenseBase;
Object minDamageObject = table.getValueAt(attackersRow, 9);
int minDamage = (Integer) minDamageObject;
damage = generator.nextInt((maxDamage - minDamage))+minDamage;
if (criticaled == true) {
damage = maxDamage * 2;
}else if (attack >= (defense + 50)) {
damage = damage * 2;
}else if (attack >= defense) {
damage = damage;
}else {
damage = 0;
}
this.outputSelection(outputString, attackersRow, defendersRow, command, damage);
this.damage(defendersRow, damage);
}
private void damage(int defendersRow, int damage) {
}
private void outputSelection(String outputString, int attackersRow, int defendersRow, String command, int damage) {
}
I doesn't see problem with code. May be you can cross check following points:
Are you able to select single / multiple row(s)? Or check what jTableObject.getRowSelectionAllowed() returns
Does your code gets called only after selecting rows. Your code should be executed after some rows are selected so that it can return you expected values.
Listener which calls above mentioned code, is it added to table.
Small points but better to cross check :).
As shown in this working example, you can add a ListSelectionListener to your table's ListSelectionModel and see if anything comes through. It may help pin down where things have gone awry: for example, a local table reference that shadows the intended one.

Categories

Resources