Placing correct discs Connect Four java game with

2019-03-05 08:16发布

问题:

I'm trying to make a Connect Four Game in Java by using user input and drawing panel. Two people switch off turns typing the column they want their piece to go in. I'm having trouble making it so discs already placed stay on the board the next turn (because the a new drawing panel pops up with the updated board each time)(we tried using GUI but failed). I am also having trouble switching off turns and making the color change each time. Thank you so much, here is what I have so far.

import java.util.*;
import java.awt.*;

public class ConnectFour{
   public static void main(String[] args){
      Scanner console = new Scanner(System.in);
      char [][] board = new char [7][6];
      for (int i = 0; i< 7; i++){
         for (int j= 0; j< 6; j++){
            board[i][j] = ' '; 
         }
      }
      boolean isBlack = true ; //black discs turn
      boolean isRed = false ;   //red discs turn
      boolean playersTurn = true ;
      while (playersTurn){
         if (isBlack == true ){
            System.out.println("Black's Turn");
         }
         else {
            System.out.println("Red's Turn");
         }
         System.out.print("Choose a column to place your disk (1-7): ");

         int column = console.nextInt()-1;
         if (column < 0 || column > 7) { //while loop?
            System.out.print( "Column needs to be within 1-7"); //try catch?
         }

         drawBoard(column, board, isBlack, isRed);
         // connectedFour(board);
         // playersTurn = !playersTurn;
      }
      // isBlack = !isBlack; INVERT WHOSE TURN IT IS!!! unreachable statement??
   }

   public static void drawBoard(int column, char [][] board, boolean isBlack, boolean isRed) {
      DrawingPanel panel = new DrawingPanel(550,550);
      int rowAvailable;
      Graphics g = panel.getGraphics();
      g.drawLine(0,0,0,500);
      g.drawLine(0,0,500,0);
      g.drawLine(500,0,500,427);
      g.drawLine(0,427,500,427);

      for (int i = 0; i< 6; i++){
         for (int j= 0; j<= 6; j++){
            g.setColor(Color.YELLOW);
            g.fillRect(j*71,i*71,71,71);
            g.setColor(Color.WHITE);
            g.fillOval(j*71,i*71,71,71);
         }
      }

      int x = 0;
      int row = 5;

      while (board[column][row-x] != ' '){
         x++;
      }

      row = 5-x;

      if (isBlack == true) {
         g.setColor(Color.BLACK);  
         board[column][row-x] = 'b';                                                
      }                                                   
      else {
         g.setColor(Color.RED);
         board[column][row-x] = 'r';
      }
        // I KNOW THIS FOR LOOP DOES NOT WORK SUCCESSFULLY    
      for (int i = 0; i< 6; i++){                               
         for (int j= 0; j<= 6; j++){
            if(board[i][j] != 'b'){
               g.fillOval((i * 71),j*71, 71,71);
            }
         }
      }



         //       g.fillOval((column * 71),row*71, 71,71); //number 142 is just a test
                     //board[i][j] = WHOSE TURN IT IS (to update array)
          //  if(isBlack){
          //     board[column][row] = 'b';
         //   }
         //   else{
         //      board[column][row] = 'r';
          //  }
   }

   //get whose turn it is as parameter?? a color string? boolean?
   public static boolean  connectedFour( char[][] board){
      int verticalCount = 0;
      for (int i = 0; i< 6; i++){ //goes down each column //EXCEPTION HERE BECAUSE 0
         for( int j=0; j<=6; j++){
            if (board[i][j]== board[i-1][j]){
               verticalCount ++;
            }
         }
      }

      int horizontalCount = 0;
      for (int i =0; i<=6; i++){
         for (int j =0; j<6; j++){
            if (board[i][j-1] == board[i][j]){
               horizontalCount++;
            }
         }
      }

      int diagonalCount = 0;
      //get diagonal here
      if (verticalCount >= 4 || horizontalCount >= 4|| diagonalCount >=4){
         return true ; //return who the winner is. String?
      //
      }
      else {
         return false ;
      }
   }
}

回答1:

  • Don't mix console based input with GUI output, these are two different user paradigms which require different work flows and approaches to manage
  • Don't use getGraphics, this is not how painting works. Swing has a defined paint process which you should use to ensure you are been notified when an update needs to be performed. See Painting in AWT and Swing and Performing Custom Painting for more details.

