简体   繁体   中英

Check if int[] contains an int

My script is caught in an infinite loop and I cannot figure out why. I have an array with 40 pawns and need to put these randomly on a board. So, I have a random number that chooses a random pawn from the array, but if the pawn has already been chosen, it has to pick a new random number, but that last part seems to bug for some reason. I cannot figure out why.

Random rand = new Random();    

int[] availablePawnsArray = {1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12 };
// this array contains 40 integers

int[] chosenPawns = new int[40];
//this array contains the index numbers of already selected pawnsfrom the previous array

int counter = 0;
//counts how many pawns have been selected already    

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 10; j++) {
    //this refers to my board, 40 locations for my 40 pawns    

        int chosenPawn = rand.nextInt(40);
        //a random numder from 0 to 40
        
        boolean found = false;
        //a boolean to say if i have already selected this pawn before or not    

        do {
            for (int n : chosenPawns) {
                if (n == chosenPawn) {
                    found = true;
                    chosenPawn = rand.nextInt(40);
                } else {
                    found = false;
                }
            }
        } while(found == true);    

        board[i][j].rank = availablePawnsArray[chosenPawn];
        chosenPawns[counter] = chosenPawn;
        counter++;
    }
}

You can have two arrays, and second one keep for selected integers, then do loop in second array check if there is any number equal to given one return false or true.

int [] selectedInts = new int[40];

boolean contains(int num) {
  for (int i = 0 ; i < selectedInts.length; i++) {
    if (i == num) return true;
  }
  return false;
}

Also you can use like

Arrays.asList().contains(yourInt);

You can simplify this by modifying the random number selection in the same way that one might shuffle a deck of cards. It is a slight variation of Fisher-Yates. I believe this should always work in linear time.

      Random rand = new Random();
      int[] availablePawnsArray = {
            1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
            6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12
      };


      int start = 39;
      for (int i = 0; i < 4; i++) {
         for (int k = 0; k < 10; k++) {
            int chosenPawn = rand.nextInt(start + 1);
            // chose the pawn
            board[i][k].rank = availablePawnsArray[chosenPawn];
            // copy the pawn from the end of the list to the 
            // chosen pawn location.
            availablePawnsArray[chosenPawn] = availablePawnsArray[start];
            // update the random number to ignore the last slot
            // in the array (the pawn in that slot has
            // been moved to occupy the chosenPawn's location)
            start--;
         }
      }

      for (int i = 0; i < 4; i++) {
         for (int k = 0; k < 10; k++) {
            System.out.print(board[i][k].rank + " ");
         }
         System.out.println();
      }
   }

Unless you need to implement it as an exercise you could use the built in shuffle method, wrapping your array of available pawns in a list:

Collections.shuffle(Arrays.asList(availablePawnsArray));
    
for (int i = 0, k = 0; i < 4; i++) 
    for (int j = 0; j < 10; j++, k++) 
        board[i][j].rank = availablePawnsArray[k];

The chosenPawns array should only be searched upto counter. Using repeatedly random to find a free spot when almost all is used, could take several thousands of steps to find the final last open spots. There is not even a guarantee to find an open spot.

Simply consider the random position as starting point to find the first free pawn, going round-robin from ... 36, 37, 38, 39, 0, 1, ....

int[] pawnsArray = {1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4,
    5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12 };
// this array contains 40 integers

boolean[] pawnsChosen = new boolean[40];
// this array tells wether the i'th pawn was chosen.

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 10; j++) {

        int pawnIndex = rand.nextInt(40);
        while (pawnsChosen[pawnIndex]) {
            pawnIndex = (pawnIndex + 1) % 40;
        }
        pawnsChosen[pawnIndex] = true;

        board[i][j].rank = availablePawnsArray[pawnIndex];
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM