<?php
$mines = 10;
####
for($x=1; $x<=9; $x++) {
for($y=1; $y<=9; $y++) {
$minefield[$x][$y] = 0;
}
}
for($i=0; $i<$mines; $i++) {
$randx = rand(1, 9);
$randy = rand(1, 9);
if($minefield[$randx][$randy] == 'X') {
$i--;
} else {
$minefield[$randx][$randy] = 'X';
}
}
What's i doing wrong?
$i--
supposed to be accomplishing? Is that like a "try again, there's already a mine here? - Alex Howansky 2012-04-05 20:18
When comparing strings (or resources) with integers, strings are translated to numbers first, as per the documentation, then compared.
As such, this:
if ($minefield[$randx][$randy] == 'X')
... where $minefield[$randx][$randy] = 0
is equivalent to:
if (0 == 0) // 0 == (int)'X'
... which is always true. Therefore, you are incrementing and decrementing $i
at each iteration.
(int)"Hello 1234"
gives 0
, while (int)"1234 Hello"
gives 1234
- netcoder 2012-04-06 14:49
I would try to set the $minefield[$x][$y] = '0'; with the quotes, so that both types are string. Might be an issue with that.
Check out the PHP Manual on this subject Comparing Strings to Numbers
as a guideline I would not do $i-- inside the loop, as this is a classic infinite-loop generator. instead do another loop inside that keep on generating random mines until it doesn't hit an existing one.
There is another solution to your problem. You can set it like that and be sure you pick only 10 positions in limited set of coordinates:
<?php
// build minefield
$minefield = array();
for($x=1; $x<=9; $x++) {
$minefield[$x] = array();
for($y=1; $y<=9; $y++) {
$minefield[$x][$y] = 0;
}
}
// prepare cartesian func
function array_cartesian() {
$_ = func_get_args();
if(count($_) == 0)
return array(array());
$a = array_shift($_);
$c = call_user_func_array(__FUNCTION__, $_);
$r = array();
foreach($a as $v)
foreach($c as $p)
$r[] = array_merge(array($v), $p);
return $r;
}
// get coordinates
$coords = array_cartesian(range(1,9), range(1,9));
// pick random coordinates' keys
$chosen_coords = array_rand($coords, 10);
foreach ($chosen_coords as $key) {
$minefield[$coords[$key][0]][$coords[$key][1]] = 'X';
}
I know, it is lengthy, but I could write it in 2-3 lines in Python.
Ps. The code for cartesian product is from here: https://stackoverflow.com/a/2516779/548696
the problem is in your second loop. as the indexes are random numbers, so maybe array value of these indexes has been set to X
in the else
statement, and by a random chance, same indexes will be checked again and again so it will goes to if
statement and here is where you minus i
!
It is not a good practice to change the value of loop variable i
in the body of the loop.
X
by random, and then if they were equal to X
he minuses the loop var - rene 2012-04-05 20:34
obviously because you decrement the loop counter :
if($minefield[$randx][$randy] == 'X') {
$i--;
} else {
$minefield[$randx][$randy] = 'X';
}
at one point all fields will equal 'X' and you'll have an infinite loop.
it is a very bad habit to play with the index in a for loop