/* Copyright 2013 Grady Moran Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.awt.Color; public class Connect_4 extends JPanel { public int[][] infoBoard;//filled with 0s (indicating open), 1s (indicating player 1 chip), and 2s (indicating player 2 chip) public Connect_4() { setLayout(new BorderLayout()); JLabel info = new JLabel("Player 1 starts"); JButton reset = new JButton("Reset"); JButton[][] board = new JButton[6][7]; int[][] infoBoard = new int[6][7]; for(int r = 0; r < 6; r++)//sets all spots in infoBoard as 0 { for(int c = 0; c < 7; c++) { infoBoard[r][c] = 0; } } JPanel north = new JPanel(); north.setLayout(new FlowLayout()); add(north, BorderLayout.NORTH); north.add(info); info.setForeground(Color.red);//not sure what I was looking for in doing this JPanel center = new JPanel(); center.setLayout(new GridLayout(6,7)); add(center, BorderLayout.CENTER); for(int r = 0; r < 6; r++) { for(int c = 0; c < 7; c++) { board[r][c] = new JButton(); board[r][c].setBackground(Color.white); board[r][c].addActionListener(new spot_Handler(r, c, infoBoard, board, info)); center.add(board[r][c]); } } JPanel south = new JPanel(); south.setLayout(new FlowLayout()); add(south, BorderLayout.SOUTH); south.add(reset); reset.addActionListener(new reset_Handler(infoBoard, board, info)); }//constructor public int getStreakLength(int r, int c, int[][]infoBoard)//returns max streak (int) that current location has { int[] dirs = new int[8];//first val is streak N, second streak NE, etc for (int q = 0; q < dirs.length; q++) dirs[q] = 0; for (int d = 0; d < 8; d++) { if (d==0)//N { for(int start = r; start > -1; start--) { if(infoBoard[r][c]==infoBoard[start][c]) dirs[d]++; else break;//needed or else it will count all instances of current player's token in the direction specified } } if(d==1)//NE { int f = r;//temp row var int g = c;//temp col var while((f>-1) && (g<7)) { if(infoBoard[f][g] == infoBoard[r][c]) { dirs[d]++; f--; g++; } else break; } } if(d==2)//E { for(int start = c; start < 7; start++) { if(infoBoard[r][c]==infoBoard[r][start]) dirs[d]++; else break; } } if(d==3)//SE { int f = r;//row int g = c;//col while((f<6) && (g<7)) { if(infoBoard[f][g] == infoBoard[r][c]) { dirs[d]++; f++; g++; } else break; } } if(d==4)//S { for(int start = r; start < 6; start++) { if(infoBoard[r][c]==infoBoard[start][c]) dirs[d]++; else break; } } if(d==5)//SW { int f = r;//row int g = c;//col while((f<6) && (g>-1)) { if(infoBoard[f][g] == infoBoard[r][c]) { dirs[d]++; f++; g--; } else break; } } if(d==6)//W { for(int start = c; start > -1; start--) { if(infoBoard[r][c]==infoBoard[r][start]) dirs[d]++; else break; } } if(d==7)//NW { int f = r;//row int g = c;//col while((f>-1) && (g>-1)) { if(infoBoard[f][g] == infoBoard[r][c]) { dirs[d]++; f--; g--; } else break; } } } int maxStreak = dirs[0]; for(int i = 1; i < dirs.length; i++) { if(dirs[i] > maxStreak) maxStreak = dirs[i]; } if(infoBoard[r][c] == 0) return 0;//does not count streaks of white else return maxStreak; //returns max val of dirs[] }//getStreakLength public static void main(String[] args) { JFrame frame = new JFrame("Connect 4"); frame.setSize(400, 400); frame.setLocation(200, 100); frame.setContentPane(new Connect_4()); frame.setVisible(true); }//main private class spot_Handler implements ActionListener //when space on board is selected { private int myRow, myCol; private int[][] infoBoard; private JButton[][] board; private JLabel info; public spot_Handler(int r, int c, int[][] infoBoard_b, JButton[][] board_b,JLabel info_b) { myRow = r; myCol = c; infoBoard = infoBoard_b; board = board_b; info = info_b; } public void actionPerformed(ActionEvent e) { int p1spots = 0;//num of spots on board occupied by p1 int p2spots = 0; for(int r = 0; r<6; r++) { for(int c = 0; c<7; c++) { if(infoBoard[r][c] == 1) p1spots++; if(infoBoard[r][c] == 2) p2spots++; } } boolean endgame = false; for(int r = 0; r<6; r++) { for(int c = 0; c<7; c++) { if(getStreakLength(r,c,infoBoard) >= 4) { endgame=true; } } } boolean filledUnder = true; for(int i = 5; i > myRow; i--) { if(infoBoard[i][myCol] == 0) filledUnder = false; } if(filledUnder && !endgame) { boolean full = false; int count = 0; for (int r = 0; r < 6; r++) { for (int c = 0; c < 7; c++) { if(infoBoard[r][c] != 0) count++; } } if (count == 41) full = true; if(infoBoard[myRow][myCol] == 0) { if (p2spots >= p1spots)//player 1 moving { if (full) { info.setText("Board is full. Press reset."); info.setForeground(Color.black); infoBoard[myRow][myCol] = 1; board[myRow][myCol].setBackground(Color.red); } else { infoBoard[myRow][myCol] = 1; board[myRow][myCol].setBackground(Color.red); info.setText("Player 2's turn"); if(getStreakLength(myRow, myCol, infoBoard) >= 4) info.setText("Player 1 wins!"); else info.setForeground(Color.blue); } } else//player 2 moving { if (full) { info.setText("Board is full. Press reset."); info.setForeground(Color.black); infoBoard[myRow][myCol] = 2; board[myRow][myCol].setBackground(Color.blue); } else { infoBoard[myRow][myCol] = 2; board[myRow][myCol].setBackground(Color.blue); info.setText("Player 1's turn"); if(getStreakLength(myRow, myCol, infoBoard) >= 4) info.setText("Player 2 wins!"); else info.setForeground(Color.red); } } } else if (infoBoard[myRow][myCol] != 0 && !full) info.setText("Space is filled; try another space"); if (full) { info.setText("Board is full. Press reset."); info.setForeground(Color.black); } } else if (!filledUnder && !endgame) { info.setText("Piece is not connected with bottom of board."); } }//actionPerformed }//spot_Handler private class reset_Handler implements ActionListener { private int[][] infoBoard; private JButton[][] board; private JLabel info; public reset_Handler(int[][] infoBoard_b, JButton[][] board_b, JLabel info_b) { infoBoard = infoBoard_b; board = board_b; info = info_b; } public void actionPerformed(ActionEvent e) { for (int r = 0; r<6; r++) { for (int c = 0; c<7; c++) { board[r][c].setBackground(Color.white); infoBoard[r][c] = 0; } } info.setText("Player 1 starts"); info.setForeground(Color.red); } }//reset_Handler }//Connect_4