Title: Chess with no brains
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Chess with no brains

Chess Game ... what it does:

- This game draws the pieces in their starting place on the Chess board
- Pieces can be dragged and dropped on new squares.

What the Chess Game does not do ... quite a bit

- It doesn't limit the game to 2 players
- It doesn't enforce taking turns ... in fact chaos would ensue if 2 people tried to drag a piece at the same time
- Doesn't know anything about the game of chess ... free for all for where a piece can go. In fact you can stack all of the pieces on top of each other.

Generic Coordinates -

- In a networked game we have the problem of what to do if 2 users have resized their screens differently.
- You could enforce the same size and not allow any resizing by making a call:
setResizable(false);
- I can demo the problem with an earlier version of the chess game:
chess_networked_pixels
- Another approach is to keep the actual pixel values in the View part of your program and translate everything to a common "generic coordinate" system. What this would look like could vary depending on the program you are writing.
- It turns out that in chess a useful choice is to use double x and y values and use numbers between 0 and 7.99999.
- Of course we will need to translate back and forth between generic coordinates and real pixel coordinates. To encapsulate all of this logic, I have provided the routine:
BoardDimensions.java
- The following zip file has the Chess program (including images) along with gameNet and all of the other games discussed in "Networked Programs"
NetworkedPrograms.zip

MyMain.java

same as everything else including guiChat

MyGameInput.java

package chess_networked_generic_coordinates;

import java.io.Serializable;



public class MyGameInput  implements Serializable
{
    static final int CONNECTING=0;
    static final int MOUSE_PRESSED=1;
    static final int MOUSE_RELEASED=2;
    static final int MOUSE_DRAGGED=3;

    String sendersName;
    int cmd=CONNECTING;
    DPoint dpoint=new DPoint(-1,-1);

    public void setName(String n)
    {
        sendersName =n;
    }

    public void setMouseCmd(int cmd, DPoint dp)
    {
        this.cmd=cmd;
        dpoint = dp;
    }

}

class DPoint implements Serializable
{
    double x,y;
    DPoint()
    {
        x=-1;
        y=-1;
    }
    DPoint(double x, double y)
    {
        this.x = x;
        this.y = y;
    }
    DPoint deltaPoint(DPoint secondPoint)
    {
        double dx = secondPoint.x -x;
        double dy = secondPoint.y -y;
        return new DPoint(dx,dy);
    }
}



MyGameOutput.java

package chess_networked_generic_coordinates;

import java.io.Serializable;


public class MyGameOutput  implements Serializable
{
    MyGame myGame=null;

    public MyGameOutput(MyGame mg)
    {
        myGame =mg;
    }

}



MyGame.java

package chess_networked_generic_coordinates;


import java.awt.Graphics;
import java.io.Serializable;

import gameNet.*;


public class MyGame extends GameNet_CoreGame implements Serializable{
    ChessGame chessGame= new ChessGame();


    public Object process(Object ob)
    {
        MyGameInput myGameInput= (MyGameInput)ob;
        switch(myGameInput.cmd)
        {
        case MyGameInput.MOUSE_PRESSED:
            chessGame.mousePressed(myGameInput.dpoint);
            break;
        case MyGameInput.MOUSE_RELEASED:
            chessGame.mouseReleased(myGameInput.dpoint);
            break;
        case MyGameInput.MOUSE_DRAGGED:
            chessGame.mouseDragged(myGameInput.dpoint);
            break;
        case MyGameInput.CONNECTING:
            break;
        }

        return new MyGameOutput(this);
    }




}





ChessGame.java

package chess_networked_generic_coordinates;

import java.awt.Graphics;
import java.io.Serializable;

public class ChessGame implements Serializable{
    private Piece[] pieces = new Piece[32];

    private int selectedIndex = -1;

    private DPoint pressed_point=new DPoint();
    private DPoint dragged_point = new DPoint();


    public ChessGame()
    {
        // Fill in all the pieces and their locations
        int index=0;

        for (int i=0; i < 8; i++) // black pawns in row 1
        {
            pieces[index++] = new Piece(PieceType.Pawn, ColorType.black, i, 1);
        }
        for (int i=0; i < 8; i++) // white pawns in row 6
        {
            pieces[index++] = new Piece(PieceType.Pawn, ColorType.white, i, 6);
        }

        PieceType[] startingKingRow={PieceType.Rook, PieceType.Knight, PieceType.Bishop,
                PieceType.Queen, PieceType.King,
                PieceType.Bishop,PieceType.Knight,PieceType.Rook};

        for (int i=0; i < 8; i++) // black king row in row 0
        {
            pieces[index++] = new Piece(startingKingRow[i], ColorType.black, i, 0);
        }
        for (int i=0; i < 8; i++) // white king row in row 7
        {
            pieces[index++] = new Piece(startingKingRow[i], ColorType.white, i, 7);
        }

    }

    // Draws all pieces into their current location.
    public void drawInPosition(Graphics g, BoardDimensions boardDimensions)
    {
        for (int i=0; i < pieces.length; i++)
        {
            if (i != selectedIndex)
                pieces[i].drawInPosition(g, boardDimensions);
            else
            {
                // The selected piece is still being dragged around
                DPoint delta = pressed_point.deltaPoint(dragged_point);
                pieces[i].dragDraw(g, boardDimensions, delta.x, delta.y);
            }
        }
    }




    void mousePressed(DPoint dpoint)
    {
        pressed_point = dpoint;
        dragged_point = dpoint;

        int xSelectLoc = (int)dpoint.x;
        int ySelectLoc = (int)dpoint.y;

        for (int i=0; i < pieces.length; i++)
        {
            if (pieces[i].areYouHere(xSelectLoc, ySelectLoc))
            {
                selectedIndex = i;
                break;
            }
        }

    }
    void mouseDragged(DPoint dpoint)
    {
        dragged_point = dpoint;
    }
    void mouseReleased(DPoint dpoint)
    {
        pressed_point = dpoint;
        if (selectedIndex >= 0)
        {
            int xSelectLoc = (int)dpoint.x;
            int ySelectLoc = (int)dpoint.y;
            if (xSelectLoc >= 0 && ySelectLoc >= 0)
            {
                pieces[selectedIndex].moveLoc(xSelectLoc, ySelectLoc);
            }
            selectedIndex = -1;
        }
    }


}





Piece.java


package chess_networked_generic_coordinates;

import java.awt.Graphics;
import java.io.Serializable;

enum ColorType {black, white};
enum PieceType {Pawn, Rook, Knight, Bishop, Queen, King};



class Piece implements Serializable
{
    int xSquare, ySquare;
    PieceType pieceType;
    ColorType color;


    Piece (PieceType p, ColorType c, int xSquare, int ySquare)
    {
        this.pieceType=p;
        this.color =c;
        this.xSquare = xSquare;
        this.ySquare = ySquare;
    }

    void moveLoc(int x, int y)
    {
        xSquare = x;
        ySquare = y;
    }
    boolean areYouHere(int xSelectLoc, int ySelectLoc)
    {
        if (xSelectLoc == xSquare && ySelectLoc == ySquare)
            return true;
        else
            return false;
    }

     void drawInPosition(Graphics g, BoardDimensions boardDimensions)
     {
         boardDimensions.boardDraw(g, pieceType, color, xSquare, ySquare);
     }

     // The following will be used while we are dragging piece around
     void dragDraw(Graphics g, BoardDimensions boardDimensions,
             double xDelta, double yDelta)
     {
         boardDimensions.boardDraw(g, pieceType, color, xSquare+xDelta, ySquare+yDelta);
     }

}




ChessPiece


package chess_networked_generic_coordinates;

import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;


class ChessPiece
{
    static PieceType[] pieceType= PieceType.values();
    static ColorType[] colorType = ColorType.values();
    static ChessPiece[][]chessPieces = new ChessPiece[colorType.length][pieceType.length];

    static void readInImages()
    {
        for (int i=0; i < colorType.length; i++)
            for (int j=0; j < pieceType.length; j++)
                chessPieces[i][j] = new ChessPiece(i,j);
    }

    Image pieceImg ;
    int width, height;

    private Image loadImage(String fileName) {
            return new ImageIcon(fileName).getImage();
        }
    ChessPiece(int colorIndex, int pieceIndex)
    {
        String imageName ="images/"+colorType[colorIndex].toString() +
                pieceType[pieceIndex].toString()+".gif";

        pieceImg = loadImage(imageName);
        width = pieceImg.getWidth(null);
        height = pieceImg.getHeight(null);
    }
    void draw(Graphics g, int x, int y, int wSpace, int hSpace)
    {
        double wfraction= (double)width/(double)wSpace;
        double hfraction = (double)height/(double)hSpace;
        int h, w;

        if (hfraction > wfraction)
        {
            h = (int)(height/hfraction);
            w = (int)(width/hfraction);
            x = Math.max(0,x+wSpace/2-w/2);
            g.drawImage(pieceImg,x, y, w,h, null);
        }
        else
        {
            w = (int)(width/wfraction);
            h = (int)(height/wfraction);
            y = Math.max(0,y+hSpace/2 - h/2);
            g.drawImage(pieceImg,x, y, w,h, null);
        }
    }

}




MyUserInterface.java

package chess_networked_generic_coordinates;

import gameNet.GamePlayer;
import gameNet.GameNet_UserInterface;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;



public class MyUserInterface extends JFrame implements GameNet_UserInterface
{
    GamePlayer myGamePlayer;
    MyGameInput myGameInput;
    ChessGame chessGame=null;

    Image offScreenImage=null;
    int lastWidth=-1, lastHeight=-1;

    BoardDimensions boardDimensions = new BoardDimensions();

    MyUserInterface() {
        super("The chessboard is the world, the chessPieces are the phenomena of the universe");
        setSize(600, 600);

        ChessPiece.readInImages();

        MouseClickMonitor ml = new MouseClickMonitor();
        addMouseListener(ml);
        addMouseMotionListener(ml);

        addWindowListener(new Termination());
        //setResizable(false);
    }
    public void startUserInterface (GamePlayer player)
    {
        myGamePlayer = player;

        myGameInput = new MyGameInput();
        myGameInput.setName(player.getPlayerName());
        myGamePlayer.sendMessage(myGameInput); // Default is the "Connecting command"

        setVisible(true);
    }
    public void receivedMessage(Object ob)
    {
        MyGameOutput myGameOutput = (MyGameOutput)ob;
        chessGame = myGameOutput.myGame.chessGame;
        repaint();
    }


