I'm trying to create a strategy that will play against human or another strategy for the game Gomoku. I already have some kind of minimax function, although i don't quite understand how does it work and i also have a getscore function, which should send back the best score to minimax ? But the problem is that my getScore function does not recognize if there are 4 or 5 circles in a row/col/diagonally.
Here is my code:
public class JarmoStrategyV1 implements ComputerStrategy {
public static int Lrow = 0;
public static int Lcol = 0;
public static int Drow = 0;
public static int Dcol = 0;
public static final int E = 0;
public static final int X = 1; // black
public static final int O = -1; // white
public static final int WINSCORE = 100;
private static final int WINCOUNT = 5;
public Location getMove(SimpleBoard board, int player) {
// let's operate on 2-d array
int[][] b = board.getBoard();
System.out.println(getScore(b, player));
for (int row = 0; row < b.length; row++) {
for (int col = 0; col < b[0].length; col++) {
if (b[row][col] == SimpleBoard.EMPTY) {
// first empty location
return new Location(row, col);
}
}
}
return null;
}
#Override
public String getName() {
return "Student name";
}
public static int minimax(int[][] board, int player, int depth) {
if (getScore(board, player) == WINSCORE) {
//
return WINSCORE;
}
if (depth == 2) {
return getScore(board, player);
}
int max = Integer.MIN_VALUE;
if (player == -1){
max = Integer.MAX_VALUE;
}
System.out.println(max);
List<Location> possibleMoves = getPossibleMoves(board);
for (Location loc : possibleMoves) {
board[loc.getRow()][loc.getColumn()] = player;
int newplayer = 0 - player;
if(newplayer == 1){
int value = minimax(board, newplayer,depth + 1);
if(value < max) {
max = value;
}
}
if (newplayer == -1){
int value = minimax(board, newplayer, depth + 1);
if (value > max) {
max = value;
}
}
board[loc.getRow()][loc.getColumn()] = E;
}
return max;
}
public static int getScore(int[][] board, int muutuja) {
//int yks = 0;
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == muutuja) {
if (row <= (board.length - 5)) {
if (col <= board.length && getCount(board, row, col, 0, 1, muutuja, WINCOUNT) >= (WINCOUNT - 1) && getCount(board, row, (col + 4), 0, 1, E, 1 ) >= 1) return 1; // - 4 in a row
if (row >= 1 && getCount(board, row, col, 1, 0, muutuja, WINCOUNT) >= (WINCOUNT -1) && getCount(board, (row - 1), col, 1, 0, E, 1) == 1) return 1;
if (getCount(board, row, col, 1, 0, muutuja, WINCOUNT) >= WINCOUNT) return 100; // | 5 in a row
if (col <= WINCOUNT && getCount(board, row, col, 1, 1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // \
if (col >= WINCOUNT && getCount(board, row, col, 1, -1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // /
}
if (col <= WINCOUNT && getCount(board, row, col, 0, 1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // -
}
}
}
return 0;
}
public static int getCount(int[][] board, int row, int col, int rowd, int cold, int player, int test) {
int count = 0;
for (int i = 0; i < test; i++) {
if (board[row + i * rowd][col + i * cold] == player) count++;
else break;
}
return count;
}
public static ArrayList<Location> getPossibleMoves(int[][] board) {
ArrayList<Location> availableMoves = new ArrayList<Location>();
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == E) {
availableMoves.add(new Location(row, col));
}
}
}
return availableMoves;
}
}
There seems to be some kind of a problem with getScore, when i run this code then i can only play for a while until my Gomoku app crashes.
If you want to try this out yourself then you can open this via Eclipse.
Download the project file: http://www68.zippyshare.com/v/feWl2QwC/file.html
Import it to eclipse projects/workspace.
And you also have to build path to those 2 jar files in lib folder.
NOTE: I can only edit files in gomoku.strategies package.
the stacktrace shows an exception. add debug print or run with debugger
java.lang.IllegalArgumentException: It's computer's turn, pass the player to makeMove()
at gomoku.Game.makeMove(Game.java:476)
Related
This question already has an answer here:
Customizable TicTacToe game board with Java
(1 answer)
Closed 28 days ago.
Already implemented horizontal and vertical methods, i can't figure out diagonals
That's my working methods:
private boolean checkHorizontalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK HORIZONTAL WIN
for (int row = 0; row < gameSize; row++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, 0);
int counter = 1;
for (int column = 0; column < gameSize; column++) {
char pawn = getPawnAtCoords(gameBoard, gameSize, row, column);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
return false;
}
private boolean checkHVerticalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK VERTICAL WIN
for (int column = 0; column < gameSize; column++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, 0, column);
int counter = 1;
for (int row = 0; row < gameSize; row++) {
char pawn = getPawnAtCoords(gameBoard, gameSize, row, column);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
return false;
}
Anyone got an idea for diagonals?
Already tried everything what i can do by myself.
ChatGPT did it
private boolean checkDiagonalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK DIAGONAL WIN (LEFT TO RIGHT)
for (int row = 0; row < gameSize - gameDifficulty + 1; row++) {
for (int col = 0; col < gameSize - gameDifficulty + 1; col++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, col);
int counter = 1;
for (int i = 1; i < gameDifficulty; i++) {
int nextRow = row + i;
int nextCol = col + i;
char pawn = getPawnAtCoords(gameBoard, gameSize, nextRow, nextCol);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
}
// CHECK DIAGONAL WIN (RIGHT TO LEFT)
for (int row = 0; row < gameSize - gameDifficulty + 1; row++) {
for (int col = gameSize - 1; col >= gameDifficulty - 1; col--) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, col);
int counter = 1;
for (int i = 1; i < gameDifficulty; i++) {
int nextRow = row + i;
int nextCol = col - i;
char pawn = getPawnAtCoords(gameBoard, gameSize, nextRow, nextCol);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
}
return false;
}
I am working on a Percolation java program. I have implemented the following Percolation.java file and am running into an error when testing it with certain input files, as described below.
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private int n;
private WeightedQuickUnionUF verify;
private WeightedQuickUnionUF solution;
private int sink;
private int source = 0;
private boolean[][] grid;
private int openSites = 0;
private int length;
// creates n-by-n grid, with all sites initially blocked
public Percolation(int n) {
if (n <= 0) {
throw new IllegalArgumentException();
}
this.length = n;
this.grid = new boolean[length][length];
this.sink = (length * length) + 1;
verify = new WeightedQuickUnionUF(length * length + 2);
solution = new WeightedQuickUnionUF(length * length + 2);
for (int i = 0; i < length; i++) {
verify.union(encode(0, i), source);
solution.union(encode(0, i), source);
}
for (int j = 0; j < length; j++) {
verify.union(encode(n - 1, j), sink);
}
}
// opens the site (row, col) if it is not open already
public void open(int row, int col) {
grid[row][col] = true;
openSites++;
if ((row - 1) >= 0 && isOpen(row - 1, col)) {
verify.union(encode(row, col), encode(row - 1, col));
solution.union(encode(row, col), encode(row - 1, col));
}
if ((row + 1) < length && isOpen(row + 1, col)) {
verify.union(encode(row, col), encode(row + 1, col));
solution.union(encode(row, col), encode(row + 1, col));
}
if ((col - 1) >= 0 && isOpen(row, col - 1)) {
verify.union(encode(row, col), encode(row, col - 1));
solution.union(encode(row, col), encode(row, col - 1));
}
if ((col + 1) < length && isOpen(row, col + 1)) {
verify.union(encode(row, col), encode(row, col + 1));
solution.union(encode(row, col), encode(row, col + 1));
}
}
// is the site (row, col) open?
public boolean isOpen(int row, int col) {
return grid[row][col];
}
// is the site (row, col) full?
public boolean isFull(int row, int col) {
return solution.find(source) == solution.find(encode(row, col));
}
// returns the number of open sites
public int numberOfOpenSites() {
return openSites;
}
// does the system percolate?
public boolean percolates() {
return verify.find(0) == verify.find(sink);
}
// An integer ID (1...n) for site (i, j).
private int encode(int row, int col) {
int number = length * row + 1 + col;
return number;
}
// unit testing (required)
public static void main(String[] args) {
String filename = args[0];
In in = new In(filename);
int n = in.readInt();
Percolation perc = new Percolation(n);
while (!in.isEmpty()) {
int i = in.readInt();
int j = in.readInt();
perc.open(i, j);
}
StdOut.println(perc.numberOfOpenSites() + " open sites");
if (perc.percolates()) {
StdOut.println("percolates");
}
else {
StdOut.println("does not percolate");
}
// Check if site (i, j) optionally specified on the command line
// is full.
if (args.length == 3) {
int i = Integer.parseInt(args[1]);
int j = Integer.parseInt(args[2]);
StdOut.println(perc.isFull(i, j));
}
}
}
However, when I test the code using certain input files, I receive error messages such as the following:
java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
Percolation.isOpen(Percolation.java:63)
TestPercolation.checkIsOpen(TestPercolation.java:122)
TestPercolation.checkIsOpen(TestPercolation.java:105)
TestPercolation.check(TestPercolation.java:177)
TestPercolation.checkFile(TestPercolation.java:198)
TestPercolation.test1(TestPercolation.java:659)
TestPercolation.main(TestPercolation.java:963)
java.lang.ArrayIndexOutOfBoundsException: Index 25 out of bounds for length 25
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
What in my code could be causing this? In other words, where is the issue and how can I fix it?
I have a question about my homework in scratching my head-on.
So I need to build a program that counts the number of areas of true value (near to each other) in the 2D array.
{0,1,0,0}
{1,0,0,1}
{1,1,0,1}
{1,0,0,1}
So the program needs to return 3 because there 3 places with trues.
If there are no true then to return 0.
The program needs to recursive and without loops.
Thanks in advance to the ones that will help me solve this one. I didn't even have any idea how to start it.
Ok, you do a dfs to record the cells you went and you can have a boolean[][] to record the cells you went. Then you just loop through the grid to see where you have not gone. If you did not go there yet, go there and also perform a dfs on nearby cells, but anyway, a code would be more clear.
public static int[][] grid;
public static boolean[][] went;
public static int r, c;
public static void dfs(int x, int y) {
if (x < 0 || x >= r || y < 0 || y >= c) {//out of the grid
return;
}
if (went[x][y]) {//I went here
return;
}
went[x][y] = true;
if (grid[x][y] == 0) {//It's false here so don't go
return;
}
dfs(x - 1, y);
dfs(x + 1, y);
dfs(x, y - 1);
dfs(x, y + 1);
}
public static void main(String[] args) throws IOException {
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(input.readLine());
//input reading
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
grid = new int[r][c];
went = new boolean[r][c];
for (int i = 0; i < r; i++) {
st = new StringTokenizer(input.readLine());
for (int j = 0; j < c; j++) {
grid[i][j] = Integer.parseInt(st.nextToken());
}
}
//end of input reading
int cnt = 0;//number of areas
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
// If I have not went have and the value
// must be true so I would perform a dfs
// (since I only care about the value of 1s)
if (!went[i][j] && grid[i][j] == 1) {
cnt++;//add to our counter
dfs(i, j);//have not went here
}
}
}
System.out.println(cnt);
}
This solution uses the only recursion. No loops.
public static void main(String... args) {
System.out.println(countTrueAreas(new int[][] {
{ 0, 1, 0, 0 },
{ 1, 0, 0, 1 },
{ 1, 1, 0, 1 },
{ 1, 0, 0, 1 } })); // 3
}
public static int countTrueAreas(int[][] grid) {
return countTrueAreas(grid, 0, 0, 10) - 10;
}
private static int countTrueAreas(int[][] grid, int row, int col, int num) {
if (row == grid.length)
return num;
if (col == grid[row].length) {
if (++row == grid.length)
return num;
col = 0;
}
if (grid[row][col] == 1)
dfs(grid, row, col, num++);
return countTrueAreas(grid, row, col + 1, num);
}
private static void dfs(int[][] grid, int row, int col, int num) {
if (row < 0 || row >= grid.length)
return;
if (col < 0 || col >= grid[row].length)
return;
if (grid[row][col] != 1)
return;
grid[row][col] = num;
dfs(grid, row, col - 1, num);
dfs(grid, row, col + 1, num);
dfs(grid, row - 1, col, num);
dfs(grid, row + 1, col, num);
}
I wrote a program for the percolation problem for the Coursera Algorithms course. Everything seems to compile successfully, but when I run it in terminal, it just freezes and no output is shown. Is my performance just way too slow, or is there a bug somewhere in my code? Code is posted below, the arguments I use are n = 200 and 100 trials. Thank you so much in advance!
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private WeightedQuickUnionUF grid;
private WeightedQuickUnionUF grid2;
private boolean[] openSites;
private int numOpenSites, gridLength, topIndex, bottomIndex;
public Percolation(int n) {
// create n-by-n grid, with all sites blocked
if (n <= 0) {
throw new IllegalArgumentException();
}
int numNodes = (n * n) + 2;
grid = new WeightedQuickUnionUF(numNodes);
grid2 = new WeightedQuickUnionUF(numNodes);
openSites = new boolean[n * n];
numOpenSites = 0;
gridLength = n;
topIndex = n * n;
bottomIndex = n * n + 1;
}
public void open(int row, int col) { // open site (row, col) if it is not open already
//check if row and col are valid
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
//if not open, then open
if (!isOpen(row, col)) {
openSite(row, col);
connectTopVirtualSite(row, col);
connectAdjacentSites(row, col);
connectBottomVirtualSite(row, col);
numOpenSites++;
}
}
private void openSite(int row, int col) {
int index = convertToIndex(row, col);
//set that site to true
openSites[index] = true;
}
private void connectTopVirtualSite(int row, int col) {
if (row == 1) {
grid.union(topIndex, convertToIndex(row, col));
grid2.union(topIndex, convertToIndex(row, col));
}
}
private void connectAdjacentSites(int row, int col) {
connectTop(row, col);
connectLeft(row, col);
connectRight(row, col);
connectBottom(row, col);
}
private void connectTop(int row, int col) {
if (row > 1 && isOpen(row - 1, col)) {
grid.union(convertToIndex(row - 1, col), convertToIndex(row, col));
grid2.union(convertToIndex(row - 1, col), convertToIndex(row, col));
}
}
private void connectLeft(int row, int col) {
if (col > 1 && isOpen(row, col - 1)) {
grid.union(convertToIndex(row, col - 1), convertToIndex(row, col));
grid2.union(convertToIndex(row, col - 1), convertToIndex(row, col));
}
}
private void connectRight(int row, int col) {
if (col < gridLength && isOpen(row, col + 1)) {
grid.union(convertToIndex(row, col), convertToIndex(row, col + 1));
grid2.union(convertToIndex(row, col), convertToIndex(row, col + 1));
}
}
private void connectBottom(int row, int col) {
if (row < gridLength && isOpen(row + 1, col)) {
grid.union(convertToIndex(row, col), convertToIndex(row + 1, col));
grid2.union(convertToIndex(row, col), convertToIndex(row + 1, col));
}
}
private void connectBottomVirtualSite(int row, int col) {
if (row == gridLength) {
grid2.union(convertToIndex(row, col), bottomIndex);
}
}
private int convertToIndex(int row, int col) {
return gridLength * (row - 1) + (col - 1);
}
public boolean isOpen(int row, int col) { // is site (row, col) open?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return openSites[convertToIndex(row, col)];
}
public boolean isFull(int row, int col) { // is site (row, col) full?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return grid.connected(convertToIndex(row, col), topIndex);
}
public int numberOfOpenSites() { // number of open sites
return numOpenSites;
}
public boolean percolates() { // does the system percolate?
return grid2.connected(topIndex, bottomIndex);
}
//public static void main(String[] args) // test client (optional)
}
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
import static java.lang.Math.sqrt;
public class PercolationStats {
private double[] results;
public PercolationStats(int n, int trials) {
if (n <= 0 || trials <= 0) {
throw new IllegalArgumentException();
}
results = new double[trials];
//fill up results with the p values of every trial
runExperiments(n, trials);
}
private void runExperiments(int n, int trials) {
int row, col;
for (int i = 0; i < trials; i++) {
Percolation test = new Percolation(n);
while (!test.percolates()) {
//generate new random row and col
row = StdRandom.uniform(n - 1) + 1;
col = StdRandom.uniform(n - 1) + 1;
test.open(row, col);
}
results[i] = (double)(test.numberOfOpenSites()) / (n * n);
}
}
public double mean() {
//return sample mean of all the p values
return StdStats.mean(results);
}
public double stddev() {
//return sample standard deviation of percolation threshold
return StdStats.stddev(results);
}
public double confidenceLo() {
return mean() - ((1.96 * stddev()) / sqrt(results.length));
}
public double confidenceHi() {
return mean() + ((1.96 * stddev()) / sqrt(results.length));
}
public static void main(String[] args) {
PercolationStats test = new PercolationStats(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
System.out.println("mean = " + test.mean());
System.out.println("stddev = " + test.stddev());
System.out.println("95% confidence interval = [" + test.confidenceLo() + ", " + test.confidenceHi() + "]");
}
}
i'm a bit stuck with the Sudoku algorithm, i coded it using backtrack, and following the theorical steps this should work, and i tried to debuge it, but is too hard (and yes, it solve some numbers and does things)
i paste the code, i hope that you can help me, i really can't see where the problem is...
public void backtracking(int row,int col){
if(row > 8){
System.out.println("Solution Found!!");
printSudoku();
}
if (m[row][col] != 0){
next(row, col);
}
else {
for(int i =1; i < n;i++)
if(row(row, i) && col(col, i)) {
m[row][col] =i;
next(row, col);
}
m[row][col] = 0;
}
}
public void next( int row, int col ) {
if( col < 8)
backtracking( row, col + 1 ) ;
else
backtracking( row+ 1, 0 ) ;
}
public boolean region(int x, int y, int numReg) {
x = (x / 3) * 3 ;
y = (y / 3) * 3 ;
for( int r = 0; r < 3; r++ )
for( int c = 0; c < 3; c++ )
if( m[x+r][y+c] == numReg )
return false ;
return true ;
}
public boolean row(int x, int k){
for(int i =0; i < 9; i++)
if(m[x][i] == k)
return false;
return true;
}
public boolean col(int x, int k){
for(int i =0; i < 9; i++)
if(m[i][x] == k)
return false;
return true;
}
I ommited the "printSudoku" method, is just a double for and you know.
The code seems almost right.
As far as i can see you just forgot to call the region method. And I can't see where the variable n is coming from.
Try it with this slightly modified backtracking method:
public static void backtracking(int row, int col) {
if (row > 8) {
System.out.println("Solution Found!!");
printSudoku();
System.exit(0); //exiting after solution is found
}
if (m[row][col] != 0) {
next(row, col);
} else {
for (int i = 1; i <= 9; i++) //replaced i < n with i<=9
if (row(row, i) && col(col, i) && region(row, col, i)) { //calling region method too
m[row][col] = i;
next(row, col);
}
m[row][col] = 0;
}
}