Java-Matrix multiplication failing in loop only - java

I'm a math student writing a program to help with my research, but a small flaw is holding me up and I'm not sure what's going wrong.
In the first two calls to the power method, the computation is correct. In the loop, the first power works fine, but the matrix that is made when j=2 is a 2x2 matrix, instead of the correct one I usually get!
I'm sorry if I haven't included enough information, but the program is becoming quite large and I'm unfamiliar with conventions in CS and on SO. I appreciate any help.
public Queue<OrdInt> tree(Matrix inputMatr) {
Queue<OrdInt> holder = new LinkedList<OrdInt>();
LinkedList<Matrix> powers = new LinkedList<Matrix>();
powers.add(Matrix.identity(inputMatr.size));
int Np=0;
int j=1;
while(!powers.contains(inputMatr.power(j)) && j<Math.pow(2, inputMatr.size)){
powers.add(inputMatr.power(j));
try {
Np = (2*powers.get(j).nullspaceDim() - powers.get(j-1).nullspaceDim() - powers.get(j).matrixMultiply(inputMatr).nullspaceDim());
System.out.println("J+1 dim: " +powers.get(j).matrixMultiply(inputMatr).size);
} catch (Exception e) {
e.printStackTrace();
}
if(Np!=0){
holder.offer(new OrdInt(j, Np));
}
j++;
}
return holder;
}
edit: by request, the code for power and matrix multiply.
public Matrix matrixMultiply(Matrix one) throws Exception{
if(this.size != one.size){
throw new Exception("Incompatible Matrices.");
}
Matrix total = new Matrix(this.size);
for(int x=0; x<this.size; x++){
for (int y=0; y<this.size; y++){
int hold=0;
for(int z=0; z<this.size; z++){
hold += this.get(x,z)*one.get(z,y);
}
total.set(x,y,hold%2);
}
}
return total;
}
public Matrix power(int power) {
Matrix holder = this;
if(power==0){
return identity(this.size);
}
if(power==1){
return this;
}
else{
for(int x=0; x<power; x++){
try {
holder =holder.matrixMultiply(this);
} catch (Exception e) {
e.printStackTrace();
}
}
return holder;
}
}

Related

why is the remaining number of occupants not calculated correctly?

I'm coding a rescue simulation program and while applying the required tests it keeps giving a failure saying that the number of occupants remaining in the building is not correctly calculated and I can't figure out why!
below i provided the two methods that are supposed to give back the number of occupants.
Thanks in advance!
public void treat(){
boolean f=false;
if(!f){
((Disaster)((Citizen)this.getTarget()).getDisaster()).setActive(false);
ResidentialBuilding r= (ResidentialBuilding)this.getTarget();
if(r.getOccupants().size()!=0){
for(int i=0;i<r.getOccupants().size();i++){
if(this.getPassengers().size()<=this.getMaxCapacity()){
f=true;
Citizen z=(Citizen)r.getOccupants().get(i);
if(z.getState()!=CitizenState.DECEASED){
r.getOccupants().remove(i);
this.getPassengers().add(z);
}
}
}
}
else{
this.setState(UnitState.IDLE);
this.jobsDone();
}
}
else
this.cycleStep();
}
public void cycleStep(){
if(super.getDistanceToBase()==0)
super.getWorldListener().assignAddress(this, 0, 0);
if(super.getTarget()!=null){
if(this.getLocation()== this.getTarget().getLocation()){
this.setDistanceToBase(this.getLocation().getX() + this.getLocation().getY());
}
else if(this.getDistanceToBase()<=0){
this.setDistanceToBase(0);
this.setLocation(new Address(0,0));
for (int i = 0; i < this.getPassengers().size(); i++) {
Citizen c = (Citizen)this.getPassengers().remove(i);
}
}
else{
this.setDistanceToBase(this.getDistanceToBase()-this.getStepsPerCycle());
}
}
}

Making a targeting system in Java

