Java method call in method of another class - java

This is the main class:
public class Sudoku extends JFrame {
MenuBar Bar;
MenuItem itemFile[];
MenuItem itemHelp[];
Menu file;
Menu help;
public Sudoku() {
super("Sudoku");
setLayout(new FlowLayout());
setResizable(false);
itemFile =new MenuItem[2];
itemHelp =new MenuItem[2];
itemFile[0]=new MenuItem("New");
itemFile[1]=new MenuItem("Exit");
itemHelp[0]= new MenuItem("Rules");
itemHelp[1]= new MenuItem("Creators");
file=new Menu("File");
help=new Menu("Help");
file.add(itemFile[0]);
help.add(itemHelp[0]);
file.add(itemFile[1]);
help.add(itemHelp[1]);
Bar =new MenuBar();
Bar.add(file);
Bar.add(help);
setMenuBar(Bar);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
Game game = new Game();
ButtonController buttonController = new ButtonController(game);
ButtonPanel buttonPanel = new ButtonPanel();
buttonPanel.setController(buttonController);
add(buttonPanel, BorderLayout.EAST);
SudokuPanel sudokuPanel = new SudokuPanel();
SudokuController sudokuController = new SudokuController(sudokuPanel, game);
sudokuPanel.setGame(game);
sudokuPanel.setController(sudokuController);
add(sudokuPanel, BorderLayout.CENTER);
game.addObserver(buttonPanel);
game.addObserver(sudokuPanel);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public boolean action(Event evt, Object arg){
if(evt.target instanceof MenuItem){
String text=(String)arg;
System.out.println("Selected="+arg);
if(text.equals("Exit"))
System.exit(0);
else if(text.equals("New"))
// Get newGame() of Game class to run here.
}
return true;
}
This is the Game class:
package sudoku.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
public class Game extends Observable {
private int[][] solution;
private int[][] game;
private boolean[][] check;
private int selectedNumber;
private boolean help;
public Game() {
newGame();
check = new boolean[9][9];
help = true;
}
public void newGame() {
solution = generateSolution(new int[9][9], 0);
game = generateGame(copy(solution));
setChanged();
notifyObservers(UpdateAction.NEW_GAME);
}
public void checkGame() {
selectedNumber = 0;
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++)
check[y][x] = game[y][x] == solution[y][x];
}
setChanged();
notifyObservers(UpdateAction.CHECK);
}
public void setHelp(boolean help) {
this.help = help;
setChanged();
notifyObservers(UpdateAction.HELP);
}
public void setSelectedNumber(int selectedNumber) {
this.selectedNumber = selectedNumber;
setChanged();
notifyObservers(UpdateAction.SELECTED_NUMBER);
}
public int getSelectedNumber() {
return selectedNumber;
}
public boolean isHelp() {
return help;
}
public boolean isSelectedNumberCandidate(int x, int y) {
return game[y][x] == 0 && isPossibleX(game, y, selectedNumber)
&& isPossibleY(game, x, selectedNumber) && isPossibleBlock(game, x, y, selectedNumber);
}
public void setNumber(int x, int y, int number) {
game[y][x] = number;
}
public int getNumber(int x, int y) {
return game[y][x];
}
public boolean isCheckValid(int x, int y) {
return check[y][x];
}
private boolean isPossibleX(int[][] game, int y, int number) {
for (int x = 0; x < 9; x++) {
if (game[y][x] == number)
return false;
}
return true;
}
private boolean isPossibleY(int[][] game, int x, int number) {
for (int y = 0; y < 9; y++) {
if (game[y][x] == number)
return false;
}
return true;
}
private boolean isPossibleBlock(int[][] game, int x, int y, int number) {
int x1 = x < 3 ? 0 : x < 6 ? 3 : 6;
int y1 = y < 3 ? 0 : y < 6 ? 3 : 6;
for (int yy = y1; yy < y1 + 3; yy++) {
for (int xx = x1; xx < x1 + 3; xx++) {
if (game[yy][xx] == number)
return false;
}
}
return true;
}
private int getNextPossibleNumber(int[][] game, int x, int y, List<Integer> numbers) {
while (numbers.size() > 0) {
int number = numbers.remove(0);
if (isPossibleX(game, y, number) && isPossibleY(game, x, number) && isPossibleBlock(game, x, y, number))
return number;
}
return -1;
}
private int[][] generateSolution(int[][] game, int index) {
if (index > 80)
return game;
int x = index % 9;
int y = index / 9;
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++) numbers.add(i);
Collections.shuffle(numbers);
while (numbers.size() > 0) {
int number = getNextPossibleNumber(game, x, y, numbers);
if (number == -1)
return null;
game[y][x] = number;
int[][] tmpGame = generateSolution(game, index + 1);
if (tmpGame != null)
return tmpGame;
game[y][x] = 0;
}
return null;
}
private int[][] generateGame(int[][] game) {
List<Integer> positions = new ArrayList<Integer>();
for (int i = 0; i < 81; i++)
positions.add(i);
Collections.shuffle(positions);
return generateGame(game, positions);
}
private int[][] generateGame(int[][] game, List<Integer> positions) {
while (positions.size() > 0) {
int position = positions.remove(0);
int x = position % 9;
int y = position / 9;
int temp = game[y][x];
game[y][x] = 0;
if (!isValid(game))
game[y][x] = temp;
}
return game;
}
private boolean isValid(int[][] game) {
return isValid(game, 0, new int[] { 0 });
}
private boolean isValid(int[][] game, int index, int[] numberOfSolutions) {
if (index > 80)
return ++numberOfSolutions[0] == 1;
int x = index % 9;
int y = index / 9;
if (game[y][x] == 0) {
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++)
numbers.add(i);
while (numbers.size() > 0) {
int number = getNextPossibleNumber(game, x, y, numbers);
if (number == -1)
break;
game[y][x] = number;
if (!isValid(game, index + 1, numberOfSolutions)) {
game[y][x] = 0;
return false;
}
game[y][x] = 0;
}
} else if (!isValid(game, index + 1, numberOfSolutions))
return false;
return true;
}
private int[][] copy(int[][] game) {
int[][] copy = new int[9][9];
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++)
copy[y][x] = game[y][x];
}
return copy;
}
}
I want when I click "New" from my menubar (its action is in the main class), the newGame(); method of the Game class to be executed. I've tried many ways but all failed .. it's such a headache...
Any ideas ?

