This site requires JavaScript, please enable it in your browser!
Greenfoot back
ronzhi
ronzhi wrote ...

2013/4/8

non-repeating random number help

1
2
ronzhi ronzhi

2013/4/8

#
Hi,need a little help here i want to create enemies that pop out 5 random questions out of 6 and can't be taken twice while the enemies number and position is fix in the world class i already use random number method but still can be taken twice how do i do this? any help would be appreciated this is my world class
1
2
3
4
5
addObject(new ProEnemy(1), 350, 510);
addObject(new ProEnemy(2), 780, 510);
addObject(new ProEnemy(3), 666, 294);
addObject(new ProEnemy(4), 968, 210);
addObject(new ProEnemy(5), 155, 210);
this is my ProEnemy class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;
import javax.swing.JOptionPane;
import java.awt.Point;
import javax.swing.JDialog;
import javax.swing.JFrame;
 
/**
 * Write a description of class Addition here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class ProEnemy extends Enemies
{
    ...
    ...
    private int number = getRandomNumber(1,6);
    public int newSpot1 = getRandomNumber(120,370);
    public int newSpot2 = getRandomNumber(640,850);
    public int newSpot3 = getRandomNumber(656,868);
    public int newSpot4 = getRandomNumber(440,550);
    public int newSpot5 = getRandomNumber(179,390);
             
    JFrame frame;
     
    public ProEnemy(int voucher)
    {
        ticket = voucher;
    }
     
    public void addedToWorld(World World)
    {
        getPosition();
    }
         
    public void getPosition()
    {
        if(ticket==1)
            setMove(120,370,1,-1);
        if(ticket==2)
            setMove(640,850,1,-1);
        if(ticket==3)
            setMove(656,868,1,1);
        if(ticket==4)
            setMove(968,968,0,-1);
        if(ticket==5)
            setMove(179,390,1,1);   
    }
     
    public void respawn()
    {
         
        if(ticket==1)
            getWorld().addObject (new ProEnemy (1), (newSpot1), 510);
        if(ticket==2)
            getWorld().addObject (new ProEnemy (2), (newSpot2), 510);
        if(ticket==3)
            getWorld().addObject (new ProEnemy (3), (newSpot3), 294);
        if(ticket==4)
            getWorld().addObject (new ProEnemy (4), 968, 210);
        if(ticket==5)
            getWorld().addObject (new ProEnemy (5), (newSpot5), 210);
    }
     
    setMove()
    ..
    ..
 
    public void act()
    {
        animate();
        movement
        ..
        ..
        touchingPlayer();
    }
 
    animate()
    ..
    ..
     
    public boolean touchingPlayer()
    {
        Actor touchingPlayer = getOneObjectAtOffset(0, 0, Player.class);
        if(touchingPlayer != null)
        {
            throwQuestion();
            getWorld().removeObject(this);
        }
        return touchingPlayer!=null;
    }
     
    public int getRandomNumber(int start,int end) 
    
       int normal = Greenfoot.getRandomNumber(end-start+1); 
       return normal+start; 
    }
     
    public void throwQuestion()
    {
        if (number == 1)
        {
            int answer = 0;
            String input = JOptionPane.showInputDialog(null, "1+1 = ?");
            if (input == null)
            {
                errorQuestion();
            }
            else
            {
                try
                {
                    answer = Integer.parseInt(input);
                    if (answer == 2)
                    {
                        JOptionPane.showMessageDialog(frame,"good");
                    }
                    else
                    {
                        int reply = JOptionPane.showConfirmDialog(null, "do you want to retry ?", "wrong answer", JOptionPane.YES_NO_OPTION);
                        if (reply == JOptionPane.YES_OPTION)
                        {
                            throwQuestion();
                        }
                        else
                        {
                            respawn();
                        }
                    }
                }
                catch(Exception ex)
                {
                    errorQuestion();
                }
            }
        }
        ..
        ..
        repeat until number == 6
    }
     
    public void errorQuestion()
    {
        try
        {
            respawn();
        }  
        catch(Exception ex)
        {
 
        }
    }
}
Gevater_Tod4711 Gevater_Tod4711

2013/4/8

#
If you save the values that were already teaken (in an array or some variables) you can check whether the value that you choose was already taken. If it was already taken you try another. You should do this in a loop because in the worst case it'll never be true and that would be an awefull lot of code if you don't do this in a loop.
ronzhi ronzhi

2013/4/8

#
would you please give little example Gevater? have no idea where i put the loop, in the act or addedToWorld?
Gevater_Tod4711 Gevater_Tod4711

2013/4/8

#
I'm not sure but I think the random number you are using is in the constructor. So you have to add this loop whereever the new objects are created.It's not in this class I think.
danpost danpost

2013/4/8

#
An easy way to randomly select 5 out of 6 is by using a simple little trick:
1
2
3
4
5
6
7
8
9
10
11
12
// add this instance field
String options = "123456"; // list of option values for questions
// then, in act or method it calls
if (options.length() > 1)
{
    int opt = Greenfoot.getRandomNumber(options.length())// random shuffle value
    for (int i=0; i<opt; i++) options = options.substring(1)+options.charAt(0); // shuffle
    number = Integer.valueOf(""+options.charAt(0)); // get question number
    options = options.substring(1); // remove question from options
    // throw the question here
}
else // not throwing question anymore (or yet)
It does not matter if 'opt' does not equal 'number' as each question will still have the same chance of being picked at any choosing. 'opt' will actually refer to the position in the 'opts' string, as it is at the moment, that is chosen.
ronzhi ronzhi

2013/4/9

#
thanks danpost,i'll try it out
ronzhi ronzhi

2013/4/9

#
first question often got repeat in last question and sometimes got repeat twice in 3rd and last i put it in method that called when player touch the enemies is it correct?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public void throwQuestion()
    {
        if (options.length() > 1
        
            int opt = Greenfoot.getRandomNumber(options.length());// random shuffle value
            for (int i=0; i<opt; i++)
            options = options.substring(1)+options.charAt(0); // shuffle 
            number = Integer.valueOf(""+options.charAt(0)); // get question number 
            options = options.substring(1); // remove question from options 
            // throw the question here 
            System.out.print(number);
            if (number == 1)
            {
                int answer = 0;
                String input = JOptionPane.showInputDialog(null, "1+1 = ?");
                if (input == null)
                {
                    errorQuestion();
                }
                else
                {
                    try
                    {
                        answer = Integer.parseInt(input);
                        if (answer == 2)
                        {
                            JOptionPane.showMessageDialog(frame,"good");
                        }
                        else
                        {
                            int reply = JOptionPane.showConfirmDialog(null, "do you want to retry ?", "wrong answer", JOptionPane.YES_NO_OPTION);
                            if (reply == JOptionPane.YES_OPTION)
                            {
                                throwQuestion();
                            }
                            else
                            {
                                respawn();
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        errorQuestion();
                    }
                }
            }      
        }
    }
danpost danpost

2013/4/9

#
Your questions should not repeat unless you restore the value of the String 'options'. Unless I see how the rest of your code goes with this, I could not help you.
ronzhi ronzhi

2013/4/9

#
the rest of code is same as my first post with addition of yours in the throwQuestion method i know the questions repetition is a mess,but that's what come to my head at this time any suggestion/improvement would be a great help
danpost danpost

2013/4/9

#
Ther was some code you left out when you put in
1
2
...
...
ronzhi ronzhi

2013/4/9

#
oh sorry, in the throwQuestions method that was for questions 1 until 6 the difference is just the question like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
if (number == 1
        
            int answer = 0
            String input = JOptionPane.showInputDialog(null, "1+1 = ?"); 
            if (input == null
            
                errorQuestion(); 
            
            else 
            
                try 
                
                    answer = Integer.parseInt(input); 
                    if (answer == 2
                    
                        JOptionPane.showMessageDialog(frame,"good"); 
                    
                    else 
                    
                        int reply = JOptionPane.showConfirmDialog(null, "do you want to retry ?", "wrong answer", JOptionPane.YES_NO_OPTION); 
                        if (reply == JOptionPane.YES_OPTION) 
                        
                            throwQuestion(); 
                        
                        else 
                        
                            respawn(); 
                        
                    
                
                catch(Exception ex) 
                
                    errorQuestion(); 
                
            
        }
if (number == 2
        
            int answer = 0
            String input = JOptionPane.showInputDialog(null, "3+7 = ?"); 
            if (input == null
            
                errorQuestion(); 
            
            else 
            
                try 
                
                    answer = Integer.parseInt(input); 
                    if (answer == 10
                    
                        JOptionPane.showMessageDialog(frame,"good"); 
                    
                    else 
                    
                        int reply = JOptionPane.showConfirmDialog(null, "do you want to retry ?", "wrong answer", JOptionPane.YES_NO_OPTION); 
                        if (reply == JOptionPane.YES_OPTION) 
                        
                            throwQuestion(); 
                        
                        else 
                        
                            respawn(); 
                        
                    
                
                catch(Exception ex) 
                
                    errorQuestion(); 
                
            
        }
//until if (number == 6) with different qestions
danpost danpost

2013/4/10

#
You could probably save yourself a lot of anguish and pain by using arrays for your question sets. Declare then as static final Strings using a double array. The major array for the question sets; the minor for the question themselves.
1
2
3
4
5
private static final String[][] Q =
    { { "1+1", "3+7", "5+3", "8+6", "2+4", "9+5" },
      { "4+7", "5+6", "8+8", "7+9", "0+6", "3+4" } };
private int qSet;
private String options = "123456";
I only show two sets of question here, but you can add as many groups of question as you need. I also show the other fields you will need. Use the int field 'qSet' to track which question set you are on, and use one set of code for ALL the questions. Right now, any change you make in one, you have to make in all 6 codings for each question. If you have not worked with arrays before, they are not that difficult to understand. You can refer to any element in the array by 'Q' (ex. Q refers to the fifth question in the second set (remember java starts counting at zero) which is "0+6". With this knowledge, you can see that you can refer to any element by 'Q'. You can also create an array of answer in the same way and check the input responses to the elements in that array. The answer array can be set up exactly the same way as the question array; the only difference being the question array is a String array and the answer array will be an int array.
1
2
private static final int A[][] =
    { { 2, 10, 8, 14, 6, 14 }, { 11, 11, 16, 16, 6, 7 } };
danpost danpost

2013/4/10

#
NVM
ronzhi ronzhi

2013/4/10

#
that's awesome danpost,i got it but how to compare if Q is = A using this double array with your trick before? and i try your code w/o throw question and print the result it still has repeat questions when the opt randomly got same number twice
danpost danpost

2013/4/10

#
The following is not tested, but should be close to what you are looking for. It could probably be the entire body of your 'throwQuestion' method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
if (options.length < 2)
{
    options = "123456";
    qSet++;
    if (qS > 5) qSet = 0; // replace '5' with number of sets of questions you have
}
int opt = Greenfoot.getRandomNumber(options.length())
for (int i=0; i<opt; i++) options = options.substring(1)+options.charAt(0);
number = Integer.valueOf(""+options.charAt(0));
options = options.substring(1);
int reply = JOptionPane.YES_OPTION;
while (reply == JOptionPane.YES_OPTION)
{
    int answer = 0
    String input = JOptionPane.showInputDialog(null, Q[qSet][number]+" = ?"); 
    if (input == null
    
        errorQuestion(); 
    
    else 
    
        try 
        
            answer = Integer.parseInt(input); 
            if (answer == A[qSet][number])
            
                JOptionPane.showMessageDialog(frame, "good");
            
            else 
            
                reply = JOptionPane.showConfirmDialog(null, "do you want to retry ?", "wrong answer", JOptionPane.YES_NO_OPTION);
            }
        }
        catch(Exception ex) 
        
            errorQuestion(); 
        
    }
}
if (reply != JOptionPane.YES_OPTION) respawn();
There are more replies on the next page.
1
2