FloodFill method not working properly. (Recursion) - recursion

I am trying to make minesweeper game. Everything is working fine except the floodFill method. Once the floodFill method reveals one number, the recursion stops. I do not want the recursion to stop but go on so that it checks other neighbors as well but it does not. I am not sure what I am doing wrong.
package zProject_MineSweeper;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
import javax.swing.JPanel;
public class MyPanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
static final int screenW = 600;
static final int screenH = 600;
static final int unitSize = 40;
static final int rowsNum = screenW/unitSize;
static final int colsNum = screenH/unitSize;
// In this code i have defined bomb as -5
static final int bombNum = -5;
static final int bombGap = 10;
static final double bombProb = 0.05;
static final int fontSize = 20;
int[][] values;
boolean[][] path;
Random random;
MyPanel(){
initializeAll();
initializeValues();
}
private void initializeAll() {
this.addMouseListener(new MyMouseListeners());
this.setPreferredSize(new Dimension(screenW,screenH));
this.setFocusable(true);
this.setBackground(new Color(200,200,200));
random = new Random();
values = new int[rowsNum][colsNum];
path = new boolean[rowsNum][colsNum];
}
private void initializeValues() {
double randomBombProb;
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
path[i][j] = false;
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
randomBombProb = random.nextDouble();
if (randomBombProb< bombProb) {
values[i][j] = bombNum;
}
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (values[i][j] != bombNum) {
setNumbers(i,j);
}
}
}
}
private void setNumbers(int i, int j) {
//Check number of bombs near each node
int sum = 0;
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum) / rowsNum;
int coly = (j + y + colsNum) / colsNum;
if (rowx==1 && coly==1) {
if(values[i+x][j+y] == bombNum) {
sum++;
}
}
}
}
values[i][j] = sum;
}
public void floodFill(int i, int j) {
if(values[i][j]==0) {
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum)/rowsNum;
int coly = (j + y + colsNum)/colsNum;
if (rowx == 1 && coly == 1 && !path[i][j]) {
path[i][j] = true;
floodFill(i+x,j+y);
}
}
}
}
else {
path[i][j] = true;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
private void draw(Graphics g) {
g.setFont(new Font("Times Roman", Font.BOLD, fontSize));
FontMetrics metrics = getFontMetrics(g.getFont());
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (path[i][j]==true) {
drawValue(g,metrics,i,j);
}
else {
g.setColor(new Color(120,120,120));
g.fillRect(i*unitSize, j*unitSize, unitSize, unitSize);
}
}
}
drawGrid(g);
}
private void drawValue(Graphics g, FontMetrics metrics,int i, int j) {
// Centering the numbers in each cell
if (values[i][j] != bombNum) {
g.setColor(new Color(10,10,10));
g.drawString("" + values[i][j],
i*unitSize + unitSize/2 - metrics.stringWidth("" + values[i][j])/2,
j*unitSize + unitSize/2 + fontSize/2);
}
else {
g.setColor(Color.RED);
g.fillOval(i*unitSize+bombGap, j*unitSize+bombGap, unitSize-(2*bombGap), unitSize-(2*bombGap));
}
}
private void drawGrid(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
g2.setColor(new Color(10,10,10));
for(int i=0; i<rowsNum; i++) {
g2.drawLine(unitSize*i, 0, unitSize*i, screenH);
}
for(int i=0; i<colsNum; i++) {
g2.drawLine(0, unitSize*i, screenW, unitSize*i);
}
}
public class MyMouseListeners implements MouseListener {
public void mouseClicked(MouseEvent e) {
if(e.getButton() == 1) {
int i = e.getX()/unitSize;
int j = e.getY()/unitSize;
floodFill(i, j);
repaint();
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
}

Related

Inverted half pyramid using numbers in JavaFX

I made a normal half pyramid in JavaFX with this code
public void buttonpressed() {
int iNum = Integer.parseInt(Num.getText());
String sResult = "";
String sNumber = "";
for (int i = 1; i<=iNum; i++ ) {
sNumber += i;
sResult += sNumber + "\n";
result.setText(sResult);
}
}
Which outputs (if the inputted number was 5)
1
12
123
1234
12345
Now I have to make 2 triangles (one normal and one inverted) which would look like this (inputted number = 5)
1 12345
12 1234
123 123
1234 12
12345 1
The problem is that I don't understand how to make an inverted triangle, I found how to make one in Java
public class Main {
public static void main(String[] args) {
int rows = 5;
for (int i = rows; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
System.out.print(j + " ");
}
System.out.println();
}
}
}
But I can't adapt it to JavaFX so please help me with that.
I tried copying the for loops and adapting it to JavaFX but it didn't work.
public void buttonpressed() {
int iNum = Integer.parseInt(Num.getText());
String sResult = "";
String sNumber = "";
for (int i = inum3; i >= 1; i--) {
for (int j = 1; j <= i; ++j) {
sNumber+=j;
sResult += sNumber +"\n";
}
result.setText(sResult);
}
}
The result I want is
12345
1234
123
12
1
Instead, with the provided code, I get
1
12
123
1234
12345
123451
1234512
12345123
123451234
123451234123
1234512341231
12345123412312
123451234123121
The whole code is
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class invertedtriangle extends Application{
TextField num = new TextField();
Label result = new Label();
public void start(Stage stage) {
GridPane p = new GridPane();
Scene scene = new Scene(p, 1000, 900);
Label input = new Label("Input a number");
Button press = new Button("Press");
p.add(input,0,1);
p.add(num, 0,2);
p.add(press, 0, 3);
p.add(result, 0, 4);
press.setOnAction(e -> buttonpressed());
p.setHgap(10.0);
p.setVgap(7.0);
stage.setTitle("inv triangle");
stage.setScene(scene);
stage.show();
}
public void buttonpressed() {
int iNum = Integer.parseInt(num.getText());
String sResult = "";
String sNumber = "";
for (int i = iNum; i >= 1; i--) {
for (int j = 1; j <= i; ++j) {
sNumber+=j;
sResult += sNumber +"\n";
}
result.setText(sResult);
}
}
public static void main(String[] args){
launch (args);
}
}
Just use the solution you already have, appending text to a string instead of sending it to the console:
public void buttonPressed() {
int iNum = Integer.parseInt(num.getText());
String sResult = "";
for (int i = iNum; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
// System.out.print(j + " ");
sResult = sResult + (j+" ");
}
// System.out.println();
sResult = sResult + "\n";
}
result.setText(sResult);
}
Note that it is far more efficient to use a StringBuilder instead of building up strings by concatenation (basically, in Java, you should never repeatedly perform string concatenation on the same string in a loop):
public void buttonPressed() {
int iNum = Integer.parseInt(num.getText());
StringBuilder text = new StringBuilder();
for (int i = iNum; i >= 1; --i) {
for (int j = 1; j <= i; ++j) {
text.append(j).append(" ");
}
text.append("\n");
}
result.setText(text.toString());
}

