Quick Program question:

converting/changing methods

Page 1 of 1

12 Replies - 1231 Views - Last Post: 07 February 2008 - 12:44 PM Rate Topic: -----

#1 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Quick Program question:

Post icon  Posted 06 February 2008 - 12:31 AM

* I put a lot of time into this post so please help me. *
This is for a project due soon.. Immediate attention necessary


Hello all, I hope I have permission to ask here, if not -- can you please link me to a forum that allows code/project help?

Let me explain just a little before I ask - I have to make a Knight's Tour program, on an 8x8 grid.
I already completed the project, but found out that instead of user input, it is supposed to quickly process the solution (meaning random numbers).

Everything is set up and working correctly, but I have the user inputs instead of the random.

Here are my questions:

There are 2 main lines where the program asks for input,
int m = in.nextInt()-1; and
moveNumber = in.nextInt()-1;


I'm thinking I can edit those methods (including removing the print line statements about entering an integer) and add a:

Random rndgenerator = new Random.nextInt(8) +1;

//the +1 makes a random int of 0-7 become 1-8 ( what we want )

twice, with the generator having a different name.

Also, we mustn't forget about


import java.util.Random;





Is this conversion as simple as it seems? Is there something I'm missing? Any tips are appreciated, as this is actually a really heavily weighted assignment.

Code:
import java.util.*;
public class KnightsTourMain 
{
		
		int board[][]= new int [8][8];//Initializing the board to a 2d 8 b 8 array
		int horizontal[] = {2,1,-1,-2,-2,-1,1,2}; //declaring the horizontal moves the knight can do
		int vertical[] = {-1,-2,-2,-1,1,2,2,1}; //declaring the vertical moves the knight can do
		int currentRow = 4; //current starting Row for the knight
		int currentColumn = 4;//current staring column for the knight
		int moves = 0; //initializing the number of moves
		
		public void move(int moveNumber)//checks whether the moveNumber is a valid on the board move
		{							   //then will move providing that there hasn't been a move there already  
			Scanner in = new Scanner(System.in);
			while ((validrow(moveNumber)==false) || (validColumn(moveNumber)==false))
			{
				System.out.println("That move would take you off the board, enter another move number between 1 and 8");
				moveNumber = in.nextInt()-1;
			}//end while
			if((validrow(moveNumber)==true) &&(validColumn(moveNumber)==true))
			{
				currentRow +=vertical[moveNumber];
				currentColumn+=horizontal[moveNumber];
				moves++;
				board[currentRow][currentColumn]= moves;
				System.out.println("Current number of moves is :"+moves);
				output();
			}
			
		}//end move
		public boolean anyvalidmoves()//checks whether there are any available moves
		{
			for (int i =0;i<8;i++)
			{
				while (((validrow(i)==false) ||(validColumn(i)==false))&&(i<7))
				{
					i++;
				}//end while
				
				if(board[currentRow+vertical[i]][currentColumn+horizontal[i]]==0);
					return true;
			}//end for
			return false;
		}//end any valid moves
		public boolean validrow(int moveNumber)//checks if the move will be a row that is on the board
		{
			if((currentRow+vertical[moveNumber] < 0)||(currentRow+vertical[moveNumber] >7))
				return false;
			else
				return true;
		}//end valid row
		public boolean validColumn(int moveNumber)//checks whether the move will be to a column
		{										   //that is on the board
			if((currentColumn+horizontal[moveNumber] < 0)||(currentColumn+horizontal[moveNumber] > 7))
				return false;
			else
				return true;
		}//end validColumn
		public void output()//outputs the chess board
		{
			for (int i =0;i<board.length;i++)
			{
				for (int j =0;j<board[i].length;j++)
				{
					System.out.printf("%d ",board[i][j]);
				}//end inner for
				System.out.println();
			}//end outer for
		}//end method output
		
		
		public void input()//while there are any valid moves this will ask you to move
		{
			while(anyvalidmoves()==true)
			{
				Scanner in = new Scanner(System.in);
				System.out.println("Enter a move between 1 and 8");
				int m = in.nextInt()-1;
				move(m);
			}//end while
		   
		   
		   
			if(moves <64)
			{
				System.out.println("There are no valid moves left");
				System.out.println("Youre knights tour lasted "+moves);
				output();
			}
			else
			{
				System.out.println("You managed a full knights tour well done!!");
				output();
			}
			System.exit(0);
			
			
			
		}//end method in out
		public static void main(String[]args)
		{
			KnightsTourMain k = new KnightsTourMain();
			k.input();
			
		}//end main
		
		
		
	}//end KnightsTour


