{-WETT A THIRD IMPLEMENTATION: THE THREE ARE ABSOLUTELY SIMILAR. this one however uses a different static evaluation (the one that the author had before the genetic algorithms took place) Again: feel free to tune tha depth value PS: I did again rename the module, as the file name implies The implementation is based on a paper "A genetic algorithm to improve an Othello Program" by Jean Marc Alliot and Nicolas Durand, which I accidently found on the internet. It offers a simple algorithmic approach - the use of an alpha-beta pruning algorithm to determine the next move, which is based on a simple static evaluation function, described in the paper mentioned above. Basically, the author shows using generic algorithms as a way to increase the efficiency of the evaluation function. As a result, he finds a "better" static evaluation of the board, which I tried to implement. For the representation of the board I chose a Map, mainly because it has a simple interface. The idea behind the evaluation: Every single position on the board has a static value, which is known before the program starts. During the evaluation we consider the following: tiles/positions that have our disks on them are + values, and they add up to the end result. Analogue the positions with disks of the opponent, or more so their values, get subtracted to the end result. So that we don't leave behind the strategic advantage, which comes with more possible moves at every single moment in the game, there is a mobilityCoeffitient, based on the number of possible Moves of both players. It also gets subtracted to the result. Last but not least, tiles that are around already occupied corners changes their static values from negative to 0 (corners are a good tile to conquer, therefore they have the highest value on the board. tiles around them however are a terrible choice, as long as the corner is free). And tiles on the edges, connected to conquered corners get a bonus. At the tope are the starting values for the alphabeta-pruning: you can change the depth value if necessary, unfortunately I have trouble with optimizing the algorithm any further (mostly because of lack of time) ... so the maximal value that my PC can stand is 4 :D which is ridiculous... more about the function: executeMove and determineNextMove are self-explanatory, possibleMoves figures out all possible Moves for a given player. Since I am new to Haskell, after numerous attempts to actually not go through all tiles on the board for this, I figured it doesn't change anything related to speed and left the implementation as simple as possible. The function checks if a tile forms a sandwich in any single one of the 8 direction (checkDirection does that specifically) and if so - this tile can be one of the next moves (of course it must be free as a starter :D). "The flippin' functions" just calculate the tiles which have to be flipped after the execution of a certain Play move. One of them counts how many tiles have to be flipped in eache direction and another uses foldr to accumulate a map with all of the tiles, which are to be flipped. the eval function does exactly what I described above, it's mostly pattern matched and there are a ton of funny numbers, which represent the static table from the paper. finally, the alpha Betha has a standard structure - alphaPrune and betaPrune are the parts, that would normally be in a for-loop, and here happens the actual pruning. The only exception is, that to simplify things (or maybe not ...) I wrote a redundant part of the algorithm for the 0-level, because I did need the move (and not only the value that this move led to), so that I can return it as a result of the function. -}