JavaFX Connect Four AI

I made a Connect four Ai with minmax algorithm. It’s my first bigger JavaFX project. Any help for improvements would be really appreciated.

enter image description here

Board:

import java.util.ArrayList;  class Move {      private int row, col;      public Move(int row, int col) {         this.row = row;         this.col = col;     }      public int getRow() {         return row;     }      public int getCol() {         return col;     }      @Override     public String toString() {         return "Move{" +                 "row=" + row +                 ", col=" + col +                 '}';     } }   public class Board {      private final int playerX = 1;     private final int playerO = 2;      private int rows;     private int cols ;     private int board[][];     private int moves;     private Move lastMove;     private Ai ai;      public Board(int rows, int cols, int depth) {         this.rows = rows;         this.cols = cols;         this.board = new int[rows][cols];         this.moves = 0;         this.lastMove = new Move(0, 0);         this.ai = new Ai(this, depth);     }      public int[][] getBoard() {         return board;     }      public int getMoves() {         return moves;     }      public Move getLastMove() {         return lastMove;     }      public void doMove(Move m, int player) {         board[m.getRow()][m.getCol()] = player;     }      public void undoMove(Move m) {         board[m.getRow()][m.getCol()] = 0;     }      public void doAiMove(int player) {         Move best = ai.getBestMove();         board[best.getRow()][best.getCol()] = player;         moves++;         lastMove = best;     }      private Move generateMove(int col) {          for(int r = rows - 1; r >= 0; r--) {             if(board[r][col] == 0) {                 return new Move(r, col);             }         }         return null;     }      public ArrayList<Move> generateMoves() {         ArrayList<Move> moves = new ArrayList<>();          for(int c = 0; c < cols; c++) {              Move m = generateMove(c);              if(m != null) {                 moves.add(m);             }         }         return moves;     }      public void playerMove(int col) {         Move m = generateMove(col);          if(m != null) {             doMove(m, playerX);             moves++;             lastMove = m;         }     }      private int checkWin(int row, int col, int player) {          if(col >= cols - 4) {             if(board[row][col] == player && board[row][col-1] == player &&                     board[row][col-2] == player && board[row][col-3] == player) {                 return player;             }         }          if(col <= cols - 4) {             if(board[row][col] == player && board[row][col+1] == player &&                     board[row][col+2] == player && board[row][col+3] == player) {                 return player;             }         }          if(row <= rows - 4) {             if(board[row][col] == player && board[row+1][col] == player &&                     board[row+2][col] == player && board[row+3][col] == player) {                 return player;             }         }          if(row >= rows - 3) {             if(board[row][col] == player && board[row-1][col] == player &&                     board[row-2][col] == player && board[row-3][col] == player) {                 return player;             }         }          if(col >= cols - 4 && row >= rows - 3) {             if(board[row][col] == player && board[row-1][col-1] == player &&                     board[row-2][col-2] == player && board[row-3][col-3] == player) {                 return player;             }         }          if(col <= cols - 4 && row <= rows - 4) {             if(board[row][col] == player && board[row+1][col+1] == player &&                     board[row+2][col+2] == player && board[row+3][col+3] == player) {                 return player;             }         }          if(col <= cols - 4 && row >= rows - 3) {             if(board[row][col] == player && board[row-1][col+1] == player &&                     board[row-2][col+2] == player && board[row-3][col+3] == player) {                 return player;             }         }          if(col >= cols - 4 && row <= rows - 4) {             if(board[row][col] == player && board[row+1][col-1] == player &&                     board[row+2][col-2] == player && board[row+3][col-3] == player) {                 return player;             }         }          return 0;     }      public int checkBoardState(Move lastMove, int board[][]) {              int x = checkWin(lastMove.getRow(), lastMove.getCol(), playerX);             int o = checkWin(lastMove.getRow(), lastMove.getCol(), playerO);              if(x == playerX) return x;             if(o == playerO) return o;              if(moves == rows * cols) return 0;              return -1;     }  } 

Ai:

