How to change a value in an array C++ - c++

This function is for code to play a game of tic tac toe:
//--------------------FUNCTION--------------------
bool playCell(int player, int position, int gameBoard[]) {
if (gameBoard[position] == 10 || gameBoard[position] == 11) {
return false;
} else {
return true;
if (player == 0){
gameBoard[position] = 10;
} else {
gameBoard[position] = 11;
} // end if
}
} // end function
playCell takes a player (0 for "O", 1 for "X"), a position (1 to 9), and the nine element gameBoard, and returns true if the move is legal (i.e. that spot is not yet taken), and false otherwise. If the move is legal it changes the position to that players number (10 for "O", 11 for "X"). If the player or position input is invalid, it returns false.
I'm trying to figure out how to get the array to change its value to either a 10 or 11 depending on the player, and saving to the position they entered to play in.

The return keyword redirect the program flow back to the main program. So the code after return will not be executed. Change the position of return:
//--------------------FUNCTION--------------------
bool playCell(int player, int position, int gameBoard[])
{
if (gameBoard[position] == 10 || gameBoard[position] == 11)
{
return false;
}
else
{
if (player == 0)
{
gameBoard[position] = 10;
}
else
{
gameBoard[position] = 11;
} // end if
return true;
}
} // end function

You have a return statement prior to your array assignment here:
return true; // HERE
if (player == 0){
gameBoard[position] = 10;
} else {
gameBoard[position] = 11;
} // end if
this causes your code not to be executed. Remove this line from there and put in the correct place.

Related

when i try to compile i keep getting message vector subscript out of range

string getName() { return name; }
string getE1() { return enemy1; }
string getE2() { return enemy2; }
string getE3() { return enemy3; }
bool isEnemy(string check) {
if (check == enemy1 || check == enemy2 || check == enemy3)
//if the name being checked is an enemy of this knight
return true;
else
return false;
}
int Candidate(Knight b) {//'b' is an enemy of 'a' who is in the seat before 'b'(ie. b seat=2 a seat=1
int toSwap = b.seatingPos;//toSwap holds seating pos # of 'b'
int checkFriends = (toSwap - 1);//holds seating pos of 'a'
string nameA = table[checkFriends].getName();
for (int i = 0; i < 8; i++) {
if (table[i].isEnemy(nameA) || table[i].getName() == nameA) //if not enemies, then must be friends
{
continue;
}
else
{
friends.push_back(table[i].seatingPos);
}//adds seating # of friends of 'a' to friends vector
}
for (int j = 0; j < 4; j++) {//check friends of 'a' to see if their neighbor is friends with 'b'
int check2 = table[friends[j]].seatingPos;//check 2 holds seating pos # of 'c'
if (check2 != 7)
++check2;
else
return check2;
if ((table[toSwap].isEnemy(table[check2].getName()))) //if neighbor of c is friends with b(toSwap)
{
continue;
}
else {
return check2;//if not enemies then must be friends return seating pos of acceptable candidate
}
}
return 0;
}
when i debug the code it says i have an unhandled exception when assigning
string nameA = table[checkFriends].getName();
the value of checkfriends = 0 so it shouldnt be out of the range of the vector.
debugger also says: Unhandled exception at 0x7BC8F2F6 (ucrtbased.dll) in Knights.exe: An invalid parameter was passed to a function that considers invalid parameters fatal. occurred
this occurs during the 1st if statement.
thanks for any help!!!

Why does my recursion not return to previous pointer?

I am working on an assignment in which we must create a 20-questions type game from a binary search tree. We read the tree in from a text file that is formatted like this:
Does it walk on 4 legs?
Does it fly?
*centipede?
Is it an insect?
*bird?
*butterfly?
Does it purr?
Does it howl?
*mouse?
*dog?
*cat?
Later, I am going to allow the user to add to this list. At the moment, however, I am unable to accurately read the list into a binary search tree. I have set it up so that (I think) it will use recursion and return to the previous "current" node pointer when it ends a loop of the function. Currently, however, the current node pointer remains the same.
The below function is passed a vector of the strings from the text file.
string line;
string guess;
bool start = true;
void buildTree(vector<string> gameData, Node* current, int &counter)
{
//fill node with question or answer
//recursive:
// add to the left until we encounter an asterisk
// add to the right
line = gameData[counter];
//if a question
if (line[0] != '*')
{
if (current->getData().empty())
{
current->setData(line);
cout << current->getData() << endl;
}
if (!start)
{
//if noChild is empty AND current isn't a guess, go to noChild
if ((current->getNo()->getData().empty())
&& (current->isGuess() == false))
{
current = current->getNo();
}
//otherwise, go to yes
else {
current = current->getYes();
}
}
while (counter < gameData.size())
{
if (!start) { counter++; }
start = false;
buildTree(gameData, current, counter);
}
}
//if a guess
else
{
//if data is full, go to no
if (current->getData().empty() == false)
{
current = current->getNo();
}
//otherwise, go to yes
else
{
//current = current->getYes();
for (int i = 1; i < line.size(); i++)
{
guess.push_back(line[i]);
}
current->setData(guess);
guess.clear();
cout << current->getData() << endl;
counter++;
current->setGuess(true);
}
}
}

