Implementing MiniMax Algorithm IN JAVA plus random heuristic - minimax

i am trying to implement a minimax algorithm from scratch in java.
General point is known to all, through a tree i try to find the best possible move.
I dont have something crucial from code to show now, first i would like someone to give me a general approach so i can start the project and then update the post with my code.
In addition to that i am also going to implement a random heuristic for my game, that will in random choose the next move and pass it to the game, but this will be added later on.
I will be adding bounty on this question.
P.S.
This is not a duplicate, i dont want to copy someone else's code, i have to do the whole code on my own.

So the main thinking to follow is the following:
Calculate the best move with the given game field and the rating mechanism
field the input field where to calculate from ratingMechanisms the mechanism to rate the move and return the best move.
In a more in depth analysis:
The key to the Minimax algorithm is a back and forth between the two players, where the player whose "turn it is" desires to pick the move with the maximum score. In turn, the scores for each of the available moves are determined by the opposing player deciding which of its available moves has the minimum score. And the scores for the opposing players moves are again determined by the turn-taking player trying to maximize its score and so on all the way down the move tree to an end state.
A description for the algorithm, assuming X is the "turn taking player," would look something like:
-If the game is over, return the score from X's perspective.
-Otherwise get a list of new game states for every possible move
-Create a scores list
-For each of these states add the minimax result of that state to the scores list
-If it's X's turn, return the maximum score from the scores list
-If it's O's turn, return the minimum score from the scores list
-You'll notice that this algorithm is recursive, it flips back and forth between the players until a final score is found.
In the main part you should use a for in order to minimize or maximize each level (also you can try adding some debugging like this: //System.out.println("max/min level " + i);), then while getting the current level of the tree check if it is null so you get no exceptions, and for the that level add it in the max node, while parsing in the min node.
In order to use the max and min nodes you have create the functions for these.
The maximize part of the algorithms: The node will get the biggest rating of his children. WARNING: if no child exists, the rating will be the min.
For the minimize part of the algorithms. The node will get the lowest rating of his children. WARNING: if no child exists, the rating will be max.

Related

Amount based Sorting

I have two values, an address and amount in a game. In each round the user makes his contribution. The users address and the total contribution is sent to a function which maintains a list of players in a sorted manner.
There is a function that rewards the top players and resets the list. What would be the best approach to maintain the list of players and be able to reset it in a round independent manner.

How to normalize sequence of numbers?

I am working user behavior project. Based on user interaction I have got some data. There is nice sequence which smoothly increases and decreases over the time. But there are little discrepancies, which are very bad. Please refer to graph below:
You can also find data here:
2.0789 2.09604 2.11472 2.13414 2.15609 2.17776 2.2021 2.22722 2.25019 2.27304 2.29724 2.31991 2.34285 2.36569 2.38682 2.40634 2.42068 2.43947 2.45099 2.46564 2.48385 2.49747 2.49031 2.51458 2.5149 2.52632 2.54689 2.56077 2.57821 2.57877 2.59104 2.57625 2.55987 2.5694 2.56244 2.56599 2.54696 2.52479 2.50345 2.48306 2.50934 2.4512 2.43586 2.40664 2.38721 2.3816 2.36415 2.33408 2.31225 2.28801 2.26583 2.24054 2.2135 2.19678 2.16366 2.13945 2.11102 2.08389 2.05533 2.02899 2.00373 1.9752 1.94862 1.91982 1.89125 1.86307 1.83539 1.80641 1.77946 1.75333 1.72765 1.70417 1.68106 1.65971 1.64032 1.62386 1.6034 1.5829 1.56022 1.54167 1.53141 1.52329 1.51128 1.52125 1.51127 1.50753 1.51494 1.51777 1.55563 1.56948 1.57866 1.60095 1.61939 1.64399 1.67643 1.70784 1.74259 1.7815 1.81939 1.84942 1.87731
1.89895 1.91676 1.92987
I would want to smooth out this sequence. The technique should be able to eliminate numbers with characteristic of X and Y, i.e. error in mono-increasing or mono-decreasing.
If not eliminate, technique should be able to shift them so that series is not affected by errors.
What I have tried and failed:
I tried to test difference between values. In some special cases it works, but for sequence as presented in this the distance between numbers is not such that I can cut out errors
I tried applying a counter, which is some X, then only change is accepted otherwise point is mapped to previous point only. Here I have great trouble deciding on value of X, because this is based on user-interaction, I am not really controller of it. If user interaction is such that its plot would be a zigzag pattern, I am ending up with 'no user movement data detected at all' situation.
Please share the techniques that you are aware of.
PS: Data made available in this example is a particular case. There is no typical pattern in which numbers are going to occure, but we expect some range to be continuous with all the examples. Solution I am seeking is generic.
I do not know how much effort you want to involve in this problem but if you want theoretical guaranties,
topological persistence seems well adapted to your problem imho.
Basically with that method, you can filtrate local maximum/minimum by fixing a scale
and there are theoritical proofs that says that if you sampling is
close from your function, then you extracts correct number of maximums with persistence.
You can see these slides (mainly pages 7-9 to get the idea) to get an idea of the method.
Basically, if you take your points as a landscape and imagine a watershed starting from maximum height and decreasing, you have some picks.
Every pick has a time where it is born which is the time where it becomes emerged and a time where it dies which is when it merges with an higher pick. Now a persistence diagram pictures a point for every pick where its x/y coordinates are its time of birth/death (by assumption the first pick does not die and is not shown).
If a pick is a global maximal, then it will be further from the diagonal in the persistence diagram than a local maximum pick. To remove local maximums you have to remove picks close to the diagonal. There are fours local maximums in your example as you can see with the persistence diagram of your data (thanks for providing the data btw) and two global ones (the first pick is not pictured in a persistence diagram):
If you noise your data like that :
You will still get a very decent persistence diagram that will allow you to filter local maximum as you want :
Please ask if you want more details or references.
Since you can not decide on a cut off frequency, and not even on the filter you want to use, I would implement several, and let the user set the parameters.
The first thing that I thought of is running average, and you can see that there are so many things to set, to get different outputs.

Recursive backtracking, showing the best solution

For school I am supposed to use recursive backtracking to solve a Boat puzzle. The user inputs a maximum weight for the boat, the amount of item types, and a weight and value for each item type. More than one of each item type can be placed on the boat.
Our assignment states "The program should find a solution that fills the boat with selected valuable items such that the total value of the items in the boat is maximized while the total weight of the items stays within the weight capacity of the boat."
It also has pretty specific template for the recursive backtracking algorithm.
Currently I am using contiguous lists of items to store the possible items and the items on the boat. The item struct includes int members for weight, value, count (of how many times it is used) and a unique code for printing purposes. I then have a Boat class which contains data members max_weight, current_weight, value_sum, and members for each of the contiguous lists, and then member functions needed to solve the puzzle. All of my class functions seem to be working perfectly and my recursion is indeed displaying the correct answer given the example input.
The thing I can't figure out is the condition for extra credit, which is, "Modify your program so that it displays the best solution, which has the lowest total weight. If there are two solutions with the same total weight, break the tie by selecting the solution with the least items in it." I've looked at it for awhile, but I'm just not sure how I can change it make sure the weight is minimized while also maximizing the value. Here is the code for my solution:
bool solve(Boat &boat) {
if (boat.no_more()) {
boat.print();
return true;
}
else {
int pos;
for (int i = 0; i < boat.size(); i++){
if (boat.can_place(i)) {
pos = boat.add_item(i);
bool solved = solve(boat);
boat.remove_item(pos);
if (solved) return true;
}
}
return false;
}
}
All functions do pretty much exactly what their name says. No more returns true if none of the possible items will fit on the boat. Size returns the size of the list of possible items. Adding and removing items change the item count data and also the Boat current_weight and value_sum members accordingly. Also the add_item, remove_item and can_place parameter is the index of the possible item that is being used. In order to make sure maximized value is found, the list of possible items is sorted in descending order by value in the Boat's constructor, which takes a list of possible items as a parameter.
Also here is an example of what input and output look like:
Any insight is greatly appreciated!
It turned out that the above solution was correct. The only reason I was getting an incorrect answer was because of my implementation of the nomore() function. In the function I was checking if any item in the possible items list was less than the weight left on the boat. I should have been checking if they were less than or equal to the weight on the boat. A simple mistake.
The wikipedia entry was indeed of use and I enjoyed the comic :)

