Checking grid for word search game - java

i made this boggle-type game, and so far it works very well. This method here is for searching the 10x10 grid to see if the word the user entered is correct. The problem i have is that this code only works for words that appear left to right, and top to bottom. Now i don't expect to do diagonal, but i would like to make it to where the words that appear in reverse order are also accepted by the system. I've been told that the word that you enter would have to be flipped (reversed) in order to see if it matches properly (which makes sense. After all, you're looking for a word that is backwords). So exactly how would i achieve this? Now, i'm not very good with coding, so please, if you have time then write down what code i would have to use. Thank you.
public static boolean wordSearch (char[][] table, String search)
{
int ctr = search.length();
String temp = "";
// LEFT TO RIGHT / X-AXIS
for (int row = 0; row < 10; row++) //Checks each row (x) one by one
{
for (int a = 0; a <= (10 - ctr); a++)
{
StringBuilder s = new StringBuilder(10-ctr);//Does... something
for (int x = a; x <= (a+ctr-1); x++) //Checks every possibility in the row
{
s.append(table[row][x]);
temp = s.toString();
if (temp.equals(search))
{
return true;
}
}
}
}
// TOP TO BOTTOM / Y-AXIS
for (int column = 0; column < 10; column++)
{
for (int b = 0; b <= (10 - ctr); b++)
{
StringBuilder v = new StringBuilder(10-ctr);
for (int y = b; y <= (b+ctr-1); y++)//checks every possibility in grid
{
v.append(table[y][column]);
temp = v.toString();
if (temp.equals(search))
{
return true;
}
}
}
}
return false;//if word isn't in grid it returns as false, which then displays an error message
}

EDIT ... the Java version!!! (I have no Java compiler handy right now but I think this is right...)
At the second line of your code, we compute the reverse string;
there are thousands of ways to do this, but this one is pretty self-explanatory (I am assuming there is no white space in your string...):
int ls = search.length(); // length of initial string
StringBuilder sb = new StringBuilder(); // temporary place to store growing string
for(int ii=ls-1;ii>=0; ii--) {
sb.append(search.charAt(ii)); // build the string one character at a time
}
hcraes = sb.toString(); // convert to "regular" string
Now, at every point where you have the line
if (temp.equals(search))
change that line to
if (temp.equals(search) || temp.equals(hcraes))
that should do the trick.

Related

How can I set a grid with the value of my 2D array?(Java, Android Studio)

I have a school project, I have to build a Tetris Game.
So I began with the creation of my menu with the different level, when I click on one level i go to my second activity (the game area) and I have also created my custom block.
My problem is a visual issue, indeed I don't know what type of layout I have to use for my surface game (gridlayout, linearlayout, grid etc. ...).
And then how to affect my blocks custom in this surface game, in this layout?
See the result expected.
enter image description here
I'm not sure I understand what you want entirely but ill give it a shot from what i think you mean.
You should use a nested for loop to do it, if your array was int[10,20](not right syntax but i cant be bothered to count the actual size of your array).
you should go:
(pseudocode)
also assume your resolution is 100, 200
For(int i = 1 To 10){
For(int k = 1 To 20){
DrawSquare(i*10, k*10, "block type")
k = k + 1
}
i = i + 1
}
Then it will fill your 100, 200 area with the block type specified. Now if you want to load what block type you want freom the array you can just call the array in the block type.
DrawSquare(i*10, k*10, Array[i,k])
Obviously bear in mind that its all pseudocode to display the logic.
Hope this helps
Building on Valhalla's answer with a Java-specific example, it's still a bit unclear what you're asking, but assuming you want to initialise the grid to begin with you can use this code:
private final int columns = 10;
private final int rows = columns * 2;
private int[][] grid;
private void initialise() {
grid = new int[columns][rows];
for (int i = 0; i < columns; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j] = 0;
}
}
}
And assuming that you have a block that starts at the top, and falls one square with each iteration provided there's nothing underneath, you can try this:
private void blockFall() {
// Start from 1 row above the bottom and parse upwards
// so a block won't drop right to the bottom on a single iteration
for (int i = 0; i < columns; i++) {
for(int j = rows - 2; j >= 0; j--) {
if (grid[i][j] > 0 && grid[i][j+1] == 0) {
grid[i][j+1] = grid[i][j];
grid[i][j] = 0;
}
}
}
}

Processing range of lines in a 2d array or file

I'm very new to programming. I'm studying on my own, and the examples from the book I'm using are too easy so I'm trying to do something harder. Lotteries are one of my hobbies and I think the problem I chose will make it easier for me to learn Java.
This program calculates frequencies (how many times each number from 1 t0 70 appears in my txt file) in Keno, a type of lottery(In Keno, a draw consists of 20 numbers out of 70, instead of the widespread 6 out of 49).
I want to calculate the frequencies not for the entire txt file, but just for a section of it, for example if the file has x lines, I want just the lines between x-5 and x-10, something like this.I don't know the number of lines in my file, perhaps thousands, but it always has 20 columns.
The program works fine for the entire file, but I run into trouble when trying to work just on a section of it. I think that I should read the file into a 2d array and then I could process the lines I want. I'm having hard times transferring every line into a matrix. I've read every post regarding reading a file into a 2d array but couldn't make it work.
Below is one of the many attempts I made over more than a week
public static void main(String args[]) {
int[][] matricea = new int [30][40];
int x=0, y=0;
try {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
int k=0; // k counts the lines
String draw;
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
System.out.println(" nr. of lines is " + k);
reader.close();
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
} catch (Exception e) {
System.out.println("There was a problem opening and processing the file.");
}
}
Formatting and improving current code
I'll show how to solve your problem, but first I would like to point out a few things in your code that could be improved by some formatting, or that perhaps are unnecessary.
Just to help you improve your coding skills, readability is very important! :)
And don't forget, consistency is key! If you like one style better than the more common style, or the preferred style, that's fine as long as you use it throughout your coding. Don't switch between two styles.
If you don't care to read these comments, you can find the solution at the bottom of my answer. Just note that your original code will be different in my solution because I have formatted it to be most readable for me.
Spacing in variable declarations
Original code
int[][] matricea = new int [30][40];
int x=0, y=0;
Spacing modified
int[][] matricea = new int[30][40];
int x = 0, y = 0;
Notice the space removed between int and [30][40], and the space added between the variables and the initialization, i.e. - x=0 => x = 0.
Initializing an int array to contain all 0's
Original code
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
Same as
int[] numbers = new int[72]; //each keno draw has 70 numbers
You don't have to set each value to 0, Java will do that for you. In fact, Java has default values, or null values, for all types. Thanks to Debosmit Ray!
I won't go into the exceptions to this case, or when or why or how, you can read about that in this post, and pay close attention to Aniket Thakur's answer.
But why do you have an array of size 72, if there are only 70 possibilities?
Choosing variable names
Original code
int k=0; // k counts the lines
Same as
int numLines = 0;
You should always make your variables names something meaningful to their purpose. If you ever have to put a comment like k counts the lines to describe a variable's purpose, consider if a better name would work instead.
Functionalizing code
Original code
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
Same as
while ( (draw = reader.readLine()) != null ) {
processLine(draw);
}
Of course, you'll have to make the method processLine(String line), but that won't be hard. It's just taking what you have and moving it to a separate method.
The original code's while loop is very busy and messy, but with the latter option makes the purpose clear, and the code clean.
Of course each situation is different, and you might find that only removing part of the code into a method would be a better solution. Just play around and see what makes sense.
Error!
Original code
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
This code should not work, since pieces is declared in the while loop above it, and is local to that above loop. This for loop is outside the scope of where pieces exists.
I'll tell you how to fix it, but I'm not sure what the code is supposed to be doing. Just let me know what its purpose is, and I'll provide you with a solution.
After formatting!
This is what the code may look like after applying my above comments. I have added comments to parts that I have changed.
public static void main(String args[]) {
try {
doKenoStuff();
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff() throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[30][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
// We can clean up our loop condition by removing
// the assignment (draw = reader.readLine) from it.
// Just make sure draw doesn't begin as null.
String draw = "";
int row;
for(row = 0; draw != null; row++) {
draw = reader.readLine();
// We read a line from the file, then send it
// to extractLineData which will collect the info
// from each column, and update matricea and numbers
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
}
}
Solution
Note: I am not perfect, and my code is not either. I'm not trying to say that what I have suggested is in any way the only way to do this. It could definitely be improved, but it is a start. You should take my solution and see how you can improve it yourself.
What can you find that you could code in a cleaner, or faster, or better way?
So, how do we fix the problem?
We have a method that reads from the start of a file, to the end of it, and it logs the data it finds inside matricea.
A quick and easy solution is to simply make that method take in two parameters, a starting line number, and an ending line number.
public static void doKenoStuff(int start, int end) throws IOException {
Then we simply make a loop to skip over the starting lines! It's that easy!!!
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
Don't forget that we may not need the big 30 row matricea to be 30 rows anymore. We can shrink that down to end - start + 1. That way, if a user wants to read from line 45 to line 45, we only need 45 - 45 + 1 = 1 row in matricea.
int[][] matricea = new int[end - start + 1][40];
And the very last thing we need to add is a condition in our line reading loop, that prevents us from going past the ending line.
for(row = 0; draw != null, row <= end; row++) {
And there you have it. Simple as that!
Complete solution
public static void main(String args[]) {
int start = 7, end = 18;
try {
doKenoStuff(start, end);
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff(int start, int end) throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[end - start + 1][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
String draw = "";
int row;
for(row = 0; draw != null, row <= end; row++) {
draw = reader.readLine();
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
try {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
} catch (NumberFormatException) {
// You don't have to do anything in this block, but
// you can print out what input gave the exception if you want.
System.out.println("Bad input: \"" + linePieces[column] + "\"");
}
}
}

How to loop through an array and get how many zeros there are

I have a 2D array and it's like a maze.
So I loop through the first row to see if there is a zero (This zero is the opening) and then I go down to see if there is another zero below that zero.
The problem is that after the first 2 rows I don't know how I can write code to check left,right or down of that zero and move there and continue until I cannot do so any longer.
import java.util.Scanner;
public class AssignmentTwo
{
//int[rows][columns]
int[][] gasCavern = {{1,1,1,1,1,0,1},
{1,0,0,1,1,0,1},
{1,1,1,0,0,0,1},
{1,1,0,0,1,1,1},
{1,0,1,0,1,0,1},
{1,0,1,0,0,0,1},
{0,0,0,1,1,1,0},
{1,1,1,0,0,0,1}};
int counter = 0;
boolean checked = false;
// forLoop that deals with the first 2 rows.
// First check 1st row for a zero.
// Then check down and increment counter which ultimately shows area.
for(int column = 0; column < gasCavern[0].length; column++)
{
//Checking for opening in 1st row
if(gasCavern[0][column]== 0)
{
counter++;
gasCavern[0][column] = 2;
if(gasCavern[1][column]==0)
{
counter++;
}
}
}
for(int i=1; i<gasCavern.length; i++)
{
for(int j=0; j < gasCavern.length; j++)
{
if(gasCavern[i][j])
{
//Looking left
if(gasCavern[i][j-1]==2)
{
gasCavern[i][j-1]=2;
counter++;
}
//Looking Right
if(gasCavern[i][j+1]==2)
{
gasCavern[i][j+1]=2;
counter++;
}
//Looking up
if(gasCavern[i+1][j]==2)
{
gasCavern[i+1][j]=2;
counter++;
}
//Looking down
if(gasCavern[i-1][j]==2)
{
gasCavern[i-1][j]==2
counter++;
}
}
}
}
public boolean checkedForZeros()
{
//If returning false,go through while loop again
}
}
This is the code I have so far. In case I wasn't clear this is what I want to happen:
http://imgur.com/YOr86xs
I think with a bit more thought you would have got it!
Think about it, all you have to do is check the adjacent elements in the row you are looking at, which are just the columns in each side. Therefore:
[column+1]
Would check the element to the right, and:
[column-1]
Would check the element to the left.
Just be sure you don't accidentally go out of bounds.
EDIT: Let us know how you get on, if you are still struggling, I will provide more code, but try first.
This should work:
for (int x = 0; x < gasCavern.length; x++) {
for (int y = 0; y < gasCavern[x].length; y++) {
int num = gasCavern[x][y];
if (num == 0) {
// if it is a zero
} else {
// if it's not a zero (a one)
}
}
}

Comparing integers of rows and columns of a 2d array. Sudoku

Hey I'm having trouble getting my code to compare the integers of a given row or column and block to make sure there are no duplicates within those parameters. I don't know if it would be a good idea separating the three contraints in 3 different methods or just trying to attempt to do all at once.
public static rowCheck(int[][] nsudokuBoard) {
for (int i =0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// (nsudokuBoard)
}
}
}
this is my code im starting. before you guys bash on me for not even being able to compile this im stuck on how to compare all the values of a row of the 2d array.
You can compare all the values of the 2d array as shown in the code below:
void validate(final int[][] nsudokuBoard) {
final int width = nsudokuBoard[0].length;
final int depth = nsudokuBoard.length;
for (int i = 0; i < width; i++) {
int j = i;
int reference = nsudokuBoard[i][j];
do {
if (j < width) {
int current = nsudokuBoard[i][j];
if (current == reference) {
// invalid entry found do something
}
}
if (j < depth) {
// note reversed indexes
int current = nsudokuBoard[j][i];
if (current == reference) {
// invalid entry found do something
}
}
++j;
} while ((j >= width) || (j >= depth));
}
}
I haven't tried to compile this code, but it should give you an idea of how to accomplish your task. I would suggest that rather than passing in int[][] sudokuBoard that you should define a class which encapsulates the concept of a SudokuSquare and pass in SudokuSquare[][] , that way your validate method can return a List<SudokuSquare> containing all the offending entries.
I'll show how you might do it for one row, and then you can figure out the rest. I'm assuming your values are 1 through 9 inclusive, and that you don't have any zeroes or any "unfilled entries."
boolean isRowValid(int[][] grid, int row) {
boolean[] seen = new boolean[9];
int row; // chosen somewhere else
for (int col = 0; col < 9; col++) {
if (seen[grid[row][col] - 1]) { // if we've seen this value before in this row
return false; // there is a duplicate, and this is a bad sudoku
}
seen[grid[row][col] - 1] = true; // mark us as having seen this element
}
return true; // we're all good
}
return true; // this row is fine
make a class Cell with fields row,col,block,value; then make a class Matrix with field cells = cell[], fill matrix.
make a class checker with main method Matrix matrix = init(int[][]) and check(matrix), where init(·) fills the matrix.
boolean ok = check(matrix) where check(Matrix) does if(!rowcheck())return false; if(!colcheck()) return false etc;
create some methods like getrows(), getrow(r) and for(Cell cell: matrix.values()) to filter out the ones you want.
a bit tedious but i have done it and it is solid as rock.
As a note, filtering over matrix may seem stupid but computers are fast and the problem is O(1) since it is 9x9.

Java function needed for finding the longest duplicated substring in a string?

Need java function to find the longest duplicate substring in a string
For instance, if the input is “banana”,output should be "ana" and we have count the number of times it has appeared in this case it is 2.
The solution is as below
public class Test{
public static void main(String[] args){
System.out.println(findLongestSubstring("i like ike"));
System.out.println(findLongestSubstring("madam i'm adam"));
System.out.println(findLongestSubstring("When life hands you lemonade, make lemons"));
System.out.println(findLongestSubstring("banana"));
}
public static String findLongestSubstring(String value) {
String[] strings = new String[value.length()];
String longestSub = "";
//strip off a character, add new string to array
for(int i = 0; i < value.length(); i++){
strings[i] = new String(value.substring(i));
}
//debug/visualization
//before sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Arrays.sort(strings);
System.out.println();
//debug/visualization
//after sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Vector<String> possibles = new Vector<String>();
String temp = "";
int curLength = 0, longestSoFar = 0;
/*
* now that the array is sorted compare the letters
* of the current index to those above, continue until
* you no longer have a match, check length and add
* it to the vector of possibilities
*/
for(int i = 1; i < strings.length; i++){
for(int j = 0; j < strings[i-1].length(); j++){
if (strings[i-1].charAt(j) != strings[i].charAt(j)){
break;
}
else{
temp += strings[i-1].charAt(j);
curLength++;
}
}
//this could alleviate the need for a vector
//since only the first and subsequent longest
//would be added; vector kept for simplicity
if (curLength >= longestSoFar){
longestSoFar = curLength;
possibles.add(temp);
}
temp = "";
curLength = 0;
}
System.out.println("Longest string length from possibles: " + longestSoFar);
//iterate through the vector to find the longest one
int max = 0;
for(int i = 0; i < possibles.size();i++){
//debug/visualization
System.out.println(possibles.elementAt(i));
if (possibles.elementAt(i).length() > max){
max = possibles.elementAt(i).length();
longestSub = possibles.elementAt(i);
}
}
System.out.println();
//concerned with whitespace up until this point
// "lemon" not " lemon" for example
return longestSub.trim();
}
}
This is a common CS problem with a dynamic programming solution.
Edit (for lijie):
You are technically correct -- this is not the exact same problem. However this does not make the link above irrelevant and the same approach (w.r.t. dynamic programming in particular) can be used if both strings provided are the same -- only one modification needs to be made: don't consider the case along the diagonal. Or, as others have pointed out (e.g. LaGrandMere), use a suffix tree (also found in the above link).
Edit (for Deepak):
A Java implementation of the Longest Common Substring (using dynamic programming) can be found here. Note that you will need to modify it to ignore "the diagonal" (look at the Wikipedia diagram) or the longest common string will be itself!
In Java : Suffix Tree.
Thanks to the ones that have found how to solve it, I didn't know.

Categories

Resources