Skip to content

Instantly share code, notes, and snippets.

@ahmednasserpro
Created June 22, 2019 19:28
Show Gist options
  • Save ahmednasserpro/ff3a957e5bcff620c65f8724e337a68b to your computer and use it in GitHub Desktop.
Save ahmednasserpro/ff3a957e5bcff620c65f8724e337a68b to your computer and use it in GitHub Desktop.
(Game: play connect four with computer) Revise Exercise 18.34 to play the game with the computer. The program lets the user make a move first, followed by a move by the computer. The minimum requirement is for the computer to make a legal move. You are encouraged to design good strategies for the computer to make intelligent moves
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PlayConnectFourWithComputer extends JFrame {
private Cell[][] cells = new Cell[6][7];
private char nextDisc = 'R';
private int[][] result;
private Timer timer = new Timer(100, new FlashingCells());
private JButton startOver = new JButton("Start Over");
public PlayConnectFourWithComputer() {
JPanel p1 = new JPanel(new GridLayout(6, 7));
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[0].length; j++)
p1.add(cells[i][j] = new Cell(i, j));
JPanel p2 = new JPanel();
p2.add(startOver);
add(p1);
add(p2, BorderLayout.SOUTH);
startOver.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.stop();
startOver();
}
});
}
private class FlashingCells implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (cells[result[0][0]][result[0][1]].token == ' ') {
cells[result[0][0]][result[0][1]].token = nextDisc;
cells[result[1][0]][result[1][1]].token = nextDisc;
cells[result[2][0]][result[2][1]].token = nextDisc;
cells[result[3][0]][result[3][1]].token = nextDisc;
} else {
cells[result[0][0]][result[0][1]].token = ' ';
cells[result[1][0]][result[1][1]].token = ' ';
cells[result[2][0]][result[2][1]].token = ' ';
cells[result[3][0]][result[3][1]].token = ' ';
}
repaint();
}
}
class Cell extends JPanel {
public char token = ' ';
public int i, j;
public Cell(int i, int j) {
this.i = i;
this.j = j;
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (result != null)
return; // Game over
if (nextDisc == 'R' && isAvailabel(i, j)) {
token = nextDisc;
repaint();
result = isConsecutiveFour(cells);
System.out.println(result);
if (result != null) {
timer.start();
return;
}
if (isDraw()) {
JOptionPane.showMessageDialog(null,
"A draw, no winner, start over");
startOver();
}
nextDisc = 'Y';
}
if (nextDisc == 'Y') {
int[][] availabelRowAndColumn =
getAvailabelRowAndColumn(cells);
int row = availabelRowAndColumn[0][0];
int column = availabelRowAndColumn[0][1];
cells[row][column].token = nextDisc;
cells[row][column].repaint();
result = isConsecutiveFour(cells);
if (result != null) {
timer.start();
return;
}
if (isDraw()) {
JOptionPane.showMessageDialog(null,
"A draw, no winner, start over");
startOver();
}
nextDisc = 'R';
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
int radius = Math.min(getWidth(), getHeight()) * 4 / 10;
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
switch (token) {
case ' ':
g.setColor(Color.white);
g.fillOval(getWidth() / 2 - radius, getHeight() / 2 - radius,
radius * 2, radius * 2);
break;
case 'R':
g.setColor(Color.red);
g.fillOval(getWidth() / 2 - radius, getHeight() / 2 - radius,
radius * 2, radius * 2);
break;
case 'Y':
g.setColor(Color.yellow);
g.fillOval(getWidth() / 2 - radius, getHeight() / 2 - radius,
radius * 2, radius * 2);
}
}
public boolean isAvailabel(int i, int j) {
return cells[i][j].token == ' ' && (i == 5 || cells[i + 1][j].token != ' ');
}
private boolean isDraw() {
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[0].length; j++)
if (cells[i][j].token == ' ')
return false;
return true;
}
}
private void startOver() {
nextDisc = 'R';
result = null;
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[0].length; j++)
cells[i][j].token = ' ';
repaint();
}
private static int[][] getAvailabelRowAndColumn(Cell[][] cells) {
int numberOfElements = 0;
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[0].length; j++)
if (cells[i][j].isAvailabel(i, j))
numberOfElements++;
int[][] array = new int[numberOfElements][2];
int currentIndex = 0;
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[0].length; j++) {
if (cells[i][j].isAvailabel(i, j)) {
array[currentIndex][0] = i;
array[currentIndex][1] = j;
currentIndex++;
}
}
}
if (numberOfElements != 0) {
int[][] result = new int[1][2];
int random = (int) (Math.random() * numberOfElements);
result[0][0] = array[random][0];
result[0][1] = array[random][1];
return result;
}
return null;
}
private static int[][] isConsecutiveFour(Cell[][] cells) {
char[][] values = new char[cells.length][cells[0].length];
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[0].length; j++)
values[i][j] = cells[i][j].token;
return isConsecutiveFour(values);
}
private static int[][] isConsecutiveFour(char[][] values) {
int numberOfRows = values.length;
int numberOfColumns = values[0].length;
// Check rows
for (int i = 0; i < numberOfRows; i++) {
if (isConsecutiveFour(values[i]) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(values[i]);
result[0][0] = result[1][0] = result[2][0] = result[3][0] = i;
result[0][1] = k;
result[1][1] = k + 1;
result[2][1] = k + 2;
result[3][1] = k + 3;
return result;
}
}
// Check columns
for (int j = 0; j < numberOfColumns; j++) {
char[] column = new char[numberOfRows];
for (int i = 0; i < numberOfRows; i++)
column[i] = values[i][j];
if (isConsecutiveFour(column) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(column);
result[0][0] = k;
result[1][0] = k + 1;
result[2][0] = k + 2;
result[3][0] = k + 3;
result[0][1] = result[1][1] = result[2][1] = result[3][1] = j;
return result;
}
}
// Check major diagnoal (lower part)
for (int i = 0; i < numberOfRows - 3; i++) {
int numberOfElements = numberOfRows - i;
char[] diagnoal = new char[numberOfElements];
for (int j = 0; j < numberOfElements; j++)
diagnoal[j] = values[i + j][j];
if (isConsecutiveFour(diagnoal) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(diagnoal);
result[0][0] = i + k;
result[0][1] = i + k + 1;
result[0][2] = i + k + 2;
result[0][3] = i + k + 3;
result[0][1] = k;
result[1][1] = k + 1;
result[2][1] = k + 2;
result[3][1] = k + 3;
return result;
}
}
// Check major diagnoal (upper part)
for (int j = 1; j < numberOfColumns - 3; j++) {
int numberOfElements = numberOfColumns - j;
char[] diagnoal = new char[numberOfElements];
for (int i = 0; i < numberOfElements; i++)
diagnoal[i] = values[i][j + i];
if (isConsecutiveFour(diagnoal) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(diagnoal);
result[0][0] = k;
result[1][0] = k + 1;
result[2][0] = k + 2;
result[3][0] = k + 3;
result[0][1] = k + j;
result[1][1] = k + j + 1;
result[2][1] = k + j + 2;
result[3][1] = k + j + 3;
return result;
}
}
// Check sub-diagnoal (left part)
for (int j = 3; j < numberOfColumns; j++) {
int numberOfElements = Math.min(j + 1, numberOfRows);
char[] diagnoal = new char[numberOfElements];
for (int i = 0; i < numberOfElements; i++)
diagnoal[i] = values[i][j - i];
if (isConsecutiveFour(diagnoal) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(diagnoal);
result[0][0] = k;
result[1][0] = k + 1;
result[2][0] = k + 2;
result[3][0] = k + 3;
result[0][1] = j - k;
result[1][1] = j - k - 1;
result[2][1] = j - k - 2;
result[3][1] = j - k - 3;
return result;
}
}
// Check sub-diagnoal (right part)
for (int i = 1; i < numberOfRows - 3; i++) {
int numberOfElements = numberOfRows - i;
char[] diagnoal = new char[numberOfElements];
for (int j = 0; j < numberOfElements; j++)
diagnoal[j] = values[i + j][numberOfColumns - j - 1];
if (isConsecutiveFour(diagnoal) != null) {
int[][] result = new int[4][2];
int k = isConsecutiveFour(diagnoal);
result[0][0] = i + k;
result[1][0] = i + k + 1;
result[2][0] = i + k + 2;
result[3][0] = i + k + 3;
result[0][1] = numberOfColumns - k - 1;
result[1][1] = numberOfColumns - k - 2;
result[2][1] = numberOfColumns - k - 3;
result[3][1] = numberOfColumns - k - 4;
return result;
}
}
return null;
}
private static Integer isConsecutiveFour(char[] values) {
for (int i = 0; i < values.length - 3; i++) {
boolean isEqual = true;
for (int j = i; j < i + 3; j++) {
if (values[j] == ' ' || values[j] != values[j + 1]) {
isEqual = false;
break;
}
}
if (isEqual)
return i;
}
return null;
}
public static void main(String[] args) {
JFrame frame = new PlayConnectFourWithComputer();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment