# Relativ FertigesProgramm Objektorientierte Gestalten



## Coldstorm (22. Jan 2009)

Hi,
ich hab vor längerer Zeit mach ein Schachprogramm versucht zu programmieren. Es funktionierte schon einigermaßen, aber zum Beispiel konnte ich noch kein Matt setzen und so Spielerein.
Das Schach war für zwei menschliche Spieler gedacht am selben PC bzw. will es jetzt Netzwerk machen.
Ich hab damals nur eine Klasse geschrieben. Natürlich ist das nicht besonders übersichtlich...kann mir jemand helfen, wie ich das anpacken kann, dass ich den Code objektorientiert mache? Oder zumindest irgendwie übersichtlicher?

Danke im Voraus


Hier der Code:


```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;
import java.applet.*;
import java.lang.Math;

public class chess extends Applet implements MouseListener
{
    Image   imagePieces[];
   
    static final int Black = 0;
    static final int White = 1;

    static final int Leer = -1;
    static final int BauerS = 0;
    static final int TurmS = 1;
    static final int SpringerS = 2;
    static final int LaeuferS = 3;
    static final int DameS = 4;
    static final int KoenigS = 5;
    static final int BauerW = 6;
    static final int TurmW = 7;
    static final int SpringerW = 8;
    static final int LaeuferW = 9;
    static final int DameW = 10;
    static final int KoenigW = 11;

    int anBoard[][];

    int nActivePiece[] = { -1, -1 };

    int nPlayer = White;

    public void init()
    {
    imagePieces = new Image[12];
    imagePieces[ BauerS ] = getImage( getCodeBase(), "images/BauerS.gif" );
    imagePieces[ TurmS ] = getImage( getCodeBase(), "images/TurmS.gif" );
    imagePieces[ SpringerS ] = getImage( getCodeBase(), "images/SpringerS.gif" );
    imagePieces[ LaeuferS ] = getImage( getCodeBase(), "images/LaeuferS.gif" );
    imagePieces[ DameS ] = getImage( getCodeBase(), "images/DameS.gif" );
    imagePieces[ KoenigS ] = getImage( getCodeBase(), "images/KoenigS.gif" );
    imagePieces[ BauerW ] = getImage( getCodeBase(), "images/BauerW.gif" );
    imagePieces[ TurmW ] = getImage( getCodeBase(), "images/TurmW.gif" );
    imagePieces[ SpringerW ] = getImage( getCodeBase(), "images/SpringerW.gif" );
    imagePieces[ LaeuferW ] = getImage( getCodeBase(), "images/LaeuferW.gif" );
    imagePieces[ DameW ] = getImage( getCodeBase(), "images/DameW.gif" );
    imagePieces[ KoenigW ] = getImage( getCodeBase(), "images/KoenigW.gif" );

    // Clear the board
    anBoard = new int[8][8];

    for ( int i = 0; i < 8; ++i )
        for ( int j = 0; j < 8; ++j )
        anBoard[i][j] = Leer;

    anBoard[0][0] = TurmS;
    anBoard[0][1] = SpringerS;
    anBoard[0][2] = LaeuferS;
    anBoard[0][4] = DameS;
    anBoard[0][3] = KoenigS;
    anBoard[0][5] = LaeuferS;
    anBoard[0][6] = SpringerS;
    anBoard[0][7] = TurmS;
    anBoard[1][0] = BauerS;
    anBoard[1][1] = BauerS;
    anBoard[1][2] = BauerS;
    anBoard[1][3] = BauerS;
    anBoard[1][4] = BauerS;
    anBoard[1][5] = BauerS;
    anBoard[1][6] = BauerS;
    anBoard[1][7] = BauerS;

    anBoard[7][0] = TurmW;
    anBoard[7][1] = SpringerW;
    anBoard[7][2] = LaeuferW;
    anBoard[7][4] = DameW;
    anBoard[7][3] = KoenigW;
    anBoard[7][5] = LaeuferW;
    anBoard[7][6] = SpringerW;
    anBoard[7][7] = TurmW;
    anBoard[6][0] = BauerW;
    anBoard[6][1] = BauerW;
    anBoard[6][2] = BauerW;
    anBoard[6][3] = BauerW;
    anBoard[6][4] = BauerW;
    anBoard[6][5] = BauerW;
    anBoard[6][6] = BauerW;
    anBoard[6][7] = BauerW;

    addMouseListener( this );
    }

    public void destroy()
    {
    removeMouseListener( this );
    }

    public void paint( Graphics g )
    {
    Dimension d = getSize();

    Image offScrImage = createImage( d.width, d.height );
    Graphics og = offScrImage.getGraphics();

    int xoff = d.width / 8;
    int yoff = d.height / 8;
   
    /* Draw grid of black/white squares, oriented according
       to whether this player is white or black. */
   
    for ( int c = 0; c < 8; ++c ) {
        for ( int r = 0; r < 8; ++r ) {
        if ( (c + r) % 2 == 0 ) {
            og.setColor( Color.gray );
        } else {
            og.setColor( Color.white );
        }
        og.fillRect( xoff * c, yoff * r, xoff, yoff );

        /* Draw each image according to map */
   
        int nPiece = anBoard[ r ][ c ];
        if ( nPiece >= 0 ) {
            og.drawImage( imagePieces[ nPiece ],
                 c * xoff,
                 r * yoff,
                 this );
        }
        }
    }

    /* Draw rect around active piece */
    if ( nActivePiece[0] >= 0 ) {
        if ( nPlayer == White )
        og.setColor( Color.red );
        else
        og.setColor( Color.blue );

        og.drawRect( xoff * nActivePiece[0],
            yoff * nActivePiece[1],
            xoff, yoff );
        og.drawRect( xoff * nActivePiece[0] - 1,
            yoff * nActivePiece[1] - 1,
            xoff + 2, yoff + 2 );
    }

    g.drawImage( offScrImage, 0, 0, this );
    }

    boolean checkMoveLat( int c1, int r1, int c2, int r2 ) {
    boolean bOK = false;
    int nPiece = anBoard[ r1 ][ c1 ];
    int nPType = nPiece % 6;
    int nDestPiece = anBoard[ r2 ][ c2 ];
    int nDestPType = nDestPiece % 6;

    if ( c1 == c2 && r1 != r2 ) {
        int rd;
        if ( r1 < r2 )
        rd = 1;
        else
        rd = -1;
       
        bOK = true;
        for ( int r = r1 + rd; r != r2; r += rd ) {
        if ( anBoard[ r ][ c1 ] != -1 ) {
            bOK = false;
            break;
        }
        }
    }
    else if ( r1 == r2 && c1 != c2 ) {
        int cd;
        if ( c1 < c2 )
        cd = 1;
        else
        cd = -1;
       
        bOK = true;
        for ( int c = c1 + cd; c != c2; c += cd ) {
        if ( anBoard[ r1 ][ c ] != -1 ) {
            bOK = false;
            break;
        }
        }
    }

    return bOK;
    }

    boolean checkMoveDiag( int c1, int r1, int c2, int r2 ) {
    boolean bOK = false;
    int nPiece = anBoard[ r1 ][ c1 ];
    int nPType = nPiece % 6;
    int nDestPiece = anBoard[ r2 ][ c2 ];
    int nDestPType = nDestPiece % 6;

    if ( (c1 + r1) % 2 == 0 && (c2 + r2) % 2 == 0 ) {
        if ( c1 + r1 == c2 + r2 ) {
        bOK = true;
        }
        else if ( c1 - r1 == c2 - r2 ) {
        bOK = true;
        }
    }
    else if ( (c1 + r1) % 2 == 1 && (c2 + r2) % 2 == 1 ) {
        if ( c1 + r1 == c2 + r2 ) {
        bOK = true;
        }
        else if ( c1 - r1 == c2 - r2 ) {
        bOK = true;
        }
    }
    if ( bOK ) {
        int cd;
        if ( c1 < c2 )
        cd = 1;
        else
        cd = -1;
        int rd;
        if ( r1 < r2 )
        rd = 1;
        else
        rd = -1;

        int r = r1 + rd;
        int c = c1 + cd;
        for ( ; c != c2; r += rd, c += cd ) {
        if ( anBoard[ r ][ c ] != -1 ) {
            bOK = false;
            break;
        }
        }
    }

    return bOK;
    }

    boolean checkMove( int c1, int r1, int c2, int r2 ) {
    if ( c1 == c2 && r1 == r2 )
        return false;

    boolean bOK = false;
    int nPiece = anBoard[ r1 ][ c1 ];
    int nPType = nPiece % 6;
    int nDestPiece = anBoard[ r2 ][ c2 ];
    int nDestPType = nDestPiece % 6;

    switch ( nPType ) {
    case BauerS:
        if ( nPiece < 6 ) {
        if ( c1 == c2 ) {
            if ( r1 == r2 - 1 )    {
            if ( nDestPiece == -1 )
                bOK = true;
            }
            else if ( r1 == r2 - 2 && r1 == 1 ) {
            if ( anBoard[ r2 - 1 ][ c1 ] == -1 )
                bOK = true;
            }
        }
        else if ( c1 == c2 + 1 || c1 == c2 - 1 ) {
            if ( r1 == r2 - 1 )    {
            if ( nDestPiece != -1 && nDestPiece > 5 )
                bOK = true;
            }
        }
        }
        else {
        if ( c1 == c2 ) {
            if ( r1 == r2 + 1 )    {
            if ( nDestPiece == -1 )
                bOK = true;
            }
            else if ( r1 == r2 + 2 && r1 == 6 ) {
            if ( anBoard[ r2 + 1 ][ c1 ] == -1 )
                bOK = true;
            }
        }
        else if ( c1 == c2 + 1 || c1 == c2 - 1 ) {
            if ( r1 == r2 + 1 )    {
            if ( nDestPiece != -1 && nDestPiece < 6 )
                bOK = true;
            }
        }
        }
        break;
    case TurmS:
        bOK = checkMoveLat( c1, r1, c2, r2 );
        break;
    case SpringerS:
        if ( r1 == r2 - 2 || r1 == r2 + 2 ) {
        if ( c1 == c2 - 1 || c1 == c2 + 1 ) {
            bOK = true;
        }
        }
        else if ( c1 == c2 - 2 || c1 == c2 + 2 ) {
        if ( r1 == r2 - 1 || r1 == r2 + 1 ) {
            bOK = true;
        }
        }
        break;
    case LaeuferS:
        bOK = checkMoveDiag( c1, r1, c2, r2 );
        break;
    case DameS:
        bOK = checkMoveLat( c1, r1, c2, r2 );
        if ( bOK == false )
        bOK = checkMoveDiag( c1, r1, c2, r2 );
        break;
    case KoenigS:
        if ( Math.abs( r1 - r2 ) < 2
         && Math.abs( c1 - c2 ) < 2
         && (Math.abs( r1 - r2 ) != 0
             || Math.abs( c1 - c2 ) != 0) )
        bOK = true;
        break;
    default:
        break;
    }

    if ( bOK == true ) {
        if ( nPiece < 6 && (nDestPiece == -1 || nDestPiece > 5) )
        bOK = true;
        else if ( nPiece > 5 && (nDestPiece == -1 || nDestPiece < 6) )
        bOK = true;
        else
        bOK = false;
    }

    return bOK;
    }

    public void mouseReleased( MouseEvent e ) {
    }

    public void mousePressed( MouseEvent e ) {
    }

    public void mouseClicked( MouseEvent e ) {
    if ( nActivePiece[0] >= 0 ) {
        int x = e.getX();
        int y = e.getY();

        // Figure out the row/column
        Dimension d = getSize();
        int c = (int)((x * 8) / d.width);
        int r = (int)((y * 8) / d.height);
        if ( c < 0 || c > 7 )
        return;
        if ( r < 0 || r > 7 )
        return;

        if ( checkMove( nActivePiece[0], nActivePiece[1], c, r ) ) {
        anBoard[ r ][ c ] = anBoard[ nActivePiece[1] ][ nActivePiece[0] ];
        anBoard[ nActivePiece[1] ][ nActivePiece[0] ] = -1;
        nPlayer = (nPlayer + 1) % 2;
        }

        nActivePiece[0] = -1;
        nActivePiece[1] = -1;
    }
    else {
        int x = e.getX();
        int y = e.getY();

        // Figure out the row/column
        Dimension d = getSize();
        int c = (int)((x * 8) / d.width);
        int r = (int)((y * 8) / d.height);
        if ( c < 0 || c > 7 )
        return;
        if ( r < 0 || r > 7 )
        return;

        // Check to see if there's a piece there.
        // If so, set active piece to it.
        if ( anBoard[ r ][ c ] != -1 ) {
        // Check to see who's turn it is
        if ( (anBoard[ r ][ c ] < 6 && nPlayer == 0)
             || (anBoard[ r ][ c ] > 5 && nPlayer == 1)
             ) {
            nActivePiece[0] = c;
            nActivePiece[1] = r;
        }
        }
    }

    repaint();
    }

    public void mouseEntered( MouseEvent e ) {
    }

    public void mouseExited( MouseEvent e ) {
    }
}
```


