While loop gets terminated before condition is met when backtracking - java

I'm trying to write an iterative program that will help me palce 4 queens on a 4x4 board without them hitting each other. The problem is after looping through each position and backtracking a couple of times my main while loop that keeps looping until a solution is found gets terminated and the program ends even though the condition is not yet met.
I tried the following code:
static int[] solve(char[][] board){
int[] position = new int[4];
int row = 0;
int column = 0;
while(row < 4){
for(boolean check; column < board.length; column++){
System.out.println("["+row+","+column+"]");
check = true;
for(int queen= 0; queen < row; queen++){
if (position[queen] == column || queen- position[queen] == row - column || queen + position[queen] == row + column) {
check = false;
break;
}
}
if(check){
position[row] = column;
column = 0;
row++;
}
if(column > 2){
column = position[--row];
}
}
}
return position;
}
I'm currently getting the following output:
| Q | X | X | X |
| X | X | X | Q |
| X | Q | X | X |
| Q | X | X | X |
To check when exactly the while loop is getting terminated I printed the location (row and column)
System.out.println("["+row+","+column+"]"); and got the following:
[0,0][1,0][1,1][1,2][2,0][2,1][2,2][2,3][1,3][2,0][2,1][3,0][3,1][3,2][3,3][2,2][2,3]
After backtracking to [2,3] the while loop ends even though my row count is still less than 4.
I was expecting the following output:
| X | Q | X | X |
| X | X | X | Q |
| Q | X | X | X |
| X | X | Q | X |
I tried the code in a different compiler and still got the same wrong output. Is there a logical mistake that I missed out?
I'm new to programming so I'm still trying to get the hang of the fundamentals.

Related

simplest MiniMax algorithm for TicTacToe AI in Java

I was trying to get a grasp of MiniMax algorithm, and have read up on it. My initial approach was to implement a simple MiniMax algorithm, and then to add alpha-beta pruning. However this is my current code:
public int miniMax(char[] node, int playerNum)
{
int victor = checkWin(node); // returns 0 if game is ongoing, 1 for p1, 2 for p2, 3 for tie.
if(victor != 0) //game over .
return score(victor);
if(playerNum == 2) //AI
{
int bestVal = Integer.MIN_VALUE;
int bestSpot = 0;
for(int i = 0; i < node.length; i++)
{
if(node[i] != '-')
continue;
node[i] = getSymbol(playerNum);
int value = miniMax(node, 1);
if(value > bestVal)
{
bestVal = value;
bestSpot = i;
}
node[i] = '-';
}
return bestSpot;
}
else
{
int bestVal = Integer.MAX_VALUE;
int bestSpot = 0;
for(int i = 0; i < node.length; i++)
{
if(node[i] != '-')
continue;
node[i] = getSymbol(playerNum);
int value = miniMax(node, 2);
if(value < bestVal)
{
bestVal = value;
bestSpot = i;
}
node[i] = '-';
}
return bestSpot;
}
}
And my score function
private int Score(int gameState)
{
if(gameState ==2) //O wins.
return 10;
else if(gameState==1) //X wins
return -10;
return 0;
}
Now, I have a working AI that tries to block my move and win, however sometimes it is making non-intelligent choices for instance this is the output I get if my input read from console is 6,7,8 in that order. It does not attempt to block my win. But in other cases it does.
| O | O | |
| | | |
| X | X | X |
In my second attempt I tried 4,3 and it blocked my winning move.
| | O | |
| X | X | O |
| | | |
I was wondering anyone could point out what is wrong with my implementation?
The behavior of the code for the shown examples is correct!
So why is the threat in the following position not blocked? Why does the program play move 1 instead of 6?
O . . O 1 2
. . . numbering available moves: 3 4 5
X X . X X 6
It is because if the game is lost on perfect play the program just plays the first available move.
The algorithm only cares about win or loss and not in how many moves.
See what happens if the threat is blocked:
O . . O . .
. . . . X . and X wins on his next move
X X O X X O

array combine inputs more then 2

