Checkers Java Code Error

1.9k views Asked by At

I have created two classes for checkers game. One is board and the other is pieces. The difficulty that I am having is that with the pieces I cannot seem to get them to move and neither can I get them to stay in that spot correctly and that I am actually unable to go any further due to the fact that I do not understand what is going wrong here. Can someone please correct me on what I am doing wrong.

            import java.awt.Color;
            import java.awt.Dimension;
            import java.awt.Graphics;
            import java.awt.GridLayout;
            import java.awt.Image;

            import javax.swing.JButton;
            import javax.swing.JPanel;


            public class Board extends JPanel {

              private int[][] state;
              public final static int EMPTY = 0;
              public final static int RED = 1;
              public final static int BLUE = 2;
              public final static int BLUE_KING = 3;
              public final static int RED_KING = 4;
              public final static int HIGHLIGHT = 5;

              public Board() {
                state = new int[8][8];
                setSize(400, 400);
              }

              public void paint(Graphics g){

                for(int y=0;y<8;y++){
                  for(int x=0;x<8;x++){
                    if(x%2 == y%2){
                       g.setColor(Color.WHITE);
                    }
                    else{
                       g.setColor(Color.GRAY);

                    }
                    g.fillRect(x*50,y*50,50,50);

                    switch(state[x][y]){
                    //6 cases that will be available for this game
                    /*
                     * Empty will be the empty spot; Red will be the red checkers. Blue will be the blue checkers. The blue king will occur when it reaches other side
                     * and the red king will occur when it reaches other side. The highlight will show the possible moves that can occur when it [red/blue] king will be selected
                     * 
                     */
                      case EMPTY: break;
                      case RED: 
                        g.setColor(Color.RED);
                        g.fillOval(x*50,y*50,50,50);
                        break;
                      case BLUE:
                        g.setColor(Color.BLACK);
                        g.fillOval(x*50,y*50,50,50);
                        break;
                      case BLUE_KING:
                        g.setColor(Color.BLACK);
                        g.fillOval(x*50,y*50,50,50);
                        g.setColor(Color.WHITE);
                        g.drawString("K",x*50+25,y*50+25);
                        break;
                      case RED_KING:
                        g.setColor(Color.RED);
                        g.fillOval(x*50,y*50,45,45);
                        g.setColor(Color.WHITE);
                        g.drawString("K",x*50+25,y*50+25);
                        break;
                      case HIGHLIGHT:
                        g.setColor(Color.YELLOW);
                        g.drawOval(x*50,y*50,50,50);
                        break;
                    }

                  }
                }
              }

              public void setState(int x,int y, int s){
                state[x][y]=s;
              }

              public int getState(int x,int y){
                return state[x][y];
              }



            }

Also here's the pieces class

                        import javax.swing.*;
                        import java.awt.*;
                        import javax.swing.ImageIcon;
                        import java.awt.event.*;

                        public class Checkers implements MouseListener
                        {
                           int p1pieces = 12; 
                           int p2pieces = 12;
                           int xcord;
                           int ycord;
                           int exist;
                           int exist2;
                           int leftx = 0;
                           int lefty = 1;
                           int rightx = 0;
                           int righty = 1;
                           int oldXvalue, oldYvalue;
                           Board b=new Board();
                           JFrame frame = new JFrame("Checkers");
                           JPanel panel = new JPanel();
                           JButton newgame = new JButton("New Game");
                           JTextField turn = new JTextField("Players one turn");
                           JTextField pieces = new JTextField("Player 1 has " +p1pieces + " pieces. Player 2 has " + p2pieces + " pieces.");


                           public Checkers()
                           {
                             frame.setSize(500,500);
                             frame.add(b);
                             frame.add(panel);
                             frame.setVisible(true);
                             frame.addMouseListener(this);
                             b.setState(0,0, Board.BLUE);
                             b.setState(2,0, Board.BLUE);
                             b.setState(4,0, Board.BLUE);
                             b.setState(6,0, Board.BLUE);
                             b.setState(7,1, Board.BLUE);
                             b.setState(5,1, Board.BLUE);
                             b.setState(3,1, Board.BLUE);
                             b.setState(1,1, Board.BLUE);
                             b.setState(0,2, Board.BLUE);
                             b.setState(2,2, Board.BLUE);
                             b.setState(4,2, Board.BLUE);
                             b.setState(6,2, Board.BLUE);

                             b.setState(7,7, Board.RED);
                             b.setState(5,7, Board.RED);
                             b.setState(3,7, Board.RED);
                             b.setState(1,7, Board.RED);
                             b.setState(0,6, Board.RED);
                             b.setState(2,6, Board.RED);
                             b.setState(4,6, Board.RED);
                             b.setState(6,6, Board.RED);
                             b.setState(1,5, Board.RED);
                             b.setState(3,5, Board.RED);
                             b.setState(5,5, Board.RED);
                             b.setState(7,5, Board.RED);
                           }


                           public void mouseEntered(MouseEvent e){}
                           public void mouseClicked(MouseEvent e){}
                           public void mouseExited(MouseEvent e){}
                           public void mouseReleased(MouseEvent e){}

                          public void mousePressed(MouseEvent e)
                          {
                           Object o = e.getSource(); 
                           {
                                 oldXvalue = xcord;
                                 oldYvalue = ycord;
                               }
                           xcord = (e.getX() / 50);
                           ycord = (e.getY() / 50) ;
                           exist = b.getState(xcord,ycord);
                           if(exist == 1 || exist == 2)

                           highlightleft();
                           highlightright();
                           move();

                           b.repaint();
                          }

                          public void highlightleft()
                           {
                             exist = b.getState(xcord, ycord);
                             if(exist == 1)
                             {
                               exist2 = b.getState(xcord-1, ycord -1);
                             }
                             if(exist == 2)
                             {
                               exist2 = b.getState(xcord-1, ycord +1);

                             }
                             if(exist == 1 && exist2 == 0)
                             {
                                b.setState(xcord-1,ycord -1, Board.HIGHLIGHT);
                               leftx = xcord -1;
                               lefty = ycord -1;

                             }
                             else if(exist == 2 && exist2 == 0)
                             {
                               b.setState(xcord -1, ycord + 1 ,Board.HIGHLIGHT);
                               leftx = xcord -1;
                               lefty = ycord +1;
                             }



                          }

                          public void highlightright()
                           {
                             exist = b.getState(xcord, ycord);
                             if(exist == 1)
                             {
                               exist2 = b.getState(xcord+1, ycord -1);
                             }
                             if(exist == 2)
                             {
                               exist2 = b.getState(xcord+1, ycord +1);
                             }
                             if(exist == 1 && exist2 == 0)
                             {
                                b.setState(xcord+1,ycord -1, Board.HIGHLIGHT);
                                rightx = xcord+1;
                                righty = ycord -1;

                             }
                             else if(exist == 2 && exist2 == 0)
                             {
                               b.setState(xcord +1, ycord + 1 ,Board.HIGHLIGHT);
                               rightx = xcord+1;
                               righty=ycord +1;
                             }
                          }
                          public void removehighlight()
                          {
                            exist = b.getState(xcord,ycord);



                            b.setState(leftx,lefty,Board.EMPTY);
                            b.setState(rightx,righty,Board.EMPTY);

                          }


                          public void move()
                          {
                           exist = b.getState(xcord,ycord);
                           exist2 = b.getState(oldXvalue,oldYvalue);
                           if(exist == 5)
                           {
                             if(exist2 == 1)
                             {
                             b.setState(oldXvalue, oldYvalue, Board.EMPTY);
                             b.setState(xcord,ycord, Board.EMPTY);
                             b.setState(xcord,ycord, Board.RED);
                             }
                             else if(exist2 == 2)
                             {
                             b.setState(oldXvalue, oldYvalue, Board.EMPTY);
                             b.setState(xcord,ycord, Board.EMPTY);
                             b.setState(xcord,ycord, Board.BLUE);
                             }
                             /* 
                              * I think that there should be something here for the code to be cleared and then you can repeat it
                              */
                           }



                          }

                           public static void main(String [] args){ 

                             new Checkers();
                           }
                        }