----------



## Guest (22. Jan 2009)

Coldstorm hat gesagt.:
			
		

> Hi,
> ich hab vor längerer Zeit mal ein Schachprogramm versucht zu programmieren. Es funktionierte schon einigermaßen, aber zum Beispiel konnte ich noch kein Matt setzen und so Spielereien.
> Das Schach war für zwei menschliche Spieler gedacht am selben PC bzw. will es jetzt für Netzwerk machen.
> Ich hab damals nur eine Klasse geschrieben. Natürlich ist das nicht besonders übersichtlich...kann mir jemand helfen, wie ich das anpacken kann, dass ich den Code objektorientiert mache? Oder zumindest irgendwie übersichtlicher?
> ...


----------



## winterwanderer (23. Jan 2009)

Hallo,
auch wenn das ernüchternd klingt. Ich glaube, es ist sinnvoller nochmal ganz neu anzufangen. Dabei kannst du vielleicht einzelne Codebruchstücke wiederverwenden.
Ein objektorientiertes Programm, ist einfach gänzlich anders aufgebaut. Du solltest dir zuerst überlegen, welche relvanten Objekte vorkommen und in welcher Beziehung sie zueinander stehen.
Also: ein *Schachspiel* besteht aus einem *Schachbrett*, *Spielfiguren* und *Spielregeln*, das von einem *Weißspieler* und einem *Schwarzspieler* gespielt wird.
Die Speilfiguren bestehen aus *König*, *Dame*, *Türme*, *Läufer*, *Springer*, *Bauern*. 
Als Regeln sind festgelegt: Regeln, die einzelne Figuren betreffen (wie dürfen einzelne Figuren ziehen) und Regeln, die das gesamte Spielbrett betreffen (z.B. je Feld nur eine Figur, etc.)
Außerdem musst du irgendwo die *Spielsituation* festhalten und dir eine *Bewertung* für die Situation überlegen...
Alle fettgedruckten Wörter können als Klassen fungieren. Es gibt sicher noch weit mehr. Nun mußt du dir überlegen, wie die Klassen in Verbindung zueinander stehen und dir überlegen, welche Funktionen jeder einzelnen Klasse zukommen.

Erst nach diesen Überlegungen (und am besten, nachdem du diese Überlegungen z.B. in einem Klassendiagramm festgehalten hast), solltest du mit der Ausprogrammierung beginnen. Dabei kannst du dann evtl. Codebestandteile wiederverwenden.


----------

