2017-03-08 15 views
2

編集:私は解決策が良い午後方法1と7の間の2つの乱数を作る方法、両方とも5ではない?

public int getRandomNumber(int start,int end) 
{ 
int normal = Greenfoot.getRandomNumber(end-start+1); 
return normal+start; 
} 

getRandomNumber(int, int) 

を使用して要求されたので、これはHow do I generate random integers within a specific range in Java?に別の質問です。私はGreenfootのプロジェクトに取り組んできました。Javaの場合、メインキャラクターは7x7スクリーンで3枚のコインを使用しています。私はこのコードを書いています:

public class FirstLevel extends World 
{ 
public int getRandomNumber(int start,int end) 
{ 
    int normal = Greenfoot.getRandomNumber(end-start+1); 
    return normal+start; 
} 

/** 
* Constructor for objects of class FirstLevel. 
* 
*/ 
public FirstLevel() 
{  
    // Create a new world with 600x400 cells with a cell size of 1x1 pixels. 
    super(9, 9, 60); 
    MainCharacter theDuckDude = new MainCharacter(); 
    addObject(theDuckDude, 4, 4); 
    coin coin1 = new coin(); 
    coin coin2 = new coin(); 
    coin coin3 = new coin(); 
    addObject(coin1, getRandomNumber(1, 7), getRandomNumber(1, 7)); 
    addObject(coin2, getRandomNumber(1, 7), getRandomNumber(1, 7)); 
    addObject(coin3, getRandomNumber(1, 7), getRandomNumber(1, 7)); 
} 
} 

このように、3つのコインとダックのキャラクターがランダムな場所に表示されます。明らかに

Actor actor = getOneIntersectingObject(coin.class); 
getWorld().removeObject(actor); 

は、このコードは私のtheDuckDude文字がコイン俳優に触れると、コインが削除されたことを示しています。ここに私のtheDuckDude文字からのコードの抜粋です。あなたは、おそらく見てきたように、これは非常に問題を提起:theDuckDudeとコインの俳優が同じ広場に生成されている場合、ゲームが正常に動作しません:だから enter image description here

、私はこれらのランダムに生成することができます方法はありint型は、

public int getRandomNumber(int start,int end) 
{ 
    int normal = Greenfoot.getRandomNumber(end-start+1); 
    return normal+start; 
} 

getRandomNumber(1, 7) 

方法を使用して、どのように私はそれを一緒に除外が 5,5というランダムな位置を生成することができますか?

+1

は今まであなたをしましたそれらが同じであることをテストし、別のペアを生成する場合は考慮してください。 –

+3

これは第2の問題であり、統計的には明らかではないので再開されました。 – Bathsheba

+3

コインを同じ広場に置くことはできますか? – matt

答えて

3

表示可能な四角形は49個ですが、有効な四角形は48個あります。 0〜47までの整数を選択し、1を加えて中央の正方形を除外し、そこからxyを派生させます。

static final int ROWS = 7; 
static final int COLS = 7; 
static final int EXCLUDE_X = 5; 
static final int EXCLUDE_Y = 5; 

int index = ThreadLocalRandom.current().nextInt(ROWS * COLS - 1); // range: [0, 47] 
if (index >= ((EXCLUDE_Y * ROWS) + EXCLUDE_X)) {  // offset the center square 
    index++; 
} 
int x = (index % COLS); 
int y = (index/ROWS); 

私はここThreadLocalRandomにこだわってきましたが、簡単にあなたのGreenfootヘルパーで動作するように同じことを言い替えることができます。

2

基本的に2つの方法があります。

単純な方法は、2つのランダムな整数を選択することです。あなたがduckDudeのポジションに当たったら、もう一度選んでください。別のポジションになるまでもう一度:

int x; 
    int y; 
    do { 
     x = getRandomNumber(1, 7); 
     y = getRandomNumber(1, 7); 
    } while (x == duckDudeX && y == duckDudeY); 
    addObject(character, x, y); 

これは機能します。たとえそれが最終的に終了するとしても、反復の回数に上限はないことがわかります。

もう1つの選択肢は、四角形を選択するときに既に禁止されている四角形を除外することです。これはまた、他のいくつかの答えの基本的なアイデアです。それは初期のビットを必要とするので、私のバージョンでは、有効な正方形の座標のリストを使用しています。

List<Pair> validPairs = new ArrayList<>(49); 

    for (int x = 1; x <= 7; x++) { 
     for (int y = 1; y <= 7; y++) { 
      validPairs.add(new Pair(x, y)); 
     } 
    } 
    validPairs.remove(new Pair(duckDudeX, duckDudeY)); 

今すぐコインのための正方形を選ぶことは簡単です:

Pair where = validPairs.get(getRandomNumber(0, validPairs.size() - 1)); 
    addObject(character, where.getX(), where.getY()); 

補助Pairクラスはにいくつかの行を追加しますしかし、プロジェクト、:

public class Pair { 
    private int x; 
    private int y; 

    public Pair(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(x, y); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Pair other = (Pair) obj; 
     if (x != other.x) 
      return false; 
     if (y != other.y) 
      return false; 
     return true; 
    } 

} 

編集:私は、あなたが不足している部品の中で自分自身を記入し、何かに同意しなかった場合にも、正しいでしょう期待していたあなたのコード。私は私のコードでは:かどうか

static final int duckDudeX = 4; 
static final int duckDudeY = 4; 

それはあなたの質問やコードから明確ではなかった(4、4)または(5、5)禁断の正方形でした。私のコードがduckDudeXまたはduckDudeYと表示されているところであれば、もちろん4または5を入力してもかまいません。それが私のコードであれば、変数または定数の宣言を主張したいと思います。定数が適切であるかどうかを最もよく知っており、おそらくより良い名前を見つけることもできます。

+0

エラー:theDuckDudeX変数が見つかりません –

+1

コインのランダム座標を生成する前に、あなた自身を初期化してduckdudeのx座標とy座標でそれぞれ更新してください。 – skbrhmn

+0

申し訳ありませんが、禁止されている広場は4,4 –

0

私が正しく理解していれば、5,5位は単なる例であり、与えられた範囲内で別個の乱数を生成するアルゴリズムを探しています。

通常、事前にインデックスの配列をシャッフルし、シャッフルされたインデックスを1つずつ取得するよりも、ただし、間に手動でインデックスを選択する場合は、これは機能しません(例:ランダムコインの生成 - >特定コインの削除 - >別のランダムコインの生成)。

この問題を解決するには、アルゴリズムをシャッフルフィッシャーイエーツの代替バージョンを実装することです:

static void shuffle(int[] ar) {   
    Random rnd = ThreadLocalRandom.current(); 
    for (int i = ar.length - 1; i > 0; i--){ 
     int index = rnd.nextInt(i + 1); 

     int a = ar[index]; 
     ar[index] = ar[i]; 
     ar[i] = a; 
    } 
} 

あなたが見ることができるように配列項目が配列の末尾にシャッフルされると、それは意志もはやその位置を変更しません。したがって、我々はループを削除し、一つ一つではなく、同じ結果を得るシャッフルアイテムやインデックスを取得することができます。

public class Shuffler { 
    private final int indexCount; 
    private final int[] indexes; 
    private final int[] indexIndexes; 
    private int nextIndexI; 

    public Shuffler(int indexCount){ 
     this.indexCount = indexCount; 
     indexes = new int[indexCount]; 
     indexIndexes = new int[indexCount]; 
     for(int i = 0; i < indexCount; i++){ 
      indexes[i] = i; 
      indexIndexes[i] = i; 
     } 
     nextIndexI = indexCount - 1; 
    } 

    public int nextIndex(){   
     if(nextIndexI == -1){ 
      return -1; 
     } 

     Random rnd = ThreadLocalRandom.current();  
     int i = rnd.nextInt(nextIndexI + 1); 

     swap(i, nextIndexI); 

     return indexes[nextIndexI--];  
    } 

    public boolean pickIndex(int index){   
     if(0 > index || index >= indexCount || indexIndexes[index] > nextIndexI){ 
      return false; 
     } 

     swap(indexIndexes[index], nextIndexI);  
     nextIndexI--; 

     return true;   
    } 

    public boolean reinsertIndex(int index){   
     if(0 > index || index >= indexCount || indexIndexes[index] <= nextIndexI){ 
      return false; 
     } 

     nextIndexI++;  
     swap(indexIndexes[index], nextIndexI); 

     return true;  
    } 

    private void swap(int i1, int i2){ 
     indexIndexes[indexes[i1]] = i2; 
     indexIndexes[indexes[i2]] = i1; 

     int tmp = indexes[i1]; 
     indexes[i1] = indexes[i2]; 
     indexes[i2] = tmp; 
    } 

} 

この変更は、特定のインデックスを選択し、再挿入するためにユーザを可能にする方法を紹介する機会を提供していますこれらの2つの方法でヘルパーアレイindexIndexesが使用され、実際のインデックスを高速に検索できます。シャッフラーを使用して

は簡単です:あなたはもちろんの行を置き換えることができ

//demo 
static final int ROWS = 7; 
static final int COLS = 7; 

Shuffler shuffler = new Shuffler(ROWS*COLS);   
for(int i = 0; i < ROWS*COLS; i++){ 
    int index = shuffler.nextIndex(); 
    int x = index % COLS; 
    int y = index/ROWS; 
    System.out.println(x + " " + y); 
} 

Random rnd = ThreadLocalRandom.current();  
int i = rnd.nextInt(nextIndexI + 1); 

を独自のgetRandomNumber()方法で。

0

この質問に対する回答は非常に簡単ですが、注意してください。あなたが逃したことがあります。以下のコードを守ってください。

public class FirstLevel extends World 
{ 
public int getRandomNumber(int start,int end) 
{ 
    int normal = Greenfoot.getRandomNumber(end-start+1); 
    return normal+start; 
} 

public FirstLevel() 
{  

    super(9, 9, 60); 
    int coin1x = 0; 
    int coin2x = 0; 
    int coin3x = 0; 
    int coin1y = 0; 
    int coin2y = 0; 
    int coin3y = 0; 
    MainCharacter theDuckDude = new MainCharacter(); 
    addObject(theDuckDude, 4, 4); 
    coin coin1 = new coin(); 
    coin coin2 = new coin(); 
    coin coin3 = new coin(); 
coin1x = getRandomNumber(1, 9); 
coin1y = getRandomNumber(1, 9); 
coin2x = getRandomNumber(1, 9); 
coin2y = getRandomNumber(1, 9); 
coin3x = getRandomNumber(1, 9); 
coin3y = getRandomNumber(1, 9); 

while (coin1x == 4 && coin1y == 4) 
{ 
    coin1x = getRandomNumber(1, 9); 
    coin1y = getRandomNumber(1, 9); 

} 
while (coin2x == 4 && coin2y == 4) 
{ 
    coin2x = getRandomNumber(1, 9); 
    coin2y = getRandomNumber(1, 9); 
    while (coin2y == coin1y && coin2x == coin1x); 
    { coin2x = getRandomNumber(1, 9); 
     coin2y = getRandomNumber(1, 9); 
    } 
    while (coin2y == coin3y && coin2x == coin3x); 
    { 
     coin2x = getRandomNumber(1, 9); 
     coin2y = getRandomNumber(1, 9); 
    } 
    while (coin1x == coin3x && coin1y == coin3y); 
    { 
     coin3x = getRandomNumber(1, 9); 
     coin3y = getRandomNumber(1, 0); 
    } 
} 
while (coin3x == 4 && coin3y == 4) 
{ 
    coin3x = getRandomNumber(1, 9); 
    coin3y = getRandomNumber(1, 9); 
} 


int x; 
int y; 
addObject(coin1, coin1x, coin1y); 
    addObject(coin2, coin2x, coin2y); 
    addObject(coin3, coin3x, coin3y); 

お知らせこのコードは、あなたが逃した二つの新しいものを持っています。まず、このコードは、コインは4,4広場に置かれているかどうかをチェックします:

while (coin1x == 4 && coin1y == 4) 
{ 
coin1x = getRandomNumber(1, 9); 
coin1y = getRandomNumber(1, 9); 

} 

しかし、また、2枚のコインが同じ広場にある場合は、コードがチェックされますがわかります

while (coin2y == coin1y && coin2x == coin1x); 
{ coin2x = getRandomNumber(1, 9); 
    coin2y = getRandomNumber(1, 9); 
} 
関連する問題