This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am currently trying to make a java card game but am having trouble setting the card. I am taking in values such as 2H 3D 4S 5C 6H in the main function. I am trying to put these values into my Card class but when I try to set my rank I get a nullpointerexception error.
I am new to java programing and can not figure out why this is happening. Any suggestions? Am I not allowed to make an array of Cards?
public class Game {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
String[] player1arr = new String[5];
String[] player2arr = new String[5];
Card[] player1 = new Card[5];
Card[] player2 = new Card[5];
for(int i = 0; i < 5; i++){
player1arr[i] = sc.next();
char first = player1arr[i].charAt(0);
int rank = Character.getNumericValue(first); //error
player1[i].setRank(rank);
}
for(int i = 0; i < 5; i++){
player2arr[i] = sc.next();
System.out.println(player2arr[i]);
}
}
}
class Card{
private int rank;
private char suit;
public int getRank(){
return rank;
}
public void setRank(int r){
rank = r;
}
}
When you create an array of objects, the array is initially filled with the default value of null.
Call
cards[i] = new Card();
to initialize all the objects within the array :)
You need to instantiate Cards in your main method.
for(int i = 0; i < 5; i++){
player1arr[i] = sc.next();
char first = player1arr[i].charAt(0);
int rank = Character.getNumericValue(first); //error
player1[i] = new Card();
player1[i].setRank(rank);
}
Related
This question already has an answer here:
How to copy(memory) array in java?
(1 answer)
Closed 4 years ago.
this is for the fifteen game, I made a class (Config), which consists of an array of ints to represent the state of the board.
then I made some move methods which receive Config A, create a copy of it,finds its 0 and applies whatever move the method is supposed to and then returning it as Config B.
thats happening as plan but the problem is that when I try to print config A afterwards it also changed, and is the same as B no matter what move I do.
Example: https://imgur.com/qnZX12Y dada.tabela is the array
if I print randomconfig before the move_left_new, it prints the original config as it should, however if I print it afterwards, it will print the same as testingmove.
import java.util.*;
class Config{
int[] tabela;
Config(){
int[] blanks ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
tabela = blanks;
}
public Config(int arraydado[]){
tabela = arraydado;}
public void printTabela(){
for(int i = 0; i<16 ;i++)
System.out.print(tabela[i] + " ");
System.out.println();
}
}
public static Config move_left_new(Config dada){
int i;
int temp;
Config resultante = new Config(dada.tabela);
for(i = 0; i<16; i++){
if(resultante.tabela[i] == 0)
break;
}
if( i!=0 && i!= 4 && i!= 8 && i!=12){
temp = resultante.tabela[i-1];
resultante.tabela[i-1] = 0;
resultante.tabela[i] = temp;
}
return resultante;
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int arr[] = new int[16];
for(int i=0; i<16; i++)
arr[i] = input.nextInt();
Config randomconfig = new Config(arr);
randomconfig.printTabela(); //original
Config changed = move_left_new(randomconfig);
randomconfig.printTabela(); //should be the same as before but isnt
changed.printTabela(); // moved as it should
}
Arrays are references in java. So after you do Config resultante = new Config(dada.tabela);, the tabela of resultance and dada would both refer/point to the same array.
What you might want to do, is to create a shallow copy of dada.tabela, then pass that shallow copy to Config's constructor to instantiate resultante.
Try:
Config resultante = new Config(dada.tabela.clone());
or
Config resultante = new Config(Arrays.copyOf(dada.tabela, dada.tabela.length));
This question already has answers here:
What's the simplest way to print a Java array?
(37 answers)
Closed 6 years ago.
I'm trying to write a class that returns a String to the main method. The String is supposed to contain 6 randomly generated numbers from 1-99, and the numbers are supposed to be sorted before they are returned. However it doesn't work at all and I've been sitting all day trying to figure this out. I am new to Java and would prefer to just give it up but it's a class at my university. The code looks like this:
package lab1;
import java.util.Random;
import java.util.Scanner;
public class Lab111 {
private String rad;
public String getLottorad() {
Random r = new Random();
int[] tal = new int[6];
for (int i = 0; i < 6; i++) {//generating 6 numbers
tal[i] = r.nextInt(99)+1;
}
int i,j,crap;
for(i=0;i<100;i++) //trying to sort the generated numbers
for(j=i+1;j<100;j++)
if(tal[i]>tal[j])
{
crap=tal[i];
tal[i]=tal[j];
tal[j]=crap;
}
rad = String.valueOf(tal[i]); /*trying to turn the sorted numbers into an int*/
return rad;
}
public static void main(String[] args) {
System.out.print("How many lottery lines do you want? :");
Scanner tgb = new Scanner(System.in);
int antal = tgb.nextInt();
Lab111 l = new Lab111();
for (int i = 0; i < antal; i++)
System.out.println(l.getLottorad()); // printing the sorted strings
}
}
If someone could explain what I'm doing wrong it would be really appreciated. Me and a classmate that is on my level have been tearing our hair off all day.
You might have to change your code as below.
private String rad;
public String getLottorad() {
Random r = new Random();
int[] vek = new int[10];
for (int i = 0; i < 10; i++) {
vek[i] = r.nextInt(22);
rad = String.valueOf(vek[i]);
}
return rad;
}
public static void main(String[] args) {
System.out.print("How many lottery lines do you want? :");
Scanner tgb = new Scanner(System.in);
int antal = tgb.nextInt();
Lab111 l = new Lab111();
for (int i = 0; i < antal; i++)
System.out.println(l.getLottorad());
}
This question already has answers here:
Cannot make a static reference to the non-static method
(8 answers)
Closed 7 years ago.
This question is based on my former question. How to add a "cheat" function to a Java mastermind game
I added the cheat function to my program, but it cannot compile because of "Cannot Make Static Reference to Non-Static Method"(the old codes works, you can check it through the link I post). Here are my new codes:
import java.util.*;
public class mm {
static int[] random;
public static void main(String[] args) {
System.out.println("I'm thinking of a 4 digit code.");
//update
mm m1 = new mm();
random = m1.numberGenerator();
int exact=0, close=0;
while(exact!=4){
int[] guess= m1.userinput(); //update
exact=0;
close=0;
for(int i=0;i<guess.length;i++){
if(guess[i]==random[i]){
exact++;
}
else if (random[i]==guess[0] || random[i]==guess[1] || random[i]==guess[2] || random[i]==guess[3]) {
close++;
}
}
if(exact==4){
System.out.println("YOU GOT IT!");
}
else{
System.out.println("Exact: "+exact+" Close: "+close);
}
}
}
public int[] userinput() {
System.out.print("Your guess: ");
Scanner user = new Scanner(System.in);
String input = user.nextLine();
//cheater
if (input.equals("*")) {
System.out.format("Cheater!Secret code is:");
for(int i=0;i<random.length;i++){
System.out.print(random[i]);
}
}
int[] guess = new int[4];
for (int i = 0; i < 4; i++) {
guess[i] = Integer.parseInt(String.valueOf(input.charAt(i)));
}
return guess;
}
public int[] numberGenerator() {
Random rnd = new Random();
int[] randArray = {10,10,10,10};
for(int i=0;i<randArray.length;i++){
int temp = rnd.nextInt(9);
while(temp == randArray[0] || temp == randArray[1] || temp == randArray[2] || temp == randArray[3]){
temp=rnd.nextInt(9);
}
randArray[i]=temp;
}
return randArray;
}
}
How to solve this?
You can't call a non-static method directly from a static method. in public static main(String [] args)
To do so, you should first create an object of the class.
try this at main method:
mm m1 = new mm();
random = m1.numberGenerator();
int [] guess = m1.userInput();
this should work
The other option would be to make userinput method static as well
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I just started learning Java required for my course.
Everything seems fine, no syntax errors but when I run my code I have an error
Exception in thread "main" java.lang.NullPointerException
at Deck.<init>(Deck.java:18)
at MainDriver.main(MainDriver.java:17)
Here is my code.
Class Card
public abstract class Card {
public CardValue value;
public CardSuit suit;
CardValue [] cardvalue = CardValue.values();
CardSuit [] cardsuit = CardSuit.values();
public Card () {
value = cardvalue[0];
suit = cardsuit[0];
}
public String toString() {
return this.suit + " of " + this.value;
}
abstract boolean CardCompare(Card P1, Card P2);
}
Class Deck
import java.util.Random;
public class Deck {
Card[] playingCards = new Card[52];
public Deck() {
int cardNumber = 0;
CardValue [] cardvalue = CardValue.values();
CardSuit [] cardsuit = CardSuit.values();
for (int i = 0; i < 4; i++)
{
for(int j = 0; j < 13; j++) //Error here (Deck.java:18)
{
playingCards[cardNumber].value = cardvalue[j];
cardNumber++;
}
playingCards[cardNumber].suit = cardsuit[i];
}
}
public Card draw() {
Random rand = new Random();
int cardDraw = rand.nextInt(52);
return playingCards[cardDraw];
}
}
Class Main
public class MainDriver extends Card{
static final int HANDS = 52;
boolean CardCompare(Card P1, Card P2)
{
if (P1.value.ordinal() > P2.value.ordinal())
return true;
else if (P1.suit.ordinal() > P2.suit.ordinal())
return true;
else return false;
}
public static void main(String[] args) {
Deck player1 = new Deck(); //Some reason there's a error here too (MainDriver.java:17)
Deck player2 = new Deck();
int player1Score = 0, player2Score = 0;
int CardCounter = 0;
while(CardCounter < 52)
{
player1.draw();
player2.draw();
System.out.println(player1 + " " + player2);
CardCounter++;
}
System.out.printf("Final score: Player 1--%d; Player 2--%d", player1Score, player2Score);
}
}
I don't understand why the MainDriver.java:17 is having an error at all. I used abstract in Card because I will also extend it with other class(have not worked on yet) and I will define a different boolean through there. I also have trouble with comparing the cards in the main driver.
I did not include CardValue and CardSuit but they're public enums with suits(Clubs, Diamonds, Hearts, Spades) & values(Two, Three, all the way to Jack, Queen, King, Ace).
If you think you are getting an NPE at this line:
for(int j = 0; j < 13; j++) //Error here (Deck.java:18)
you are mistaken. An NPE at that line is impossible. Nothing in that particular line uses reference types in any way.
Check that you have recompiled all of your code and that the version of the source code matches the compiled classes that you are using.
If we allow for your mistake with building / running, then #Eran has identified a plausible cause of the NPEs.
It's more likely the error is here :
playingCards[cardNumber].value = cardvalue[j];
since you never assign a new Card to playingCards[cardNumber], which is null.
Change your loop to :
for (int i = 0; i < 4; i++)
{
for(int j = 0; j < 13; j++)
{
playingCards[cardNumber] = new Card ();
playingCards[cardNumber].value = cardvalue[j];
cardNumber++;
}
playingCards[cardNumber].suit = cardsuit[i];
}
Also change
public abstract class Card
to
public class Card
Since you can't instantiate an abstract class.
I've been trying to make this method for the deck to deal, but once it deals 52 cards it goes onto an infinite loop.
I am aware this is because I have it to generate a random number until it gets a card that has not been set, but once all cards are set, the condition will never be true, therefore infinite loop.
Even though I know my problem, I don't know how to fix it. I've been trying for hours. I want to throw an exemption once it reaches 52 cards, but it never reaches that if statement once it goes into infinite loop.
public PlayingCard deal() {
Random swift = new Random();
int index = swift.nextInt(DECK_SIZE);
cardsInDeck = DECK_SIZE;
int i = 51;
while (this.deck[index] == false||i==cardsInDeck) {index = swift.nextInt(DECK_SIZE);}
if(i==cardsInDeck) { throw new RuntimeException("Empty Deck");}
PlayingCard.CardRank[] Ranking = PlayingCard.CardRank.values();
PlayingCard.CardSuit[] Suiting = PlayingCard.CardSuit.values();
PlayingCard.CardRank Rank = Ranking[index % 13];
PlayingCard.CardSuit Suit = Suiting[index % 4];
PlayingCard selected = new PlayingCard(Suit, Rank);
this.deck[index] = false;
i++;
cardsInDeck--;
return selected;
}
=============================================================================
the whole code
import java.util.Random;
public class DeckOfCards {
public static final int DECK_SIZE = 52;
//Instance Variables
private boolean[] deck; //An implicit set of 52 Playing-Cards
private int cardsInDeck;//Number of cards currently in the deck
private Random dealer; //Used to rendomly select a card to be dealt
//Constructor
public DeckOfCards() {
this.deck = new boolean[DECK_SIZE];
int index = 0;
for (PlayingCard.CardSuit Suit : PlayingCard.CardSuit.values()) {
for (PlayingCard.CardRank Rank : PlayingCard.CardRank.values()) {
PlayingCard card = new PlayingCard(Suit, Rank);
deck[index] = true;
index++;
}
}
}
//Collect all 52 Playing-Cards into the deck
public void shuffle() {
/*Random shuffle = new Random();
for (int j = 0; j < this.deck.length; j++) {
int k = shuffle.nextInt(this.deck.length);
boolean temp = this.deck[j];
this.deck[j] = this.deck[k];
this.deck[k] = temp;*/
int index = 0;
for (PlayingCard.CardSuit Suit : PlayingCard.CardSuit.values()) {
for (PlayingCard.CardRank Rank : PlayingCard.CardRank.values()) {
PlayingCard card = new PlayingCard(Suit, Rank);
deck[index] = true;
index++;
}
}
}
//Simulate dealing a randomly selected card from the deck
//Dealing from an empty deck results in a RuntimeException
public PlayingCard deal() {
Random swift = new Random();
int index = swift.nextInt(DECK_SIZE);
cardsInDeck = DECK_SIZE;
int i = 0;
while (this.deck[index] == false&&i>0) {index = swift.nextInt(DECK_SIZE);}
if(i>cardsInDeck) { throw new RuntimeException("Empty Deck");}
PlayingCard.CardRank[] Ranking = PlayingCard.CardRank.values();
PlayingCard.CardSuit[] Suiting = PlayingCard.CardSuit.values();
PlayingCard.CardRank Rank = Ranking[index % 13];
PlayingCard.CardSuit Suit = Suiting[index % 4];
PlayingCard selected = new PlayingCard(Suit, Rank);
this.deck[index] = false;
i++;
cardsInDeck--;
return selected;
}
==================================================================
public static void main(String[] args) {
DeckOfCards myDeck = new DeckOfCards();
myDeck.shuffle();
for (int p = 1; p <= 4; p++) {
for (int c = 1; c <= 13; c++) {
System.out.print(myDeck.deal() + " ");
}
System.out.println();
}
try {
System.out.println(myDeck.deal());
} catch (RuntimeException rte) {
System.out.println(rte.getMessage());
}
}
}
I've been trying to make this method for the deck to deal, but once it deals 52 cards it goes onto an infinite loop.
The easy way to deal a deck of cards is to:
Place all cards in an ArrayList.
Call Collections.shuffle() on that list;
Deal out the cards in the order in which they appear in the shuffled list.
The code will be a lot simpler than what you have right now, and will be much easier to debug.
have you tried something like this in the while
while ((this.deck[index] == false||i==cardsInDeck)&&i<52)
?
Once you start picking random indexes, it is too late. You need to test whether the deck has any cards first.
if (cardsInDeck <= 0) ...throw an exception?...
while (this.deck[index] == false) {index = swift.nextInt(DECK_SIZE);}
You need to initialize cardsInDeck correctly (set to DECK_SIZE not in deal but in shuffle and the constructor). You want the invariant that cardsInDeck is equal to the number of indexes for which deck[index]==true.