Tests randomly fails

I'm writing board game and I need following functionality: player rolls two dices, if he rolled doubles (same number on both dice), he gets to roll again, if he rolled doubles again, he goes to jail.
In my Game class it looks like that
void logic::Game::rollTheDice() {
m_throwsInCurrentTurn++;
int firstThrow = m_firstDice.roll();
int secondThrow = m_secondDice.roll();
m_totalRollResult += firstThrow + secondThrow;
if (firstThrow == secondThrow) m_doublesInCurrentTurn++;
}
std::string logic::Game::checkForDoubles() {
std::string message;
if (m_doublesInCurrentTurn == 0 && m_throwsInCurrentTurn == 1) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 1) {
message = "Doubles! Roll again.";
m_canThrow = true;
m_canMove = false;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 2) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 2 && m_throwsInCurrentTurn == 2) {
message = "Doubles again! You are going to jail.";
m_canThrow = false;
m_canMove = false;
getActivePlayer().lockInJail();
}
return message;
}
void logic::Game::setInMotion(unsigned number) {
m_players[m_activePlayer].startMoving();
m_players[m_activePlayer].incrementPosition(number);
}
m_canThrow basicly enables or disables ability to click "Roll the Dice" button, m_canMove decides if player token can start moving, m_players[m_activePlayer] is std::vector<Player>, startMoving() does that,
void logic::Player::startMoving() {
m_isMoving = true;
}
needed for token movement, so baiscly not relevant here.
Last function from Game class I need to show you is reset(), used mainly for testing purposes
void logic::Game::reset() {
m_throwsInCurrentTurn = 0;
m_doublesInCurrentTurn = 0;
m_totalRollResult = 0;
}
Now finnaly Unit Test that sometimes goes wrong. Sometimes, I mean completely random, like 1 out of 10-20 times.
//first throw is double, second throw is not
TEST_F(GameTestSuite, shouldFinishAfterSecondRollAndMove) {
auto game = m_sut.get();
do {
if (game.getThrowsInCurrentTurn() == 2) game.reset();
game.rollTheDice();
game.checkForDoubles();
if (game.getThrowsInCurrentTurn() == 1 && game.getDoublesInCurrentTurn() == 1) {
ASSERT_EQ(game.canThrow(), true);
ASSERT_EQ(game.canMove(), false);
}
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
ASSERT_EQ(game.canThrow(), false);
ASSERT_EQ(game.canMove(), true);
game.setInMotion(game.getTotalRollResult());
ASSERT_EQ(game.getActivePlayer().isMoving(), true);
ASSERT_EQ(game.getActivePlayer().getPosition(), game.getTotalRollResult());
}
This line exactly, ASSERT_EQ(game.canThrow(), false); sometimes is equal true after do-while loop that should end once m_canThrow is set to false
Shouldn't:
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
be
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() <= 1);
You want to allow up to two turns but 0 or 1 doubles.

Can't figure out how to loop playerturns and moves Tic Tac Toe (C++) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
EDIT: Solved now thank you triple_r and AJNeufield for your help on this problem I was having.
I've looked around multiple websites and YouTube about this and I can't seem to find anything on what I am specifically looking for this as my format for the program is a good bit different than others. Therefore, it's hard to decipher where I need to put the things I do need that I know of.
Please note that I'm relatively new to C++ so I'd appreciate all the feedback or criticism you might provide me.
Also, note my code does compile and run it just does not allow me to put in more than one input and more than likely does not allow for a switch of player turns.
Quick Edit: Switched the code with the new setup suggested by triple_r but I seemed to have messed it up somewhere along the line and it does compile(with the exception of x and y not being utilized and one other error) but it always starts off with player 2 going first and as soon as it receives input it ends automatically with a segmentation fault.
#include <iostream>
#include <cstdlib>
using namespace std;
//////////////////////////////////////////////////////////
void initboard(char board[3][3])
{
int x,y;
for (x=0;x<3;x++)
for (y=0;y<3;y++)
board[x][y]=' ';
return;
}
//////////////////////////////////////////////////////////
void printboard(char board[3][3])
{
int x,y;
for (x=0;x<3;x++)
{
cout<<"\n";
for (y=0;y<3;y++)
{
cout<<" "<<board[x][y]<<" ";
if (y<2) cout<<"|";
}
if (x<2) cout<<"\n===========";
}
return;
}
//////////////////////////////////////////////////////////
void getmove(char board[3][3], int player)
{
return;
}
//////////////////////////////////////////////////////////
int main()
{
bool done=false;
char board[3][3];
int x,y,player=1,turn,playerchoice,playermark;
initboard(board);
turn=0;
do
{
if (player==1)
playermark='X';
else
playermark='O';
if (turn%2)
player=1;
else
player=2;
cout<<"Player "<<player<<" where do you want to move?: ";
cin>>playerchoice;
if (playerchoice==1)
{
board[0][0]=playermark;
}
else if (playerchoice==2)
{
board[0][1]=playermark;
}
else if (playerchoice==3)
{
board[0][2]=playermark;
}
else if (playerchoice==4)
{
board[1][0]=playermark;
}
else if (playerchoice==5)
{
board[1][1]=playermark;
}
else if (playerchoice==6)
{
board[1][2]=playermark;
}
else if (playerchoice==7)
{
board[2][0]=playermark;
}
else if (playerchoice==8)
{
board[2][1]=playermark;
}
else if (playerchoice==9)
{
board[2][2]=playermark;
}
else
{
cout<<"Invalid move ";
}
if (board[x][y]!=' ')
cout<<"Move is already taken.";
board[x][y]=playermark;
if(board[x][y]==' ')
turn++;
}while (!done);
void printboard(char board[3][3]);
return 0;
}
EDIT: based on the updated code
So, the first thing I can see is that you are using x and y in your program but you don't initialize them or assign any values to them. Also, try to use functions/classes/... yo make your code more readable. You already have a function for player move but you are not using it. You can move the large if statement inside that function and that will make your main code shorter and more readable.
Here are my comments on the main part of your program:
int main()
{
// add a new variable to see if the move was valid or not:
bool done=false, validmove = true;
char board[3][3];
int x, y, player = 1, turn = 0, playerchoice, playermark;
initboard(board);
do
{
// swap the two `if`s so you decide who`s turn it is then assign the player mark,
// also, reverse the condition to make sure turn '0' is player 1's turn.
if (!(turn % 2))
player = 1;
else
player = 2;
if (player == 1)
playermark = 'X';
else
playermark = 'O';
cout << "Player " << player << " where do you want to move?: ";
cin >> playerchoice;
// Assign `x` and `y` here instead of updating the board, because you want to make
// sure that the move is valid before putting the mark:
validmove = true;
if (playerchoice == 1)
{
x = 0; y = 0;
}
else if (playerchoice == 2)
{
x = 0; y = 1;
}
else if (playerchoice == 3)
{
x = 0; y = 2;
}
else if (playerchoice == 4)
{
x = 1; y = 0;
}
else if (playerchoice == 5)
{
x = 1; y = 1;
}
else if (playerchoice == 6)
{
x = 1; y = 2;
}
else if (playerchoice == 7)
{
x = 2; y = 0;
}
else if (playerchoice == 8)
{
x = 2; y = 1;
}
else if (playerchoice == 9)
{
x = 2; y = 2;
}
else
{
cout << "Invalid move, try again!";
// Make sure to mark the move as invalid so they get a chance to
// change their move:
validmove = false;
}
// check to see if the turn was valid:
if(validmove)
{
if (board[x][y] != ' ')
{
cout << "Move is already taken, try again";
}
else
{
board[x][y] = playermark;
turn++;
}
}
// have to make sure you have a condition for end of game. A simple
// one is to check if turn is less than `9`, otherwise the board is
// full:
if(turn == 9)
done = true;
// you probably want to add a few more checks to see who won the game.
}while (!done);
// when calling a function, no need to put the return type or parameter type:
printboard(board);
return 0;
}
========================================================================
There are two do-while loops in your program and both seem to be meant as a game loop. What I would do is:
initboard(...);
turn = 0;
do{
//this is the game loop
...;
if( validturn )
turn++;
}while(!done);
release_resources(...);
return 0;
so, you fold everything into one loop. In that loop, you want to:
find who's turn it is:
if (turn % 2)
player = 1;
else
player = 2;
get users input:
std::cin >> playerchoice;
...
convert player choice to grid location:
switch ( move )
{
case 0:
x = 0;
y = 0;
break;
case 1:
...;
...
default:
//invalid move
}
see if the move is valid:
if( board[x][y] != ' ' )
//already taken, invalid move
then apply the move:
board[x][y] = playermark;
I hope this helps.
Your cin >> playerchoice is outside your do { ... } while ( moves != 9); loop. Move it inside.