Choosing the best stucture for my list of players

I am in trouble choosing the most pertinent structure for my data, here are the explanations:
I am actually working on a game project for school, a Bomberman like game in c++.
I am designing the Map object, who contain Bombs, Boxes, Players and Walls.
The map is 2D, I have already 2 containers of type:
std::unordered_map<int, std::unordered_map<int, AEntity*> > *UMap;
One contain Walls, the other contain destructible objects (Bombs, Boxes).
I have already discussed this choice here -> Choice of unsorted_map.
It's mainly for fast access time and because there can only be one element per map's box.
Now as the title suggest I'am in trouble choosing a data container for my players, because there can be multiple players on a single map's box, unordered_maps can't be used.
In a first time I was going to use a std::list<AEntity*> sorted with std::sorted, AEntity containing the entity information (coords), but while coding my
playerOn(const int x, const int y);
function I found it was a poor choice. I can't retrieve fast enough which player(s) is on the given box using dichotomies, and if there is no player of this box it's a waste of time.
How should I store my (AEntity)Players in order to be able to retrieve them fast
(On of the itchy thing is that there can be more than 500 player at the single time, on big map, that's why I am looking for optimization)
I am running out of brain juice. Thanks for your future answers.
Edit about my probleme
It's mainly because I want to know if there is another solution to go trough my whole std::list of player to find if there is someone on box(x, y). Looks slow and not optimized, but i can't figure another way to do this.
(I can change container type if needed)
First of all, before trying any optimization, you should profile your code to detect where is the bottleneck. You will be surprised. Once that said :
1) Your unordered_maps seem like a lot of over-engineering. The answers provided in your previous post are true but I think it is useless in your case. You absolutely do not care of a O(log(n)) cost when n = 500. Just make a vector of Entities*. It is much enough.
2) You seem to be falling in the god object anti-design pattern. A bomberman game is an excellent project for studying OOP, as it teaches you to avoid the God Object design pattern. Make sure each class does its own business and no class handles all the logic (I suspect your class Map or Game has too much power).
a) Create a vector of players, a vector of bombs, a vector of walls, a vector of fires, etc.
b) Map should be a 2-dimensionnal array storing list of pointers to the entities that are present on each Map's box. (Each Map[i][j] holds pointers to all the elements that are on the box of index (i,j)).
c) Bombs should create fire elements.
d) Your central routine should be something like :
while(gameContinued)
{
for each entity in the game
{
entity.Update(map);
}
game.Render();
}
Bomb update consists in making the bomb's texture rendering dynamic and create fires if delay is over-due (and update the Map with the fires pointers accordingly).
Fire update consists in nothing except vanishing if delay is over-due (and update the Map).
Player update consists in moving through keyboard event handling (and updating their current internal x and y values ), creating bomb if needed, dying if for their position (x,y), there is a fire in the Map[i][j] list of entities.
3) In most of my students implementation of bomberman, the only issue they can get is with textures and deep copy of objects. Make sure you have a Texture Loader (using Singleton Pattern) to avoid loading multiple times the same textures, and you should be fine.

Improve board game turn processing

I have a fairly simple board game i've been building in C++. Currently, players are assigned a player number (1, 2, 3...N) depending on the number of players in the game. Pretty standard. The players and their stats are kept in a file which include their name and their number. I then process turns via reading a directory with turn files. The turns are submitted by the players and contain only their player name and their task/turn. In the future, I plan to have player numbers change so to mix up the order of the game.
(if you're a board gamer, think Caylus or Agricola)
Players are read in at the start of the application. I then give a command and turns are processed. Basically, I simply read the directory of turns, 1 by 1, and match that turn to a player name. As it stands, there is no order in turn processing. Player 3 can go before player 2.
I figured this wasn't a great design so I came up with the following solution:
As I'm comparing which turn goes with which player, insert that turn into a std::map<int, Turn>, the key being the player number.
After I gather all the turns, search for player N, starting with 1, within the map and process his turn.
I'm iterating through the list of players again here because I need to match the player with the player number in order to process the turn.
Do this until I've processed all players.
Is there a better way to do this? This seems kludgey and a lot of overhead.
Thanks!
Note: My turn processing method takes in a Player class (which represents the player stats file) and a struct representing the turn read from the turn file.
So as I understand it, your problem is you have thee bits of linked data: Turns, PlayerIDs and PlayerTurnPositions (OK the latter 2 are ints but I'll assume you've typedef-ed them to something like that to avoid confusion). And you want to maintain a lookup from the PlayerID and PlayerTurnPosition values to the corresponding Turn, and also maintain a bidirectional relation between the Player info.
This is just screaming out to use a boost::bimap with some extra info attached to each pair relation; something like
boost::bimaps::bimap<
boost::bimaps::vector_of<PlayerID>,
boost::bimaps::vector_of<PlayerTurnPosition>,
boost::bimaps::with_info<boost::shared_ptr<Turn> >
>
should do the job nicely (although there are other options for the left/right view container types; set_of probably makes more sense given playerIDs and positions are presumably unique).
Example of this sort of with_info usage in the docs.
You might think of defining an Action class for a player acting in his turn, which is defined by a player number and a turn number, and define a comparison on this class. Read all Actions from the files, insert them into an ordered list, and then process these actions.