I'm writing my first own chess game in Java.
My code already works for two players, manually playing from the keyboard, and I would like to expand it to a player against the computer game.
My problem is that I've never dealt with random actions.
The method which is moving a piece on the board, needs to receive 4 inputs:
two integers for the piece location, and two integers for the destination on the board.
Choosing the wrong inputs is OK since the movePiece method already checks if the integers are not out of the board's bounds, that they really reach a piece of the current player's color, that there's a piece in the coordination and its not empty, etc.
But how do I get these 4 integerss randomly? And how do I make them as closest as possible to "real" inputs (so I don't spend a lot of time disqualifying bad inputs)?
Java provides at least two options to generate random values:
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html
http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#random()
E.g. to get random int values bounded by 4:
int x = new Random().nextInt(4);
int y = (int) (Math.random() * 4);
System.out.println(x + " " + y);
>> 2 3
If you really would like to create a computer player who just moves about randomly, I think it would be better to do it it like this:
Randomly select one of the existing chess pieces on the board
Compute all legal destinations to which that chess piece could move
If there are no legal destinations, choose a new piece amongst the previously not selected pieces
Randomly select one of the computed legal destinations
However, letting a computer player move about randomly is rather silly. A computer player would need to have some form of logic to compare which out of two moves is better. Implementing such logic is probably rather complex, and you're probably better off using a chess library as someone suggested in the comments.
You don't need 4 ints. You only need 1.
A way of doing this:
Iterate the pieces on the board.
For each piece, determine its available moves and stick all the available moves in a list.
Pick one move from the list at random (or at non-random, if you feel so-inclined).
Related
I am making a simple game.
I have 6 buttons and i want to shuffle them each time on different locations.
So i've made a simple method to achieve this.
private void changeButtonPlace(ImageView button) {
Random r = new Random();
int newXloc = r.nextInt(getScreenWidth() - (2 * button.getLayoutParams().width));
int newYloc = r.nextInt(getScreenHeight() - (3 * button.getLayoutParams().height));
button.setX(newXloc);
button.setY(newYloc);
}
It works pretty well, but sometimes the buttons override each other which means that it goes on the almost the same location. I want each button to be on a unique location and don't touch other buttons.
Any idea how i can achieve this?
Thanks in advance!
What you are looking for is collision detection, and my answer will greatly simplified this process. I suggest searching for collision detection algorithms to learn more.
So, for super simple starts, we can compare the position, length, and height of 2 boxes. For my example, I am going to assume the origin of these to boxes are their upper left corner.
if((boxA.xPos + boxA.length ) < boxB.xPos || boxA.xPos > (boxB.xPos + boxB.length))
That will check if the two boxes are touching along the x-axis, and we can change the values for the y-axis as well
if((boxA.yPos + boxA.height ) < boxB.yPos || boxA.yPos > boxB.yPos + boxB.height)
Now, this is not a very efficient way of doing this. There are lots and lots of better ways to simplified this logic, and save on resources. But, it is quick and dirty, and probably good enough for a small application like your simple game involving only 6 buttons.
So, with these two equations, you can either nest them then run your collision code inside, or you can OR them together to one equation like this:
if(((boxA.yPos + boxA.height) < boxB.yPos || boxA.yPos > (boxB.yPos + boxB.height)) || ((boxA.xPos + boxA.length ) < boxB.xPos || boxA.xPos > (boxB.xPos + boxB.length)))
That is a lot to read for one line, and if you just starting out, I would suggest nesting them so you can better see the flow of logic through the equations. But, keep in mind for the future, if you ever need to squeeze those few extra bits of performance, OR them together to one if statement is alright place to start.
One way would be to make a grid and instead of a random location on the screen use a random point on the grid. That way you can check if the current grid location has a button on it already.
If you want them to be more scattered you could add each button to an array and check that the new doesn't touch the other buttons. Loop infinitely creating random locations and another loop to check they don't hit the other buttons in the array. Once a new location is found add the button and break out of the infinite loop.
You should take in account the width of the button , and before setting the location of the button make sure no button intersect with a simple if, if they do just randomize the intersecting buttons, should be easy to programm
Edit :
Lets make it a bit simpler an assume you have 3 buttons an assuming they are located on a 2d axis with these coordinates
A : 1,0
B : 2,0
C : 5,0
button width : X=2 Y=2
As you can see in this example at first glance it seems as though no button intersects with each other yet if you add the width to B you understand that is real location is B [1,3] ,[-1,1] intersects with the real location of C [4,6],[-1,1] assuming the coordinates are the center of the button
first [,] represents X axis second [,] represents Y axis
therefore your check will be something like so:
For each Button x
For each button x
calculate real coordinates of button x and y check intersection
if exists recalculate the coordinates and start the loop over
this solution is a bit expensive when talking about running time but once you get the idea you will be able to find something easier.
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 have written an Android app. It is a simple version of the old board game Connect 4. Currently my "Board" object holds the counters which have been places on the board. There are 2 players to this game.
The Board class comprises of 7 ArrayList objects, each one represents a column on the board.(the board is 7 across x 6 upwards). So for example when the red player clicks on the third column on the screen I call
boardObj.addCounter("red", column);
and inside the board object in the addCounter() function it does something like
column3.add(playerColor);
so the ArrayList column3 gets another item added and so forth.
My question is - is there a better data structure I can use as opposed to using 7 ArrayLists? I noticed that the function which checks whether there is a win, which is called after a counter is added to the board, is becoming quite an expensive function in terms of CPU. What structure would allow me to get and set the data and run my checkwin() algorithm with the best performance?
You have a 7x6 board, and you need to test for elements on the same row, column or diagonal.
A 2-dimensional array is the most obvious choice. I would use that.
I am currently working on a game and have come into a bit of a problem.
I am working on an algorithm that will create a path for the AI characters to follow in the game. It is a top down adventure game and the AI will choose a random location on a 50 by 50 map then take the shortest path, taking obstructions into account.
I originally had it so that the AI will use 0-3 to determine how to move. If it is 0, they move up, 1, right, etc. Now I am trying to use the A* algorithm to create a list of moves. Once they arrive, they will choose a new destination and the process will repeat.
The problem I am having is storing the squares. From what I understand, you need a closed list and an open list. I was planning on using linked lists for these, then ultimately using a third linked list that stores the path to be followed.
The issue is that I need to store both an x and a y coordinate. I thought I could just use two lists for each, but that seems inefficient.
By the way, I am using Java to program it.
Instead of having lists for each coordinate just wrap your x and y into a class. You can use the Point class or make your own storing the x and y and implementing a comparison to help with your A* Search. You can also have a look at Implementation of A Star (A*) Algorithm in Java
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 .