Recursive solution to Sudoku generator - java

I'm trying to code an algorithm that creates a legal Sudoku board in either Java or Javascript. Neither work, and I'm not entirely sure why.
Essentially, the problem in both programs is that either x or y is getting incremented more than it should (skipping the square). I can't for the life of me figure out how this is happening. I can provide the HTML that completes the JS solution if need be.
My best guess is it has to do with how I've created a stack using recursion, but as far as I can tell, it should work.
In my old code there was an incorrect for loop, I'm aware of this. I pasted an old version, it's fixed now.
Java:
import java.util.*;
public class SudokuGenerator
{
//credit:cachao
//http://stackoverflow.com/questions/9959172/recursive-solution-to-sudoku-generator
public static final int BOARD_WIDTH = 9;
public static final int BOARD_HEIGHT = 9;
public SudokuGenerator() {
board = new int[BOARD_WIDTH][BOARD_HEIGHT];
}
//Recursive method that attempts to place every number in a square
public int[][] nextBoard()
{
nextBoard(0,0);
return board;
}
public void nextBoard(int x, int y)
{
int nextX = x;
int nextY = y;
//int[] toCheck = Collections.shuffle(Arrays.asList({1,2,3,4,5,6,7,8,9}));
int[] toCheck = {1,2,3,4,5,6,7,8,9};
Collections.shuffle(Arrays.asList(toCheck));
for(int i=0;i<toCheck.length;i++)
{
if(legalMove(x, y, toCheck[i]))
{
board[x][y] = toCheck[i];
if(x == 8)
{
if(y == 8)
break;//We're done! Yay!
else
{
nextX = 0;
nextY++;
}
}
else
{
nextX++;
}
nextBoard(nextX, nextY);
}
}
board[x][y] = 0;
}
public boolean legalMove(int x, int y, int current) {
for(int i=0;i<9;i++) {
if(current == board[x][i])
return false;
}
for(int i=0;i<9;i++) {
if(current == board[i][y])
return false;
}
int cornerX = 0;
int cornerY = 0;
if(x > 2)
if(x > 5)
cornerX = 6;
else
cornerX = 3;
if(y > 2)
if(y > 5)
cornerY = 6;
else
cornerY = 3;
for(int i=cornerX;i<10 && i<cornerX+3;i++)
for(int j=cornerY;j<10 && j<cornerY+3;j++)
if(current == board[i][j])
return false;
return true;
}
public void print()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
System.out.print(board[i][j] + " ");
System.out.println();
}
}
public static void main(String[] args)
{
SudokuGenerator sg = new SudokuGenerator();
sg.nextBoard();
sg.print();
}
int[][] board;
}
Javascript:
//Recursive method that attempts to place every number in a square
function driver()
{
board = new Array(10);
for(var i=0;i<9;i++)
board[i] = new Array(10);
nextBoard(0,0);
print();
}
function nextBoard(x, y)
{
var nextX = x;
var nextY = y;
for(var i=1;i<10;i++) {
console.log(y + " " + x + " " + i);
document.getElementById(y + " " + x).innerHTML = i;
if(legalMove(x, y, i)) {
board[x][y] = i;
if(x === 8) {
if(y === 8)
return board;//We're done! Yay!
else {
nextX = 0;
nextY++;
}
}
else
nextX++;
nextBoard(nextX, nextY);
}
}
//This is needed for legalMove to work, otherwise [x][y] == 9
board[x][y] = undefined;
}
function legalMove(x, y, current) {
for(var i=0;i<9;i++) {
if(current === board[x][i])
return false;
}
for(var i=0;i<9;i++) {
if(current === board[i][y])
return false;
}
var cornerX = 0;
var cornerY = 0;
if(x > 2)
if(x > 5)
cornerX = 6;
else
cornerX = 3;
if(y > 2)
if(y > 5)
cornerY = 6;
else
cornerY = 3;
for(var i=cornerX;i<10 && i<cornerX+3;i++)
for(var j=cornerY;j<10 && j<cornerY+3;j++)
if(current === board[i][j])
return false;
return true;
}
function print() {
for(var i=0;i<9;i++)
for(var j=0;j<9;j++)
{
document.getElementById(i + " " + j).innerHTML = board[i][j];
console.log(board[i][j]);
}
}
var board;

