The BoardDrawer as a Class

I've just finished drawing my board! It's a truly amazing accomplishment I think, especially since it's taken me many weeks to reach this point, perhaps even a month or more. With childlike enthusiasm I show my mom and my little sister, and they all are very amazed. Perhaps this is a justification of my indulgence in computer science, not only as a hobby but as a major. But, after my many hours of trying to understand a programming language that I've only had contact with for a couple of months in order to manpulate it into a home-grown chess program, I realize that I'm still a very long way from a real accomplishment when my little sister ask, "how do you move the pieces?", and I have no reply. Yes, she's right. At this point everyone can see the pieces and it looks just like any other chess program that anyone has ever seen, but they don't move. The board's DoMove function is just sitting there. Without a move it means nothing.

The BoardDrawer class, despite its name, has to do more than just draw the board. It has to allow the user to use the board that it has drawn and it has to redraw the board. The user uses the board when he clicks on it, so the BoardDrawer has to know when this happens. Let's examine the sequence that takes place when the user moves a piece. First of all, he must click on a piece in order to select it, hence the start of a move which contains a start row and a start col. Then he holds down the mouse button and moves it to the destination square only then releasing it. Therefore, we need to know when the user clicks on a start square and releases on a destination square. But more importantly, we need to know what square he's clicking in.

Before I said the screen is mapped out using coordinates. That applies here to, becuase modern programming languages allow you get the location of the mouse pointer on the screen through a pair of absolute coordinates. Because the clicks are taking place on the board and the board is sufficiently mapped out, we can change these coordinate into integer values that represent what square in the board array the user has clicked on. This is a simple function, but essential to the game. Given one coordinate this function returns what square the user has clicked in by dividing the difference between that coordinate and the start coordinate by the cell size. It's simple and it works. Since the startx and starty are different, we need functions for each.

mouseToarrayX(int i){
    return (i-startx) / cellSize;
}

mouseToarrayY(int i)
    return (i - starty) / cellSize;
}

In JAVA the BoardDrawer is a component and therefore has inherent functions to handle mouse events ranging from mouse clicks to mouse releases. The function excepts an event parameter that contains all the information you could ever need about a mouse click, including the X and Y coordinates of the click. The path is clear now. When a mouse click takes place it will be converted into a board array value and we'll have the start square and start row. The click will be evaluated for one thing, if the user is clicking on his piece. If the user is, then we'll say its a valid move and allow it by setting a boolean validSelection to true.

public void mouseClicked(MouseEvent e){
    boolean validSelection = false;
    sRank = mouseToarrayX(e.getX());
    sFile = mouseToarrayY(e.getY()):
    if(board[sFile][sRank].getColor == getSide()){
        validSelection = true;
    }
}

For the mouseReleased we must check to see if the mouseClicked routine validated a selection. Then we make sure of two things:

  • The user didn't try to capture his own piece
  • The move was valid. If these two conditions are true the move is valid.

public void mouseReleased(MouseEvent e){
    if(validSelection){
        eRank = mouseToarrayX(e.getX());
        eFile = mouseToarrayY(e.getY());
        if(board[sFile][sRank].getColor() == board[sFile][sRank].getColor())
            return;
        //a move object
        Move move = new Move(sRank, sFile, eRank, eFile);
        if(moveProvedInvalid(move)){
            return;
        //now do the move
        DoMove(move);
        repaint();//repaint the component
    }
}

Now the pieces will move. Notice that I used the functions of the board class as if we were in the board. This is not the case. The BoardDrawer in fact has its own board that it uses to implement these functions. Now that you've gotten this far I give you your next prize, the skeleton of my board class with no codes, but just the functions it uses. Take it, enhance it, and read the next section. Cherish your boarddrawer class and please don't name you boarddrawer class BoardDrawer. Be original. Don't take it for granted. You've achieved more with your chess program so far than many computer science students ever will. You have developed something beautiful and unique, that is the definition of a boarddrawer...beautiful and unique.

class BoardDrawer extends Canvas implements MouseListener, MouseMotionListener{
    //here some new concepts will pop up, don't be surprised!
   
    //debugging or not
    private final boolean DEBUG = Driver.BOARDDRAWERDEBUG;  
    
    /square colors
    private Color sqColor1;
    private Color sqColor2;

    //the modes of the boarddrawer
    private boolean PGNMODE = false;
    private boolean PLAYMODE = true;
    private boolean SETUPMODE = false;

    //holds type of capturing piece
    private int[] whiteCapturingTypes;
    private int[] blackCapturingTypes;

    //associated counters
    private int w = 0;
    private int b = 0;

    //pieces in the map
     private Piece[][] map;
     private boolean setUp = false;

     //manages the movearray
     private MoveHandler mh = new MoveHandler();
    
     //for accessing the table model for the updating of tables
     private QueField field;
    Que q = new Que();

     //for any required counting
     Counter counter = new Counter();

     //holds the incheck symbol...for printing
     private String inCheck;
    
      //holds the current move symbol
     private String move;

     private boolean first = true;

     //holds the current move object
     private Move thisMove = new Move();
     //determines side of castling
     private boolean castlingKingSide;
     private boolean ambiguous = false;
     //for printing: is this a castling move
     private boolean castled;
     //for the querying of mvoes
     private int iStartRow, iStartCol, iEndCol, iEndRow;

     //for drawing to board and collecting the arrea of mouseClicks
     private int nMapWidth, nMapHeight;
     private int nBoardWidth;
     private int nStartX;
     private int nStartY;
     private int nMapStartX, nMapStartY;
     private int nImageOffset = 0;
     private int nImageWidth = 32;
     private int hXCoords, hYCoords;
     private int ChangeXCoords=0, ChangeYCoords=0;
    
     //string to hold debuggin info
     private String strStatus;
    
      //is the current piece selection valid
     private boolean validSelection = true;
    
     //for the drawing of the board
     private Image[][] imageArray;
     private int iCellSize = 35;
    
     //conversion of formats
     private StringConverter c = new StringConverter();
    
     //analysis moves for checks and pins
     private MoveAnalyzer m = new MoveAnalyzer(Mila);
    
     //the board array
     static Board Mila = new Board();
    
     //holds the rectangular bounds of the board component
     private Rectangle rectBounds;
    
     private boolean capturingMove;
    
     private boolean appendArea = false;

     the constructor
     public BoardDrawer(QueField field, Image[][] imageArray){}

     //the many functions of my BoardDrawer class
     private void initCaptures(){}

     private void initMap(){}

     public void paint(Graphics g){}

     public void clearBoard(){}

     public void drawHighlight(Graphics g){}

     public void clearCaptures(Graphics g){}

     public void clearMap(Graphics g){}

     public void drawCaptures(Graphics g){}

     public void drawCaptureSquare(Graphics g, int nFile, int nRank, boolean white, int temp){}

     public void update(Graphics g){}

    private void drawBoard(Graphics g){}

    private void drawOutLine(Graphics g){}

    public void drawCoordinates(Graphics g, int nFile, boolean rank){}

    public int getSquareX(int nFile){}

    public int getSquareY(int nRank){}

    public int mouseToArrayX(int x){}

    public int mouseToArrayY(int y){}

    public void drawMap(Graphics g){}

    public void drawMapSquare(Graphics g, int nFile, int nRank){}

    public int getCaptureSquareY(int nRank){}

    public int getMapSquareX(int nFile){}

    public int getMapStart(int nFile){}

    public int getCaptureStart(int nRank){}

    public int getMapSquareY(int nRank){}

    public int mouseToMapY(int y){}

    public int mouseToMapX(int x){}

    //move forward through the abstract board array
    public void forward(){}

    //move back
    public void back(){}

    public void start(){}

    //sets up a new game
    public void newGame(){}

    public void End(){}

    //for painting squares
    public boolean checkBlack(int i, int j){}

    //handle mouse events
    public void  mouseReleased(final java.awt.event.MouseEvent evt) {}

    public void mouseClicked(final java.awt.event.MouseEvent p1) {}

    public void mouseMoved(final java.awt.event.MouseEvent evt) {}

    public void printOut(String s){}

    public void showStatus(String s){}

    public void setSquareColor(Color color, Color color2){}

    public Color getSquareColor(int row, int col){}

    public void trimTable(Counter counter, Que q){}

    public void setTable(String move, Que q, Counter counter){}

    public void toArray(PGNReader reader){}

    public void setModePGN(){}

    public void setModePLAY(){}

    public void setModeSETUP(){}
}//BoardDrawer


start  The Move Array