First of all, I am not sure whether it is allowed to ask this kind of question. So I am trying to create a board game and I was stuck at the implementation of generating valid moves for Piece. Here is the extract of the class diagram.
You can think this board game like chess, so we need to know the location of other pieces while generating valid moves. The problem is I have no idea how to check it. Is my class diagram wrong? Or should I check at the board every time I check a square? And how do I do that in Java? Thanks for helping.
The piece should not decide what its valid moves are, it should only be aware of where it is and how it's capable of moving. It is not responsible for that sort of logic.
The board should manage whether or not that's allowed or not (that is, it takes a piece which returns its possible moves to it, and in turn returns the valid moves).
The Piece class exposes a getPossibleMoves method that returns the list of positions it can reach:
public List<Square> getPossibleMoves(){ // might want to differentiate types of moves
Then, the board class has a getValidMoves method that takes a piece and returns its valid moves.
public List<Square> getValidMoves(Piece piece) {
return piece.getPossibleMoves().
stream(). // and filter by
filter(move -> isOnValidBoardCoordinate(move)). // can shorten
filter(move -> doesNotIntersectOtherPiece(move)).
filter(move -> otherValidation(move)).
collect(Collectors.toList());
}
Related
I am using Slick2D to make a simple game with a number of sprites. There is a player sprite which will push other object sprites around the map.
I have used an ArrayList to store all the sprite types created, but when I use the player to push a particular type of sprite (for example a wooden block) all the occurrences of that particular sprite type in that map gets updated as well. How do I specify to update that one particular wooden block rather than updating all the wooden blocks loaded in the game?
ArrayList:
private ArrayList<Sprite> sprites;
Creating all the sprites and storing them inside the ArrayList:
public static ArrayList<Sprite> loadSprites(String filename) {
ArrayList<Sprite> list = new ArrayList<>();
/*bunch of code to load the sprite*/
list.add(World.createSprite(name, x, y));
return list;
}
here types is a 2D array where I am storing all the names of the sprites according to their map coordinates, which I am getting from a csv file.
public static Sprite createSprite(String name, float x, float y) {
switch (name) {
case "player":
return new Player(x, y, "player");
case "wood":
return new Wall(x, y, "wood");
case "tile":
return new Floor(x, y, "tile");
case "wall":
return new Stone(x, y, "wall");
case "metal":
return new Target(x, y, "metal");
}
return null;
}
Thanks in advance. :)
What you need to do is to identify the object the player pushes. Let's assume you have three sprites in your list all of the type wood. From what you wrote in your question it seems like if the player starts pushing obviously all sprites get updated as well because either:
Your program can't determine what sprite exactly is supposed to be pushed.
Your program knows what sprite is supposed to be pushed but cant determine what sprite to update visually (hard to tell with your provided code)
So what you should do is to ensure that the pushing action is only performed to the object/sprite the player is interacting with. You need to have constraints to check for this interaction this constraint might be pushing a button or intersecting with that one particular sprite / object. So you could do for example the following:
Iterate through your arraylist and check with which object/sprite your player is intersecting.
If there is an intersection with an object of your list you exactly know what object that is and you could call the update, push or any other method on the object.
If you have more than one possible candidate to update you need to specify your search, for example you could only interact with objects / sprites your player is looking at.
Call the needed method of that particular one object (eg. push()).
What also might be a solution is that you should be sure about your game architecture. By this I mean that you should be certain about how your game is internally designed. Generally each gameobject in your game should have sprite and maybe a sound or certain other attributes. By this you make sure that each object has a specific sprite just for itself, so you wont get into trouble with updating any other sprites because you only can access this specific sprite by this specific object. So maybe you should consider not iterating over a list of sprites but rather iterate over a list of gameobjects in your world (I'm not sure but maybe a sprite is a gameobject for you, but a sprite is just the graphical representation of a gameobject.). Check for interaction with each of these gameobjects and in case perform a specific action. Such code could look like the following:
//inside the update method of your player
for(GameObject gameObject : world.getAllGameObjects()){
if(player.getHitbox().intersects(gameObject.hitbox())){
gameObject.update() //push, update sprite, whatever
}
}
Checking for intersection is only one solution as I already said you could also check for the pressing of a key or for a certain distance. From my understanding what is important for you is the identification of a single object and to update that single object.
It's hard to tell what exactly your problem is because I dont have insight in your entire code, but if you ensure to find the right object to interact with and also making sure that only this object is graphically updated this will work.
Beside the architecture it self the problem might be here:
if (Loader.getSpriteOfType("wood", Player.getPlayerX() - 1, Player.getPlayerY())) {
dir = DIR_LEFT;
}
I'm not sure what Loader.getSpriteOfType(..) does since I don't know how sprites or objects are entirly stored and handled in your game cycle, but I'd assume that it returns all (not only a specific one) sprites of type "wood" because it's searching for "wood" and finds all objects which "wood", but you want only the exact one which your player is interacting with so maybe you should be more specific in that if-clause (just an assumption though since I don't know your code).
Hope this helps you and gives you something to think about.
I'm creating a Pacman clone in JavaFX, but actually the language shouldn't matter at all, it's more about the logic behind it which I can't figure out.
I've taken a video of the issue, it illustrates quite well what bug I'm facing.
I want that the Player can eat a Food (eg. the Food gets deleted from the board[][] and the score is increased). This works. But I also want the Ghosts not to be able to eat the Food, but my draws are all based off of the board[][], so I can't have a Ghost and a Food at the same place.
Not sure how it should be done, my thought was that I can create a holdingObject variable which "holds" the Food object and which is then placed back to where it came from when the Ghost moves further.
My GameView has these two important fields in it:
private static GameObject board[][];
private static LinkedHashSet<Moveable> moveableLinkedHashSet;
Both variables get filled by other methods, these work fine.
The following code block seems to contain the issue, although it may also have to be dealed with in the Line #89 (see link below).
private void executeMoveWithPosition(Position positionDest) {
GameObject ghost = this;
// TODO: Fix holding object. Currently it's a mess:
// TODO: Two consecutive foods won't be handled correctly, food gets set to wrong position at the beginning
// holdingObject gets set to the current position - possibly null, that's ok
LevelManager.getBoard()[position.getX()][position.getY()] = holdingObject;
// ghost gets inserted at the new position
LevelManager.getBoard()[positionDest.getX()][positionDest.getY()] = ghost;
// holdingObject gets emptied
holdingObject = null;
// actually move the ghost
position.setX(positionDest.getX());
position.setY(positionDest.getY());
}
Ghost.java, from which I removed methods and if clauses which didn't matter for this.
If I understand correctly, you simply don't know what data structure you should use to represent your game board, including the player, enemies and items (food).
Without investigating your code in detail, I would suggest...
You create a Tile class. The board can then be made up of those. It can save information on whether it is a traversable or not and could also hold the item that is placed upon it.
Your enemies already have a class (Ghost) that holds their position, so just make sure you have a collection of enemies that you can iterate over for rendering and game logic. This way, you don't need the board to keep track of these itself.
Optionally, have an Item (or Food) class, that you handle just like your enemies: they hold their position and you keep all of them in a collection. Again, the Tiles then don't need to keep track of these anymore.
In order to figure out if there is a Ghost or Food on a Tile, you would then need to iterate over all of these and check their position. For a game with such a small and simple level, this should be no issue.
Of course, there are other solutions and ultimately only you can know which one fits your project.
EDIT: As it turns out after exchange of some comments, solving the problem at hand was as easy as just not putting the Ghosts into the board array, as they do hold their own position. The above covers that plus is a bit more general and broad and should hopefully apply to others with similar issues as well.
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.
I have made threads in the past about similar questions but because of my lack of detail the answers have not really been related to what I needed so I am going to try explain my question in as much detail as I can and hopefully it will be easier for you to understand what I require.
I watched Bucky's slick game tutorials on youtube and made a 2D Java game, the game is basically a 2D player viewed from above (birds eye view) can move around a 2D map with user key input (up, down, left, right). The map the player moves around is very small so that meant boundaries had to be set so that the player could not walk off of the map, to give you a better idea of how this was done, here is the tutorial for setting up the voundries:
http://www.youtube.com/watch?v=FgGRHId8Fn8
The video will also show you exactly what the game is like.
The problem is, these boundaries only require one axis meaning that if the player is walking down you say something like "if player gets to the coordinate (number) on the X axis change the player movement to the opposite direction so that he can not go any further."
Now this creates a problem for me because this only requires one axis so it easy to set up and understand but if you look on the video, on the map there is a house and I want my player not to be able to walk over that also but this deals with 2 dimensions, I have looked at things like rectangle collisions and have seen things relating to them in the other posts but I get confused because I am new to Java and havent really done much with it at the moment apart from watching Bucky's tutorials.
My code at the moment for my game class has got the following methods: init, render and update. So to sum it up I really just want to set up a way of not letting my player walk through the house, I will mention also (I should have mentioned it in my other threads) as I am very new to Java, could you please take a step by step method of showing me how to set up the collisions, I mean even the basics of things like making the rectangle if required.
If my code is required please tell me and I will post it as soon as possible.
Thank you in advance.
You can set up the board as a 2x2 grid of a class that has has property such as 'isBlocked'. By default the edges of the board would have this property set to true to prevent the character from walking off the edge. When you add other obstacles such as a house or a wall the grid position(s) the object occupies would also have the property set to true. Then when moving a character you just check if the grid position the character moves to has the property set to false to see if it's an allowable move. This also makes it quite trivial to save the level data so you can just load them from disk later on.
Two possible options:
Extend Shape or Rectangle or the relevant Slick objects (they should exist IMO) and just check for intersect()
Look for (x1,y1) and (x2,y2) values such that it starts outside and ends up inside.
Assuming you have intersect() methods:
//Grab the previous position
prevPosX = movingobject.X;
prevPosY = movingobject.Y;
//Update the position
movingobject.update();
//Test for collision
if(movingobject.intersects(targetobj)) {
//If it collided, move it back
movingobject.X = prevPosX;
movingobject.Y = prevPosY;
//And reverse the direction
//(might want to do other stuff - e.g. just stop the object)
movingobject.speed *= -1; //Reverse the speed
}
in this case your update class should also add one more condition to look for the house. let say the cooridnates of house(assuming rectanglular house here for other shape just change x and y values) are (x1,y1)(x1,y2)(x2,y2)(x3,y1) you have to add a condition to make sure
x value is not between x1 and x2 and at the same time y value cannot between y1 and y2.
I am a beginner in Java and trying to practice. I want to write a basic text based noughts and crosses game in java without any GUI. I want to test if it works by writing unit tests to check if they pass. I don't want any answers but just want guidance on how to go about doing this. This is what I have decided so far:
Have the following classes: GameTest, Game, Board and Player (have two instances of this)
Use an array for the board.
I would appreciate if anyone would have any suggestions on how i could improve or ideas on how to do it.
Thanks
it would probably go something like this:
a player should be 'x' or 'o' (or 0/1)
a board is a 1-d array(0..8) or 2d(3x3) array of int or char (0,1,2) or ('_','x','o')
methods:
switchTurn()
currentTurn() (return 'x'/'o')
playMove(player, cell) - cell can be a single integer (0..8) or 2d (0..2,0..2)
validMove() returns true
isWinner(player)
isDraw() (not valid moves)
this should give you a rough idea