2

There are 2 answers

1
abcdef On

I have no idea when you get your errors so its hard to say anything without knowing what the actual error is.

But I would say your highlighting code could remove any red blue checker piece location information, you don't check if there is information there already. Your highlight method has a couple of ifs and and an if else statement. The if's will all be checked as well as the if else block.

But I could he wrong on this assumption because its hard to know what all your == code means as you don't use constants.

0
Gilbert Le Blanc On

I've created a Checkers GUI.

I have not implemented moves yet, although I have started to code the MouseListener. Here is what the Checkers GUI looks like.

Checkers GUI

I used a model / view / controller pattern (MVC) to code this GUI. I wrote 4 model classes, 3 view classes, and 5 controller classes.

When I code a Swing GUI, here's how I implement the MVC pattern:

  1. The view may get information from the model.
  2. The view may not update the model.
  3. The controller will update the model, and repaint the view.

I don't have a single controller class. So far, I have 5 controller classes.

Here's the main class, Checkers.

package com.ggl.checkers;

import javax.swing.SwingUtilities;

import com.ggl.checkers.model.CheckersModel;
import com.ggl.checkers.view.CheckersFrame;

public class Checkers implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Checkers());
    }

    @Override
    public void run() {
        new CheckersFrame(new CheckersModel());
    }
}

Short and effective. This 19 line Java class does 3 things.

  1. Puts the Swing GUI on the Event Dispatch thread (EDT) by calling the SwingUtilities invokeLater method.
  2. Instantiates the CheckersModel class.
  3. Instantiates the CheckersFrame class.

Next, let's look at the model classes. This is the CheckersModel class.

package com.ggl.checkers.model;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.ggl.checkers.model.CheckerPiece.PieceType;

public class CheckersModel {

    private Color boardEdgeColor;
    private Color lightSquareColor;
    private Color darkSquareColor;
    private Color lightPieceColor;
    private Color darkPieceColor;

    private GameParameters gameParameters;

    private List<CheckerPiece> pieces;
    private List<CheckerSquare> board;
    private List<GameParameters> parameters;


    public CheckersModel() {
        this.parameters = new ArrayList<GameParameters>();
        setGameParameters();

        this.boardEdgeColor = Color.ORANGE;
        this.lightSquareColor = Color.WHITE;
        this.darkSquareColor = Color.GRAY;
        this.lightPieceColor = Color.RED;
        this.darkPieceColor = Color.BLACK;

        this.board = new ArrayList<CheckerSquare>();
        setBoard();

        this.pieces = new ArrayList<CheckerPiece>();
        setPieces();
    }

    public void setGameParameters() {
        this.gameParameters = new GameParameters(
                "American Checkers", 8, 12, true, false);
        gameParameters.setSelected(true);
        parameters.add(gameParameters);

        GameParameters gp = new GameParameters(
                "Canadian Checkers", 12, 30, true, true);
        parameters.add(gp);

        gp = new GameParameters(
                "International Checkers", 10, 20, true, true);
        parameters.add(gp);
    }

    public void setGameParameters(GameParameters gameParameters) {
        this.gameParameters = gameParameters;
    }

