-1

I am trying to add a twist to the game of chess, where the game is decided by a taking the most pieces. Each piece is worth 1 point, and the game ends when one player has 10 points.

When there is a "kill"/the piece is removed, a message needs to update so as to show the score. This code below shows the part where the "kill" code is. I just coded a "System.out.println" in the method to test if an output will show if a piece is "killed".

import Menus.GameUI;
import java.util.LinkedList;

public class Piece {
    public int xPos;
    public int yPos;
    public int x;
    public int y;
    public boolean isWhite;
    LinkedList<Piece> ps;
    public String type;

    public Piece(int xPos, int yPos, boolean isWhite, String type, LinkedList<Piece> ps) {
        this.xPos = xPos;
        this.yPos = yPos;
        x = xPos*64;
        y = yPos*64;
        this.isWhite = isWhite;
        this.ps = ps;
        this.type = type;
        ps.add(this);
    }//constructor
    
    public boolean move(int xPos, int yPos){//allows the piece to move
        if(GameUI.getPiece(xPos*64, yPos*64) != null){
            if(GameUI.getPiece(xPos*64, yPos*64).isWhite != isWhite){
                GameUI.getPiece(xPos*64, yPos*64).kill();
                //check that a piece is not the same colour, so it can be "killed"/removed
            }else{
                x = this.xPos*64;
                y = this.yPos*64;
                return true;
                //ensures a piece cannot move to the same square if a piece of the same colour is already on
            }//end of if
        }//end of if
        this.xPos = xPos;
        this.yPos = yPos;
        x = xPos*64;
        y = yPos*64;
        return false;
    }//move
    
    public int kill(){//removes a piece if a piece of the other colour is on the same square
        int score = 1;
        ps.remove(this);
        System.out.println(score);
        return score;
    }//kill

This is the main class which would show the score:

import Pieces.Pawn;
import Pieces.Piece;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;

/**
 *
 * @author V
 */
public class GameUI {

    public static LinkedList<Piece> ps = new LinkedList<>();
    public static Piece selPiece = null;
    private static JLabel wMess = new JLabel("  ScoreW:  ");
    private static JLabel bMess = new JLabel("  ScoreB:  ");
    //public static final int MAX_HEALTH = 10;
    
    public static void main(String[] args) throws IOException{
        
        //extracts the images 
        BufferedImage all = ImageIO.read(new File("chess.png"));
            Image img[] = new Image[12];
            int ind = 0;
            for(int y = 0; y < 400; y += 200){
                for(int x = 0; x < 1200; x += 200){
                    img[ind] = all.getSubimage(x, y, 200, 200).getScaledInstance(64, 64, BufferedImage.SCALE_SMOOTH);
                    ind++;
                }//end of for
            }//end of for
        
        //Displays the white pieces on the board
        Piece wKing = new Piece(4, 7, true, "King", ps) {};
        Piece wQueen = new Piece(3, 7, true, "Queen", ps) {};
        Piece wBishop = new Piece(2, 7, true, "Bishop", ps) {};
        Piece wBishop2 = new Piece(5, 7, true, "Bishop", ps) {};
        Piece wKinght = new Piece(1, 7, true, "Knight", ps) {};
        Piece wKnight2 = new Piece(6, 7, true, "Knight", ps) {};
        Piece wRook = new Piece(0, 7, true, "Rook", ps) {};
        Piece wRook2 = new Piece(7, 7, true, "Rook", ps) {};
        
        for(int i = 0; i < 8; i++){
            //displays the pawns across the board
            //"i" is equal to the horizontal tile position on board
            Piece wPawn = new Pawn(i, 6, true, "Pawn", ps) {};
        }//for

        //Displays the black pieces
        Piece bKing = new Piece(4, 0, false, "King", ps) {};
        Piece bQueen = new Piece(3, 0, false, "Queen", ps) {};
        Piece bBishop = new Piece(2, 0, false, "Bishop", ps) {};
        Piece bBishop2 = new Piece(5, 0, false, "Bishop", ps) {};
        Piece bKinght = new Piece(1, 0, false, "Knight", ps) {};
        Piece bKnight2 = new Piece(6, 0, false, "Knight", ps) {};
        Piece bRook = new Piece(0, 0, false, "Rook", ps) {};
        Piece bRook2 = new Piece(7, 0, false, "Rook", ps) {};
        
        for(int i = 0; i < 8; i++){
            //displays the pawns across the board
            //"i" is equal to the horizontal tile position on board
            Piece bPawn = new Piece(i, 1, false, "Pawn", ps) {};
        }//for
        
        JFrame frame = new JFrame();
        frame.setBounds(10, 10, 1024, 512);
        JPanel panel = new JPanel(new BorderLayout());
        
        JToolBar tools = new JToolBar();
        JButton exit = new JButton("exit");
        tools.setFloatable(false);
        frame.add(tools,BorderLayout.AFTER_LINE_ENDS);
        
        tools.add(wMess);//displays the health of the white side
        tools.addSeparator();
        tools.add(bMess);//displays the helath of the black side
        
        tools.addSeparator();
        tools.add(exit);
        //exit.addActionListener(this);
        
        frame.setUndecorated(true);//removes border so board is seen in full
        JPanel pn = new JPanel(){
            
            @Override
            public void paint(Graphics g){
                boolean white = true;
                
                for(int y = 0; y < 8; y++){
                    for(int x = 0; x < 8; x++){
                        if(white){
                            g.setColor(new Color(0, 0, 255));
                        }else{
                            g.setColor(new Color(255, 0, 0));
                        }//end of if
                    g.fillRect(x*64, y*64, 64,64);
                    white =! white;//check value of white, and reverses it
                    }//end of for
                white =! white;
                }//end of for
                for(Piece p: ps){
                    int imagePos = 0;
                    if(p.type.equalsIgnoreCase("King")){
                        imagePos = 0;
                    }
                    if(p.type.equalsIgnoreCase("Queen")){
                        imagePos = 1;
                    }
                    if(p.type.equalsIgnoreCase("Bishop")){
                        imagePos = 2;
                    }
                    if(p.type.equalsIgnoreCase("Knight")){
                        imagePos = 3;
                    }
                    if(p.type.equalsIgnoreCase("Rook")){
                        imagePos = 4;
                    }
                    if(p.type.equalsIgnoreCase("Pawn")){
                        imagePos = 5;
                    }
                    if(!p.isWhite){
                        imagePos += 6;
                    }//if
                    //checks the position of the piece in the image
                    g.drawImage(img[imagePos], p.xPos*64, p.yPos*64, this);
                }//end of for
            }//paint
        };
        
        frame.add(pn);
        frame.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                //allows the pieces to be dragged to desired square
                if(selPiece != null){
                    selPiece.x = e.getX()-32;
                    selPiece.y = e.getY()-32;
                    frame.repaint();
                }//end of if
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                
            }
        });
        frame.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
               
            }

            @Override
            public void mousePressed(MouseEvent e) {
                //selects the piece when mouse is pressed
                selPiece = getPiece(e.getX(), e.getY());
            }
            
            @Override
            public void mouseReleased(MouseEvent e) {
       
                if(selPiece == null){
                    return;
                    //if tile is selected with nothing on it, nothing happens
                }//end of if
                selPiece.move((e.getX()/64), (e.getY()/64));
                frame.repaint();
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                
            }

            @Override
            public void mouseExited(MouseEvent e) {
                
            }
        });
        frame.setDefaultCloseOperation(3);
        frame.setVisible(true);
    }//end of main
    
    public static Piece getPiece(int x, int y){
        int xPos = x/64;
        int yPos = y/64;
        for(Piece p: ps){
            if(p.xPos == xPos && p.yPos == yPos){
                return p;
            }//end of if
        }//end of for
        
        return null;
    }//getPiece  

}//end of class

Now how would I be able to show this "score" in the main class under the "wMess" or "bMess" JLabel which would hold the score and continuously update when a piece is "killed"? The other problem is that it will not be able to determine which colour "killed" which, so it will not know which score to update. How can I fix these things?

Vish
  • 11
  • 2

2 Answers2

1

In my opinion, the way you have structured your code is poor. You have a circular dependency between class GameUI and class Piece. Sometimes circular dependencies are required however not in this case. Class Piece should only contain details about itself, including:

  • its color, i.e. is it black or white
  • its type, i.e. is it a rook or a knight or a pawn, etc.
  • its current location on the board

When writing custom painting code, you should override method paintComponent and not method paint.

Rather than fix your code, I wrote my own version that incorporates your idea of maintaining a score for each player and increasing the score every time one player captures one of his opponent's pieces. The code adheres to Java naming conventions (as mentioned by @kleopatra in this comment).

The code is not complete. It does not check for a winner, for example, but I hope it will help you to complete your game according to your requirements. Nonetheless you can run it, as is, and play chess with it. The code uses letters to indicate the various pieces, rather than icons, simply because I was too lazy to search for such icons. You can add an icon member to class ChessPiece and change method paintComponent, in class GameUI, so that it paints the icon rather than drawing the letter.

Also, the [Swing] timer uses a method reference for the ActionListener implementation.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

public class GameUI extends JPanel implements MouseListener {
    private boolean  whiteTurn;
    private int  counter;
    private int startColumn;
    private int startRow;
    private List<ChessPiece>  black;
    private List<ChessPiece>  white;
    private JLabel  turn;
    private JTextField  blackScore;
    private JTextField  whiteScore;
    private Timer  timer;

    public GameUI() {
        setPreferredSize(new Dimension(512, 512));
        setFocusable(true);
        addMouseListener(this);
        whiteTurn = true;
        timer = new Timer(500, this::showTurn); // 'repeats' is initially true
        List<ChessPiece> list = List.of(new ChessPiece(false, ChessPiece.ROOK, 0, 0),
                                        new ChessPiece(false, ChessPiece.KNIGHT, 1, 0),
                                        new ChessPiece(false, ChessPiece.BISHOP, 2, 0),
                                        new ChessPiece(false, ChessPiece.QUEEN, 3, 0),
                                        new ChessPiece(false, ChessPiece.KING, 4, 0),
                                        new ChessPiece(false, ChessPiece.BISHOP, 5, 0),
                                        new ChessPiece(false, ChessPiece.KNIGHT, 6, 0),
                                        new ChessPiece(false, ChessPiece.ROOK, 7, 0),
                                        new ChessPiece(false, ChessPiece.PAWN, 0, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 1, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 2, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 3, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 4, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 5, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 6, 1),
                                        new ChessPiece(false, ChessPiece.PAWN, 7, 1));
        black = new ArrayList<>(list);
        list = List.of(new ChessPiece(true, ChessPiece.ROOK, 0, 7),
                       new ChessPiece(true, ChessPiece.KNIGHT, 1, 7),
                       new ChessPiece(true, ChessPiece.BISHOP, 2, 7),
                       new ChessPiece(true, ChessPiece.QUEEN, 3, 7),
                       new ChessPiece(true, ChessPiece.KING, 4, 7),
                       new ChessPiece(true, ChessPiece.BISHOP, 5, 7),
                       new ChessPiece(true, ChessPiece.KNIGHT, 6, 7),
                       new ChessPiece(true, ChessPiece.ROOK, 7, 7),
                       new ChessPiece(true, ChessPiece.PAWN, 0, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 1, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 2, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 3, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 4, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 5, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 6, 6),
                       new ChessPiece(true, ChessPiece.PAWN, 7, 6));
        white = new ArrayList<>(list);
    }
/* Start 'MouseListener' interface methods. */
    @Override // java.awt.event.MouseListener
    public void mouseClicked(MouseEvent event) {
        // Do nothing.
    }

    @Override // java.awt.event.MouseListener
    public void mouseEntered(MouseEvent event) {
        // Do nothing.
    }

    @Override // java.awt.event.MouseListener
    public void mouseExited(MouseEvent event) {
        // Do nothing.
    }

    @Override // java.awt.event.MouseListener
    public void mousePressed(MouseEvent event) {
        int x = event.getX();
        startColumn = x / 64;
        int y = event.getY();
        startRow = y / 64;
    }

