Need Help sorting out nested for loops - java

I'm trying to make a trivia game for my English class that will randomly pick a question, but will not pick the same one twice. I currently have a prototype set up, but I can't figure out what is going wrong that is preventing it from actually printing the questions.
Here's the behemoth:
import java.io.*;
import java.util.*;
public class qpicker
{
public static void main (String args[])
{
int qs = 0;
boolean q1checker, q2checker, q3checker, q4checker, q5checker,
q6checker, q7checker, q8checker, q9checker, q10checker, q11checker,
q12checker,q13checker, q14checker, q15checker, q16checker, q17checker,
q18checker, q19checker, q20checker; //this disaster is where i declared my
q1checker = false; //booleans
q2checker = false;
q3checker = false;
q4checker = false;
q5checker = false;
q6checker = false;
q7checker = false;
q8checker = false;
q9checker = false;
q10checker = false;
q1checker = false;
q12checker = false;
q13checker = false;
q14checker = false;
q15checker = false;
q16checker = false;
q17checker = false;
q18checker = false;
q19checker = false;
q20checker = false; //here i tried to set all booleans to false,
//thinking maybe that was the issue
do
{
qs++;
Random random = new Random();
double rng = random.nextDouble();
double selecter = rng * 10;//makes the random number easier to read
if(rng <=.5)
{
if(q1checker = false)
{
System.out.println("Put first q in here");
q1checker = true;
break;
}
}
System.out.print("cheese");//code progress tracker
if(rng <=1 && rng >.5)//this is where the question would be pulled
{
if(q2checker = false)//this ensures questions aren't repeated
{
System.out.println("Put second q in here");//display quest.
q2checker = true;
break;
}
}
System.out.print("e");
if(rng <=1.5 && rng > 1)//question picked
{
if(q3checker = false)//ensures questions aren't repeated
{
System.out.println("Put third q in here");//display quest.
q3checker = true;
break;
}
}
System.out.print("y");
if(rng <=2 && rng > 1.5 )
{
if(q4checker = false)
{
System.out.println("Put fourth q in here");
q4checker = true;
break;
}
else if (q4checker = true)
{continue;}
System.out.print(" ");
}if(rng <=2.5 && rng > 2)
{
if(q5checker = false)
{
System.out.println("Put fifth q in here");
q5checker = true;
break;
}
}
System.out.print("good");
if(rng <=3 && rng > 2.5)
{
if(q6checker = false)
{
System.out.println("Put sixth q in here");
q6checker = true;
break;
}
}
System.out.print("ness");//spells out "cheesey goodness" 20 times
}while (qs < 20);//ensures all questions are printed (in final product)
}
}

static void shuffleArray(string[] ar)
{
//set the seed for the random variable
Random rnd = ThreadLocalRandom.current();
//go from the last element to the first one.
for (int i = ar.size()- 1; i > 0; i--)
{
//get a random number till the current position and simply swap elements
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
This way you shuffle the entire array and get the values in a random order but NO duplicate at all. Every single element changes position, so that no matter what element (position) you pick, you get a country from a random position. You can return the entire vector, the positions are random.
You could try this method, for shuffling your array and returning the entire array in random order since it mixes the elements.

From what I see you are trying to allow them to choose questions until they are exhausted, choosing randomly. You can do this easily with an ArrayList, where you pick randomly an index from the list to pull your question, remove the question from your list, so it is no longer available to choose from. Note that after you remove and use it from the list, the list will be smaller by 1
String[] questionArray = ["Question 1","Question 2","Question 3","Question 4","Question 5"];
ArrayList<String> questionList = Arrays.asList(questionArray);
//Get a random number within the range of 0..questionList.size()
int chosenIndex = 1; //Made up for simplicity
String chosen = questionList.remove(chosenIndex);
//Now that you have chosen a question, and it was removed from the list
//The list is one element smaller. Next time you get a random number
//make sure you use the range: 0..chosen.size()
System.out.println(chosen);
I believe this is what you are looking for.

You should use arrays.
Also remember that = is an assignment operator while == is comparation
This:
if(rng <=.5)
{
if(q1checker = false)
Is wrong, it should be:
if(rng <=.5)
{
if(q1checker == false)
Or better:
if(rng <=.5)
{
if(!q1checker)

Related

Why does my method overwrite positions in my array

So I have this method here
while(oMenu == 1 || oMenu == 2){
oMeny = Kbd.readInt("\nClick 1 to make an account\nClick 2 to login\nClick 3 to exit the program");
if(oMeny == 1){
for(int i = 0; Account[i] != null; i++){
if(Account[i] == null){
pos = i;
}
}
Account[pos] = new Account();
}
if(oMeny == 2){
String s = Kbd.readString("Input your accountnumber: ");
for(int i = 0; Account[i] != null; i++){
if(Account[i] != null && s.equals(Account[i].getAccountNumber())){
System.out.println("Welcome!");
// Here is rest of my code , the "inner" menu that works menyMetod(iMeny,mMeny);
}
else{
System.out.println("There are no accounts with that given accountnumber!");
}
}
}
}
}
I want to understand why if I access the oMeny == 1 and make 2 accounts Why I can't seem to access the first one I make but rather the latest one? It seems that somehow my array "overwrites" the first empty position. Basically I want to find the first empty position in my array, so in the first case it's always index 0 and then the next time I make an account again, it should be Index 1 logically.
EDIT : Heres my code for the Account class
public class Account{
private int money, transactions;
private String AccountNumber;
public Account(){
money = Kbd.readInt("\nHow much money do you want to put in?");
AccountNumber = Kbd.readString("\nWhat account number do you want?");
}
The error is here:
for (int i = 0; accounts[i] != null; i++) {
if (accounts[i] == null)
The for loop repeats as long i points to a non-null entry. Therefore the if-condition is never true.
This becomes quickly obvious when you run the program line by line in a debugger.
Next time please provide a complete code example that can be compiled. Your code is full of error, It took me a lot of time to fix it before I was able to execute it.
Corrected code:
import java.util.Scanner;
class Main
{
static Scanner kbd = new Scanner(System.in);
static Account[] accounts = new Account[100];
static class Account
{
//public int money;
public String accountNumber;
public Account()
{
//System.out.println("\nHow much money do you want to put in?");
//money = Kbd.nextInt();
System.out.println("\nWhat account number do you want?");
accountNumber = kbd.next();
}
}
public static void main(String[] args)
{
int oMenu = 1;
int pos = 0;
while (oMenu == 1 || oMenu == 2)
{
System.out.println("\nClick 1 to make an account\nClick 2 to login\nClick 3 to exit the program");
oMenu = kbd.nextInt();
if (oMenu == 1)
{
for (int i = 0; i<accounts.length; i++)
{
if (accounts[i] == null)
{
accounts[i] = new Account();
break;
}
}
}
if (oMenu == 2)
{
System.out.println("Input your accountnumber: ");
String s = kbd.next();
Account found=null;
for (int i = 0; i<accounts.length; i++)
{
if (accounts[i] != null && s.equals(accounts[i].accountNumber))
{
found=accounts[i];
}
}
if (found!=null)
{
System.out.println("Welcome! nr. "+found.accountNumber);
}
else
{
System.out.println("There are no accounts with that given accountnumber!");
}
}
}
}
}
Notice how I also fixed the second for-loop.
You did not show the declaration or initialization of pos, so I think it is not working how you expect because you do not go into the for loop where Account[i] is null to set pos. Try this
if(oMenu == 1){
int pos = 0;
while (Account[pos] != null && pos < Account.length)
pos++;
if (pos < Account.length)
Account[pos] = new Account();
else{
//expand array and add account or throw error
}
}

Finding duplicates in an array of objects

The purpose of this project is to make a pokedex that adds and holds all the pokemon passed in by user input. When the user inputs a pokemon that is already stored in the pokedex the word "duplicate" is supposed to be printed to the console. The word duplicate is printed even though there are no actual duplicates within the object array. Here is my output from the console :
Welcome to your new PokeDex!
How many Pokemon are in your region?: 3
Your new Pokedex can hold 3 Pokemon. Let's start using it!
List Pokemon
Add Pokemon
Check a Pokemon's Stats
Sort Pokemon
Exit
What would you like to do? 2
Please enter the Pokemon's Species: red
Duplicate
Now here is all the code used that could possibly be making this error
import java.util.Scanner;
public class Project4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to your new PokeDex!");
System.out.print("How many Pokemon are in your region?: ");
int size = input.nextInt();
Pokedex pokedex = new Pokedex(size);
System.out.println("\nYour new Pokedex can hold " + size + " Pokemon. Let's start using it!");
int choice = 0;
boolean done = false;
while (!done) {
System.out.println("\n1. List Pokemon\n2. Add Pokemon\n3. Check a Pokemon's Stats" + "\n4. Sort Pokemon\n5. Exit");
System.out.print("\nWhat would you like to do? ");
choice = input.nextInt();
switch (choice) {
case 1:
String[] pokemonList = pokedex.listPokemon();
if (pokemonList == null)
System.out.println("Empty");
else
for (int i = 0; i < pokemonList.length; i++) {
System.out.println((i + 1) + ". " + pokemonList[i]);
}
break;
case 2:
System.out.print("\nPlease enter the Pokemon's Species: ");
String species = input.next();
pokedex.addPokemon(species);
break;
}
}
}
}
In the following class I have the actual method that adds the pokemon and the constructor for Pokedex
public class Pokedex {
Pokemon[] pokedex;
String pokeArray[];
public Pokedex(int size) {
pokedex = new Pokemon[size];
pokeArray = new String[size];
}
public boolean addPokemon(String species) {
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++) {
if (pokedex[i] == null) {
pokedex[i] = stuff;
}
else if (i < pokedex.length && pokedex[i] != null) {
System.out.println("Max");
}
if (pokedex[i].getSpecies().equalsIgnoreCase(species)) {
System.out.print("Duplicate");
break;
}
}
return false;
}
}
Sorry for the mass amounts of code I just need help tracing where this unexpected result is coming from.
The reason it's doing that is because of this bit of code here:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if (pokedex[i] == null)
pokedex[i] = stuff;
else if (i < pokedex.length && pokedex[i] !=null)
System.out.println("Max");
if(pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.print("Duplicate");
break;
}
}
return false;
}
The problem is just a little bit of syntax missing. In your for loop, you check to see if
A) there are any empty spots in the array
B) if every element in the array up to the user inputted size is full
and C) if any element in the array matches the one we're trying to add.
The problem you're encountering is because your C is an if instead of an else if. Because A sees the index is null, it assigns the new Pokemon to the Pokedex. Then because C is an if instead of an else if, it runs after you assign the new Pokemon and sees the Pokemon we just added and says it's a duplicate. Changing it to an else if would fix this.
Also, since there was no break; in A, it would assign every element of the array to the first one entered, causing any further additions to call Max. I edited the code and this is what I had that worked for me:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if(pokedex[i] !=null && pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.println("Duplicate");
break;
}
else if (pokedex[i] == null)
{
pokedex[i] = stuff;
break;
}
else if(i + 1 == pokedex.length)
{
System.out.println("Max");
break;
}
}
return false;
}
Also, out of curiosity, why is the addPokemon() function a boolean? You return a value (albeit arbitrarily) and then never do anything with that value. You could just make it a void, have it return nothing, and it would work just as fine.

