Comparison logic not working - java

I have a 9 names that I need to display in a rotation sequence. Like the image:
rotation schedule
As you can see, the names go one position down in the list, with the 9th name taking top of it at each rotation.
The variable that controls the rotation is the integer iName. Theres a method that just reads an user input (an imagebutton touch) and adds or decreases the value of iName. It starts at 0 (list is displayed Adams to Ida), and when the user gives the command it assumes 1 (so the list is displayed from Ida to Henry).
Actually, the user can go back in time and turn iName from 5 to 4, so the list changes from Easy-Denver, to Frank-Easy.
I have 9 TextViews doing this job, and it's updated inside a loop, as follows:
int[] arrNames_Ids = {R.id.Name1, R.id.Name2, R.id.Name3, R.id.Name4, R.id.Name5, R.id.Name6, R.id.Name7, R.id.Name8, R.id.Name9};
String[] arrPeople = new String {"Adams","Boston","Chicago","Denver","Easy","Frank","George","Henry","Ida"}
String sAlternative_Name = "";
for (iCounter = 0; iCounter < 9; iCounter++){
// iName is a global variable, stars at 0, but it changes upon user request:
sName = arrPeople[iName];
// this "if" statement is the problematic piece of code.......
if (((iCounter == 1)||(iCounter == 3)||(iCounter == 5))&& (sName.equals("Adams")){
sAlternative_Name = mtAlternative_Name();
sName = sAlternative_Name;
} else {
if ((sAlternative_Name != "") && (sName.equals(sAlternative_Name))){
sName = "Adams";
}
}
// without the previous "if" the following part works properly, so the list rotates accordingly;
tvNames = (TextView) getView().findViewById(arrNames_Ids[iCounter]);
tvNames.setText(sName);
iName = iName + 1;
if (iName > 8){
iName = 0;
}
}
public String mtAlternative_Name(){
int iCycle;
String sName_Aux = "";
// iCurrent_Cycle is a global variable, assumes values from 0 to 73, and it controls the order in which arrPeople is supposed to be shown:
iCycle = iCurrent_Cycle % 18;
switch (iCycle){
case 1: sName_aux = "George"; break;
case 3: sName_aux = "Easy"; break;
case 5: sName_aux = "Chicago"; break;
case 10: sName_aux = "Henry"; break;
case 12: sName_aux = "Frank"; break;
case 14: sName_aux = "Denver"; break;
}
return sName_Aux;
}
The idea is to prevent "Adams" from occupying the positions 1, 3 and 5.
Everytime he's in those positions someone else (sAlternative_Name) takes the place, and "Adams" goes to the position that person was supposed to take.
The array arrPeople doesn't change, example:
If "Adams" was supposed to be in position 4, "Easy" takes the place and "Adams" goes to position 8.
But when the list rotates agains (going foward), "Adams" takes position 5 and "Easy" takes position 9.
I'm new to Java and don't have much experience in programming either, but I can't see what's wrong with this code...
The % operator I use it's to make the names in green to take place in "Adams" position. As you can see, "Boston" and "Ida" are not in the game... but were supposed to be......... this is ok, and I'll manage to think something later, but right now I'd wish I could understand why my code isn't working...
Thanks a lot...

The logic I used is that created a 2 dimensional array that held the entire round table (Without Adams being removed from positions 1,3 or 5). Then, another nested loop is run to substitute "Adams" in each row with "Chicago". Finally, the 2 dimensional array is printed. This gives you the output.
(I took Chicago as the alternate name instead of Easy because at times, Easy can also be at position 1,3 or 5 with respect to Adam's position so the interchange would still cause the exception to persist.)
String[] arrPeople={"Adams","Boston","Chicago","Denver","Easy","Frank","George","Henry","Ida"};
String[][] roundtable=new String[9][9];
int i,j,p;
for(i=0;i<9;i++){
p=i;
for(j=0;j<9;j++){
roundtable[i][j]=arrPeople[p++];
if(p==9)
p=0;
}
}
for(i=0;i<9;i++){
for(j=0;j<5;j+=2){
if(roundtable[i][j].equals("Adams")){
roundtable[i][j+2]="Adams";
roundtable[i][j]="Chicago";
break;
}
}
}
for(i=0;i<9;i++){
for(j=0;j<9;j++)
System.out.print(roundtable[i][j]+"\t");
System.out.println("\n");
}

Related

comparing the value of each round of a for loop?

Is there a way to grab the resulting number from each iteration of this loop and compare it to the next?
This is a Slot Machine Sim in Java,
I'm trying to find a way to see how many of the results match.
so I thought I would capture the number that is resulted from each round of the For loop and compare it to the previous one.
but I have no idea how to write that?
is there a better way to do this?
what I have so far:
for (int count=1; count<= 3 ; ++count)
{
number = slotM.nextInt(6);
switch (number)
{
case 0:
System.out.print("-cherries-");
break;
case 1:
System.out.print("-Oranges-");
break;
case 2:
System.out.print("-Palms-");
break;
case 3:
System.out.print("-Bells-");
break;
case 4:
System.out.print("-Melones-");
break;
default:
System.out.print("-Bars-");
break;
}
System.out.print(number);
}
Yep there are several better ways. If you have a fixed number of options (6 in your case) an enum might be a good option:
enum Picture {
CHERRIES, ORANGES, PALMS, BELLS, MELONS, BARS;
public String getName() {
return "-" + name().substring(0, 1) + name().substring(1).toLowerCase() + "-";
}
That way you can store your numbers as pictures rather than numbers.
Picture pictures[3];
Random random = new Random();
for (int i = 0; i < pictures.length; i++)
picture[i] = Picture.values[random.nextInt(pictures.length)];
To get the printed version:
for (Picture picture: picture)
System.out.print(picture.getName());
You’ll need some kind of storage outside of the loop so that each iteration can reference it.
int[] results Look in to arrays - you can put the results of each round into a part of the array, and look up the value.
You are declaring your count variable in the for loop, just declare outside and make a comparison with it

How to make method that operates on tab with variable amount of rows?

I'm making game, and the game is based on shuffled tab[] of Integers. Every level of game takes array with different parameters (scope of numbers is changing) and an integer for let's say length of level. For now, I made arrayFatory class which makes that arrays with given parameters.
In code there are made 6 levels and they are represented by 6 arrayFactory objects which are assigned to currentArray. The currentArray is an array chosen to be "the current for that level" by switch case. And the cases are integers determining length of levels.
array1 = new RandomArrayFactory(3, 100);
array2 = new RandomArrayFactory(101, 200);
array3 = new RandomArrayFactory(201, 310);
array4 = new RandomArrayFactory(396, 720);
array5 = new RandomArrayFactory(721, 999);
array5 = new RandomArrayFactory(1000, 1310);
array6 = new RandomArrayFactory(1396, 2000);
switch (scoreCount) {
case 0:
progressScope = 13;
currentArray = array1.getNumbertab();
break;
case 13:
progressScope = 31;
currentArray = array2.getNumbertab();
break;
case 44:
progressScope = 56;
currentArray = array3.getNumbertab();
break;
case 100:
progressScope = 106;
currentArray = array4.getNumbertab();
break;
case 206:
progressScope = 214;
currentArray = array5.getNumbertab();
break;
case 420:
progressScope = currentArray.length;
currentArray = array6.getNumbertab();
break;
}
as you can see there is a lot of hardcoded variables and this is what I want to change. I would like to have kind of class with constructor that takes tab with scopes for every level and "progressScope" int, which I could use in place where currentArray is doing it's job.
And it is possible for me only when there is final amount of levels, then I could just copy that switch statement to my new class and return tab and int. But I would like to have possibility of defining new levels on as simple way as I can, I believe the simplest way would be the constructor that takes tab[][][] parameter, two first are values for arrayScope and second one for progressScope.
But how to make body of method so flexible to carry variable amount of levels to create? Or maybe my thinking is totally wrong and I should made it totally different? I'm not looking for specific answers, rather some tips or conceptions
To be able to add/remove any new levels, you should replace the switch with hardcoded values by a loop with a Collection.
Actually you choose a level according to the score count and you associate some information to your level (progressScope, numberTab).
This approach seems to have a drawback. It supposes that the actual score reaches exactly the score associated to each level. But how to handle if the current score exceeds a score corresponding to a level without never be equal to ?
So a switch that performs a perfect matching (equals) is so maybe not the more suitable solution.
As alternative, I propose you to define a List of Level ordered by descending score where Level will contain all information to represent a Level (core level data but also side but useful information as progressScope, numberTab and requiredScore).
You could create your levels in this way :
List<Level> levels = new ArrayList<>();
levels.add(new Level(3, 100, 0, 13));
levels.add(new Level(201, 310, 13, 31));
and introduce a method to retrieve a Level "matching" to a score:
public Level findLevel(List<Level> levels, int score) {
for (Level level : levels) {
if (score >= level.getRequiredScore()) {
return level;
}
}
throw new RuntimeException("should not come here !");
}
Now you can invoke it:
Level currentLevel = findLevel(levels, currentScore);
progressScope = currentLevel.getProgressScope();
currentArray = currentLevel.getCurrentArray();

Converting a recursive method into a non-recursive method using loop in java

So I'm currently making a game where the instructions are to move left or right within an array using the integer stored at a marked index (circle in this case) until we can get the circle to the last index of the array. The last integer of the array is always 0.
For example,
[4] 1 2 3 1 0, here we start at the circle 0 (index)
We move 4 to the right, 4 1 2 3 [1] 0
Then 1 time to the right, 4 1 2 3 1 [0]. Here the game stops and we win.
My code is as follows for a recursive method:
public static boolean rightWing (int circle, int[] game, List<Integer> checkerList){
int last = game.length-1;
if (circle == last){ // base case for recursion
return true;
}
if (circle < 0){ // if we go out of bounds on the left
return false;
}
if (circle > last){ // if we go out of bounds on the right
return false;
}
if (checkerList.contains(circle)){ // check for the impossible case
return false;
}
checkerList.add(circle); // adds the circle value for the last check to checkerList so we can check for the impossible case
int moveRight = circle + game[circle]; // these two integers help the game move according to the value of the int at circle
int moveLeft = circle - game[circle];
return rightWing( moveRight, game, checkerList) || rightWing(moveLeft, game,checkerList);
}
This works great, but the only problem is it's recursive and slow. I'm trying to redesign it using loops and stacks/queues to make it more efficient, but I'm stuck after writing this (in pseudo):
Boolean rightWing (int circle, List<int> game, List<int> checkerList)
Int lastPlace = game.size() - 1
For int i <- 0 to game.size() - 1 do
If i equals lastPlace then // returns true when i is at the last position of the game
Return true
Any input on how to go forward would be appreciated!
The most important bit: when debugging app for the slowness, you should collect some performance data first to identify where your app is spending the most of its time. Otherwise fixing performance is inefficient. You can use jvisualvm it's bundled with jdk.
Data structures rule the world of performance
One thing why it can be slow is because of this:
if (checkerList.contains(circle)){ // check for the impossible case
return false;
}
The more items you have in the list, the slower it becomes. List has linear complexity for the contains method. You can make it constant complexity if you'll use HashSet. E.g. if you have list with 100 elements, this part will be around slower 100 times with List than with HashSet.
Another thing which might be taking some time is boxing/unboxing: each time you put element to the list, int is being wrapped into new Integer object - this is called boxing. You might want to use IntSet to avoid boxing/unboxing and save on the GC time.
Converting to the iterative form
I won't expect this to affect your application speed, but just for the sake of completeness of the answer.
Converting recursive app to iterative form is pretty simple: each of the method parameters under the cover is stored on a hidden stack on each call of your (or others function). During conversion you just create your own stack and manage it manually
public static boolean rightWingRecursive(int circle, int[] game) {
Set<Integer> checkerList = new HashSet<Integer>();
Deque<Integer> statesToExplore = new LinkedList<>();
int last = game.length - 1;
statesToExplore.push(circle);
while (!statesToExplore.isEmpty()) {
int circleState = statesToExplore.pop();
if (circleState == last) { // base case for recursion
return true;
}
if (circleState < 0) { // if we go out of bounds on the left
continue;
}
if (circleState > last) { // if we go out of bounds on the right
continue;
}
if (checkerList.contains(circle)) { // check for the impossible case
continue;
}
checkerList.add(circle); // adds the circle value for the last check to
// checkerList so we can check for the
// impossible case
int moveRight = circle + game[circle]; // these two integers help the
// game move according to the
// value of the int at circle
int moveLeft = circle - game[circle];
statesToExplore.push(moveRight);
statesToExplore.push(moveLeft);
}
return false;
}

Select value from arraylist based on its percentage [duplicate]

This question already has answers here:
How to pick an item by its probability?
(13 answers)
Closed 6 years ago.
I got an arraylist of objects. Each objects got 2 values, content and weight. content is just a simple string while weight decides the percentage of how often the string should be used.
If I have 2 objects in the array:
Object 1:
content: hello
weight: 20
Object 2:
content: hey
weight: 80
First objects content should be used 20% of times while the second objects content should be used 80% of all times.
How would I decide which content gets selected based on the weight?
I got the following code so far:
foreach (ContentModels cont in match_array)
{
if (match_array.Count == 1)
{
match = cont.content;
break;
}
}
which pretty much selects the first content if the arraylist only contains one object but I don't know what do to if there are more than one objects?
Alright, I wanted to take a stab at this without looking at someone else's code. Here's what I came up with.
Btw, I hope it was the Java tag that was in error and not the C# tag :D.
Here's the entire program. What follows below is an explanation of each piece
.NET Fiddle
I chose to take each element to be a portion in a ratio. Therefore, in your example, your total is 100 (20 + 80) meaning that the 20 content model should get chosen 20% of the time. If you want to constrain your content models such that their total weights add up to 100, that should be done at the time that you create them.
So here's my solution.
First the content models:
class ContentModel
{
public string Content { get; set; }
public int Weight { get; set; }
}
And then a list of test cases:
static List<ContentModel> contentOptions = new List<ContentModel>
{
new ContentModel
{
Content = "hello",
Weight = 20
},
new ContentModel
{
Content = "hey",
Weight = 80
},
new ContentModel
{
Content = "yo dawg",
Weight = 90
}
};
Given these test cases we would expect to see 'Hello' appear about 10.5% of the time (20 / (80 + 90 + 20)) * 100. And so on for the rest of the test cases.
Here's the generator that makes that happen:
Here all we're going to do is figure out what the total weight is that we're working with. Then we're going to pick a random number and go through each model asking "Is this number from this content model?" If no, then subtract that content model's weight and move to the next one until we get to a model where the selection - weight is < 0. In this case we have the model that was chosen. I hope that makes sense.
(Note: I chose to recalculate the total weight every time in case you change the source list of options. If you make that list readonly, then you could move that .Sum() call outside the while loop.)
static IEnumerable<string> GetGreetings()
{
Random generator = new Random();
while (true)
{
int totalWeight = contentOptions.Sum(x => x.Weight);
int selection = generator.Next(0, totalWeight);
foreach (ContentModel model in contentOptions)
{
if (selection - model.Weight > 0)
selection -= model.Weight;
else
{
yield return model.Content;
break;
}
}
}
}
And finally, here's the main method which will also test this whole thing:
static void Main(string[] args)
{
List<string> selectedGreetings = new List<string>();
/* This will get 1000 greetings,
* which are the Content property of the models, group them by the greeting,
* count them, and then print the count along with the greeting to the Console.
*/
GetGreetings()
.Take(1000)
.GroupBy(x => x)
.Select(x => new { Count = x.Count(), Content = x.Key })
.ToList()
.ForEach(x => Console.WriteLine("{0} : {1}", x.Content, x.Count));
Console.ReadLine();
}
Here are my results from a run through:

Need to show random picture for behaviour

Please, forgive my ignorance, as I am new to Java programming. However, I need to show a picture (at random) for each of the three behaviours listed, below. Each picture has a designated image - What would be the best method to do so?
String whatsUp()
{
double r;
int myNumber;
String behaviour="";
r = Math.random();
myNumber = (int) (r * 3.0)+1;
switch(myNumber)
{
case 1:
behaviour = "reading";
break;
case 2:
behaviour = "surfing the web";
break;
case 3:
behaviour = "interacting with other students";
break;
}
return behaviour;
}
}
First of all, your process to get a random number doesn't make a lot of sense. What you'll want to to is create a new random object "r":
Random r = new Random();
Then you can use this object to create a random number from zero to a certain index. In your case this would be three.
int randomNumber = r.nextInt(index); //replace index with three
However, this would give the numbers 0, 1, and 2 so you will want to add one to the number.
int randomNumber = r.nextInt(index) + 1;
This will now give you a random number from one to three.
To get three images into the system you could use ImageIcon or similar method, which I will let you figure out for yourself.
I would then put the ImageIcons inside an ArrayList so that they can be easily accessed like so:
ArrayList<ImageIcon> images = new ArrayList<ImageIcon>();
images.add(imageOne);
images.add(imageTwo);
images.add(imageThree);
Thus, when inside case 1, 2, or 3 you could have a reference to the ArrayList you created with the first random number you you created like this
selectedImage = images.get(r); // the random number acts as the index
This will not display any image; you will have to work out how to do that yourself, but hopefully this gives you a good idea of where to go from here.

Categories