Have tried debugging my MiniMax code but can't seem to find the problem here. The main method is evalGame(), which returns 1 for a win, -1 for a loss and 0 for a tie. Are there any obvious errors I have made in the MiniMax algorithm?
package tictactoe;
import static tictactoe.Player.*;
import java.util.Arrays;
public class MinimaxTTT {
private Player[] board = new Player[9];
private static Player player = X;
public MinimaxTTT() {
Arrays.fill(board, E);
player = X;
}
public MinimaxTTT(Player[] b, Player p) {
for(int i = 0; i < 9; i++) {
board[i] = b[i];
}
player = p;
}
public static boolean checkWin(Player[] b, Player p) {
if((b[0]==p&&b[1]==p&&b[2]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)
|| (b[0]==p&&b[1]==p&&b[2]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[0]==p&&b[1]==p&&b[2]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)) {
return true;
}
return false;
}
private static boolean checkTie(Player[] b) {
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
return false;
}
}
return true;
}
private static boolean gameOver(Player[] b) {
return checkTie(b) || checkWin(b, X) || checkWin(b, O);
}
private static int maxOfArray(int[] a) {
int max = a[0];
for (int i : a)
if (max < i)
max = i;
return max;
}
private static int minOfArray(int[] a) {
int min = a[0];
for (int i : a)
if (min > i)
min = i;
return min;
}
private static int getEmptyNumber(Player[] b) {
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E)
spaces++;
}
return spaces;
}
private static int evalGame(Player[] b, Player p, Player currentP) {
if(gameOver(b)) {
if(checkWin(b, p)) {
return 1;
} else if(checkWin(b, p == X ? O : X)) {
return -1;
} else {
return 0;
}
} else {
int[] arrayEval = new int[getEmptyNumber(b)];
for(int i = 0; i < getEmptyNumber(b); i++) {
arrayEval[i] = evalGame(possibleBoards(b, currentP)[i], p, currentP == X ? O : X);
}
if(currentP == p) {
return maxOfArray(arrayEval);
} else {
return minOfArray(arrayEval);
}
}
}
public static Player[][] possibleBoards(Player[] b, Player p) {
Player[][] toReturn = new Player[getEmptyNumber(b)][9];
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
for(int j = 0; j < 9; j++) {
toReturn[spaces][j] = b[j];
}
toReturn[spaces][i] = p;
spaces++;
}
}
return toReturn;
}
public static void main(String[] args) {
Player[] p = new Player[9];
Arrays.fill(p, E);
p[1] = X;
System.out.println(evalGame(p, O, O));
}
}
I have since looked over my code and realised I made a mistake while debugging. The working, edited code is below for anyone who is interested
package tictactoe;
import static tictactoe.Player.*;
import java.util.Arrays;
public class MinimaxTTT {
private Player[] board = new Player[9];
private Player player = X;
public MinimaxTTT() {
Arrays.fill(board, E);
player = X;
}
public MinimaxTTT(Player[] b, Player p) {
for(int i = 0; i < 9; i++) {
board[i] = b[i];
}
player = p;
}
public Player[] getBoard() {
return board;
}
public void setBoard(Player[] b) {
for(int i = 0; i < 9; i++) {
board[i] = b[i];
}
}
public void setSquare(int i, Player p) {
board[i] = p;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player p) {
player = p;
}
public void switchPlayers() {
player = player == X ? O : X;
}
public boolean checkWin(Player[] b, Player p) {
if(b[0] == p && b[1] == p && b[2] == p
|| b[3] == p && b[4] == p && b[5] == p
|| b[6] == p && b[7] == p && b[8] == p
|| b[0] == p && b[3] == p && b[6] == p
|| b[1] == p && b[4] == p && b[7] == p
|| b[2] == p && b[5] == p && b[8] == p
|| b[0] == p && b[4] == p && b[8] == p
|| b[2] == p && b[4] == p && b[6] == p) {
return true;
}
return false;
}
public boolean checkTie(Player[] b) {
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
return false;
}
}
return true;
}
public boolean gameOver(Player[] b) {
return checkTie(b) || checkWin(b, X) || checkWin(b, O);
}
private int maxOfArray(int[] a) {
int max = a[0];
for (int i : a)
if (max < i)
max = i;
return max;
}
private int minOfArray(int[] a) {
int min = a[0];
for (int i : a)
if (min > i)
min = i;
return min;
}
private int getEmptyNumber(Player[] b) {
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E)
spaces++;
}
return spaces;
}
private int findIndex(int[] is, int n) {
for(int i = 0; i < is.length; i++) {
if(is[i] == n)
return i;
}
return 0;
}
private int[] evalGame(Player[] b, Player p, Player currentP, int depth) {
int[] toReturn = new int[2];
if(gameOver(b)) {
if(checkWin(b, p)) {
toReturn[1] = 10 + depth;
return toReturn;
} else if(checkWin(b, p == X ? O : X)) {
toReturn[1] = depth - 10;
return toReturn;
} else {
toReturn[1] = 0;
return toReturn;
}
} else {
depth += 1;
int[] arrayEval = new int[getEmptyNumber(b)];
for(int i = 0; i < getEmptyNumber(b); i++) {
arrayEval[i] = evalGame(possibleBoards(b, currentP)[i], p, currentP == X ? O : X, depth)[1];
}
if(currentP == p) {
int position = findIndex(arrayEval, maxOfArray(arrayEval));
int base = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
if(base == position) {
toReturn[0] = i;
break;
} else {
base++;
}
}
}
toReturn[1] = maxOfArray(arrayEval);
return toReturn;
} else {
toReturn[1] = minOfArray(arrayEval);
return toReturn;
}
}
}
public Player[][] possibleBoards(Player[] b, Player p) {
Player[][] toReturn = new Player[getEmptyNumber(b)][9];
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
for(int j = 0; j < 9; j++) {
toReturn[spaces][j] = b[j];
}
toReturn[spaces][i] = p;
spaces++;
}
}
return toReturn;
}
public Player[] move() {
if(!gameOver(board)) {
board[evalGame(board, player, player, 0)[0]] = player;
}
return board;
}
}
Related
I am using MinMax algorithm for Tictactoe, and it works correctly, but it's trying to win, without blocking my turns, so it's very easy to win the AI.
I added the depth parameter, but the result is the same.
Here you can see my code:
public int playMiniMax(Tableau t, char maximizingPlayer,int depth) {
int bestMove = 0;
if (t.getWinner() == 'x') {
return 1;
} else if (t.getWinner() == 'd') {
return 0;
} else if (t.getWinner() == 'o') {
return -1;
}
else if (depth == 0) {
return 0;
}
else {
int bestValue;
int i;
if (maximizingPlayer == 'x') {
bestValue = Integer.MIN_VALUE;
for(i = 1; i <= 9; ++i) {
if (t.chooseCase(i, 'x')) {
bestValue = Math.max(bestValue, this.playMiniMax(t, 'o',depth-1));
bestMove = i;
t.resetCase(i);
}
}
} else {
bestValue = Integer.MAX_VALUE;
for(i = 1; i <= 9; ++i) {
if (t.chooseCase(i, 'o')) {
bestValue = Math.min(bestValue, this.playMiniMax(t, 'x',depth-1));
bestMove = i;
t.resetCase(i);
}
}
}
return bestMove;
}
}
The "bestMove" is the best case(from 1 to 9) proposed by minmax, and in my main I am calling it like this:
int movei = playerAI.playMiniMax(t, 'x',3);
correctCase = t.chooseCase(movei, 'x');
public class Tableau {
private char[][] charArray;
private boolean gameIsOver = false;
private char winner = 'n';
Tableau(char[][] _charArray) {
this.charArray = _charArray;
this.moves = new Stack();
this.ceateTable();
}
public void ceateTable() {
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (j != 2 && j != 5) {
System.out.print(this.charArray[i][j] + "|");
} else {
System.out.println(this.charArray[i][j] + "|");
}
}
}
}
public boolean chooseCase(int number, char player) {
int c = 1;
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (c == number && this.charArray[i][j] == '-') {
this.charArray[i][j] = player;
return true;
}
++c;
}
}
return false;
}
public void resetCase(int number) {
int c = 1;
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (c == number) {
this.charArray[i][j] = '-';
}
++c;
}
}
}
public boolean checkWin(char player) {
if ((this.charArray[0][0] != player || this.charArray[0][1] != player || this.charArray[0][2] != player) && (this.charArray[1][0] != player || this.charArray[1][1] != player || this.charArray[1][2] != player) && (this.charArray[2][0] != player || this.charArray[2][1] != player || this.charArray[2][2] != player) && (this.charArray[0][0] != player || this.charArray[1][0] != player || this.charArray[2][0] != player) && (this.charArray[0][1] != player || this.charArray[1][1] != player || this.charArray[2][1] != player) && (this.charArray[0][2] != player || this.charArray[1][2] != player || this.charArray[2][2] != player) && (this.charArray[0][0] != player || this.charArray[1][1] != player || this.charArray[2][2] != player) && (this.charArray[0][2] != player || this.charArray[1][1] != player || this.charArray[2][0] != player)) {
return false;
} else {
System.out.println("Dear " + player + " you won!");
this.gameIsOver = true;
this.winner = player;
return true;
}
}
public boolean isFull() {
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (this.charArray[i][j] == '-') {
return false;
}
}
}
return true;
}
public boolean checkDraw(char player) {
if (!this.checkWin(player) && this.isFull()) {
System.out.println("It's a draw!!!");
this.winner = 'd';
return true;
} else {
return false;
}
}
public boolean checkLoose(char player) {
return player == 'x' ? this.checkWin('o') : false;
}
public boolean isGameIsOver() {
return this.gameIsOver;
}
public void setGameIsOver(boolean gameIsOver) {
this.gameIsOver = gameIsOver;
}
public char getWinner() {
return this.winner;
}
public void setWinner(char winner) {
this.winner = winner;
}
}
The problem relies on the ChooseCase function, because it is just evaluating where the board is empty, so it would choose the first or the last empy space ( depending on minimizing or maximizing). You need to adjust your Evaluation Function to be aware of the board state so it can makes a better choice, taking this exmple:
https://kartikkukreja.wordpress.com/2013/03/30/heuristic-function-for-tic-tac-toe/
In Java should look like this:
private final int possibleWins = 8;
private final int[][] threeInARow = {
{ 0, 1, 2 },
{ 3, 4, 5 },
{ 6, 7, 8 },
{ 0, 3, 6 },
{ 1, 4, 7 },
{ 2, 5, 8 },
{ 0, 4, 8 },
{ 2, 4, 6 }
};
private final int[][] heuristicArray = {
{ 0, -10, -100, -1000 },
{ 10, 0, 0, 0 },
{ 100, 0, 0, 0 },
{ 1000, 0, 0, 0 }
};
public int evaluatePosition(char[] board, char player) {
char opponent = (player == 'X') ? 'O' : 'X', piece;
int players, others, t = 0, i, j;
for (i = 0; i < 8; i++) {
players = others = 0;
for (j = 0; j < 3; j++) {
piece = board[threeInARow[i][j]];
if (piece == player)
players++;
else if (piece == opponent)
others++;
}
t += heuristicArray[players][others];
}
return t;
}
Also check the previous question: How to create an evaluation function for a TIC-TAC-TOE variant game
I have written a program for an assignment where we had to write a simple Gomoku program. I thought I had it all, but when I compile and run, it sets off the win scenario even if I only have 4 of a kind and even if they're not next to each other. (It should only set off a win if there are five in a row of one kind...X's or O's). I feel like I should be resetting my counter back to 0 before each turn, but I'm not sure where I should be doing that. Any tips would be appreciated!
import java.util.Scanner;
public class Gomoku1
{
public static void main (String[] args)
{
Scanner input = new Scanner(System.in);
char[][] map = new char [19][19];
int row = 0;
int column = 0;
//fill game with dots
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map[i].length; j++)
{
map[i][j] = '.';
}
}
printMap(map);
char player1Choice = 'X';
char player2Choice = 'O';
int [] place;
while (true)
{
System.out.println("Player 1's turn!");
place = userTurn(map, player1Choice);
if (isValidMove(map, place[0], place[1]) == false)
{
System.out.println("Invalid move! Try again!");
place = userTurn(map, player1Choice);
}
if (isValidMove(map, place[0], place[1])) {
map[place[0]][place[1]] = player1Choice;
printMap(map);
}
if (isBoardFull(map) == true)
{
System.out.println("Board is full. Tied game.");
break;
}
if (hasPlayerWon(map, player1Choice) == true)
{
System.out.println("Player 1 Wins!");
break;
}
else
{
System.out.println("Player 2's turn!: ");
place = userTurn(map, player2Choice);
//System.out.println(isValidMove(map, row, column));
if (isValidMove(map, place[0], place[1]) == false)
{
System.out.println("Invalid move! Try again!");
place = userTurn(map, player2Choice);
}
if (isValidMove(map, place[0], place[1])) {
map[place[0]][place[1]] = player2Choice;
printMap(map);
}
if (isBoardFull(map) == true)
{
System.out.println("Board is full. Tied game.");
break;
}
if (hasPlayerWon(map, player2Choice) == true)
{
System.out.println("Player 2 Wins!");
break;
}
}
}
}
public static void printMap (char[][] map)
{
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map[i].length; j++)
{
System.out.printf("%2c", map[i][j]);
}
System.out.println();
}
}
public static int [] userTurn (char[][] map, char playerChoice)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter row: ");
int row = input.nextInt();
System.out.print("Enter column: ");
int column = input.nextInt();
int place [] = {row, column};
return place;
}
public static boolean isValidMove (char[][] map, int row, int column)
{
//System.out.println ("n is valid move");
if (row < 0 || row > 18 || column < 0 || column > 18 || map[row][column]=='O' || map[row][column]=='X')
{
return false;
}
else
{
return true;
}
}
public static boolean isBoardFull (char[][] map)
{
int openSpots = 0;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (!(map[i][j]=='.'))
openSpots++;
}
}
if (openSpots == 361)
{
return true;
}
return false;
}
public static boolean hasPlayerWon(char[][] map, int player)
{
if (isHorizontalWin(map, player) == true || isVerticalWin(map, player) == true || isDiagonalWin(map, player) == true)
{
return true;
}
return false;
}
public static boolean isHorizontalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 0;
c += 1;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
public static boolean isVerticalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 1;
c += 0;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
public static boolean isDiagonalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count++;
r += 1;
c += 1;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
}
You have problems in all three of the function that check win conditions: isHorizontalWin, isVerticalWin, and isDiagonalWin. All three increment the variable count, but this variable is never set back to zero. Additionally, the check to see if count == 5 should be made inside the loop. Here is an example on how to fix isHorizontalWin:
public static boolean isHorizontalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 0;
c += 1;
}
if (count == 5)
{
return true;
} else {
count = 0;
}
}
}
}
return false;
}
public class Tree {
protected class Node {
Integer val;
Node[] leaves;
Node(int v, int grad) {
val = v;
leaves = new Node[grad];
}
}
int counter = 1;
int grad;
int height;
protected Node root;
public Tree(int grad, int hoehe) throws IllegalArgumentException {
if (grad < 0)
throw new IllegalArgumentException("Grad < 0");
if (hoehe < 0)
throw new IllegalArgumentException("Hoehe < 0");
if (grad == 0 && hoehe > 1)
throw new IllegalArgumentException("Grad = 0 && Hoehe > 1");
root = new Node(0, grad);
inOrderCreate(root, hoehe, grad);
this.height = hoehe;
this.grad = grad;
}
public void inOrderCreate(Node root, int height, int grad) {
if (root != null && height > 1) {
for (int j = 0; j < root.leaves.length; j++) {
if (root.leaves[j] == null)
root.leaves[j] = new Node(0, grad);
else {
for (int i = 0; i < root.leaves[j].leaves.length; i++) {
root.leaves[j].leaves[i] = new Node(0, grad);
}
}
inOrderCreate(root.leaves[j], height - 1, grad);
}
}
}
public int heightOfTree(Node node) {
if (node == null) {
return 0;
} else {
int max = 0;
for (Node n : node.leaves) {
if (heightOfTree(n) > max)
max = heightOfTree(n);
}
return 1 + max;
}
}
public int maxNode(Node node) {
int nodeCount = 0;
for (int i = 0; i < heightOfTree(node); i++) {
nodeCount += Math.pow(node.leaves.length, i);
}
return nodeCount;
}
public int maxLeaf(Node node) {
return (int) Math.pow(node.leaves.length, heightOfTree(node) - 1);
}
public int maxLeaves() {
return maxLeaf(root);
}
public int maxNodes() {
return maxNode(root);
}
public void printMaxNodesAndLeafs() {
System.out.println("Baum des Grades " + grad + " mit der Hoehe " + height);
System.out.println("---------------------------------");
if (root == null) {
System.out.println("maximale Anzahl von Knoten: 0");
System.out.println("maximale Anzahl von Blaettern: 0\n");
} else {
System.out.println("maximale Anzahl von Knoten: " + maxNodes());
System.out.println("maximale Anzahl von Blaettern: " + maxLeaves() + "\n");
}
}
public void filling(Node n) {
if (n != null) {
n.val = counter;
counter++;
for (int j = 0; j < n.leaves.length; j++) {
filling(n.leaves[j]);
}
}
}
This method will fill the binary tree with natural values.
public void fill() {
counter = 1;
if (root != null) {
root.val = counter;
counter++;
for (int j = 0; j < root.leaves.length; j++) {
filling(root.leaves[j]);
}
}
}
public void inOrderSearch(Node p, int val) {
if (p != null) {
if (heightOfTree(p) == val) {
for (int i = (int) ((Math.pow(grad, heightOfTree(p) - 1)) * grad) - 1; i > 0; i--) {
System.out.print(" ");
}
System.out.print(p.val);
}
for (int j = 0; j < p.leaves.length; j++) {
if (j != 0)
System.out.print(" ");
inOrderSearch(p.leaves[j], val);
}
}
}
This is my print method, which should print all values in order.
public void printTree() {
Node p = root;
if (p != null) {
for (int i = heightOfTree(p); i > 0; i--) {
inOrderSearch(root, i);
System.out.print("\n");
}
}
}
}
But as you can on the following images, the print is not symmetric.
This should be the output of this code:
But my output is this here, 10 and 12 should be symmetric:
Like many other person as I see, I have a problem with my implementation of the Minmax algorithm for the game Connect4. In the example below, the algorithm doesn't try to block the player two and I don't understand why. My evaluation function is really basic: a binary function. Maybe it's because of the depth, but I don't think so.
Code:
public class Moteur {
public static void addPawn(int[][] game, int column, int player) {
int i = 0;
while (i < 6 && game[i][column] == 0) {
i++;
}
game[(i==6)?5:i-1][column] = player;
}
public static void kickPawn(int[][] game, int column) {
int i = 0;
while (i < 6 && game[i][column] == 0) {
i++;
}
game[i][column] = 0;
}
public static void AI_play(int[][] game, int depth) {
int max = -10000;
int tmp = 0;
int maxj = -5;
int j;
for (j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 1);
tmp = Min(game, depth - 1);
if (tmp > max) {
max = tmp;
maxj = j;
}
kickPawn(game, j);
}
}
addPawn(game, maxj, 1);
}
public static int Max(int[][] game, int depth) {
if(depth == 0 || winner(game) != 0) {
return eval(game);
}
int max = -10000;
int j, tmp;
for(j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 2);
tmp = Min(game, depth - 1);
if(tmp > max) {
max = tmp;
}
kickPawn(game, j);
}
}
return max;
}
public static int Min(int[][] game, int depth) {
if(depth == 0 || winner(game) != 0) {
return eval(game);
}
int min = 10000;
int j, tmp;
for(j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 1);
tmp = Max(game, depth - 1);
if(tmp < min) {
min = tmp;
}
kickPawn(game, j);
}
}
return min;
}
public static int eval(int[][] game) {
int gameWinner, nb_pawns = 0;
for (int i = 0; i < game.length; i++) {
for (int j = 0; j < game[0].length; j++) {
if(game[i][j] != 0) {
nb_pawns++;
}
}
}
gameWinner = winner(game);
if(gameWinner == 1) {
return 1000 - nb_pawns;
} else if (gameWinner == 2) {
return -1000 + nb_pawns;
} else {
return 0;
}
}
public static int winner(int[][] game) {
Integ e = new Integ();
for (int j = 0; j < game[0].length; j++) {
if(game[5][j]!= 0 && testWinner(game, j, e)) {
return e.getI();
}
}
return 0;
}
public static boolean testWinner(int[][] game, int lastColumn, Integ e) {
int lastRow = 0;
while (lastRow < 6 && game[lastRow][lastColumn] == 0) {
lastRow++;
}
lastRow = lastRow;
int i = 0;
int j = 0;
int currentPlayer = game[lastRow][lastColumn];
e.setI(currentPlayer);
int sequence = 0;
i = lastRow;
boolean b = i < 3
&& game[i][lastColumn] == currentPlayer
&& game[i+1][lastColumn] == currentPlayer
&& game[i+2][lastColumn] == currentPlayer
&& game[i+3][lastColumn] == currentPlayer;
if(b) {
return true;
}
sequence = 0;
j = lastColumn;
do {
j--;
} while(0 < j && game[lastRow][j] == currentPlayer);
if(j < 0 || game[lastRow][j] != currentPlayer) {
j++;
}
while(j <= 6 && game[lastRow][j] == currentPlayer) {
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i--;
j--;
} while(0 < i && 0 < j && game[i][j] == currentPlayer);
if(i < 0 || j < 0 || game[i][j] != currentPlayer) {
i++;
j++;
}
while(i <= 5 && j <= 6 && game[i][j] == currentPlayer) {
i++;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i++;
j--;
} while(i < 5 && 0 < j && game[i][j] == currentPlayer);
if (5 < i || j < 0 || game[i][j] != currentPlayer) {
i--;
j++;
}
while(0 <= i && j <= 6 && game[i][j] == currentPlayer) {
i--;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
return false;
}
public static void main(String[] args) {
int[][] game = new int[6][7];
int depth = 5;
game[5][3] = 2;
game[4][3] = 2;
game[3][3] = 2;
AI_play(game, depth);
//game[4][0] = 2;
//AI_play(game, depth);
//game[5][2] = 2;
//AI_play(game, depth);
//game[5][3] = 2;
//AI_play(game, depth);
//game[1][0] = 2;
//AI_play(game, depth);
//game[5][4] = 2;
//AI_play(game, depth);
for (int i = 0; i < game.length; i++) {
for (int j = 0; j < game[0].length; j++) {
System.out.print(game[i][j]);
}
System.out.println("");
}
}
private static class Integ {
private int i;
public Integ() {
this.i = 0;
}
public void increment() {
this.i = this.i + 1;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}
}
public Generation newGen() {
Generation newGen = new Generation();
for (int i = 1; i < 26; i++) {
for (int j = 1; j < 76; j++) {
int x = i;
int y = j;
int n = numberOfNeighbors(x, y);
if (gen[i][j] == 'X') {
if (n == 2 || n == 3) {
newGen.gen[i][j] = 'X';
}
if (n != 2 || n != 3) {
newGen.gen[i][j] = '.';
}
}
if (gen[i][j] == '.') {
if (n == 3) {
newGen.gen[i][j] = 'X';
}
if (n != 3) {
newGen.gen[i][j] = '.';
}
}
}
}
return newGen;
}
//I'm taking a char[][] called gen and passing it to the above method, and it is supposed to return a value of type Generation(the class) and then print it to the console in the method below.
public void printToScreenNew() {
Generation newGen = newGen();
System.out.print(newGen.toString());
System.out.println("\n");
}