In the Java code:
I'll translate it to psuedocode:
for all z values:
If for current (x,y), the number 'z' is legal then:
insert z to current (x,y)
if finished
hooray!
else
go to next square
else try next number
But what if you can't put any number there as it ends up being illegal (aka a board where you can't insert any number in a specific square)?
You don't address that. What you need to do is implement it via backtracking:
for all z values:
If for current (x,y) the number 'z' is legal then:
insert z to current (x,y)
go to next(x,y)
try to complete the board // recursive call
if you completed the board // == the result of the recursion is legal
return the completed board
If all z values have been attempted
return "cannot complete board"
increment z, try again with current (x,y)

Java:
You should initialize your board variable, you may want to initialize it in a constructor:
public class SudokuGenerator {
public static final int BOARD_WIDTH = 9;
public static final int BOARD_HEIGHT = 9;
public SudokuGenerator() {
board = new int[BOARD_WIDTH][BOARD_HEIGHT];
}
}
I believe that your loop iterator in the function nextBoard it is wrong:
for(int i=1;i<10;i++){ ... }
I think that you want to iterate from 0 to 9.
In the function nextBoard, you also need to check the variable:
int[] toCheck = {1,2,3,4,5,6,7,8,9};
You get an java.lang.ArrayIndexOutOfBoundsException, you should initialize it from 0 to 8, otherwise you try to access the board row number 9 and you get a runtime error.
Another problem that you need to solve is that x is being set to nine in nextBoard() function. Call the function nextBoard(int x, int y) "manually" with these parameteres: nextBoard(7,3) and you will understand why x is being set to nine. Check specifically the values of the variable nextX.
I believe it will really help you if you use a debugger to check this kind of errors, here you have a nice tutorial with a video explanation(in case your are using the Eclipse IDE).
Hope it helps.

Java:
Your loop iterator in nextBoard range from 1 to 9. I don't think you meant that. Same in the function legalMove.... initialize cornerX and cornerY to 0.

interesting question, I just noticed this one bug in the Java code: isn't the call to Collection.shuffle() useless since the toCheck array will remain unmodifed (unshuffled) after this call? Here is my quick fix (and I'm sure there are more clever ways to do it):
List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Collections.shuffle(lst);
for (int i=0; i<lst.size(); i++)
toCheck[i] = lst.get(i);