In the constructor you create an instance of the Game object - but it goes out of scope at the end of the method. You should keep a reference in the Sudoku class:
public class Sudoku extends JFrame {
...
private Game game;
public Sudoku() {
...
game = new Game();
Then:
public boolean action(Event evt, Object arg) {
if(evt.target instanceof MenuItem) {
String text=(String)arg;
System.out.println("Selected="+arg);
if(text.equals("Exit")) {
System.exit(0);
} else if(text.equals("New")) {
game.newGame();
}
}
return true;
}

Add a "Game" object as a member class of your main class, then you can access its methods anywhere in your class:
public class Sudoku extends JFrame {
private Game game;
// rest of your Sudoku class code as it currently is, but change:
Game game = new Game();
// to:
this.game = new Game();
// In your 'action' method, you can now call like this:
this.game.newGame();

Related

Using Depth-First Search in JAVA program instead of Breadth-First Search

I have a JAVA program where I am creating graphs and I have a Breadth-First Search but I would like to change it to Depth First Search. What changes should I make in a code? Thanks for help in advance.
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void bfs(CCGraph g, int start)
{
Queue<Integer> q = new LinkedList<Integer>();
int i, v;
q.offer(start);
discovered[start] = true;
while (!q.isEmpty())
{
v = q.remove();
process_vertex(v);
processed[v] = true;
for (i = g.degree[v] - 1; i >= 0; i--)
{
if (!discovered[g.edges[v][i]])
{
q.offer(g.edges[v][i]);
discovered[g.edges[v][i]] = true;
parent[g.edges[v][i]] = v;
}
}
}
}
I think you should understand the difference between depth first search and breadth first search. The code for depth first search goes as follows:
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void dfs(CCGraph g, int vertex)
{
discovered[vertex] = true;
for (i = g.degree[vertex] - 1; i >= 0; i--)
{
if (!discovered[g.edges[vertex][i]])
{
parent[g.edges[v][i]]=vertex;
dfs(g.edges[v][i]]);
}
}
}
}
The basic difference is the order by which vertexes are tested. While BFS uses queue (FIFO: First In First Out), DFS use stack (LIFO: Last In First Out).
You could implement stack using LinkedList:
LinkedList<Integer> stack = new LinkedList<Integer>();
stack.pop(); //returns the top of the stack
For more information please post mcve including test data.
Full code of the program. The goal is to change bfs to dfs.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class CCGraph
{
static final int MAXV = 100;
static final int MAXDEGREE = 50;
public int edges[][] = new int[MAXV + 1][MAXDEGREE];
public int degree[] = new int[MAXV + 1];
public int nvertices;
public int nedges;
CCGraph()
{
nvertices = nedges = 0;
for (int i = 1; i <= MAXV; i++)
degree[i] = 0;
}
void read_CCGraph(boolean directed)
{
int x, y;
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of vertices: ");
nvertices = sc.nextInt();
System.out.println("Enter the number of edges: ");
int m = sc.nextInt();
System.out.println("Enter the edges: <from> <to>");
for (int i = 1; i <= m; i++)
{
x = sc.nextInt();
y = sc.nextInt();
insert_edge(x, y, directed);
}
sc.close();
}
void insert_edge(int x, int y, boolean directed)
{
if (degree[x] > MAXDEGREE)
System.out.printf(
"Warning: insertion (%d, %d) exceeds max degree\n", x, y);
edges[x][degree[x]] = y;
degree[x]++;
if (!directed)
insert_edge(y, x, true);
else
nedges++;
}
void print_CCGraph()
{
for (int i = 1; i <= nvertices; i++)
{
System.out.printf("%d: ", i);
for (int j = degree[i] - 1; j >= 0; j--)
System.out.printf(" %d", edges[i][j]);
System.out.printf("\n");
}
}
}
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void bfs(CCGraph g, int start)
{
LinkedList<Integer> q = new LinkedList<Integer>();
int i, v;
q.offer(start);
discovered[start] = true;
while (!q.isEmpty())
{
v = q.remove();
process_vertex(v);
processed[v] = true;
for (i = g.degree[v] - 1; i >= 0; i--)
{
if (!discovered[g.edges[v][i]])
{
q.offer(g.edges[v][i]);
discovered[g.edges[v][i]] = true;
parent[g.edges[v][i]] = v;
}
}
}
}
static void initialize_search(CCGraph g)
{
for (int i = 1; i <= g.nvertices; i++)
{
processed[i] = discovered[i] = false;
parent[i] = -1;
}
}
static void process_vertex(int v)
{
System.out.printf(" %d", v);
}
static void connected_components(CCGraph g)
{
int c;
initialize_search(g);
c = 0;
for (int i = 1; i <= g.nvertices; i++)
{
if (!discovered[i])
{
c++;
System.out.printf("Component %d:", c);
bfs(g, i);
System.out.printf("\n");
}
}
}
static public void main(String[] args)
{
CCGraph g = new CCGraph();
g.read_CCGraph(false);
g.print_CCGraph();
connected_components(g);
}
}

