import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JApplet;
import javax.swing.JComponent;
public class JavimkasDame extends JApplet implements MouseListener {
private int s = 64; // size of a field
private Model model;
private Man activeMan; // Gerade gewählter Stein
public void init() {
model = new Model();
Board board = new Board(model);
board.addMouseListener(this);
add(board);
setSize(s*8,s*8);
}
public void mousePressed(MouseEvent e) {
if (!model.turn) return; // Mensch ist nicht dran
if (activeMan!=null) activeMan.setActive(false);
Man man = model.getMan(e.getX(),e.getY()); // Welcher Stein ist an Pos x,y
if (man!=null) {
man.setActive(true);
activeMan = man;
} else { // x,y ist leer
if (activeMan!=null) { // Ist ein Stein gewählt worden
model.moveTo(activeMan,e.getX(),e.getY());
activeMan = null;
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
private class Model {
private volatile boolean turn = true; // Wer ist dran
private Artificial ki; // KI
private Man[] reds;
private Man[] blue;
private Model() {
ki = new Artificial(this);
reds = new Man[12];
blue = new Man[12];
for (int i=0;i<12;i++) {
reds[i] = new Man(i*2%8+i/4%2,i/4,Color.RED);
blue[i] = new Man(i*2%8+(i/4+1)%2,i/4+5,Color.BLUE);
}
}
/**
* Gebe den Stein an Stelle x,y zurück, oder null, wenn das Feld leer ist
*/
private Man getMan(int x, int y) {
for (Man m:reds)
if (m.isThere(x,y)) return m;
for (Man m:blue)
if (m.isThere(x,y)) return m;
return null;
}
private void moveTo(Man man, int x, int y) {
if (isValidMove(x,y)) {
man.setLocation(x/s*s, y/s*s);
turn = !turn;
}
if (!turn) ki.move();
}
/**
* Überprüfe, ob ein neuer Stein auf x,y gesetzt werden kann
*/
public boolean isValidMove(int x, int y) {
return 0<=x && x<8*s && 0<=y && y<8*s // Innerhalb des Boards
&& (x/s+y/s)%2==0 // Feld ist schwarz
&& getMan(x, y)==null; // Feld ist leer
}
}
private class Artificial implements Runnable {
private Model model;
private Artificial(Model model) {
this.model = model;
}
public void move() {
new Thread(this).start();
}
public void run() {
Man man = null;
int x = 0;
int y = 0;
try {
Thread.sleep(1000); // Berechne meinen nächsten Zug
Random rand = new Random();
boolean done = false;
while(!done) {
man = model.reds[rand.nextInt(12)];
int xx = man.getX()+((rand.nextInt(2)==0)?-s:s); // Richtungswahl
int yy = man.getY()+((rand.nextInt(2)==0)?-s:s);
done = model.isValidMove(xx,yy); // true, falls xx,yy leer
x = xx;
y = yy;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
/*
* Könnte man sich überlegen, das mit SwingUtilities im EDT
* laufen zu lassen
*/
model.moveTo(man, x, y);
}
}
}
private class Board extends JComponent {
public Board(Model model) {
for (Man m:model.reds) add(m);
for (Man m:model.blue) add(m);
}
public void paintComponent(Graphics g) {
for (int i=0;i<8;i++) {
for (int j=0;j<8;j++) {
g.setColor((i+j)%2==0?Color.BLACK:Color.WHITE);
g.fillRect(i*s,j*s,s,s);
}
}
}
}
private class Man extends JComponent {
private Color color; // blau oder rot
private boolean active; // true, wenn dieser Stein gerade angewählt wurde
public Man(int x, int y, Color color) {
this.color = color;
setLocation(x*s, y*s);
setSize(s,s);
}
public void paintComponent(Graphics g) {
Color col = active?Color.GREEN:color;
g.setColor(col);
g.fillOval(0,0,s,s);
g.setColor(col.darker());
g.fillOval(s/4,s/4,s/2,s/2);
}
/**
* Wähle den Stein aus oder ab
*/
private void setActive(boolean b) {
this.active = b;
repaint();
}
/**
* true, wenn sich x,y innerhalb des Steins befinden.
* Siehe auch contains(x,y)
*/
public boolean isThere(int x, int y) {
return getX()<=x && x<getX()+getWidth() &&
getY()<=y && y<getY()+getHeight();
}
}
}