    public void setBoard() {
        this.board.clear();
        Color color1 = getLightSquareColor();
        Color color2 = getDarkSquareColor();
        if (!gameParameters.isLightSquareOnRight()) {
            color1 = getDarkSquareColor();
            color2 = getLightSquareColor();
        }

        int squareWidth = gameParameters.getSquareWidth();
        int squaresPerSide = gameParameters.getSquaresPerSide();
        int margin = squareWidth / 2;

        int x = margin;
        int y = margin;

        for (int i = 0; i < squaresPerSide; i++) {
            for (int j = 0; j < squaresPerSide; j++) {
                Color color = null;

                if (getGameParameters().isLightSquareOnRight()) {
                    if (i % 2 == j % 2) {
                        color = color1;
                    } else {
                        color = color2;
                    }
                } else {
                    if (i % 2 == j % 2) {
                        color = color2;
                    } else {
                        color = color1;
                    }
                }

                Rectangle r = new Rectangle(x, y, squareWidth, squareWidth);
                Point p = new Point(i, j);

                CheckerSquare cs = new CheckerSquare(color, p, r);
                board.add(cs);

                x += squareWidth;
            }

            y += squareWidth;
            x = margin;
        }
    }

    public void setPieces() {
        this.pieces.clear();

        int squaresPerSide = getGameParameters().getSquaresPerSide();
        Color topColor = getDarkPieceColor();
        Color bottomColor = getLightPieceColor();
        if (!getGameParameters().isLightMovesFirst()) {
            topColor = getLightPieceColor();
            bottomColor = getDarkPieceColor();
        }

        int rows = getGameParameters().getPiecesPerSide() * 2 / squaresPerSide;

        for (int i = 0; i < squaresPerSide; i++) {
            if (i < rows) {
                if (getGameParameters().isLightSquareOnRight()) {
                    if ((i % 2) == 0) {
                        setPieceRow(topColor, i, 1);
                    } else {
                        setPieceRow(topColor, i, 0);
                    }
                } else {
                    if ((i % 2) == 0) {
                        setPieceRow(topColor, i, 0);
                    } else {
                        setPieceRow(topColor, i, 1);
                    }
                }
            }

            if (i > (squaresPerSide - rows - 1)) {
                if (getGameParameters().isLightSquareOnRight()) {
                    if ((i % 2) == 0) {
                        setPieceRow(bottomColor, i, 1);
                    } else {
                        setPieceRow(bottomColor, i, 0);
                    }
                } else {
                    if ((i % 2) == 0) {
                        setPieceRow(bottomColor, i, 0);
                    } else {
                        setPieceRow(bottomColor, i, 1);
                    }
                }
            }

        }
    }

    public void resetPieceColor(Color previousColor, Color newColor) {
        for (CheckerPiece cp : pieces) {
            if (cp.getColor().equals(previousColor)) {
                cp.setColor(newColor);
            }
        }
    }

    public void resetSquareColor(Color previousColor, Color newColor) {
        for (CheckerSquare cs : board) {
            if (cs.getColor().equals(previousColor)) {
                cs.setColor(newColor);
            }
        }
    }

    private void setPieceRow(Color color, int row, int column) {
        int squaresPerSide = gameParameters.getSquaresPerSide();

        for (int j = column; j < squaresPerSide; j += 2) {
            CheckerPiece cp = new CheckerPiece(color, PieceType.Man);
            cp.setLocation(new Point(row, j));
            pieces.add(cp);
        }
    }

    public int getSquaresPerSide() {
        return gameParameters.getSquaresPerSide();
    }

    public Color getBoardEdgeColor() {
        return boardEdgeColor;
    }

    public void setBoardEdgeColor(Color boardEdgeColor) {
        this.boardEdgeColor = boardEdgeColor;
    }

    public Color getLightSquareColor() {
        return lightSquareColor;
    }

    public void setLightSquareColor(Color lightSquareColor) {
        this.lightSquareColor = lightSquareColor;
    }

    public Color getDarkSquareColor() {
        return darkSquareColor;
    }

    public void setDarkSquareColor(Color darkSquareColor) {
        this.darkSquareColor = darkSquareColor;
    }

    public Color getLightPieceColor() {
        return lightPieceColor;
    }

