So im programming a battleships game, and im trying to place ships on a board. I can get it to place the ship going left and going down from the starting point but cant get it going down or left. I understand my method overall is in-effeicient.
public static int[][] SetUserBoard(int[][] board) {
int x;
int y;
y = 0;
for (int z = 0; z < 10; z++) {
String gridv;
gridv = "";
int direction;
System.out.println("Set the Position for Ship no. " + (z+1));
Scanner s1 = new Scanner(System.in);
System.out.println("Enter the grid column(A-H):");
gridv = s1.nextLine();
if (gridv.equals("A")) {
y = 0;
}
if (gridv.equals("B")) {
y = 1;
}
if (gridv.equals("C")) {
y = 2;
}
if (gridv.equals("D")) {
y = 3;
}
if (gridv.equals("E")) {
y = 4;
}
if (gridv.equals("F")) {
y = 5;
}
if (gridv.equals("G")) {
y = 6;
}
if (gridv.equals("H")) {
y = 7;
}
System.out.println("Enter the y co=ordinate: ");
x = s1.nextInt();
x -= 1;
System.out.println("Enter the direction of the ship 0-3(0=down,1=right,2=up,3=left): ");
direction = s1.nextInt();
if(z == 0) { //placing 4 unit ship in first increment
if(direction == 0 && x < 5){ //vertical placement - down
for(int i=0; i < 4; i++) {
board[x][y] = 0;
x += 1;
}
}
if(direction == 1 && y < 5) { //horizontal placement - right
for(int i=0; i < 4; i++) {
board[x][y] = 0;
y += 1;
}
}
if(direction == 2 && x > 3 ) { //vertical placement - up
for(int i=0; i < 4; i++) {
board[x][y] = 0;
x -= 1;
}
}
if(direction == 3 && y > 3) { //horizontal placement - left
for(int i=0; i < 4; i++) {
board[x][y] = 0;
y -= 1;
}
}
}
...if(z > 0 && z < 3) { //placing 3 unit ships in 2nd and 3rd increment....
return board;
}
if you ignore the bottom part, and focus on the if z=0 part as that's which part i'm using to test this with my most updated try. Originally I had an indexing error which I managed to solve but now all the program does is run as usual except when moving onto the next one the board isn't updated and is still empty. So im stumped as to what logic to use for up/left.
For diagonal changes, you need to alter both i and j as you traverse the ship. For instance:
UP_LEFT = 4
...
ship_len = 4
...
if(direction == UP_LEFT &&
y > ship_len-1 &&
x > ship_len-1) { // SE-NW placement
for(int i=0; i < ship_len; i++) {
board[x][y] = 0;
y -= 1;
x -= 1;
}
}
Related
I'm coding Conway's Game of Life on Processing 3 and I want to store x and y so that the squares don't change right away, but I don't know how to store it to use later. Any help is appreciated!
void keyPressed() {
for (int x = 0; x < 30; x++) {
for (int y = 0; y < 30; y++) {
int numNeighbours = numNeighbours(x,y);
if (cells[x][y] == true) {
if (numNeighbours > 3 || numNeighbours <= 1) { //underpopulation or overpopulation
}
}
else if (cells[x][y] == false) {
if (numNeighbours == 3) {
}
}
}
}
}
Based on my understanding of your code (and the Game of Life), you don't need to store x and y. What you actually need to do is to store the (x, y) pairs where the cell changes state.
You could do this by creating pairs and adding them to lists.
But a another idea is to use a second array representing the next generation of the game and put all of the new values there; e.g.
for (int x = 0; x < 30; x++) {
for (int y = 0; y < 30; y++) {
int numNeighbours = numNeighbours(x,y);
if (cells[x][y] == true) {
if (numNeighbours > 3 || numNeighbours <= 1) {
cellsNext[x][y] = false;
} else {
cellsNext[x][y] = true;
}
}
else if (cells[x][y] == false) {
if (numNeighbours == 3) {
cellsNext[x][y] = true;
} else {
cellsNext[x][y] = false;
}
}
}
}
Note: that could be simplified / written better, but I have written it as above so that you can see clearly what I have done.
I have this class that randomly creates rooms next to each other, and prints brackets (which represent the rooms) to the console. But I wanted to know how to add something like that to a JPanel for a GUI. Here is the room generator class:
public class Rooms {
static final int width = 15, height = 10;
static final int rooms = 19;
static boolean[][] room = new boolean[width][height];
static int neighborCount(int x, int y) {
int n = 0;
if (x > 0 && room[x-1][y]) n++;
if (y > 0 && room[x][y-1]) n++;
if (x < width-1 && room[x+1][y]) n++;
if (y < height-1 && room[x][y+1]) n++;
return n;
}
public void Rooms() {
room[width/2][height/2] = true;
Random r = new Random();
int x, y, nc;
for (int i = 0; i < rooms; i++) {
while (true) {
x = r.nextInt(width);
y = r.nextInt(height);
nc = neighborCount(x, y);
if (!room[x][y] && nc == 1) break;
}
room[x][y] = true;
}
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
System.out.print(room[x][y] ? "[]" : " ");
System.out.print();
}
}
}
Thanks for the help!
You probably want to use java.awt.Graphics. It lets you draw primitive shapes like lines, rectangles, circles, etc. This might get you started. Section 2 also covers how to draw on a JPanel.
trying to create a Conways Game of life, but apparently the shapes are not like they have to be. Perhaps someone can help me find the issue.
For example the glider :
- X - - - -
- - X X - -
- X X - - -
- - - - - -
becomes this
- - X X - -
- X - - - -
X X X - - -
- X X X - -
but should be like this :
- - X - - -
- - - X - -
- X X X - -
- - - - - -
And my code looks like this
public Frame(int x, int y) {
setWidth(x);
setHeight(y);
if (x<1)
frame = null;
else if (y<1)
frame = null;
else {
frame = new String [x][y];
for (int i=0; i<frame.length; i++) {
for (int j=0; j<frame[i].length; j++) {
frame [i][j] = DEAD;
}
}
} // else
} // construktor
public Integer getNeighbourCount(int x, int y) {
Frame cell = new Frame(getHeight(), getWidth());
int counter = 0;
if(frame[x][y].equals(ALIVE))
{
counter = counter - 1;
}
for(int i=x-1; i<=x+1;i++){
if(i<frame.length && i>0){
for(int j=y-1; j<=y+1;j++){
if(j<frame[i].length && j>0){
if (frame[i][j]==ALIVE) {
counter++;
}
}
}
}
}
return counter;
}
public Frame nextFrame() {
// Returns next frame
Frame cell = new Frame(getWidth(), getHeight());
//cell.frame = new String[getWidth()][getHeight()];
for(int i = 0; i < frame.length; i++){
for(int j =0; j <frame[i].length;j++){
int n = getNeighbourCount(i,j);
if(cell.frame[i][j]==null) {
cell.frame[i][j] = DEAD;
}
if (isAlive(i, j) && n < 2 || n > 3) {
cell.frame[i][j] = DEAD;
}
if (isAlive(i, j) && n == 3 || n == 2){
cell.frame[i][j] = ALIVE;
}
if(!isAlive(i, j) && n == 3) {
cell.frame[i][j] = ALIVE;
}
if(isAlive(i, j) && n > 3){
cell.frame[i][j] = DEAD;
}
frame[i][j] = cell.frame[i][j];
}
}
cell.toString();
return cell;
}
`
Full code http://pastebin.com/LMwz724H
Here's a solution that works - using an enum for each cell and getting the i/j and x/y stuff right (I think). It certainly generates the correct first iteration:
static class GameOfLife {
final int w;
final int h;
State[][] frame;
enum State {
Dead, Alive;
}
public GameOfLife(int w, int h) {
this.w = w;
this.h = h;
frame = new State[h][w];
}
public void alive(int x, int y) {
frame[y][x] = State.Alive;
}
public void tick() {
frame = nextGeneration();
}
private int surroundingPopulation(int x, int y) {
int pop = 0;
for (int i = y - 1; i <= y + 1; i++) {
for (int j = x - 1; j <= x + 1; j++) {
// On frame - vertically.
if ((i >= 0 && i < h)
// On frame horizontally.
&& (j >= 0 && j < w)
// Alive
&& (frame[i][j] == State.Alive)
// Not the center.
&& (i != y || j != x)) {
pop += 1;
}
}
}
return pop;
}
private State[][] nextGeneration() {
State[][] next = new State[h][w];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int pop = surroundingPopulation(x, y);
// Any live cell
if (frame[y][x] == State.Alive) {
if (pop < 2) {
// ... with fewer than two live neighbours dies, as if caused by under-population.
next[y][x] = State.Dead;
} else if (pop > 3) {
// ... with more than three live neighbours dies, as if by overcrowding.
next[y][x] = State.Dead;
} else {
// ... with two or three live neighbours lives on to the next generation.
next[y][x] = State.Alive;
}
} else {
// Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
if (pop == 3) {
next[y][x] = State.Alive;
}
}
}
}
return next;
}
#Override
public String toString() {
StringBuilder s = new StringBuilder();
for (State[] row : frame) {
for (State c : row) {
s.append(c == State.Alive ? "X" : " ");
}
s.append("\r\n");
}
return s.toString();
}
}
public void test() {
GameOfLife g = new GameOfLife(6, 6);
g.alive(1, 0);
g.alive(2, 1);
g.alive(3, 1);
g.alive(1, 2);
g.alive(2, 2);
System.out.println("Before:\r\n" + g);
g.tick();
System.out.println("After:\r\n" + g);
}
I believe the problem is that you are copying the new value as you iterate through the loop. This means neighbours are using the value from the next tick rather than the current one.
You can fix this by waiting until you calculated all new values in your new frame: cell.frame and then iterate through the frame again and copy from cell.frame to frame.
An alternative (better in my view) is to have away of cloning a frame during construction. Then you could change your nextFrame method to create a clone of frame and use the clone to set the new values in frame.
You are changing the DEAD and ALIVE frames while you iterate through the grid. You need to store the coordinates which should die or become alive and perform that afterwards.
Store the coordinates in two ArrayLists (dead, alive). The first and second position is the x and y axis, and change those coordinates according to whether they should become alive or not.
Here's a snippet from a simple test I wrote a while back. As others have mentioned, don't change values on an active board while still reading them. Instead, clone the board and make changes to the copy while reading the current board.
Another problem I bumped into a few times was iterating over y, then x for each y, but referring to x,y when accessing a point. It feels back to front :)
// Rules:
// 1) Any live cell with fewer than two live neighbours dies, as if caused by under-population.
// 2) Any live cell with two or three live neighbours lives on to the next generation.
// 3) Any live cell with more than three live neighbours dies, as if by overcrowding.
// 4) Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
void mutateGrid() {
// Copy existing grid into the next generation's grid
boolean[][] mutatedGrid = new boolean[gridXWidth][gridYHeight];
for (int i = 0; i < gridXWidth; i++) {
System.arraycopy(grid[i], 0, mutatedGrid[i], 0, gridYHeight);
}
// Start mutation rules
for (int y = 0; y < gridYHeight; y++) {
for (int x = 0; x < gridXWidth; x++) {
int liveNeighbours = countLiveNeighbours(x,y);
if (liveNeighbours < 2 || liveNeighbours > 3) {
mutatedGrid[x][y] = false;
}
else if (liveNeighbours == 3) {
mutatedGrid[x][y] = true;
}
}
}
grid = mutatedGrid;
}
int countLiveNeighbours(int x, int y) {
int count = 0;
for (int j = y-1; j <= y+1; j++) {
for (int i = x-1; i <= x+1; i++) {
if (i < 0 || j < 0 || i >= gridXWidth || j >= gridYHeight){
continue;
}
if (grid[i][j]) {
count++;
}
}
}
count -= grid[x][y]?1:0; // remove self from count
return count;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Looping in a spiral
I'm creating a program to populate a 3 by 3 matrix. I want to result in something looking like this
5 4 3
6 1 2
7 8 9
As you have probably noticed it is a spiral.
Now the algorithm I'm using is this: I have a 2-d array where the values represent the coordinates of the number. First I assign that every number coordinate in this array will have a value of 10. Then starting at 9 I decrease my x coordinate and assign the value of the coordinate to currentnum - 1 until it reaches the end or its value is not 10; Then I do the same thing except I increase the value of Y; Then decrease the value of x; Then of Y;
The reason I assign 10 to every number is so like it acts as a road for my program. Since current num will never exceed 9. If the value of a square is 10 it is like a green light. If it is not 10 meaning a value has been assigned to that square it breaks out of it.
Here is my code, please note it is written in Java
public class spiral {
/**
* #param args
*/
public static void main(String[] args) {
int spiral [] [] = new int[3][3];
for(int i = 0; i <= 2; i++){
for(int j = 0; j <= 2; j++){
spiral[i][j] = 10;
}
}
//0 is x value, 1 is y value
spiral[0][0] = 9;
int x = 1;
int y = 1;
int counter = 1;
int currentnum = 9;
int gridsquare = 3;
for(int i = 0; i <= 8; i++){
if(counter == 5){
counter = 1;
}
if(counter == 1){
System.out.println(x + " " + y);
for(int j = 0;j <= 1;j++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
x += 1;
}
else{
y += 1;
break;
}
}
}
if(counter == 2){
for(int k = 0; k <= 0; k++){
System.out.print(x + " " + y);
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
y += 1;
}
else{
x -= 1;
break;
}
}
}
if(counter == 3){
for(int z = 0; z <= 0; z++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
x -= 1;
}
else{
y -= 1;
break;
}
}
}
if(counter == 4){
for(int b = 0; b <= 0; b++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
y -= 1;
}
else{
x += 1;
break;
}
}
}
counter++;
}
System.out.print(currentnum);
}
}
I'm getting this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at spiral.main(spiral.java:44)
Since I'm new to Java would someone please suggest a posible fix for this. Also if you see any problems with my algorithm please do inform me.
You do not need to pre-fill with 10: zero works just as well.
I think the best approach to solving the spiral is to think of how you do it manually: start in a corner, and go horizontally until you hit non-zero or an edge of the array. Then you turn right. Stop when the current number goes past N*N.
Now let's look at what each part of the algorithm means:
Starting in the corner means setting x=0 and y=0.
Going in a straight line means x=x+dx, y=y+dy, where either dx or dy is zero, and dy or dx is 1 or -1.
Turning right means assigning dx to dy and -dy to dx.
Here is how it looks in the code:
int current = 1;
// Start in the corner
int x = 0, y = 0, dx = 1, dy = 0;
while (current <= N*N) {
// Go in a straight line
spiral[x][y] = current++;
int nx = x + dx, ny = y + dy;
// When you hit the edge...
if (nx < 0 || nx == N || ny < 0 || ny == N || spiral[nx][ny] != 0) {
// ...turn right
int t = dy;
dy = dx;
dx = -t;
}
x += dx;
y += dy;
}
You've incremented x or y to 3 which is past the end of one of your arrays.
Step through your program with the debugger or add System.out.println statements before each if (counter) to find out where you're doing this.
I am writing a bouncing ball class (I'm just starting to use Java) and it works but it looks like every time the ball hits an edge the containing box gets bigger
Code for the bounce trigger
int i = 0;
int j = 0;
int k = 0;
double x = 3;
double y = 3;
while(i < 200){
if(j == 0){
x += 2;
} else {
x -= 2;
}
if(k == 0){
y += 4;
} else {
y -= 4;
}
if(thisEye.getX() > 400){
j = 1;
}
if(thisEye.getX() < 0) {
j = 0;
}
if(thisEye.getY() > 200){
k = 1;
}
if(thisEye.getY() < 0) {
k = 0;
}
Color someShade = rGen.nextColor(); // var for the color of the eyes
Color someOtherShade = rGen.nextColor();// var for the color of the pupules
moveThis(thisEye,x,y,someShade); // Go over all the shapes with the same X,Y offset - var x,y
moveThis(thisPupul,x,y,someOtherShade);
moveThis(thisEye2,x,y,someShade);
moveThis(thisPupul2,x,y,someOtherShade);
moveThis(face,x,y,rGen.nextColor());
moveThis(nose,x,y,rGen.nextColor());
pause(150.0); // wait for next cycle to slow down the images
//i++; this was to see if it just got farther off with each loop, it dose.
}
}
private void moveThis(GOval subject, double x, double y, Color newShade){
subject.setFillColor(newShade);
subject.move(x, y);
}
the 'face' will bounce off the right spot once then each time it bounces it gets farther and farther off the screen tell is so far of the it only is on screen for a short time then off the other side tell it comes back on screen for a bit.
I marked it as home work but I'm a html/php coder in the day and am just using the iTunesU Stanford videos at night.
but I'm trying to learn so pointers would be great.
The problem could be (though very unlikely) with your theEye.getX() and theEye.getY() method. What if you change your boundary condition check from
if(thisEye.getX() > 400){
j = 1;
}
if(thisEye.getX() < 0) {
j = 0;
}
if(thisEye.getY() > 200){
k = 1;
}
if(thisEye.getY() < 0) {
k = 0;
}
TO
if(x > 400){
j = 1;
}
if(x < 0) {
j = 0;
}
if(y > 200){
k = 1;
}
if(y < 0) {
k = 0;
}
Otherwise, please post the complete source code so we can see where else could the problem be.