patternjavaMinor
Connect Four game with minimax AI
Viewed 0 times
minimaxconnectwithfourgame
Problem
I have created a connect four game between a bot and a player. It was quite a bit of a challenge since I wasn't too fond of the minmax algorithm until now. I know there's always room for improvement and I am wondering if someone can tell me if my code is up to standards, i.e. better solutions etc. Please feel free to scrutinize my code.
```
package connect4;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
enum Piece
{
Red,
Blue,
None
}
class Board extends JButton
{
public int i, j;
public Piece piece = Piece.None;
public Board(int i, int j)
{
this.i = i;
this.j = j;
setOpaque(true);
setColor();
}
public void setPiece(Piece piece)
{
this.piece = piece;
setColor();
}
public void setColor()
{
switch(piece)
{
case Red:
setBackground(Color.red);
break;
case Blue:
setBackground(Color.blue);
break;
case None:
setBackground(Color.white);
break;
}
}
}
class Tree // this is the minmax algorithm
{
public int value;
Board[][] Boards; // this is the board
private ArrayList bestMoves;
Board prev = null;
int depth;
static int maxDepth = 4; // this is the max depth im going down
public Tree(Board[][] Boards, int depth)
{
this.Boards = Boards;
this.bestMoves = new ArrayList();
this.depth = depth;
this.value = getValue();
if(depth -100 )
{
ArrayList possibilities = new ArrayList();
for(int i = 0; i child.value)
{
bestMoves.clear();
bestMoves.add(possibilities.get(i));
```
package connect4;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
enum Piece
{
Red,
Blue,
None
}
class Board extends JButton
{
public int i, j;
public Piece piece = Piece.None;
public Board(int i, int j)
{
this.i = i;
this.j = j;
setOpaque(true);
setColor();
}
public void setPiece(Piece piece)
{
this.piece = piece;
setColor();
}
public void setColor()
{
switch(piece)
{
case Red:
setBackground(Color.red);
break;
case Blue:
setBackground(Color.blue);
break;
case None:
setBackground(Color.white);
break;
}
}
}
class Tree // this is the minmax algorithm
{
public int value;
Board[][] Boards; // this is the board
private ArrayList bestMoves;
Board prev = null;
int depth;
static int maxDepth = 4; // this is the max depth im going down
public Tree(Board[][] Boards, int depth)
{
this.Boards = Boards;
this.bestMoves = new ArrayList();
this.depth = depth;
this.value = getValue();
if(depth -100 )
{
ArrayList possibilities = new ArrayList();
for(int i = 0; i child.value)
{
bestMoves.clear();
bestMoves.add(possibilities.get(i));
Solution
First, you should ask yourself whether the names you chose are good. For example, a typical game of connect four takes place on a single Board, yet you defined an array of boards and call this array a board. This doesn't make sense.
A completely different topic is spelling rules. In Java, field and variable names start with a lowercase letter. You have
You did not say what you mean by optimize. But no matter if it's for speed or for clarity, you should separate the complicated game logic from the user interface logic. Doing this enables you to test the game logic using unit tests.
If you strive for speed, you should remember the last position where a piece was dropped, since you only need to check at this particular position whether there is a new row of 4.
Please use a program that formats your code whenever you save it. This will make it look more consistent.
Your use of the random number generator is unfair, since it favors lower indexes. A quick fix would be
Note that I changed the class name from
A completely different topic is spelling rules. In Java, field and variable names start with a lowercase letter. You have
Board Board sometimes, which confuses every reader.You did not say what you mean by optimize. But no matter if it's for speed or for clarity, you should separate the complicated game logic from the user interface logic. Doing this enables you to test the game logic using unit tests.
If you strive for speed, you should remember the last position where a piece was dropped, since you only need to check at this particular position whether there is a new row of 4.
Please use a program that formats your code whenever you save it. This will make it look more consistent.
Your use of the random number generator is unfair, since it favors lower indexes. A quick fix would be
(int)(Math.random() * bestMoves.size()), but that still looks complicated. A better way is to define a random number generator and ask it for integer numbers:class MiniMax {
Random rnd = new Random();
int randomMove() {
return bestMoves.get(rnd.nextInt(bestMoves.size());
}
}Note that I changed the class name from
Tree to MiniMax. By choosing clear names you make the comments of the form // This is … superfluous.Code Snippets
class MiniMax {
Random rnd = new Random();
int randomMove() {
return bestMoves.get(rnd.nextInt(bestMoves.size());
}
}Context
StackExchange Code Review Q#150541, answer score: 6
Revisions (0)
No revisions yet.