import java.util.ArrayList;  public class Ai {      private final int playerX = 1;     private final int playerO = 2;     private Board board;      private int depth;     private Move bestMove;      public Ai(Board board, int depth) {         this.board = board;         this.depth = depth;     }      /*public void setDepth(int depth) {         this.depth = depth;     }*/      private int min(int depth, int alpha, int beta) {          ArrayList<Move> moves = board.generateMoves();         int minValue = beta;          if(depth == 0 || moves.size() == 0) {             return evaluate(board.getBoard());         }          for(Move m: moves) {              board.doMove(m, playerO);             int v = max(depth - 1, alpha, minValue);             board.undoMove(m);              if(v < minValue) {                 minValue = v;                  if(minValue <= alpha) break;                  if(depth == this.depth) {                     bestMove = m;                 }             }          }         return minValue;     }      private int max(int depth, int alpha, int beta) {          ArrayList<Move> moves = board.generateMoves();         int maxValue = alpha;          if(depth == 0 || moves.size() == 0) {             return evaluate(board.getBoard());         }          for(Move m: moves) {              board.doMove(m, playerX);             int v = min(depth - 1, maxValue, beta);             board.undoMove(m);              if(v > maxValue) {                 maxValue = v;                  if(maxValue >= beta) break;                  if(depth == this.depth) {                     bestMove = m;                 }              }          }         return maxValue;     }      private int evaluateSegment(int[] s) {          int countX = 0, countO = 0;          for(int i = 0; i < s.length; i++) {             if(s[i] == playerX) countX++;             if(s[i] == playerO) countO++;         }          if(countX == 0) {             if(countO == 4) return -1000;             if(countO == 3) return -50;             if(countO == 2) return -10;             if(countO == 1) return -1;         }          if(countO == 0) {             if(countX == 4) return 1000;             if(countX == 3) return 50;             if(countX == 2) return 10;             if(countX == 1) return 1;         }          return 0;     }      private int evaluate(int board[][], int row, int col) {          int rows = board.length;         int cols = board[0].length;         int score = 0;          if(col >= cols - 4) {            score += evaluateSegment(new int[] {board[row][col], board[row][col-1], board[row][col-2], board[row][col-3]});         }          if(col <= cols - 4) {             score += evaluateSegment(new int[] {board[row][col], board[row][col+1], board[row][col+2], board[row][col+3]});         }          if(row <= rows - 4) {             score += evaluateSegment(new int[] {board[row][col], board[row+1][col], board[row+2][col], board[row+3][col]});         }          if(row >= rows - 3) {             score += evaluateSegment(new int[] {board[row][col], board[row-1][col], board[row-2][col], board[row-3][col]});         }          if(col >= cols - 4 && row >= rows - 3) {             score += evaluateSegment(new int[]{board[row][col], board[row-1][col-1], board[row-2][col-2], board[row-3][col-3]});         }          if(col <= cols - 4 && row <= rows - 4) {             score += evaluateSegment(new int[]{board[row][col], board[row+1][col+1], board[row+2][col+2], board[row+3][col+3]});         }          if(col <= cols - 4 && row >= rows - 3) {             score += evaluateSegment(new int[]{board[row][col], board[row-1][col+1], board[row-2][col+2], board[row-3][col+3]});         }          if(col >= cols - 4 && row <= rows - 4) {             score += evaluateSegment(new int[]{board[row][col], board[row+1][col-1], board[row+2][col-2], board[row+3][col-3]});         }          return score;     }      private int evaluate(int board[][]) {          int score = 0;          for(int r = 0; r < board.length; r++) {             for(int c = 0; c < board[r].length; c++) {                  score += evaluate(board, r, c);              }         }          return score;     }       public Move getBestMove() {         max(depth, Integer.MIN_VALUE, Integer.MAX_VALUE);         return bestMove;     }  } 

Main:

import javafx.application.Application; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Button; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.event.ActionEvent;  import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;   public class Main extends Application {      private final int rows = 6;     private final int cols = 7;      private final int playerX = 1;     private final int playerO = 2;      private final int canvasHeight = 600;     private final int canvasWidth = 700;     private final double cellHeight = (double) canvasHeight / rows;     private final double cellWidth = (double) canvasWidth / cols;      private int clickedButton = -1;      private Board board;     private int depth = 8;      public Main() {         board = new Board(rows, cols, depth);     }      @Override     public void start(Stage primaryStage) {          primaryStage.setTitle("Connect Four");          GridPane gridPane = new GridPane();         gridPane.setPadding(new Insets(20.0, 0.0, 20.0, 0.0));          VBox box = new VBox();         box.setPadding(new Insets(20.0,20.0,20.0,50.0));          Canvas canvas = new Canvas(canvasWidth, canvasHeight);         GraphicsContext gc = canvas.getGraphicsContext2D();         drawBoard(gc);           Button buttonArray[] = new Button[cols];          for(int i = 0; i < cols; i++) {             buttonArray[i] = new Button("Input");             buttonArray[i].setMinWidth(cellWidth);             buttonArray[i].setMaxWidth(cellWidth);             buttonArray[i].setId(""+i);             gridPane.add(buttonArray[i], i, 0);         }          for(Button b: buttonArray) {              b.setOnAction(new EventHandler<ActionEvent>() {                 @Override                 public void handle(ActionEvent event) {                      if(board.getMoves() % 2 == 0 && board.checkBoardState(board.getLastMove(), board.getBoard()) == -1) {                          clickedButton = Integer.valueOf(b.getId());                         board.playerMove(clickedButton);                         repaintCanvas(gc);                          for(Button button: buttonArray) {                             button.setDisable(true);                         }                           if(board.getMoves() % 2 == 1 && board.checkBoardState(board.getLastMove(), board.getBoard()) == -1) {                              ExecutorService es = Executors.newFixedThreadPool(1);                             Runnable r = new Runnable() {                                  @Override                                 public void run() {                                          board.doAiMove(playerO);                                         repaintCanvas(gc);                                          for(Button button: buttonArray) {                                             button.setDisable(false);                                         }                                      }                             };                              es.execute(r);                             es.shutdown();                          }                     }                  }              });         }          VBox b = new VBox();         b.setPadding(new Insets(20.0,20.0,20.0,350.0));          Button restart = new Button("Restart");         restart.setOnAction(new EventHandler<ActionEvent>() {             @Override             public void handle(ActionEvent event) {                 board = new Board(rows, cols, depth);                 repaintCanvas(gc);             }         });          b.getChildren().add(restart);           box.getChildren().addAll(gridPane, canvas, b);         primaryStage.setScene(new Scene(box, 800, 800));         primaryStage.setResizable(false);           primaryStage.show();     }       private void drawBoard(GraphicsContext gc) {          gc.setFill(Color.rgb(128, 255, 0));         gc.fillRect(0, 0, canvasWidth, canvasHeight);          gc.setFill(Color.BLACK);          for(int i = 0; i <= rows; i++) {             gc.strokeLine(0, i * cellHeight, canvasWidth, i * cellHeight);         }          for(int i = 0; i <= cols; i++) {             gc.strokeLine(i * cellWidth, 0, i * cellWidth, canvasHeight);         }          int offset = 3;         int board[][] = this.board.getBoard();          for(int r = 0; r < rows; r++) {             for(int c = 0; c < cols; c++) {                  if(board[r][c] == playerX) {                     gc.setFill(Color.RED);                     gc.fillOval(c * cellHeight, r * cellWidth, cellWidth - offset, cellHeight - offset);                 }                  if(board[r][c] == playerO) {                     gc.setFill(Color.BLUE);                     gc.fillOval(c * cellHeight, r * cellWidth, cellWidth - offset, cellHeight - offset);                 }              }         }     }      private void repaintCanvas(GraphicsContext gc) {         gc.clearRect(0, 0, canvasWidth, canvasHeight);         drawBoard(gc);     }       public static void main(String[] args) {         Main m = new Main();         launch(args);      } } 

after ketozin handiest four weeks of remedy.

The suggest losses of 3.08 ± 0.24 kg body weight and 1.eleven ± 0.09 kg / m² BMI price were determined after 12 weeks, with a reduction in waist circumference and hip circumference of about 7.08 and five.96cm, respectively. similarly, a extensive reduction in BMI turned into discovered in volunteers treated with Moro juice extract after ketozin handiest four weeks of remedy.

In end, medical records and consequences suggest that…

after ketozin handiest four weeks of remedy.

How to translate connection on four graphs to quantum 6j symbols

I need the explicit quantum 6j symbols for the Haagerup fusion category for a physics research project. This paper math/9803044 by Asaeda and Haagerup brute-force constructs the Haagerup subfactor, by giving explicit connections on four graphs. So I wonder: (1) Is the data of connections equivalent to the quantum 6j symbols? (2) If so, how can I translate?