infix to postfix program

I have written the following infix to postfix program but it's not working.
My program takes input but doesn't show any result. Can anyone help find the problem in my program.
And also it would be a great help if you tell if my Algorithm for converting infix to postfix is correct or not.
using namespace std;
class Stack
{
private:
int top;
char s[mx];
public:
Stack()
{
top=-1;
}
void push(char c)
{
if(!stackFull())
s[++top]=c;
}
void pop()
{
if(!stackEmpty())
top--;
else cout<<"Stack is empty"<<endl;
}
char topShow()
{
if(!stackEmpty())
return s[top];
}
bool stackEmpty()
{
if(top==-1)
return 1;
else return 0;
}
bool stackFull()
{
if(top == (mx-1))
return 1;
else return 0;
}
};
class Expression
{
private:
char entry2;
int precedence;
char infix[mx];
char postfix[mx];
public:
int prec(char symbol)
{
switch(symbol)
{
case '(':return 0; break;
case '-':return 1; break;
case '+':return 2; break;
case '*':return 3; break;
case '/':return 4; break;
}
}
void Read()
{
cout<<"Enter the infix expression: ";cin>>infix;
for(int i=0;infix[i]!='\0';i++)
{
convertToPostfix(infix[i]);
}
}
void ShowResult()
{
cout<<"Postfix expression"<<endl;
for(int j=0;postfix[j]!='\0';j++)
{
cout<<postfix[j];
}
}
void convertToPostfix(char c)
{
int p=0;
Stack myStack;
precedence=prec(c);
entry2=myStack.topShow();
if(isdigit(c))
{
postfix[++p]=c;
}
if(precedence>prec(entry2))
{
myStack.push(c);
}
if(precedence<prec(entry2))
{
switch(c)
{
case '(': myStack.push(c); break;
case ')': while(myStack.topShow()!= '(')
{
postfix[++p]=myStack.topShow();
myStack.pop();
};myStack.pop();break;
case '+':
case '-':
case '*':
case '/': while(prec(myStack.topShow())>=precedence)
{
postfix[++p]=myStack.topShow();
myStack.pop();
};break;
}
}
}
};
int main()
{
Expression myExp;
myExp.Read();
myExp.ShowResult();
return 0;
}
Here are some issues I found:
Boolean Functions Return true or false
Match return types with return values. The numbers 1 and 0 are not Boolean values.
Precedence table
Add and subtract have same precedence.
Multiply and divide have same precedence.
Multiply and divide have higher precedence than add and subtract.
Stack disappears
Since the stack is declared as a local variable in the function, it will be created fresh when entering the function and destroyed before exiting the function.
Solution: move it to the class as a class member or declare it as static.
Multiple statements per line are not more efficient
Blank lines and newlines do not affect performance, and add negligible time to the build.
However, they make your program more readable which helps when inspecting or debugging. Use them.
And similarly with space before and after operators.
Build the habit now rather than correcting when you get a job.
Call function once and store the value
You call prec(entry2) twice, which is a waste of time. Call it once and save the value in a variable. Similarly with stack.TopShow().
Use std::vector not an array
The std::vector will grow as necessary and reduce the chance of buffer overflow.
With an array, you must check that your indices are always within range. Also, array capacities don't change; you have to declare a new instance and copy the data over.
The variable mx is not declared
The compiler should catch this one. You use mx as the capacity for an array and comparing for full. However, it is never declared, defined nor initialized. Prefer std::vector and you won't have to deal with these issues.
Input is not validated
You input a letter, but don't validate it.
Try these characters: space, #, #, A, B, etc.
Missing default for switch
Crank up your compiler warnings to maximum.
Your switch statements need defaults.
What precedence do numeric characters ('0'..'9') have?
(You check the precedence of numeric characters.)
Check all paths through your functions and program.
Using a debugger (see below) or pen and paper, check your program flow through you functions. Include boundary values and values not within the bounds.
Case statements: break or return
You don't need a break after a return statement. Think about it. Can the program continue executing at the line after a return statement?
Use a debugger or print statements
You can print variables at different points in your program. This is an ancient technique when debuggers are not available.
Learn to use a debugger. Most IDEs come with them. You can single step each statement and print out variable values. Very, very, useful.
class infixToPostfix{
public static void postfix(String str){
Stack<Character> stk = new Stack<Character>();
for(Character c : str.toCharArray()){
// If operands appears just print it
if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'){
System.out.print(c);
}else{
// Open paranthesis push is
if(c == '('){
stk.push(c);
//Close paranthesis pop until close paranthesis
}else if( c == ')'){
while(stk.peek() != '(')
System.out.print(stk.pop());
stk.pop();
// check the precedence of operator with the top of stack
}else if(c == '+' || c == '-'){
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '*' || top == '/' || top == '+' || top == '-'){
System.out.print(stk.pop());
}
}
stk.push(c);
}else{
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '/' || top == '*'){
System.out.print(stk.pop());
}
}
stk.push(c);
}
}
}
//Print all the remaining operands
while(!stk.isEmpty()) System.out.print(stk.pop());
System.out.println();
}
public static void main(String args[]){
String str = "A+B-(c+d*Z+t)/e";
postfix(str);
}
}
using stack and map u can solve the problem
1) create a map having operator as key and some integer to set priority. operator with same precedence will have same value something like:
map<char,int>oprMap;
oprMap['^'] = 3;
oprMap['*'] = 2;
oprMap['/'] = 2;
oprMap['+'] = 1;
oprMap['-'] = 1;
2) iterate through given expression call these checks
1) if current element
i) is operand add it to result
ii) not operand do following check
a. while not (stack is empty and element is open bracket and found operator with higher precedence.
add top of the stack to the result and pop()
b. push current element to stack
iii) if open brackets push to stack
iv) if closed brackets pop until get closed bracket and add it to result
3) while stack is not empty pop() and add top element to the result.
{
stack<char>S;
for (int i = 0; i < n; i++) {
if(isOperand(exps[i])) {
res = res + exps[i];
} else if(isOperator(exps[i])){
while(!(S.empty() && isOpenParanthesis(S.top()) && isHeigherPrecedence(S.top(),exps[i])){
res = res+S.top();
S.pop();
}
S.push(exps[i]);
} else if(isOpenParanthesis(exps[i])) {
S.push(exps[i]);
} else if(isClosingParanthesis(exps[i])) {
while(!S.empty() && !isOpenParanthesis(S.top())) {
res = res+S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
res = res + S.top();
S.pop();
}
}
}
#include<bits/stdc++.h>
using namespace std;
// This isHigher function checks the priority of character a over b.
bool isHigher(char a,char b)
{
if(a=='+' || a=='-')
return false;
else if((a=='*' && b=='*') || (a=='*' && b=='/') || (a=='/' && b=='*') ||
(a=='/' && b == '/')|| (a=='^' && b=='^')||(a=='*' && b=='^') || (a=='/' &&
b=='^'))
return false;
return true;
}
int main(){
string s;
cin>>s;
s = s + ")";
//Vector postfix contains the postfix expression.
vector<char>postfix;
stack<char>mid;
mid.push('(');
for(int i=0;i<s.length();i++)
{
if(s[i] == '(')
mid.push(s[i]);
else if(s[i] == '+' || s[i] == '^' || s[i] == '-' || s[i] == '*'||
s[i] == '/')
{
if(mid.top() == '(')
mid.push(s[i]);
else {
if(isHigher(s[i],mid.top()))
mid.push(s[i]);
else
{
while(mid.top()!='(')
{
if(!isHigher(s[i],mid.top()))
{
postfix.push_back(mid.top());
mid.pop();
}
else
break;
}
mid.push(s[i]);
}
}
}
else if(s[i] == ')')
{
while(mid.top() != '(')
{
postfix.push_back(mid.top());
mid.pop();
}
mid.pop();
}
else
postfix.push_back(s[i]);
}
for(int i=0;i<postfix.size();i++)
cout<<postfix[i];
return 0;
}