Is This A Good Question/Topic? 0
  • +

Replies To: Quick Program question:

#2 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3106
  • View blog
  • Posts: 19,145
  • Joined: 14-September 07

Re: Quick Program question:

Posted 06 February 2008 - 12:46 AM

Have you run this current code and have had the expected outcome?

--KYA
Was This Post Helpful? 0
  • +
  • -

#3 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Re: Quick Program question:

Posted 06 February 2008 - 09:10 AM

View PostKYA, on 6 Feb, 2008 - 12:46 AM, said:

Have you run this current code and have had the expected outcome?

--KYA



to answer your question, yes - the code DOES work when compiled and run.


But I no longer want the code to have user input, I want it to be more streamlined - completely autonomous
Was This Post Helpful? 0
  • +
  • -

#4 DillonSalsman  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 13
  • View blog
  • Posts: 144
  • Joined: 30-October 07

Re: Quick Program question:

Posted 06 February 2008 - 10:09 AM

Hmm I think you need to generate a random number from 0-7, plug it into your 2 move arrays (horizontal, and vertical)with something along the lines of:
int thisMoveX = horizontal[randomNumber];
int thisMoveY = vertical[randomNumber];


Now, what if this move is invalid?
while(moveValid == false)
{
	   //however  you generate your random number
	   int thisMoveX = horizontal[randomNumber];
	   int thisMoveY = vertical[randomNumber];
	   //call your method of checking if move is valid
	   //set moveValid == true if it is valid
}

Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Quick Program question:

Posted 06 February 2008 - 10:13 AM

If your move method was set up for it, your answer would be as simple as
public void inputRandom() {
	java.util.Random rnd = new java.util.Random();
	
	while(anyvalidmoves()) {
		move(rnd.nextInt(8) );
	}
}



Unfortunately, the move method also accepts user input. I'd make the move method return a boolean, indicating success or not. While not successful and still moves remaining, loop.

It's not the most elegant menthod. Ideally, you'd wouldn't ask for the same random move in a set. There are numer of ways to attack it, but that should be the first iteration for just getting it working.

Hope this helps.

EDIT: removed a "+1", twas wrong.

This post has been edited by baavgai: 06 February 2008 - 11:49 AM

Was This Post Helpful? 0
  • +
  • -

#6 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Re: Quick Program question:

Posted 06 February 2008 - 02:24 PM

I did what you said, Baavgai, at least I hope. I removed the input method and created the random method.

I had to remove the input line from Main, and now the program compiles but doesn't run. Where did I lose track? Its getting too complicated to remember what I'm trying to do :(

Am I missing something in Main? How do I get the program to start at 0,0, or say, another coordinate of my choose?
** Edit, I have variables for starting coordinates. to start at 0,0 , these should say currentRow = 0; and currentColumn = 0;**
I also only want it to print out when its all finished now, not every time a move happens. How do I do that?

Thank you so much, this is due Friday and sadly I'm still not ready. Thank you again so much.

This is my new code: You will notice it is a new filename/project name now because I didnt want to edit the original, working code.

import java.util.*;
public class KTAuto
{
		
		int board[][]= new int [8][8];//Initializing the board to a 2d 8 b 8 array
		int horizontal[] = {2,1,-1,-2,-2,-1,1,2}; //declaring the horizontal moves the knight can do
		int vertical[] = {-1,-2,-2,-1,1,2,2,1}; //declaring the vertical moves the knight can do
		int currentRow = 4; //current starting Row for the knight
		int currentColumn = 4;//current staring column for the knight
		int moves = 0; //initializing the number of moves
		
		public void inputRandom() 
		{
			java.util.Random rnd = new java.util.Random();
			
			while(anyvalidmoves()) 
			{
				move(rnd.nextInt(8) );
			}
			if(moves <64)
			{
				System.out.println("There are no valid moves left");
				System.out.println("Youre knights tour lasted "+moves);
				output();
			}
			else
			{
				System.out.println("You managed a full knights tour well done!!");
				output();
			}
			System.exit(0);
		}
		
		
		public void move(int moveNumber)//checks whether the moveNumber is a valid on the board move
		{							   //then will move providing that there hasn't been a move there already  
			Scanner in = new Scanner(System.in);
			while ((validrow(moveNumber)==false) || (validColumn(moveNumber)==false))
			{
				System.out.println("That move would take you off the board, enter another move number between 1 and 8");
				moveNumber = in.nextInt()-1;
			}//end while
			if((validrow(moveNumber)==true) &&(validColumn(moveNumber)==true))
			{
				currentRow +=vertical[moveNumber];
				currentColumn+=horizontal[moveNumber];
				moves++;
				board[currentRow][currentColumn]= moves;
				System.out.println("Current number of moves is :"+moves);
				output();
			}
			
		}//end move
		public boolean anyvalidmoves()//checks whether there are any available moves
		{
			for (int i =0;i<8;i++)
			{
				while (((validrow(i)==false) ||(validColumn(i)==false))&&(i<7))
				{
					i++;
				}//end while
				
				if(board[currentRow+vertical[i]][currentColumn+horizontal[i]]==0);
					return true;
			}//end for
			return false;
		}//end any valid moves
		public boolean validrow(int moveNumber)//checks if the move will be a row that is on the board
		{
			if((currentRow+vertical[moveNumber] < 0)||(currentRow+vertical[moveNumber] >7))
				return false;
			else
				return true;
		}//end valid row
		public boolean validColumn(int moveNumber)//checks whether the move will be to a column
		{										   //that is on the board
			if((currentColumn+horizontal[moveNumber] < 0)||(currentColumn+horizontal[moveNumber] > 7))
				return false;
			else
				return true;
		}//end validColumn
		public void output()//outputs the chess board
		{
			for (int i =0;i<board.length;i++)
			{
				for (int j =0;j<board[i].length;j++)
				{
					System.out.printf("%d ",board[i][j]);
				}//end inner for
				System.out.println();
			}//end outer for
		}//end method output
		
	   
		public static void main(String[]args)
		{
			
			
		}//end main
		
		
		
	}

This post has been edited by needhelpbadly: 06 February 2008 - 02:25 PM

Was This Post Helpful? 0
  • +
  • -

#7 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Re: Quick Program question:

Posted 06 February 2008 - 02:36 PM

I'd like to follow up by stating that I put a simple

System.out.Println("abc");

in my new random move method, and no text gets printed to the screen. That means somewhere in my program, it is getting "short-circuited", possible because I dont have any starting function calls in Main?


Please help, im completely lost now ;p
Was This Post Helpful? 0
  • +
  • -

#8 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3106
  • View blog
  • Posts: 19,145
  • Joined: 14-September 07

Re: Quick Program question:

Posted 06 February 2008 - 05:34 PM

View Postneedhelpbadly, on 6 Feb, 2008 - 03:36 PM, said:

I'd like to follow up by stating that I put a simple

System.out.Println("abc");

in my new random move method, and no text gets printed to the screen. That means somewhere in my program, it is getting "short-circuited", possible because I dont have any starting function calls in Main?


Please help, im completely lost now ;p

Nothing is being printed to the screen in that case becasue there is literally nothing in your main() function.

--KYA
Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Quick Program question:

Posted 06 February 2008 - 05:56 PM

You're still asking for user input moveNumber = in.nextInt()-1;.

Also, your main is empty. It should look something like this?
public static void main(String[]args) {
	KTAuto pgm = new KTAuto();
	pgm.inputRandom();
}



You have all the code. This should just be an exercise in refactoring.
Was This Post Helpful? 0
  • +
  • -

#10 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Re: Quick Program question:

Posted 06 February 2008 - 09:12 PM

Thanks so much for the help. I spent 10 minutes re-vamping the code and all the random inputs are working now. I made the variables clearer so the code is easier to read.


One problem I'm having now is that the program seems to not want to pass move # 29.

From any starting position, the program stops at 29. The error must reside in one of my loops somewhere but I cant find it. I'm desperate, can someone help me with this?

I tried using <7, <6, <5 etc on the loops, but thats a no go. Please hint the answer, or tell me outright. My due date is getting closer. Thank you so much Baavgai, and everyone else.

Heres my new code:
public class KnightsTour 
{
	int grid[][];
	boolean finished;
	final int Xcord[] = {-1, 1, -1, 1, -2, 2, -2, 2};
	final int Ycord[] = {-2, 2, 2, -2, -1, 1, 1, -1};
 
	public static void main(String args[])
	{
		int totMoves = 1;
		KnightsTour kt = new KnightsTour();
		kt.check( 0, 0, totMoves);
		kt.drawGrid();
	}
	
	public KnightsTour()
	{
		grid = new int[8][8];
		finished = false;
		grid[0][0] = 1;
	}
	
	public int check(int x, int y, int totMoves)
	{
		System.out.println("Printed from check outside loop()");
		for(int i = 0; i < 8; i++)
		{
			if(finished == true)
			{
				return totMoves;
			}
			else
			{
				if(x+Xcord[i]<8 && x+Xcord[i]>=0)
				{
					if(y+Ycord[i]<8 && y+Ycord[i]>=0)
					{				
						//on the grid
						if((grid[x+Xcord[i]][y+Ycord[i]])==0)
						{
							grid[x+Xcord[i]][y+Ycord[i]]=-1;
							grid[x+Xcord[i]][y+Ycord[i]]=check(x+Xcord[i],y+Ycord[i], totMoves + 1);
							finished = true;
							
						}
					}
						
				}
			}
			
			
		}
		if(totMoves >= 64 || finished == true)
		{
			finished = true;
			return totMoves;
		}
		else
		{
			return 0;
		}
		
		
	}
	
	public void drawGrid()
	{
		System.out.println("Drawing grid");
		//Draw grid
		for(int i = 0; i < 8; i++)
		{
			System.out.println("\n________________________");
			for(int j = 0; j < 8; j++)
			{
				if(grid[j][i] < 10)
				{
					System.out.print("|0" + grid[j][i]);
				}
				else
				{
					System.out.print("|" + grid[j][i]);
				}
			}
		}
	}
 
}

Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Quick Program question:

Posted 07 February 2008 - 06:31 AM

This is setup completely differently from the one before. You have no random. You're now using recursion.

It looks like it's a solver, but it's fundamentally flawed in many ways. Event the draw grid is different, you used printf before and now it's like you forgot printf.

Um, are you just grabbing code from other people?
Was This Post Helpful? 0
  • +
  • -

#12 needhelpbadly  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 06-February 08

Re: Quick Program question:

Posted 07 February 2008 - 08:09 AM

I didn't realize I had to use recursion. I met with my professor to get some help.

I just honestly dont know whats wrong with this code now. I dont think i'm going to get anywhere with this project. I put test Print line statements in all the methods. It appears as tho the first and second if statement run 20-30 times before finally going into the 3rd if statement ( the main one ).


I'm completely lost and I'm going to give up.

I dont even know if the Knight's move table is set up correctly, because I did infact copy that from someone else.
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Quick Program question:

Posted 07 February 2008 - 12:44 PM

Your check simply will not work. It goes off into recursion land and doesn't load the board up.

To do this right, you actually need a copy of the working board for every single iteration. You also have to allow a success to filter back up.

I'm going to give you a partial solution. You will need to implement the class Board. If you can do that successfully, then the solver will work. You've already written all this code at least once. You just have to organize it correctly.

public class KnightsTour {
	//these are the 8 positions our knight can move
	// note, I kinda loaded these values for quick feedback
	// if all goes well, you should get an answer at tries=544921
	private final int offsetRow[] = {-2,-2,-1,-1,1,1,2,2};
	private final int offsetCol[] = {1,-1,2,-2,2,-2,1,-1};
	
	private final int totalPossibleMoves = 8;
	
	// it's fun to count
	private int iterationTotal = 0;

	// THIS CLASS IS INCOMPLETE!!  YOU MUST DO SOME WORK
	// for the recursion to work, you need copy your board a lot
	// this class should make the solver much easier to understand
	class Board {
		// rows and cols doesn't change
		// however, if written right, we can test on a smaller boards, like 5x5
		public static final int rows = 8;
		public static final int cols = 8;
		public static final int boardSize = rows * cols;

		// basic constructor, starts us off
		public Board() { this.move(rows/2, cols/2); }
		
		// makes a new Board instance from an existing one
		public Board(Board b) {
			// your code here
		}

		// makes a new Board instance from an existing one
		// and applies the requested move
		public Board(Board b, int moveRow, int moveCol) {
			this(b);
			this.move(moveRow, moveCol);
		}
		
		
		// current move count, incremented each successful move
		public int getMoveCount() { 
			// your code here
		}
		
		public int getCurrentRow() { 
			// your code here
		}
		
		public int getCurrentCol() { 
			// your code here
		}

		// if another object wants to examine our data, they can look here
		public int getValue(int row, int col) {
			// your code here
		}

		//check if row and col are a valid move
		public boolean isValid(int row, int col) {
			return (row>=0) && (col>=0) && (row<rows) && (col<cols) && (boardData[row][col]==0);
		}
		
		
		// make a move
		// this should call isValid, increment out move count, 
		// apply that count to the board data
		public boolean move(int moveRow, int moveCol) {
			// your code here
		}


		// check for win
		public boolean isWin() { 
			// your code here
		}
		
		
		// returns a display of the board
		// this is pretty subjective
		public String toString() {
			// your code here
		}
	}

	// private, because class Board is private
	// also, we're just given a default solution for this
	private Board solveForBoard(Board board) {
		// just counting the number of times this method gets called.
		this.iterationTotal++;
		// If the board that gets passed here is a winner, send it back up the line
		// this will cause all active method calls to stop naturally.
		if (board.isWin()) { return board; }
		
		// the loop runs through the list of possible moves
		for(int i = 0; i < totalPossibleMoves; i++) {
			// we apply the offsets to our current position, given i
			int row = board.getCurrentRow() + offsetRow[i];
			int col = board.getCurrentCol() + offsetCol[i];
			// if row,col isn't valid, ignore it.
			if (board.isValid(row, col)) {
				// create a copy of the current board object in this method
				// and move it based on row, col
				// then given that object to this method again
				Board newBoard = solveForBoard(new Board(board, row, col));
				// normally a null will be returned
				// if newBoard is not null, then it's a winner
				// return it, leave the method, all other methods will also stop due to this
				if (newBoard!=null ) { return newBoard; }
			}
		}
		// if we got this far, we had now winners, keep trying
		return null;
	}

	// what the public calls
	public void solve() {
		// initialize a counter
		this.iterationTotal = 0;
		// solve, starting with the default board
		Board board = solveForBoard(new Board());
		// we will have an answer if we got this far.
		// if it's null, then the Board class has a problem
		
		// show the user how long it took
		System.out.println("tries: " + this.iterationTotal);
		
		// show the user the answer
		System.out.println(board);
	}
	
	public static void main(String args[]) {
		KnightsTour kt = new KnightsTour();
		kt.solve();
	}
}



Good luck.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1