I am starting with Java and I was wondering how could you reverse a diagonal search like the one shown in the picture but from bottom left to right or from right top to bottom left.
The code for the diagonal search shown in the picture is :
// top-left to bottom-right - green diagonals
for (int rowStart = 0; rowStart < rowMax - 4; rowStart++) {
int count = 0;
int row, col;
for (row = rowStart, col = 0; row < rowMax && col < colMax; row++, col++) {
if (gridTable[row][col] == player) {
count++;
if (count >= 4) return 1;
} else {
count = 0;
}
}
}
// top-left to bottom-right - red diagonals
for (colStart = 1; colStart < colMax - 4; colStart++) {
count = 0;
int row, col;
for (row = 0, col = colStart; row < rowMax && col < colMax; row++, col++) {
if (gridTable[row][col] == player) {
count++;
if (count >= 4) return 1;
} else {
count = 0;
}
}
}
I have a project at school where I have to create a Sudoku Program. I have managed to get a Solver algorithm working but not a Generator. I spent a lot of time online to see if people had found ways to make a working one and I found a man named Mark Fredrick Graves, Jr. (https://www.youtube.com/user/mfgravesjr) who provided a very detailed code on the creation of a sudoku grid on his GitHub (https://github.com/mfgravesjr/finished-projects/tree/master/SudokuGridGenerator). However, I felt that using a one dimensional array was unnecessarily difficult in terms of finding the equations to access lines, columns and boxes. I therefore tried to translate his code into a two dimensional array but I am running into issues with some of his sorting methods and what some variables represent like "int step = (a%2==0? rowOrigin + j: colOrigin + j*9);". What I would like to know is how to translate the methods he uses from one dimensional arrays into two dimensional arrays. Below are the methods (code snippets) in question and my half attempt at translating it myself.
public int[] generateGrid(){
ArrayList<Integer> arr = new ArrayList<Integer>(9);
solvedGrid = new int[81];
for(int i = 1; i <= 9; i++) arr.add(i);
//loads all boxes with numbers 1 through 9
for(int i = 0; i < 81; i++){
if(i%9 == 0) {
Collections.shuffle(arr);
}
int perBox = ((i / 3) % 3) * 9 + ((i % 27) / 9) * 3 + (i / 27) * 27 + (i % 3);
solvedGrid[perBox] = arr.get(i%9);
}
//tracks rows and columns that have been sorted
boolean[] sorted = new boolean[81];
for(int i = 0; i < 9; i++){
boolean backtrack = false;
//0 is row, 1 is column
for(int a = 0; a<2; a++){
//every number 1-9 that is encountered is registered
boolean[] registered = new boolean[10]; //index 0 will intentionally be left empty since there are only number 1-9.
int rowOrigin = i * 9;
int colOrigin = i;
ROW_COL: for(int j = 0; j < 9; j++){
//row/column stepping - making sure numbers are only registered once and marking which cells have been sorted
int step = (a%2==0? rowOrigin + j: colOrigin + j*9);
int num = solvedGrid[step];
if(!registered[num]) {
registered[num] = true;
}else {
//if duplicate in row/column
//box and adjacent-cell swap (BAS method)
//checks for either unregistered and unsorted candidates in same box,
//or unregistered and sorted candidates in the adjacent cells
for(int y = j; y >= 0; y--){
int scan = (a%2==0? i * 9 + y: i + 9 * y);
if(solvedGrid[scan] == num){
//box stepping
for(int z = (a%2==0? (i%3 + 1) * 3: 0); z < 9; z++){
if(a%2 == 1 && z%3 <= i%3) {
continue;
}
int boxOrigin = ((scan % 9) / 3) * 3 + (scan / 27) * 27;
int boxStep = boxOrigin + (z / 3) * 9 + (z % 3);
int boxNum = solvedGrid[boxStep];
if((!sorted[scan] && !sorted[boxStep] && !registered[boxNum]) || (sorted[scan] && !registered[boxNum] && (a%2==0? boxStep%9==scan%9: boxStep/9==scan/9))){
solvedGrid[scan] = boxNum;
solvedGrid[boxStep] = num;
registered[boxNum] = true;
continue ROW_COL;
}else if(z == 8) {
//if z == 8, then break statement not reached: no candidates available
//Preferred adjacent swap (PAS)
//Swaps x for y (preference on unregistered numbers), finds occurence of y
//and swaps with z, etc. until an unregistered number has been found
int searchingNo = num;
//noting the location for the blindSwaps to prevent infinite loops.
boolean[] blindSwapIndex = new boolean[81];
//loop of size 18 to prevent infinite loops as well. Max of 18 swaps are possible.
//at the end of this loop, if continue or break statements are not reached, then
//fail-safe is executed called Advance and Backtrack Sort (ABS) which allows the
//algorithm to continue sorting the next row and column before coming back.
//Somehow, this fail-safe ensures success.
for(int q = 0; q < 18; q++){
SWAP: for(int b = 0; b <= j; b++){
int pacing = (a%2==0? rowOrigin+b: colOrigin+b*9);
if(solvedGrid[pacing] == searchingNo){
int adjacentCell = -1;
int adjacentNo = -1;
int decrement = (a%2==0? 9: 1);
for(int c = 1; c < 3 - (i % 3); c++){
adjacentCell = pacing + (a%2==0? (c + 1)*9: c + 1);
//this creates the preference for swapping with unregistered numbers
if((a%2==0 && adjacentCell >= 81)
|| (a%2==1 && adjacentCell % 9 == 0)) {
adjacentCell -= decrement;
}else {
adjacentNo = solvedGrid[adjacentCell];
if(i%3!=0
|| c!=1
|| blindSwapIndex[adjacentCell]
|| registered[adjacentNo]) {
adjacentCell -= decrement;
}
}
adjacentNo = solvedGrid[adjacentCell];
//as long as it hasn't been swapped before, swap it
if(!blindSwapIndex[adjacentCell]){
blindSwapIndex[adjacentCell] = true;
solvedGrid[pacing] = adjacentNo;
solvedGrid[adjacentCell] = searchingNo;
searchingNo = adjacentNo;
if(!registered[adjacentNo]){
registered[adjacentNo] = true;
continue ROW_COL;
}
break SWAP;
}
}
}
}
}
//begin Advance and Backtrack Sort (ABS)
backtrack = true;
break ROW_COL;
}
}
}
}
}
}
if(a%2==0) {
for(int j = 0; j < 9; j++) {
sorted[i*9+j] = true; //setting row as sorted
}
}else if(!backtrack) {
for(int j = 0; j < 9; j++) {
sorted[i+j*9] = true; //setting column as sorted
}
}else {//reseting sorted cells through to the last iteration
//backtrack = false;
for(int j = 0; j < 9; j++) {
sorted[i*9+j] = false;
}
for(int j = 0; j < 9; j++) {
sorted[(i-1)*9+j] = false;
}
for(int j = 0; j < 9; j++) {
sorted[i-1+j*9] = false;
}
for(int j = 0; j < 81; j++) {
sorted[j] = false;
}
i-=2;
}
}
}
if(!isPerfect(solvedGrid)) {
throw new RuntimeException("ERROR: Imperfect grid generated.");
}
return solvedGrid;
}
My code (unfinished)
public int[][] generateGrid(){
ArrayList<Integer> arr = new ArrayList<Integer>(9);
ArrayList<Integer> values = new ArrayList<Integer>(9);
solvedGrid = new int[9][9];
for(int i = 1 ; i <= 9; i++) {
arr.add(i);
values.add(i);
}
//Fill all boxes with number 1 to 9
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
if(j == 0) {
Collections.shuffle(arr);
}
solvedGrid[(i/3)*3+(j/3)][(i%3)*3+(j%3)] = arr.get(j);
}
}
//boolean[][] sorted = new boolean[9][9];
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
int[] rowColValues = new int[9];
rowColValues[j] = solvedGrid[0][j];
ArrayList<Integer> occurence = new ArrayList<Integer>();
for(int k = 0; k < rowColValues.length; k++) {
occurence.add((k+1), occurence.get(k+1)+1);
if(occurence.get(k+1) != 1) {
//swap with number in the box that isn't already in rowColValues
//Not sure how to do this...
//Create a method that takes the correct variables as parameters ?
break;
}
}
//Read the sudoku row then column wise and swap values that already exist in the column or row.
}
}
print2DGrid(solvedGrid);
return solvedGrid;
}
Conway's game of life with each cell being a thread
Hey guys,
So like the title says, I have to make a program that implements threading in Conway's game of life, where each dead or alive cell is a thread.
My first goal was to simply get the game working, which i did (pretty fun challenge)
So i can print the 20x20 grid, and each cell is initialized as a random number 1 or 0, where 1 is alive, and 0 is dead.
Now, I've been watching videos on how to use threading, but i'm still unsure as to how i'm supposed to implement this for each cell...
I have 3 classes, Main, Cell, and CellRules
my Cell class looks like:
public class Cell implements Runnable
{
public static int myCount = 0;
private String name;
private int neighbors;
private int alive; // 0 is dead; 1 is alive.
Random rand = new Random();
public Cell (String nm)
{
name = nm;
myCount = rand.nextInt(999);
neighbors = 0;
// 2 because it is exclusive
this.setLife(rand.nextInt(2));
}
public void run()
{
while(Cell.myCount <= 10){
try
{
System.out.println("Expl Thread: " + (++Cell.myCount));
Thread.sleep(100);
} catch (InterruptedException iex)
{
System.out.println("Exception in thread:
"+iex.getMessage());
}
}
}
There are a few other things in there, that are really for simplicity, i don't believe they are necessary to be shown, and same thing for the Cell Rules class. Cell Rules looks like:
/**
* This function simply gets the number of neighbors for each cell, and saves the future generation
* based on the number neighbors from arr to future array.
*
* #param arr Arr that will be checked for neighbors
* #param futureGen This array will keep track of the future generation
* #param columns numbers of columns
* #param rows numbers of rows
*/
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows)
{
for (int x = 0; x < rows; x++)
{
for (int y = 0; y < columns; y++)
{
arr[x][y].setNeighbors(0);
// Upper left corner
if (x == 0 && y == 0)
for (int i = 0; i <= 1; i++)
for (int j = 0; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Upper margin checks
if ((x == 0) && (y != 0 && y <= columns - 2))
for(int i = 0; i <= 1; i++)
for(int j = -1; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Upper right corner
if ((x == 0) && (y == columns - 1))
for(int i = 0; i <= 1; i++)
for(int j = -1; j <= 0; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Left margin checks
if ((y == 0) && (x != 0 && x <= rows - 2))
for (int i = -1; i <= 1; i++)
for (int j = 0; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Lower left corner
if ((x == rows - 1) && y == 0)
for (int i = -1; i <= 0; i++)
for (int j = 0; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Bottom margin checks
if ((x == rows - 1) && (y != 0 && y <= columns - 2 ))
for (int i = -1; i <= 0; i++)
for (int j = -1; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Lower right corner
if ((x == rows - 1) && (y == columns - 1))
for (int i = -1; i <= 0; i++)
for (int j = -1; j <= 0; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Right margin checks
if ((y == columns - 1) && (x != 0 && x <= rows - 2))
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 0; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Middle area checks ( can check all around now )!
if ((x > 0) && (x < rows - 1) && (y > 0) && (y < columns - 1) )
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
// Do not add yourself!
if (arr[x][y].getLife() == 1)
arr[x][y].subNeighbor();
// Get the new generation through the neighbors
if ((arr[x][y].getLife() == 1) &&
(arr[x][y].getNeighbors() < 2))
futureGen[x][y].setLife(0);
else if ((arr[x][y].getLife() == 1) &&
(arr[x][y].getNeighbors() > 3))
futureGen[x][y].setLife(0);
else if ((arr[x][y].getLife() == 0) &&
(arr[x][y].getNeighbors() == 3))
futureGen[x][y].setLife(1);
else
futureGen[x][y].setLife(arr[x][y].getLife());
}
}
}
I'm not sure where the implementation of the threads really goes, Any guidance or explanations would be greatly appreciated!
Have a nice day :)
First of all, your checkN function is way overengineered. Let's simplify it a bit.
/**
* This function simply gets the number of neighbors for each cell, and saves the future generation
* based on the number neighbors from arr to future array.
*
* #param arr Arr that will be checked for neighbors
* #param futureGen This array will keep track of the future generation
* #param columns numbers of columns
* #param rows numbers of rows
*/
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows) {
for (int x = 0; x < rows; x++) {
for (int y = 0; y < columns; y++) {
arr[x][y].setNeighbors(0);
for(int i = -1; i <= 1; i++) {
for(int j = -1; j <= 1; j++) {
if(i == 0 && j == 0) continue; //don't check self
if(x + i < 0 || x + i >= rows) continue; //bounds checking
if(y + j < 0 || y + j >= columns) continue; //bounds checking
if (arr[x + i][y + j].getLife() == 1)
arr[x][y].addNeighbor();
}
}
// Get the new generation through the neighbors
if(arr[x][y].getLife() == 1 &&
(arr[x][y].getNeighbors() == 2 || arr[x][y].getNeighbors() == 3))
futureGen[x][y].setLife(1);
else if(arr[x][y].getLife() == 0 && arr[x][y].getNeighbors() == 3)
futureGen[x][y].setLife(1);
else
futureGen[x][y].setLife(0);
}
}
}
We can then refactor this into a few extra functions:
private void countNeighbors(Cell[][] arr, int row, int column, int rows, int columns) {
Cell c = arr[row][column];
c.setNeighbors(0);
for(int i = -1; i <= 1; i++) {
for(int j = -1; j <= 1; j++) {
if(i == 0 && j == 0) continue; //don't check self
if(row + i < 0 || row + i >= rows) continue; //bounds checking
if(column + j < 0 || column + j >= columns) continue; //bounds checking
if (arr[row + i][column + j].getLife() == 1)
c.addNeighbor();
}
}
}
private void evaluateNeighbors(Cell oldCell, Cell newCell) {
if (oldCell.getLife() == 1 &&
(oldCell.getNeighbors() == 2 || oldCell.getNeighbors() == 3))
newCell.setLife(1);
else if(oldCell.getLife() == 0 && oldCell.getNeighbors() == 3)
newCell.setLife(1);
else
newCell.setLife(0);
}
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows) {
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
countNeighbors(arr, row, column, rows, columns);
evaluateNeighbors(arr[row][column], futureGen[row][column]);
}
}
}
The reason we're refactoring like this will become apparent in a moment.
So back to the original question: where do we insert threading into this program?
You need to make a decision on how you want to split up threads. Based on your question, it sounds like you want to launch an independent thread for each cell that gets evaluated. While there's not any problems with this approach in theory, this really doesn't guarantee any significant speedup, simply because at thousands of cells (which you will quickly hit for even modest sizes of grids) you'll be creating thousands of threads, and only mega-servers will have enough threads to take advantage of it.
Nonetheless, if that's what you want to do, the code (Java 8 required) looks like this:
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows)
{
ArrayList<Thread> threads = new ArrayList<>();
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
Integer thread_local_row = row;
Integer thread_local_column = column;
Thread t = new Thread(() -> {
countNeighbors(arr, thread_local_row, thread_local_column, rows, columns);
evaluateNeighbors(arr[thread_local_row][thread_local_column], futureGen[thread_local_row][thread_local_column]);
});
t.start();
threads.add(t);
}
}
for(Thread t : threads)
t.join();
}
The end result is that each cell will receive its own dedicated thread. Note how little we had to change once the code was refactored.
Like I mentioned, however, this is overkill in terms of the number of threads we're creating. So an alternative is to create a new thread for each row.
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows)
{
ArrayList<Thread> threads = new ArrayList<>();
for (int row = 0; row < rows; row++) {
Integer thread_local_row = row;
Thread t = new Thread(() -> {
for (int column = 0; column < columns; column++) {
countNeighbors(arr, thread_local_row, column, rows, columns);
evaluateNeighbors(arr[thread_local_row][column], futureGen[thread_local_row][column]);
}
});
t.start();
threads.add(t);
}
for(Thread t : threads)
t.join();
}
This is better, but of course, it once again could become overkill if you have a lopsided grid that has lots of rows but very few columns.
So a third option is to make the number of threads constant, and scale the workload per thread to fit the number of threads.
public void checkN(Cell [][] arr, Cell [][] futureGen, int columns, int rows)
{
ArrayList<Thread> threads = new ArrayList<>();
final int NUM_OF_THREADS = 8; //Or can be passed as an argument
for(int tid = 0; tid < NUM_OF_THREADS; tid++) {
Integer thread_local_row_start = tid * rows / NUM_OF_THREADS;
Integer thread_local_row_end = (tid + 1) * rows / NUM_OF_THREADS;
Thread t = new Thread(() -> {
for (int row = thread_local_row_start; row < thread_local_row_end; row++) {
for (int column = 0; column < columns; column++) {
countNeighbors(arr, row, column, rows, columns);
evaluateNeighbors(arr[row][column], futureGen[row][column]);
}
}
});
t.start();
threads.add(t);
}
for(Thread t : threads)
t.join();
}
This option tends to be the most performant, since you can set NUM_OF_THREADS to be equal to the number of processor cores in your machine, or whatever value you find in testing to yield ideal performance.
You can use any of these techniques, or else come up with a different technique to split up the threads (for example, maybe an algorithm that perfectly splits the workloads, rather than rounding to nearest-row-counts?). The important part is simply keeping your code organized well enough to facilitate your workload splitting mechanism.
If you're limited to Java 7, all of the code written can still be used, but the lambda structure needs to be replaced with an Anonymous Inner Class, and any variables that need to be used in the thread body need to be made final:
public void checkN(final Cell [][] arr, final Cell [][] futureGen, final int columns, final int rows)
{
ArrayList<Thread> threads = new ArrayList<>();
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
final Integer thread_local_row = row;
final Integer thread_local_column = column;
Thread t = new Thread(new Runnable() {
public void run() {
countNeighbors(arr, thread_local_row, thread_local_column, rows, columns);
evaluateNeighbors(arr[thread_local_row][thread_local_column], futureGen[thread_local_row][thread_local_column]);
}
});
t.start();
threads.add(t);
}
}
for(Thread t : threads)
t.join();
}
I am making Tetris in Java. I am having difficulty having my blocks shift down, once a row has been removed (because it filled up). My code is throwing an arrayIndexOutOfBounds error. The rest of the code works, where it finds which row is full and sets that row to 0. But in the if statement near the bottom, that's where it doesn't work. Thanks ! :)
// Removes any rows that are filled
public static int removeRows()
{
// Variables
int numOfRows = tetrisGrid.getNumOfRows();
int numOfCols = tetrisGrid.getNumOfCols();
int numRowsRemoved = 0;
int [][] grid = tetrisGrid.getGrid();
// Finds the number of rows that are filled
for (int row = 0; row < numOfRows; row++)
{
for (int col = 0; col < numOfCols; col++)
{
int blockValue = tetrisGrid.getBlockValue(row, col);
if (blockValue == 0)
{
break;
}
if (col == numOfCols - 1)
{
numRowsRemoved++;
// Sets the rows filled to zero
for (int change = 0; change < numOfCols; change++)
{
grid [row][change] = 0;
}
// Shifts everything down until it hits blocks below
for (int shiftRow = 0; shiftRow < 2; shiftRow++)
{
for (int shiftCol = 0; shiftCol < numOfCols; shiftCol++)
{
if (blockValue == 1)
{
grid [row][col] = 0;
row++;
col++;
grid [row][col] = 1;
row--;
col--;
}
else if (blockValue == 0)
break;
}
}
// TAKE OUT -------------------------
System.out.println ("--------");
tetrisGrid.printGrid();
System.out.println ("--------");
// -------------------------
}
}
}
tetrisGrid.setGrid(grid);
return numRowsRemoved;
}
The following pice of code is my code for my Game of Life. For some reason it works very strangely. The first few steps of the game are wrong, and then the whole output turns to zeroes. I don't know which method is causing the problem, but I assume it is the count neighbors method.
The board is a 2D array called GOLBoard, and the x and y coordinates are cellRow and cellCol. Alive cells are 1, and dead cells are 0s. The way I avoid out of bounds problems are by making the board 12x12, but I use only 1 to 11 for rows and columns.
<code> #Override
public int countNeighbours(int cellRow, int cellCol) {
int neighbours = 0;
for (int i = cellRow-1; i < cellRow + 2; i++) {
for (int j = cellCol - 1; j < cellCol + 2; j++) {
if (GOLBoard[i][j] == 1) {
neighbours += 1;
}
}
}
if (GOLBoard[cellRow][cellCol] == 1) {
return(neighbours-1);
} else {
return(neighbours);
}
}
#Override
public int applyRules(int cellRow, int cellCol) {
int alive = 0;
if (GOLBoard[cellRow][cellCol] == 1) {
if (countNeighbours(cellRow, cellCol) == 2 || countNeighbours(cellRow, cellCol) == 3) {
alive = 1;
} else if (countNeighbours(cellRow, cellCol) < 2 || countNeighbours(cellRow, cellCol) > 3) {
alive = 0;
}
}
if (GOLBoard[cellRow][cellCol] == 0) {
if (countNeighbours(cellRow, cellCol) == 3) {
alive = 1;
}
}
return (alive);
}
#Override
public void takeStep() {
for (int row = 1; row < 11; row++) {
for (int col = 1; col < 11; col++) {
GOLBoard[row][col] = applyRules(row, col);
}
}
}
#Override
public String toString() {
for (int row = 1; row < 11; row++) {
for (int col = 1; col < 11; col++) {
System.out.print("[" + GOLBoard[row][col] + "]");
}
System.out.println("");
}
return("");
}
} <code>
If I am recalling the rules of GOL correctly, the evolution of the board should proceed in a series of "generations", wherein the state of each cell on a "new" board is determined solely by the conditions of the corresponding cell on the "old" board. Your program is trying to continuously evolve a single board, so that changes to previously computed cells are affecting the outcome of cells yet to be computed. Your takeStep routine should be doing something more like this:
newBoard = new int[12][12];
for (int row = 1; row < 11; row++) {
for (int col = 1; col < 11; col++) {
newBoard[row][col] = applyRules(row, col);
}
}
GOLBoard = newBoard;
As far as I can tell, your countNeighbours is OK.