Changing position in game is making problems - game-maker-studio-1.4

I tried to create table game with character and wanna to change position of my character through dice.
All points, where I wanna to get are saved in array global.array_points[1] to [20]: global.array_points[1]] = point_1;
When dice got number from 1 to 6 in step function of my character is:
if(character.x != global.array_points[global.new_complete_position].x &&
character.y != global.array_points[global.new_complete_position].y)
{
global.position_character += 1;
x = global.array_points[global.position_character].x;
y = global.array_points[global.position_character].y;
}
Sometimes my code is working perfect, but sometimes, my game still works, but character does not to know change position.
Do you know, how to solve this problem please?

Related

C++ How to generate a random Path

I'm trying to write a function that can generate a random path for a given 2D array of points (x, y).
Now the path has a few requirements I'd like it to meet in order for it to be valid.
The path cannot:
...be a straight line from point A to B.
...go back on itself but can go backwards (demonstrated below).
...run parallel/along itself.
I also want to make sure the path starts from the left and ends on the right to hopefully keep it simple.
So I'm looking for something that would do:
......... | ......... | ########.
......... | ......... | .......#.
##....### end | ....####. | ...#####.
.######.. | #####..#. | ...#.....
......... | .......## end | ...###### end
But I don't know where to start and there's vary little information available that does something similar to this.
I could go the A* rout but that seems overkill and from what I know about A* (vary little) I'd need to create "fake" obstacles. Anyway before I go on a rant, can anyone help me?
Any suggestions is greatly appreciated! Thank you.
The following description and code snippet should give you enough information to solve the problem without providing an exact solution. Note: the following does not satisfy all of your criteria (e.g., preventing a straight line solution) but any missing pieces should be easy to fill in.
Create the grid
Generate random starting cell
Generate random ending cell that is different than the starting cell
Walk from the starting cell to the ending cell
Mark each position as being 'visited'
Determine the valid moves from this position
At least 1 valid move: add this position position to the 'solution path' and update this position to be one of the valid moves
No valid moves: update this position to be the position most recently added to the solution path (i.e., backup) and remove the position most recently
added to the solution path
Note if the 'solution path' is empty restart again at step 4
Reset the grid back to its original state
Traverse the solution path and mark each cell as 'visited'
Print grid
// Step 1
Grid grid(10, 10);
// Step 2
Cell start = grid.generateRandomCell();
// Step 3
Cell end = start;
while (end == start)
{
end = grid.generateRandomCell();
}
std::vector<Cell> solutionPath;
// Step 4
Cell pos = start;
while (pos != end)
{
// Step 4.1
grid.setValue(pos, '#');
// Step 4.2
std::vector<Cell> possibleMoves = getPossibleMoves(grid, pos);
if (!possibleMoves.empty())
{
// Step 4.2.1
solutionPath.push_back(pos);
pos = possibleMoves[rand() % possibleMoves.size()];
}
else
{
// Step 4.2.2
if (!solutionPath.empty())
{
pos = solutionPath.back();
solutionPath.erase(--solutionPath.end());
}
else
{
pos = start;
grid.reset();
}
}
}
// Step 5
grid.reset();
// Step 6
for (size_t i = 1; i < solutionPath.size(); ++i)
{
grid.setValue(solutionPath[i], 'A' + ((i - 1) % 26));
}
grid.setValue(start, '#');
grid.setValue(end, '!');
// Step 7
std::cout << grid << "\n";
You can just try things one square at a time until you find a solution:
do
create an array e.g. bool points[Num_Rows][Num_Columns] = { false };, tracking where you've been
initialise std::pair<int,int> cursor { rand() % Num_Rows, 0 };, tracking where you are
repeat
work out which directions your cursor can move in without leaving the board or breaking your rules
if there are none, you're bust: go back to "do" above
pick one, recording that you've moved there by setting the related points[] element
if you're cursor's in the right-hand column, you're done, break from the loop

Using Libtcod, how to console->print a string with a dynamic amount of colors?