The following is a very basic example of how you might work with the API, instead of against it.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ConnectFour {

    public static void main(String[] args) {
        new ConnectFour();
    }

    public ConnectFour() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GamePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public enum Player {

        RED, BLUE, NONE;
    }

    public class GamePane extends JPanel {

        private BoardPane boardPane;
        private JLabel label;
        private Player player = null;

        public GamePane() {
            setLayout(new BorderLayout());
            boardPane = new BoardPane();
            add(boardPane);

            label = new JLabel("...");
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setForeground(Color.WHITE);
            label.setOpaque(true);
            label.setBorder(new EmptyBorder(10, 10, 10, 10));

            add(label, BorderLayout.NORTH);

            updatePlayer();

            boardPane.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    updatePlayer();
                }
            });
        }

        protected void updatePlayer() {
            String text = "...";
            Color color = null;
            if (player == null || player.equals(Player.BLUE)) {
                player = Player.RED;
                text = "Red";
                color = Color.RED;
            } else if (player.equals(Player.RED)) {
                player = Player.BLUE;
                text = "Blue";
                color = Color.BLUE;
            }

            label.setText(text);
            label.setBackground(color);
            boardPane.setPlayer(player);
        }

    }

    public class BoardPane extends JPanel {

        private Player[][] board;
        private Player player;

        private int hoverColumn = -1;

        public BoardPane() {
            board = new Player[8][8];
            for (int row = 0; row < board.length; row++) {
                for (int col = 0; col < board[row].length; col++) {
                    board[row][col] = Player.NONE;
                }
            }

            MouseAdapter mouseHandler = new MouseAdapter() {

                @Override
                public void mouseMoved(MouseEvent e) {
                    hoverColumn = getColumnAt(e.getPoint());
                    repaint();
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    hoverColumn = -1;
                    repaint();
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (hoverColumn > -1) {
                        addPieceTo(hoverColumn);
                        repaint();
                    }
                }

            };

            addMouseMotionListener(mouseHandler);
            addMouseListener(mouseHandler);
        }

        public void addChangeListener(ChangeListener listener) {
            listenerList.add(ChangeListener.class, listener);
        }

        public void removeChangeListener(ChangeListener listener) {
            listenerList.add(ChangeListener.class, listener);
        }

        public void setPlayer(Player player) {
            this.player = player;
        }

        protected void addPieceTo(int col) {
            boolean added = false;
            if (col >= 0 && col < board[0].length) {
                for (int row = 0; row < board.length; row++) {
                    if (board[row][col] != Player.NONE) {
                        if (row >= 0) {
                            board[row - 1][col] = player;
                            added = true;
                        }
                        break;
                    }
                }
            }
            if (!added) {
                if (board[0][col] == Player.NONE) {
                    board[board.length - 1][col] = player;
                    added = true;
                }
            }
            if (added) {
                fireStateChanged();
            }
            repaint();
        }

        protected void fireStateChanged() {
            ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
            if (listeners != null && listeners.length > 0) {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : listeners) {
                    listener.stateChanged(evt);
                }
            }
        }

        protected int getColumnAt(Point p) {

            int size = Math.min(getWidth() - 1, getHeight() - 1);

            int xOffset = (getWidth() - size) / 2;
            int yOffset = (getHeight() - size) / 2;

            int padding = getBoardPadding();

            int diameter = (size - (padding * 2)) / 8;

            int xPos = p.x - xOffset;
            int column = xPos / diameter;

            return Math.min(Math.max(0, column), board[0].length - 1);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected int getBoardPadding() {
            return 10;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            int size = Math.min(getWidth() - 1, getHeight() - 1);

            int xOffset = (getWidth() - size) / 2;
            int yOffset = (getHeight() - size) / 2;

            g2d.fill(new RoundRectangle2D.Double(xOffset, yOffset, size, size, 20, 20));

            int padding = getBoardPadding();

            int diameter = (size - (padding * 2)) / 8;

            for (int row = 0; row < board.length; row++) {
                int yPos = (yOffset + padding) + (diameter * row);
                for (int col = 0; col < board[row].length; col++) {
                    int xPos = (xOffset + padding) + (diameter * col);
                    switch (board[row][col]) {
                        case RED:
                            g2d.setColor(Color.RED);
                            break;
                        case BLUE:
                            g2d.setColor(Color.BLUE);
                            break;
                        default:
                            g2d.setColor(getBackground());
                            break;
                    }
                    g2d.fill(new Ellipse2D.Double(xPos, yPos, diameter, diameter));
                }
            }

            if (hoverColumn > -1) {
                int yPos = (yOffset + padding) + (diameter * 0);
                int xPos = (xOffset + padding) + (diameter * hoverColumn);
                if (player != null) {
                    switch (player) {
                        case RED:
                            g2d.setColor(Color.RED);
                            break;
                        case BLUE:
                            g2d.setColor(Color.BLUE);
                            break;
                        default:
                            g2d.setColor(getBackground());
                            break;
                    }
                    g2d.fill(new Ellipse2D.Double(xPos, yPos, diameter, diameter));
                }

            }

            g2d.dispose();
        }

    }

}