Sign in to follow this  
MateBoy

Help with XNA/C Sharp - randomizing positions

Recommended Posts

I'm creating a game that consists of moving around fifteen tiles (and one empty spot) so that they end up in their correct positions (AKA a slider puzzle).

I've made a method that shuffles all bricks' positions when you press the S Key. The problem is, once you release the button, the positions keeps updating randomly.
I just want them to be shuffling when the button is held down.

Here's how it works:
in the main Game1 class, I check whether the S key is pressed or not. If it is, it calls the method Shuffle which is in the TileHandler class. The TileHandler class unsurprisingly handles all the tiles.
Anyway, the Shuffle method just changes all the tiles' state (which of course is an enum) to shuffled. Then, in the Draw method, it checks what state the tiles are in. If it is Shuffled, it calls the method RandomizePositions, that returns a new random Point that is used to mathematically place the tiles accordingly.

But, as stated, it keeps updating the positions continuously once the S key has been pressed.
I realize that the problem is that the state hasn't changed from Shuffled, so it keeps throwing around random positions, but the REAL question is [b]how to I make it stop updating positions?[/b]

Share this post


Link to post
Share on other sites
Hi,

There are numerous things that could be happening. Post your code that is connected to this so we can see what you are / are not doing.
Also step through in your debugger, this will enlightened you to what exactly your program is doing.

x

Share this post


Link to post
Share on other sites
[font="arial, verdana, tahoma, sans-serif"][size="2"][quote name='MateBoy' timestamp='1318175026' post='4870822']
I'm creating a game that consists of moving around fifteen tiles (and one empty spot) so that they end up in their correct positions (AKA a slider puzzle).

I've made a method that shuffles all bricks' positions when you press the S Key. The problem is, once you release the button, the positions keeps updating randomly.
I just want them to be shuffling when the button is held down.

Here's how it works:
in the main Game1 class, I check whether the S key is pressed or not. If it is, it calls the method Shuffle which is in the TileHandler class. The TileHandler class unsurprisingly handles all the tiles.
Anyway, the Shuffle method just changes all the tiles' state (which of course is an enum) to shuffled. Then, in the Draw method, it checks what state the tiles are in. If it is Shuffled, it calls the method RandomizePositions, that returns a new random Point that is used to mathematically place the tiles accordingly.

But, as stated, it keeps updating the positions continuously once the S key has been pressed.
I realize that the problem is that the state hasn't changed from Shuffled, so it keeps throwing around random positions, but the REAL question is [b]how to I make it stop updating positions?[/b]
[/quote]


I am fairly new to XNA / C# so I'm not sure this is 100% correct but I think you can check if a key is currently not pressed.

something like[/size][/font]
[code]

KeyboardState currentKey = Keyboard.GetState();

if (currentKey.IskeyDown(Keys.S) == true && currentKey.IskeyUp(Keys.S) !=true )
{
//Set your state / enum to shuffled

} else { //Set your state / enum back to normal }
[/code]


off the top of my head so syntax may not be right.

----------------------------------------------------------------------------------------------------------------------------

I just realized you said you check if the key is pressed or "not". As MonKan said, please post the code related to the issue and we will try and help you. Edited by Oblivion Jedi

Share this post


Link to post
Share on other sites
[quote name='Monkan' timestamp='1318180673' post='4870842']
Hi,

There are numerous things that could be happening. Post your code that is connected to this so we can see what you are / are not doing.
Also step through in your debugger, this will enlightened you to what exactly your program is doing.

x
[/quote]

As I stated previously, I know why this is happening (since the positions are updated in the draw method, it happens continously), but I can't figure out a way to solve it all.

The following code block just checks if the S key is pressed:
[code]if (kState.IsKeyDown(Keys.S) == true)
{
tileHandler.Shuffle();
}[/code]

Then, in TileHandler:
[code]public void Shuffle()
{
foreach (Tile tile in tiles ) //tiles is the name of the twodimensional array that holds the sixteen tiles
{
tile.tileState = Tile.TileState.Shuffling;
}
}[/code]

Then, in the Draw method in TileHandler:
[code]public void Draw()
{
for (int x = 0; x < tiles.GetLength(0); x++)
{
for (int y = 0; y < tiles.GetLength(1); y++)
{
switch (tiles[x, y].tileState)
{
case Tile.TileState.Unshuffled: // if the state is Unshuffled, the tiles are just displayed in their correct positions
tiles[x, y].Draw(mCorrectPos = new Point(x, y)); // the draw method for the Tile class has a Point as a parameter
break;
case Tile.TileState.Shuffling:
tiles[x, y].Draw(mCurrentPos = new Point(random.Next(0, tiles.GetLength(0)), random.Next(0, tiles.GetLength(1)))); // here's where the problem lies; the positions are updated continously
break;
}
}
}
}[/code]


I know that the positions should not be randomized in the Draw method, but how else can I do it?

Share this post


Link to post
Share on other sites
Hi,

Surely you just have to change the state back to unshuffle after you've shuffled them.

i.e -
[code]
foreach (Tile tile in tiles)
{
tile.tileState = Tile.TileState.Unshuffled.
}
[/code]


call this after you have shuffled them otherwise they will be continuously shuffled.

EDIT:: And no this shouldn't really be done in the draw function, you would be better doing it all in your shuffle function so instead of setting a state in the shuffle function you just loop through all the tiles and shuffle them there and use the Draw to just draw them all.

x

Share this post


Link to post
Share on other sites
You need to Check the state and shuffle the tiles in another method such as an Update method, set the state back to unshuffled after shuffling. and only draw in the draw method using the mCurrentPos variable.

Maybe something like this


[code]
//Check the state and update the mCurrentPos variable
public void Update()
{
for (int x = 0; x < tiles.GetLength(0); x++)
{
for (int y = 0; y < tiles.GetLength(1); y++)
{
switch (tiles[x, y].tileState)
{
case Tile.TileState.Unshuffled:
mCorrectPos = new Point(x, y);
break;
case Tile.TileState.Shuffling:
mCurrentPos = new Point(random.Next(0, tiles.GetLength(0)), random.Next(0, tiles.GetLength(1))));

//set state back to unshuffled after shuffling
tile.tileState = Tile.TileState.Unshuffled;
break;
}
}
}

}

