/*****************************/
/*VierGewinnt3D © t.heyn 2001*/
/*****************************/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.Vector;
public class VierGewinnt3D extends Applet implements Konstanten, ActionListener, ItemListener
{
Cube3D platte = new Cube3D(new Point3D(-50,0,-50), new Vector3D(100,10,100));//platte
Stab stab[][] = new Stab[4][4];//stäbe
Stab temp[] = new Stab[3];
Matrix matrix = new Matrix(new double[4][4]);//globale tranformationsmatrix
Vector sorter = new Vector(16);
Color farbe [] = {new Color(140,90,20),new Color(140,140,50),new Color(0,0,0),new Color(140,90,20)};
int gitter[][][] = new int[4][4][4];
int distanz=100;
int werBeginnt=HELL, derLevel=ANFAENGER;
int total, sieger=0;
int mausX, mausY;
int woHatsVier;
double xtheta=0.6, ytheta=0.4;
TextArea text= new TextArea("",15,12,TextArea.SCROLLBARS_NONE);
Choice anfang = new Choice();
Choice level = new Choice();
AudioClip ton[] = new AudioClip[5];
Image HintergrundBild = null;
Image hintergrund;
Graphics HintergrundGrafik = null;
public void init()
{
laden();
showStatus("Vier gewinnt 3D © t.heyn 2001");
setLayout(new BorderLayout());
addMouseMotionListener(new MyMouseMotion());
addMouseListener(new MyMouse());
Panel anzeige = new Panel();
anzeige.setLayout(new BorderLayout());
add("East",anzeige);
Label titel = new Label("Vier gewinnt 3D",Label.CENTER);
titel.setBackground(Color.yellow);
titel.setFont(new Font("SansSerif",Font.BOLD,18));
anzeige.add("North",titel);
anzeige.add("Center",text);
text.setEnabled(false);
Panel controls = new Panel();
controls.setLayout(new BorderLayout());
anzeige.add("South",controls);
anfang.add("Weiss beginnt");
anfang.add("Schwarz beginnt");
anfang.addItemListener(this);
controls.add("Center",anfang);
level.add("Anfänger");
level.add("Normalo");
level.add("Profi");
level.addItemListener(this);
controls.add("North",level);
Button neu= new Button("Neues Spiel");
neu.addActionListener(this);
controls.add("South",neu);
//initialisieren der globalen tranformationsmatrix
matrix.initMatrix();
matrix.rotate(xtheta,ytheta,0); //nach vorne kippen
//grundplatte berechnen
platte.setColor(farbe[PLATTE]);
platte.updateCube(matrix,DISTANZ);
//stäbe
neuesSpiel();
}
public void paint(Graphics g)
{
boolean sortiert=false;
g.drawImage(hintergrund,0,0,null);
g.translate(X_URSPRUNG,Y_URSPRUNG);
if (platte.r[3].visible) platte.paint(g);
//zuerst alle stäbe in vector einlesen
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
sorter.addElement(stab[i][j]);
}
}
//dann sortieren nach entfernung vom betrachter mit bubble sort
while (! sortiert)
{
sortiert=true;
for (int i=0;i<15;i++)
{
temp[1]=(Stab)sorter.elementAt(i);
temp[2]=(Stab)sorter.elementAt(i+1);
if (temp[2].p[0].wz > temp[1].p[0].wz)
{
sorter.setElementAt(temp[2],i);
sorter.setElementAt(temp[1],i+1);
sortiert=false;
}
}
}
//und von hinten nach vorne zeichnen
for (int i=0;i<16;i++)
{
temp[0]=(Stab)sorter.elementAt(i);
if (! platte.r[3].visible) temp[0].vonUnten=true;
else temp[0].vonUnten=false;
temp[0].paint(g);
}
sorter.removeAllElements();
if (! platte.r[3].visible) platte.paint(g);
}
public final void update(Graphics g) //double buffering
{
if(HintergrundBild==null) HintergrundBild = createImage(2*X_URSPRUNG,2*Y_URSPRUNG);
HintergrundGrafik = HintergrundBild.getGraphics();
HintergrundGrafik.clearRect(0,0,2*X_URSPRUNG,2*Y_URSPRUNG);
paint(HintergrundGrafik);
g.drawImage(HintergrundBild,0,0,null);
}
public void itemStateChanged(ItemEvent e) // all die doofen listener
{
String farbe=(String) anfang.getSelectedItem();
if (farbe=="Weiss beginnt") werBeginnt=HELL;
if (farbe=="Schwarz beginnt") werBeginnt=DUNKEL;
String grad=(String) level.getSelectedItem();
if (grad=="Anfänger") derLevel=ANFAENGER;
if (grad=="Normalo") derLevel=NORMALO;
if (grad=="Profi") derLevel=PROFI;
neuesSpiel();
}
public void actionPerformed(ActionEvent e)
{
neuesSpiel();
}
private class MyMouseMotion extends MouseMotionAdapter
{
public void mouseDragged(MouseEvent e)
{
matrix.initMatrix();
xtheta += (e.getY() - mausY) * (5.0f / size().width);
ytheta += (mausX - e.getX()) * (5.0f / size().height);
matrix.rotate(xtheta,ytheta,0);
platte.updateCube(matrix,distanz);
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
stab[i][j].updateCube(matrix,distanz);
}
}
mausX=e.getX();
mausY=e.getY();
update(getGraphics());
}
}
private class MyMouse extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
mausX=e.getX();
mausY=e.getY();
if (sieger>0) return;
//stab berechnen
int dx, dy;
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
dx= (int) stab[i][j].p[3].sx-mausX+X_URSPRUNG;
dy= (int) stab[i][j].p[3].sy-mausY+Y_URSPRUNG;
if (dx*dx+dy*dy<=49 && stab[i][j].anzahlKugeln<4)
{
setzen(HELL,i,j);
if (siegtest(HELL)) schluss(HELL);
if (total==64) schluss(REMIS);
if (sieger>0) return;
computerZugBerechnen();
if (total==64) schluss(REMIS);
return;
}
}
}
}
}
private void computerZugBerechnen()
{
int dringendste=TABU;
gefahrtest();
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
stab[i][j].prioritaet=0;
//nächster stab wenn dieser voll ist
if (stab[i][j].anzahlKugeln>=4)
{
stab[i][j].prioritaet=GERINGSTE;
continue;
}
//eigenen sieg suchen und setzen
gitter[i][j][stab[i][j].anzahlKugeln]=DUNKEL;
if (siegtest(DUNKEL))
{
setzen(DUNKEL,i,j);
schluss(DUNKEL);
return;
}
//sieg gegner verhindern
gitter[i][j][stab[i][j].anzahlKugeln]=HELL;
if (siegtest(HELL))
{
setzen(DUNKEL,i,j);
return;
}
gitter[i][j][stab[i][j].anzahlKugeln]=0;
//test ob stab tabu für schwarz
if (tabutest(HELL,i,j) && derLevel != ANFAENGER)
{
stab[i][j].prioritaet=TABU;
continue;
}
//test auf doppelmoppel für schwarz
if (doppeltest(DUNKEL,i,j) && derLevel == PROFI)
{
stab[i][j].prioritaet=200;
dringendste=200;
continue;
}
//test ob stab tabu für weiss
if (tabutest(DUNKEL,i,j) && derLevel != ANFAENGER)
{
stab[i][j].prioritaet=TABU+10;
continue;
}
//nächsten zug testen
if (derLevel == PROFI) stab[i][j].prioritaet += 10*naechsterZugTest(HELL,i,j);
if (derLevel != ANFAENGER) stab[i][j].prioritaet += 5*naechsterZugTest(DUNKEL,i,j);
//besser nicht auf leeren stab setzen
if (derLevel == PROFI && stab[i][j].anzahlKugeln==0) stab[i][j].prioritaet -=5;
//dringendsten stab rausfinden
if (stab[i][j].prioritaet>dringendste) dringendste=stab[i][j].prioritaet;
}
}
//zufällig setzen auf einen stab mit höchster priorität
int i=0,j=0;
boolean suchen=true;
while (suchen)
{
i=(int)(Math.random()*4);
j=(int)(Math.random()*4);
if (stab[i][j].prioritaet==dringendste) suchen=false;
}
setzen(DUNKEL,i,j);
return;
}
private boolean siegtest(int farbe)
{
int anzahl;
for (int test=0;test<76;test++)
{
anzahl=0;
for (int kugel=0;kugel<4;kugel++)
{
if (gitter[testdaten[4*test+kugel][0]] [testdaten[4*test+kugel][1]] [testdaten[4*test+kugel][2]] == farbe) anzahl++;
}
if (sieger>0 && anzahl==4)//wenn spiel fertig dann markieren
{
for (int kugel=0;kugel<4;kugel++)
{
stab[testdaten[4*test+kugel][0]] [testdaten[4*test+kugel][1]].kugel[testdaten[4*test+kugel][2]].markieren();
}
}
if (anzahl==4) return true;
}
return false;
}
private void gefahrtest()//testet alle leeren positionen, ob hier 4 erreicht werden könnten
{
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
int hoehe=stab[i][j].anzahlKugeln;
for (int h=0;h<4;h++) //gefahren setzen
{
if (gitter[i][j][h] != 0) continue;
gitter[i][j][h]=DUNKEL;
if (siegtest(DUNKEL)) stab[i][j].gefahr[h]=DUNKEL;
gitter[i][j][h]=HELL;
if (siegtest(HELL)) stab[i][j].gefahr[h]=HELL;
gitter[i][j][h]=0;
}
}
}
}
private int naechsterZugTest(int farbe, int i, int j)
{
gitter[i][j][stab[i][j].anzahlKugeln]=farbe;
stab[i][j].anzahlKugeln++;
int anzahl=0;
//alle stäbe ausprobieren
for (int x=0;x<4;x++)
{
for (int y=0;y<4;y++)
{
if (stab[x][y].anzahlKugeln>=4) continue;
int dieserStab=0;
for (int h=stab[x][y].anzahlKugeln;h<4;h++)
{
gitter[x][y][h]=farbe;
if (siegtest(farbe))
{
anzahl++;
//wenn 2 siege übereinander möglich dann wichtig
dieserStab++;
if (dieserStab==2) anzahl+=20;
}
else dieserStab=0;
gitter[x][y][h]=0;
}
}
}
stab[i][j].anzahlKugeln--;
gitter[i][j][stab[i][j].anzahlKugeln]=0;
return anzahl;
}
private boolean tabutest(int farbe, int i, int j)
{
if (stab[i][j].anzahlKugeln < 3)
{
if (stab[i][j].gefahr[stab[i][j].anzahlKugeln+1]==farbe) return true;
}
return false;
}
private boolean doppeltest(int farbe, int i, int j)
{
if (stab[i][j].anzahlKugeln >= 3) return false;
int doppel=0;
if (tabutest(DUNKEL,i,j)) doppel++;
gitter[i][j][stab[i][j].anzahlKugeln]=farbe;
stab[i][j].anzahlKugeln++;
if (tabutest(DUNKEL,i,j)) doppel++;
stab[i][j].anzahlKugeln--;
gitter[i][j][stab[i][j].anzahlKugeln]=0;
if (doppel==2) return true;
return false;
}
private void schluss(int farbe)
{
sieger=farbe;
text.append("\n\n"+kommentar[sieger]);
siegtest(sieger);
update(getGraphics());
ton[sieger].play();
}
private void neuesSpiel()
{
sieger=0;
total=0;
for (int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
stab[i][j] = new Stab(new Point3D(-40+(25*i),-43,-40+(25*j)), new Vector3D(1,43,1));
stab[i][j].setColor(farbe[STAB]);
stab[i][j].updateCube(matrix,distanz);
for (int k=0;k<4;k++)
{
gitter[i][j][k]=0;
}
}
}
schreiben();
if (werBeginnt==DUNKEL) setzen(DUNKEL, (int)(Math.random()*4), (int)(Math.random()*4));
update(getGraphics());
ton[0].play();
}
private void setzen(int was, int i, int j)
{
schreiben();
total++;
gitter[i][j][stab[i][j].anzahlKugeln]=was;
stab[i][j].kugelDazu(farbe[was]);
stab[i][j].updateCube(matrix,distanz);
update(getGraphics());
ton[4].play();
}
private void schreiben()
{
text.setText("Wer zuerst vier waagrecht, senkrecht oder diagonal hat, gewinnt. Du hast Weiss, "
+"der Computer Schwarz. Klicke die Spitze des Stabes an, wenn du setzen willst. "
+"\n\nDu kannst das ganze Spiel mit der Maus drehen.");
//for (int t=0;t<4;t++) text.append("\n"+stab[t][0].prioritaet+" "+stab[t][1].prioritaet+" "+stab[t][2].prioritaet+" "+stab[t][3].prioritaet+" ");
}
private void laden()
{
for (int t=0;t<5;t++)
{
ton[t]= getAudioClip(getCodeBase(),""+t+".au");
}
MediaTracker tracker=new MediaTracker(this);
hintergrund = getImage(getCodeBase(),"hintergrund.gif");
tracker.addImage(hintergrund,1);
try
{
tracker.waitForAll();
}
catch(InterruptedException e) {}
}
}
Zusätzliche Klassen
//Stab//
import java.awt.*;
public class Stab extends Cube3D implements Konstanten
{
int anzahlKugeln, prioritaet, distance;
boolean istAktiv, vonUnten;
Sphere3D kugel[] = new Sphere3D[4];
int gefahr[] = new int[4];
public Stab(Point3D p0, Vector3D v)
{
super(p0,v);
anzahlKugeln = 0;
istAktiv=false;
vonUnten=false;
prioritaet=0;
}
public void kugelDazu(Color color)
{
if (anzahlKugeln>=4) return;
kugel[anzahlKugeln] = new Sphere3D(new Point3D(p[0].lx,-5-10*anzahlKugeln,p[0].lz),5.5);
kugel[anzahlKugeln].setColor(color);
anzahlKugeln++;
if (anzahlKugeln==4) prioritaet=GERINGSTE;
for (int i=4; i<8; i++)
{
p[i].ly -= 9.9;
}
updateCube(matrix,distance);
}
public void paint(Graphics g)
{
if (! vonUnten) //kugeln zeichnen wenn von oben
{
for (int i=0; i<anzahlKugeln; i++)
{
kugel[i].paint(g);
}
super.paint(g);
}
else //kugeln zeichnen wenn von unten
{
super.paint(g);
for (int i=anzahlKugeln-1; i>=0; i--)
{
kugel[i].paint(g);
}
}
}
public void updateCube(Matrix matrix,int distance)
{
super.updateCube(matrix, distance);
for (int i=0; i<4; i++)
{
if (kugel[i] != null) kugel[i].updateSphere(matrix,distance);
}
}
}
//Kugel//
import java.awt.*;
public class Sphere3D extends Panel
{
Point3D z;
double radius, r;
Color color;
Matrix matrix;
//konstruiert aus dem zentrum und radius die kugel
public Sphere3D (Point3D z, double radius)
{
this.z=z;
this.radius=radius;
setColor(new Color(0,0,0));
}
public void updateSphere(Matrix matrix, int distance)
{
this.matrix=matrix;
project3DTo2D(distance);
createWorldCoordinates();
}
public void setColor(Color color)
{
this.color=color;
repaint();
}
public void markieren()
{
setColor(new Color((color.getRed()+40)%255,color.getGreen(),color.getBlue()));
}
public void paint(Graphics g)
{
int red=color.getRed();
int green=color.getGreen();
int blue=color.getBlue();
//kreise zeichnen
for (int i=(int)(r);i>0;i-=2)
{
if (red<235) red+=20;
if (green<235) green+=20;
if (blue<235) blue+=20;
g.setColor(new Color(red,green,blue));
g.fillOval((int)(z.sx-i),(int)(z.sy-i),i*2,i*2);
}
}
//Projiziert die 3DVektoren der WELT-Koordinaten des Objektes auf 2DVektoren, die die BILDSCHIRM-
//Koordinaten des Objektes angeben.
public void project3DTo2D(int distance)
{
z.sx = 200 * z.wx / (z.wz+distance);
z.sy = 200 * z.wy / (z.wz+distance);
r = 200 * radius / (z.wz+distance);
}
//Multipliziert die 3DVektoren der LOKALEN-Koordinaten des Objektes mit der Transformationsmatrix,
//die die Daten für Rotation,Verschiebung,Skalierung enthält, und speichert die Berechnungen
//als die WELT-Koordinaten des Objektes ab.
public void createWorldCoordinates()
{
z.wx = z.lx*matrix.mm[0][0] + z.ly*matrix.mm[1][0] + z.lz*matrix.mm[2][0] + matrix.mm[3][0];
z.wy = z.lx*matrix.mm[0][1] + z.ly*matrix.mm[1][1] + z.lz*matrix.mm[2][1] + matrix.mm[3][1];
z.wz = z.lx*matrix.mm[0][2] + z.ly*matrix.mm[1][2] + z.lz*matrix.mm[2][2] + matrix.mm[3][2];
}
}
//Quader//
import java.awt.*;
public class Cube3D extends Panel
{
Rectangle3D r[] = new Rectangle3D[6];
Point3D p[] = new Point3D[8];//eckpunkte
Matrix matrix;
//konstruiert aus dem scheitelpunkt und dem vektor der körperdiagonalen den quader (normal)
public Cube3D(Point3D p0, Vector3D v)
{
p[0] = new Point3D(p0.lx, p0.ly, p0.lz);
p[1] = new Point3D(p0.lx, p0.ly, p0.lz+v.z);
p[2] = new Point3D(p0.lx+v.x, p0.ly, p0.lz+v.z);
p[3] = new Point3D(p0.lx+v.x, p0.ly, p0.lz);
p[4] = new Point3D(p0.lx, p0.ly+v.y, p0.lz);
p[5] = new Point3D(p0.lx, p0.ly+v.y, p0.lz+v.z);
p[6] = new Point3D(p0.lx+v.x, p0.ly+v.y, p0.lz+v.z);
p[7] = new Point3D(p0.lx+v.x, p0.ly+v.y, p0.lz);
r[0] = new Rectangle3D(p[3],p[0],p[4],p[7]); // vorne
r[1] = new Rectangle3D(p[6],p[5],p[1],p[2]); // hinten
r[2] = new Rectangle3D(p[5],p[6],p[7],p[4]); // oben
r[3] = new Rectangle3D(p[2],p[1],p[0],p[3]); // unten
r[4] = new Rectangle3D(p[2],p[3],p[7],p[6]); // rechts
r[5] = new Rectangle3D(p[0],p[1],p[5],p[4]); // links
setColor(new Color(200,200,200));
}
public void paint(Graphics g)
{
for (int i=0; i<6; i++) //sechs seiten zeichnen wenn sichtbar
{
if (r[i].visible)
{
int arx[] = { (int)r[i].p1.sx, (int)r[i].p2.sx, (int)r[i].p3.sx, (int)r[i].p4.sx };
int ary[] = { (int)r[i].p1.sy, (int)r[i].p2.sy, (int)r[i].p3.sy, (int)r[i].p4.sy };
g.setColor(r[i].color);
g.fillPolygon(arx,ary,arx.length);
}
}
}
public void setColor(Color c)
{
Color c1 = c.darker();
r[0].color = c.brighter();
r[1].color = c1.darker();
r[2].color = c;
r[3].color = c;
r[4].color = c.darker();
r[5].color = c.darker();
}
public void updateCube(Matrix matrix,int distance)
{
this.matrix=matrix;
for (int i=0; i<6; i++)
{
createWorldCoordinates(r[i]);
project3DTo2D(r[i],distance);
backfaceCulling(r[i]);
}
}
//Multipliziert die 3DVektoren der LOKALEN-Koordinaten des Objektes mit der Transformationsmatrix,
//die die Daten für Rotation,Verschiebung,Skalierung enthält, und speichert die Berechnungen als die WELT-
//Koordinaten des Objektes ab.
public void createWorldCoordinates(Rectangle3D r)
{
Point3D p[] = { r.p1, r.p2, r.p3, r.p4 };
for (int i=0; i<4; i++)
{
p[i].wx = p[i].lx*matrix.mm[0][0] + p[i].ly*matrix.mm[1][0] + p[i].lz*matrix.mm[2][0] + matrix.mm[3][0];
p[i].wy = p[i].lx*matrix.mm[0][1] + p[i].ly*matrix.mm[1][1] + p[i].lz*matrix.mm[2][1] + matrix.mm[3][1];
p[i].wz = p[i].lx*matrix.mm[0][2] + p[i].ly*matrix.mm[1][2] + p[i].lz*matrix.mm[2][2] + matrix.mm[3][2];
}
}
//Projiziert die 3DVektoren der WELT-Koordinaten des Objektes auf 2DVektoren, die die BILDSCHIRM-Koordinaten
//des Objektes angeben.
public void project3DTo2D(Rectangle3D r, int distance)
{
Point3D p[] = { r.p1, r.p2, r.p3, r.p4 };
for (int i=0; i<4; i++)
{
p[i].sx = 200 * p[i].wx / (p[i].wz+distance);
p[i].sy = 200 * p[i].wy / (p[i].wz+distance);
}
}
//Berechnet, in welche Richtung das Polygon zeigt. Die Formel ist die letzte Zeile des Vektorproduktes
//und gibt die z-Koordinate des Normalenvektors aus den ersten drei Punkten des Polygons an (BILDSCHIRM-
//Koordinaten). Ist z positiv, so zeigt die Fläche mindestens 90 Grad vom Betrachter weg.
public void backfaceCulling(Rectangle3D r)
{
double z = (r.p2.sx-r.p1.sx) * (r.p3.sy-r.p1.sy) - (r.p2.sy-r.p1.sy) * (r.p3.sx-r.p1.sx);
if (z>0) r.visible=false;
else r.visible=true;
}
}
public class Point3D
{
double lx, ly, lz; // lokale Koordinaten
double wx, wy, wz; // Weltkoordinaten
double sx, sy; // Bildschirmkoordinaten
//Konstruiert aus den übergebenen double Werten einen Punkt mit 3D Koordinaten
public Point3D(double X, double Y, double Z)
{
this.lx = X;
this.ly = Y;
this.lz = Z;
}
}
public class Vector3D
{
double x, y, z;
double abs; //betrag
//Konstruiert aus den übergebenen double Werten einen 3D Vektor
public Vector3D(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
abs = Math.sqrt(x*x + y*y + z*z);
}
}
public class Rectangle3D
{
protected Point3D p1, p2, p3, p4; // Die vier Eckpunte
protected boolean visible = true; // Für BackfaceCulling
protected Color color; // Farbe der Fläche
//Konstruiert aus den übergebenen Scheitelpunkten ein Rechteck mit 3D Koordinaten.
public Rectangle3D(Point3D P1, Point3D P2, Point3D P3, Point3D P4)
{
this.p1 = P1;
this.p2 = P2;
this.p3 = P3;
this.p4 = P4;
}
}
public class Matrix
{
double mm[][];
public Matrix(double mm[][])
{
this.mm=mm;
}
// Berechnet die Rotationsmatrizen aller drei Achsen
// und multipliziert diese mit der Transformationsmatrix.
// Rotationswinkel der Achsen in Radian
public void rotate(double ax, double ay, double az)
{
if (ax!=0.0)// x-Rotationsmatrix
{
double mat1[][] = new double[4][4];
double xmat[][] = new double[4][4];
xmat[0][0]=1; xmat[0][1]=0;
xmat[0][2]=0; xmat[0][3]=0;
xmat[1][0]=0; xmat[1][1]=Math.cos(ax);
xmat[1][2]=Math.sin(ax); xmat[1][3]=0;
xmat[2][0]=0; xmat[2][1]=-1*Math.sin(ax);
xmat[2][2]=Math.cos(ax); xmat[2][3]=0;
xmat[3][0]=0; xmat[3][1]=0;
xmat[3][2]=0; xmat[3][3]=1;
matrixMultiplication(mat1,xmat,mm);
matrixCopy(mm,mat1);
}
if (ay!=0.0)// y-Rotationsmatrix
{
double mat1[][] = new double[4][4];
double ymat[][] = new double[4][4];
ymat[0][0]=Math.cos(ay); ymat[0][1]=0;
ymat[0][2]=-1*Math.sin(ay);ymat[0][3]=0;
ymat[1][0]=0; ymat[1][1]=1;
ymat[1][2]=0; ymat[1][3]=0;
ymat[2][0]=Math.sin(ay); ymat[2][1]=0;
ymat[2][2]=Math.cos(ay); ymat[2][3]=0;
ymat[3][0]=0; ymat[3][1]=0;
ymat[3][2]=0; ymat[3][3]=1;
matrixMultiplication(mat1,ymat,mm);
matrixCopy(mm,mat1);
}
if (az!=0.0)// z-Rotationsmatrix
{
double mat1[][] = new double[4][4];
double zmat[][] = new double[4][4];
zmat[0][0]=Math.cos(az); zmat[0][1]=Math.sin(az);
zmat[0][2]=0; zmat[0][3]=0;
zmat[1][0]=-1*Math.sin(az);zmat[1][1]=Math.cos(az);
zmat[1][2]=0; zmat[1][3]=0;
zmat[2][0]=0; zmat[2][1]=0;
zmat[2][2]=1; zmat[2][3]=0;
zmat[3][0]=0; zmat[3][1]=0;
zmat[3][2]=0; zmat[3][3]=1;
matrixMultiplication(mat1,zmat,mm);
matrixCopy(mm,mat1);
}
}
// Methoden für die Matrixrechnungen
//Initialisiert die übergebene 4x4 Matrix als Identitätsmatrix
public void initMatrix()
{
mm[0][0]=1; mm[0][1]=0; mm[0][2]=0; mm[0][3]=0;
mm[1][0]=0; mm[1][1]=1; mm[1][2]=0; mm[1][3]=0;
mm[2][0]=0; mm[2][1]=0; mm[2][2]=1; mm[2][3]=0;
mm[3][0]=0; mm[3][1]=0; mm[3][2]=0; mm[3][3]=1;
}
//Multipliziert die übergebenen Matrizen
//result[][] Speichert das Ergebnis der Multiplikation
//mat1[][] Der erste Faktor der Multiplikation
//mat2[][] Der zweite Faktor der Multiplikation
public void matrixMultiplication(double result[][], double mat1[][], double mat2[][])
{
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
for (int k=0; k<4; k++)
result[i][j] += mat1[i][k] * mat2[k][j];
}
//Kopiert die übergebenen Matrizen
//dest[][] In diese Matrix wird kopiert
//source[][] Aus dieser Matrix wird kopiert
public void matrixCopy(double dest[][], double source[][])
{
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
dest[i][j] = source[i][j];
}
}
//damit die hauptklasse nicht zu gross wird
public interface Konstanten
{
public static final int PLATTE=0, HELL=1, DUNKEL=2, STAB=3;
public static final int REMIS=3;
public static final int ANFAENGER=0, NORMALO=1, PROFI=2;
public static final int X_URSPRUNG=250, Y_URSPRUNG=200;
public static final int DISTANZ=100;
public static final int GERINGSTE=-1000, HOECHSTE=1000, NORMAL=0, TABU=-90;
public final String kommentar[] = {"","Weiss Gewinnt!","Schwarz gewinnt!","Unentschieden"};
public static final int testdaten[][] =
{
//waagrecht seitwärts
{0,0,0},{1,0,0},{2,0,0},{3,0,0}, {0,1,0},{1,1,0},{2,1,0},{3,1,0},
{0,2,0},{1,2,0},{2,2,0},{3,2,0}, {0,3,0},{1,3,0},{2,3,0},{3,3,0},
{0,0,1},{1,0,1},{2,0,1},{3,0,1}, {0,1,1},{1,1,1},{2,1,1},{3,1,1},
{0,2,1},{1,2,1},{2,2,1},{3,2,1}, {0,3,1},{1,3,1},{2,3,1},{3,3,1},
{0,0,2},{1,0,2},{2,0,2},{3,0,2}, {0,1,2},{1,1,2},{2,1,2},{3,1,2},
{0,2,2},{1,2,2},{2,2,2},{3,2,2}, {0,3,2},{1,3,2},{2,3,2},{3,3,2},
{0,0,3},{1,0,3},{2,0,3},{3,0,3}, {0,1,3},{1,1,3},{2,1,3},{3,1,3},
{0,2,3},{1,2,3},{2,2,3},{3,2,3}, {0,3,3},{1,3,3},{2,3,3},{3,3,3},
//waagrecht nach hinten
{0,0,0},{0,1,0},{0,2,0},{0,3,0}, {1,0,0},{1,1,0},{1,2,0},{1,3,0},
{2,0,0},{2,1,0},{2,2,0},{2,3,0}, {3,0,0},{3,1,0},{3,2,0},{3,3,0},
{0,0,1},{0,1,1},{0,2,1},{0,3,1}, {1,0,1},{1,1,1},{1,2,1},{1,3,1},
{2,0,1},{2,1,1},{2,2,1},{2,3,1}, {3,0,1},{3,1,1},{3,2,1},{3,3,1},
{0,0,2},{0,1,2},{0,2,2},{0,3,2}, {1,0,2},{1,1,2},{1,2,2},{1,3,2},
{2,0,2},{2,1,2},{2,2,2},{2,3,2}, {3,0,2},{3,1,2},{3,2,2},{3,3,2},
{0,0,3},{0,1,3},{0,2,3},{0,3,3}, {1,0,3},{1,1,3},{1,2,3},{1,3,3},
{2,0,3},{2,1,3},{2,2,3},{2,3,3}, {3,0,3},{3,1,3},{3,2,3},{3,3,3},
//senkrecht
{0,0,0},{0,0,1},{0,0,2},{0,0,3}, {1,0,0},{1,0,1},{1,0,2},{1,0,3},
{2,0,0},{2,0,1},{2,0,2},{2,0,3}, {3,0,0},{3,0,1},{3,0,2},{3,0,3},
{0,1,0},{0,1,1},{0,1,2},{0,1,3}, {1,1,0},{1,1,1},{1,1,2},{1,1,3},
{2,1,0},{2,1,1},{2,1,2},{2,1,3}, {3,1,0},{3,1,1},{3,1,2},{3,1,3},
{0,2,0},{0,2,1},{0,2,2},{0,2,3}, {1,2,0},{1,2,1},{1,2,2},{1,2,3},
{2,2,0},{2,2,1},{2,2,2},{2,2,3}, {3,2,0},{3,2,1},{3,2,2},{3,2,3},
{0,3,0},{0,3,1},{0,3,2},{0,3,3}, {1,3,0},{1,3,1},{1,3,2},{1,3,3},
{2,3,0},{2,3,1},{2,3,2},{2,3,3}, {3,3,0},{3,3,1},{3,3,2},{3,3,3},
//diagonal waagrecht
{0,0,0},{1,1,0},{2,2,0},{3,3,0}, {3,0,0},{2,1,0},{1,2,0},{0,3,0},
{0,0,1},{1,1,1},{2,2,1},{3,3,1}, {3,0,1},{2,1,1},{1,2,1},{0,3,1},
{0,0,2},{1,1,2},{2,2,2},{3,3,2}, {3,0,2},{2,1,2},{1,2,2},{0,3,2},
{0,0,3},{1,1,3},{2,2,3},{3,3,3}, {3,0,3},{2,1,3},{1,2,3},{0,3,3},
//diagonal seitwärts senkrecht
{0,0,0},{1,0,1},{2,0,2},{3,0,3}, {0,0,3},{1,0,2},{2,0,1},{3,0,0},
{0,1,0},{1,1,1},{2,1,2},{3,1,3}, {0,1,3},{1,1,2},{2,1,1},{3,1,0},
{0,2,0},{1,2,1},{2,2,2},{3,2,3}, {0,2,3},{1,2,2},{2,2,1},{3,2,0},
{0,3,0},{1,3,1},{2,3,2},{3,3,3}, {0,3,3},{1,3,2},{2,3,1},{3,3,0},
//diagonal nach hinten senkrecht
{0,0,0},{0,1,1},{0,2,2},{0,3,3}, {0,0,3},{0,1,2},{0,2,1},{0,3,0},
{1,0,0},{1,1,1},{1,2,2},{1,3,3}, {1,0,3},{1,1,2},{1,2,1},{1,3,0},
{2,0,0},{2,1,1},{2,2,2},{2,3,3}, {2,0,3},{2,1,2},{2,2,1},{2,3,0},
{3,0,0},{3,1,1},{3,2,2},{3,3,3}, {3,0,3},{3,1,2},{3,2,1},{3,3,0},
//körperdiagonalen
{0,0,0},{1,1,1},{2,2,2},{3,3,3}, {0,0,3},{1,1,2},{2,2,1},{3,3,0},
{3,0,0},{2,1,1},{1,2,2},{0,3,3}, {3,0,3},{2,1,2},{1,2,1},{0,3,0},
};
}