    @Override // java.awt.event.MouseListener
    public void mouseReleased(MouseEvent event) {
        int x = event.getX();
        int column = x / 64;
        int y = event.getY();
        int row = y / 64;
        List<ChessPiece> list;
        if (whiteTurn) {
            list = white;
        }
        else {
            list = black;
        }
        // Move the relevant [chess] piece.
        for (ChessPiece piece : list) {
            if (piece != null) {
                if (piece.getColumn() == startColumn  &&  piece.getRow() == startRow) {
                    piece.setColumn(column);
                    piece.setRow(row);
                }
            }
        }
        if (whiteTurn) {
            list = black;
        }
        else {
            list = white;
        }
        // Check if the moved piece captured one of the opponent's pieces.
        for (ChessPiece piece : list) {
            if (piece != null) {
                if (piece.getColumn() == column  &&  piece.getRow() == row) {
                    int index = list.indexOf(piece);
                    if (index >= 0) {
                        System.out.printf("(%d) %s%n", index, piece);
                        list.set(index, null);
                        if (whiteTurn) {
                            incrementScore(whiteScore);
                        }
                        else {
                            incrementScore(blackScore);
                        }
                    }
                }
            }
        }
        repaint();
        whiteTurn = !whiteTurn; // swap turns
        counter = 0;
        timer.start();
    }
/* End 'MouseListener' interface methods. */
    @Override // javax.swing.JComponent
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Color color = Color.red;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                g2d.setColor(color);
                int x = j * 64;
                int y = i * 64;
                g2d.fillRect(x, y, 64, 64);
                g2d.setColor(Color.black);
                g2d.drawRect(x, y, 64, 64);
                for (ChessPiece piece : black) {
                    if (piece != null) {
                        if (piece.getRow() == i  &&  piece.getColumn() == j) {
                            g2d.drawString(Character.toString(piece.getType()), x + 30, y + 30);
                        }
                    }
                }
                g2d.setColor(Color.white);
                for (ChessPiece piece : white) {
                    if (piece != null) {
                        if (piece.getRow() == i  &&  piece.getColumn() == j) {
                            g2d.drawString(Character.toString(piece.getType()), x + 30, y + 30);
                        }
                    }
                }
                if (color == Color.red) {
                    color = Color.blue;
                }
                else {
                    color = Color.red;
                }
            }
        }
    }

    private void buildAndDisplayGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createScorePanel(), BorderLayout.PAGE_START);
        frame.add(this, BorderLayout.CENTER);
        frame.add(createTurnPanel(), BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        this.requestFocusInWindow();
        frame.setVisible(true);
    }

    private JPanel createScorePanel() {
        JPanel scorePanel = new JPanel();
        JLabel whiteScoreLabel = new JLabel("White: ");
        scorePanel.add(whiteScoreLabel);
        whiteScore = new JTextField(4);
        whiteScore.setText("0");
        scorePanel.add(whiteScore);
        JLabel blackScoreLabel = new JLabel("Black: ");
        scorePanel.add(blackScoreLabel);
        blackScore = new JTextField(4);
        blackScore.setText("0");
        scorePanel.add(blackScore);
        return scorePanel;
    }

    private JPanel createTurnPanel() {
        JPanel turnPanel = new JPanel();
        turnPanel.setBackground(Color.gray);
        turn = new JLabel("WHITE");
        turn.setBackground(Color.gray);
        Font f = turn.getFont();
        f = f.deriveFont(16.0f);
        turn.setFont(f);
        turn.setForeground(Color.white);
        turnPanel.add(turn);
        return turnPanel;
    }

    private void incrementScore(JTextField textField) {
        int score = Integer.parseInt(textField.getText());
        textField.setText(Integer.toString(++score));
    }

    // Blink text of 'turn'
    private void showTurn(ActionEvent event) {
        if (++counter >= 5) {
            timer.stop();
        }
        else {
            if (counter % 2 == 1) {
                turn.setText("");
            }
            else {
                if (whiteTurn) {
                    turn.setText("WHITE");
                    turn.setForeground(Color.white);
                }
                else {
                    turn.setText("BLACK");
                    turn.setForeground(Color.black);
                }
            }
        }
    }

    public static void main(String[] args) {
        GameUI instance = new GameUI();
        EventQueue.invokeLater(() -> instance.buildAndDisplayGui());
    }
}