Leetcode 2360 Longest Cycle in a Graph

I use nearly the same method as in the discussion. But mine reaches the time limitation but his passes all cases. I want to know how to improve my code and why there is difference?
Here is my entire code:
boolean[] visited;
public int dfs(int step, int[] edges, int node, Map<Integer, Integer> path) {
path.put(node, step);
visited[node] = true;
if (edges[node] == -1) {
return -1;
}
if (path.containsKey(edges[node])) {
return step - path.get(edges[node]) + 1;
}
return dfs(step + 1, edges, edges[node], path);
}
public int longestCycle(int[] edges) {
int res = -1;
visited = new boolean[edges.length];
for (int i = 0; i < edges.length; i++) {
if (visited[i]) {
continue;
}
int maxCircleLength = dfs(0, edges, i, new HashMap<Integer, Integer>());
res = Math.max(maxCircleLength, res);
}
return res;
}
This is his solution:
public int longestCycle(int[] edges) {
int longest = -1;
boolean visited[] = new boolean[edges.length]; // global visisted
HashMap<Integer, Integer> map;
for(int i=0; i<edges.length; i++){
if(visited[i]) continue;
int distance = 0, curr_node = i;
map = new HashMap<>(); // local visited
while(curr_node != -1){
if(map.containsKey(curr_node)){
longest = Math.max(longest, distance - map.get(curr_node));
break;
}
if(visited[curr_node]) break;
visited[curr_node] = true;
map.put(curr_node, distance);
curr_node = edges[curr_node];
distance++;
}
}
return longest;
}

Maximum Xor between Two Arrays | Trie

Given two integer vectors A and B, we have to pick one element from each vector such that their xor is maximum and we need to return this maximum xor value from the function int Solution::solve(vector &A, vector &B).
I found out that the code below is not passing all the test cases when I'm declaring and initializing the head pointer globally right beneath the class Trienode. Why is that?
Code
class Trienode
{
public:
Trienode* left;
Trienode* right;
Trienode()
{
left=0;
right=0;
}
};
// Trienode* head = new Trienode;
int Max_Xor_Pair(Trienode* head, vector<int> B)
{
int n=B.size();
int max_xor=INT_MIN;
for(int i=0; i<n; i++)
{
int pair1 = B[i];
int pair2 = 0;
Trienode* curr=head;
for(int j=31; j>=0; j--)
{
int bit = (pair1>>j)&1;
if(bit)
{
if(curr->left)
curr=curr->left;
else
{
curr=curr->right;
pair2 += pow(2,j);
}
}
else
{
if(curr->right)
{
curr=curr->right;
pair2 += pow(2,j);
}
else
curr=curr->left;
}
}
int curr_xor = pair1 ^ pair2;
max_xor = max(max_xor, curr_xor);
}
return max_xor;
}
void Insert(Trienode* head, int num)
{
Trienode* curr=head;
for(int i=31; i>=0; i--)
{
int x = num;
int bit= (x>>i)&1;
if(bit)
{
if(!curr->right)
{
Trienode* temp = new Trienode;
curr->right=temp;
}
curr=curr->right;
}
else
{
if(!curr->left)
{
Trienode* temp = new Trienode;
curr->left=temp;
}
curr=curr->left;
}
}
}
int Solution::solve(vector<int> &A, vector<int> &B) {
Trienode* head = new Trienode;
for(int x:A)
Insert(head,x);
return Max_Xor_Pair(head,B);
}
Sample Input
A : [ 15891, 6730, 24371, 15351, 15007, 31102, 24394, 3549, 19630, 12624, 24085, 19955, 18757, 11841, 4967, 7377, 13932, 26309, 16945, 32440, 24627, 11324, 5538, 21539, 16119, 2083, 22930, 16542, 4834, 31116, 4640, 29659, 22705, 9931, 13978, 2307, 31674, 22387, 5022, 28746, 26925, 19073, 6271, 5830, 26778, 15574, 5098, 16513, 23987, 13291, 9162 ]
B : [ 18637, 22356, 24768, 23656, 15575, 4032, 12053, 27351, 1151, 16942 ]
When head is a global variable, and you don't have this line in Solution::solve:
Trienode* head = new Trienode;
...then head will retain its value after the first test case has finished, and so the second test case will not start with an empty tree. Each test case will add more nodes to the one tree. Of course this means that, except for the first test case, the tree rooted by head is not the intended tree.
To make the version with the global variable work, reset it in Solution::solve:
head->left = head->right = nullptr;
BTW, you should also initialise these members with nullptr (instead of 0) in your TrieNode constructor. This better reflects the intent.
You can also go with this approach:
Code:
struct Node {
Node* left;
Node* right;
};
class MaxXorHelper{
private : Node* root;
public :
MaxXorHelper() {
root = new Node();
}
void addElements(vector<int> &arr) {
for(int i=0; i<arr.size(); i++) {
Node* node = root;
int val = arr[i];
for(int j=31; j>=0; j--) {
int bit = (val >> j) & 1;
if(bit == 0) {
if(!node->left) {
node->left = new Node();
}
node = node->left;
}
else {
if(!node->right) {
node->right = new Node();
}
node = node->right;
}
}
}
}
int findMaxXor(vector<int> &arr) {
int maxXor = INT_MIN;
for(int i=0; i<arr.size(); i++) {
Node* node = root;
int val2 = 0;
int val1 = arr[i];
for(int j=31; j>=0; j--) {
int bit = (val1 >> j) & 1;
if(bit == 0) {
if(node->right) {
val2 |= (1 << j);
node = node->right;
} else{
node = node->left;
}
}
else {
if(node->left) {
node = node->left;
} else{
val2 |= (1 << j);
node = node->right;
}
}
}
int curXor = val1 ^ val2;
maxXor = max(maxXor, curXor);
}
return maxXor;
}
};
int Solution::solve(vector<int> &A, vector<int> &B) {
MaxXorHelper helper;
helper.addElements(A);
return helper.findMaxXor(B);
}

Update GridPane with Slider in JavaFx