Any help or direction to references is very much appreciated!

Turan’s theorem to prove four colour theorem

We have, by one of Turán’s theorem, that among the $ n$ -vertex simple graphs with no $ r+1$ clique, the $ r$ -complete multipartite graph which has its number of vertices in each partite sets differing by at most $ 1$ vertex(The Turán graph) is the one that has maximum number of edges.

Now, by Kuratowski’s theorem, a planar graph should not contain a $ 5$ clique or its topological equivalents. Why cant we apply the Turán’s theorem to prove the four colour theorem? Specifically, using $ r=4$ would help us do the job, I think? The case of graphs like Mycielski graphs could be handled by showing them topologically equivalent to $ K_{3,3}$ , which arent allowed by Kuratowski theorem. Any clarifications as where this approach may fail? Thanks beforehand.

How to implement acquaintance and aggregate as described by the Gang of Four

Is the following implementation in PHP correct?

I focused on what they say about the lifetime of dependencies:

“Aggregation implies that an aggregate object and its owner have identical lifetimes.“

The implementation of acquaintance:

    class B {}     class A     {         /**          * @var B          */         private $  b;          // $  b can be injected to $  a via a constructor         public function __construct(B $  b)         {             $  this->b = $  b;              // this is not possible and would be an aggregation relationship             // $  this->b = new B();         }          // $  b can also be injected to $  a via a setter         public function setB(B $  b)         {             $  this->b = $  b;         }     } 

The implementation of aggregation:

    class B {}     class A     {         /**          * @var B          */         private $  b;          // $  b is instantiated in the constructor (the lifetime of $  b is the same as of $  a)         public function __construct()         {             $  this->b = new B();         }     } 

Disjoint paths between four vertices

Consider the following property of an undirected graph: For any four distinct vertices $ a,b,c,d$ , there is a path from $ a$ to $ b$ and a path from $ c$ to $ d$ such that the two paths do not share any vertex.

Is there a name for this property, or has it been studied? It looks related to vertex connectivity but not quite the same. Also it seems that any graph satisfying this property must have vertex connectivity at least $ 2$ .

What way should I take four values and order them in descending/ascending ordering keeping their related Key?

I have four players. Each player has a score. Their score is contained in a TextView and their name in another TextView. At the minute I have a HashMap that generates identifiable keys e.g. (player 1, player 2) and retrieves their related score as a value.

I need to sort the scores in both descending and ascending order(depending on if a Gametype is one or another.) but we will use just descending for this example.

I found a way to sort the values into a inside the HashMap I mentioned previously. I thought I would just be able to print this HashMap out in order but of course I soon learned that that you use the get methond in the HashMap and thet retrieves the value of the key provided. To solve this problem I googled and seen I can change it into an Array and iterate through it that way:

 private void populateViews() {      for (int i = 0; i < numOfPlayers; i++) {         tv_positions[i].setText(String.valueOf(finishingPositions.keySet().toArray()[i]));     }  } 

This feels like a round about way. What way should I be doing this?

Need help allocating one of the four primary partitions for ubuntu 18.04

i am trying to learn and play with ubuntu on my hp desktop with these specs : enter image description here

So, i tried making the partition by myself after downloading the ubuntu 18.04, opening disk management and shrinking my C: drive volume by ~80Gb as you can see in the screenshot

enter image description here

But after making the live usb for ubuntu , i rebooted my desktop and loaded into ubuntu , but i am not able to find out :

Q1) Which primary partition should i remove ? [ of all my 4 drives ) Q2) How to make it available for ubuntu downloading?

I do not have any valuable data on the desktop itself so i really dont care about backing up as long as i can use windows and ubuntu 18.04 in dual boot.

I wanted to have atleast 80GB for Ubuntu and 16gb for swap.

Thanks again.

Basic Connect Four Game 2

so here is an updated version of a basic connect four game I had posted previously. Changes include:

  • an overhauled validator, simplifying the process by knowing where the last move was made
  • Utilized an array with elements referncing how full each column is to simplify the logic of making a move and checking for a tie
  • The game is now GUI based utilizing swing to build both the game and main menus, built on top of the previous text based logic and functions
  • Added the ability to save, load, and start new games from the GUI menu