I'm working on an implementation of the "Merge Numbers" game, seen here on the Play store: https://play.google.com/store/apps/details?id=com.ft.game.puzzle.cubelevels
The idea is that if I have a 2D array of cells, some of which are empty and others of which have numbers, and I place a given number into an empty cell, then if that number matches at least 3 of its neighbors, the neighbors are made empty and the cell value is incremented. A simple example:
| 1 | 2 | 3 | 4 |
| 3 | | 2 | |
| 1 | 2 | 3 | |
| | 2 | 1 | 4 |
If the next number (generated randomly by the game) is 2, and I place it into cell (1, 1) (where (0, 0) is the upper left cell), the new game board should look like this:
| 1 | | 3 | 4 |
| 3 | 3 | | |
| 1 | | 3 | |
| | 2 | 1 | 4 |
The newly-placed 2 is incremented to 3, and the neighboring cells with value of 2 have been cleared.
I'm having trouble figuring out how to do this. Here is my code so far:
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[][] w = {{1, 2, 3, 4}, {3, 0, 4, 0}, {1, 2, 3, 0}, {0, 2, 1, 4}};
Scanner input = new Scanner(System.in);
System.out.println("Enter space for putting 1: ");
int a = input.nextInt();
int b = input.nextInt();
if (a == 1 && b == 1) {
w[1][1] = 1;
for (a = 0; a < w.length; a++) {
for (b = 0; b < w[0].length; b++) {
System.out.print(w[a][b] + " ");
}
System.out.print('\n');
}
System.out.println("Enter space for putting 4: ");
a = input.nextInt();
b = input.nextInt();
if (a == 1 && b == 3) {
w[1][3] = 4;
for (a = 0; a < w.length; a++) {
for (b = 0; b < w[0].length; b++) {
System.out.print(w[a][b] + " ");
}
System.out.print('\n');
}
}
}
}
}
How can I check to see if the neighbors of the newly-added number have the same value?
How can I increment the newly-added number?

populating and printing a 2D array given text file containing characters

im trying to print out a text file into a grid-like format after pulling them from a text file. Similar to this method, creating a 2 level for looping going through each row and column. However im not sure the process how it differs when dealing with characters rather than numbers.
example of text file im trying to replicate, excluding the first numbers
8 10
+-+-+-+-+-+-+-+-+-+
| |
+ +-+-+-+ +-+-+-+ +
| | | |
+ + +-+-+-+-+-+ + +
| | | | | |
+ + + +-+-+-+ + + +-+
| | | | | | | S|
+ + + + +-+ + + + +-+
| | | |E| | | |
+ + + +-+ +-+ + + +
| | | | | |
+ + +-+-+-+-+-+ + +
| | | |
+ +-+-+-+-+-+-+-+ +
| |
+-+-+-+-+-+-+-+-+-+
static void readMazeFile(String mazefile) throws FileNotFoundException {
Scanner mazeIn = new Scanner (new File (mazefile));
int height = mazeIn.nextInt();
int width = mazeIn.nextInt();
System.out.print(width);
System.out.print(height);
// get array height & width
int arrayHeight = (height*2)+1;
int arrayWidth = (width*2)+1;
System.out.print(arrayHeight);
System.out.print(arrayWidth);
// create new array set variables
char mazeAsArray[][] = new char[arrayHeight][arrayWidth];
int charCount = 0;
//populate and print array
System.out.print("-------------\n");
for (int r = 0; r < 9; r++){
for (int c = 0; c < 9; c++){
System.out.print(mazeAsArray[r][c]);
}
}
}
thank you
How do i get characters in a file into a 2D array in Java?
Most of the problems are answered in that link. First of all you are not assigning anything into the array. I'll copy my answer from that link here.
for (int row = 0; row < arrayheight; row++)
{
if(!mazein.hasNextLine())
break; // if there is no more lines to read, break the loop
String line = mazein.nextLine();
Char[] chars = line.toCharArray();
for (int col = 0, i = 0; (col < arraywidth && i < chars.length); col++,i++)
{
mazeAsArray[row][col] = chars[i];
System.out.print(mazeAsArray[row][col]);
}
}
Update:
I see your file don't have a regular number of characters in each line. You'll have to count the number of lines for the height and the number of characters in the longest line for the width or you could just input them yourself.

Complexity in tilde notation of nested for loops

How do I find the complexity in tilde notation of the following algorithm:
for (int j = 0; j < N; j++) {
for (int k = j + 1; k < N; k++) {
array[k] = array[j];
}
array[j] = k
}
I've made a table with how many times the inner for-loop loops if N = 9:
| j | # of loops |
|:-----------|------------:|
| 0 | 8 |
| 1 | 7 |
| 2 | 6 |
| 3 | 5 |
| 4 | 4 |
| 5 | 3 |
| 6 | 2 |
| 7 | 1 |
| 8 | 0 |
As you evaluate, the number of inner iterations decreases linearly from 8 down to 0, i.e. it is 4 on average, for a total of 4.9=36.
More generally, the average is (N-1)/2 and the total N.(N-1)/2.
Consequently, I(N) ~ N²/2, in terms of the iteration count.
In terms of memory accesses (R+W), it's the double: A(N) ~ N². (The extra access in the outer loop adds a negligible N contribution.)

Using a 2D arraylist to create a chessboard and pieces

I'm currently trying to create a program that will spit out a chessboard like this one (it looks better in the actual program, just to editor doesn't like me using the "-" symbol so I put them in quotation marks):
-----------------
| | | | |K| | | |
-----------------
| |P| | | |P| | |
-----------------
| | | | | | | | |
-----------------
| | | | | | | | |
-----------------
| | | | | | | | |
-----------------
| | | | | | | | |
-----------------
| | | | | |N| | |
-----------------
| | | | |K| | | |
-----------------
I'm using two methods, a showBoard method and an addPiece method. I'm currently stuck with the addPiece method, and I'm trying to make it so the method takes three inputs: the row int, the column int, and the string name (just K for king, for example). However, I can't get the addPiece method to put the pieces where I want them to go, or even at all. Here's what I have so far:
public class ChessBoard {
public static String[][] board = new String[8][8];
public static int row = 0;
public static int col = 0;
public static void addPiece(int x, int y, String r){
board[x][y] = new String(r);
}
public static void showBoard(){
for (row = 0; row < board.length; row++)
{
System.out.println("");
System.out.println("---------------");
for(col = 0; col < board[row].length; col++)
{
System.out.print("| ");
}
}
System.out.println("");
System.out.println("---------------");
}
public static void main(String[] args) {
System.out.println(board.length);
showBoard();
addPiece(1,2,"R");
}
}
I know it has something to do with the way I wrote my addpiece method, but I'm still kind of confused as to how writing the method should be, and that is my best attempt (which doesn't work). Does anyone have any suggestions? Thanks!
You never print the pieces values
for(col = 0; col < board[row].length; col++)
{
if ( board[row][col] != null ) {
System.out.print("|" + board[row][col]);
}
else
System.out.print("| ");
}
And also you'll need to add the pience before you show the board:
addPiece(1,2,"R"); //before
showBoard();
Why are you using new String(r)? Your board array is already an array of Strings, just use:
board[x][y] = r;
Also you are adding the piece after the showBoard method in main, switch them around
addPiece(1,2,"R");
showBoard();
Note that addPiece is changing the state of the board. If you want to see that change, you need to redisplay the new board state.
public class ChessBoard {
public static String[][] board = new String[8][8];
public static void addPiece(int x, int y, String r){
board[x][y] = r;//no need for new String(), board is already made of Strings.
}
public static void showBoard(){
//it's generally better practice to initialize loop counters in the loop themselves
for (int row = 0; row < board.length; row++)
{
System.out.println("");
System.out.println("---------------");
for(int col = 0; col < board[row].length; col++)
{
System.out.print("|"); //you're only printing spaces in the spots
if(board[column][row] == null){
System.ot.print(" ");
}else{
System.out.print(board[column][row]);
}
}
}
System.out.println("");
System.out.println("---------------");
}
public static void main(String[] args) {
System.out.println(board.length);
showBoard(); //board does not have R in it yet.
addPiece(1,2,"R"); //board now has R in it.
showBoard(); //display the new board with R in it.
}
}

Categories

Resources