In Java array indexes are zero-based. In nextBoard you loop over 1..9 for i and use it as an index into toCheck which will skip the first element at index 0 and go past the end of the array. This will throw ArrayIndexOutOfBoundsException if the line containing toCheck[i] is reached with i equal to 9.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SudokuNrupen {
public static int[][] p;
public static int tmp[] ;
public static int tmp2D[][] ;
public static void main(String[] args){
tmp = new int[9];
tmp2D = new int[3][3];
p = new int[9][9];
System.out.print("Enter the name of he file below ");
Scanner scan = new Scanner (System.in);
String name = scan.nextLine();
File file = new File( name );
if ( file.exists()){
try {
Scanner inFile = new Scanner( file );
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
if(inFile.hasNextInt()){
p[i][j] = inFile.nextInt();
}
}
}
inFile.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(SudokuNrupen.class.getName()).log(Level.SEVERE, null, ex);
}
}
display(p);
solve(p);
System.out.println("Solved Sudoku is:");
display(p);
}
public static void display(int [][] p)
{
for(int i=0; i<p.length;i++)
{
for(int j=0; j<p[i].length;j++)
{
System.out.print(" ");
if(p[i][j]<10) System.out.print(p[i][j] + " ");
else System.out.print(p[i][j]);
System.out.print(" ");
}
System.out.println();
}
}
public static boolean solve(int [][] p)
{
if(!isValidSudoku(p))
{
return false;
}
if(isComplete(p)==true)
{
return true;
}
for(int i=0; i<9; i++)
{
for(int j=0 ; j<9 ; j++)
{
if(p[i][j]==0)
{
int k=1;
while(k<=9)
{
p[i][j]=k;
if(solve(p))
{
return true;
}
else k++;
}
p[i][j]=0;
return false;
}
}
}
return true;
}
public static boolean isComplete(int [][]p)
{
for(int i=0; i<9; i++)
{
for(int j=0 ; j<9 ; j++)
{
if(p[i][j]==0){
return false;
}
}
}
return true;
}
public static boolean isRepeated(int [] a)
{
for(int i=0; i<8; i++)
{
if((a[i]!=0 || a[i+1]!=0))
{
if(a[i]==a[i+1]){
return true;
}
}
}
return false;
}
public static boolean isDuplicateEx0(int [][]p)
{
for(int i=0; i<p[0].length; i++)
{
for(int j=0 ; j<9 ; j++)
{
tmp[j]=p[i][j];
}
Arrays.sort(tmp);
System.out.println(Arrays.toString(tmp));
if(isRepeated(tmp)==true)
{
System.out.println("Duplicates are found in row");
return true;
}
}
display(p);
for(int j=0; j<p[0].length; j++)
{
for(int i=0 ; i<9 ; i++)
{
tmp[i]=p[i][j];
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
System.out.println("Duplicates are found in columns");
return true;
}
}
display(p);
for(int z=0;z<9;z++){
tmp[z]=0;
}
int x=0,y=0;
for(int i=0; i<3;i++)
{
y=0;
for(int j=0;j<3;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=0; i<3;i++)
{
y=0;
for(int j=3;j<6;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=0; i<3;i++)
{
y=0;
for(int j=6;j<9;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=3; i<6;i++)
{
y=0;
for(int j=0;j<3;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=3; i<6;i++)
{
y=0;
for(int j=3;j<6;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=3; i<6;i++)
{
y=0;
for(int j=6;j<9;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=6; i<9;i++)
{
y=0;
for(int j=0;j<3;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=6; i<9;i++)
{
y=0;
for(int j=3;j<6;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
for(int z=0;z<9;z++){
tmp[z]=0;
}
x=0;
y=0;
for(int i=6; i<9;i++)
{
y=0;
for(int j=6;j<9;j++)
{
tmp2D[x][y]=p[i][j];
y++;
}
x++;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
}
}
Arrays.sort(tmp);
if(isRepeated(tmp)==true)
{
return true;
}
return false;
}
public static boolean isValidSudoku(int [][] p)
{
return (!isDuplicateEx0(p));
}
}

Related

Can anyone tell me why my calculateCoin function doesnt show up?

Can anyone help me why the calculateCoin function doesn't show up? Basically what it does is, it calculates the coin, that was generated randomly in the drawMap function within 20% chance.
What I did and not sure doing right is, I called the calculateCoin function IN the drawMap function, and then I call the drawMap in the main.
public static void main(String[] args) {
Main main = new Main();
System.out.println(main.drawMap());
}
public int[][] drawMap(){
int[][] map = new int[5][5];
char coin = 'o';
for(int i =0; i<map.length; i++){
for(int j =0; j<map[i].length; j++){
map[i][j] = (int)(Math.random()*10);
if(map[i][j]<2){
System.out.print(coin+ " ");
}
else
System.out.print("*"+ " ");
}
System.out.println("");
}
calculateCoin(map, coin);
System.out.println("");
return map;
}
public int calculateCoin(int[][] map, char coin){
int result = 0;
for(int i = 0; i<map.length; i++){
for(int j = 0; j<map[i].length; j++){
if(map[i][j] == coin){
result++;
}
}
}
return result;
}
The function is actually being called but the value that you return from it is not stored in any variable. If you want something to happen after printing the map, store the result of the call in a variable and then print it.
int calculatedCoin = calculateCoin(map, coin);
System.out.println("Calculated coin: " + calculatedCoin)
try this , but basically you declare a type of a class not a method.
public class dave {
public static void main(String[] args) {
dave main = new dave();
System.out.println(dave.drawMap());
}
public static int[][] drawMap() {
int[][] map = new int[5][5];
char coin = 'o';
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
map[i][j] = (int) (Math.random() * 10);
if (map[i][j] < 2) {
System.out.print(coin + " ");
} else
System.out.print("*" + " ");
}
System.out.println("");
}
calculateCoin(map, coin);
System.out.println("");
return map;
}
public static int calculateCoin(int[][] map, char coin) {
int result = 0;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
if (map[i][j] == coin) {
result++;
}
}
}
return result;
}
}

Minesweeper Nearby Mine Counting

I'm trying to create a 10x10 Minesweeper-esque board made of _'s, with 10 mines randomly placed as *'s. No actual gameplay is involved, just the making of the board. I've been able to (somewhat) successfully place the mines randomly but I can't get the nearby mine counting aspect to work. I've tried many different things but this is what I've come up with so far.
import java.util.Random;
public class Mines {
public static final int BOARD_SIZE = 10;
enum Space {Empty, Mine, MineCount};
public static void main(String[] args) {
Random rand = new Random();
//Creates board
Space[][] board = new Space[BOARD_SIZE][BOARD_SIZE];
for (int y=0;y<board.length;y++)
{
for (int x=0;x<board.length;x++)
{
board[x][y] = Space.Empty;
}
}
System.out.println("Creating empty board");
//Draws the board
for(int y=0;y<board.length;y++)
{
for(int x=0;x<board.length;x++)
{
switch(board[y][x])
{
case Empty:
System.out.print("_");
break;
default:
System.out.println("?");
}
}
System.out.println();
}
System.out.println("Placing mines");
//Sets mines
for(int i=0;i<board.length;i++)
{
int mX = rand.nextInt(BOARD_SIZE);
int mY = rand.nextInt(BOARD_SIZE);
if(board[mX][mY] == Space.Empty)
{
board[mX][mY] = Space.Mine;
}
}
for(int y=0;y<board.length;y++)
{
for(int x=0;x<board.length;x++)
{
switch(board[y][x])
{
case Empty:
System.out.print("_");
break;
case Mine:
System.out.print("*");
break;
}
}
System.out.println();
}
//Count mines
System.out.println("Counting the mines");
//Prints board again
for(int y=0;y<board.length;y++)
{
for(int x=0;x<board.length;x++)
{
switch(board[y][x])
{
case Empty:
System.out.print("_");
break;
case Mine:
System.out.print("*");
break;
case MineCount:
int mineCount = 0;
if(board[x-1][y-1] == Space.Mine)
{
mineCount++;
board[y][x] = Space.MineCount;
System.out.print(mineCount);
}
}
}
System.out.println();
}
}
}
Try this code (Not an object oriented approach), but is easily understandable:
import java.util.Random;
public class Mines {
public static final int BOARD_SIZE = 5;
enum Space {
Empty, Mine
};
public static void main(String[] args) {
Random rand = new Random();
// Creates board
System.out.println("Empty board");
Space[][] board = new Space[BOARD_SIZE][BOARD_SIZE];
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board.length; x++) {
board[x][y] = Space.Empty;
System.out.print("_");
}
System.out.println();
}
// Sets mines
for (int i = 0; i < BOARD_SIZE; i++) {
int mX = rand.nextInt(BOARD_SIZE);
int mY = rand.nextInt(BOARD_SIZE);
// Condition if random number combination [mX, mY] generated previously. Guarantees BOARD_SIZE mines always.
if(Space.Mine.equals(board[mX][mY])) {
i--;
continue;
}
board[mX][mY] = Space.Mine;
}
System.out.println("\nPlacing mines");
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board.length; x++) {
switch (board[y][x]) {
case Empty :
System.out.print("_");
break;
case Mine :
System.out.print("*");
break;
}
}
System.out.println();
}
// Count mines
System.out.println("\nCounting mines");
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board.length; x++) {
if(Space.Mine.equals(board[y][x])) {
System.out.print("*");
} else {
System.out.print(findAdjCount(y, x, board));
}
}
System.out.println();
}
}
private static int findAdjCount(int row, int col, Space[][] board) {
int cnt = 0;
// Check 8 adjacent positions
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if(i >= 0 && i < BOARD_SIZE && j >= 0 && j < BOARD_SIZE) {
if(Space.Mine.equals(board[i][j])) {
cnt++;
}
}
}
}
return cnt;
}
}

