accessing class method problem
i'm trying to finish up the last project in our course and i cant get this part to work. it won't let me compile it and doesn't tell me the reason , other than application errors when i try to find out what the problem was. and then when i did run it, it'd give me
Quote:
1|Exception in thread "main" java.lang.NullPointerException
at Board.printBoard(Board.java:65)
at Game.playGame(Game.java:98)
at Game.main(Game.java:46)
but the lines aren't red.
the culprit, for the Game class:
Code :
public static int playGame(int[] playerplayingCondition) {
Game game = new Game();
int nextTurn = 1; //currentPlayer's assigned turn.
int Result; //Result of the winningCondition, if found, no more turn.
while (true) { //Everytime the current game has remaining moves left, it'll ask for the player/computer to submit move
Board.printBoard(); //This just asks for the moves of the current Players, and the move is submitted each time as a turn.
if (playerplayingCondition[nextTurn] == 0) {
Player.getComputerMove(game, nextTurn);
} else {
Player.getHumanMove(game, nextTurn);
}
Result = getWinningConditions();
if (Result > 0) {
return Result;
}
//If the current player turn is 1, second player it 2. Makes it so that it rotates each turn.
if (nextTurn ==1){
nextTurn = 2;
}
else if (nextTurn ==2){
nextTurn = 1;
}
//If there is still no winningCondition found, returns -1. makes the turn goes looping again.
}
}
and then i'm trying to relate it to this one: This is the Player class
Code :
public static void getHumanMove(Game game, int player) {
char rowChar, columnChar;
int row, column;
boolean acceptableAnswer;
do {
acceptableAnswer = true; //Initialize the boolean first as true so the loop can go.
System.out.print("Please enter your move. " +
"For example, " +
Board.columnLegend[1] + //I just put in a random value as an example
Board.rowLegend[0] +
": " );
Scanner in = new Scanner(System.in);
String move = in.nextLine(); //Returns user's answer into move
columnChar = move.toUpperCase().charAt(0); // columnChar is the column letter corresponding to user's answer
column = Board.ValidatingMoves(columnChar, Board.columnLegend); //checks to see if the character matchValuees with the A,B,C legend
rowChar = move.toUpperCase().charAt(1); //rowChar is the row number corresponding to user's answer
row = Board.ValidatingMoves(rowChar, Board.rowLegend); //checks to see if the numbers matchValuees with 1,2,3 legend
//Starts validation process
//Makes sure that the answer is exactly 2 characters.
if (move.length() <2 ||move.length() >2) {
System.out.println("Must use exactly two characters");
continue;
}
//Checks if column is A, B, or C.
//It's in numbers instead of letters because it uses the ValidatingMoves method
//that returns the legend as numbers. [i][0] = A, [i][1] = B, [i][2] = C
if (column < 0 || column > 2) {
System.out.println("Invalid column! Use A, B, or C. ");
continue;
}
// Check if row is 1, 2, or 3.
//[0][j] = 1, [1][j] = 2, [2][j] = 3
if (row < 0 || row > 2) {
System.out.println("Invalid row! Use 1, 2, or 3. ");
continue;
}
// Checks if move is occupied
//When everything else is passed, this returns false so it doesn't have to loop
else {
acceptableAnswer = false;
}
} while (acceptableAnswer !=false);
}
/*********************************************************************
* Method Name: getComputerMove
* Parameters: ticc, player
* Returns: NONE
* Description: It generates randomMoves for the computer
*********************************************************************/
static void getComputerMove(Game game, int player){
int i, j; // row, column
if (Board.findRemainingMoves()){ //Checks to see if there are moves left
do {
Random randomNumbers = new Random();
int move = (int)(randomNumbers.nextDouble() *9) +1;
i = (move - 1)/ Board.board.length; //Makes sure the move of the array isn't out of bounds.
j = (move - 1) % Board.board[i].length;
} while ((Board.board[i][j] !=0)); //Making sure that it isn't on an occupied space
//Submits computer's move
System.out.println("Computer Moves: " +
Board.columnLegend[j] +
Board.rowLegend[i]);
}
}
and I get this: whenever I change the Player class's getMoves methods parameter into Player game instead of Game game
Quote:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method getComputerMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
The method getHumanMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
and the red lines appears there at getComputerMove
Code :
Player.getComputerMove(game, nextTurn);
} else {
Player.getHumanMove(game, nextTurn);
}
I also have a Board class that prints out the board but it only gives me an error whenever the Game gives me an error b/c it can't submit any moves.
It works for Procedural Programming though...like just one class but we have to now split into different classes for OOP.
Help will be appreciated
Re: accessing class method problem
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method getComputerMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
The method getHumanMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
It seems you passed the method a Player object when you should have passed it a Game object.
Also, I don't know what you did in printBoard() as it wasn't posted.
That's where the Null Pointer is coming from.
It can't be coming from
Board.printBoard() as that's a void method and it's not being used to initialize any variables with that statement anyway.
You could always use System.out.println() to check the various variables inside the method printBoard() and see which variable is the one turning up null.
Re: accessing class method problem
Quote:
Originally Posted by
steel55677
we have to now split into different classes for OOP.
Then why have you made everything static?
Re: accessing class method problem
can you show the main method?
kinda wanna see...
Re: accessing class method problem
Quote:
The method getHumanMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
Where is this method defined that takes a Player object vs a Game object?
Is there some other code that you have not posted that uses a Player object?
Re: accessing class method problem
I'm still not sure what static means, I just let Eclipse change it to make it work.
This is my Board object
Code :
public class Board {
public static int[][] board;
public static char[] rowLegend = { '1', '2', '3' }; // I defined the row as [i][0] = 1 [i][1] = 2, [i][2] = 3.
public static char[] columnLegend = { 'A', 'B', 'C' }; // I defined the column as [0][j] = A, [1][j] = B, [2][j] = C.
public Board() {
board = new int [3][3]; //sets the board row and column size
fillEmptySpaces(); //pre-sets the board so that it'll make it unoccupied for player moves.
}
/*********************************************************************
* Method Name: fillEmptySpaces
* Parameters: a, k
* Returns: NONE
* Description: It fills all the elements in the array with spaces so
* the program can check if it's anymore moves left.
*********************************************************************/
public void fillEmptySpaces() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = 0;
}
}
}
/*********************************************************************
* Method Name: printBoard
* Parameters:
* Returns: NONE
* Description: Prints out the formatted board. Keeps it in memory
* everytime a move is submitted.
*********************************************************************/
public static void printBoard() {
int i, j;
String Space = " ";
String Vert = "|";
String Horz = "--";
//This prints out the column/top of the board
System.out.print(Space + Space);
for (j = 0; j < 3; j++)
System.out.print(columnLegend[j] + Space);
System.out.println();
//This prints out the row/horizontal of the board
for (i = 0; i < 3; i++) {
System.out.print(Space + Horz);
for (j = 0; j < 3; j++)
System.out.print(Horz);
System.out.println();
System.out.print(rowLegend[i] + Vert);
for (j = 0; j < 3; j++) {
//Ends board printing.
char playerOne = 'X';
char playerTwo = 'O';
//The first defaultplayer will be printed by X, when move is submitted
if (board[i][j] == 1)
System.out.print(playerOne);
//The second defaultplayer will be printed by O, when move is submitted
else if (board[i][j] == 2)
System.out.print(playerTwo);
//Keeps the board intact, so that it'll not reformat when X or O is added.
else
System.out.print(Space);
System.out.print(Vert);
}
System.out.println();
}
}
/*********************************************************************
* Method Name: ValidatingMoves
* Parameters: selection, characters
* Returns: NONE
* Description: Searches through the array to see if the letter given
* is good and returns the letter to the letter entered
* , if it's not , returns -1 as false.
*********************************************************************/
public static int ValidatingMoves(char selection, char[] characters) {
int matchValue;
for (matchValue = 0; matchValue < 3; matchValue++) {
if (characters[matchValue] == selection) {
// Found a matchValue
return matchValue;
}
}
return -1;
}
/*********************************************************************
* Method Name: findRemainingMoves
* Parameters:
* Returns: true/false
* Description: Searches the array to find any blank spaces. If there
* then it returns false so the program goes again.
* if it there are spaces, it'll return true so it'll stop
* the game and searches for winning conditions.
*********************************************************************/
public static boolean findRemainingMoves() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 0) {
return true;
}
}
}
return false;
}
/*********************************************************************
* Method Name: submitMove
* Parameters: i, j, defaultPlayer
* Returns: true/false
* Description: Searches through the board to find any empty spaces.
* If there are, then you cannot make move (false).
* If the move is unoccupied, defaultPlayer is able to make
* move at given [i][j] location.
*********************************************************************/
public static boolean submitMove(int i, int j, int defaultPlayer) {
if (board[i][j] != 0) {
return false;
}
board[i][j] = defaultPlayer;
return true;
}
}
the Game:
Code :
import java.util.Random;
public class Game {
public static void main(String[] args) {
boolean errorCheck = true;
int playerplayingCondition[] = new int[3];
int player, Result; //player is the player that goes
//Result is the result of the final game.
System.out.println("****************" );
System.out.println(" Tic-Tac-Toe!" );
System.out.println("****************");
System.out.println();
System.out.println("Please enter the column and then row of your move.");
System.out.println();
while (errorCheck !=false) {
for (player = 1; player <= 2; player++) { //moves 2 times because there are two players
Random randomNumber = new Random(); //Sets randomNumber
int randomCondition = randomNumber.nextInt(2); // Makes it generate between 0-2
//I used the even/odd calculation to make the player who goes first randomized
if (randomCondition % 2 == 0)
{
playerplayingCondition[1] =1; //playerPlayingcondition means that whoever is [i], will be selected to be 1 or 0 which means who will go first. [i] is the player, = # means who's going first.
playerplayingCondition[2]=0;
System.out.println("You will be going first(X).");
System.out.println();
break;
}
else
{
playerplayingCondition[1] =0; //computer goes first
playerplayingCondition[2]=1;
}
}
//Prints out who wins and who lost
Result = playGame(playerplayingCondition);
switch (Result) {
case 1:
System.out.println("Game winning board:");
Board.printBoard();
System.out.println("Congratulations! (X) won!");
System.out.println("Sorry. (O) Lost!");
System.out.println();
break;
case 2:
System.out.println("Game winning board:");
Board.printBoard();
System.out.println("Congratulations! (O) won!");
System.out.println("Sorry. (X) Lost!");
System.out.println();
break;
default:
System.out.println("Game winning board:");
Board.printBoard();
System.out.println("It's a tie. Cats Game!");
System.out.println();
}
//This value makes it so that after all the looping for asking the possible moves are done, terminate = 0;
int terminate = -1;
//Once it's set to -1, the if == -1, errorCheck makes it false; which exits the game entirely
if(terminate == -1){
errorCheck = false;
}
}
System.out.println("Thanks for playing. Goodbye!");
}
/*********************************************************************
* Method Name: playGame
* Parameters:
* Returns: NONE
* Description: Submits user move
*********************************************************************/
public static int playGame(int[] playerplayingCondition) {
Game game = new Game();
int nextTurn = 1; //currentPlayer's assigned turn.
int Result; //Result of the winningCondition, if found, no more turn.
while (true) { //Everytime the current game has remaining moves left, it'll ask for the player/computer to submit move
Board.printBoard(); //This just asks for the moves of the current Players, and the move is submitted each time as a turn.
if (playerplayingCondition[nextTurn] == 0) {
Player.getComputerMove(game, nextTurn);
} else {
Player.getHumanMove(game, nextTurn);
}
Result = getWinningConditions();
if (Result > 0) {
return Result;
}
//If the current player turn is 1, second player it 2. Makes it so that it rotates each turn.
if (nextTurn ==1){
nextTurn = 2;
}
else if (nextTurn ==2){
nextTurn = 1;
}
//If there is still no winningCondition found, returns -1. makes the turn goes looping again.
}
}
/*********************************************************************
* Method Name: getWinningConditions
* Parameters:
* Returns: NONE
* Description: It finds all the winningConditions. If winningCondition
* exists, it returns the result. If not, then it returns -1.
*********************************************************************/
public static int getWinningConditions() {
int j;
int Result;
//Checks the row for [X][X][X] or
//[O]
//[O]
//[O]
for (j = 0; j < 3; j++) {
Result = getResultRow(j);
if (Result != -1) return Result;
Result = getResultColumn(j);
if (Result != -1) return Result;
}
//Checks the board for diagonal winning conditions
//Starts from the top left
//[x][ ][ ]
//[ ][x][ ]
//[ ][ ][x]
Result = Board.board[0][0];
for (j = 1; j <3; j++) {
if (Board.board[j][j] != Result) {
Result = -1;
break;
}
}
//Starts from bottom left
//[ ][ ][x]
//[ ][x][ ]
//[x][ ][ ]
Result = Board.board[2][0];
for (j = 1; j < 3; j++) {
if (Board.board[2 - j][j] != Result) {
// Values along this diagonal differ, no Result
Result = -1;
break;
}
}
if (Result != -1)
return Result;
if (Result != -1) return Result;
return -1;
}
/*********************************************************************
* Method Name: getResultRow
* Parameters:
* Returns: NONE
* Description: Searches the row for the winningCondition.
*********************************************************************/
// Determines if the current row has a Result
private static int getResultRow(int i) {
int j;
for (j = 1; j < 3; j++) {
if (Board.board[i][j] != Board.board[i][0]) {
return -1; //If the moves are all different in the same row, then result is -1 or no winning conditions
}
}
return Board.board[i][0]; //If the row has all the same value, it'll return the row[i]
}
/*********************************************************************
* Method Name: getResultColumn
* Parameters:
* Returns: NONE
* Description: Searches the column for the winningCondition.
*********************************************************************/
private static int getResultColumn(int j) {
int i;
for (i = 1; i < 3; i++) {
if (Board.board[i][j] != Board.board[0][j]) {
return -1; //If the moves are all different in the same column, then result is -1 or no winning conditions
}
}
return Board.board[0][j]; ////If the column has all the same value, it'll return the column[j]
}
}
and Player
Code :
import java.util.Random;
import java.util.Scanner;
public class Player {
/*********************************************************************
* Method Name: getHumanMove
* Parameters: ticc, player
* Returns: NONE
* Description: Submits user move
*********************************************************************/
public static void getHumanMove(Player game, int player) {
char rowChar, columnChar;
int row, column;
boolean acceptableAnswer;
do {
acceptableAnswer = true; //Initialize the boolean first as true so the loop can go.
System.out.print("Please enter your move. " +
"For example, " +
Board.columnLegend[1] + //I just put in a random value as an example
Board.rowLegend[0] +
": " );
Scanner in = new Scanner(System.in);
String move = in.nextLine(); //Returns user's answer into move
columnChar = move.toUpperCase().charAt(0); // columnChar is the column letter corresponding to user's answer
column = Board.ValidatingMoves(columnChar, Board.columnLegend); //checks to see if the character matchValuees with the A,B,C legend
rowChar = move.toUpperCase().charAt(1); //rowChar is the row number corresponding to user's answer
row = Board.ValidatingMoves(rowChar, Board.rowLegend); //checks to see if the numbers matchValuees with 1,2,3 legend
//Starts validation process
//Makes sure that the answer is exactly 2 characters.
if (move.length() <2 ||move.length() >2) {
System.out.println("Must use exactly two characters");
continue;
}
//Checks if column is A, B, or C.
//It's in numbers instead of letters because it uses the ValidatingMoves method
//that returns the legend as numbers. [i][0] = A, [i][1] = B, [i][2] = C
if (column < 0 || column > 2) {
System.out.println("Invalid column! Use A, B, or C. ");
continue;
}
// Check if row is 1, 2, or 3.
//[0][j] = 1, [1][j] = 2, [2][j] = 3
if (row < 0 || row > 2) {
System.out.println("Invalid row! Use 1, 2, or 3. ");
continue;
}
// Checks if move is occupied
//When everything else is passed, this returns false so it doesn't have to loop
else {
acceptableAnswer = false;
}
} while (acceptableAnswer !=false);
}
/*********************************************************************
* Method Name: getComputerMove
* Parameters: ticc, player
* Returns: NONE
* Description: It generates randomMoves for the computer
*********************************************************************/
static void getComputerMove(Player game, int player){
int i, j; // row, column
if (Board.findRemainingMoves()){ //Checks to see if there are moves left
do {
Random randomNumbers = new Random();
int move = (int)(randomNumbers.nextDouble() *9) +1;
i = (move - 1)/ Board.board.length; //Makes sure the move of the array isn't out of bounds.
j = (move - 1) % Board.board[i].length;
} while ((Board.board[i][j] !=0)); //Making sure that it isn't on an occupied space
//Submits computer's move
System.out.println("Computer Moves: " +
Board.columnLegend[j] +
Board.rowLegend[i]);
}
}
}
Whenever I compile it, it shows :
Quote:
****************
Tic-Tac-Toe!
****************
Please enter the column and then row of your move.
and error starts at the problem where I can't get the moves from Player object to Game.
then when I change the player I get
Quote:
****************
Tic-Tac-Toe!
****************
Please enter the column and then row of your move.
You will be going first(X).
A B C
--------
I think that because there's an error with Move, the board can't print =\
thanks for the feedback so far.
Re: accessing class method problem
Quote:
error starts at the problem where I can't get the moves from Player object to Game.
Please post the error message and the code where the error occurs.
Re: accessing class method problem
Quote:
****************
Tic-Tac-Toe!
****************
Please enter the column and then row of your move.
You will be going first(X).
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method getComputerMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
The method getHumanMove(Player, int) in the type Player is not applicable for the arguments (Game, int)
at Game.playGame(Game.java:100)
at Game.main(Game.java:46)
Code :
Player.getComputerMove(game, nextTurn);
} else {
Player.getHumanMove(game, nextTurn);
and when I change the Player to Game game instead of Player game, like this
Code :
public static void getComputerMove(Game game, int player){
public static void getHumanMove(Game game, int player)
I get
Quote:
****************
Tic-Tac-Toe!
****************
Please enter the column and then row of your move.
You will be going first(X).
A B C
--------
1|Exception in thread "main" java.lang.NullPointerException
at Board.printBoard(Board.java:65)
at Game.playGame(Game.java:98)
at Game.main(Game.java:46)
Code :
//The first defaultplayer will be printed by X, when move is submitted
if (board[i][j] == 1)
Board.printBoard(); //This just asks for the moves of the current Players, and the move is submitted each time as a turn.
Code :
Board.printBoard(); //This just asks for the moves of the current Players, and the move is submitted each time as a turn.
if (playerplayingCondition[nextTurn] == 0) {
Player.getComputerMove(game, nextTurn);
} else {
Player.getHumanMove(game, nextTurn);
}
Result = getWinningConditions();
if (Result > 0) {
return Result;
}
this is the game. 98 error
and last
Code :
Result = playGame(playerplayingCondition);
I have no idea what to do because Eclipse doesn't show any syntax errors / red lines.
Re: accessing class method problem
Quote:
Originally Posted by
steel55677
I'm still not sure what static means,
Then you should learn.
Basically static means it belongs to the class and not an instance of the class. Imagine if in the Person class the name was static. Then you, me and everybody in the world would have the same name. If name was non-static then every Person can have their own name.
Re: accessing class method problem
Quote:
"main" java.lang.NullPointerException
at Board.printBoard(Board.java:65)
What variable on line 65 has a null value? Track back in your code to see why it does not have a valid non null value.
Java naming conventions are that class names start with Capital letters, variables names start with lower case letters.
You have a lot of uppercase names where there would be a variable. Your uppercase names say that you have a lot of static methods:
Board.printBoard();
Player.getHumanMove(game, nextTurn);
BTW Your little pieces of posted code are useless for seeing what is happening in your code.
Re: accessing class method problem
Ok thanks, I'm going to try finding that error and see what happens when I change it to variable
Re: accessing class method problem
Just asking, why are you making these weird Documentations comments?
You should use @return, @param, @author, etc.