Hallo,
ich muss für ein Praktikum das Spiel Othello/Reversi in Java programmieren.
Bin im Grunde damit fertig, bis auf ein Problem, an dem ich schon seit Tagen verzweifelt sitze.
Mein Gegenspieler (KI) soll ein Feld mit dem besten score wählen, wählt aber entweder ein Feld, welches schon besetzt ist oder eins, was für ihn gar nicht erlaubt ist zu setzen (und somit wird sein Zug übersprungen). Ich habe in der Datenstruktur das ganze eigentlich abgeklärt, es scheint aber nicht zu funktionieren.
Ich vermute den Fehler in der "Check"-Methode
OthelloKI
OthelloDatenstruktur
Vielen lieben Dank für jede Hilfe.
ich muss für ein Praktikum das Spiel Othello/Reversi in Java programmieren.
Bin im Grunde damit fertig, bis auf ein Problem, an dem ich schon seit Tagen verzweifelt sitze.
Mein Gegenspieler (KI) soll ein Feld mit dem besten score wählen, wählt aber entweder ein Feld, welches schon besetzt ist oder eins, was für ihn gar nicht erlaubt ist zu setzen (und somit wird sein Zug übersprungen). Ich habe in der Datenstruktur das ganze eigentlich abgeklärt, es scheint aber nicht zu funktionieren.
Ich vermute den Fehler in der "Check"-Methode
OthelloKI
Java:
package othello;
import java.util.*;
import szte.mi.Move;
import szte.mi.Player;
public class OthelloKI implements Player{
private OthelloDatenstruktur data;
private int order;
private Random rnd;
private Status me;
private Status opp;
private LinkedList<Move> posMoves;
private HashMap<Move, Integer> possibleMoves;
int [] counter = new int[2];
static final int squareScores[][] = new int[][]
{{50, -1, 5, 2, 2, 5, -1, 50},
{-1, -10, 1, 1, 1, 1, -10, -1},
{5, 1, 1, 1, 1, 1, 1, 5},
{2, 1, 1, 0, 0, 1, 1, 2},
{2, 1, 1, 0, 0, 1, 1, 2},
{5, 1, 1, 1, 1, 1, 1, 5},
{-1, -10, 1, 1, 1, 1, -10, -1},
{50, -1, 5, 2, 2, 5, -1, 50}};
@Override
public void init( int order, long t, Random rnd ) {
this.data = new OthelloDatenstruktur();
this.order = order;
this.rnd = rnd;
this.posMoves = new LinkedList<Move>();
this.possibleMoves = new HashMap<Move, Integer>();
if(this.order==0){
me=Status.black;
opp=Status.white;
}
else if(this.order==1){
me=Status.white;
opp=Status.black;
}
else throw new IllegalArgumentException();
data.setRandom(this.rnd);
}
@Override
public Move nextMove(Move prevMove, long tOpponent, long t ) {
data.move(prevMove, opp);
fillPosMoves();
Move bestMove = null;
int bestMoveScore = -1000;
for (Map.Entry<Move, Integer> entry : possibleMoves.entrySet()) {
if (entry.getValue() > bestMoveScore) {
bestMove = entry.getKey();
bestMoveScore = entry.getValue();
}
}
System.out.println("Best: " + bestMove.x + "," + bestMove.y + " score: " + bestMoveScore);
return bestMove;
}
private void fillPosMoves(){
for(int i=0; i<8; i++)
for(int j=0; j<8; j++)
if(data.isValid(new Move(i,j), me))
{
this.posMoves.add(new Move(i,j));
this.possibleMoves.put(new Move(i,j), squareScores[i][j]);
}
}
}
OthelloDatenstruktur
Java:
package othello;
import szte.mi.*;
import java.util.*;
enum Status {nil ,black , white};
public class OthelloDatenstruktur {
Status [][] board = new Status[8][8];
int [] counter = new int[2]; // 0 = schwarz, 1 = weiß
boolean PassCounter;
Random rnd;
public OthelloDatenstruktur() {
clear();
}
public Status get(int x, int y) {
return board[x][y];
}
public void set(Move move, Status player) {
switch (board[move.x][move.y]) {
case white: counter[1]--; break;
case black: counter[0]--; break;
}
board[move.x][move.y]=player;
switch (player) {
case white: counter[1]++; break;
case black: counter[0]++; break;
}
}
public void setRandom(Random rnd){
this.rnd = rnd;
}
public int getCounter(Status player) {
return counter[player.ordinal()-1];
}
public void clear() {
for (int i = 0 ; i < 8 ; i++)
for (int j = 0 ; j < 8 ; j++)
board[i][j]=Status.nil;
board[3][4]=Status.black;
board[4][3]=Status.black;
board[3][3]=Status.white;
board[4][4]=Status.white;
counter[0] = 2;
counter[1] = 2;
PassCounter = false;
}
public void println() {
System.out.print("[");
for (int i = 0 ; i < 8 ; i++) {
for (int j = 0 ; j < 8 ; j++)
System.out.print(board[i][j]+",");
System.out.println((i == 7? "]":""));
}
}
public int move(Move move, Status stat) {
return checkBoard(move,stat);
}
public boolean gameEnd() {
return counter[0]+counter[1]==64;
}
private int Check(Move move, int incx, int incy, Status stat , boolean set) {
Status opponent;
int x=move.x;
int y=move.y;
if (stat == Status.black) opponent=Status.white; else opponent=Status.black;
int n_inc=0;
if (board[x][y] != Status.nil) {
return 0;
}
if (board[x][y] == board[3][4] || board[x][y] == board[4][3] || board[x][y] == board[3][3] || board[x][y] == board[4][4]){
return 0;
}
x+=incx; y+=incy;
while ((x<8) && (x>=0) && (y<8) && (y>=0) && (board[x][y]==opponent)) {
x+=incx; y+=incy;
n_inc++;
}
if ((n_inc != 0) && (x<8) && (x>=0) && (y<8) && (y>=0) && (board[x][y]==stat)) {
if (set)
for (int j = 1 ; j <= n_inc ; j++) {
x-=incx; y-=incy;
set(new Move(x,y),stat);
}
return n_inc;
}
else return 0;
}
public int checkBoard(Move move, Status stat) {
int y=Check(move,1,0,stat,true);
y+=Check(move,-1,0,stat,true);
y+=Check(move,0,1,stat,true);
y+=Check(move,0,-1,stat,true);
y+=Check(move,1,1,stat,true);
y+=Check(move,-1,1,stat,true);
y+=Check(move,1,-1,stat,true);
y+=Check(move,-1,-1,stat,true);
if (y != 0) set(move,stat);
return y;
}
public boolean isValid(Move move, Status stat) {
if (Check(move,1,0,stat,false) != 0) return true;
if (Check(move,-1,0,stat,false) != 0) return true;
if (Check(move,0,1,stat,false) != 0) return true;
if (Check(move,0,-1,stat,false) != 0) return true;
if (Check(move,1,1,stat,false) != 0) return true;
if (Check(move,-1,1,stat,false) != 0) return true;
if (Check(move,1,-1,stat,false) != 0) return true;
if (Check(move,-1,-1,stat,false) != 0) return true;
return false;
}
public boolean userCanMove(Status player) {
for (int i = 0 ; i < 8 ; i++)
for (int j = 0 ; j < 8 ; j++)
if ((board[i][j] == Status.nil) && isValid(new Move(i,j),player)) return true;
return false;
}
}
Vielen lieben Dank für jede Hilfe.