简体   繁体   中英

Selecting a random element in boolean array in java

I am making a one player Tic-Tac-Toe game against a computer and was wondering how I would be able to select a random boolean value that is false in an array where some values are true and some are false. I know to use Math.random() but I was wondering how I would be able to select a different random element if the selected element is true instead of false? Or if anybody knows a better way instead of using Math.random().

One possible way to do this, without changing the structure of your code, would be to collect all the indices of the false values in the array, and then pick one of those indices at random.

Something like this:

Random r = new Random();
boolean[] values = { true, false, false, true, false, true, false, false, false };

int[] falseIndices = IntStream.range(0, values.length)
  .filter(i -> !values[i])
  .toArray();
System.out.println(Arrays.toString(falseIndices));
int randomFalseIndex = falseIndices[r.nextInt(falseIndices.length)];
System.out.format("%s: %s%n", randomFalseIndex, values[randomFalseIndex]);

You have an array of boolean values, I'm assuming the indices represent something in your game. If you need to randomly retrieve a boolean value from the array (I assume you mean you want the index of the boolean value), then it becomes inefficient to use Math.random() and keep picking until you get a false value. Instead, consider redesigning your problem to have 2 arrays of ints, one representing true values and one representing false values. Rather than having the boolean false at index 3, you would store the int 3 in your false array. Once it is redesigned like this, to access a random false element, you would simply use Math.random() once onto your false array of ints.

Alternatively, you can just have an additional int array to track just the indices of the false values, which you can index into with Math.random() to get the random false value.

I have implemented a small snippet for a nice tictactoe implementation, please ignore my previous implementation since it was very problematic. Here you can set start point & with a proper enumeration, you can follow the board more properly. This answer is much more Java-like IMO;

public static void main(String[] args) throws Exception {
    Boolean aiStarts = true;
    Integer size = 9, step = 0;
    List<Spot> board = new ArrayList<>(Collections.nCopies(size, Spot.E));

    do {
        int i;
        do {
            i = (int)(Math.random() * size);
        } while (!Spot.E.equals(board.get(i)));
        board.set(i, step++ % 2 == (aiStarts ? 0 : 1) ? Spot.X : Spot.O);
    } while (board.stream().filter(s -> Spot.E.equals(s)).count() > 0);

    System.out.println(board.subList(0, 3));
    System.out.println(board.subList(3, 6));
    System.out.println(board.subList(6, 9));
}

enum Spot {
    X, O, E;
}

Where AI uses X and User uses `O', you can replace the auto insertion logic with your user's input. This prints out, as an example;

[O, X, O]
[X, X, X]
[O, X, O]

I think you can try the code, the result is random 在此处输入图片说明

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