Creating a double mirrored triangle

I need help making a mirrored triangle like this:
* *
** **
*** ***
********
I can get each one seperatly, but I can't combine them.
public static void main(String[] args){
for( int i = 1; i <= 5; i++ ){
for( int j = 0; j < i; j++ ){
System.out.print("*");
}
System.out.println();
}
for(int i = 0; i < 6; i++)
{
for(int j = 5; j > 0; j--)
{
if(i < j)
System.out.print(" ");
else
System.out.print("*");
}
System.out.println();
}
}
You need to track the position from both sides to be able to show * at correct location. Here is the solution:
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 10; j++) {
if (j <= i || j > 10 - i) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
You can do it using this code.
public class Test {
public void sizeOfTri(int triSize) { //Number of lines
int line = 1;
for(int i = 0; i < triSize; i++) { //Handles Each line
int temp = triSize * 2;
for(int j = 1; j < temp; j++) { //Handles Each space on the line
if(j <= line && j == triSize || j >= temp - line && j == triSize) { //For the very last line because it needs an extra *
System.out.print("**");
} else if(j <= line || j >= temp - line) { //For normal lines
System.out.print("*");
} else if(j == triSize) {
System.out.print(" "); //For the second to last line because it needs an extra space to make it look mirrored
} else { //For normal lines
System.out.print(" ");
}
}
System.out.println();
line++;
}
}
public static void main(String[] args) {
new Test().sizeOfTri(4);
}
}
I commented on next to if statements on which part does what. This will produce an output which looks like the below when run
* *
** **
*** ***
********
Although, all the above implementations are really good ones. I thought of doing it bit differently and make use of 2-D arrays.
package algorithms;
public class DrawMirror {
static void initialize(String[][] array){
for (int i=0; i<MAX_X; i++){
for (int j=0; j < MAX_Y; j++){
array[i][j] = " ";
}
}
}
static void draw(String[][] array, int x, int y){
for (int i=0; i < y; i++){
array[x][i] = "*";
array[x][MAX_Y-i-1] = "*";
}
}
final static int MAX_X = 4;
final static int MAX_Y = 8;
public static void main(String[] args) {
String[][] array = new String[MAX_X][MAX_Y];
initialize(array);
for (int i=0; i < MAX_X ; i++){
draw(array,i,i+1);
}
for( int i = 0; i < MAX_X; i++ ){
for( int j = 0; j < MAX_Y; j++ ){
System.out.print(array[i][j]);
}
System.out.println();
}
}
}
The following code is a function with variable height.
public static void printDoubleTriangle(int height) {
for(int i = 0; i < height; i++) {
for(int j = 0; j < 2*height; j++) {
if(j <= i || (2*height - j - 1) <= i) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}

Java - Uncommon sort a multidimensional array

I need help with this exercise
Consider you have 2d array
String[][]myArray={
{"0.0","0.1","0.2","0.3","0.4"},
{"1.0","1.1","1.2","1.3"},
{"2.0","2.1","2.2","2.3","2.4","2.5"}
};
and you wish to print:
0.0|1.0|2.0|
0.1|1.1|2.1|
0.2|1.2|2.1|
0.3|1.3|2.3|
0.4|2.4|
2.5|
I have tried to use Comparator
Here is code :
public static void main(String[] args) {
String[][]Array={
{"0.0","0.1","0.2","0.3","0.4"},
{"1.0","1.1","1.2","1.3"},
{"2.0","2.1","2.2","2.3","2.4","2.5"}
};
Arrays.sort(Array, new PorKolumn(2));
for (int i = 0; i < Array.length; i++) {
String [] kol = Array[i];
for(int j=0; j<kol.length; j++) {
System.out.print(kol[j] + " | ");
}
System.out.println();
}
}
}
class PorKolumn implements Comparator{
int Kolumny;
public PorKolumn(int Kolumny) {
this.Kolumny = Kolumny;
}
public int compare (Object o1, Object o2 ){
String [] kol1 = (String []) o1;
String [] kol2 = (String []) o2;
return kol1[Kolumny].compareTo(kol2[Kolumny]);
}'
Thx for any help.
public static void print( String[][] a ){
int iRow = 0;
while(true){
boolean done = false;
for( int iCol = 0; iCol < a.length; iCol++ ){
if( iRow < a[iCol].length ){
System.out.print( a[iCol][iRow] + "|" );
done = true;
}
}
if( ! done ) break;
System.out.println();
iRow++;
}
}
Prints as requested:
0.0|1.0|2.0|
0.1|1.1|2.1|
0.2|1.2|2.2|
0.3|1.3|2.3|
0.4|2.4|
2.5|
As #Teepeemm stated there is no sorting:
String[][]myArray={
{"0.0","0.1","0.2","0.3","0.4"},
{"1.0","1.1","1.2","1.3"},
{"2.0","2.1","2.2","2.3","2.4","2.5"}
};
int maxLength = 0;
for(int i = 0; i < myArray.length; i++)
if(maxLength < myArray[i].length)
maxLength = myArray[i].length;
for(int j = 0; j < maxLength; j++) {
for(int i = 0; i < myArray.length; i++)
if(j < myArray[i].length)
System.out.print(myArray[i][j] + "|");
System.out.print("\n");
}
}
Output:
0.0|1.0|2.0|
0.1|1.1|2.1|
0.2|1.2|2.2|
0.3|1.3|2.3|
0.4|2.4|
2.5|
You could try something like this:
(This is untested code, because i have written it directly here)
int i = 0;
boolean ongoing = true;
while(ongoing){
for(int j = 0; j < myArray.length; j++){
if(myArray[j][i] == null){
System.out.print("\t|");
ongoing = false;
continiue;
}
ongoing = true;
System.out.print(myArray[j][i]+"\t|");
}
System.out.print("\n");
i++;
}
it should give out the right format.

Conway's Game of Life Update(Next Generation)

I am working on Conway's game of life java code and I am having a struggle with my update method also known as the next generation creator. I will post my code I have written so far and please let me know what I can do to fix the update method.
A cell is born if there was none at time T
1 and exactly three of its neighbors were alive.
An existing cell remains alive if at time T
1 there were either two or three neighbors
A cell dies from isolation if at time T
1 there were fewer than two neighbors.
A cell dies from overcrowding if at time T
1 there were more than three neighbors.
public class GameOfLife {
private char [][] grid;
private int rows;
private int columns;
public GameOfLife(int rows, int columns) {
grid=new char[rows][columns];
for(int i=0;i<grid.length;i++)
{
for(int j=0;j<grid[i].length;j++)
grid[i][j]=' ';
}
}
public int numberOfRows() {
int countRows=0;
for(int i=0;i<grid.length;i++){
countRows++;
rows=countRows;
}
return rows;
}
public int numberOfColumns() {
int countColumns=0;
for(int i=0;i<1;i++){
for(int j=0;j<grid[i].length;j++)
countColumns++;
columns=countColumns;
}
return columns;
}
public void growCellAt(int row, int col) {
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++)
grid[row][col]='O';
}
}
public boolean cellAt(int row, int col) {
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++)
if(grid[row][col]=='O')
return true;
}
return false;
}
public String toString() {
String result="";
for(int i=0;i<rows;i++){
for(int j=0;j<columns;j++)
result+=grid[i][j];
}
return result;
}
public int neighborCount(int row, int col) {
int count=0;
int i=row;
int j=col;
int left;
int right;
int up;
int down;
if(i > 0)
up = i-1;
else
up = grid.length-1;
if(i < (grid.length-1))
down = i+1;
else
down = 0;
if(j > 0)
left = j-1;
else
left = grid[i].length - 1;
if(j < (grid[i].length-1))
right = j+1;
else
right = 0;
if(grid[up][left] == 'O')
count++;
if(grid[up][j] == 'O')
count++;
if(grid[up][right] == 'O')
count++;
if(grid[i][left] == 'O')
count++;
if(grid[i][right] == 'O')
count++;
if(grid[down][left] == 'O')
count++;
if(grid[down][j] == 'O')
count++;
if(grid[down][right] == 'O')
count++;
return count;
}
public void update() {
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++){
if(grid[i][j]==' ' && neighborCount(i,j)==3)
grid[i][j]='O';
if(neighborCount(i,j)<2 || neighborCount(i,j)>3)
grid[i][j]= ' ';
if(grid[i][j]=='O' && neighborCount(i,j)==2 || neighborCount(i,j)==3)
grid[i][j]='O';
}
}
}
}
Ok regarding making a new array in the update method, is this all that needs to be done? Also, how would I go about making assertion tests for the update method?
public void update() {
char[][] newGrid = new char[grid.length][grid[0].length];
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[i].length;j++){
if(grid[i][j]==' ' && neighborCount(i,j)==3)
newGrid[i][j]='O';
if(neighborCount(i,j)<2 || neighborCount(i,j)>3)
newGrid[i][j]= ' ';
if(grid[i][j]=='O' && neighborCount(i,j)==2 || neighborCount(i,j)==3)
newGrid[i][j]='O';
}
}
}
It looks like you are trying to modify the same grid you are looping through. As you loop through your grid, changes should be made based on the previous state of the grid. Try constructing a new grid instead of writing over the old one.
That's how I would go about it.
Note that this is C++11 implementation
template<std::size_t X, std::size_t Y>
class GameOfLife {
private:
std::pair<int, int> neighbors[8];
public:
typedef std::array<std::array<uint16_t,Y>,X> Grid;
private:
uint16_t getCellStatus(Grid const& conway, int x, int y) {
uint16_t liveCount = 0;
for(auto&& neighbor: neighbors) {
int nX = x + neighbor.first;
int nY = y + neighbor.second;
if(nX>=0 && nX<X && nY>=0 && nY<Y){
if(conway[nX][nY]>0) liveCount++;
}
}
if(conway[x][y]>0){
if(liveCount==2 ||liveCount == 3) return 1;
}
else {
if(liveCount==3) return 1;
}
return 0;
}
public:
GameOfLife() {
size_t index = 0;
for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j){
if((i|j)==0) continue;
neighbors[index].first = i;
neighbors[index++].second = j;
}
}
}
Grid getNextConway(Grid const& conway) {
Grid output;
for(size_t i=0; i<X; ++i)
for(size_t j=0; j<Y; ++j) output[i][j]=getCellStatus(conway,i,j);
return output;
}
Grid printGrid(Grid const& conway) {
for (int i = 0; i < X; ++i){
for (int j = 0; j < Y; ++j) {
if(conway[i][j]==0) std::cout<<"0";
else std::cout<<"1";
}
std::cout<<std::endl;
}
std::cout<<std::endl;
}
};
int main() {
size_t const DIM = 8;
size_t const NUM_GENS = 10;
typedef GameOfLife<DIM,DIM> Game;
typename Game::Grid gameGrid;
for (int i = 0; i < DIM; ++i) {
for (int j = 0; j < DIM; ++j) {
gameGrid[i][j] = rand()%2;
}
}
Game conway;
conway.printGrid(gameGrid);
for (int i = 0; i < NUM_GENS; ++i) {
gameGrid = conway.getNextConway(gameGrid);
conway.printGrid(gameGrid);
}
return 0;
}

Categories

Resources