Array index out of bounds while traversing edge members of array

I am creating a random maze generator in Java using the recursive backtracker algorithm. I need to set the edges of my maze cell data array to have been already visited by the algorithm so that it won't step out of bounds. The problem is probably staring me right in the face, I just cannot see where my error is.
Here is the whole error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30
at mazeMaker.Maze.initBoundries(Maze.java:55)
at mazeMaker.Maze.<init>(Maze.java:46)
at mazeMaker.Main.main(Main.java:8)
I have tried tracing the error as best I could and experimented with changing my variables. The program relies on multiple class files, so I think it would be best just to show the whole thing.
Main.java
package mazeMaker;
public class Main
{
public static void main(String[] args)
{
Maze mainMaze = new Maze(20, 30);
}
}
Maze.java
package mazeMaker;
import java.util.Random;
import java.util.Stack;
public class Maze
{
public int xSize = 0;
public int ySize = 0;
public int totalDimensions = 0;
Random randomGenerator = new Random();
public Cell[][] cellData;
public Stack<Cell> cellStack = new Stack<Cell>();
Cell tempCell; // Temporary variable used for maze generation
public Maze(int xSize, int ySize)
{
cellData = new Cell[xSize][ySize];
this.xSize = xSize;
this.ySize = ySize;
this.totalDimensions = this.xSize * this.ySize;
// Initialize array objects
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j] = new Cell();
}
}
// Assign x and y positions
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j].xPos = i;
cellData[i][j].yPos = j;
}
}
initBoundries();
}
private void initBoundries()
{
// Initialize the border cells as visited so we don't go out of bounds
for (int col = 0; col < this.xSize; col++)
{
cellData[0][col].hasBeenVisited = true;
cellData[this.ySize][col].hasBeenVisited = true;
}
for (int row = 0; row < this.ySize; row++)
{
cellData[row][0].hasBeenVisited = true;
cellData[row][this.xSize].hasBeenVisited = true;
}
}
private void generateMaze(int x, int y)
{
// Set current cell as visited
cellData[x][y].hasBeenVisited = true;
// While there are unvisited neighbors
while (!cellData[x][y+1].hasBeenVisited || !cellData[x+1][y].hasBeenVisited || !cellData[x][y-1].hasBeenVisited || !cellData[x-1][y].hasBeenVisited)
{
// Select a random neighbor
while (true)
{
int r = randomGenerator.nextInt(4);
if (r == 0 && !cellData[x][y+1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasNorthWall = false;
cellData[x][y+1].hasSouthWall = false;
generateMaze(x, y + 1);
break;
}
else if (r == 1 && !cellData[x+1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasEastWall = false;
cellData[x+1][y].hasWestWall = false;
generateMaze(x+1, y);
break;
}
else if (r == 2 && !cellData[x][y-1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasSouthWall = false;
cellData[x][y-1].hasNorthWall = false;
generateMaze(x, y-1);
break;
}
else if (r == 3 && !cellData[x-1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasWestWall = false;
cellData[x-1][y].hasEastWall = false;
generateMaze(x-1, y);
break;
}
}
}
// There are no unvisited neighbors
tempCell = cellStack.pop();
generateMaze(tempCell.xPos, tempCell.yPos);
}
// Begin generating maze at top left corner
private void generateMaze()
{
generateMaze(1,1);
}
}
Cell.java
package mazeMaker;
public class Cell
{
public boolean isCurrentCell;
public boolean hasBeenVisited;
public boolean hasNorthWall;
public boolean hasSouthWall;
public boolean hasEastWall;
public boolean hasWestWall;
public int xPos;
public int yPos;
}
cellData[this.ySize][col].hasBeenVisited = true;
You have initialized your cellData as cellData[20][30], but in the above-mentioned line you are calling cellData[30][col]. Instead of 30, the first bracket should have a value from 0 to 19, because the row size is 20.
My guess is from this code in initBoundries()
// Initialize the border cells as visited so we don't go out of bounds
for (int col = 0; col < this.xSize; col++)
{
cellData[0][col].hasBeenVisited = true;
cellData[this.ySize][col].hasBeenVisited = true;
}
this.ySize after initialize (from constructor) has value 30.

Fruchterman and Reingold algorithm vertices occupy same place in output (graph layout)

I was attempting to implement Fruchterman and Reingold algorithm in Java, but for some reasons, the coordinate of output vertices sometimes occupy the same coordinates, which is not something this algorithm would want. Where did I go wrong?
Coordinate object (vector)
public class Coordinates {
private float x;
private float y;
public Coordinates(float xx, float yy){
x = xx; y = yy;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public String toString(){
return x+" "+y;
}
public Coordinates subtract(Coordinates c){
return new Coordinates(x-c.x, y - c.y);
}
public Coordinates add(Coordinates c){
return new Coordinates(x + c.x, y + c.y);
}
public Coordinates unit(){
if(length() == 0)
return new Coordinates(0.000001f,0.0000001f);
else
return new Coordinates(x/(float)Math.sqrt(x*x + y*y),y/(float)Math.sqrt(y*y + x*x));
}
public float length(){
return (float)Math.sqrt(x*x + y*y);
}
public float distance(Coordinates c){
return (float) Math.sqrt((x-c.x)*(x-c.x) + (y-c.y)*(y-c.y));
}
public Coordinates scale(float k){
return new Coordinates(k*x,k*y);
}
}
Node object
import java.util.LinkedList;
public class Node {
private LinkedList<Node> incidentList; //has 30 elements for 30 vertices. 1 if incident, 0 if not
private int color;
private Coordinates coord;
private Coordinates disp;
public Coordinates getDisp() {
return disp;
}
public void setDisp(float x, float y) {
disp.setX(x);
disp.setY(y);
}
public void setDisp(Coordinates d) {
disp = d;
}
private int id;
public Node(){
incidentList = new LinkedList<Node>();
color = 0;
coord = new Coordinates(0,0);
disp = new Coordinates(0,0);
id = -1;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public LinkedList<Node> getIncidentList() {
return incidentList;
}
public void addEdge(Node n) {
incidentList.add(n);
}
public void removeEdge(Node n){
incidentList.remove(n);
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public Coordinates getCoord() {
return coord;
}
public void setCoord(float x, float y) {
coord.setX(x);
coord.setY(y);
}
public int getDegree(){
return incidentList.size();
}
public boolean isAdjacent(Node n){
return incidentList.contains(n);
}
}
Graph object (with layout algorithm function frlayout)
import java.util.ArrayList;
import java.util.Random;
public class MyGraph{
private final int DISRESPECT = -1;
private final int MORECOLOR = -3;
private final float EPSILON = 0.003f;
private ArrayList<Node> graphNodes; //maximum of 30 vertices
private int nVertices = 0;
private int score = 50;
int maxColor = 0;
int[] colorPopulation = new int[15];
double boundx, boundy, C;
public double getBoundx() {
return boundx;
}
public void setBoundx(double boundx) {
this.boundx = boundx;
}
public double getBoundy() {
return boundy;
}
public void setBoundy(double boundy) {
this.boundy = boundy;
}
public double getC() {
return C;
}
public void setC(double c) {
C = c;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getnVertices() {
return nVertices;
}
public MyGraph(){
graphNodes = new ArrayList<Node>();
}
public ArrayList<Node> getGraphNodes() {
return graphNodes;
}
//add a new node into the graph
//also set the id of that node
public void addNode(Node n){
graphNodes.add(n);
n.setId(nVertices++);
}
public void addEdge(Node n1, Node n2){
n1.addEdge(n2);
n2.addEdge(n1);
}
//randomly generate a graph with parsity
public void randomGenerating(double parse){ //parse is between 0 and 1
Random gen = new Random(System.currentTimeMillis());
int tempNVertices = 6; //CHANGE HERE TO BECOME A RANDOM NUMBER
for(int i = 0; i< tempNVertices; i++){
Node n = new Node();
float x = 0,y = 0;
while(true){
boolean flag = true;
x = gen.nextFloat();
y = gen.nextFloat();
for(int j = 0; j < i; j++){
if(x*boundx == graphNodes.get(j).getCoord().getX() && y*boundx == graphNodes.get(j).getCoord().getY())
flag = false; break;
}
if (flag)
break;
}
n.setCoord((float)(x*boundx),(float)(y*boundy));
addNode(n);
}
for(int i = 0; i < tempNVertices; i++){
for(int j = i + 1; j < tempNVertices; j++){
if(gen.nextDouble() < parse){
addEdge(graphNodes.get(i),graphNodes.get(j));
}
}
}
}
public void frLayout(){
double w = boundx, h = boundy;
double area = w*h;
double k = C*Math.sqrt(area/nVertices);
double temperature = 1000;
for(int i = 0; i < nVertices; i++)
System.out.println(graphNodes.get(i).getCoord().getX()+" "+graphNodes.get(i).getCoord().getY());
System.out.println("------------------------------");
for(int m = 0; m< 900; m++){
for(int i = 0; i < nVertices; i++){
Node v = graphNodes.get(i);
v.setDisp(0,0);
for(int j = 0; j< nVertices; j++){
Node u = graphNodes.get(j);
if(i!= j){
Coordinates delta = v.getCoord().subtract(u.getCoord());
double myFr = fr(u,v,k);
v.setDisp(v.getDisp().add(delta.unit().scale((float)myFr)));
if(Double.isNaN(v.getDisp().getX())){
System.out.println("PANIC: "+u.getCoord().getX()+" "+u.getCoord().getY()+" "+delta.getX()+" "+v.getCoord().getX());
return;
}
}
}
}
for(int i = 0; i < nVertices; i++){
Node v = graphNodes.get(i);
for(int j = i+1; j< nVertices; j++){
Node u = graphNodes.get(j);
if(v.isAdjacent(u)){
Coordinates delta = v.getCoord().subtract(u.getCoord());
double myFa = fa(u,v,k);
v.setDisp(v.getDisp().subtract(delta.unit().scale((float)myFa)));
u.setDisp(u.getDisp().add(delta.unit().scale((float)myFa)));
}
}
}
for(int i = 0; i< nVertices; i++){
//actually adjusting the nodes
Node v = graphNodes.get(i);
if(i == 0){
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());
Coordinates disp = v.getDisp().unit().scale((float)Math.min(v.getDisp().length(), temperature));
System.out.println(">>"+disp.getX()+" "+disp.getY());
}
Coordinates newCoord = (v.getCoord().add(v.getDisp().unit().scale((float)Math.min(v.getDisp().length(), temperature))));
v.setCoord(newCoord.getX(), newCoord.getY());
// //prevent from going outside of bound
// float x = (float)Math.min(w, Math.max(0,v.getCoord().getX()));
// float y = (float)Math.min(h, Math.max(0, v.getCoord().getY()));
//
// v.setCoord(x,y);
if(i == 0){
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());
}
}
temperature *= 0.9;
System.out.println("TEMPERATURE = "+temperature);
}
for(int i = 0; i< nVertices; i++){
Node v = graphNodes.get(i);
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());;
}
}
private double fa(Node ni, Node nj, double k){
double distance = ni.getCoord().distance(nj.getCoord());
return distance*distance/k;
}
private double fr(Node ni, Node nj, double k){
double distance = ni.getCoord().distance(nj.getCoord());
return k*k/(distance+0.000001);
}
public static void main(String[] args){
MyGraph grph = new MyGraph();
grph.setBoundx(480);
grph.setBoundy(480);
grph.setC(1);
grph.randomGenerating(1);
grph.frLayout();
}
}
Apologies for the overly long question. I tried tutorials on net, but couldn't get anywhere closer to figuring out what's going wrong. Note that when finding unit vector, if a vector is zero (0,0), I make it a very small, non-zero vector so that when two vertices are close to one another, they will repel violently just as the author of the algorithm hoped.
Any instructions would be appreciated.
I found my bug. I was taking square root of the distance twice while computing the attraction and repulsion forces as well as a few other smaller bugs. I posted the corrected code in my question. Hopefully anyone out there attempting this algorithm will find it useful. Note that by removing the boundary, we let the graph free to evolve, it could produce better shape. Once obtaining the resulting graph, we could always translate/scale it so that it fit into whatever dimension required.

Issues with MouseListener

I would really like some help with this game I am making. I have tried for the longest time and the solution eludes me. It doesn't do very much at the moment. Basically, I need the mouse listener to look for a left click and change the direction of the snake one way, and the other for a right click. But I can't seem to get the listener set up correctly. Excuse me if my coding is poor or if there is a better solution to something I am doing, I haven't been coding for that long.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.*;
import java.awt.Color;
import java.util.*;
import java.awt.event.*;
public class SnakeGame implements MouseListener{
static int delta = 10;
public static void main(String[] args) {
JFrame f = new JFrame("Snake Game"){
#Override
public void paint(Graphics g){
ArrayList<Integer> snakeX = new ArrayList<Integer>();
ArrayList<Integer> snakeY = new ArrayList<Integer>();
ArrayList<Integer> food = new ArrayList<Integer>();
char direction = 'e';
int tail = 2;
int foodX;
int foodY;
boolean game = true;
boolean check = false;
boolean recheck = true;
snakeX.add(0,20);
snakeX.add(1,10);
snakeX.add(2,0);
snakeY.add(0,0);
snakeY.add(1,0);
snakeY.add(2,0);
Random rnd = new Random();
do{
foodX = (rnd.nextInt(750/delta)+1) * delta;
foodY = (rnd.nextInt(750/delta)+1) * delta;
//System.out.println(foodX + " : " + foodY);
for(int i = 0; i < snakeX.size(); i++){
if(recheck){
if(foodX != snakeX.get(i).intValue() && foodY != snakeY.get(i).intValue()){
check = true;
recheck = false;
}
else{
check = false;
recheck = true;
}
}
}
}while(!check);
food.add(0, foodX);
food.add(1, foodY);
while (game){
g.fillRect(0,0,759,781);
drawSnake(snakeX, snakeY, food, g);
moveSnake(snakeX, snakeY, direction, game, food, g);
drawFood(food, g);
for(long delay = 0; delay < 75000000; delay++);
}
}
};
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(768,790);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public void mousePressed(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseReleased(MouseEvent e){
}
public void mouseClicked(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public static void drawFood(ArrayList<Integer> food, Graphics g){
g.setColor(Color.red);
g.fillRect(food.get(0).intValue()+9, food.get(1).intValue()+31, delta, delta);
}
public static void drawSnake(ArrayList<Integer> snakeX, ArrayList<Integer> snakeY, ArrayList<Integer> food, Graphics g){
g.setColor(Color.black);
g.fillRect(0,0,760,782);
drawFood(food, g);
g.setColor(Color.white);
for(int i = 0; i < snakeX.size(); i++){
g.fillRect(snakeX.get(i)+9, (int) snakeY.get(i)+31, delta, delta);
}
}
public static void checkContact(ArrayList<Integer> snakeX, ArrayList<Integer> snakeY, Boolean game){
for(int i = 1; i < snakeX.size(); i++){
if(snakeX.get(i) == snakeX.get(0) && snakeY.get(i) == snakeY.get(0))
game = false;
}
}
public static void checkFood(ArrayList<Integer> snakeX, ArrayList<Integer> snakeY, ArrayList<Integer> food, Graphics g){
if(snakeX.get(0).intValue() == food.get(0).intValue() && snakeY.get(0).intValue() == food.get(1).intValue()){
setFood(food, snakeX, snakeY);
snakeX.add(snakeX.get(snakeX.size()-1).intValue()-delta);
snakeY.add(snakeY.get(snakeY.size()-1).intValue()-delta);
}
}
public static void setFood(ArrayList<Integer> food, ArrayList<Integer> snakeX, ArrayList<Integer> snakeY){
boolean check = false;
boolean recheck = true;
Random rnd = new Random();
int foodX;
int foodY;
do{
foodX = (rnd.nextInt(750/delta)+1) * delta;
foodY = (rnd.nextInt(750/delta)+1) * delta;
//System.out.println(foodX + " : " + foodY);
for(int i = 0; i < snakeX.size(); i++){
if(recheck){
if(foodX != snakeX.get(i).intValue() && foodY != snakeY.get(i).intValue()){
check = true;
recheck = false;
}
else{
check = false;
recheck = true;
}
}
}
}while(!check);
food.set(0, foodX);
food.set(1, foodY);
}
public static void moveSnake(ArrayList<Integer> snakeX, ArrayList<Integer> snakeY, char direction, Boolean game, ArrayList<Integer> food, Graphics g){
if(snakeX.get(0).intValue() < 740 && snakeX.get(0).intValue() >= 0 && snakeY.get(0).intValue() < 740 && snakeY.get(0).intValue() >= 0){
if(direction == 'e'){
int temp = snakeX.get(0).intValue();
int temp2 = 0;
snakeX.set(0, temp+delta);
for(int i = 1; i < snakeX.size(); i++){
temp2 = snakeX.get(i);
snakeX.set(i,temp);
temp = temp2;
}
int tempY = snakeY.get(0).intValue();
int tempY2 = 0;
snakeY.set(0, tempY);
for(int i = 1; i < snakeY.size(); i++){
tempY2 = snakeY.get(i);
snakeY.set(i,tempY);
tempY = tempY2;
}
}
else if(direction == 'n'){
int temp = snakeX.get(0).intValue();
int temp2 = 0;
snakeX.set(0, temp);
for(int i = 1; i < snakeX.size(); i++){
temp2 = snakeX.get(i);
snakeX.set(i,temp);
temp = temp2;
}
int tempY = snakeY.get(0).intValue();
int tempY2 = 0;
snakeY.set(0, tempY+delta);
for(int i = 1; i < snakeY.size(); i++){
tempY2 = snakeY.get(i);
snakeY.set(i,tempY);
tempY = tempY2;
}
}
else if(direction == 'w'){
int temp = snakeX.get(0).intValue();
int temp2 = 0;
snakeX.set(0, temp-delta);
for(int i = 1; i < snakeX.size(); i++){
temp2 = snakeX.get(i);
snakeX.set(i,temp);
temp = temp2;
}
int tempY = snakeY.get(0).intValue();
int tempY2 = 0;
snakeY.set(0, tempY);
for(int i = 1; i < snakeY.size(); i++){
tempY2 = snakeY.get(i);
snakeY.set(i,tempY);
tempY = tempY2;
}
}
else if(direction == 's'){
int temp = snakeX.get(0).intValue();
int temp2 = 0;
snakeX.set(0, temp);
for(int i = 1; i < snakeX.size(); i++){
temp2 = snakeX.get(i);
snakeX.set(i,temp);
temp = temp2;
}
int tempY = snakeY.get(0).intValue();
int tempY2 = 0;
snakeY.set(0, tempY-delta);
for(int i = 1; i < snakeY.size(); i++){
tempY2 = snakeY.get(i);
snakeY.set(i,tempY);
tempY = tempY2;
}
}
checkFood(snakeX, snakeY, food, g);
checkContact(snakeX, snakeY, game);
}
drawSnake(snakeX, snakeY, food, g);
}
}
Your game loop (the part of your code that says while(game)) which is supposed to run until the game is over is a little misplaced. Because that loop is infinite on purpose it will never reach the lines after it that set up values for the frame. These statements:
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(768,790);
f.setLocationRelativeTo(null);
f.setVisible(true);
Need to be placed before the loop. Then to properly register the frame's mouse listener you have to add it to your frame like this:
f.addMouseListener(this);
This works because SnakeGame can be considered a MouseListener because it implements that interface.
Bonus Tip:
The correct way to pause execution is to use a swing timer, not have a for loop run a bunch of times.
Read this for more information about using timers.
Hope that Helps!
You must add the mouse listener f.addMouseListener(this); Your code is really hard to read as it's all done inside main. You should first start a new instance of your class and use its constructor
public SnakeGame(){
//code here
}
It's a lot to explain look up how to structure your classes.

Inheritance problems in Java

I have some problems with getting inheritance to work. In the parent class, the array Coefficients is private. I have some access methods but I still can't get it to work.
import java.util.ArrayList;
public class Poly {
private float[] coefficients;
public static void main (String[] args){
float[] fa = {3, 2, 4};
Poly test = new Poly(fa);
}
public Poly() {
coefficients = new float[1];
coefficients[0] = 0;
}
public Poly(int degree) {
coefficients = new float[degree+1];
for (int i = 0; i <= degree; i++)
coefficients[i] = 0;
}
public Poly(float[] a) {
coefficients = new float[a.length];
for (int i = 0; i < a.length; i++)
coefficients[i] = a[i];
}
public int getDegree() {
return coefficients.length-1;
}
public float getCoefficient(int i) {
return coefficients[i];
}
public void setCoefficient(int i, float value) {
coefficients[i] = value;
}
public Poly add(Poly p) {
int n = getDegree();
int m = p.getDegree();
Poly result = new Poly(Poly.max(n, m));
int i;
for (i = 0; i <= Poly.min(n, m); i++)
result.setCoefficient(i, coefficients[i] + p.getCoefficient(i));
if (i <= n) {
//we have to copy the remaining coefficients from this object
for ( ; i <= n; i++)
result.setCoefficient(i, coefficients[i]);
} else {
// we have to copy the remaining coefficients from p
for ( ; i <= m; i++)
result.setCoefficient(i, p.getCoefficient(i));
}
return result;
}
public void displayPoly () {
for (int i=0; i < coefficients.length; i++)
System.out.print(" "+coefficients[i]);
System.out.println();
}
private static int max (int n, int m) {
if (n > m)
return n;
return m;
}
private static int min (int n, int m) {
if (n > m)
return m;
return n;
}
public Poly multiplyCon (double c){
int n = getDegree();
Poly results = new Poly(n);
for (int i =0; i <= n; i++){ // can work when multiplying only 1 coefficient
results.setCoefficient(i, (float)(coefficients[i] * c)); // errors ArrayIndexOutOfBounds for setCoefficient
}
return results;
}
public Poly multiplyPoly (Poly p){
int n = getDegree();
int m = p.getDegree();
Poly result = null;
for (int i = 0; i <= n; i++){
Poly tmpResult = p.multiByConstantWithDegree(coefficients[i], i); //Calls new method
if (result == null){
result = tmpResult;
} else {
result = result.add(tmpResult);
}
}
return result;
}
public void leadingZero() {
int degree = getDegree();
if ( degree == 0 ) return;
if ( coefficients[degree] != 0 ) return;
// find the last highest degree with non-zero cofficient
int highestDegree = degree;
for ( int i = degree; i <= 0; i--) {
if ( coefficients[i] == 0 ) {
highestDegree = i -1;
} else {
// if the value is non-zero
break;
}
}
float[] newCoefficients = new float[highestDegree + 1];
for ( int i=0; i<= highestDegree; i++ ) {
newCoefficients[i] = coefficients[i];
}
coefficients = newCoefficients;
}
public Poly differentiate(){
int n = getDegree();
Poly newResult = new Poly(n);
if (n>0){ //checking if it has a degree
for (int i = 1; i<= n; i++){
newResult.coefficients[i-1]= coefficients[i] * (i); // shift degree by 1 and multiplies
}
return newResult;
} else {
return new Poly(); //empty
}
}
public Poly multiByConstantWithDegree(double c, int degree){ //used specifically for multiply poly
int oldPolyDegree = this.getDegree();
int newPolyDegree = oldPolyDegree + degree;
Poly newResult = new Poly(newPolyDegree);
//set all coeff to zero
for (int i = 0; i<= newPolyDegree; i++){
newResult.coefficients[i] = 0;
}
//shift by n degree
for (int j = 0; j <= oldPolyDegree; j++){
newResult.coefficients[j+degree] = coefficients[j] * (float)c;
}
return newResult;
}
}
Can anyone help me fix my Second class that inherits from the one above? I cant seem to get my multiply and add methods for the second class to work properly.
public class QuadPoly extends Poly
{
private float [] quadcoefficients;
public QuadPoly() {
super(2);
}
public QuadPoly(int degree) {
super(2);
}
public QuadPoly(float [] f) {
super(f);
if (getDegree() > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
public QuadPoly(Poly p){
super(p.coefficients);
for (int i = 0; i < coefficients.length; i++){
if (coefficients[i] < 0){
throw new Exception("Expecting positive coefficients!");
}
}
}
// public QuadPoly(Poly p){
// super(p.coefficients);
//}
public QuadPoly addQuad (QuadPoly p){
return new QuadPoly(super.add(p));
}
public QuadPoly multiplyQuadPoly (QuadPoly f){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
return new QuadPoly(super.multiplyPoly(f));
}
I would make the coefficients protected or use an accessor method.
I wouldn't throw a plain checked Exception. An IllegalArgumentException would be a better choice.
What is quadcoefficients? They don't appear to be set anywhere.
You put coefficients private. I wouldn't change this but I would add a getter method into Poly class:
public class Poly {
//somecode here
public float[] getCoefficients(){
return this.coefficients;
}
}
Then I would use it by the getter method in other code;
public QuadPoly(Poly p){
super(p.getCoefficients);
//some more code here
}
Even if you make coefficient protected, you are trying to reach coefficients field of another Object, which is a parameter. So it is not related to inheritance and the problem.

Categories