Created
May 7, 2017 18:50
-
-
Save joennlae/a5f231ae97b795ca1becf5504a1bb424 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package u9a2; | |
import java.util.ArrayList; | |
import reversi.*; | |
public class MinMaxPlayer implements ReversiPlayer | |
{ | |
/** | |
* Die Farbe des Spielers. | |
*/ | |
private int color = 0; | |
private long timeLimit = 0; | |
public MinMaxPlayer() | |
{ | |
} | |
/** | |
* Speichert die Farbe und den Timeout-Wert in Instanzvariablen ab. Diese | |
* Methode wird vor Beginn des Spiels von {@link Arena} aufgerufen. | |
* | |
* @see reversi.ReversiPlayer | |
*/ | |
public void initialize(int color, long timeout) | |
{ | |
//this.timeLimit = timeout; | |
this.timeLimit = 5000; | |
this.color = color; | |
if (color == GameBoard.RED) | |
{ | |
System.out.println("MinMax ist Spieler RED."); | |
} | |
else if (color == GameBoard.GREEN) | |
{ | |
System.out.println("MinMax ist Spieler GREEN."); | |
} | |
} | |
/** | |
* Macht einen Zug für den HumanPlayer, indem der Benutzer zur Eingabe eines | |
* Zuges aufgefordert wird. Diese Methode wird von {@link reversi.Arena} | |
* abwechselnd aufgerufen. | |
* | |
* @see reversi.ReversiPlayer | |
* @return Der Zug des HumanPlayers. | |
*/ | |
public Coordinates nextMove(GameBoard gb) | |
{ | |
long timeout = System.currentTimeMillis() + timeLimit - 10; | |
Coordinates coord = null; | |
int tiefe = 0; | |
System.out.print("MinMaxPlayer "); | |
if (color == GameBoard.RED) | |
{ | |
System.out.print("(RED)"); | |
} | |
else if (color == GameBoard.GREEN) | |
{ | |
System.out.print("(GREEN)"); | |
} | |
if(gb.isMoveAvailable(color)){ //damit gepasst wird | |
BestMove bestmove = null; | |
try{ | |
bestmove = max(1,timeout,gb,0); | |
} | |
catch(Timeout e){ | |
//throw new AssertionError(); | |
return null; | |
} | |
try{ | |
for ( int i= 2; bestmove.cut; i++){ //falls endspiel situation und nicht mehr genügend zügen inerhalb der zeit | |
bestmove = max(i, timeout, gb,0); | |
tiefe = i; | |
} | |
} | |
catch( Timeout e){ | |
System.out.println("Tiefe " + tiefe + "ging noch"); | |
} | |
coord = bestmove.coord; | |
} | |
return coord; | |
} | |
public ArrayList<Coordinates> getPossibleMoves(GameBoard gb, int player){ | |
ArrayList<Coordinates> possibleMoves = new ArrayList<Coordinates>(); | |
for(int i = 1; i<9; i++){ | |
for(int j= 1; j<9; j++){ | |
if(gb.checkMove(player, new Coordinates(i,j))){ | |
possibleMoves.add(new Coordinates(i,j)); | |
} | |
} | |
} | |
return possibleMoves; | |
} | |
private BestMove max(int maxDepth,long timeout, GameBoard gb, int depth) throws Timeout{ | |
if(System.currentTimeMillis() >= timeout) throw new Timeout(); | |
if(depth== maxDepth) return new BestMove(null,eval(gb), true); | |
ArrayList<Coordinates> possibleMoves = getPossibleMoves(gb, color); | |
if( possibleMoves.isEmpty()){ | |
if(gb.isMoveAvailable(Utils.other(color))){ //schauen, was andere Spieler zieht nach passen des eigenen Spielers | |
BestMove result = min(maxDepth,timeout, gb, depth + 1); | |
return new BestMove(null, result.value, false); | |
} | |
else { //spiel fertig da kein Spieler mehr ziehen kann | |
return new BestMove(null, finalRes(gb),false); | |
} | |
} | |
BestMove bestmove = new BestMove(null, -1, false); // | |
for( Coordinates coord : possibleMoves){ | |
GameBoard gbc = gb.clone(); | |
gbc.checkMove(color, coord); | |
gbc.makeMove(color, coord); | |
BestMove result = min(maxDepth,timeout,gbc,depth + 1); | |
bestmove.cut = (bestmove.cut || result.cut); | |
if(result.value > bestmove.value){ | |
bestmove.coord = coord; | |
bestmove.value = result.value; | |
} | |
} | |
return bestmove; | |
} | |
private BestMove min(int maxDepth,long timeout, GameBoard gb, int depth) throws Timeout { | |
if(System.currentTimeMillis() >= timeout) throw new Timeout(); | |
if(depth== maxDepth) return new BestMove(null,eval(gb), true); | |
ArrayList<Coordinates> possibleMoves = getPossibleMoves(gb, Utils.other(color)); | |
if( possibleMoves.isEmpty()){ | |
if(gb.isMoveAvailable(color)){ //schauen, was andere Spieler zieht nach passen des eigenen Spielers | |
BestMove result = max(maxDepth, timeout,gb, depth + 1); | |
return new BestMove(null, result.value, false); | |
} | |
else { //spiel fertig da kein Spieler mehr ziehen kann | |
return new BestMove(null, finalRes(gb),false); | |
} | |
} | |
BestMove bestmove = new BestMove(null, -1, false); | |
for( Coordinates coord : possibleMoves){ | |
GameBoard gbc = gb.clone(); | |
gbc.checkMove(color, coord); | |
gbc.makeMove(color, coord); | |
BestMove result = max(maxDepth,timeout,gbc,depth + 1); | |
bestmove.cut = (bestmove.cut || result.cut); | |
if(result.value > bestmove.value){ | |
//bestmove.coord = coord; | |
bestmove.value = result.value; | |
} | |
} | |
return bestmove; | |
} | |
private int eval(GameBoard gb){ | |
return gb.countStones(color); | |
} | |
private int finalRes(GameBoard gb){ | |
return gb.countStones(color); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment