2017-03-08 8 views
2

편집 : 내가 솔루션이 방법 1과 7 사이의 2 개의 임의의 정수를 만드는 방법.

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?에 다른 문제이다. 저는 Java로 Greenfoot 프로젝트를 진행했습니다. 주인공은 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)); 
} 
} 

이렇게 알 수 있듯이 세 동전과 오리 캐릭터가 임의의 위치에 나타납니다. 분명히

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

는,이 코드는 내 theDuckDude 문자가 동전 배우를 접촉 할 때, 동전이 제거되었는지 보여줍니다 여기 내 theDuckDude 문자의 코드의 조각이다. 당신은 아마 보았 듯이,이 상당히 문제가있다 : theDuckDude와 동전 배우가 같은 광장에 발생하는 경우, 게임이 제대로 작동하지 않습니다 : 그래서 enter image description here

, 나는이 무작위로 생성 할 수있는 방법이있다

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

getRandomNumber(1, 7) 

방법을 사용하는 int는 내가 할 수있는 방법은 그 제외 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

기본적으로 두 가지 방법이 있습니다.

간단한 방법은 두 개의 임의의 정수를 선택하는 것입니다. 너가 duckDude 위치를 명중하면, 너는 다시 쑤신다. 그리고 다른 위치를 얻을 때까지 :

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

그것은 작동합니다. 그다지 만족스럽지 않은 점은 그것이 결국 종료 될지라도, 반복 회수에 대한 상한선이 없다는 것입니다.

다른 옵션은 사각형을 선택할 때 이미 금지 된 사각형을 제외하는 것입니다. 이것은 또한 다른 답변의 몇 가지 기본 아이디어입니다.내 버전은 유효 사각 좌표의 목록을 사용하므로 초기화 조금 필요합니다

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

보조 Pair 클래스에 몇 줄을 추가 : 이제 동전의 사각형을 따기

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)); 

간단을 그래도 프로젝트 :

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

Error : theDuckDudeX 변수를 찾을 수 없습니다. –

+1

동전을 임의로 생성하기 전에 duckdude의 x 좌표와 y 좌표로 각각 초기화하고 업데이트하십시오. – skbrhmn

+0

죄송합니다. 금단의 광장은 4, 4입니다. –

0

정확하게 이해한다면, 5,5 위치는 단지 예일 뿐이며 주어진 범위 내에서 별개의 난수를 생성하는 알고리즘을 찾고 있습니다.

일반적으로 인덱스 배열을 미리 셔플하고 셔플 인덱스를 하나씩 검색하는 것이 좋습니다. 그러나 인덱스를 수동으로 선택하려면이 옵션이 작동하지 않습니다 (예 : 임의의 동전 생성 -> 특정 동전 제거 -> 다른 임의의 동전 생성). 당신이 볼 수 있듯이, 한 번 배열 항목이 배열의 마지막에 셔플

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; 
    } 

} 

이 수정의 특정 인덱스를 선택하고 다시 삽입 할 수 있도록 해주는 방법을 소개 할 수있는 기회를 제공을 between (도우미 배열 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); 

} 

뿐만 아니라 두 개의 동전이 같은 광장에있는 경우 코드를 확인합니다주의 사항 :

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