Reputation: 13
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().
Upvotes: 0
Views: 1427
Reputation: 14837
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]);
Upvotes: 2
Reputation: 14698
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]
Upvotes: 0
Reputation: 20571
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.
Upvotes: 0