    public void paint(Graphics screen) {

        Dimension d = getSize();
        if (d.width != lastWidth || d.height != lastHeight)
        {
            lastWidth = d.width;
            lastHeight = d.height;
            offScreenImage = createImage(lastWidth, lastHeight);
        }
        Graphics g = offScreenImage.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0,0, d.width, d.height);

        Insets insets = getInsets();
        int top = insets.top;
        int left = insets.left;
        int square_width = (d.width - left - insets.right)/8;
        int square_height = (d.height - top - insets.bottom)/8;
        boardDimensions.setParms(left, top, square_width, square_height);

        // Color in the Board squares
        for (int i=0; i < 8; i++)
        {
            for (int j=0; j < 8; j++)
            {
                int x = left +  j*square_width;
                int y = top + i*square_height;
                if ((i+j)%2==1)
                {
                    g.setColor(Color.green);
                    g.fillRect(x, y, square_width, square_height);
                }
                else
                {
                    g.setColor(Color.gray);
                    g.fillRect(x, y, square_width, square_height);
                }
            }
        }// end of outer for loop

        // Draw pieces in their current location
        if (chessGame != null)
        {
            chessGame.drawInPosition(g, boardDimensions);
        }
        // To avoid flicker we copy the offScreenImage to the real screen
        screen.drawImage(offScreenImage, 0,0, this);
    }


    //*******************************************
    // Another Inner class to handle Mouse Events
    //*******************************************
    class MouseClickMonitor extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            DPoint dpoint =  boardDimensions.getDpoint(e.getX(), e.getY());
            if (dpoint != null)
            {
                myGameInput.setMouseCmd(MyGameInput.MOUSE_PRESSED, dpoint);
                myGamePlayer.sendMessage(myGameInput);
            }
        }

        public void mouseReleased(MouseEvent e)
        {
            DPoint dpoint =  boardDimensions.getDpoint(e.getX(), e.getY());
            if (dpoint != null)
            {
                myGameInput.setMouseCmd(MyGameInput.MOUSE_RELEASED, dpoint);
                myGamePlayer.sendMessage(myGameInput);
            }
        }
        public void mouseDragged(MouseEvent e)
        {
            DPoint dpoint =  boardDimensions.getDpoint(e.getX(), e.getY());
            if (dpoint != null)
            {
                myGameInput.setMouseCmd(MyGameInput.MOUSE_DRAGGED, dpoint);
                myGamePlayer.sendMessage(myGameInput);
            }
        }



    }
    //*******************************************
    // Another Inner class
    //*******************************************
    class Termination extends WindowAdapter
    {
        public void windowClosing(WindowEvent e)
        {
            myGamePlayer.doneWithGame();
            System.exit(0);
        }
    }



}





BoardDimensions.java


package chess_networked_generic_coordinates;

import java.awt.Graphics;

public class BoardDimensions {

    private int xstart=-1, ystart=-1;
    double square_width=-1, square_height=-1;


    public void setParms(int xstart, int ystart, double square_width, double square_height)
    {
        this.xstart = xstart;
        this.ystart = ystart;
        this.square_width = square_width;
        this.square_height = square_height;
    }
    DPoint getDpoint(int x, int y)
    {
        double dx = (x - xstart)/square_width;
        double dy = (y - ystart)/square_height;
        if (dx < 0.0 || dy < 0.0 || dx >= 8.0 || dy >= 8.0)
            return null;
        else
            return new DPoint(dx, dy);
    }
    public void boardDraw(Graphics g, PieceType pieceType, ColorType color, double x, double y)
    {
        ChessPiece chessPiece = ChessPiece.chessPieces[color.ordinal()][pieceType.ordinal()];
        int xPixel = xstart+(int)(square_width * x) ;
        int yPixel = ystart+(int)(square_height * y);
        chessPiece.draw(g, xPixel, yPixel, (int)square_width, (int)square_height);
    }
}



What kind of things could you do if you chose to Chess as your project:

- You could make it a game between 2 players which take turns
- Add chess brains so that pieces can only move to places which fit their move capability.
- When a piece is captured, it could be removed from the board.
- You might want to have the chess game as the Center part of a boarder layout. Then you could have one planel to display the captured pieces
- You could have a status line that displays players names and whose turn it is and anything else useful
- Sometimes chess is played where there is a ticking clock of how much time each player has taken.
- You could make the game Pausable (remember the pausable tictactoe game). Because the game is Serializable it can be easily written to a file. Later this file could be read in to restore the state of the game.
- You could allow each player to select his own preferred chess piece images. Perhaps the default is the star-wars pieces, but each user has an option to select another set of pieces with a different style.
- Anything else you want to do.

October 19, 2013 1:22 AM