在这个程序中,我想用三个O来替换随机位置的三个N.我尝试使用forloop来实现这一目标,但是,' O'我得到的是不一致的。我不确定哪个部分出了问题......
static char grid[][];
public static void Board()
{
Random rn = new Random();
grid = new char [3][3];
for(int row = 0; row<grid.length; row++)
{
for(int col = 0; col<grid.length; col++)
{
grid[row][col] = 'N';
for(int i = 0; i<3; i++)
{
grid[rn.nextInt(3)][rn.nextInt(3)] = 'O';
}
System.out.print(grid[row][col]);
}
System.out.println();
}
}
答案 0 :(得分:2)
你需要分开你的循环。
首先用N
s初始化数组,然后替换3 N
s:
for(int row = 0; row<grid.length; row++) {
for(int col = 0; col<grid[row].length; col++) {
grid[row][col] = 'N';
}
}
for(int i = 0; i<3; i++) {
grid[rn.nextInt(3)][rn.nextInt(3)] = 'O';
}
在内部初始化循环中运行for(int i = 0; i<3; i++)
会导致3个随机单元格被分配O
3x3次,之后可以用N
覆盖这些单元格,因为您之前正在执行此操作初始化完成。
您还应该注意,grid[rn.nextInt(3)][rn.nextInt(3)] = 'O'
分配的单元格可能不是3个唯一单元格,因此您最终可能会少于3 O
s。
您可以使用while循环替换第二个循环,以确保更换正好3个单元格:
int i = 0;
while(i < 3) {
int x = rn.nextInt(3);
int y = rn.nextInt(3);
if (grid[x][y] != 'O') {
grid[x][y] = 'O';
i++;
}
}
答案 1 :(得分:1)
有时候一点抽象会让事情变得更容易。
为什么你的循环内有随机内容?您的约束是您希望九个数组索引中的三个完全不同。因此:不要迭代数组并在那里调用随机函数。
只需创建(0,8)范围内的随机数,直到得到三个不同的值;然后更新数组中的相应索引。
你知道,棘手的部分是关于正好三个;这可以通过以下代码实现:
Set<Integer> randomIndexesToChange = new HashSet<>();
while (randomIndexesToChange.size() < 3) {
randomIndexesToChange.put( ... another random number from (0, 8) );
}
或者像RealSceptic建议的那样,创建一个集合对象,它只包含0到8之间的所有索引;然后你使用shuffle;然后选择前三个:
List<Integer> allIndexes = Arrays.asList(0, 1, ...
Collections.shuffle(allIndexes);
// now allIndexes is in random order
// so allIndexes.get(0) gives you the first index that should be O
...
答案 2 :(得分:0)
使用3个随机O
填充网格的另一种方法是在初始化时立即执行:
int numOs = 3;
for(int row = 0; row<grid.length; row++) {
for(int col = 0; col<grid[row].length; col++) {
if( numOs > 0 && randomConditionForO() ) {
grid[row][col] = 'O';
numOs--;
} else {
grid[row][col] = 'N';
}
}
}
randomConditionForO()
可能类似于rn.nextInt() % 2 == 0
等。如果您想提供设置O的概率,让我们说25%,您可以使用rn.nextInt(100) < 25
之类的内容或rn.nextFloat() < 0.25f
。
然而,这里的问题是,由于条件的随机性,你可能会得到少于3个Os,所以你可能想要反击。一种方法可能是为Ns提供计数并相应地增加O的概率。
示例:
int numOs = 3;
int numNs = gridSize - numOs; //gridSize would be 3x3 = 9 in your example
for(int row = 0; row<grid.length; row++) {
for(int col = 0; col<grid[row].length; col++) {
if( numOs > 0 && rn.nextInt(numNs + 1) < numOs ) {
grid[row][col] = 'O';
numOs--;
} else {
grid[row][col] = 'N';
numNs--;
}
}
}
这里rn.nextInt(numNs + 1) < numOs
意味着选择O的概率随着每个选择的N而增加,并且随着每个选择的O减少。因为nextInt(bound)
将返回0(包括)和{{1}之间的整数}(独占)我们需要传入bound
,这样如果没有更多的Ns可用,我们使用绑定1,因为它是独占的,我们总是得到0,小于{{1}只要有可用的Os(因此获得100%的概率)。
答案 3 :(得分:-1)
以@GhostCats为基础回答:
static char grid[][];
public static void Board()
{
int width=3, height=3;
// create new array filled with 'N'
grid = new char [width][height];
for(char[] col: grid)
Arrays.fill(col, 'N');
// create list of all possible indexes
List<Integer> index = IntStream.range(0,width*height).boxed()
.collect(Collectors.asList());
Collections.shuffle(index);
// replace first three indexes with 'O'
for(int i=0; i<3; i++)
grid[index.get(i)/width][index.get(i)%width] = 'O';
}
需要Java 8。