I'm new at this, I´m creating a field that solves N x N Matrixes, and I want the spinner to add more TextFields every time I change its value, so the user can select the size of the matrix and then solve it...However I don't know how to do this.
I've tried to attach a listener JavaFX spinner but it didn't work, and it has created some errors in the code.
The code in question...
public static void main(String[] args) {
// TODO Auto-generated method stub
launch(args);
}
public void start(Stage primaryStage) throws Exception{
Double[][] A = new Double[6][6];
Label tamanoML = new Label("Tamaño Matriz:");
Spinner tamanoMS =new Spinner(1,5,0,1);
int tamano=(int) tamanoMS.getValue();
int r;
Label[] campoL = new Label[6];
TextField campo [][] = new TextField[6][6];
Button resolverB = new Button("Resolver matrix");
resolverB.setOnAction((ActionEvent t) -> {
int n=(int) tamanoMS.getValue();
int cont=0;
for(int i=0; i<n; i++) {
for(int j=0; j<n+1; j++) {
A[i][j]=Double.parseDouble(campo[i][j].getText());
}
}
for (int a = 0; a < n; a++) {
Double temp = 0.0;
temp = A[cont][cont];
for (int y = 0; y < (n + 1); y++) {
A[cont][y] = A[cont][y] / temp;
}
for (int x = 0; x < n; x++) {
if (x!=cont) {
Double c = A[x][cont];
for (int z = 0; z < (n + 1); z++) {
A[x][z] = ((-1 * c) * A[cont][z]) + A[x][z];
}
}
}
cont++;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n+1; j++) {
campo[i][j].setText(""+A[i][j]);
}
}
});
Button limpiarb = new Button("Limpiar");
limpiarb.setOnAction((ActionEvent t) -> {
for(int i=0; i<tamano+1; i++) {
for(int j=0; j<tamano+1; j++) {
campo[i][j].setText("0");
}
}
});
GridPane mainPane = new GridPane();
mainPane.setMinSize(650,350);
mainPane.setPadding(new Insets(10,10,10,10));
mainPane.setVgap(5);
mainPane.setHgap(5);
mainPane.setAlignment(Pos.CENTER);
mainPane.add(tamanoML, 0, 0);
mainPane.add(tamanoMS, 1, 0);
mainPane.add(resolverB,0,1);
mainPane.add(limpiarb,1,1);
for(int i=0; i<tamano+1; i++) {
r=i+1;
if(r<tamano+1) {
r=i+1;
campoL[i]=new Label("X"+r);
mainPane.add(campoL[i],i,2);
}else {
campoL[i]=new Label("R");
mainPane.add(campoL[i],i,2);
}
}
for(int i=0; i<tamano; i++) {
for(int j=0; j<tamano+1; j++) {
campo[i][j] = new TextField("0");
mainPane.add(campo[i][j],j,i+3);
}
}
tamanoMS.valueProperty().addListener((newValue) -> {
int s;
for(int i=0; i<tamano+1; i++) {
s=i+1;
if(s<tamano+1) {
s=i+1;
campoL[i]=new Label("X"+s);
mainPane.add(campoL[i],i,2);
}else {
campoL[i]=new Label("R");
mainPane.add(campoL[i],i,2);
}
}
for(int i=0; i<tamano; i++) {
for(int j=0; j<tamano+1; j++) {
campo[i][j] = new TextField("0");
mainPane.add(campo[i][j],j,i+3);
}
}
s=0;
});
Scene scene = new Scene(mainPane);
primaryStage.setScene(scene);
primaryStage.setTitle("Ventas del Dia");
primaryStage.show();
}
Ok so the first thing you want to do is rewrite your listener like this
tamanoMS.valueProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("heard");
int s;
for(int i=0; i<newValue+1; i++) {
s=i+1;
if(s<newValue+1) {
s=i+1;
campoL[i]=new Label("X"+s);
mainPane.add(campoL[i],i,2);
}else {
campoL[i]=new Label("R");
mainPane.add(campoL[i],i,2);
}
}
for(int i=0; i<newValue; i++) {
for(int j=0; j<newValue+1; j++) {
campo[i][j] = new TextField("0");
mainPane.add(campo[i][j],j,i+3);
}
}
s=0;
});
I'm gonna be honest I don't quite understand why you need oldValue and obs but you do. However, the reason your matrix wasn't expanding was because you weren't updating tamano to the most recent number.
You also need to change your spinner to this so that is know the value that is coming out is an integer.
Spinner<Integer> tamanoMS =new Spinner<Integer>(1,5,0,1);

Beginner coder checking if input is part of a cycle?

public Graph (int nb){
this.nbNodes = nb;
this.adjacency = new boolean [nb][nb];
for (int i = 0; i < nb; i++){
for (int j = 0; j < nb; j++){
this.adjacency[i][j] = false;
}
}
}
public void addEdge (int i, int j){
if(!(i<0 || i>=this.nbNodes|| j<0 || j>=this.nbNodes))
{
this.adjacency[i][j] = true;
this.adjacency[j][i] = true;
}
}
public void removeEdge (int i, int j){
if(!(i<0 || i>=this.nbNodes|| j<0 || j>=this.nbNodes))
{
this.adjacency[i][j] = false;
this.adjacency[j][i] = false;
}
}
public int nbEdges(){
int c =0;
for(int i=0; i<this.nbNodes; i++)
{
for(int j= 0; j<this.nbNodes; j++)
{
if(this.adjacency[i][j]==true)
{
c++;
}
}
}
return c/2;
}
public boolean cycle(int start){
return false;
}
A Graph has a number of nodes nbNodes and is characterized by its adjacency matrix adjacency. adjacency[i][j] states whether or not there is an edge from the i-th node to the j-th node.
the graphs are undirected.
I am a beginner coder and am having trouble writing cycle(int start)
It takes as input an integer, g.cycle(i) returns true if the i-th node is part of a cycle (and false otherwise).
does anyone have any idea on how I should approach this?

Resources