Related
I started making this extremely simple 2048 game, without graphics and stuff (only array), and made the board :
import java.util.*;
public class GameBoard
{
String [][] GameBoard;
void justprint(String s, int n) //(ignore, just a function that makes next steps easier)
{
for(int i = 0; i<n;i++)
{
System.out.print(s);
}
System.out.println();
}
public GameBoard(int n)
{
GameBoard = new String [n][n];
Random num = new Random();
for(int i = 0; i<n;i++)
{
for(int j = 0; j<n;j++)
{
GameBoard[i][j] = " ";
}
}
System.out.print("-");
justprint("-----", n);
int r1 = num.nextInt(n);
int r2 = num.nextInt(n);
int r3 = num.nextInt(n);
int r4 = num.nextInt(n);
GameBoard[r1][r2] = " 2";
GameBoard[r3][r4] = " 2";
for(int i = 0; i<n;i++)
{
System.out.print("|");
for(int j = 0; j<n;j++)
{
System.out.print(GameBoard[i][j] + "|");
}
System.out.println();
System.out.print("-");
justprint("-----", n);
}
this.GameBoard = GameBoard;
}
}
Now, I want to make the functions to check if the neighbouring places are blank, or to add if they are the same number, etc.; but I have to make them in another class. I can probably make the functions to check all of that, but can someone tell me just how I could implement all of it in different classes?
I already tried doing it, but I want the user to input the size of the game board, and I can't do that as if I make a new class I have to write like
GameBoard gb = new GameBoard[4][4];
I don't want to define the size, but if I don't then I can't define my movement functions...
Any ideas?
So, I have been making this Tic Tac Toe program for a while now.
It's a basic Tic Tac Toe game but the game board is scalable. The program is almost finished but one little feature is missing.
I have to make the game end if player gets five or more marks in a row when the game board is larger than 4x4.
F.E. If the game board is 9x9 the game has to end when the player or the computer gets five marks in a row.
(Mark = "O" or "X").
The game now ends when someone gets marks in a row equals to the size of the board (if 9x9 you need 9 marks in a row to win).
I have to implement a feature in the playerHasWon and I've been having a lot of trouble finding out how. I think it's a simple to implement thing but I have not found out how to do it.
Hope my explanation is easy enough to understand. Here's the code:
package tictac;
import java.util.Scanner;
import java.util.Random;
public class Tictac {
public static final int DRAW = 0; // game ends as a draw
public static final int COMPUTER = 1; // computer wins
public static final int PLAYER = 2; // player wins
public static final char PLAYER_MARK = 'X'; // The "X"
public static final char COMPUTER_MARK = 'O'; // The "O"
public static int size; // size of the board
public static String[][] board; // the board itself
public static int score = 0; // game win score
public static Scanner scan = new Scanner(System.in); // scanner
/**
* Builds the board with the integer size and user input.
*
* Displays game win message and switches play turns.
*
* #param args the command line parameters. Not used.
*/
public static void main(String[] args) {
while (true) {
System.out.println("Select board size");
System.out.print("[int]: ");
try {
size = Integer.parseInt(scan.nextLine());
} catch (Exception e) {
System.out.println("You can't do that.");
continue; // after message, give player new try
}
break;
}
int[] move = {};
board = new String[size][size];
setupBoard();
int i = 1;
loop: // creates the loop
while (true) {
if (i % 2 == 1) {
displayBoard();
move = getMove();
} else {
computerTurn();
}
switch (isGameFinished(move)) {
case PLAYER:
System.err.println("YOU WIN!");
displayBoard();
break loop;
case COMPUTER:
System.err.println("COMPUTER WINS!");
displayBoard();
break loop;
case DRAW:
System.err.println("IT'S A DRAW");
displayBoard();
break loop;
}
i++;
}
}
/**
* Checks for game finish.
*
* #param args command line parameters. Not used.
*
* #return DRAW the game ends as draw.
* #return COMPUTER the game ends as computer win.
* #return PLAYERE the game ends as player win.
*/
private static int isGameFinished(int[] move) {
if (isDraw()) {
return DRAW;
} else if (playerHasWon(board, move,
Character.toString(COMPUTER_MARK))) {
return COMPUTER;
} else if (playerHasWon(board, move,
Character.toString(PLAYER_MARK))) {
return PLAYER;
}
return -1; // can't be 0 || 1 || 2
}
/**
* Checks for win for every direction on the board.
*
* #param board the game board.
* #param move move on the board.
* #param playerMark mark on the board "X" or "O".
* #return the game is won.
*/
public static boolean playerHasWon(String[][] board, int[] move,
String playerMark) { //playermark x || o
// horizontal check
for (int i = 0; i < size; i++) {
if (board[i][0].equals(playerMark)) {
int j;
for (j = 1; j < size; j++) {
if (!board[i][j].equals(playerMark)) {
break;
}
}
if (j == size) {
return true;
}
}
}
// vertical check
for (int i = 0; i < size; i++) {
if (board[0][i].equals(playerMark)) {
int j;
for (j = 1; j < size; j++) {
if (!board[j][i].equals(playerMark)) {
break;
}
}
if (j == size) {
return true;
}
}
}
// diagonals check
int i;
for (i = 0; i < size; i++) {
if (!board[i][i].equals(playerMark)) {
break;
}
}
if (i == size) {
return true;
}
for (i = 0; i < size; i++) {
if (!board[i][(size - 1) - i].equals(playerMark)) {
break;
}
}
return i == size;
}
/**
* Checks for draws.
*
* #return if this game is a draw.
*/
public static boolean isDraw() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (board[i][j] == " ") {
return false;
}
}
}
return true;
}
/**
* Displays the board.
*
*
*/
public static void displayBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
System.out.printf("[%s]", board[i][j]);
}
System.out.println();
}
}
/**
* Displays the board.
*
*
*/
public static void setupBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
board[i][j] = " ";
}
}
}
/**
* Takes in user input and sends it to isValidPlay.
*
* #return null.
*/
public static int[] getMove() {
Scanner sc = new Scanner(System.in);
System.out.println("Your turn:");
while (true) {
try {
System.out.printf("ROW: [0-%d]: ", size - 1);
int x = Integer.parseInt(sc.nextLine());
System.out.printf("COL: [0-%d]: ", size - 1);
int y = Integer.parseInt(sc.nextLine());
if (isValidPlay(x, y)) {
board[x][y] = "" + PLAYER_MARK;
return new int[]{x, y};
} else { // if input is unallowed
System.out.println("You can't do that");
continue; // after message, give player new try
}
} catch (Exception e) {
System.out.println("You can't do that.");
}
return null;
}
}
/*
* Randomizes computer's turn, where it inputs the mark 'O'.
*
*
*/
public static void computerTurn() {
Random rgen = new Random(); // Random number generator
while (true) {
int x = (int) (Math.random() * size);
int y = (int) (Math.random() * size);
if (isValidPlay(x, y)) {
board[x][y] = "" + COMPUTER_MARK;
break;
}
}
}
/**
* Checks if a move is possible.
*
* #param inX x-move is out of bounds.
* #param inY y-move is out of bounds.
* #return false
*/
public static boolean isValidPlay(int inX, int inY) {
// Play is out of bounds and thus not valid.
if ((inX >= size) || (inY >= size)) {
return false;
}
// Checks if a play have already been made at the location,
// and the location is thus invalid.
return (board[inX][inY] == " ");
}
}
// End of file
Took a quick look, detected the problem and came up with a quick fix:
public static boolean checkDiagonal(String markToLook) {
// how many marks are we looking for in row?
int sizeToWin = Math.min(size, 5);
// running down and right
// don't need to iterate rows that can't be the starting point
// of a winning diagonal formation, thus can exlude some with
// row < (size - (sizeToWin - 1))
for (int row = 0; row < (size - (sizeToWin - 1)); row++) {
for (int col = 0; col < size; col++) {
int countOfMarks = 0;
// down and right
for (int i = row; i < size; i++) {
if (board[i][i] == null ? markToLook == null :
board[i][i].equals(markToLook)) {
countOfMarks++;
if (countOfMarks >= sizeToWin) {
return true;
}
}
}
countOfMarks = 0;
// down and left
for (int i = row; i < size; i++) {
if (board[i][size - 1 - i] == null ? markToLook == null :
board[i][size - 1 - i].equals(markToLook)) {
countOfMarks++;
if (countOfMarks >= sizeToWin) {
return true;
}
}
}
}
}
return false;
}
And call it from your PlayerHasWon method instead of performign the checks there. Basically we iterate each possible starting square on the board for a diagonal winning formation, and run check down+left and down+right for each of the squares.
I am in awful hurry and did not test it much, but will return in couple of hours to improve this solution. Seems to work.
Edit: My previous solution I found lacking in further tests, I've updated the above code to function as desired.
First, I think playerMark should be a char and not a String. That said, let's go for the answer. The "horizontal" case would be:
// This is the number of marks in a row required to win
// Adjust formula if necessary
final int required = size > 4 ? 5 : 3;
for (int i = 0; i < size; i++) {
int currentScore = 0;
for (j = 0; j < size; j++) {
if (board[i][j].equals(playerMark)) {
currentScore++;
if (currentScore >= required)
return true;
}
else {
currentScore = 0;
}
}
}
}
The vertical case would be analogous. The diagonal one is a bit trickier as now it would require board[i][i+k] for the main diagonal and board[i][k-i] for the secondary; and it may not be obvious which values k and i must traverse. Here's my attempt (variable required as in horizontal case):
Note: everything from here down has been completely rewritten on 2015-12-16. The previous versions didn't work and the algorithm was not explained.
After two failed attempts I decided to do my homework and actually sort things out instead of doing everything in my head thinking I can keep track of all variables. The result is this picture:
Main diagonals are painted in blue, secondary diagonals in green.
Each diagonal is identified by a value of k, with k=0 being always being the longest diagonal of each set. Values of k grow as diagonals move down, so diagonals above the longest one have negative k while diagonals below the longest one have positive k.
Things that hold for both diagonals:
Diagonal contains size-abs(k) elements. Diagonals in which size-abs(k) is less than required need not be searched. This means that, for board size size and required length required, we'll search values of k from required-size to size-required. Notice that these have the same absolute value, with the first being <=0 and the second >=0. These values are both zero only when required==size, i.e. when we need the full diagonal to claim a win, i.e. when we only need to search k=0.
For k<=0, possible values of i (row) go from 0 to size+k. Values greater than or equal to size+k cross the right edge of the board and are thus outside the board.
For k>=0, possible values of i (row) go from k to size. Values below k cross the left edge of the board and are thus outside the board.
Only for main (blue) diagonals:
Value of j (column) is k+i.
Only for secondary (green) diagonals:
Value of j (column) is size-1+k-i. In case this is not obvious, just pick the top right corner (k=0,i=0) and notice j=size-1. Then notice that adding 1 to k (keeping i constant) always moves j by 1 right (it would go out of the board if done from k=0,i=0, just think about the intersection of horizontal line i=0 with diagonal k=1), and adding 1 to i (keeping k constant) always moves j by 1 to the left.
The ressulting code would be:
// Main diagonal
for (int k = required - size; k < size - required; k++)
{
int currentScore = 0;
startI = Math.max (0, k);
endI = Math.min (size, size+k);
for (int i = startI, i < endI; i++)
{
if (board[i][k+i].equals (playerMark))
{
currentScore++;
if (currentScore >= required)
return true;
}
else
currentScore = 0;
}
}
// Secondary diagonal
for (int k = required - size; k < size - required; k++)
{
int currentScore = 0;
startI = Math.max (0, k);
endI = Math.min (size, size+k);
for (int i = startI, i < endI; i++)
{
if (board[i][size-1+k-i].equals (playerMark))
{
currentScore++;
if (currentScore >= required)
return true;
}
else
currentScore = 0;
}
}
At this point, the code is nearly identical in both cases, changing only the j index in board[i][j]. In fact, both loops could be merged, taking care only of keeping two currentScore variables, one for the main (blue) diagonal and the other for the secondary (green) diagonal.
I want to construct a square matrix (2D) of size n (which will be input by the user)
Now I want to construct a diagonal pattern.
For example (3X3 Matrix):
2 3
1
4 5
The value variable will be initialized to 1 and stored at the center of the square matrix. Then value will be incremented and stored at upper left corner as shown above, and so on.
It is a simple program to be displayed on console.
User input can taken from command line.
I am trying to generalize a condition in a for loop that will work for square matrix of size 5,7,9... (odd numbers).
For a matrix of size 5 it will be
6 7
2 3
1
4 5
8 9
(the empty spaces can be zero)
My code:
import java.util.*;
public class MatrixAdv
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
System.out.println("Please enter size of element...");
int n=sc.nextInt(); //stores size of Matrix
int value=0; //To be incremented everytime to get the Pattern
int [][] matrix = new int[n][n];
int k=0;
for(int i=0;i<some Condition;i++)
{
for(int j=1;j<some Condition;j++)
{
k=n-2-j;
matrix[k][k]=++value;
}
}
}
//Display the value in matrix form
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
Print(matrix[i][j]+"\t");
}
Print("\n");
}
}
its very easy to print 99% matrix patterns if you know the magic of matrix...and you can do it without using any memory.
here is the code......
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
if(n == 1)
cout<<1;
else
{
int sv=2*n-4,a,b;
a=sv;b=sv+1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i == j && i+j == n+1)
{
cout<<" 1 ";
sv=4;
}
else
{
if(i == j)
cout<<" "<<a<<" ";
else if((i+j) == n+1)
cout<<" "<<b<<" ";
else
cout<<" ";
}
}
if(i < n/2+1)
{
sv=sv-4;
a=sv;b=sv+1;
}
else if(i > n/2+1)
{
sv=sv+4;
b=sv;a=sv+1;
}
else
{
sv=4;
b=sv;a=sv+1;
}
cout<<"\n";
}
}
}
There are basically 2 options for solving this:
Go through the whole matrix, row by row and column by column, and check whether a certain value has to be set at the current position
Go through all the positions where a certain value has to be set.
Both of them have nothing to do with the condition of a for-loop. However, here an example for the second approach:
public class MatrixAdv
{
public static void main(String args[])
{
//Scanner sc = new Scanner(System.in);
//System.out.println("Please enter size of element...");
//int n = sc.nextInt(); // stores size of Matrix
int n = 9;
int value = 0;// To be incremented everytime to get the Pattern
int[][] matrix = new int[n][n];
matrix[n/2][n/2] = 1;
int maxValue = ((n / 2) * 4) + 1;
int r = n / 2 - 1;
int c = n / 2 - 1;
int d = 2;
for (value=2; value<=maxValue; value++)
{
matrix[r][c] = value;
int step = ((value-2)%4);
switch (step)
{
case 0: c+=d; break;
case 1: r+=d; c-=d; break;
case 2: c+=d; break;
case 3: d+=2; r-=d-1; c-=d-1; break;
}
}
// Display the value in matrix form
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] == 0)
{
System.out.printf("%3s", "_");
}
else
{
System.out.printf("%3d", matrix[i][j]);
}
}
System.out.print("\n");
}
}
}
(Disclaimer: There are maybe 20 different versions of this question on SO, but a reading through most of them still hasn't solved my issue)
Hello all, (relatively) beginner programmer here. So I've been trying to build a Sudoku backtracker that will fill in an incomplete puzzle. It seems to works perfectly well even when 1-3 rows are completely empty (i.e. filled in with 0's), but when more boxes start emptying (specifically around the 7-8 column in the fourth row, where I stopped writing in numbers) I get a Stack Overflow Error. Here's the code:
import java.util.ArrayList;
import java.util.HashSet;
public class Sudoku
{
public static int[][] puzzle = new int[9][9];
public static int filledIn = 0;
public static ArrayList<Integer> blankBoxes = new ArrayList<Integer>();
public static int currentIndex = 0;
public static int runs = 0;
/**
* Main method.
*/
public static void main(String args[])
{
//Manual input of the numbers
int[] completedNumbers = {0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,3,4,
8,9,1,2,3,4,5,6,7,
3,4,5,6,7,8,9,1,2,
6,7,8,9,1,2,3,4,5,
9,1,2,3,4,5,6,7,8};
//Adds the numbers manually to the puzzle array
ArrayList<Integer> completeArray = new ArrayList<>();
for(Integer number : completedNumbers) {
completeArray.add(number);
}
int counter = 0;
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
puzzle[i][j] = completeArray.get(counter);
counter++;
}
}
//Adds all the blank boxes to an ArrayList.
//The index is stored as 10*i + j, which can be retrieved
// via modulo and integer division.
boolean containsEmpty = false;
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
if(puzzle[i][j] == 0) {
blankBoxes.add(10*i + j);
containsEmpty = true;
}
}
}
filler(blankBoxes.get(currentIndex));
}
/**
* A general method for testing whether an array contains a
* duplicate, via a (relatively inefficient) sort.
* #param testArray The int[] that is being tested for duplicates
* #return True if there are NO duplicate, false if there
* are ANY duplicates.
*/
public static boolean checkDupl(int[] testArray) {
for(int i = 0; i < 8; i++) {
int num = testArray[i];
for(int j = i + 1; j < 9; j++) {
if(num == testArray[j] && num != 0) {
return false;
}
}
}
return true;
}
/**
* If the puzzle is not full, the filler will be run. The filler is my attempt at a backtracker.
* It stores every (i,j) for which puzzle[i][j] == 0. It then adds 1 to it's value. If the value
* is already somewhere else, it adds another 1. If it is 9, and that's already there, it loops to
* 0, and the index beforehand is rechecked.
*/
public static void filler(int indexOfBlank) {
//If the current index is equal to the size of blankBoxes, meaning that we
//went through every index of blankBoxes, meaning the puzzle is full and correct.
runs++;
if(currentIndex == blankBoxes.size()) {
System.out.println("The puzzle is full!" + "\n");
for(int i = 0; i < 9; i++) {
System.out.println();
for(int j = 0; j < 9; j++) {
System.out.print(puzzle[i][j]);
}
}
System.out.println("\n" + "The filler method was run " + runs + " times");
return;
}
//Assuming the puzzle isn't full, find the row/column of the blankBoxes index.
int row = blankBoxes.get(currentIndex) / 10;
int column = blankBoxes.get(currentIndex) % 10;
//Adds one to the value of that box.
puzzle[row][column] = (puzzle[row][column] + 1);
//Just used as a breakpoint for a debugger.
if(row == 4 && column == 4){
int x = 0;
}
//If the value is 10, meaning it went through all the possible values:
if(puzzle[row][column] == 10) {
//Do filler() on the previous box
puzzle[row][column] = 0;
currentIndex--;
filler(currentIndex);
}
//If the number is 1-9, but there are duplicates:
else if(!(checkSingleRow(row) && checkSingleColumn(column) && checkSingleBox(row, column))) {
//Do filler() on the same box.
filler(currentIndex);
}
//If the number is 1-9, and there is no duplicate:
else {
currentIndex++;
filler(currentIndex);
}
}
/**
* Used to check if a single row has any duplicates or not. This is called by the
* filler method.
* #param row
* #return
*/
public static boolean checkSingleRow(int row) {
return checkDupl(puzzle[row]);
}
/**
* Used to check if a single column has any duplicates or not.
* filler method, as well as the checkColumns of the checker.
* #param column
* #return
*/
public static boolean checkSingleColumn(int column) {
int[] singleColumn = new int[9];
for(int i = 0; i < 9; i++) {
singleColumn[i] = puzzle[i][column];
}
return checkDupl(singleColumn);
}
public static boolean checkSingleBox(int row, int column) {
//Makes row and column be the first row and the first column of the box in which
//this specific cell appears. So, for example, the box at puzzle[3][7] will iterate
//through a box from rows 3-6 and columns 6-9 (exclusive).
row = (row / 3) * 3;
column = (column / 3) * 3;
//Iterates through the box
int[] newBox = new int[9];
int counter = 0;
for(int i = row; i < row + 3; i++) {
for(int j = row; j < row + 3; j++) {
newBox[counter] = puzzle[i][j];
counter++;
}
}
return checkDupl(newBox);
}
}
Why am I calling it a weird error? A few reasons:
The box that the error occurs on changes randomly (give or take a box).
The actual line of code that the error occurs on changes randomly (it seems to usually happen in the filler method, but that's probably just because that's the biggest one.
Different compilers have different errors in different boxes (probably related to 1)
What I assume is that I just wrote inefficient code, so though it's not an actual infinite recursion, it's bad enough to call a Stack Overflow Error. But if anyone that sees a glaring issue, I'd love to hear it. Thanks!
Your code is not backtracking. Backtracking implies return back on failure:
if(puzzle[row][column] == 10) {
puzzle[row][column] = 0;
currentIndex--;
filler(currentIndex);// but every fail you go deeper
}
There are must be something like:
public boolean backtrack(int currentIndex) {
if (NoBlankBoxes())
return true;
for (int i = 1; i <= 9; ++i) {
if (NoDuplicates()) {
puzzle[row][column] = i;
++currentIndex;
if (backtrack(currentIndex) == true) {
return true;
}
puzzle[row][column] = 0;
}
}
return false;
}
So this problem is a little bit complicated to understand what I'm trying to do.
Basically, I am trying to randomly generate 3 vectors, all of size 11.
The first vector must have a 1 at position 0 with the next 5 positions being 0 (e.g. 100000) while the next five digits can be either 0 1 or 2, however there can only be one zero used in the last 5 digits, hence 10000012101 would be valid but 10000012001 wouldn't.
The same is applicable to the second and third vector however the first 1 will move a place for the second and the third (010000xxxxx for the second, and 001000xxxxx for the third).
There are more conditions that have to be satisfied. Each vector must differ from each other in at least 5 positions (10000011210 would differ from 01000022100 in 5 positions which would work).
However, there is also a final constraint which states that if you add the vectors modulo 3, then the result of adding these two must have at least 5 NON zero values in the vector.
I have went about this by using arraylists. As I know the first 6 elements of each arraylist for each vector I manually put these in, and for the next 5 elements I randomly assign these, if there is more than one 0 in the last five digits, i call the method again recursively.
The problem I have with this program is that when I try to run my code it comes up with a
Exception in thread "main" java.lang.StackOverflowError
at java.util.ArrayList.get(Unknown Source)
I think it's because it's continuously trying to loop and therefore crashing but I'm not sure. See below for the code.
import java.util.ArrayList;
/**
* The purpose of this class is to be able to capture different ways
* of generating six vectors that will produce a collection of 729
* vectors that guarantee 9 out of 11 correct.
*/
public class GenerateVectors {
static ArrayList<Integer> firstVector = new ArrayList<Integer>();
static ArrayList<Integer> secondVector = new ArrayList<Integer>();
static ArrayList<Integer> thirdVector = new ArrayList<Integer>();
static ArrayList<Integer> sumOfXandY = new ArrayList<Integer>();
//Creates the first vectors to ensure it starts with "1,0,0,0,0,0"
//and has at most one more zero in the last 5 digits
public void createFirstVector(){
int[] fir stVector1 = {1,0,0,0,0,0};
for (int i=0; i<firstVector1.length; i++) {
firstVector.add(firstVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
firstVector.add(x);
}
int j = 0;
for(int i = 6; i<firstVector.size(); i++){
if(firstVector.get(i).equals(0)){
j++;
}
}
if(j>1){
OneZeroInLastFive(firstVector);
}
int[] sum = {0,0,0,0,0,0,0,0,0,0,0};
for (int i=0; i<sum.length; i++) {
sumOfXandY.add(sum[i]);
}
}
//Edits the vector if there is more than 0 in the last five digits
public void OneZeroInLastFive(ArrayList<Integer> x){
int j = 0;
for(int i = 6; i<x.size(); i++){
if(x.get(i).equals(0)){
j++;
}
}
if(j>1){
x.set(6, (int) (Math.random()*3));
x.set(7, (int) (Math.random()*3));
x.set(8, (int) (Math.random()*3));
x.set(9, (int) (Math.random()*3));
x.set(10, (int) (Math.random()*3));
j = 0;
OneZeroInLastFive(x);
}
}
//Creates the second vector with the last 5 digits random
public void createSecondVector(){
int[] secondVector1 = {0,1,0,0,0,0};
for (int i=0; i<secondVector1.length; i++) {
secondVector.add(secondVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
secondVector.add(x);
}
}
//Creates the third vector with the last 5 digits random
public void createThirdVector(){
int[] thirdVector1 = {0,0,1,0,0,0};
for (int i=0; i<thirdVector1.length; i++) {
thirdVector.add(thirdVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
thirdVector.add(x);
}
}
/**
* Will edit the second vector to ensure the following conditions are satisfied
* - The sum of x and y modulo 3 has at least 5 NON zeros
* - x and y must DIFFER in at least 5 places
* - There is only one zero within the last 5 digits
*
*/
public void checkVectors(ArrayList<Integer> x, ArrayList<Integer> y){
int k = 0;
int m = 0;
for(int j = 0; j < x.size(); j++){
if(x.get(j).equals(y.get(j))){
;
}
else{
k++;
}
}
for(int i = 6; i<y.size(); i++){
if(y.get(i).equals(0)){
m++;
}
}
if((k>4 && m<1)&& checkNonZeros(x,y)){
System.out.println("Conditions met");
}
else{
y.set(6, (int) (Math.random()*3));
y.set(7, (int) (Math.random()*3));
y.set(8, (int) (Math.random()*3));
y.set(9, (int) (Math.random()*3));
y.set(10, (int) (Math.random()*3));
k = 0;
m = 0;
checkVectors(x,y);
}
}
public ArrayList<Integer> addTwoVectors(ArrayList<Integer> x, ArrayList<Integer> y, ArrayList<Integer> z){
for(int i = 0; i<x.size(); i++){
int j = x.get(i);
int k = y.get(i);
z.set(i, ((j+k)%3));
}
return z;
}
public boolean checkNonZeros(ArrayList<Integer> x, ArrayList<Integer> y){
addTwoVectors(x,y, sumOfXandY);
int j = 0;
for(int i = 0; i<firstVector.size(); i++){
if(sumOfXandY.get(i).equals(0)){
;
}
else{
j++;
}
}
if(j<5){
return false;
}
else {
return true;
}
}
public static void main(String[] args){
GenerateVectors g = new GenerateVectors();
g.createFirstVector();
g.createSecondVector();
g.createThirdVector();
g.checkVectors(firstVector,secondVector);
g.checkVectors(secondVector,thirdVector);
System.out.println(firstVector);
System.out.println(secondVector);
System.out.println(thirdVector + "\n");
System.out.println(g.checkNonZeros(firstVector, secondVector));
System.out.println(g.checkNonZeros(secondVector,thirdVector));
System.out.println(sumOfXandY);
}
}
Any help would be much appreciated!!!
The problem is that you have methods that recursively call themselves in order to 'redo', which may happen many times before you get a success. This is fine in languages like scheme or ml which do proper tail recursion, but java does not, so you get stack overflows.
In order to fix this you need to manually convert the recursive code into a loop. Code that looks like:
method(arg1, arg2) {
Code_block_1;
if (test) {
Code_block_2;
} else {
Code_block_3;
method(newarg1, newarg2);
}
}
needs to become something like:
method(arg1, arg2) {
Code_block_1;
while(!test) {
Code_block_3;
arg1 = newarg1;
arg2 = newarg2;
Code_block_1;
}
Code_block_2;
}
You can then refactor stuff to get rid of/merge the duplicated code if you wish.