[/code]


[code]
public void Draw()
{
for (int x = 0; x < tiles.GetLength(0); x++)
{
for (int y = 0; y < tiles.GetLength(1); y++)
{
tiles[x, y].Draw(mCorrectPos);

}
}

}
[/code]

Just a thought

Share this post


Link to post
Share on other sites
[quote name='Oblivion Jedi' timestamp='1318187157' post='4870873']
You need to Check the state and shuffle the tiles in another method such as an Update method, set the state back to unshuffled after shuffling. and only draw in the draw method using the mCurrentPos variable.

Maybe something like this...
[/quote]

Ahh, so close! When the S key is pressed, it shuffles, and when it is released, it stops! But, it seems like they're all getting the same position. The for loop seems to go through completely and just draw all sixteen tiles at the last possible iteration of the nested for loops. So, in conclusion, just one mCurrentPos is created for all tiles. Hmm, how do I create a different mCurrentPos for each tile?


Share this post


Link to post
Share on other sites
[quote name='MateBoy' timestamp='1318190860' post='4870880']
Ahh, so close! When the S key is pressed, it shuffles, and when it is released, it stops! But, it seems like they're all getting the same position. The for loop seems to go through completely and just draw all sixteen tiles at the last possible iteration of the nested for loops. So, in conclusion, just one mCurrentPos is created for all tiles. Hmm, how do I create a different mCurrentPos for each tile?
[/quote]

Maybe make an Array out of mCurrentPos?


[code]

Vector2 [] mCurrentPos;
[/code]


[code]

//Check the state and update the mCurrentPos variable
public void Update()
{
for (int x = 0; x < tiles.GetLength(0); x++)
{
for (int y = 0; y < tiles.GetLength(1); y++)
{
switch (tiles[x, y].tileState)
{
case Tile.TileState.Unshuffled:
mCurrentPos[x] = new Point(x, y);
break;
case Tile.TileState.Shuffling:
mCurrentPos[x] = new Point(random.Next(0, tiles.GetLength(0)), random.Next(0, tiles.GetLength(1))));

//set state back to unshuffled after shuffling
tile.tileState = Tile.TileState.Unshuffled;
break;
}
}
}

}
[/code]


[code]

public void Draw()
{
for (int x = 0; x < tiles.GetLength(0); x++)
{
for (int y = 0; y < tiles.GetLength(1); y++)
{
tiles[x, y].Draw(mCurrentPos[x]);

}
}

}
[/code]

Share this post


Link to post
Share on other sites
[quote name='Oblivion Jedi' timestamp='1318196209' post='4870884']
Maybe make an Array out of mCurrentPos?
[/quote]

Hmm, tried that, it shuffles all tiles, but some tiles are getting the same random position. Is there a way to make sure no random value can be generated more than once?

Share this post


Link to post
Share on other sites
[quote name='MateBoy' timestamp='1318274320' post='4871165']Is there a way to make sure no random value can be generated more than once?[/quote]

[url=http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle][u]Randomly shuffle[/u][/url] an array of valid positions, then just pair these up with the tiles.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this