I'm making a Connect 4 game in Java for more complex practice in checking and for an AI. I already input the mechanics of the game and got the graphics to work. When the user clicks on a numbered button, it drops a token with a color based on whether the first player is up. However, even though the repaint method is called before the bool that handles the player's turn(player1 is the variable), it appears that the cell changes color even though I didn't activate it.
So what's going on?
Code:
import java.awt.event.*;
import java.util.Random;
public class Control implements ActionListener, ItemListener {
Connect4 game = null;
boolean player1 = true; //Checks which player is up
int[][] theBoard = new int[7][6]; //Sets up the board for values [7]-columns, [6]- rows
int[] valid = new int[4]; //Grabs 4 in a row. This is use for a win
//This is for the AI
boolean AI=false; //Is the AI playing or not?
boolean AITurn=false; //A value that switches the AI's turn
boolean AIMadeUpMind=false; //This is for moves in advance
int AINumber=0; //This is for what row the AI will choose
Random generator = new Random(); //This is for whether the AI hadn't made up its mind.
public Control(Connect4 game)
{
game = new Connect4(this);
this.game=game;
}
public static void main(String[] args) {
Control control = new Control(null);
}
public void actionPerformed(ActionEvent input) {
Object current = input.getSource();
//This deals with the slot buttons
for(int x = 0; x < 7; x++)
{
if(current.equals(game.rowButton[x]))
{
dropToken(x);
}
}
//This is for the Start button
if(current.equals(game.start))
{
for(int x = 0; x < 7; x++)
{
game.rowButton[x].setEnabled(true);
}
for(int y = 0; y < 7; y++)
{
for(int z = 0; z < 6; z++)
{
theBoard[y][z]=0;
game.cell[y][z].taken=false;
game.cell[y][z].repaint();
}
}
game.start.setEnabled(false);
game.AI.setEnabled(false);
}
}
public void itemStateChanged(ItemEvent input) {
Object current = input.getSource();
//This is for the AI
if(current.equals(game.AI))
{
if(game.AI.isSelected())
{
AI = true;
}
else
{
AI = false;
}
System.out.println("The AI is " + AI);
}
}
//Handle's the AI's behavior
void AIMove()
{
if(AITurn==true)
{
checkMove(); //First it'll check each move
//Then if it didn't find a move, this will randomly pick a move
while(AIMadeUpMind==false)
{
AINumber = generator.nextInt(7);
if(game.rowButton[AINumber].isEnabled())
{
AIMadeUpMind=true;
}
}
dropToken(AINumber); //When the AI found a move, it'll play the token
}
}
//If it's the AI's turn, it'll check the valid array values and determine a move there
void AIDetermineMove()
{
}
//Will drop the token
void dropToken(int x)
{
int max=0;
//Checks for spaces
for(int y = 5; y >= 0; y--)
{
if(theBoard[x][y]==0)
{
System.out.println(player1);
game.cell[x][y].taken=true;
game.cell[x][y].repaint();
if(player1==true)
{
theBoard[x][y]=1;
player1=false;
if(AI==true)
{
AITurn=true;
}
break;
}
else
{
theBoard[x][y]=2;
player1=true;
if(AI==true)
{
AIMadeUpMind=false;
AITurn=false;
}
break;
}
}
else
{
max++;
}
}
//If there are no moves in this column, it'll lock the button
if(max==5)
{
game.rowButton[x].setEnabled(false);
}
//Then it'll need to check every move for a win
checkMove();
//If the AI is playing, it'll activate the AI's script
if((AI==true) && (AITurn==true))
{
AIMove();
}
}
//The main script for checking wins and for the computer to check for counter/win moves.
void checkMove()
{
checkHorizontalMoves(); //#1- The game will check Horizontal moves for a win.
checkVerticalMoves(); //#2 - The game will check Vertical moves for a win.
checkDiagonal1Moves(); //#3 - The game will check Forward Diagonal moves for a win.
checkDiagonal2Moves(); //#4 - The game will check Reverse Diagonal moves for a win.
}
void checkHorizontalMoves()
{
System.out.println("\nFor Horizontal Wins!");
for (int y = 0; y < 6; y++) // Row
{
System.out.println("For row " + (y+1));
for(int x = 0; x < 4; x++) //Column
{
for(int z = 0; z < 4; z++) //Offset
{
valid[z] = theBoard[x+z][y];
System.out.println("x:" + ((x+z)+1) + ",y:" + (y+1) + " which holds the value " + valid[z]);
}
System.out.println();
checkWin();
if(AITurn==true)
{
}
}
}
}
void checkVerticalMoves()
{
System.out.println("\nFor Vertical Wins!");
for (int y = 0; y < 7; y++) //Column
{
System.out.println("For column " + (y+1));
for(int x = 0; x < 3; x++) //Row
{
for(int z = 0; z < 4; z++) //Offset
{
valid[z] = theBoard[y][x+z];
System.out.println("x:"+ (y+1) + ",y:" + ((x+z)+1) + " which holds the value " + valid[z]);
}
System.out.println();
checkWin();
if(AITurn==true)
{
}
}
}
}
void checkDiagonal1Moves()
{
System.out.println("\nFor Diagonal Wins!");
for (int y = 0; y < 4; y++) //Column
{
System.out.println("For diagonal " + (y+1));
for(int x = 0; x < 3; x++) //Row
{
for(int z = 0; z < 4; z++) //Offset
{
valid[z] = theBoard[y+z][x+z];
System.out.println("x:" + ((y+z)+1) + ",y:" + ((x+z)+1)+ " which holds the value " + valid[z]);
}
System.out.println();
checkWin();
if(AITurn==true)
{
}
}
}
}
void checkDiagonal2Moves()
{
System.out.println("\nFor Diagonal Wins!");
for (int y = 3; y < 7; y++) //Column
{
System.out.println("For reverse diagonal " + (y-2));
for(int x = 0; x < 3; x++) //Row
{
for(int z = 0; z < 4; z++) //Offset
{
valid[z] = theBoard[y-z][z+x];
System.out.println("x:" + ((y-z)+1) + ",y:" + ((z+x)+1)+ " which holds the value " + valid[z]);
}
System.out.println();
checkWin();
if(AITurn==true)
{
}
}
}
}
void checkWin()
{
for(int x = 0; x < 2; x++)
{
if((valid[0]==(x+1)) && (valid[1]==(x+1)) && (valid[2]==(x+1)) && (valid[3]==(x+1)))
{
System.out.println("Player " + (x+1) + " wins!");
for(int z = 0; z < 7; z++)
{
game.rowButton[z].setEnabled(false);
}
game.start.setEnabled(true);
game.AI.setEnabled(true);
AITurn=false;
}}
}
}
Code:
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
public class Connect4 {
Control control;
Cell[][] cell = null;
JFrame window = new JFrame("Connect 4");
//Row 1
JPanel row1 = new JPanel();
JCheckBox AI = new JCheckBox("AI");
JButton start = new JButton("Start");
//Row 2
JPanel row2 = new JPanel();
JButton[] rowButton = new JButton[7];
Dimension rowButtonSize = new Dimension(32,32);
//Row3
JPanel row3 = new JPanel();
public Connect4(Control control)
{
cell = new Cell[7][6];
this.control = control;
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(300,365);
window.setResizable(false);
FlowLayout layout = new FlowLayout();
window.setLayout(layout);
FlowLayout layout1 = new FlowLayout();
row1.setLayout(layout1);
row1.add(AI);
row1.add(start);
window.add(row1);
//It'll then draw the slot 1 through 7 buttons
FlowLayout layout2 = new FlowLayout();
row2.setLayout(layout2);
for(int x =0; x < 7; x++)
{
rowButton[x]= new JButton(Integer.toString(x+1));
rowButton[x].setPreferredSize(rowButtonSize);
rowButton[x].addActionListener(control);
row2.add(rowButton[x]);
rowButton[x].setEnabled(false);
}
window.add(row2);
//Then it'll set up the cells for the board
GridLayout layout3 = new GridLayout(6,7);
row3.setLayout(layout3);
for(int y = 0; y < 6; y++)
{
for(int x = 0; x < 7; x++)
{
cell[x][y] = new Cell(control);
System.out.println(x + "," + y);
row3.add(cell[x][y]);
}}
row3.setPreferredSize(new Dimension(32*7,32*6));
window.add(row3);
AI.addItemListener(control);
start.addActionListener(control);
window.setVisible(true);
}
}
class Cell extends JComponent
{
boolean taken=false;
Control control;
public Cell(Control control)
{
this.control = control;
}
public void paint(Graphics g)
{
//This'll draw the rectangle for the cell.
super.paint(g);
g.setColor(Color.black);
g.drawRect(0, 0, 31, 31);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(taken==true)
{
drawCircle(g,control.player1); //This'll draw a circle representing the player's token
}
}
void drawCircle(Graphics g, boolean player1Taken)
{
if(player1Taken==true)
{
g.setColor(Color.yellow);
}
else
{
g.setColor(Color.red);
}
g.fillOval(0, 0, 31, 31);
}
}