I've got a helper function that accepts a string and a vector of colors to use to format the string and right now my solution is to manually check the size of the color vector and call the console print with that same amount of colors.
Say I've got a color vector of 4, in the code it'd do something like:
void helper_func(TCODConsole* con, std::string msg_str, std::vector<TCOD_colctrl_t> color_vector)
{
char* message = msg_str.c_str();
//this is repeated 1 through 16, adding another color_vector.at(n) for each.
...
else if (color_vector.size() == 2)
//message might be "%cHello%c was in red"
console->print(x, y, message, color_vector.at(0), color_vector.at(1))
...
else if (color_vector.size() == 4)
//message might be "%cThe octopus%c shimmers at %cnight%c"
console->print(x, y, message, color_vector.at(0), color_vector.at(1), color_vector.at(2), color_vector.at(3))
...
}
While this works, it's awful and I was looking into different ways of pulling it off, allowing for more than 16 colors, etc.
I've tried doing a sprintf for each color in the vector, adding it to the out_string and repeating. I've tried doing the same with an ostringstream. I've tried splitting the msg_str on "%c" and then joining the resulting strings once I've added the color in to each. It never worked out, always either using the first color and then using random characters instead of colors from there on out.
I was hopeful that any of the above would work because simply sprintf(out_char, format_msg, TCOD_COLCTRL_1) prints to the console (using console->print(out_char)) just fine.
My question is: is there a good way to pass a varying number of colors to the console->print function and have it accurately display those colors, without severe code redundancy?
As a fallback, I could print out a section of the string up to the first color, calculate its size, move x over by that much and print the next section, but that's not ideal.
I suppose that this question could be generalized to asking the same thing about regular printf with substitutions too.
One possible alternative to a variadic functions might involve parsing msg_str for "%c" and iteratively printing each segment of the string in the correct color according to color_vector. I'm not sure if this code below will compile--I wrote it in notepad, so it might need some work. Hopefully you get the gist of what I'm suggesting.
void helper_func(TCODConsole* con, std::string msg_str, std::vector<TCOD_colctrl_t> color_vector)
{
std::string str2;
std::size_t pos;
std::size_t pos2;
pos = msg_str.find("%c");
if (pos != std::string::npos)
str2 = msg_str.substr(0,pos);
else
str2 = msg_str;
console->print(x, y, str2.c_str());
int n = 0;
while (pos != std::string::npos) {
pos2 = msg_str.find("%c",pos+1);
if (pos2 != std::string::npos)
str2 = msg_str.substr(pos+2,pos2);
else
str2 = msg_str.substr(pos2+2,msg_str.length()-pos2+2);
console->print(x, y, str2.c_str(),color_vector.at(n));
pos = pos2;
n++;
}
}
I thought I should mention, there is a problem in my code. The x value in the second print statement needs to be calculated each time through the while loop since x changes as a function of pos2. Otherwise, everything will just keep printing in the same spot. :) Should be an easy change...

Strange characters appearing in 2D Char Array

I'm coding a game that utilizes a 'grid', which I have created using a 2 dimensional array of structs, which contain a char value and a boolean value. In my program's .h file, I declare the struct and create the grid.
struct Tile
{
char letter;
bool active;
};
Tile grid [6][5];
In my .cpp file, I initialize the grid so that all values are blank.
for (int i = 0; i < 7; ++i)
{
for (int j = 0; j < 6; ++j)
{
grid[i][j].active == false;
//grid[i][j].letter = '.';
//it always crashes when i try doing the above line
}
}
The function that prints the grid, printGrid, is below
for (int i = 0; i < 7; ++i)
{
for (int j = 0; j < 6; ++j)
{
cout << i;
//the above statement is for debugging purposes so that I can see
//which column easier
std::cout << grid[i][j].letter;
}
std::cout << std::endl;
}
cout << "1 2 3 4 5 6" << endl;
Now, the original goal was to have the default .letter value be '.'. But for some reason, when I tried to do this, there are disastrous results; the screen fills up with characters moving so fast I can't entirely see what they are (I recall some hearts and smiley faces), along with an obnoxious, rapid beeping. So I decided to leave that commented line out.
When I run the program without that line, for some reason, the "grid" always displays characters in certain spots, without any input from the user, or without me having expressly declared any values to that spot. For instance, the spot of the 1st column from the left and the bottom row, always has a character in it (grid[6][5].letter). It changes every time I run the program, and I've seen it range from a heart, to the letter A, to the spanish 'n' (the one with a ~ over it).
I thought to myself, "Hey, since grid[6][5] is the spots that are always buggy, I'll just declare those individual spot's .letter values to be blank (' ')!". That didn't work.
I've got no idea why this one spot is giving me trouble. There were other areas that would have an abnormal character, but I was able to neutralize them by setting their .letter values to blank. If anyone has any idea on how to fix this, pleas
EDIT: The other abnormal characters, which appear at grid[6][0], grid[6][1], grid[6][5], and grid[6][4], all make my program crash at later stages if I set them to blank (' '); however, blanking grid[6][5] is the one that makes it crash at the get go. I tried using a debugger, but it wasn't able to tell me anything helpful.
you're running over the end of your arrays
Tile grid [6][5]; needs to be Tile grid [7][6];
or you need to loop only to i < 6 and j < 5.