This is a "tower defense" game. I have a class called soldier.
if(wave1==true){
for(int i=0;i<(wave*10);i++){
handler.addObject(new soldier(getX(), getY(), ID.soldier, handler));
try {
// System.out.println(i);
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
wave++;
wave1=false;
try {
// System.out.println(i);
Thread.sleep(WT);
} catch (InterruptedException e) {
}
}
Every time this code is called is the soldier gets spawned 10 times for every wave, but I have one issue. I would like the tower 1 to kill the furthest soldier in range. The code for the killing:
private void collision() {
for(int i=0; i< Handler.object.size();i++){
GameObject tempObject = Handler.object.get(i);
if(tempObject.getID()== ID.ST1){
if(getBounds().intersects(tempObject.getBounds())){
Hsol=(Hsol-1);
if(Hsol<=0){
handler.removeObject(this);
}
}
}
}
}
So I know I need to do a distance formula to find which ones closer, but I'm not sure how to do that.
Given two points (x1, y1) and (x2, y2), the distance formula is
√[(x1-x2)^2 + (y1-y2)^2]
So, using that formula, you can loop through each soldier and see which one is closest to the point that the attack is coming from.
private void collision() {
for(int i=0; i< Handler.object.size();i++){
GameObject tempObject = Handler.object.get(i);
if(tempObject.getID()== ID.ST1){
if(this==handler.object.get(3)){
if(getBounds().intersects(tempObject.getBounds())){
Hsol=(Hsol-1);
if(Hsol<=0){
handler.removeObject(this);
HUD.coin=(HUD.coin+100);
instances=(instances-1);
//System.out.println(HUD.coin);
}
}
}
}
}
}

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.

I'm getting an IndexOutOfBoundsException with my arraylist, what am I doing wrong?

This class is in a program for a game I'm writing that is basically Space Invaders. I'm getting Exceptions for some reason and I don't see why I should be getting them.
Here's the class in question, but I can post all the code if necessary:
public class GamePanel extends JPanel {
Launcher launcher1;
Background bground1;
Shot shot;
public ArrayList<Shot> shots;
public int numShots;
public static int counter;
public GamePanel() throws IOException {
super();
this.shots = new ArrayList<>();
this.numShots = 0;
launcher1 = new Launcher();
bground1 = new Background();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bground1.background, 0, 0, getWidth(), getHeight(), null);
g.drawImage(launcher1.baldEagleImage, launcher1.getLxCoord(), launcher1.lyCoord, null);//paint the launcher
while (counter == 1) {
for (int i = 0; i < shots.size(); i++) {
g.drawImage(shots.get(i).mcDShotImage, shots.get(i).staticXLauncherCoord, shots.get(i).getSyCoord(), null);
}
}
}
public void move(GamePanel gamePanel) {
launcher1.moveX();
if (numShots > 0) {
moveShot();
}
repaint();
}
public void moveShot() {
for (int i = 0; i < numShots; i++) {//loop to move all the shots
if (shots.get(i).getSyCoord() > 10) { // THIS IS THE ISSUE, but I don't know why
counter = 1;
shots.get(i).moveY();
repaint();
} else {
counter = 0;
shots.remove(i);
repaint();
}
}
}
public void createShots() {
try {
for (int j = 0; j < numShots; j++) {
shots.add(new Shot());
}
} catch (IOException | IndexOutOfBoundsException e) {
System.out.println("caught an exception" + e);
}
}
}
The problem is in this piece of code:
} else {
counter = 0;
shots.remove(i);
repaint();
}
You remove an item from shots without adjusting numShots, causing an index out of bounds exception in one of subsequent iterations.
To fix this, either add numShots-- in the else branch, or use the built-in size() method that returns the count of elements in a list instead: unlike numShots which you need to maintain, shots.size() never gets "out of sync" with the actual count.
In the above line of code what is apparent is the issue is numShots is > shots.size() (because you also remove shots.
Since I couldn't where you are incrementing the numShots, in this piece of code one simple (albeit not sure from your logic perspective) change your for loop as below:
for (int i = 0; i < shots.size(); i++)

Printing ArrayList of 2D arrays in a specific format

I'm trying to save an ArrayList to a text file in a particular format. It's in the correct format but it only prints out the color of one element in the ArrayList of blocks. I know the problem lies with the getBlockColor() method, what's the best way to implement this method? Here's what I've got so far.
This is the method that is in the class with the ArrayList of frames.
public void saveFrames(String fileName) {
System.out.println("**method save writes data back to a file "
+ fileName);
try {
PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(fileName)));
outfile.println(frames.size());
outfile.println(Frame.getCOLUMNS());
for (Frame f : frames) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
Color a = f.getBlockColor();
if (a.equals(Color.white)) {
outfile.print("w");
}
if (a.equals(Color.orange)) {
outfile.print("o");
}
if (a.equals(Color.red)) {
outfile.print("r");
}
if (a.equals(Color.yellow)) {
outfile.print("y");
}
if (a.equals(Color.green)) {
outfile.print("g");
}
if (a.equals(Color.blue)) {
outfile.print("b");
}
}
outfile.println("");
}
}
outfile.close();
}
catch (IOException e) {
System.out.println("file not found try again");
}
}
This is the code from the frame that is supposed to get the color of the blocks.
public Color getBlockColor() {
for (int ROWS = 0; ROWS < 20; ROWS++) {
for (int COLUMNS = 0; COLUMNS < 20; COLUMNS++) {
blockColor = blocks[ROWS][COLUMNS].getBackground();
}
}
return blockColor;
}
I think you made a small mistake in getting the block color.
I guess you were supposed to return the color for a specific row and column, like this:
public Color getBlockColor(int row, int column) {
return blocks[row][column].getBackground();
}

Categories

Resources