    public void setLightPieceColor(Color lightPieceColor) {
        this.lightPieceColor = lightPieceColor;
    }

    public Color getDarkPieceColor() {
        return darkPieceColor;
    }

    public void setDarkPieceColor(Color darkPieceColor) {
        this.darkPieceColor = darkPieceColor;
    }

    public Dimension getPreferredBoardSize() {
        int squareWidth = gameParameters.getSquareWidth();
        int squaresPerSide = gameParameters.getSquaresPerSide();
        int width = squareWidth * (squaresPerSide + 1);
        return new Dimension(width, width);
    }

    public List<GameParameters> getGameParametersList() {
        return Collections.unmodifiableList(parameters);
    }

    public GameParameters getGameParameters() {
        return gameParameters;
    }

    public CheckerPiece getPieceOnSquare(Point p) {
        for (CheckerPiece cp : pieces) {
            if (cp.isLocation(p)) {
                return cp;
            }
        }
        return null;
    }

    public CheckerPiece getPieceOnSquare(int x, int y) {
        for (CheckerSquare cs : board) {
            if (cs.containsLocation(x, y)) {
                CheckerPiece cp = getPieceOnSquare(cs.getCoordinate());
                return cp;
            }
        }

        return null;
    }

    public void draw(Graphics g) {
        int squareWidth = gameParameters.getSquareWidth();
        int squaresPerSide = gameParameters.getSquaresPerSide();
        int width = squareWidth * (squaresPerSide + 1);

        g.setColor(getBoardEdgeColor());
        g.fillRect(0, 0, width, width);

        for (CheckerSquare cs : board) {
            cs.draw(g);
            CheckerPiece cp = getPieceOnSquare(cs.getCoordinate());
            if (cp != null) {
                cp.draw(g, cs.getLocation(), squareWidth);
            }
        }
    }

}

You'll see the the board squares, as well as the checker pieces, are kept in a list. The board squares are kept in a list because I needed to know the pixel positions of each square. As you'll see later, I put the pixel positions in a Rectangle. This allows me to convert a mouse click to a square, and eventually to a checker piece.

The GameParameters class holds the parameters for a particular checkers game. Right now, I have American checkers, Canadian checkers, and International checkers. You can see on the GUI image that the different checker games have different parameters.

Next, let's look at the GameParameters class.

package com.ggl.checkers.model;

public class GameParameters {

    private boolean isSelected;
    private boolean lightSquareOnRight;
    private boolean lightMovesFirst;

    private int piecesPerSide;
    private int squaresPerSide;
    private int squareWidth;

    private String gameName;

    public GameParameters(String gameName, int squaresPerSide,
            int piecesPerSide, boolean lightSquareOnRight,
            boolean lightMovesFirst) {
        this.gameName = gameName;
        this.squaresPerSide = squaresPerSide;
        this.piecesPerSide = piecesPerSide;
        this.lightSquareOnRight = lightSquareOnRight;
        this.lightMovesFirst = lightMovesFirst;
        this.squareWidth = 500 / squaresPerSide;
        this.isSelected = false;
    }

    public boolean isLightSquareOnRight() {
        return lightSquareOnRight;
    }

    public boolean isLightMovesFirst() {
        return lightMovesFirst;
    }

    public int getPiecesPerSide() {
        return piecesPerSide;
    }

    public int getSquaresPerSide() {
        return squaresPerSide;
    }

    public int getSquareWidth() {
        return squareWidth;
    }

    public String getGameName() {
        return gameName;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }

    @Override
    public String toString() {
        return gameName;
    }
}

This class holds the game parameters that make each checkers variation unique.

Next, let's look at the CheckerSquare class.

package com.ggl.checkers.model;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

public class CheckerSquare {

    private Color color;

    private Point coordinate;

    private Rectangle location;

