this is a problem that I've been really struggling with
I need to create a game for some University coursework. The game is basically a 4x4 grid. When i click a button, the player should move randomly within 1 square of it's location.
There's enemy spaceships that are generated randomly over the grid, and if the player lands on the spaceship, it destroys it. if there's two enemy ships on the same sqaure and the player lands on that square, the player is destroyed.
I've created a GIU using gridlayout and the button that I need to move the player, but I'm having problems trying to figure out how to actually use the grid. I've created an element class to create objects for the grid (ie, a list of enemy ships), but I don't know how to use this class with my gridlayout. I know I also have to redraw the grid after each move to reflect the changes, but I don't know if I would need to create a custom redraw method for this.
Any push in the correct direction so I can get my program actually doing something would be really helpful.
Some time ago I created a card game that also operated based on a GridLayout. Below is some of the code that was used to drive major events:
CardPanel extends JPanel {
public CardPanel() {
setLayout(gridLayout);
placeCards(N);
chatBoxText = new JTextArea(5, 30);
}
public void placeCards(int numCards) {
for (int i = 0; i < numCards; i++) {
Card card = deck.distributeCard();
String cardImageName = card.getImageName();
JLabel jLabel = makeImage(cardImageName);
cardSet.add(new GraphicCard(card, jLabel));
add(jLabel);
jLabel.addMouseListener(this);
}
if (GameLogic.noSetsOnBoard(cardSet)) {
gridLayout.setRows(gridLayout.getRows() + 1);
placeCards(3);
}
}
public void updateCard(Integer location) {
Card card = deck.distributeCard();
String cardImageName = card.getImageName();
JLabel jLabel = makeImage(cardImageName);
cardSet.set(location, new GraphicCard(card, jLabel));
jLabel.addMouseListener(this);
}
}
The CardPanel here is an object that represents the GridLayout (you see the constructor) as well as some of those helper methods.
Further on, on particular actions, I have the following code:
cardPanel.removeAll();
// Some other logic here
for (GraphicCard card: cardSet) {
cardPanel.add(card.getJLabel());
}
cardPanel.revalidate();
cardPanel.repaint();
In short, yes, it is custom, but it is not difficult. There are better ways to do it than the above such that you do not need to empty the entire panel in order to refresh it, the logic I have omitted above merited this particular solution.
The approach I used kept track of a CardPanel object which was an abstraction that contained not only the information that each box represented (in my case a card with some values), but also the graphic element to be rendered.
This was some time ago, so I don't recall the exact details but hopefully this is helpful.
I am currently making a TicTacToe program for an assignment in college. I have my board laid out with 3x3 JTextFields, each one has an action listener attached. What I need to do is create another class which will check for errors (eg a user will put a number or a letter that is NOT x or o) they should get a dialog box stating the error and the JTextField they tried to enter will return to blank. How would I go about implementing the error checking, through try - catch - finally method?
Another question, I have a GameGUI class, I also want to have a GameLogic class. How do I check from GameLogic if the game has been won? In my GameLogic I will have something like
if j1, j2 and j3 are all x or o then display dialog box "x player wins".
I will try to answer the question regarding a general board game. Your object oriented thinking of splitting into different classes is correct. What I do generally is that I have the GameLogic containing my logic and validations for the game as well as determining whether the game is over or not and so on.
The GameGUI class would then have an instance variable of the type GameLogic that's initialized on creating an object of type GameGUI. In my way of thinking, I would have the GameLogic representing the board state with 2D Array of chars. The GameGUI would be just there to relay input from the user to the GameLogic which determines if the game is over. The GameLogic should throw an Exception of the type that you want to clarify and then the GameGUI should try to update the board with the input text from the user in the JText fields, catch the error from the GameLogic (if any) and then repaint the GUI that's displayed to the user based on the input it got. I will give a sample below to clarify my point although I won't provide the actual implementation for the TicTacToe game, you can easily do it on your own.
public class GameLogic {
....
char[][]board;
public GameLogic() {
//initialize the board representation for game
}
public boolean gameOver() {
//determine if the game is over by checking the board 2D array
// 3 xs or os in a row, column, or diagonal should determine the game is over or if there are no more moves
}
public void move(char character, int x, int y) {
//update a certain position with a character should throw an Exception if the character is invalid or if the the character is valid but it's not the character that the user owns player1 plays with x for example but puts o.
//should also have the logic for the turns
}
...
}
public class GameGUI {
.....
GameLogic engine;
public GameGUI() {
engine = new GameLogic();
}
public void actionPerformed(ActionEvent e) {
// here you would get the co-ordinates of the clicked JTextButton
// then call the method move on the engine instance
try {
engine.move(character, x, y);
} catch(Exception e) {
//display the validation for the error that happened
}
//repaint the representation from the engine to be displayed on the GUI Frame that you are using
}
...
}
One more thing is that I would have declared the JTextFields as 2D Array of JTextFields and not as individual instance variables to mirror the representation in the GameLogic class. You can also avoid the validations all together if you use JButton class instead of JTextField and that the user gets the character he is playing with on the clicked button if it is his turn and the button is not already used before.
OK, I'm in the process of making a simple java swing chess game. This question is more about OOP design then Java Swing.
I have the following:
I have a Panel class that implements JPanel.
I then have an abstract class Piece that extends from my Panel class
Then I have my classes for the different Pieces: Pawn, King, Bishop etc that extend from my Pieces class
In my main ChessGame Class:
I am using an array of Panel to store the layout of my board
So the array will store, Panel objects, for board places with no pieces on it.
And it will store, the subclasses such as Pawn, Queen, Bishop etc (board places with pieces)
So, the top left square (0,0) maps to myArray[0][0]
My problem is that, to check if the place is empty or has chess pieces in it I have to use:
if(panels[x][y] instanceof Piece){
((Piece)panels[x][y]).makeMove();
}
What I'm asking is this terrible design? I know I should try and stay away from instanceof.
What would be a better approach?
Thanks.
You shouldn't combine the Model code (Piece) with the view code (JPanels). If you ever want to change how the board is displayed you have to change how pieces are stored!
A better design might be to separate Piece from JPanels. Then you can use a single JPanel to display a matrix of Pieces : Pieces[8][8].
My problem is that, to check if the place is empty or has chess pieces in it I have to use:
If you use a matrix, you can just have a null cell or use the Null Object Pattern to have an "empty" piece.
EDIT
Each cell in the piece matrix is a square in the board so piece[0][0] would be the top corner of the board (A8).
To paint the board your paintComponent() method would have to iterate over this matrix and draw each cell appropriately. There are several ways to implement this:
You would need to do a similar instanceof check to draw each type of piece differently
Make a new intermediate "paint strategy" object using the strategy pattern. This may require a matrix of strategy objects instead of piece objects. You may still need to do instance of checks, but maybe only the once to create the strategy objects.
After considering your problem, and knowing the problem domain, I would actually suggest the following...
In your class Panel implement a function int hasMass() as follows...
public int hasMass() {
return 0;
}
In your class Piece override that function as follows...
public int hasMass() {
if (isWhite()) // white pieces are negative.
return -1;
return 1; // black pieces positive.
}
Now you can check if the square has a piece, whether another given piece could take it... (because they have opposite polarity)... e.g. mass + mass == 0 means a capture, != 0 means the panel was empty. And of course an absolute value of 2 (for mass) would mean the move was illegal.
OK, ill start by throwing away the option of setting null to indicate that place is empty (you can do it ofc but using the Empty class is just 'better' in a way).
So let's say you have array of Panels representing your game board:
Panel[][] board;
Now for ilustration, how your class hierarchy could look like:
abstract class Panel extends JPanel { ... }
class Empty extends Panel { ... }
abstract class Piece extends Panel { ... }
class Pawn extends Piece { ... }
...
My Panel class is my Empty class is it not?
Not sure if i understand you, but let's have a look on what extends means exactly: in the show nmodel every Piece is also a Panel or every Pawn is also a Piece, so every Pawn can do all the same things as Piece (for example, 4 is complex number as well as natural number or real number, so in a way, you could say that real numbers extend complex numbers, since every real number is also a complex number)
So now you can have some nice abstract getTexture() method declared in Panel implemenented in Empty class and in all Piece subclasses, and when drawing a Panel, you dont need to look if it is empty or not.
Instead of creating (I assume) almost identical classes for each piece (Rook, Pawn, Queen etc.), you could just keep the original Piece class, make it non abstract and add a PieceType field to it. PieceType is just an enum that tells what type of piece (if any) is placed there. Instead of using instanceof, now you can check using panels[i][j].getType() == PieceType.ROOK. At least that's what I'm doing in my implementation :)
I'm also using JLabel instead of JPanel for my 8x8 board.
Instead of splitting panel to 8x8 smaller panels, you must draw the board and the pieces on a canvas. Later the players will eventually be dragging to move pieces on board. Also you could look for Bitboard presentation in chess game, although this presentation is only required for chess engines which are able to "think" for fast calculations, it is still useful when you have to check if the move that player is trying to make is correct.
Posible Bitboard:
public class BitBoard
{
public static final int P = 0;
public static final int N = 2;
public static final int B = 4;
public static final int R = 6;
public static final int Q = 8;
public static final int K = 10;
public static final int p = 1;
public static final int n = 3;
public static final int b = 5;
public static final int r = 7;
public static final int q = 9;
public static final int k = 11;
// empty field
public static final int empty = 12;
// number of pieces , squares
public static final int nPieces = 12;
public static final int nSquares = 64;
public static final int whitePieces = 12;
public static final int blackPieces = 13;
public static final int nBoards = 14;
public static long squareBits[];
// static member initialization
static
{
squareBits = new long[64];
long square = 1;
square = square << 8 * 8 - 1;
for (int i = 0; i < 64; i++) {
squareBits[i] = square >>> i;
}
}
long bitBoards[];
public BitBoard() {
bitBoards = new long[nBoards];
}
public boolean initBoard()
{
// Put the pieces on the board
EmptyBoard();
addPiece(0, r);
addPiece(1, n);
addPiece(2, b);
addPiece(3, q);
addPiece(4, k);
addPiece(5, b);
addPiece(6, n);
addPiece(7, r);
for (int i = 8; i < 16; i++) {
addPiece(i, p);
}
for (int i = 48; i < 56; i++) {
addPiece(i, P);
}
addPiece(56, R);
addPiece(57, N);
addPiece(58, B);
addPiece(59, Q);
addPiece(60, K);
addPiece(61, B);
addPiece(62, N);
addPiece(63, R);
return true;
}
public boolean addPiece(int whichSquare, int whichPiece)
{
bitBoards[whichPiece] |= squareBits[whichSquare];
bitBoards[nPieces + (whichPiece % 2)] |= squareBits[whichSquare];
return true;
}
private boolean removePiece(int whichSquare, int whichPiece)
{
bitBoards[whichPiece] ^= squareBits[whichSquare];
bitBoards[nPieces + (whichPiece % 2)] ^= squareBits[whichSquare];
return true;
}
private boolean EmptyBoard()
{
for (int i = 0; i < nBoards; i++)
{
bitBoards[i] = 0;
}
return true;
}
}
I would keep a structure of the pieces separate from the rendered board.
For example, I would make the chess pieces pure models w/o knowledge of hit they're rendered.
Pieces (baseclass)
+- Pawn
+- Knight
+- King
+- Queen
+- ..etc
This will allow you to keep an array of Pieces only, where empty squares are null.
For simplicity sake, I'd just have a matrix of peices:
Peices[][] board = new Pieces[8][8];
(of course an initialization method to traverse your 'board' and populate the board w/ the initial positions)
I would then have a visible board constructed of JPanels; a class called "Chess" to manage game; and the actual rendering of the tile/panel in the move function. Imagine:
// what a move might look like when initializing your panels
piece = board [0][0];
Chess.move(piece, 0 ,0); //responsible for clearing the old panel and rendering the panel at target location.
When the user interacts w/ your game..they click your panels..which will give you the panel coordinates. You use the same coordinates w/ your 'board' to determine what the piece is..how it can move etc..
Something like that...
I would just represent the game board using objects...for simplicity. Easiest to understand..and besides..computers are plenty fast now.
For my group project we are doing a fairly standard Hangman GUI game.
I have created a series of .png files depicting a flower that wilts as the game progresses with wrong guesses.
I have got the code to insert the ImageIcon into a JLabel, and that works fine. But I don't know how to code for the image changing when a wrong answer is guessed.
I am thinking I should create an array of the series of images and iterate through it according to the guessesLeft variable that keeps track of the number of guesses a user still has to correctly guess the puzzle.
Any ideas?
I'd recommend you to link each image to the number of guesses.
Then make method updateScore that will update user score (or guesses left) and work with images. Something like:
public class ImagedScore {
private final int guessesLeft;
private final Image image;
//getters&constructor
}
public class MainClass {
ImagedScore[] imagedScoreArray;
//constructors, other methods and data, etc.
updateScore(int score) {
ImagedScore imagedScore = imagedScoreArray[score];
//checks or other way to find proper ImagedScore object
this.score = score;
this.image = imagedScore.getImage;
}
}
I have a grid that is declared like:
PlayerStatus enum
{
OCCUPIED,
VACANT
}
PlayerStatus[][] grid_ = new PlayerStatus[200][200];
The grid is set equal to all vacant except where players located at.
I would like to have a method that tells me if a player is in a certain grid proximity of another player, something like:
boolean inRange(int x, int y, int range)
{
//This method finds if a player is close to another one
}
So if I pass into inRange(10, 15, 5) and at 10, 19 there is a player I would like the method to return true; where as 10, 21 would return false.
Are there any algorithms that do this kind of searching that I could look into? Or does anyone have any solutions? I feel that calculating diagonals and such will be rather hard, what should I do for that? Any help is appreciated.
Math.hypot() is a good choice for implementing the Pythagorean theorem. There's an example here named norm(), which is used in this KineticModel.