C++ Windows Form - If statements

I'm trying to make a password strength checker, at the moment i've got it setup so that if 'password' is typed into the password field then the strength goes red, and that if you type anything else it goes green
I've done this using the following if statement:
try{
if (password_textbox_form3->Text == "password")
{
strength_color_textbox->BackColor = Color::Red;
}
else
{
strength_color_textbox->BackColor = Color::Green;
}
}
catch (Exception^ )
{
strength_color_textbox->BackColor = Color::Black;
}
What i'm trying to do now and what i'm stuck on, is how to create a field called passwordscore that goes through a list of if statements and adds 10 if for example the password they have entered has more than 8 chars, and then from this score I can change the color of the strength box (red to green) that way
String ^ strength = password_textbox_form3->Text; //makes whatever the user enters in pw tb now called string
int passwordscore=0;
while // some sort of while loop to increment passwordscore? //passwordscore=passwordscore+1;
try{
if (strength //contains more than 8 characters)
{
//passwordscore +10
}
if (strength //contains a special character !"£$%^&*)
{
//password score +10
}
if (passwordscore <=10)
{
strength_color_textbox->BackColor = Color::Red;
}
if (passwordscore <=20)
{
strength_colour_textbox->BackColor = Color::Green;
}
I've started by assigning the contents of the password textbox to a string called strength (i think) and then got stuck on the IF statements such as how to see if strength has more than 8 characters etc
Any help or direction is appreciated, thanks
EDIT - found this from MSDN but I think it's in C#, can't be that much different to what i'm trying to do?
String ^ strength = password_textbox_form3->Text;
int numberOfDigits = 0;
int numberOfLetters = 0;
int numberOfSymbols = 0;
foreach (char c in strength)
{
if (char.IsDigit(c))
{
numberOfDigits++;
}
else if (char.IsLetter(c))
{
numberOfLetters++;
}
else if(char.IsSymbol(c))
{
numberOfSymbols++;
}
}
Take in the password as characters, and count the number of characters in the password form so that if the number of characters is >= 8 you can set the strength points to ten. Additionally you can use strings and put individual characters into a vector, and use the vector's index to count the # of characters.
EDIT TO FIRST EDIT:
Just to explain the new code posted:
A character can be either a alphabetical character (a,b,c) a number(1,2,3) or a symbol(+*^) obviously.
In the code they use one general FOREACH statement to contain three other if statements in which the character is checked to see if it is an alphabetical char a num or a symbol using the std library functions IsDigit IsSymbol IsLetter.
It adds one to the appropriate, initially declared variables whenever a character qualifies as one of the three categories.
For your purpose, you could use a similar technique but declare an int Pw_Str and Total_Char and add an if statement to increase Total_Char as necessary. When Total_Char exceeds 8 you can add 10 to Pw_Str as required and change the color using the Pw_Str variable.
To make any such code more compact instead of using if statements over and over i would suggest using a FOR loop to wind through each character and to add to the necessary variables.

How can I get the enemies to move?

Hello I am trying to get enemies to move left and right as if they are sliding backwards and forwards I know this can be done with the following code:
slide += slide_incr;
if(abs(slide)>30) slide_incr = -slide_incr;
However this is of no use to me as I need to set a boolean so I can cycle through the frames for when the enemy is going right or going left.
Ive tried the follow code with no luck:
if(abs(eSlide)<=0)
{
eSlide += eSlide_incr;
}
if(abs(eSlide)>30)
{
eSlide_incr = -eSlide_incr;
}
Any ideas on how I can implement it?
Thanks
You want to hold a hysteresis state for if you're sliding forward or backward. You are also mixing up how to use the abs() function when bounds checking. Try something along the lines of:
eSlide += eSlide_incr;
if (abs(eSlide) >= 30) {
eSlide_incr = -eSlide_incr;
}
the first thing that stands out for me is that the contents of the block:
if (abs(eSlid) <= 0) {
eSlide += eSlide_incr;
}
will never ever run (the absolute value will always be greater than or equal to 0)
as for your boolean facing, that can be achieved with:
bool isSlidingRight = eSlide_incr > 0;
(note: this would still use the left animation set for values of 0)