i have a problem with the next question, i need to solve it by using if/else, i wrote the code but i don't know if it's the solve of the question or not:
Write a program in which the user enters the coordinates of the black pawns (a, b) on the chessboard.
The program must determine whether the pawn may move to get to one field (c, d):
1. In the ordinary move;
2. When it "hit" piece or pawn opponent.
Note: Black pawn move on the board from the bottom up.
char CoordinY;
int CoordinX;
if (CoordinY > 'b' && CoordinX <= 1 && CoordinX>8)
{
cout << "Error . . . \n";
}
else
{
if (CoordinX >= 2 && CoordinX <= 8 && CoordinY == 'a' || CoordinY == 'b'*)
{
// arbitrary move:
cout << "will not get to the field (c, d) in the ordinary move.\n";
// when it "hits" enemy's figure or pawn
cout << "will not get to the field (c, d) when ше hit a figure or pawn opponent.\n";
}
else if (CoordinX>1 && CoordinX < 8 && CoordinY == 'b')
{
// arbitrary move
cout << "will not get to the field (c, d) in the ordinary move.\n";
// when it "hits" enemy's figure or pawn
cout << "will not get to the field (c, d) when it hit a figure or pawn opponent.\n";
}
In the answer I assume the following classic chess board and the fact that I am moving white pawn:
It is important because in your problem definition, blacks are moving bottom up, which is incorrect.
In my example, I will use the following variables:
char a, c; int b, d; // E2 - E4 is: a = 'e', b = 2, c = 'e', d = 4.
Arbitrary move
Where can a pawn go with an arbitrary move in chess?
One step ahead
Two steps ahead if it is standing at row 2
So, in general, a pawn at (a; b) can move to (c; d), if they stand in the same row (a == c) AND if it is one step ahead or two steps ahead for b equal to 2.
So, let's implement it:
if (a == c && (d - b == 1 || (d - b == 2 && b == 2)))
cout << "Abitrary move: YES";
} else {
cout << "Arbitrary move: NO";
}
Attack
A pawn can move with an attack if only an enemy is standing in the next row, one cell to the left or to the right:
if ((c == a + 1 || c == a - 1) && (d - b == 1))
cout << "Attack: YES";
} else {
cout << "Attack: NO";
}
Note that this solution is not working for the case which is called en passant (is it more well-known as "битое поле" or "взятие на проходе" in Russian).
This is a solution in pseudocode:
if (d == b - 1) // destination is one square up
if (c == a) // pawn is on a square in the same column as destination
return true; // yes, pawn can move forwards to destination
if (c == a - 1 || c == a + 1) // destination is one square to left or right
return true; // yes, pawn can take a white pawn to move to destination
end if
return false
First we do the check which is true for both cases... is the destination only one step in front (note that in chess pawns can also move two squares on their first turn, but you didn't request that solution so I haven't added it)?
Next we check if the move is either straight ahead, or diagonal.
You might want to check that a,b c,d are all valid chess coordinates to start with, which would prevent illegal moves being marked as ok.
Edit: also I'm assuming that the bottom of the board has a larger 'y' coordinate than the top. If the coordinates are reversed you would check for b + 1 in the first conditional.
Related
TLDR: I am making a tic tac toe game in c++. My win condition checking if statements are failing and I don't know why :(
The board state is maintained by a global 2D board array
int board[3][3]{ {0,0,0}, {0,0,0}, {0,0,0}};
As the game plays on, a 1 or 2 is inserted to represent an X or O. Periodically I check for a winner with a function that uses 8 if statements to check for win conditions (3 horizontals, 3 verticals, or 2 diagonals).
int winCheck()
{
int winner = 0;
// check horizontal 1
if ((board[0][0] == board[0][1] == board[0][2]) && (board[0][2] > 0))
{
winner = board[0][0];
}
// check horizontal 2
...
return winner;
}
Any ideas? I think the logic is fine but my syntax is off.
Sigh. After pulling my brain out for 4 hours. It appears that you can't logically compare 3 things in an if statement ie:
if (A == B == C)
You must instead do 2 comparisons...
if (A == B && B == C)
Maybe this will help someone someday...
I'm working on a program that hides a number in a grid (2d array, 10 columns and 10 rows labeled with array filled with a character such as a . or -) and prints the grid to screen.
a num for row and column are random generated and saved to array as an 'X', only shown when found
The user enters the row and column....then displays that user's guess on the grid to the screen as a character. after that, choose which direction to move...and give hints on where the randomized location for that item is hidden in the array within ten tries total or less(user cannot go to previous guess played during the program).
for example:
while (guess <9 || found == false){
cout << "Enter your next move....n, e, s, w, ne, nw, se, sw";
cin >> d;
if (d == 'E' || d == 'e')
{
col++;
guess++;
array[col][row] = guess;
cout << "moved east";
}
else if (d == 'W' || d == 'w')
{
col--;
guess++;
array[col][row] = guess;
cout << "west...";
}
....etc
else {
guess++;
cout << "not valid move. turn is incremented";
}
then after the entire while loop on all those, i display the array again but I can't get the moves to show up other than the first step(need it to do 1, 2, 3...10 or until found=true to display 'X') and am not sure how to give the hint on where the item is hidden based on guess direction. if the item is north above where the user guessed their first starting place(column and row), it should display hint based on that location. How could I implement that?
Must be: while(guess < 9&&!found), either condition not met shall leave to exiting, so you only stay in the loop if both are met... Side note: It is better code style not to compare booleans, just use if(condition) or if(!condition) as in the fixed loop condition.
Be aware that you should check your board's borders:if(col > 0)
{
--col;
++guess;Analogously for the other directions...
You need to check, if the field intended to visit already has been visited. Assuming the fields unvisited carry value 0, you can add the following condition to the border check:if(col > 0 && array[col - 1][row] != 0)Again, other directions analogously.
For the hints, calculate the distances of the coordinates between target and current position; if negative, add 'n' or 'w' to your hint for vertical or horizontal direction respectively, if positive, 's' or 'e', otherwise, no hint for the respective direction (easiest variant, prefers diagonal directions first).
Side note array[col][row]: Typically, you name the indices of the array the other way round: array[row][col]; if iterating, you use outer loop for rows, inner loop for cols (to profit from data locality):
for(r = 0; r < rows; ++r)
for(c = 0; c < cols; ++c)
std::cout << getCharFor(array[r][c]);
North and south, with code above, still are associated with vertical, east and west with horizontal direction...
Edit in response to your comment:
You do not need to check the border you are moving away from...if(d == "e")
{
if(/*col > 0 &&*/ col <= 10)
//^^^^^^^^^ obsolete...
}
If your array has a size of NxN, then the maximum index you can access is N - 1, so you only can go east if you are currently maximally at position N - 2 (if(col < N-1))
If you go diagonally, you have to check both horizontal and vertical direction:if(d == "sw")
{
if(row < N - 1 && col > 0)
}
If you have determined that you do not exit the board with the designated move, then you can access the field in the designated direction:if(d == "sw")
{
if(array[row + 1][col - 1] != 0)
// visited already; assuming you have initialized the array with 0...
}
Side note: For the hints, there is yet an unconsidered problem left: What, if the user does not follow them, and due to this, the program gives a hint to a field that already has been visited???
int trees = 3;
int tree_x, tree_y;
for(int r = 0; r < m_townsize; r++)
{
for(int c = 0; c < m_townsize; c++)
{
if(r == 0 || c == 0 || r == (m_townsize - 1) || c == (m_townsize - 1))
m_town[r][c] = 'W';
while(trees > 0)
{
tree_x = random() % m_townsize;
tree_y = random() % m_townsize;
cout << tree_y << "," << tree_x << endl;
if(m_town[tree_y][tree_x] == ' ')
{
m_town[tree_y][tree_x] = 'T';
trees -= 1;
}
}
}
}
According the code I have written, if there is a space character at the coordinate of the tree, it should place a tree and lower the tree count by 1.
If there is not a space there, it should skip placing a tree, thus not decrementing. This should cause it to pick another set of coordinates and run through again.
However, if you look at this particular output it is running to the if-statement skipping the first option to replace it with a T--since it is a W--but still decrementing by 1. I don't get it. It should skip the statement all together, not skip just the first line. Netbeans tells me my brackets are right, so it shouldn't be an issue with the assignment belonging to the if and the decrement belonging to the while.
If I make a do-while loop it places a whole bunch. I don't know what's happening.
This output placed 2 trees.
You are walking over each coordinate.
If it is on the edge you put a 'W'. Then you randomly place a tree 'T'.
Then you proceed to the next coordinate.
This means you can place some trees in squares before you overwrite with a 'W'.
Finish all the walls before placing trees. Consider a more efficient way to place walls to, like doing each edge instead of loopimg over the middle abd doing nothing.
I need help with the following code that requires me to:
Declare 3 double type variables, each representing one of three sides of a triangle.
Prompt the user to input a value for the first side, then
Set the user’s input to the variable you created representing the first side of the triangle.
Repeat the last 2 steps twice more, once for each of the remaining 2 sides of the triangle.
Use a series of nested if / else statements to determine if the triangle having side-lengths as set by the user is an EQUILATERAL, ISOSCELES, or SCALENE triangle.
[Note: look to the Wikipedia page on ‘triangle’ for definitions of these three types of triangles.]
Print the resulting triangle type to the console.
Ensure your Triangle detector works by running it 5 times as in the example above. You may use the same values as in the example.
I currently have:
//lab eleven program code on triangles
#include <iostream.h>
main()
{
//variables
float aside, bside, cside;
//enter side a
cout<<"enter the length of side a "<<endl;
cin>>aside;
//enter side b
cout<<"enter the length of side b "<<endl;
cin>>bside;
//enter side c
cout<<"enter the length of side c "<<endl;
cin>>cside;
// all sides equal
if(aside==bside && bside==cside)
cout << "Equilateral triangle\n";
// at least 2 sides equal
else if(aside==bside || aside==cside || bside==cside)
cout << "Isosceles triangle\n";
// no sides equal
else
cout << "Scalene triangle\n";
}
But I need help with the if and else if statements to determine the type triangle. Our professor has not covered this topic in class.
We use the program Ch 6.3 on Windows.
if(a==b && b==c) // all sides equal
cout << "Equilateral triangle\n";
else if(a==b || a==c || b==c) // at least 2 sides equal
cout << "Isosceles triangle\n";
else // no sides equal
cout << "Scalene triangle\n";
As your professor suggested, you should look at:
http://en.wikipedia.org/wiki/Triangle#Types_of_triangles
You should also look at:
http://www.teacherschoice.com.au/maths_library/trigonometry/solve_trig_sss.htm
Algorithm:
Solve for all angles, a1, a2, a3 (see the article above)
If you can't find a solution:
Output "Error: Not a valid triangle"
Else:
If (a1 == a2) && (a2 == a3):
Output "EQUILATERAL" and stop
If (a1 == a2) || (a2 == a3) || (a1 == a3):
Output "ISOSCELES" and stop
Output "SCALENE" and stop
Also note: Be careful about "equality" with floating point (float/double) values (such as angles). If you are doing such a comparison, you should usually use this instead:
abs(x - y) < epsilon
Where epsilon is a "sufficiently small value".
The logic falls out neatly from the definition of these different types of triangles, which as the professor notes, is information readily obtained from Wikipedia. It just involves a simple comparison of side lengths; you don't have to go as far as angles. But I'll give you some help with the "not a triangle" condition. Don't be afraid to put on your math hat here and go wandering in, a little logic isn't a bad thing for a poli sci student to endure every now and then. :-)
For the sides to make a proper triangle, for each pair of sides (I'll call them f and g), they must add up to greater than the third side's length (I'll call it h). If you're dealing with equilateral triangles, you automatically know this condition is met (why?). If you're dealing with isosceles or scalene triangles, you technically only need to check the smaller two sides against the largest side, and if it's true for them, it's true for the other two cases as well (why?). However, it may be just as convenient for you to check all three cases.
Looking at why this inequality has to hold: if the sum of two sides was exactly equal to the third side's length, you'd have a "degenerate" triangle where sides f and g could only lay on top of h! If they added up to less, the two sides could connect to the endpoints of h but then would never meet at a third point! You can test this yourself by cutting lengths of string or strips of paper and trying it out.
Three other things to think about:
In C++, double and float are not the same thing. One has less precision than the other. Make sure you use the one the professor asks for.
Checking to make sure the sides are non-negative is a great idea. You could probably reasonably rule out lengths of 0 as well, to eliminate the possibility of degenerate triangles that just look like line segments or points.
When comparing floating-point numbers, you should always be careful to consider whether a strict equality is going to get you what you want. For checking the equilateral/isosceles/scalene conditions, you're fine because the user is directly entering in the floating-point numbers and you're not manipulating them, so there's no chance for you to introduce error. But when checking the "not a triangle" condition, it's relatively easy to set up a situation where adding the two sides rounds off (because of the vicissitudes of floating-point arithmetic in the CPU) to something that's very close to, but not quite exactly, the third side. In those cases, if you want to catch degenerate triangles, what you usually do is pick an "epsilon" value (some very small value relative to the numbers you're dealing with) that represents the maximum amount of roundoff you're willing to tolerate. You then check whether the sum of f and g is somewhere between h - epsilon and h + epsilon – or put another way, whether the absolute value of f + g - h is less than or equal to epsilon. If it is, you claim that f + g = h (as best as you can tell) and deal with the degenerate case.
To complete this program you will need the following:
Make sure input is valid. In this case, input must be greater than 0. You could catch your input using a loop like
while (invar <= 0)
{
cout<<"Enter length"<<endl;
cin>>invar;
if (invar <= 0)
{
cout<<"invalid input"<<endl;
}
}
I am not sure if this is proper c++ syntax, I haven't used it in about 8 years.
you can do this for all 3 inputs. I would probably make a function to determine the triangle using 3 input variables and 1 return variable. The following is pseudo-code
if (a + b <= c) or (a + c <= b) or (b + c <= a)
{
return "you don't have a triangle."
}
else
{
if (a == b) or (a == c) or (b == c)
{
if (a == b and b == c)
{
return "equilateral"
}
return "isosceles"
}
return "scalene"
}
return -1
#include<stdio.h>
#include<ctype.h>
#include<conio.h>
#include<math.h>
int main()
{
float Side1,Side2,Side3;
float Flag1,Flag2,Sum_of_sq1,Sum_of_sq2,Sum_of_sq3;
clrscr();
printf("Enter Three Sides Side1 Side2 Side3 :");
scanf("%f %f %f", &Side1 , &Side2 , &Side3);
Flag1=(Side1==Side2)?(Side2==Side3?1:0):((Side2==Side3)?0:-1);
if(Flag1==0)
{ printf("Triangle is Isoceles\n");
}
if (Flag1==1)
{ printf("Equilateral Triangle");
}
Sum_of_sq1=pow(Side1,2)+pow(Side2,2);
Sum_of_sq2=pow(Side1,2)+pow(Side3,2);
Sum_of_sq3=pow(Side2,2)+pow(Side3,2);
if (sqrt(Sum_of_sq1)==Side3 ||sqrt(Sum_of_sq2)==Side2 || sqrt(Sum_of_sq3)==Side1)
printf("The Triangle is Right Angled Triangle");
getch();
return(0);
}
#include<iostream>
using namespace std;
//create a class
class Triangle {
//declare three sides for the triangle
double side1;
double side2;
double side3;
public:
//constructor to initialize the data members
Triangle(double s1, double s2, double s3) {
side1 = s1;
side2 = s2;
side3 = s3;
}
void triangleType() {
//all sides equal
if((side1 == side2)&&(side2 == side3))
cout << "It is an Equilateral Triangle" << endl;
//at least two sides are equal
else if((side1 == side2) || (side2 == side3) || (side1 == side3))
cout << "It is an Isosceles Triangle" << endl;
//all are different
else
cout << "It is a Scalene Triangle" << endl;
}
};
int main() {
//local variable
double a_side, b_side, c_side;
//taking the user inputs
cout << "Enter the three sides of a triangle: " << endl;
cin >> a_side >> b_side >> c_side;
Triangle t1(a_side, b_side, c_side); //create an object of Triangle
t1.triangleType(); //call the function
return 0;
}
I'm writing a Tic Tac Toe Game and I would like to know how I can make an efficient function to check who won. A two dimensional array congaing X's, O's, or blank spaces represents the board.
char CheckWin(const char board[][NUM_COLS], int& sum) // tic tac toe board - IN
{
char tmp;
int lcv;
tmp = ' ';
if (sum == 9)
{
return 'T';
}
else if (sum != 9)
{
if (((tmp = board[1][1]) != ' ' && board[0][0] == tmp && board[2][2] == tmp) || (board[2][0] == tmp && board[0][2] == tmp))
{
return tmp;
}
for (lcv = 0; lcv < 3; lcv++)
{
if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp)
{
return tmp;
}
else if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp)
{
return tmp;
}
}
}
return 'N';
}
Besides doing something similar to this over and over again, how could I check who won and return an X if X has won, an O if O has one, a T if it's a tie, and N if no one has one yet. Thanks in advance. I'm trying to get familiar with C++ and programming in general still.
EDIT: I just went with the simple method, but I somehow messed it up, anybody know how? It looks like it's not return anything because when I call it in the main after a player picks a row and column(that's working fine), it doesn't output anything
You could convert the array into two nine-bit values, one for the O positions and one for the X position, and a count of blank spaces:
x_mask = 0
y_mask = 0
empty_count = 0
mask = 1
for each square
if x then x_mask |= mask
if y then y_mask |= mask
if empty then empty_count++
mask <<= 1
Then compare the x_mask and y_mask against the eight possible winning combinations:
for each player
for each winning combination
if player_mask & winning_mask == winning_mask then player has won
and then handle the cases neither player has won:
if neither player won
if empty_count == 0
its a tie
else
moves still available
A simple "structured" approach
If you think of the board as:
A B C
D E F
G H I
Then one minimal selection of boxes that any winning layout must touch would be:
A B C
D
G
You can conceive the movement from any of these locations in a winning line in terms of a shift of 0, 1 or -1 positions in each of the X and Y directions. We can list the movements that you'd need to check:
A: (++x) (++x, ++y) (++y)
B: (++y)
C: (++y) (--x, ++y)
D: (++x)
E: (++x)
In C++, you can create a list/vector of the x/y coordinates of the starting points and the +/-/0 x/y movement deltas shown above, then use three nested loops to evaluate each line across the board.
This is considerably more work than just hardcoding the two loops over x and y coordinates and the two diagonals (below), but it's a more algorithmic approach that might appeal intellectually: more like what you might have to do if you were handling a much bigger board.
Obvious brute force approach
For the record, that simpler approach would look like this:
int x;
for (row = 0; row < 3; ++row)
if ((x = board[row][0]) != Empty &&
board[row][1] == x && board[row][2] == x)
return x;
// similar loop for columns...
...
// hardcode diagonals...
if ((x = board[1][1]) != Empty &&
(board[0][0] == x && board[2][2] == x ||
board[2][0] == x && board[0][2] == x))
return x
I suppose you could assign each winning board possibility a number (basically a hash value) and then check if the current board matches any of the values in the table by generating its hash value. On the other hand, I wouldn't suggest spending too much time trying to make the CheckWin function super-efficient. Unless it's being called millions of times or something and needs to be really fast, spend your time on something else--it probably won't be a bottleneck.