Constructive criticism/suggestions related to OOD/OOP as well as how to improve the game GUI are especially welcome, as that is where I think I need the most improvement currently. My next steps should involve adding the ability for players to play over a network, so any tips or advice to get there from where I’m at would be appreciated too.

ConnectFour.Java

import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*;  public class ConnectFour implements Serializable {     private int[][] gameBoard;     private int[] piecesInColumn; // Each index keeps track of how many game pieces are currently in the corresponding column     private static final int ROWS = 6;     private static final int COLUMNS = 7;     private static final int RED = 1;     private static final int YELLOW = 2;     private Player playerOne;     private Player playerTwo;     private int totalNumTurns;      public ConnectFour() {         this.gameBoard = new int[ROWS][COLUMNS];         this.piecesInColumn = new int[COLUMNS];         //Initialize each position in the game board to empty         for (int i = 0; i < ROWS; i++) {             for (int j = 0; j < COLUMNS; j++) {                 gameBoard[i][j] = -1;             }         }          this.totalNumTurns = 0;      }      public static void main(String[] args) {         new ConnectFour().buildMainMenu();      }      public void buildMainMenu(){         // Construct a main menu that welcomes players and takes their names          JFrame mainFrame = new JFrame();         mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);          JLabel title = new JLabel("Welcome to Connect Four!");         Font titleFont = new Font(Font.SERIF, Font.BOLD, 20);         title.setFont(titleFont);         JPanel titlePanel = new JPanel();         titlePanel.add(title);          JTextField nameOne = new JTextField(10);         JLabel nameOneLabel = new JLabel("Player one's name:");         JTextField nameTwo = new JTextField(10);         JLabel nameTwoLabel = new JLabel("Player two's name");         JPanel namesPanel = new JPanel();         namesPanel.setLayout(new BoxLayout(namesPanel, BoxLayout.Y_AXIS));         namesPanel.add(nameOneLabel);         namesPanel.add(nameOne);         namesPanel.add(nameTwoLabel);         namesPanel.add(nameTwo);          JButton startGameButton = new JButton("Start Game!");          startGameButton.addActionListener(new ActionListener(){              @Override             public void actionPerformed(ActionEvent e) {                 //Once we press start game, create player objects based on the names, close the window and open a new window with the game GUI                 playerOne = new Player(nameOne.getText());                 playerTwo = new Player(nameTwo.getText());                 System.out.println("Welcome player one: " + playerOne.getName());                 System.out.println("Welcome player two: " + playerTwo.getName());                 mainFrame.dispose();                 buildGameGUI();             }         });          JPanel startGamePanel = new JPanel();         startGamePanel.add(startGameButton);          JPanel centerPanel = new JPanel();         centerPanel.add(namesPanel);          mainFrame.getContentPane().add(BorderLayout.NORTH,titlePanel);         mainFrame.getContentPane().add(BorderLayout.SOUTH, startGamePanel);         mainFrame.getContentPane().add(BorderLayout.CENTER,centerPanel);         mainFrame.setSize(400,200);         mainFrame.setVisible(true);      }      public void buildGameGUI(){          JFrame gameFrame = new JFrame();         gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);          gameFrame.setSize(500,500);         gameFrame.setVisible(true);          ConnectFourVisualizer gameVisualizer = new ConnectFourVisualizer();          gameFrame.add(BorderLayout.CENTER, gameVisualizer);          JMenuBar menuBar = new JMenuBar();         JMenu fileMenu = new JMenu("File");         JMenuItem exit = new JMenuItem("Exit");          JPanel chooseMovePanel = new JPanel();         JLabel chooseMoveLabel = new JLabel( playerOne.getName() + ", Choose a column from 1 to 7: ");         JTextField moveChoiceField = new JTextField(5);         JButton chooseMoveButton = new JButton("Choose");          exit.addActionListener(new ActionListener() {             //Close the window and stop the program if the user clicks exit             @Override             public void actionPerformed(ActionEvent e) {                 System.exit(0);             }         });          JMenuItem loadGame = new JMenuItem("Load Game");         //Add an action listener here for loading the game         //1.) Restore the state of connect four object from the connect_four.ser file         //2.) Repaint the game board gui to display the previous state's game board and allow the game to continue          JMenuItem saveGame = new JMenuItem("Save Game");         JMenuItem newGame = new JMenuItem("New Game");          newGame.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 //Reset the board and redraw the visual representation based on the empty board                 clearBoard();                 gameVisualizer.repaint();                 totalNumTurns = 0;                 piecesInColumn = new int[COLUMNS];                 chooseMoveLabel.setText(playerOne.getName() + ", Choose a column from 1 to 7: ");                 //Re-enable the buttons and text field in case the previous game had a winner                 moveChoiceField.setEnabled(true);                 chooseMoveButton.setEnabled(true);              }         });          saveGame.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 try{                     FileOutputStream fileOutputStream = new FileOutputStream("connect_four.ser");                     ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);                     objectOutputStream.writeObject(ConnectFour.this);                     objectOutputStream.close();                     fileOutputStream.close();                 }catch (IOException ex){                     ex.printStackTrace();                 }             }         });          loadGame.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 try {                      //Set the current Connect four object references and values equal to the previously saved games values                     ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("connect_four.ser"));                     ConnectFour previousGame = (ConnectFour) objectInputStream.readObject();                     ConnectFour.this.gameBoard = previousGame.gameBoard;                     ConnectFour.this.piecesInColumn = previousGame.piecesInColumn;                     ConnectFour.this.playerOne = previousGame.playerOne;                     ConnectFour.this.playerTwo = previousGame.playerTwo;                     ConnectFour.this.totalNumTurns = previousGame.totalNumTurns;                      System.out.println("The number of turns is: " + totalNumTurns);                      //Determine whose turn it was when the game was saved, and display the appropriate label                     if(totalNumTurns % 2 == 0){                         chooseMoveLabel.setText(playerOne.getName() + ", choose a column from 1 to 7:");                     }                      else{                         chooseMoveLabel.setText(playerTwo.getName() + ", choose a column from 1 to 7");                     }                  }catch(Exception ex){                     ex.printStackTrace();                 }                 //Redraw the game gui no correctly show the loaded game state                 gameVisualizer.repaint();                 printGameBoard();             }         });          //Add the menu items to the menua bar         fileMenu.add(newGame);         fileMenu.add(saveGame);         fileMenu.add(loadGame);         fileMenu.add(exit);         menuBar.add(fileMenu);          gameFrame.getContentPane().add(BorderLayout.NORTH,menuBar);           chooseMovePanel.add(chooseMoveLabel);         chooseMovePanel.add(moveChoiceField);         chooseMovePanel.add(chooseMoveButton);          gameFrame.getContentPane().add(BorderLayout.SOUTH, chooseMovePanel);           chooseMoveButton.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                  //Notice here we're displaying whose turn in is after the current player makes their move                 int move = Integer.parseInt(moveChoiceField.getText());                 if(totalNumTurns % 2 == 0){                     //It's player one's turn, so make their move and after change the text to ask for player two                    boolean attempt =  makeMove(playerOne, move);                    if(attempt == false){                        chooseMoveLabel.setText("That was an invalid move, please try again " + playerOne.getName()+ ":");                        moveChoiceField.setText("");                        return;                    }                     chooseMoveLabel.setText(playerTwo.getName() + ", choose a column from 1 to 7:");                     moveChoiceField.setText("");                 }                  else{                     //Otherwise it's player two's turn, so make their move and change the text to ask for player one                      boolean attempt = makeMove(playerTwo, move);                      if(attempt == false){                          chooseMoveLabel.setText("That was an invalid move, please try again " + playerTwo.getName() + ":");                          moveChoiceField.setText("");                          return;                      }                     chooseMoveLabel.setText(playerOne.getName() + ", choose a column from 1 to 7:");                     moveChoiceField.setText("");                 }                 printGameBoard();                 totalNumTurns++;                 gameVisualizer.repaint();                 int hasWinner = checkForWinner(move);                 if(hasWinner != -1){                     moveChoiceField.setEnabled(false);                     chooseMoveButton.setEnabled(false);                     saveGame.setEnabled(false);                     if(hasWinner == RED){                         chooseMoveLabel.setText(playerOne.getName() + " wins!");                      }                     else if(hasWinner == YELLOW){                         chooseMoveLabel.setText(playerTwo.getName() + " wins!");                     }                 }             }         });     }      public class ConnectFourVisualizer extends JPanel{         private int xBackground;         private int yBackground;         private int widthBackground;         private int heightBackGround;         private int xGameSlot;         private int yGameSlot;         private int widthGameSlot;         private int heightGameSlot;          public ConnectFourVisualizer(){             this.widthGameSlot = 20;             this.heightGameSlot = 20;              this.heightBackGround = 300;             this.widthBackground = 350;              this.xBackground = 75;             this.yBackground = 100;         }          public void paintComponent(Graphics g){             g.setColor(Color.YELLOW);             g.fillRect(xBackground, yBackground, widthBackground, heightBackGround);             int currentX = xBackground + 40;             int currentY = yBackground + 40;              for(int i = 0; i < 6; i++) {                   for (int j = 0; j < 7; j++) {                     if(gameBoard[i][j] == RED){                         g.setColor(Color.RED);                     }                     else if(gameBoard[i][j] == YELLOW){                         g.setColor(Color.BLACK);                     }                     else{                         g.setColor(Color.WHITE);                     }                      g.fillOval(currentX, currentY, widthGameSlot, heightGameSlot);                     currentX += 40;                  }                 currentX = xBackground + 40;                 currentY += 40;              }         }     }       public boolean makeMove(Player player, int column) {         /* Since row position is determined by how many pieces are currently in a given column,          we only need to choose a column position and the row position will be determined as a result. */          //Decrement the column value by 1, as our array is zero indexed.         column--;          //Check if the column chosen is valid         if (column < 0 || column >= COLUMNS) {             System.out.println("Column choice must be between 1 and 7 !");             return false;         }          //Check if the column chosen is already full         if (isColumnFull(column)) {             System.out.println("That column is already full!");             return false;         }         /*Otherwise, start from the bottom of the column and change the value in         the first open row to the player's number*/         else {         //            for (int i = ROWS - 1; i >= 0; i--) {         //                if (gameBoard[i][column] == -1) {         //                    gameBoard[i][column] = player.getPlayerNumber();         //                    break;         //                }         //            }         //            return true;             int nextOpenRow = ROWS - 1 - piecesInColumn[column];             gameBoard[nextOpenRow][column] = player.getPlayerNumber();             piecesInColumn[column]++;             return true;         }      }       public int checkForWinner(int latestMove){          //If the gameboard is full, the game is a TIE         if(isBoardFull()){             // 0 indicates a TIE             return 0;         }          int currentCol = latestMove - 1; //Remember, the user sees the columns numbered 1 -> 7 but our array is 0 indexed         int currentRow = ROWS - piecesInColumn[currentCol]; // Determine which row the last piece was placed in         int rows =  checkRows(currentRow);        int columns =  checkColumns(currentCol);        int diagonals =  checkDiagonals(currentRow,currentCol);          if(rows == RED || columns == RED || diagonals == RED){            return RED;        }         if(rows == YELLOW || columns == YELLOW || diagonals == YELLOW){            return YELLOW;        }         //Otherwise we don't have a winner yer          return -1;     }      private int checkRows(int currentRow){         //Obtain the row and column of the latest move          for (int i = 0; i < COLUMNS - 3; i++) {              if (gameBoard[currentRow][i] == RED &&                     gameBoard[currentRow][i + 1] == RED &&                     gameBoard[currentRow][i + 2] == RED &&                     gameBoard[currentRow][i + 3] == RED) {                  return RED;             }              if (gameBoard[currentRow][i] == YELLOW &&                     gameBoard[currentRow][i + 1] == YELLOW &&                     gameBoard[currentRow][i + 2] == YELLOW &&                     gameBoard[currentRow][i + 3] == YELLOW) {                  return YELLOW;             }         }         //Otherwise, we have no winner yet         return -1;     }      private int checkColumns( int currentCol){         //Check the column          //        if(piecesInColumn[currentCol] < 4){         //            //If there are less than 4 game pieces in the column, there cannot be a winner here by column         //            return -1;         //        }          for (int i = ROWS - 1; i >= ROWS - 3; i--) {             if (gameBoard[i][currentCol] == RED &&                     gameBoard[i - 1][currentCol] == RED &&                     gameBoard[i - 2][currentCol] == RED &&                     gameBoard[i - 3][currentCol] == RED) {                  return RED;             }              if (gameBoard[i][currentCol] == YELLOW &&                     gameBoard[i - 1][currentCol] == YELLOW &&                     gameBoard[i - 2][currentCol] == YELLOW &&                     gameBoard[i - 3][currentCol] == YELLOW) {                  return YELLOW;             }          }          //Otherwise we have no winner         return -1;      }      private int checkDiagonals(int currentRow, int currentCol){         //Check the left-to-right upward diagonal containing the latest move          int startingRow = currentRow + 3;         int startingCol = currentCol - 3;          //get to a starting position that is valid on the board         while (startingRow > ROWS - 1 || startingCol < 0) {             startingRow--;             startingCol++;         }          while (startingRow - 3 >= 0 && startingCol + 3 <  COLUMNS ) {             if (gameBoard[startingRow][startingCol] == RED &&                     gameBoard[startingRow - 1][startingCol + 1] == RED &&                     gameBoard[startingRow - 2][startingCol + 2] == RED &&                     gameBoard[startingRow - 3][startingCol + 3] == RED) {                  return RED;             }              if (gameBoard[startingRow][startingCol] == YELLOW &&                     gameBoard[startingRow - 1][startingCol + 1] == YELLOW &&                     gameBoard[startingRow - 2][startingCol + 2] == YELLOW &&                     gameBoard[startingRow - 3][startingCol + 3] == YELLOW) {                  return YELLOW;             }             startingRow--;             startingCol++;          }          //Check the left to right downward diagonal containing the latest placed game piece          //Reset the starting row and column variables         startingRow = currentRow - 3;         startingCol = currentCol - 3;          while(startingRow < 0 || startingCol < 0 ){             startingCol++;             startingRow++;         }          while(startingRow + 3 < ROWS  && startingCol + 3 < COLUMNS ){             if(gameBoard[startingRow][startingCol] == RED &&                     gameBoard[startingRow + 1][startingCol + 1] == RED &&                     gameBoard[startingRow + 2][startingCol + 2] == RED &&                     gameBoard[startingRow + 3][startingCol + 3] == RED){                  return RED;             }              if(gameBoard[startingRow][startingCol] == YELLOW &&                     gameBoard[startingRow + 1][startingCol + 1] == YELLOW &&                     gameBoard[startingRow + 2][startingCol + 2] == YELLOW &&                     gameBoard[startingRow + 3][startingCol + 3] == YELLOW){                  return YELLOW;             }              startingRow++;             startingCol++;          }          //Otherwise, we have no winner yet         return -1;      }      private boolean isColumnFull(int columnNumber) {         /*Based on the way pieces are placed in a game of connect four, if the very first row of a column has          a piece in it, the column must be full.*/         if (gameBoard[0][columnNumber] == -1) {             return false;         } else {             return true;         }     }      private boolean isBoardFull() {         //If any value in our board is -1, the board is not full         for (int i = 0; i < ROWS; i++) {             for (int j = 0; j < COLUMNS; j++) {                 if (gameBoard[i][j] == -1) {                     return false;                 }             }         }         //Otherwise the board is full         return true;     }      public void printGameBoard() {         System.out.println("==============================");         //Display the number for each column         System.out.println("1 2 3 4 5 6 7");         for (int i = 0; i < ROWS; i++) {             for (int j = 0; j < COLUMNS; j++) {                 if (gameBoard[i][j] == RED) {                     System.out.print("R ");                 } else if (gameBoard[i][j] == YELLOW) {                     System.out.print("Y ");                 } else {                     System.out.print("- ");                 }             }             System.out.println();         }         System.out.println("==============================");     }      public void clearBoard() {         //Reset all board positions to -1         for (int i = 0; i < ROWS; i++) {             for (int j = 0; j < COLUMNS; j++) {                 gameBoard[i][j] = -1;             }         }     } } 

Player.Java:

import java.io.Serializable;  public class Player implements Serializable {      private final String name;     private static int counter = 0;     private int playerNumber;       public Player(String name) {         this.name = name;         this.counter++;         this.playerNumber = counter;     }      public String getName() {         return name;     }      public int getPlayerNumber() {         return playerNumber;     }  }