class ChessPiece {
    public static final char  BISHOP = 'B';
    public static final char  KING = 'K';
    public static final char  KNIGHT = 'N';
    public static final char  PAWN = 'P';
    public static final char  QUEEN = 'Q';
    public static final char  ROOK = 'R';

    private boolean white;
    private char type;
    private int column;
    private int row;

    public ChessPiece(boolean white, char type, int column, int row) {
        this.white = white;
        this.type = type;
        this.column = column;
        this.row = row;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public boolean isWhite() {
        return white;
    }

    public char getType() {
        return type;
    }

    // For debugging purposes only.
    public String toString() {
        return String.format("[%s] %c (%d, %d)", (white ? "white" : "black"), type, row, column);
    }
}

Note that [static] method of, in interface java.util.List, was added in JDK 9. If you are using an earlier version, then try the following code instead:

black = new ArrayList<>();
black.add(new ChessPiece(false, ChessPiece.ROOK, 0, 0));
black.add(new ChessPiece(false, ChessPiece.KNIGHT, 1, 0));
black.add(new ChessPiece(false, ChessPiece.BISHOP, 2, 0));
black.add(new ChessPiece(false, ChessPiece.QUEEN, 3, 0));
black.add(new ChessPiece(false, ChessPiece.KING, 4, 0));
black.add(new ChessPiece(false, ChessPiece.BISHOP, 5, 0));
black.add(new ChessPiece(false, ChessPiece.KNIGHT, 6, 0));
black.add(new ChessPiece(false, ChessPiece.ROOK, 7, 0));
black.add(new ChessPiece(false, ChessPiece.PAWN, 0, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 1, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 2, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 3, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 4, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 5, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 6, 1));
black.add(new ChessPiece(false, ChessPiece.PAWN, 7, 1));

white = new ArrayList<>();
white.add(new ChessPiece(true, ChessPiece.ROOK, 0, 7));
white.add(new ChessPiece(true, ChessPiece.KNIGHT, 1, 7));
white.add(new ChessPiece(true, ChessPiece.BISHOP, 2, 7));
white.add(new ChessPiece(true, ChessPiece.QUEEN, 3, 7));
white.add(new ChessPiece(true, ChessPiece.KING, 4, 7));
white.add(new ChessPiece(true, ChessPiece.BISHOP, 5, 7));
white.add(new ChessPiece(true, ChessPiece.KNIGHT, 6, 7));
white.add(new ChessPiece(true, ChessPiece.ROOK, 7, 7));
white.add(new ChessPiece(true, ChessPiece.PAWN, 0, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 1, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 2, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 3, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 4, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 5, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 6, 6));
white.add(new ChessPiece(true, ChessPiece.PAWN, 7, 6));

Here is a screen capture:
(It's white's turn and neither player has scored, yet.)

chess game

Abra
  • 19,142
  • 7
  • 29
  • 41
-1

Most likely not close to the best solution but:

I think you can get the "killed" counter by using an ActionListener together with a timer.

I used something similar to regularly check how many Files were selected in the explorer:

JLabel label = new JLabel();
int delay = 5; //time to wait between updates in milliseconds
ActionListener taskPerformer = new ActionListener() { 
    public void actionPerformed(ActionEvent evt) {
        int row = table.getSelectedRowCount(); //this was for me to get the amount of selected rows
        String selected = String.valueOf(row); //change int to String
            label.setText(selected + " Files selected"); //set text shown               
            }
        };
    new Timer (delay, taskPerformer).start();

obviously you would need to find another way to get the amount of kills. However, I assume you could implement a counter basically, which checks for The "kill" action.

Regarding your other question. Could you not simply put the Label in the center of a frame, while you have the others put to north and south? Maybe I misunderstood something.

hope it's somewhat useful.

TaiiKii
  • 1
  • 4