    public CheckerSquare(Color color, Point coordinate, Rectangle location) {
        this.color = color;
        this.coordinate = coordinate;
        this.location = location;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public Point getCoordinate() {
        return coordinate;
    }

    public Rectangle getLocation() {
        return location;
    }

    public boolean containsLocation(int x, int y) {
        return location.contains(x, y);
    }

    public void draw(Graphics g) {
        g.setColor(color);
        g.fillRect(location.x, location.y, location.width, location.height);
    }
}

As I mentioned before, each square is defined by a Rectangle that let's us know where the square is located. This allows a mouse click to be converted to a square coordinate, and eventually, a piece coordinate.

Finally, we'll look at the CheckerPiece class.

package com.ggl.checkers.model;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

public class CheckerPiece {

    private Color color;

    private PieceType pieceType;

    private Point location;

    public CheckerPiece(Color color, PieceType pieceType) {
        this.color = color;
        this.pieceType = pieceType;
    }

    public Point getLocation() {
        return location;
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public boolean isLocation(Point location) {
        return ((this.location.x == location.x) 
                && (this.location.y == location.y));
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public PieceType getPieceType() {
        return pieceType;
    }

    public void draw(Graphics g, Rectangle r, int width) {
        drawCircle(g, getCenter(r), width * 4 / 10);
    }

    private Point getCenter(Rectangle r) {
        int x = r.x + r.width / 2;
        int y = r.y + r.height / 2;
        return new Point(x, y);
    }

    private void drawCircle(Graphics g, Point center, int radius) {
        g.setColor(getColor());
        g.fillOval(center.x - radius, center.y - radius, 
                radius + radius, radius + radius);
    }

    public enum PieceType {
        Man, King
    }

}

Next, we'll look at the view classes. First, we'll look at the CheckersFrame class.

package com.ggl.checkers.view;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.ggl.checkers.controller.MoveMouseListener;
import com.ggl.checkers.model.CheckersModel;
import com.ggl.checkers.model.GameParameters;

public class CheckersFrame {

    private BoardPanel boardPanel;

    private CheckersModel model;

    private ControlPanel controlPanel;

    private JFrame frame;

    public CheckersFrame(CheckersModel model) {
        this.model = model;
        createPartControl();
    }

    private void createPartControl() {
        frame = new JFrame();
        frame.setTitle("Checkers");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                exitProcedure();
            }
        });

        boardPanel = new BoardPanel(model);
        boardPanel.addMouseListener(new MoveMouseListener(model));

        controlPanel = new ControlPanel(this, model);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));

        mainPanel.add(boardPanel);

        JPanel rightPanel = new JPanel();
        rightPanel.add(controlPanel.getPanel());
        mainPanel.add(rightPanel);

        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void exitProcedure() {
        frame.dispose();
        System.exit(0);
    }

    public JFrame getFrame() {
        return frame;
    }

    public void updateControlPanelPartControl(GameParameters item) {
        controlPanel.updatePartControl(item);
    }

    public void repaintBoardPanel() {
        frame.setVisible(false);
        frame.validate();
        frame.pack();
        frame.setVisible(true);
    }
}

The createPartControl method is boilerplate for creating a JFrame. We use a JFrame. You should only extend a Swing component or any other Java class when you're going to override a method.

Next, let's look at the BoardPanel class.

package com.ggl.checkers.view;

import java.awt.Graphics;

import javax.swing.JPanel;

import com.ggl.checkers.model.CheckersModel;

public class BoardPanel extends JPanel {

    private static final long serialVersionUID = 7726343503195297509L;

    private CheckersModel model;

    public BoardPanel(CheckersModel model) {
        this.model = model;
        this.setPreferredSize(model.getPreferredBoardSize());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        model.draw(g);
    }

}

This class calls the drawing code in the model, which draws the checker board and the checker pieces.

An answer is limited to 30,000 characters. I can continue this discussion in another answer if someone thinks it's worthwhile. I still have 1 view class and 5 controller classes to discuss.