Skip to content

Instantly share code, notes, and snippets.

@kevinbarbour
Last active December 16, 2015 11:59
Show Gist options
  • Save kevinbarbour/5431147 to your computer and use it in GitHub Desktop.
Save kevinbarbour/5431147 to your computer and use it in GitHub Desktop.
Connect 4 game using decision trees in java. WIP
// Kevin Barbour
// CMSC 401
// Program #5: Connect 4
// Program name: C4.java
import java.lang.Math;
import java.util.Scanner;
class Node {
final int MAXSCORE = 9999;
final int MINSCORE = -9999;
char[][] board;
Node[] children;
int[] childScores;
int score, move, moveRow, level;
char turn, ch;
boolean compTurn;
public Node(int level) {
board = new char[6][7];
this.level = level;
compTurn = false;
ch = 'B';
reset();
}
public Node(Node parent, int move, int level) {
board = new char[6][7];
for(int i = 0; i < 6; i++) {
for(int j = 0; j < 7; j++) {
board[i][j] = parent.getBoard()[i][j];
}
}
//board = (char[][])parent.getBoard().clone();
this.level = level;
this.move = move;
children = new Node[7];
this.compTurn = !parent.isCompTurn();
if(compTurn) ch = 'R';
else ch = 'B';
makeMove();
calcScore();
}
public void genNode() {
for(int i = 0; i < 7; i++) {
children[i] = new Node(this, i, level - 1);
}
}
void calcScore() {
int col = move;
int tempScore = -1;
if(this.won()) {
if(!compTurn) score = MAXSCORE;
else score = MINSCORE;
return;
}
int wCount = 0;
int bCount = 0;
if(!compTurn) {
if(9000 > tempScore && (
(board[(moveRow + 1) % 6][move] == 'R' &&
board[(moveRow + 2) % 6][move] == 'R' &&
board[(moveRow + 3) % 6][move] == 'R') ||
(board[Math.abs((moveRow - 1) % 6)][move] == 'R' &&
board[Math.abs((moveRow - 2) % 6)][move] == 'R' &&
board[Math.abs((moveRow - 3) % 6)][move] == 'R') ||
(board[moveRow][(move + 1) % 7] == 'R' &&
board[moveRow][(move + 2) % 7] == 'R' &&
board[moveRow][(move + 3) % 7] == 'R') ||
(board[moveRow][Math.abs((move - 1) % 7)] == 'R' &&
board[moveRow][Math.abs((move - 2) % 7)] == 'R' &&
board[moveRow][Math.abs((move - 3) % 7)] == 'R'))) {
tempScore = 9000;
}
if((8000 > tempScore) && (
(board[(moveRow + 1) % 6][move] == 'B' &&
board[(moveRow + 2) % 6][move] == 'B' &&
(board[(moveRow + 3) % 6][move] == ' ' ||
board[Math.abs((moveRow - 1) % 6)][move] == ' ')) ||
(board[Math.abs((moveRow - 1) % 6)][move] == 'B' &&
board[Math.abs((moveRow - 2) % 6)][move] == 'B' &&
(board[Math.abs((moveRow - 3) % 6)][move] == ' ' ||
board[(moveRow + 1) % 6][move] == ' ')) ||
(board[moveRow][(move + 1) % 7] == 'B' &&
board[moveRow][(move + 2) % 7] == 'B' &&
(board[moveRow][(move + 3) % 7] == ' ' ||
board[moveRow][Math.abs((move - 1) % 7)] == ' ')) ||
(board[moveRow][Math.abs(move - 1) % 7] == 'B' &&
board[moveRow][Math.abs(move - 2) % 7] == 'B' &&
(board[moveRow][Math.abs(move - 3) % 7] == ' ' ||
board[moveRow][(move + 1) % 7] == ' ')))) {
tempScore = 8000;
}
if((7000 > tempScore) && (
(board[(moveRow + 1) % 6][move] == 'W' &&
board[(moveRow + 2) % 6][move] == 'W' &&
(board[(moveRow + 3) % 6][move] == ' ' ||
board[Math.abs((moveRow - 1) % 6)][move] == ' ')) ||
(board[Math.abs((moveRow - 1) % 6)][move] == 'W' &&
board[Math.abs((moveRow - 2) % 6)][move] == 'W' &&
(board[Math.abs((moveRow - 3) % 6)][move] == ' ' ||
board[(moveRow + 1) % 6][move] == ' ')) ||
(board[moveRow][(move + 1) % 7] == 'W' &&
board[moveRow][(move + 2) % 7] == 'W' &&
(board[moveRow][(move + 3) % 7] == ' ' ||
board[moveRow][Math.abs((move - 1) % 7)] == ' ')) ||
(board[moveRow][Math.abs(move - 1) % 7] == 'W' &&
board[moveRow][Math.abs(move - 2) % 7] == 'W' &&
(board[moveRow][Math.abs(move - 3) % 7] == ' ' ||
board[moveRow][(move + 1) % 7] == ' ')))) {
tempScore = 7000;
}
if(tempScore < 100) tempScore = 100;
score = tempScore;
int childScore = 0;
if(level > 0) {
genNode();
for(int i = 0; i < 7; i++) {
childScore += children[i].getScore();
}
childScore = childScore/20;
score += childScore;
}
}
}//calcScore
public boolean won() {
int col = move;
int row = -1;
int count;
for(int i = 0; row == -1 && i < 20; i++) {
if(board[i % 6][col] == ch) row = i;
}
if(row < 0) return false;
count = 0;
for(int i = 0; i < 10; i++) {
if(board[row][i % 7] == ch) count++;
else count = 0;
if(count == 4) return true;
}
count = 0;
for(int i = 0; i < 10; i++) {
if(board[i % 6][col] == ch) count++;
else count = 0;
if(count == 4) return true;
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 4; j++) {
if((board[i][j] == ch &&
board[i + 1][j + 1] == ch &&
board[i + 2][j + 2] == ch &&
board[i + 3][j + 3] == ch) ||
(board[i + 3][j] == ch &&
board[i + 2][j + 1] == ch &&
board[i + 1][j + 2] == ch &&
board[i][j + 3] == ch )) {
return true;
}
}
}
return false;
}
void reset() {
for(int i = 0; i < 6; i++)
for(int j = 0; j < 7; j++)
board[i][j] = ' ';
}
void makeMove() {
if(board[0][move] != ' ') {
score = -9999999;
return;
}
for(int i = 5; i > -1; i--) {
if(board[i][move] == ' ') {
board[i][move] = ch;
moveRow = i;
return;
}
}
}//play
public void printBoard() {
for(int i = 0; i < 6; i++) {
for(int j = 0; j < 7; j++) {
System.out.printf(" %c ", board[i][j]);
}
System.out.println();
}
System.out.println(" 0 1 2 3 4 5 6");
}//printBoard
public char[][] getBoard() { return board; }
public int getScore() { return score; }
public boolean isCompTurn() { return compTurn; }
public Node[] getChildren() { return children; }
}
class CompPlayer {
static public int play(Node curNode) {
curNode.genNode();
int score = curNode.getChildren()[0].getScore();
int node = 0;
for(int i = 0; i < 7; i++) {
if(curNode.getChildren()[i].getScore() > score ||
(curNode.getChildren()[i].getScore() == score &&
Math.random() > 0.5)) {
score = curNode.getChildren()[i].getScore();
node = i;
}
}
return node;
}
}
class C4 {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
boolean gameOver = false;
boolean playerTurn = true;
int searchLevel;
System.out.println("What level should the decision tree search to?");
searchLevel = input.nextInt();
Node gameBoard = new Node(searchLevel);
while(!gameOver) {
if(playerTurn) {
gameBoard.printBoard();
System.out.printf("What column would you like to play in? [0-6] ");
int col = input.nextInt();
gameBoard = new Node(gameBoard, col, searchLevel);
} else gameBoard = new Node(gameBoard, CompPlayer.play(gameBoard), searchLevel);
if(gameBoard.won()) {
gameOver = true;
gameBoard.printBoard();
if(!playerTurn) {
System.out.println("Computer won!");
} else System.out.println("You won!");
}
playerTurn = !playerTurn;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment