I'am working on a program that makes right and left arrows. They are extended from a ShapeBase class which is implemented from a ShapeInterface. I didn't paste them so it wouldn't look overwhelming. The problem is I have figured out the right arrow ( I believe) but cannot find my way to getting the left arrow. I keep getting confused and cant seem to understand how to do it. Any help is appreciated.
RightArrow Example Output
public abstract class ShapeBase implements ShapeInterface
{
private int offset;
public ShapeBase( )
{
offset = 0;
}
public ShapeBase(int theOffset)
{
offset = theOffset;
}
public abstract void drawHere( );
public void drawAt(int lineNumber)
{
for (int count = 0; count < lineNumber; count++)
System.out.println( );
drawHere( );
}
public void setOffset(int newOffset)
{
offset = newOffset;
}
public int getOffset( )
{
return offset;
}
}
public class RightArrow extends ShapeBase
{
private int tail;
private int width;
public RightArrow()
{
super();
tail = 0;
width = 0;
}
public RightArrow(int theOffset ,int tailSize, int theWidth)
{
super(theOffset);
tail = tailSize;
width = theWidth;
set(tail , width);
}
public void set(int newHeight, int newWidth)
{
tail = newHeight;
width = newWidth;
}
public void drawHere()
{
topArrowhead();
ArrowTail();
bottomArrowHead();
}
public void topArrowhead()
{
skipSpaces(getOffset());
System.out.println("*");
for(int i = 0; i<width/2; i++)
{
skipSpaces(getOffset());
System.out.print("*");
skipSpaces(i);
System.out.println("*");
}
}
// method to draw the arrow tail
public void ArrowTail()
{
for(int count=0; count<tail; count++)
{
System.out.print("*");
}
skipSpaces(tail+width);
System.out.print("*");
}
// method to draw bottom of arrowhead
public void bottomArrowHead()
{
for(int i =1;i<width/2; i--)
{
skipSpaces(getOffset());
System.out.print("*");
skipSpaces(i);
System.out.println("*");
}
skipSpaces(getOffset());
System.out.println("*");
}
private static void skipSpaces(int number)
{
for (int count=0; count< number; count++)
System.out.print(" ");
}
}
FOR THE LEFT ARROW CLASS, I believe these are the only methods need changing.
I just don't know how
public void topArrowhead()
{
skipsSpaces(getOffset());
System.out.println("*");
for(int i = 0 i<width/2; i++)
{
skipSpaces(getOffset());
System.out.print("*");
skipSpaces(i);
System.out.println("*");
}
}
// method to draw the arrow tail
public void ArrowTail()
{
}
// method to draw bottom of arrowhead
public void bottomArrowHead()
{
}
private static void skipSpaces(int number)
{
for (int count=0; count< number; count--)
System.out.print(" ");
}
}
This is how you can draw a left arrow,it doesn't uses your methods(as you not provided source for ShapeBase) but you can see the implementation below how its get created and then can use in your own way.
public class LeftArrow
{
private int tail=15;
private int width=7;
//Method to draw the left arrow
public void DrawArrow()
{
for(int i = 0,r=0; i<width; i++)
{
//for spaces before head
for(int j=0;j<(width/2)-r;j++)
System.out.print(" ");
for(int j=0;j<=r;j++)
{
if(j==r || j==0)
System.out.print("*");
else
System.out.print(" ");//for spaces inside head
}
if(i==width/2)//to draw tail after the mid of head
ArrowTail();
if(i<width/2)//controls the increment & decrements of spaces before head
r++;
else r--;
System.out.println();
}
}
// method to draw the arrow tail
public void ArrowTail()
{
for(int count=0; count<tail; count++)
{
System.out.print("*");
}
}
public static void main(String[] args)
{
LeftArrow Arrow = new LeftArrow();
Arrow.DrawArrow();
}
}
Related
I just started to learn Java and am working on a small project which is supposed to create a gameField in a 2 dimensional String Array Field Borders are marked with a "#". In this Field I want to spawn a player who is marked as ">". This player can then turn left or right (∧ for looking up for example) and then has the option to move forward one space.
I currently have the gameField created and now want to spawn the player into that 2 dimensional String Array for which I have made a spawnPlayer method/function in the class Player. I now want to add / open that method/function in the main method. This is where I am getting the error messages and dont know what to do.
public class KonsolenWanderer {
public static void main(String[] args) {
Field field1 = new Field();
field1.createField();
Player player1 = new Player();
//Error is here!!!
player1.spawnPlayer();
}
}
public class Field {
private String [][] fieldSize = new String [10][10];
public void createField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
//Creating Field Border
if(i == 0 || i == 9 || j == 0 || j == 9) {
fieldSize[i][j] = "#";
}
else {
fieldSize[i][j] = " ";
}
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public String[][] getFieldSize() {
return fieldSize;
}
public void setFieldSize(String[][] fieldSize) {
this.fieldSize = fieldSize;
}
}
public class Player {
private static int xPosition;
private static int yPosition;
private String up = "∧";
private String down = "∨";
private String left = "<";
private String right = ">";
private String currentDirection;
Player() {
xPosition = 4;
yPosition = 4;
}
public void spawnPlayer(String[][]fieldSize) {
fieldSize[xPosition][yPosition] = ">";
}
public static void moveForward() {
}
public static void turnPlayerLeft() {
}
public static void turnPlayerRight() {
}
}
You need to set the position inside the field object or expose fieldSize from within Field class.
public class KonsolenWanderer {
public static void main(String[] args) {
Field field = new Field();
field.createField();
Player player1 = new Player();
//Error is here!!!
player1.spawnPlayer(new String[8][8], field);
field.showField();
}
}
class Field {
private String [][] fieldSize = new String [10][10];
public void createField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
//Creating Field Border
if(i == 0 || i == 9 || j == 0 || j == 9) {
fieldSize[i][j] = "#";
}
else {
fieldSize[i][j] = " ";
}
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public void showField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public String[][] getFieldSize() {
return fieldSize;
}
public void setFieldSize(String[][] fieldSize) {
this.fieldSize = fieldSize;
}
public void setPlayerPosition(int i, int j) {
i++;
j++;
fieldSize[i][j] = ">";
}
}
class Player {
private static int xPosition;
private static int yPosition;
private String up = "∧";
private String down = "∨";
private String left = "<";
private String right = ">";
private String currentDirection;
Player() {
xPosition = 4;
yPosition = 4;
}
public void spawnPlayer(String[][] fieldSize, Field field) {
for(int i = 0; i < fieldSize.length; i++) {
if (i == fieldSize.length -1){
for(int j = 0; j < fieldSize[i].length; j++) {
if (j == fieldSize.length - 1 )
field.setPlayerPosition(i, j);
}
}
}
}
public static void moveForward() {
}
public static void turnPlayerLeft() {
}
public static void turnPlayerRight() {
}
}
I have six classes for my program and I believe most of my code is correct, but when I go to run it no print statements happen and instead the program continues running forever without output. This causes a massive memory leak if I run the simulation for larger numbers (100+). I can't seem to find what the problem is but the code just won't properly execute.
**** (where I execute the program from and where I think the error is)
import java.util.*;
public class {
public static void main(String[]args){
SubSim simulate=new SubSim();
ArrayList<Wolf>WolfArrayList=new ArrayList<>();
ArrayList<Moose>MooseArrayList=new ArrayList<>();
ArrayList<Grass>GrassArrayList=new ArrayList<>();
for (int i=0;i<simulate.getInitialWolves();i++){
WolfArrayList.add(new Wolf(simulate));
}
for (int i=0;i<simulate.getInitialMoose();i++){
MooseArrayList.add(new Moose(simulate));
}
for (int i=0;i<simulate.getMaxX();i++){
for (int j=0;i<simulate.getMaxY();j++){
int grassroll=(int)(Math.random()*5);
if (grassroll==1||grassroll==2||grassroll==3||grassroll==4){
GrassArrayList.add(new Grass(simulate,i,j,2));
}
else{
GrassArrayList.add(new Grass(simulate,i,j,0));
}
}
}
simulate.setGrassArrayList(GrassArrayList);
simulate.setMooseArrayList(MooseArrayList);
simulate.setWolfArrayList(WolfArrayList);
System.out.println("Ticks Wolves Moose");
for(int i=1;i<=20;i++){
System.out.printf("%d %d %d\n",(i-1),simulate.getWolfPop(),simulate.getMoosePop());
simulate.run();
}
}
}
** Class**
import java.util.*;
public class extends Simulator{
//making private variables
private ArrayList<Grass> GrassArrayList;
private ArrayList<Moose> MooseArrayList;
private ArrayList<Wolf> WolfArrayList;
//using the animals move method
#Override
public void animalsMove() {
for (int i = 0; i < WolfArrayList.size(); i++) {
WolfArrayList.get(i).move();
WolfArrayList.get(i).setEnergy(WolfArrayList.get(i).getEnergy()-getMovementCost());
}
for (int i = 0; i < MooseArrayList.size(); i++) {
MooseArrayList.get(i).move();
MooseArrayList.get(i).setEnergy(MooseArrayList.get(i).getEnergy()-getMovementCost());
}
}
//using the animals die method
#Override
public void animalsDie(){
int WolfArraySize=WolfArrayList.size();
for (int i=0;i<WolfArraySize;i++) {
if (WolfArrayList.get(i).getEnergy() <= 0){
WolfArrayList.remove(i);
WolfArraySize = WolfArrayList.size();
}
}
int MooseArraySize=MooseArrayList.size();
for (int i=0;i<WolfArraySize;i++){
if (MooseArrayList.get(i).getEnergy() <= 0){
MooseArrayList.remove(i);
MooseArraySize = MooseArrayList.size();
}
}
}
//using animals eat method
#Override
public void animalsEat() {
for (int i = 0; i < WolfArrayList.size(); i++) {
for (int j = 0; j < MooseArrayList.size(); j++) {
if (MooseArrayList.get(j).getLocationX() == WolfArrayList.get(i).getLocationX() && MooseArrayList.get(j).getLocationY() == WolfArrayList.get(i).getLocationY()) {
MooseArrayList.remove(j);
WolfArrayList.get(i).eat();
}
}
}
for (int i = 0; i < MooseArrayList.size(); i++) {
for (int j = 0; j < GrassArrayList.size(); j++) {
if (MooseArrayList.get(i).getLocationX() == GrassArrayList.get(j).getXcord() && MooseArrayList.get(i).getLocationY() == GrassArrayList.get(j).getYcord()) {
MooseArrayList.remove(j);
WolfArrayList.get(i).eat();
}
}
}
}
//using animals reproduce method
#Override
public void animalsReproduce(){
for (int i=0;i<WolfArrayList.size();i++){
if (WolfArrayList.get(i).getEnergy() >= 100) {
Wolf puppy = (Wolf) WolfArrayList.get(i).reproduce();
WolfArrayList.add(puppy);
WolfArrayList.get(i).setEnergy(getInitialEnergy());
}
}
for (int i=0;i<MooseArrayList.size();i++) {
if (MooseArrayList.get(i).getEnergy() >= 100) {
Moose calf = (Moose) MooseArrayList.get(i).reproduce();
MooseArrayList.add(calf);
MooseArrayList.get(i).setEnergy(getInitialEnergy());
}
}
}
//using grass grows method
#Override
public void grassGrows(){
for(int i=0;i<GrassArrayList.size();i++){
if (GrassArrayList.get(i).getLength()>0){
GrassArrayList.get(i).setLength((int)(GrassArrayList.get(i).getLength()+getGrassGrowthRate()));
}
//making shorthand instanced variables
int xcord=GrassArrayList.get(i).getXcord();
int ycord=GrassArrayList.get(i).getYcord();
if(GrassArrayList.get(i).getLength()>=10){
for (int j=0;j<GrassArrayList.size();j++){
//checking area around tall grass to place seeds
if(xcord==GrassArrayList.get(j).getXcord() && ycord+1==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() && ycord+1==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() && ycord==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() && ycord-1==GrassArrayList.get(j).getYcord() || xcord==GrassArrayList.get(j).getXcord() && ycord-1==GrassArrayList.get(j).getYcord() || xcord+1==GrassArrayList.get(j).getXcord() && ycord-1==GrassArrayList.get(j).getYcord() || xcord+1==GrassArrayList.get(j).getXcord() && ycord==GrassArrayList.get(j).getYcord() || xcord+1==GrassArrayList.get(j).getXcord() && ycord+1==GrassArrayList.get(j).getYcord()){
GrassArrayList.get(j).setLength((int)(GrassArrayList.get(j).getLength()+getGrassGrowthRate()));
}
}
}
}
}
//using the run method
#Override
public void run(){
tick();
}
public int getMoosePop(){
return MooseArrayList.size();
}
public int getWolfPop(){
return WolfArrayList.size();
}
public ArrayList<Grass> getGrassArrayList() {
return GrassArrayList;
}
public void setGrassArrayList(ArrayList<Grass> grassArrayList) {
GrassArrayList = grassArrayList;
}
public ArrayList<Moose> getMooseArrayList() {
return MooseArrayList;
}
public void setMooseArrayList(ArrayList<Moose> mooseArrayList) {
MooseArrayList = mooseArrayList;
}
public ArrayList<Wolf> getWolfArrayList() {
return WolfArrayList;
}
public void setWolfArrayList(ArrayList<Wolf> wolfArrayList) {
WolfArrayList = wolfArrayList;
}
}
** Class**
public class extends {
private int movewolf;
public Wolf(Simulator simulator){
super(simulator);
}
#Override
public void eat(){
setEnergy((getEnergy()+getSimulator().getEnergyGainFromEatingMoose()));
}
#Override
public Animal reproduce(){
Wolf wolf=new Wolf(getSimulator());
wolf.setLocationX(getSimulator().randomInt(getSimulator().getMaxX()));
wolf.setLocationY(getSimulator().randomInt(getSimulator().getMaxY()));
wolf.setEnergy(getSimulator().getInitialEnergy());
return wolf;
}
#Override
public Animal die(){
return null;
}
#Override
public void move(){
int moveX=(int)(Math.random()*2);
int moveY=(int)(Math.random()*2);
if (getLocationX()<getSimulator().getMaxX()&& getLocationX()>0 && getLocationY()<getSimulator().getMaxY()&& getLocationY()>0){
if (moveX==1){
this.movewolf=getLocationX()+1;
setLocationX(movewolf);
}
else{
this.movewolf=getLocationX()-1;
setLocationX(movewolf);
}
if (moveY==1){
this.movewolf=getLocationY()+1;
setLocationY(movewolf);
}
else{
this.movewolf=getLocationY()-1;
setLocationY(movewolf);
}
}
else if (getLocationX()==getSimulator().getMaxX()){
this.movewolf=getLocationX()-1;
setLocationX(movewolf);
}
else if(getLocationX()==0){
this.movewolf=getLocationX()+1;
setLocationX(movewolf);
}
else if (getLocationY()==getSimulator().getMaxY()){
this.movewolf=getLocationY()-1;
setLocationY(movewolf);
}
else if (getLocationY()==0){
this.movewolf=getLocationY()+1;
setLocationY(movewolf);
}
else {
}
}
}
** Class**
public class extends Animal{
private int movemoose;
public Moose(Simulator simulator){
super(simulator);
}
#Override
public void eat(){
setEnergy((getEnergy()+getSimulator().getEnergyGainFromEatingGrass()));
}
#Override
public Animal reproduce(){
Moose moose=new Moose(getSimulator());
moose.setLocationX(getSimulator().randomInt(getSimulator().getMaxX()));
moose.setLocationY(getSimulator().randomInt(getSimulator().getMaxY()));
moose.setEnergy(getSimulator().getInitialEnergy());
return moose;
}
#Override
public Animal die(){
return null;
}
#Override
public void move(){
int moveX=(int)(Math.random()*2);
int moveY=(int)(Math.random()*2);
if (getLocationX()<getSimulator().getMaxX()&& getLocationX()>0 && getLocationY()<getSimulator().getMaxY()&& getLocationY()>0){
if (moveX==1){
this.movemoose=getLocationX()+1;
setLocationX(movemoose);
}
else{
this.movemoose=getLocationX()-1;
setLocationX(movemoose);
}
if (moveY==1){
this.movemoose=getLocationY()+1;
setLocationY(movemoose);
}
else{
this.movemoose=getLocationY()-1;
setLocationY(movemoose);
}
}
else if (getLocationX()==getSimulator().getMaxX()){
this.movemoose=getLocationX()-1;
setLocationX(movemoose);
}
else if(getLocationX()==0){
this.movemoose=getLocationX()+1;
setLocationX(movemoose);
}
else if (getLocationY()==getSimulator().getMaxY()){
this.movemoose=getLocationY()-1;
setLocationY(movemoose);
}
else if (getLocationY()==0){
this.movemoose=getLocationY()+1;
setLocationY(movemoose);
}
else {
}
}
}
** Class**
public class {
public Simulator getGrass(){
return grass;
}
public void setGrass(Simulator grass){
this.grass = grass;
}
public int getLength(){
return length;
}
public void setLength(int length){
this.length = length;
}
public int getInitialLength(){
return initialLength;
}
public void setInitialLength(int initialLength){
this.initialLength = initialLength;
}
public int getXcord(){
return Xcord;
}
public void setXcord(int xcord){
Xcord = xcord;
}
public int getYcord(){
return Ycord;
}
public void setYcord(int ycord){
Ycord = ycord;
}
private Simulator grass;
private int length;
private int initialLength=0;
private int Xcord;
private int Ycord;
public Grass(Simulator grass, int xcord, int ycord, int length){
this.grass = grass;
this.length = length;
Xcord = xcord;
Ycord = ycord;
setLength(initialLength);
}
}
I see a problem with the second line here:
for (int i=0;i<simulate.getMaxX();i++){
for (int j=0;i<simulate.getMaxY();j++){
I think it should be j<simulate.getMaxY()
I am not an expert on java and have run into an issue on my Snake Game. I have created a class called GameManager:
public class GameManager {
private GameObject board[][];
private int xR;
private int yR;
public Snake snk;
private Food food;
public GameManager (String fileName) {
BufferedReader fileInput = null;
try {
fileInput = new BufferedReader(new FileReader(fileName));
Scanner fileScanner = new Scanner(fileInput);
int rows = fileScanner.nextInt();
int cols = fileScanner.nextInt();
board = new GameObject[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
board[row][col] = new Empty();
}
}
while(fileScanner.hasNext()) {
fileScanner.nextLine();
int xStart = fileScanner.nextInt();
int yStart = fileScanner.nextInt();
int xEnd = fileScanner.nextInt();
int yEnd = fileScanner.nextInt();
addWall(xStart, yStart, xEnd, yEnd);
}
addGameObject(snk);
addGameObject(food);
fileScanner.close();
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(fileInput != null) {fileInput.close();}
} catch(IOException e) {
e.printStackTrace();
}
}
}
public void newRandomXY() {
Random r = new Random(0);
this.xR = r.nextInt(board.length);
this.yR = r.nextInt(board.length);
}
public void addGameObject(GameObject s) {
newRandomXY();
while(board[xR][yR].isOccupied()) {
newRandomXY();
}
if(s instanceof Snake) {
s = new Snake(xR, yR);
board[xR][yR] = s;
} else if(s instanceof Food) {
s = new Food(xR, yR);
board[xR][yR] = s;
}
}
public void addWall(int xStart, int yStart, int xEnd, int yEnd) {
for(int x = xStart; x <= xEnd; x++) {
for(int y = yStart; y <= yEnd; y++) {
board[x][y] = new Wall();
}
}
}
#Override
public String toString() {
String ret = "";
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
ret += board[row][col].toString();
}
ret += "\n";
}
return ret;
}
}
Now the issue I'm having is that whenever I try to print a string version of this board on my cmd, the program just hangs and I have to hard close the cmd. I have been messing around with some of the code and I have been able to fix the program just crashing, but I haven't been able to figure why its all not printing out.
Here is my Snake Class (Note: I also have some other methods in this class that I am not using at the moment, so I don't think they are the issue):
public class Snake extends GameObject {
private Point head;
private Deque<Point> snakeBody;
private int lenght = 0;
private String direction = "UP";
public Snake(int x, int y) {
this.head = super.newCell(x, y);
this.snakeBody = new ArrayDeque<Point>();
this.snakeBody.push(head);
}
and my toString of Snake:
public String toString(Deque<Point> s) {
String str = "";
for(Point p : s) {
String snk = p.toString();
snk = "S";
str += snk;
}
return str;
}
Here's my Food Class:
public class Food extends GameObject {
private Point foodLoc;
public Food(int x, int y) {
this.foodLoc = new Point(x, y);
}
public Point getLocation() {
return foodLoc.getLocation();
}
public String toString() {
return "F";
}
}
and here is my GameObject Class:
import java.awt.Point;
public class GameObject {
public final int CELL_SIZE = 1;
public Point newCell(int x, int y) {
return new Point(x, y);
}
public boolean isOccupied() {
return true;
}
public boolean isOccupied(Point p, Point o) {
boolean flag = false;
if(p.getLocation().equals(o.getLocation())) {
flag = true;
} else {
flag = false;
}
return flag;
}
}
I have a good feeling that my toString method in Snake is completely wrong, but I don't necessarily understand how to fix it and why my other toString methods don't work. I have looked around the forums to see if I could find and answer, but I couldn't find anything for this.
The problem is that you're trying to print an array of type gameObject, but that object does not have a .toString operator, so it's always going to return null.
I'm guessing that you want to represent the cells as either empty or occupied, or perhaps even further by having food, but you'd need a .toString in that class to define what you want returned in whatever given scenario.
I am working on a game that my friends invented - a little variation on tic tac toe: using a 4x4 board, one player (x) need to get 3 x's in a particular manner while the other can place one 'z' and one 'o' every turn and needs to fill the entire board. My problem is not with the rules and algoritems, but with the graphics: I don't have a lot of experience with graphics, and just can't get my board to work (even without any rules - just show up as needed).
I have a Board class that represents a board. A board has a two dimensional array of Cells. Each Cell (Cell = another class of mine) is also a JButton, and I would like that every time a button is clicked his image will change - so I decided to use ImageIcon. I also have a GameMain class to control the game and a Tools class to add two buttons - 'Exit' and 'Reset'.
If you could please help me by suggesting ways to get my board to load properly, I would appreciate that. Currently the board doesn't show up at all, and if I tweak the code a bit it shows up but the buttons won't show at all.
Here's the code: GameMain.java:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GameMain extends JPanel {
private Turn _turn;
Board _board;
private Tools _buttons;
private boolean isOver = false;
public enum GameState {PLAYING, xWON, oWON};
private GameState _currentState;
// Name-constants for the various dimensions used for graphics drawing
public static final int CELL_SIZE = 100; // cell width and height (square)
public static final int CANVAS_WIDTH = CELL_SIZE * 4; // the drawing canvas
public static final int CANVAS_HEIGHT = CELL_SIZE * 4;
public static final int GRID_WIDTH = 8; // Grid-line's width
public static final int GRID_WIDTH_HALF = GRID_WIDTH / 2; // Grid-line's half-width
public GameMain() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (_currentState == GameState.PLAYING) {
updateGame();
} else {
initGame(); //game over, restart
}
repaint();
}
});
setLayout(new BorderLayout());
setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT + 30));
_board = new Board();
_buttons = new Tools();
initGame();
_buttons.SetObject(_board);
add(_board, BorderLayout.CENTER);
add(_buttons, BorderLayout.SOUTH);
}
public void initGame() {
_turn = Turn.X;
_board.init();
_currentState = GameState.PLAYING;
}
public void updateGame() {
if (_board.hasWonX()) {
_currentState = GameState.xWON;
} else if (_board.hasWonO()) {
_currentState = GameState.oWON;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
_board.paint(g);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("xBlock");
frame.setSize(500, 500);
// Set the content-pane of the JFrame to an instance of main JPanel
frame.setContentPane(new GameMain());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null); // center the application window
frame.setVisible(true); // show it
}
});
}
}
Board:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
private Cell[][] _cells;
private Turn _turn;
public Board() {
setLayout(new GridLayout(4, 4));
_cells = new Cell[4][4];
_turn = Turn.X;
for (int i = 0; i < _cells.length; i++) {
for (int j = 0; j < _cells[0].length; j++) {
_cells[i][j] = new Cell(i, j);
_cells[i][j].addActionListener(this);
add(_cells[i][j]);
}
}
}
//initiate board
public void init() {
_turn = Turn.X;
for (int i = 0; i < _cells.length; i++) {
for (int j = 0; j < _cells[0].length; j++) {
_cells[i][j].setState(State.EMPTY);
}
}
}
public void fillCell(Cell c) {
if (c.getState() == State.EMPTY) {
c.setState(_turn.ordinal());
c.setEnabled(false);
c.draw();
_turn = _turn.getNext();
}
}
public void checkCellsAround(Cell c) {
State state = c.getState();
State right, left, up, down;
if (c.getJ() < 3 && c.getJ() > 0) {
right = _cells[c.getI()][c.getJ() + 1].getState();
left = _cells[c.getI()][c.getJ() - 1].getState();
} else if (c.getJ() == 0) {
right = _cells[c.getI()][c.getJ() + 1].getState();
left = State.EMPTY;
} else {
right = State.EMPTY;
left = _cells[c.getI()][c.getJ() - 1].getState();
}
if (c.getI() < 3 && c.getI() > 0) {
up = _cells[c.getI() - 1][c.getJ()].getState();
down = _cells[c.getI() + 1][c.getJ()].getState();
} else if (c.getI() == 0) {
up = State.EMPTY;
down = _cells[c.getI() + 1][c.getJ()].getState();
} else {
up = _cells[c.getI() - 1][c.getJ()].getState();
down = State.EMPTY;
}
switch (state) {
case EMPTY:
break;
case X:
if ((left == State.O && right == State.O) || (up == State.O && down == State.O) || (left == State.Z && right == State.Z) || (up == State.Z && down == State.Z)) {
c.setState(State.HOURGLASS);
}
break;
case O:
if ((left == State.X && right == State.X) || (up == State.X && down == State.X)) {
c.setState(State.EMPTY);
}
break;
case Z:
if ((left == State.X && right == State.X) || (up == State.X && down == State.X)) {
c.setState(State.HOURGLASS);
}
break;
case HOURGLASS:
break;
case SCRIBBLE:
break;
}
}
public void actionPerformed(ActionEvent E) {
Cell c = (Cell) E.getSource();
fillCell(_cells[c.getI()][c.getJ()]);
}
public boolean hasWonO() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (_cells[i][j].getState() == State.EMPTY) {
return false;
}
}
}
return true;
}
public boolean hasWonX() {
return false;
}
public void paint(Graphics g) {
g.setColor(Color.GRAY);
for (int i = 1; i < 4; i++) {
g.fillRoundRect(0, GameMain.CELL_SIZE * i - GameMain.GRID_WIDTH_HALF,
GameMain.CANVAS_WIDTH - 1, GameMain.GRID_WIDTH,
GameMain.GRID_WIDTH, GameMain.GRID_WIDTH);
}
for (int j = 1; j < 4; j++) {
g.fillRoundRect(GameMain.CELL_SIZE * j - GameMain.GRID_WIDTH_HALF, 0,
GameMain.GRID_WIDTH, GameMain.CANVAS_HEIGHT - 1,
GameMain.GRID_WIDTH, GameMain.GRID_WIDTH);
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
_cells[i][j].draw();
}
}
}
}
Cell.java:
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class Cell extends JButton {
private int _i, _j;
private State _state;
ImageIcon X = new ImageIcon(this.getClass().getResource("x-icon.png"));
ImageIcon O = new ImageIcon(this.getClass().getResource("o-icon.png"));
ImageIcon Z = new ImageIcon(this.getClass().getResource("z-icon.png"));
ImageIcon Hourglass = new ImageIcon(this.getClass().getResource("hourglass-icon.png"));
ImageIcon Scribble = new ImageIcon(this.getClass().getResource("scribble-icon.png"));
public Cell() {
this.setEnabled(true);
_i = 0;
_j = 0;
_state = State.EMPTY;
}
public Cell(int i, int j) {
this.setEnabled(true);
_i = i;
_j = j;
_state = State.EMPTY;
}
public int getI() {
return _i;
}
public int getJ() {
return _j;
}
public void setState(State state) {
_state = state;
if (state == State.EMPTY) {
this.setEnabled(true);
}
}
public void setState(int index) {
_state = State.values()[index];
}
public State getState() {
return _state;
}
public void draw() {
switch (_state) {
case EMPTY:
this.setIcon(null);
break;
case X:
this.setIcon(X);
break;
case O:
this.setIcon(X);
break;
case Z:
this.setIcon(X);
break;
case HOURGLASS:
this.setIcon(X);
break;
case SCRIBBLE:
this.setIcon(X);
break;
}
}
public void highlight() {
}
}
Tools.java:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Tools extends JPanel {
private JButton _exit, _reset;
private Board _board;
Tools() {
setLayout(new FlowLayout());
_exit = new JButton("Exit");
_reset = new JButton("Reset");
_exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
_reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
_board.init();
}
});
add(_exit);
add(_reset);
}
public void SetObject(Board b) {
_board = b;
}
}
State.java:
public enum State {
EMPTY, X, O, Z, HOURGLASS, SCRIBBLE;
public State getNext() {
return State.values()[(this.ordinal() + 1) % State.values().length];
}
}
Turn.java:
public enum Turn {
X, O, Z;
public Turn getNext() {
return Turn.values()[(this.ordinal() + 1) % Turn.values().length];
}
}
Thanks in advance!
So after running it, you are getting an ArrayIndexOutOfBoundsException at this line in the paint method of the Board class:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
_cells[i][j].draw(); <==========
}
}
Not sure how your game works, but by looking at the loops previous to this one, you are accessing only up to index 3 ( for (int j = 1; j < 4; j++) { ). So if you change the loop max to 4, it gets the game up and running.
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
_cells[i][j].draw();
}
}
Learning to read exceptions and stack traces is very important. It will save you a lot of future headaches. Take some time to read What is a stack trace, and how can I use it to debug my application errors?
And like I said in my comments,
It doesn't look like you're doing anything with the paintComponent in the GameMain. You should just get rid of the paintComponent method altogether in that class. Instead of trying to call board.paint(g);, try to just call board.repaint() in the mouse listener, instead of trying to repaint the main game panel. And just set the background in the constructor of the GameMain instead of in the paintComponent method.
Also in the Board class use paintComponent rather than paint. and don't forget to call super.paintComponent in the paintComponent method
Fixing all the things above, get it work (I guess).
UPDATE
As the MadMan pointed out in the comment below, it would be better to use the _cells.length to avoid having to rely magic numbers. This way you will be sure not to access an inexistant index
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
_cells[i][j].draw();
}
}
First of all there is a lot of code because i really don't know where my issue is, I do apologise!
I'm making a program that solves a varying size puzzle for eg (3x3 with 0-8) The zero represents a blank tile the objective is to move the the blank tile around until the goal state is reached. At the moment I am using Depth First Search to solve the puzzle. Netbeans returns a 'OutOfMemory' error when i run the program however if I change the goal state so it only requires one move to complete it displays the solution. Below is my code, I've only added some of the classes because I don't want this post being ridiculously long. Please let me know if you require the other classes
EDIT: Inserted wrong code for board class
Depth First Search Class
package npuzzle;
import java.util.ArrayList;
import java.util.Stack;
public class DFSearch {
public static void search(int[][] initial, int[][] goal, int rows, int columns)
{
Board board = new Board(initial, goal, rows, columns, "");
Node root = new Node(board);
Stack<Node> stack = new Stack<Node>();
stack.add(root);
performSearch(stack, board);
}
public static void performSearch(Stack<Node> s, Board board)
{
int searchCount = 1;
while (!s.isEmpty())
{
Node tNode = (Node) s.pop();
//if not goal state
if (!tNode.getCurrentState().isGoalState())
{
ArrayList<State> tChildren = tNode.getCurrentState().gChildren();
for (int i = 0; i < tChildren.size(); i++)
{
Node newNode = new Node(tNode, tChildren.get(i), tNode.getGCost() + tChildren.get(i).findCost(), 0);
if(!isRepeatedState(newNode))
{
s.add(newNode);
}
}
searchCount++;
}
else
{
tNode.getCurrentState().printState();
System.exit(0);
//PRINTING OF DIRECTIONS
}
}
System.out.println("Error! No solution found!");
}
private static boolean isRepeatedState(Node c)
{
boolean returnVal = false;
Node checkNode = c;
while(c.getParent() != null && !returnVal)
{
if (c.getParent().getCurrentState().equals(checkNode.getCurrentState()))
{
returnVal = true;
}
c = c.getParent();
}
return returnVal;
}
}
Board Class
package npuzzle;
import java.util.ArrayList;
import java.util.Arrays;
public class Board implements State
{
private int PUZZLE_SIZE = 0;
private int outOfPlace = 0;
private int rows;
private int columns;
private int[][] GOAL;
private int[][] currentBoard;
private String directions = "";
public Board(int[][] initial, int[][] goal, int N, int M, String direction)
{
currentBoard = initial;
GOAL = goal;
rows = N;
columns = M;
PUZZLE_SIZE = rows*columns;
directions = direction;
setOutOfPlace();
}
#Override
public boolean isGoalState() {
if (Arrays.deepEquals(currentBoard, GOAL))
{
return true;
}
return false;
}
#Override
public ArrayList<State> gChildren() {
ArrayList<State> children = new ArrayList<State>();
int[] blanktile = getBlankTile();
int[] newblanktile = Arrays.copyOf(blanktile, blanktile.length);
if (blanktile[0] != 0) {
newblanktile[0]--;
Swap(newblanktile, blanktile, children, "up");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != 0) {
newblanktile[1]--;
Swap(newblanktile, blanktile, children, "left");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[0] != (this.rows - 1)) {
newblanktile[0]++;
Swap(newblanktile, blanktile, children, "down");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != (this.columns - 1)) {
newblanktile[1]++;
Swap(newblanktile, blanktile, children, "right");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
return children;
}
#Override
public double findCost() {
return 1;
}
#Override
public void printState() {
System.out.println(directions);
}
#Override
public boolean equals(State s) {
if (Arrays.deepEquals(currentBoard, ((Board) s).getCurrentBoard()))
{
return true;
}
else
return false;
}
private void setOutOfPlace() {
int i = 0;
int j = -1;
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] != GOAL[i][j])
{
outOfPlace++;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
}
private int[] getBlankTile()
{
int i = 0;
int j = -1;
int[] blanktile = {0,0};
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] == 0) {
blanktile[0] = i;
blanktile[1] = j;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
return blanktile;
}
public int getOutOfPlace()
{
return outOfPlace;
}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
public int getPUZZLE_SIZE() {
return PUZZLE_SIZE;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
public int[][] getGOAL() {
return GOAL;
}
public int[][] getCurrentBoard()
{
return currentBoard;
}
public String getDirections()
{
return directions;
}
}