traversing a 2d array and adding indexs to a stack

I have a project for school to take my current pacman program and have pacman traverse the 2-d char array to find a pattern to complete the maze.
I am trying to use a stack and add specific index of my maze to the stack so when pacman reaches the index it pops off and he chooses a direction randomly to another index and so forth until all dots are eaten. My issue is taking my 2d array and finding the index values of the intersections and then adding them to a stack.
I am new to java and not really sure how to approach this I posted my maze I have and some code that will use the stack to find the sequence. Thanks in advanced.
private void create() {
String[] tier = new String[tall];
tier[0] = "|======================================|";
tier[1] = "|......................................|";
tier[2] = "|.====.==========================.====.|";
tier[3] = "|.||||............................||||.|";
tier[4] = "|.====.==========================.====.|";
tier[5] = "|......................................|";
tier[6] = "|.====================================.|";
tier[7] = "|......................................|";
tier[8] = "|.====.======.====----====.======.====.|";
tier[9] = "|.||||........|| ||........||||.|";
tier[10] = "|.||||.======.|| ||.======.||||.|";
tier[11] = "|.||||........|| ||....... ||||.|";
tier[12] = "|.====.======.============.======.====.|";
tier[13] = "|......................................|";
tier[14] = "|.===========..............===========.|";
tier[15] = "|.............===== =====.............|";
tier[16] = "|.=======.===.||$ $||.===.=======.|";
tier[17] = "|.|||||||.===.===== =====.===.|||||||.|";
tier[18] = "|.|||||||......................|||||||.|";
tier[19] = "|.|||||||.====================.|||||||.|";
tier[20] = "|.=======......................=======.|";
tier[21] = "|.==......====================......==.|";
tier[22] = "|.==.====.======........======.====.==.|";
tier[23] = "|....====........======........====....|";
tier[24] = "|======================================|";
for (int i = 0; i < tall; i++) {
array[i] = tier[i].toCharArray();
}
}
public boolean isPattern(Spot b, Spot e) {
Stack<Spot> ss = new Stack<Spot>();
Spot topPost, nextPost;
allOld();
ss.push(b);
markOld(b);
topPost = ss.peek();
while (!ss.empty() && (topPost.compareTo(e) != 0)) {
nextPost = getNextSpot(topPost);
if (nextPost == null) {
ss.pop();
} else {
ss.push(nextPost);
markOld(nextPost);
}
topPost = ss.peek();
}
if (ss.empty()) {
return false;
} else {
return true;
}
}
public void index(int x, int y, int dx, int dy){
x=array.length;
y=array[x].length;
for( int i=0;i <x;i++){
for(int j =0; j<y;j++){
if(array[i].get(i))//this should determine if its aninersection and then add to the stack
}
}
}
}
the last method is where i am getting stuck. I dont know how to get the specific index values. I guess i can enter them manually but I am sure there is an easier way. Please comment if need more context on the problem and Thanks again.

