I'm trying to write a tetris clone. My board is a 10x20 array of integers on which 0 means no tile, 1-7 means a tile of specific color. It is constantly translated to graphic interpretation. My shapes are 4x4 arrays of integers. I've just come to a realisation that while making all of the shapes 4x4 makes some things easier, it also causes a problem when moving a piece left and right. Let's say we've got the I shape:
0010
0010
0010
0010
Now, if I move it to left wall there will always be a two units long gap, since the 0s cant move outside of the main board array. What would be the easiest way to allow the 1s to move to the left wall without causing an out of bounds exception?
Using your described method, one way to simply avoid getting the IndexOutOfBoundsException would be to expand your board to be 18 x 24 instead of 10 x 24, and then write in additional code that doesn't let you move a block left/right if there would be any 1's in the object array that leave the middle 10 squares of the grid. By adding this 'padding' to your grid, you avoid the exception and should still be able to implement.
I hope this approach makes sense to you. If not I can provide a more pseudo-code driven answer, but I hope you get the idea. (Just comment if you have any questions.)
BTW, #assylias makes a very good point. It is important to have a good design/plan before you start implementing things to avoid road-bumps like these. It comes with experience, so keep practicing and you will get the hang of it.
NOTE: As Nick pointed out in the comment, another way of doing this is to simply check if any 1's leave the grid before moving any of the arrays. This is certainly possible (and arguably a more elegant/simple solution), although it may be a bit harder to get right.
You need a way of detecting collisions with borders and existing pieces.
You would probably have a fixed handle on each piece, you'll also have an X and Y offest for the piece which indicates it's position as it moves down the grid.
To stop a piece moving out of bounds, loop through the 4*4 matrix of the moving piece and for the bits which are set to 1 simply check
to make sure that the X position + X offset is >= 0 and <=9 and the Y Position is >=0 and <=19 if either of these checks fail
then your piece would be moving outside the limits of the board array so stop the change to x or y offest as appropriate.
Translating the co-ordinates of the set bits in your piece matrix with the board array also allows you to check and see whether your piece has collided with a tile already in the board.
You should be doing these collision checks when a piece rotates as well I would have thought.
Related
I'm currently building a 2D game with Slick2D, and right now I'm implementing my first NPC.
I already have the sprites, I was able to draw him, did the collisions, and so on, but now I want to add the feature which makes the NPC look into the direction I am currently at, when I am entering a certain range around the NPC (Which would be 2 tiles left, diagonal, right, up and down, but because I want it to be exact, I'm using the x coordinates, so for every tile I would be checking 32x32 possibilities)
To get this a little bit more clear I drew a picture:
The numbers are the x and y coordinates, while my NPC is placed at 704,704.
The problem I have is that I don't know how to check all the coordinates effectively, without having to write 5000 lines of if's. The 2 left diagonal lines, which could both be interpreted as "NPC looks up" and "NPC looks left" would make him look left, same with the 2 right ones, which would make him look right.
Is there some clever method I can use, or should I just go back and divide the x and y by 32 so I only check if my player is on a certain tile? That would be less precise, though.
This is an assignment, so I'd prefer an explanation more than straight code.
The task is to draw circles recursively like the picture
I can't work out the pattern to draw it though. A turtle class is used to draw the circles.
This is what I've managed so far
private void draw(int level, double size){
if(level < 0) return;
turtle.setPenDown(true);
turtle.drawOval(size);
//Here I think there needs to be code to move to the positions of the other circles?
draw(level-1,size/2);
}
But of course it only draws this at the moment:
EDIT:
Maybe some code could help, this isn't going to well for me.
If it's got to be recursive then I would suggest something like the following, I'll just talk algorithm wise since you asked to not have code come back.
If we're going to think of this as a long series of self-similar circles then the general process is pretty straightforward.
Check if there are n circles in your current row. The row is defined as whatever direction is forward/backward for your turtle. If you want you could store the circles drawn in a 2-d list or array to make checking easier.
If there are n circles, then turn right, otherwise draw a circle and move forward.
That will draw the circles from the outside in. If you want it from the inside out it probably makes less sense to do recursion but it would be something like this:
Function: Draw circle. Turn right if you can, otherwise move forward.
Stop when the total number of circles is equal to n^2
Hope that helps.
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'm creating an application where I need to model (and display) a large number of 2-dimensional 'balls' (circles) using java. I've started by creating an ArrayList of Circle objects (a class that I defined, which has x/y pixel coordinates of the center of the circle, radius, color, and velocity in the x & y directions). I use a java.util.Timer object with a repeated TimerTask to control the motion of the circles. The circles vary in size from around 10-50 pixel radii.
What I want to happen is have balls fall from the top of the screen (randomly distributed across the x-axis) until they reach the bottom of the screen, which acts like a floor -- ball that reach it stop moving, and balls that reach stopped balls roll downhill on the other balls until they rest at a low/flat point. In the future I might want to make their behaviour a bit more complicated, so I want to create flexible code so I can easily expand. How it works right now is that every time period each circle check to see how close they are to every other circle. If there are no other circles nearby they continue falling normally. If two (or more) circles are close to each other there is code to determine how they will interact.
I have it working perfectly for small numbers of circles (< 200), but when I get larger numbers of circles (> 400) it starts slowing down significantly. I'm sure I can optimize some of the logic to make the comparisons a bit faster, but I was wondering if there are any ways of storing the circle in some structure besides an unorganized ArrayList that would let me easily find circles that are close to each other, so I don't have to do the N^2 operation of comparing each circle to every other one and, instead, just compare a circle to the 5-10 circles closest to it. For instance, I've considered using a 2D array to represent every pixel (or maybe square of 5x5 pixels) and store a circle where its center lies (so I could check if there are circles in any of the nearby cells, and ignore the rest). However, this still seems pretty inefficient as if I'm using a 800x1000 pixel canvas with 500 circles there would be a TON of empty spaces in the 2d array that I'd waste time checking. I've also considered some sort of hashmap, but I haven't thought of a great way to use that either.
So, can anyone think of an efficient way to store these circles that corresponds to it's location in 2d space and makes it easy to find nearby circles? Thanks in advance!
You can use a QuadTree to find close neighbours. Or you can simply sort by one direction, which would be far easier to implement and should still allow you to reduce the number of candidate neighbours to a small window.
Perhaps your idea of a 2D array is not so crazy. What I think you want is one List of all your circles, and a 2D array that would reference the circles also. So at each time, you can iterate over your List<Circle> to check each one. Each Circle has x,y coords and you only have to loop on your array for (x,y +/- 5). There is no need to check the whole possible space for Circles, because you already are keeping track of each Circle's center. Just grab the center, and check around it for other circles.
I am trying to code a Gomoku (five in a row) game in Java as an individual project. For the AI, I understand that the use of a Minimax function with Alpha-beta Pruning is a good way to approach this. However, I'm having a little trouble envisioning how this would work.
My question is this: what is a good representation for a node in a minimax tree?
I'm thinking my evaluation function will "weight" all the empty spaces on the board. It will then take the best value from that board as the node of the minmax decision tree. Am I on the right direction?
And any other tips are also welcome!
Thanks in advance!
The state space search is through the different states of the board. There are a lot of moves, since you can place a stone anywhere unoccupied. Each state can be represented as a e.g. 9x9 matrix, with 3 values -- white, black, or unoccupied. With a 9x9 board, there are therefore 3 ^ 81 possible board states.
From any board state, the number of moves is the number of unoccupied vertices. You can place a stone on any of these vertices. You can only play your own color. So, at most there are 81 possible moves .. 81 for the first move, 80 for the second, and so on. So you can search to depth 5 reasonably, and possibly more .. not too bad.
The proper representation is, as mentioned, a 2D matrix -- this can just be a 2D array of ints, with values e.g. 0 for unoccupied, 1 for white, 2 for black. ... int[9,9].
Your evaluation function doesn't sound very good. Instead, I would give points for the following:
-- get 5 in a row -- basically give it the max score for this one, since it's a win
-- 4 in a row with 2 open ends -- also max score, since opponent can't block you from getting 5.
-- 4 in a row with 1 open end -- still a very threatenning position, since opponent has to play
in one spot to block.
-- 3 in a row with 2 open ends -- very high score again
--- 4, 3, 2, 1 with both closed ends -- 0, since can't ever make 5 in a row.
and so on.
Then, you just apply the standard minimax algorithm -- i.e. alpha beta pruning -- it would be exactly the same as chess, but you have a different state space generator and evaluation function.
I'd consider an evaluation function of the following form: consider each set of, say, 6 positions in a line. (On a 19x19 board there are 14 along each line and varying numbers from 0 to 14 along each diagonal; I think that comes to 742 of these on the whole board. My arithmetic may be wrong.) For each set there are 729 possible arrangements of black, white and empty spaces. Or, er, 378 if you take end-to-end symmetry into account. Or, er, um, fewer than that but I can't be bothered to work out how many fewer if you take black/white symmetry into account too.
So now your evaluation function will consist of a table-lookup for each block of 6 stones, in a 378-or-however-many-element table (or perhaps two of them, one for horizontal and vertical lines, one for diagonal ones). Add up the results and that's your evaluation of the position.
It may turn out that actually a larger table (derived from a longer row of positions) works better.
But what goes in the table? Let your program work that out. Start with arbitrary values in the table (you might, e.g., take eval(line) = #black(line)-#white(line) or something). Let your program play itself, using alpha-beta search. Now update the table entries according to what happens. There are many different ways of doing this; here are a (sketchily-described) few.
During each game, keep track of how many times each pattern occurred in each player's positions. When the game's over, adjust each pattern's score so that patterns seen more often by the winning player look better.
Each time you do a search, adjust the scores for the patterns in the current position to bring the current static score nearer to the score obtained by search.
Each time a move is made, adjust the scores for each pattern in the "before" position to make the "before" score match the "after" score better.
Have lots of different tables (hence lots of different variants of the evaluation function). Let them play against one another. Apply some sort of evolution (e.g., play all against all, then throw out the worst performers and replace them with mutants derived from the better performers).
For a more sophisticated version of these ideas (applied to chess, but the same ideas would work fine for gomoku), take a look at http://cs.anu.edu.au/~Lex.Weaver/pub_sem/publications/knightcap.pdf .