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.
Related
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.
I've been scratching my head over this for awhile now. I'm quite new to programming, so my code may not be that efficient, but it's killing me that I can't figure out what's going wrong.
The goal is to compare 'uScore' (the score of the game just played, where lower is better) to the sorted list of highscores stored in the array of objects 'records', using records[i].getName() to retrieve the score at that position. I then mark the position where 'uScore' is to be inserted using 'insertScoreHere', then shift everything below it in the array down by one place. I then set the value of the score at 'insertScoreHere' to uScore, and the name to 'uName' (player name from game just played).
public void sortWinners() {
for (int i = 0; i < 10; i++) {
if (uScore < records[i].getScore()) {
insertScoreHere = i;
i = 10; //this is terrible i know
}
}
for (int i = 9; i > insertScoreHere; i--) {
records[i] = records[i-1];
}
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
}
Now if the player name from the most recent game is 'sam', and his score is '8', and the array is empty to start with, this is what is happening (below is the array 'records'):
NAME: sam, SCORE: 8
NAME: sam, SCORE: 8
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
I've logged everything as much as I can, adding this to my code:
public void sortWinners() {
for (int i = 0; i < 10; i++) {
if (uScore < records[i].getScore()) {
insertScoreHere = i;
i = 10;
}
}
Log.v("ARRAY", "PLACE TO INSERT SCORE: " + insertScoreHere);
for (int i = 9; i > insertScoreHere; i--) {
Log.v("ARRAY", "BEFORE ITERATION I = " + i + ": " +
" | " + records[0].getScore() +
" | " + records[1].getScore() +
" | " + records[2].getScore() +
" | " + records[3].getScore() +
" | " + records[4].getScore() +
" | " + records[5].getScore() +
" | " + records[6].getScore() +
" | " + records[7].getScore() +
" | " + records[8].getScore() +
" | " + records[9].getScore());
records[i] = records[i-1];
Log.v("ARRAY", " AFTER ITERATION I = " + i + ": " +
" | " + records[0].getScore() +
" | " + records[1].getScore() +
" | " + records[2].getScore() +
" | " + records[3].getScore() +
" | " + records[4].getScore() +
" | " + records[5].getScore() +
" | " + records[6].getScore() +
" | " + records[7].getScore() +
" | " + records[8].getScore() +
" | " + records[9].getScore());
}
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
Log.v("ARRAY", "AFTER SORTING");
for (int i = 0; i < 10; i++) {
Log.v("ARRAY", "NAME: " + records[i].getName() + ", SCORE: " + records[i].getScore());
}
}
Here's an example of the result of the logging. Say we have a populated array (where duplicates have already occurred), e.g:
NAME: milfred, SCORE: 1
NAME: milfred, SCORE: 1
NAME: timmy, SCORE: 3
NAME: john, SCORE: 5
NAME: sam, SCORE: 7
NAME: dhshs, SCORE: 8
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
Now let's say the next game that is played has a score of '6' and a player name 'stringray'. This is what my logging returns:
PLACE TO INSERT SCORE: 4
BEFORE ITERATION I = 9: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
AFTER ITERATION I = 9: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
BEFORE ITERATION I = 8: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
AFTER ITERATION I = 8: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
BEFORE ITERATION I = 7: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
AFTER ITERATION I = 7: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
BEFORE ITERATION I = 6: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0
AFTER ITERATION I = 6: | 1 | 1 | 3 | 5 | 7 | 8 | 8 | 0 | 0 | 0
BEFORE ITERATION I = 5: | 1 | 1 | 3 | 5 | 7 | 8 | 8 | 0 | 0 | 0
AFTER ITERATION I = 5: | 1 | 1 | 3 | 5 | 7 | 7 | 8 | 0 | 0 | 0
AFTER SORTING
NAME: milfred, SCORE: 1
NAME: milfred, SCORE: 1
NAME: timmy, SCORE: 3
NAME: john, SCORE: 5
NAME: stingray, SCORE: 6
NAME: stingray, SCORE: 6
NAME: dhshs, SCORE: 8
NAME: , SCORE: 0
NAME: , SCORE: 0
NAME: , SCORE: 0
And lastly, here at my data types:
String uName;
int uScore;
playerRecord records[] = new playerRecord[10];
playerRecord:
public class playerRecord {
private String name;
private int score;
public playerRecord(String input_name, int input_score) {
name = input_name;
score = input_score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public void setName(String set_name) {
name = set_name;
}
public void setScore(int set_score) {
score = set_score;
}
}
Populating playerRecord:
for (int i = 0; i < 10; i++) {
records[i] = new playerRecord("", (0));
}
I hope I've been able to illustrate the issue properly. If any other details are needed please let me know.
You are having issues with memory pointers. Your array of 10 scores is actually an array of 10 pointers to playerRecord objects. I know it doesn't look like it, but this is what is happening behind the scenes when you have an array of objects.
The two duplicated elements in the array, after executing the sort operation, are actually addressing the same piece of memory!
Let's say i=4; and insertScoreHere = 3.
records[i] = records[i-1];
# records[4] = records[3];
# BUT what actually happens here is records[4] is now pointing to the
# same piece of memory as records[3]. So then:
# records[4] => memory_address_x
# records[3] => memory_address_x
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
#so now this code: records[3].setName(uName); is actually modifying
#the same piece of memory as records[4].
Solution #1:
Swap the pointers around as you do the sort. I'm going to use the object at i==9 since that one gets wiped anyway.
public void sortWinners() {
for (int i = 0; i < 10; i++) {
if (uScore < records[i].getScore()) {
insertScoreHere = i;
i = 10; //this is terrible i know
}
}
# EDIT 1: lets save this record for reuse
playerRecord temp = records[9];
for (int i = 9; i > insertScoreHere; i--) {
records[i] = records[i-1];
}
# EDIT 2: change the record to point to a separate record
records[insertScoreHere] = temp;
# ^ this index now points to a separate record from records[i]
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
}
Solution #2:
Another way to avoid messing with memory pointers will be to copy the data from one record to another:
public void sortWinners() {
for (int i = 0; i < 10; i++) {
if (uScore < records[i].getScore()) {
insertScoreHere = i;
i = 10; //this is terrible i know
}
}
for (int i = 9; i > insertScoreHere; i--) {
records[i].setName(records[i-1].getName()); # EDIT 1 **
records[i].setScore(records[i-1].getScore());# EDIT 2 **
}
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
}
The problem comes about with these lines when you want to insert your new score
records[insertScoreHere].setName(uName);
records[insertScoreHere].setScore(uScore);
What this is actually doing is replacing the name and score of the playerRecord that is at that index. Which has also the same object which you have now shuffled to the next index (insertScoreHere + 1)
To show you this all you need to do is print the address of the player records in your array:
playerRecord#996db8, playerRecord#996db8, playerRecord#163006a, playerRecord#1be847c, ...
This is after I have called your sortWinners method once - you can see that the first two elements in the array reference the same object playerRecord#996db8
To fix this you just need to insert the new score at that index by calling this
records[insertScoreHere] = new PlayerRecord(uName, uScore)
You might also want to review the naming conventions for Java
How can I fill the last n cells (inclusive) of a 2d array in java?
This is what I've tried:
if(numOfUnusedCells != 0) {
for (int k = matrix[0].length; k >= numOfUnusedCells; k--) {
matrix[rows-1][k -1] = "*";
}
}
Example
for a 2d array as such as 2 elements to fill:
+---+---+---+
| | | |
+---+---+---+
| | * | * |
+---+---+---+
Arrays.fill can do that for you:
see this example where you can fill the 1st element of the array with -21
example:
final int[][] a2dArr = new int[3][3];
System.out.println("Before: " + Arrays.deepToString(a2dArr));
for (int i = 0; i < a2dArr.length; i++) {
Arrays.fill(a2dArr[i], 0, 1, -21);
}
System.out.println("After: " + Arrays.deepToString(a2dArr));
I've run into a bit of a conundrum in a personal Java project I've been working on. I want to print a two-dimensional array of Strings in the form of a table. Not the Strings by themselves, but with row and column labels as well (think Microsoft Excel). This is what I envision the finished product to be, with asterisks representing where the Strings should go.
| A | B | C | D | E | F | G |
----+---------+---------+---------+---------+---------+---------+---------+
1 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
2 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
3 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
4 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
5 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
6 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
7 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
8 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
9 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
10 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
I know that this will use a nested forward loop, and that the logical process would be to put the String values in the inner loop, like "example[i][j]" type format. I'm just so confused as to how I go about getting the design around the cells in the right format, limiting each String to 10 characters like how Excel limits their cell size when shrunken down. Do I use substring for that? Do I use printf to get the 10th row correctly spaced?
Any pointers are greatly appreciated, I've never been stumped quite like this before.
The first line should be easy enough, assuming you don't exceed 26 columns, i.e. column name is just A to Z.
The even lines are all a lead-in of ----+, followed by columnCount repeats of ---------+.
The odd lines (except first), are a lead-in of 999 |, where 999 is a row number, right-justified, with leading spaces. That can be done with printf() or String.format() with a format string of
"%3d |".
Following the lead-in are columnCount repeats of a string value, trimmed and center-aligned to 9 characters, followed by a |.
To center-align to 9 characters, do the following:
If length > 9, trim to 9 (yes, using substring()).
Otherwise, calculate spaces needed, i.e. spacesTotal = 9 - trimmedLength.
Calculate spaces on left: spaceBefore = spacesTotal / 2.
Calculate spaces on right: spaceAfter = spacesTotal - spaceBefore.
By doing it that way, an odd number of spaces such as 5, becomes 2 before and 3 after.
Now print spaceBefore spaces, the (trimmed) text value, then spaceAfter spaces, and a |.
public static void printStringGrid(String[][] array){
System.out.print(" |");
for (int i = 0; i < array[0].length; i++){
System.out.print(" ");
System.out.print((char)('A' + i));
System.out.print(" |");
}
System.out.println();
for (int i = 0; i < array.length; i++){
System.out.print("----+");
for (int j = 0; j < array[0].length; j++){
System.out.print("---------+");
}
System.out.println();
System.out.print(" " + (i + 1) + " |");
for (int j = 0; j < array[0].length; j++){
if (array[i][j].length() < 10){
int spaces = (9 - array[i][j].length()) / 2;
for (int k = 0; k < spaces; k++){
System.out.print(" ");
}
System.out.print(array[i][j]);
for (int k = 0; k < (9 - array[i][j].length()) - spaces; k++){
System.out.print(" ");
}
}
else{
System.out.print(array[i][j].substring(0, 9));
}
System.out.print("|");
}
System.out.println();
}
}
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.
}
}