Optimal Algorithm: how to stop my if statement when I don't find the number that matches with my number that I am going to replace it with

I am doing FIFO LRU and Optimal. I have a problem for Optimal ( replace it with the one that we will not use in the longest time, so the furthest one). I got it to replace my fram number with the one that i dont use in the longest. But the problem is that when the number that i want to replace it with doesn't even exist HOW DO I STOP MY IF statesman? And im not sure which "if" to stop? i tried this:
public int toss( int pr )
{
// if we get the same number just return -1
for (int s=numberOfFrames-1; s>=0; s--)
{
// if we get the same number dont kick anything
if ( pr == fram[s])
{
return -1;
}
}
// find which frame to replace
int look2 = 0; // this is the co for the number you want to replace with.
// next time it is used.
int co = 0; // this is index to pra.
int r = -1;
for ( int d=numberOfFrames-1; d>=0; d--)
{
lookFor(d,r);
}
if (r == -1)
{
//item not found, handle however you want, one suggestion is:
return -1; //have the caller handle this correctly
}
else
{
int q = fram[r]; // remember 2 which is page we are getting raid off
fram[r] = pra[co]; // fram one we want to get raid off and replace it with the pr
return q; // return the one we kicked
}
}
int co = 0;
int look2 = 0;
public int lookFor(int d, int r)
{
for( int f=co; f>=0; f++) // f looping for pra
{
co = tossCallCount++;
System.out.println("here");
if( fram[d] == pra[f])
{
System.out.println("by"+pra[f]);
if(look2<=f)
{
System.out.println("hi"+fram[d]);
r = d;
look2 = f;
break;
}
}
}
return d;
}
}
If you break out of your loop at the place you have the System.exit(0), you will only ever look at pra[co] (because f=co, rather than looping through with pra[f]). You likely want to put the break inside of the if, so when you find the match, you stop this loop. But this will just exit you from the inner for loop, and you probably want to stop looping entirely. See Breaking out of nested loops in Java for more information on breaking multiple loops.
int r = -1;
for ( int d=numberOfFrames-1; d>=0; d--) {
for( int f=co; f>=0; f++) {
if( fram[d] == pra[f]) {
if(look2<=f) {
r = d;
look2 = f;
break;
}
}
}
}
if (r == -1) {
//item not found, handle however you want, one suggestion is:
return -1; //have the caller handle this correctly
} else {
int q = fram[r]; // remember 2 which is page we are getting raid off
fram[r] = pra[co]; // fram one we want to get raid off and replace it with the pr
return q; // return the one we kicked
}

Shrinking the Code

I've got some java code that is used for my games NPCs to move arround.
Those are obviously in an 1d array.
public void route11() {
Scanner in = new Scanner(System.in);
Random number = new Random();
int random = number.nextInt(2);
if(random ==1)
hunters[1].x = hunters[1].x -1;
else
hunters[1].y = hunters[1].y -1;
}
public void Update() {
route11();
route2();
route3();
route4();
route5();
}
Methods route2, route3, ..., route5 look pretty much the same, the only thing that changes is the value of the array to correspond with a different hunter.
Could this code be "shrinked"? Im pretty sure my lecturer will be happy to minus my mark for such a messy and very much anti-OO code.
Also, all my collision/score code looks something like this, and it works for individual hunters:
if(hunters[i].x==0 && hunters[i].y == 0){
hunters[i].x = 11;
hunters[i].y = 11;
Player.score = Player.score + 1;
}
Your issue has nothing to do with OOP design. This is just about learning to use the tools available to write less redundant and more manageable code. If you utilize a for loop in your update and pass each individual hunter then this becomes much more condensed.
I will note that there are some unrelated OOP issues that you would do well to correct.
Hunter's members such as X and Y should not be exposed publicly, utilize getters/setters
The same goes for the Player's score member/field
public void update()
{
for(var i = 0; i < 5; i++)
{
route(hunters[i]);
collisionAndScoring(hunters[i]);
}
}
public void route(Hunter hunter)
{
Scanner in = new Scanner(System.in);
Random number = new Random();
int random = number.nextInt(2);
if(random == 1)
{
hunters.x--;
}
else
{
hunter.y--;
}
}
public void collisionAndScoring(Hunter hunter)
{
if (hunter.x == 0 && hunter.y == 0) //You should define constants for these to give them more meaning
{
hunter.x = 11; //another opportunity for a constant
hunter.y = 11; //another opportunity for a constant
Player.score++;
}
}

Categories

Resources