I am currently creating a chess game consisting of the following classes:
ChessPiece - For all the various chess pieces, composed with a MovementBehaviour instance variable
MovementBehaviour - Interface implemented by PawnMovementBehaviour,
KingMovementBehaviour etc classes to define
how each piece type moves
ChessBoard - Consisting of a ChessPiece[][] 2D array with functionality like addPiece()/removePiece()/replacePiece() etc
Player - Small class helps associate which pieces belong to which human player
Game - The main class essentially which will begin by asking players for their names and desired piece colors and then running the
game by instantiating a ChessBoard and letting players move turn by
turn until checkmate is reached.
I was wondering if I should be using a Singleton pattern (With regards to the ChessBoard class) ? Currently I am not and I am passing the instance of the ChessBoard into the chess pieces movement functionality so that the piece can understand its surroundings. This is because of course moves are deemed legal depending on what spaces are occupied/empty on the board at any time.
Singletons are very rarely a good idea. I happen to have started a similar project recently so I will answer this from my current experience.
The way I've implemented it is by considering a chessboard a collection of Location objects, where a location holds an X-value, Y-value and a Piece object. Only relevant places are filled in where empty ones aren't even tracked.
You seem to be wondering if you should use a singleton for the single purpose of validation. There are many, many things you have to validate when a move is done: Can you move that way? Are you check? Is it en-passant? Is it a rochade? etc.
What you could do is create a bunch of validate methods that take as arguments a chessboard and the start- and endlocation. This way you have all information required to check if the move is valid. This does require the pieces to know their own properties: how can I move? What's my color?
When you have all this, you can implement the different validation logic to make a move.
Using a singleton will be rather nasty when you could just extract the validation and pass the chessboard around. It would also be much harder to test (and good testing is definitely something you want in a chessgame).
My setup looks like this:
Chessboard.CanMoveToLocation(int startX, int startY, int endX, int endY) {
// Call validators with local field chessboard and given location objects
}
Each validator will return a custom enum ValidationResult to indicate if it's allowed or forbidden for this particular validator.
You'll have to make sure the validators are called in the correct order (returning false after checking if it's a valid move is not a good idea: he might have been rochading or slaying en-passant). Or you could ofcourse combine related validators.
Should you wish to take a look: my current (far from finished) implementation.
In my experience, I'd rather use Observer Pattern in this case.
The ChessBoard class plays the role of Observer and the ChessPiece which should be an abstract class is the Subject class. You might want to make a look on Observer Pattern and it usage
When you take one Piece and make a movement, that means the location of that Piece has been changed and the Piece will notify to the board to check the movement whether it is valid or not.
Related
Making a minesweeper app and I have a GameGrid class to hold all the squares in a multidimensional arraylist of squares, and it handles initializing the squares along with determining where the mines will be. The Square class has variables for its position (x and y), and a variable hasMine. Now, due to some circumstances arising, I have needed to pass a GameGrid instance into the constructor of Square because I needed to access a method inside GameGrid. My question is, is this good design? For some reason, the fact that I'm passing a GameGrid instance into a Square just doesn't feel right.
I've tried to experiment with an Observer/Observable type pattern with unfortunately no luck. Another option would be to make GameGrid a singleton, just not sure if that's the best option here.
I bet a similar situation like this has probably come up before, just wondering what the best solution would be.
Edit:
Decided to clear a few things up and clarify the actual problem I'm running into.
So each square is responsible for changing its own icon when it's clicked (when it's flipped over). The problem arises when I want to implement the O-fill behavior when a zero is clicked (this concept is easy if you're familiar with minesweeper). When a zero is clicked on, all the zeroes around will automatically be flipped over. I need to use GameGrid for this and not Square because Square doesn't have access to all the squares around it.
But since a few comments have been posted and I've done a little research, I've figured out that I think I'll either just keep it as it is, and pass in the desired GameGrid instance into Square, or I'll try to work with a custom observer/observable like pattern where the updated argument (normally from notifyObservers(Object arg)) will be a custom Class that I can use to hold all the required information needed.
Say there is a simple game where I have a class called Player, which holds all the information that a player would have, e.g. name, xPosition, yPosition, width, height, etc.
The Player class has also has methods associated with it that describe what a Player can do, e.g. move(), draw(), etc.
In the game, I need to be able to know when a Player collides with any other object in the game like a wall, ceiling or other world object.
I can go about this in 2 ways:
Create a class like CollisionDetecter that has a method like detectCollision(). Include an instance of this class in the Player class and call the detectCollision() method when appropriate
Rationale:
Detecting collisions isn't really an intrinsic property of a Player like it's xPosition, yPosition or name is, so it doesn't belong in this class.
Less clutter in the Player class. (Does this count?)
Create a method like detectCollision() in the Player class which checks to see if the Player has hit anything
Rationale:
Detecting collisions is something that a Player does so the detectCollision() method should be directly in the Player class.
Only Players need to be able to detect collisions, so why should I create another whole class with just 1 method for this? Why not just include it as a method in the Player class?
I feel like I'm always struggling with debates like this.
Which method is the most appropriate and why? Are both of these bad and should I be doing something else?
In General :-
Sometimes, its better to start with it on the player class and see what the consequences are. Refactoring is ultimately your friend, if you see that the method you are writing is needing things not really related to Player, then you start working out a new design.
In Specific :-
Perhaps Player is a GameObject, and Collision Detection is a Generic concept that determines collisions between game objects.
Perhaps a player is not really a class, perhaps Player is just a GameObject with a Movement Strategy, ie Player really is composed of more fundamental aspects of a game.
Can someone help me build a chess game from the scratch using Java OOPS and Design patterns concepts.
A rough model is enough.
Are there any links/blogs for this?
First of all, this is a very broad question.
Second, Object Oriented approaches are somewhat slow, which will decrease the engines play strength.
That said, here is roughly what you need:
- a piece class, or an enum, or something similar
a chessboard class, where you can place and move pieces
a move generator, this is a function that lists all legal moves of a chessboard
an evaluation function that "rates" chesspositions, wheter black or white has an advantage
a minimax function, (see google "minimax algorithm"), that returns the best move in a position
some kind of gui for the whole thing
For more info, see the chessprogramming wiki.
I would have a class for the games map, a class for a figure (and childclasses for tower, king aso.). Also probably a class for the player.
I don't know exactly how to design a project. It's my first year at my computer science department. I'm still learning a lot of information about Java, such as inheritance, polymorphism, abstract classes, interfaces, and so on. I am really curious about these lectures and I'm willing to learn them well. Actually I've not missed any point in these lectures and I got those very well. But nobody teach me how to desing a project and we are supposed to design a decent Java project at the very end of school.
I and my 3 classmates have decided to make a new game. It is played with only one ball and the ball has changeable two colours. Also two players have the same colour with this ball's colours. When the ball is at one player's colour, this player will be able to move the ball and try to score to another player's goal. These are our idea's basic logic and we can add some new facilities and options for this game. We are so willing to achieve this project. But... although we listen and learn from our lectures, we are really confused about to design this project step-by-step. I've just tried to demonstrate our project's logic. Meanwhile, we are still learning about GUI but we are at the very beginning of GUI. So I want to understand about what kind of ways we have to follow in order to design and make this kind of project. I just want to know about tricks and shortcuts and make the most of our knowledge about class hierachies, abstract classes, superclasses, overriding, etc.(We know everything about this terms but just don't know how to use them to design a project). If you can indicate even a little info about these, I would be so so so happy and able to change my point of view. And it would facilitate our progress. Thank you!
You might want to have a look at this Java Pong Game - it's pretty simple and includes some source code that you can study.
More general advice:
You need some way to display what is happening in the game. Probably the easiest way to display the screen in a very simple game is to use a JPanel and override it's paintComponent() method to draw the game screen correctly (e.g. draw players at the right x,y locations)
You will also need a game loop that should do the following things:
Reads any input from players
Update the positions of the objects in the game
call repaint() on the JPanel so that the screen gets redrawn
Waits a short amount of time using e.g. Thread.sleep(30) to sleep for 30 milliseconds
Loops back to the start of the game loop
I would recommend separating the classes that define the user interface (frames, panels etc.) from classes that define the game logic (players, balls etc.). Ideally the game logic classes shouldn't contain any code that relates to how they are displayed or interacted with.
For a game this simple, you don't actually need many classes. I'd recommend something like:
App - contains the main(...) function which launches the game. At a minimum it should create a JFrame and add a single GamePanel inside it, but you can create other UI elements if you like. You may choose to implement your game loop also in this class - in which case the main method should call this once all the setup has been done.
GamePanel (which extends JPanel) - contains the screen drawing logic, also perhaps detects mouse movement
Game - class that represents the entire state of the game, including the locations of both players and the ball
Player - small class to represent the player, with x,y co-ordinates
Ball - small class to represent the ball, with x,y co-ordinates and dx,dy velocity
GUI isn't really suitable for making a game.
a GUI (Graphical User Intreface, Swing in java) is a set of buttons and other text/image content, as opposed to something you can make a game with: a 3D rendering engine, such as OpenGL (most commonly used on java, be it in a framework or through low level libraries).
You here have a choice:
you can either decide to do a simpler project, for example a console program, but that will run on a GUI, for example a GUI program to move files.
or you can get to learning OpenGL or similar (JOGL for java) and make that game!
(JavaFX also might work, but I don't know much about it)
Now about design.
Generally you want to have a main "looping" class that will output every frame etc.
The main "looping" class should inherit from an interface that allows all other components to get the rendering particle, the time counter etc.
Then you want several components, one for the ball, one for any other physics object (don't forget to make them implement a "physics" interface and add them as "physical object references" in your main class, so that the physics for them are calculated each frame!), one for the background, and one for user input.
You can also add multiple others that will each do a specific action.
EDIT: i just deleted the entire post and reformulated the question to be more generic.
I want to do a simple strategy game: map, units.
Map: one class. Units: another class, self drawn.
Simple questions:
How does an unit should redraw itself on the map.
A unit should be a JPanel or similar Swing component (just to be able to manage them as an entity with its own mousehandlers) or can be another thing, without neglecting the fact that it should be an autonomous object with its own action handlers and fields.
Is this map-units model correct of a simple game that would help me to learn in a fun way Java and OOP fundamentals.
Thats it!
There are 2 ways.
Either have a Map class which is the main JPanel, to maintain the collection of units, but keep the Unit class as non-Swing. When the Map's paint() method is called, ask each Unit to redraw itself by calling a method in each visible Unit. The Unit could be inherited from any base class, for example Rectangle, or some other data structure you use in the program. In this case, the Unit class handles painting and calculations, but the Map handles the clicks and events for each Unit. It could pass the message on to the Unit if needed; however, if the unit itself doesn't need to know about these things, this method works well. The Unit class is light and economical. You can also decide whether the Unit knows its position in the Map or not.
Or have each unit as a JComponent, and handle its own events separately. The disadvantage is that each instance of a Unit creates a pile of data for drawing it as well. So if you have hundreds of units, only a couple of which are drawn, this way is not efficient. The advantage is each unit can handle its own GUI events without translation etc. This assumes also a 1:1 mapping of actual units in the game and graphical units on the screen. Also it is trickier to implement certain event handlers in the Unit, if a Unit needs to know about what other Units are around!
A third and arguably better way is to have a purely data Unit class, containing the game information about the unit, as in (1), but which has a method to create the JComponent when needed. The JComponent could, for example, be an inner class in the Unit - it could then access the Unit data. This is great if a unit may need to be displayed in 2 places (e.g. on 2 screens or views).
--
Addendum to address comments
That is correct, in (1) the Map (main JPanel) implements the mouse handler, and asks each unit in turn if it is 'hit'. This allows you to do more complex things, such as have 2 units overlapping/on top of each other, and both could respond to the click.
Also, for example, they may not be rectangular, or may be drawn with an alpha channel (if the Units were JComponents, they will by default grab any mouse event over their whole rectangle, to themselves). If your units don't overlap and are in their own rectangles, then JComponent's own mouse handler is enough.
If you use approach (1), the Map can ask each unit whether it contains a clicked point, and the Map can then handle the 'selection' process. Remember, a unit on its own won't be able to work out what other units are selected - selection may involve deselecting another unit. In that case, the selection operation is really a Map operation, not a Unit operation, although it may change the appearance or function of the Unit as well.
If you use separate JComponents for the Units, you can override contains(Point) to determine if the mouse hits the item, but this won't let other Units also respond to the click. But each Unit could 'select itself' (set a flag used when drawing) then notify the Map (it will need to find it using getParent or by a preset property).
Key things you need to know before deciding on this design would be:
Will you ever need more than one 'Map' panel per game?
Will you ever need more Unit objects than are to be displayed?
Will you ever need to display a Unit more than once?
If the answers are yes, you should separate the 'Data' classes from the 'View' classes, as suggested in 3.
then: What does a Unit need to 'do' and what does it need to know about the Map and other Units in order to do this? e.g. moving is usually done by the Map class in this situation, as it depends on the Map and on other Units; drawing is best done by the Unit because there may be many unit subtypes with different data structures that may need to be drawn; Unit selection operations as you have pointed out lie somewhere in between. If you see how Swing implements this (e.g. ButtonGroup, ListSelectionModel), the 'selection' itself can be though of as a separate class.
I made a peg solitaire game a few years ago which was pretty much just a JPanel that extended MouseListener and MouseMotionListener. The pegs were primitive circles drawn in the paint method, but you could track where they landed by taking the cursor position and mathematically working out the square in which it landed. That lined up with an array that stored either a 1 or 0 for each square on the board depending if anything was there. You could also drag each piece by finding the current cursor position then calling repaint() in the mouseDragged method you get from implementing MouseMotionListener.
I'd probably suggest doing it that way to begin with. Create an array of whatever size and use that to track the units. Then each time you make a move just check that array and redraw your units in the paint method. If you're using mouse movement then you can get the current position of the unit on mouseDown then do what I mentioned before with mouseDragged, and then get your final location on mouseUp and also do your calculations in regards to legal moves etc in mouseUp.
In the paint method you'll just loop over the array that defines the map and if there is a unit at the current position on the array then do something like g.fillOval(x,y,x_dimension,y_dimension). That array could just have its elements set to 0 for no unit at the current position, or 1 for a team 1 unit at the current position, 2 for team 2 etc. The paint method will take those numbers and draw pieces accordingly (change color for each type or whatever).
I hope that makes a bit of sense.