I am creating an OOP tic tac toe game. I cannot understand why certain things are not working properly. First of all, I cannot change my gameBoard array by passing in a number for column and another one for row and changing it in that function. Second, the checkWinner function should change the player if there is no one, but it does not seem to do that either. Here is my code:
TicTacToe.h:
#ifndef TICTACTOE_H
#define TICTACTOE_H
using namespace std;
class TicTacToe{
private:
int gameBoard[3][3];
int playerTurn = 1;
public:
TicTacToe();
void printBoard();
int printPlayer();
bool changeBoard(int, int);
bool checkWinner();
};
#endif
TicTacToe.cpp:
#include "TicTacToe.h"
#include <iostream>
using namespace std;
TicTacToe::TicTacToe(){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
gameBoard[i][j] = 0;
}
}
}
void TicTacToe::printBoard(){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
cout << gameBoard[i][j];
}
cout << endl;
}
}
int TicTacToe::printPlayer(){
return playerTurn;
}
bool TicTacToe::changeBoard(int r, int s){
if (gameBoard[r][s] == 0){
gameBoard[r][s] == playerTurn;
return true;
}
else{
return false;
}
}
bool TicTacToe::checkWinner(){
if (gameBoard[0][0] && gameBoard[1][0] && gameBoard[2][0] == playerTurn){
return true;
}
else if (gameBoard[0][1] && gameBoard[1][1] && gameBoard[2][1] == playerTurn){
return true;
}
else if (gameBoard[0][2] && gameBoard[1][2] && gameBoard[2][2] == playerTurn){
return true;
}
/*********************************/
if (gameBoard[0][0] && gameBoard[0][1] && gameBoard[0][2] == playerTurn){
return true;
}
else if (gameBoard[1][0] && gameBoard[1][1] && gameBoard[1][2] == playerTurn){
return true;
}
else if (gameBoard[2][0] && gameBoard[2][1] && gameBoard[2][2] == playerTurn){
return true;
}
/*********************************/
else if (gameBoard[0][0] && gameBoard[1][1] && gameBoard[2][2] == playerTurn){
return true;
}
else if (gameBoard[0][2] && gameBoard[1][1] && gameBoard[2][0] == playerTurn){
return true;
}
/*********************************/
else{
if (playerTurn == 1){
playerTurn == 2;
}
else{
playerTurn == 1;
}
return false;
}
}
TicTacToeApp.cpp:
#include "TicTacToe.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main(){
const int boardNumber = 3;
int selection;
int row;
int col;
TicTacToe gameBoard;
do{
cout << "Welcome to TicTacToe!" << endl
<< "1) Play Game" << endl
<< "2) Quit" << endl;
cin >> selection;
if (selection == 1){
do{
gameBoard.printBoard();
cout << "Player #" << gameBoard.printPlayer() << ":" << endl
<< "Row: ";
cin >> row;
row = row - 1;
cout << "\n";
cout << "Column: ";
cin >> col;
col = col - 1;
if (gameBoard.changeBoard(row, col) == false){
cout << "Invalid Selection, try again!" << endl;
}
gameBoard.checkWinner();
} while (gameBoard.checkWinner() == false);
if (gameBoard.checkWinner() == true){
cout << "Player " << gameBoard.printPlayer() << " wins!" << endl;
}
}
} while (selection != 2);
system("PAUSE");
return 0;
}
EDIT: I have changed my stupid errors now, but I still would not change the player to 2 when there is no winner. Here is my current code for that function:
bool TicTacToe::checkWinner(){
if (gameBoard[0][0] && gameBoard[1][0] && gameBoard[2][0] == playerTurn){
return true;
}
else if (gameBoard[0][1] && gameBoard[1][1] && gameBoard[2][1] == playerTurn){
return true;
}
else if (gameBoard[0][2] && gameBoard[1][2] && gameBoard[2][2] == playerTurn){
return true;
}
/*********************************/
else if (gameBoard[0][0] && gameBoard[0][1] && gameBoard[0][2] == playerTurn){
return true;
}
else if (gameBoard[1][0] && gameBoard[1][1] && gameBoard[1][2] == playerTurn){
return true;
}
else if (gameBoard[2][0] && gameBoard[2][1] && gameBoard[2][2] == playerTurn){
return true;
}
/*********************************/
else if (gameBoard[0][0] && gameBoard[1][1] && gameBoard[2][2] == playerTurn){
return true;
}
else if (gameBoard[0][2] && gameBoard[1][1] && gameBoard[2][0] == playerTurn){
return true;
}
/*********************************/
else{
if (playerTurn == 1){
playerTurn = 2;
}
else{
playerTurn = 1;
}
return false;
}
}
You cannot assign using == operator (unless you use operator overload).
Use = operator instead to assign (update values).
Related
Been scratching my head for hours already and I have no clue what my mistake is. I'm following my professor's derived algorithm step by step and I don't know why it isn't working properly.
Here's the derived Algorithm:
Here's the code that I tried to make:
#include <iostream>
#include "ecpe202.h"
#define Max 100
using namespace std;
int getICP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 4;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 4;
}
}
int getISP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 3;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 0;
}
}
bool isOperator(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '*' || ch == '(' || ch == ')'){
return (true);
}
else{
return (false);
}
}
int main(){
char infix[Max];
char ch;
int length;
myQueue que;
myStack stk;
createQ(que);
createS(stk);
cout << "Enter an infix Expression: ";
cin >> infix;
cout << endl << endl;
cout << "The postfix Expression: ";
length = strlen(infix);
for (int i = 0; i < length; i++){
addQ(que, infix[i]);
}
while (!isEmptyQ(que)){
ch = retrieveQ(que);
//start of infix to postfix algo
//1. push
if (ch == '('){
pushS(stk, ch);
}
//2. if scanned is operand
if (!isOperator(ch)){
cout << ch;
}
else{
//2.1 push if...
if (isEmptyS(stk) || getICP(ch) > getISP(topS(stk)) || topS(stk) == '('){
pushS(stk, ch);
}
//2.2. pop all operators
else{
while(!isEmptyS(stk) && getISP(topS(stk)) >= getICP(ch) || topS(stk) == '('){
cout << popS(stk);
}
}
pushS(stk, ch);
}
//3. If scanned ')'
bool loop = true;
if (ch == ')'){
do{
if (ch == '('){
loop = false;
}
else{
cout << popS(stk);
}
}while(loop == true);
}
//repeat 1-3
}
cout << endl;
}
For the ecpe202.h:
#include<dos.h>
#include<windows.h>
#define FOREVER true
#define MAXSTACK 100
#define MAXQUEUE 100
using namespace std;
struct myStack{
int tos;
char s[MAXSTACK];
};
struct myQueue{
int head, tail, q[MAXQUEUE];
};
//STACK
void createS(myStack &S){
S.tos=-1;
}
void pushS(myStack &S, char item){
S.s[++S.tos] = item;
}
char popS(myStack &S){
return(S.s[S.tos--]);
}
char topS(myStack S){
return (S.s[S.tos]);
}
bool isFullS(myStack S){
if(S.tos == MAXSTACK - 1)
return true;
return false;
}
bool isEmptyS(myStack S){
if (S.tos == -1)
return true;
return false;
}
//QUEUE
void createQ(myQueue &Q){
Q.head = 0;
Q.tail = 0;
}
void addQ(myQueue &Q, char item){
Q.q[Q.tail++] = item;
Q.tail %= MAXQUEUE;
}
char retrieveQ(myQueue &Q){
char temp;
temp = Q.q[Q.head++];
Q.head %= MAXQUEUE;
return temp;
}
bool isFullQ(myQueue Q){
if (Q.tail == MAXQUEUE)
return true;
return false;
}
bool isEmptyQ(myQueue Q){
if (Q.tail == Q.head)
return true;
return false;
}
//GOTOXY
void gotoxy(int x, int y){
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void clrscr(){
system("CLS");
}
The output that my code:
What seems to be wrong in my program? tried re-reading it a couple of times and I still can't fix it.
I am trying to make a game on the console using C++. At the moment, I have three functions in the main.
int main() {
...
while (!level1 && !player.dead) {
drowing(l1_map);
PlayerMovements(empty, l1_map);
Enemy1Movements(enemy1, l1_map, lastloc);
cls();
}
}
The first function draws the map:
void drowing(char l1_map[26][50]) {
for (unsigned int i = 0; i < 26; i++) {
cout << endl;
for (unsigned int x = 0; x < 50; x++) {
if (x == 0) {
cout << " ";
}
//Draws the map and change colours;
//player
if (l1_map[i][x] == player.character) {
if (l1_map[player.locX][player.locY] == l1_map[enemy1.locX][enemy1.locY]) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 252);
cout << l1_map[i][x];
}
if (l1_map[player.locX][player.locY] != l1_map[enemy1.locX][enemy1.locY]) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 250);
cout << l1_map[i][x];
}
}//wall
else if (l1_map[i][x] == wall) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 128);
cout << l1_map[i][x];
}//enemy
else if (l1_map[i][x] == enemy1.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 252);
cout << l1_map[i][x];
}//empty space
else if (l1_map[i][x] == 32) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 509);
cout << l1_map[i][x];
}//key1
else if (l1_map[i][x] == key1.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 509);
cout << l1_map[i][x];
}//key2
else if (l1_map[i][x] == key2.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//key3
else if (l1_map[i][x] == key3.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//doors1
else if (l1_map[i][x] == doors1.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//doors2
else if (l1_map[i][x] == doors2.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//doors3
else if (l1_map[i][x] == doors3.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//doors4
else if (l1_map[i][x] == doors3.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//exit
else if (l1_map[i][x] == get_out1.character && !get_out1.open) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 139);
cout << l1_map[i][x];
}
else
{
cout << l1_map[i][x];
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
}
}
}
}
Second function allows player to move on the map using keyboard arrows:
void PlayerMovements(char& empty, char l1_map[26][50]) {
char awall = 219;
if (_kbhit()) {
switch ((_getch())) { //what button is pressed;
// move up
case 72:
if (l1_map[player.locX - 1][player.locY] != wall && l1_map[player.locX - 1][player.locY] != '[') {
player.locX--;
if (l1_map[player.locX + 1][player.locY] == player.character) {
l1_map[player.locX + 1][player.locY] = empty;
}
if (key3.locX == player.locX && key3.locY == player.locY) {
l1_map[key3.locX][key3.locY] = ' ';
}
}
break;
//move down
case 80:
if (l1_map[player.locX + 1][player.locY] != wall && l1_map[player.locX + 1][player.locY] != '[') {
player.locX++;
if (l1_map[player.locX - 1][player.locY] == player.character) {
l1_map[player.locX - 1][player.locY] = empty;
}
}
break;
case 75:
//left
if (l1_map[player.locX][player.locY - 1] != wall && l1_map[player.locX][player.locY - 1] != '[') {
player.locY--;
if (l1_map[player.locX][player.locY + 1] == player.character) {
l1_map[player.locX][player.locY + 1] = empty;
}
}
break;
case 77: // player moves right
if (l1_map[player.locX][player.locY + 1] != wall && l1_map[player.locX][player.locY + 1] != '[') {
player.locY++;
if (l1_map[player.locX][player.locY - 1] = player.character) {
l1_map[player.locX][player.locY - 1] = empty;
}
}
break;
}
}
}
Third function is the enemy that moves up and down:
int Enemy1Movements(enemy& enemy1, char l1_map[26][50], char& lastloc) {
//this_thread::sleep_for(chrono::milliseconds(500));
char empty = ' ';
bool ValidUp = false;
bool ValidDown = false;
bool ValidLeft = false;
bool ValidRight = false;
if (l1_map[enemy1.locX + 1][enemy1.locY] != wall && l1_map[enemy1.locX + 1][enemy1.locY] != '-') {
ValidDown = true;
}
if (l1_map[enemy1.locX - 1][enemy1.locY] != wall && l1_map[enemy1.locX - 1][enemy1.locY] != '-') {
ValidUp = true;
}
if (l1_map[enemy1.locX][enemy1.locY - 1] != wall && l1_map[enemy1.locX - 1][enemy1.locY] != '-') {
ValidLeft = true;
}
if (l1_map[enemy1.locX][enemy1.locY + 1] != wall && l1_map[enemy1.locX + 1][enemy1.locY] != '-') {
ValidRight = true;
}
////enemy move up and down
//////////////////////////
if (lastloc != 'u' && ValidDown) {
enemy1.locX++;
lastloc = 'd';
if (l1_map[enemy1.locX - 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX - 1][enemy1.locY] = 32;
}
}
else if (lastloc == 'd' && ValidUp) {
enemy1.locX--;
lastloc = 'u';
if (l1_map[enemy1.locX + 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX + 1][enemy1.locY] = 32;
}
}
else {
if (ValidUp) {
enemy1.locX--;
lastloc = 'u';
if (l1_map[enemy1.locX + 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX + 1][enemy1.locY] = 32;
}
}
else {
enemy1.locX++;
lastloc = 'd';
if (l1_map[enemy1.locX - 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX - 1][enemy1.locY] = 32;
}
}
}
return NULL;
}
What I am tryng to achieve:
I need to slow down the EnemyMovemens() function, because the enemy moves to fast. Or to make PlayerMovements() function independent from other functions.
The Problem:
I have tried to use threads. Functions like this_thread::sleep_for() and Sleep(). To put them in EnemyMovements() function. In that case, it slow down all app and my player moves very slowly.
I dont need a code, because I love to learn by myself. I just need a guidance what direction to move now.
OS: Win 10
The basic problem is that you don't having any timing in your game loop so everything is happening at the same speed. There are some good articles online that discuss game timing loops, this one for instance: http://www.koonsolo.com/news/dewitters-gameloop/ walks you through the steps from the approach you're using now to the better approach of separating your game update timing from your display timing.
That article doesn't tell you how to slow your enemy down relative to your player - one approach is to have a enemySpeed variable and use something like:
// outside main loop
int enemySlowness = 20; // adjust this as needed
int enemyMoveTimer = 0;
...
if (++enemyMoveTimer > enemySlowness)
{
Enemy1Movements(enemy1, l1_map, lastloc);
enemyMoveTime = 0;
}
There are problems with this approach, but coupled with some idea from that article should get you on the right track.
I'm working on a program for a computer science class. I have everything completed and separated into the interface/implementation and for some reason, the program loops infinitely and says "Stack is empty!" after the peek() function is called.
I've tried inserting cout << statements to see if I can pinpoint the issue, however, no luck. I would appreciate it if someone else could take a look at it.
Thank You
Header
#ifndef STACK_H
#define STACK_H
/////////////////////////////////////////////////////
////Includes/////////////////////////////////////////
/////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdlib.h>
#include <iomanip>
#include <sstream>
#include <stdio.h>
/////////////////////////////////////////////////////
using namespace std;
/*-------------------------------------------------------------------------------------------------------------*/
template <typename Object>
class Stack
{
private:
class stackListNode
{
public:
Object data;
stackListNode *next;
private:
//Nothing to declare-->placeholder since class
//sets data members to private initially
};
stackListNode *top;
public:
/////////////////////////////////////////////////
//Constructor Function//////////////////////////
Stack() {top = NULL;}
/////////////////////////////////////////////////
//Rest of functions defined inline for simplicity
void push(char token) // Push token onto the stack and create new node for top of stack
{
stackListNode *newNode = new stackListNode;
newNode->data = token;
newNode->next = top;
top = newNode;
}
int pop()
{
if(empty())
{
cout << "Stack is empty!\n" << endl;
return NULL;
}
stackListNode *temp = top;
top = temp->next;
}
char peek()
{
if(empty())
{
cout << "Stack is empty!\n" << endl;
return NULL;
}
return top->data;
}
int empty()
{
return top == NULL;
}
};
#endif
Main File:
/////////////////////////////////////////////////////
////Includes/////////////////////////////////////////
/////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <string>
#include "Stack.h"
/////////////////////////////////////////////////////
using namespace std;
int precendence(char stack_beginning); //ensures order of operations.
int precendence(char*myArray);
void InFixToPostfix(ifstream& in_file);
double EvaluatePostfix(double first_operand, double second_operand, char*myArray);
int main()
{
////VARS/////////////////////////////////////////////
string absolutePath;
cout << endl;
cout << "Please type in the name of the file you would to open \n";
cin >> absolutePath;
ifstream in_file;
in_file.open(absolutePath.c_str());
if(!in_file)
{
cout << "failed to open input file\n" ;
return 1 ;
}
else
{
InFixToPostfix(in_file); //kicks off program
}
}
void InFixToPostfix(ifstream& in_file)
{
string infix;
int right_parentheses =0;
int left_parentheses =0;
while(getline(in_file, infix))
{
char myArray[infix.size()];
strcpy(myArray, infix.c_str());
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '(')
{
right_parentheses++;
}
if(myArray[i] == ')')
{
left_parentheses++;
}
}
if(right_parentheses!=left_parentheses)
{
cout << endl;
cout << "There is a typo in one of the expressions in your file \n";
cout << "Please fix it and rerun the program \n";
exit(1);
}
for(int i = 0; i < sizeof(myArray); i++)
{
//int number = int(myArray[i]);
//deferences the pointer and reads each char in the array
//as an int rather than a character.
//int number = myArray[i];
if(isxdigit(myArray[i]) > 0) //function used to check for hexidecimal values (i.e. int's)
{
goto exit_out;
}
else if(myArray[i] == '(' || myArray[i] == ')' || myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '*' || myArray[i] == '/' || myArray[i] == '\\' || myArray[i] == '\n')
{
goto exit_out;
}
else if(myArray[i] == char(32)) //checks to see if there is a space
{
goto exit_out;
}
else
{
cout << endl;
cout << "There is an invalid character in the file\n";
exit(1);
}
exit_out:;
}
////////Declares a STRING Stack////////////////////////////////
Stack<char> stack_string;
////////Declares an Int Stack/////////////////////////////////
Stack<int> stack_int;
//////////////////////////////////////////////////////////////
for(int i = 0; i < sizeof(myArray); i++)
{
int number = isxdigit(myArray[i]);
if(number > 0)
{
cout << number;
//outputs the number b/c it is an operand
}
if(myArray[i] == '(')
{
stack_string.push(myArray[i]);
}
if(myArray[i] == ')')
{
//cout << "test";
while(stack_string.peek() != '(')
{
cout << stack_string.peek();
stack_string.pop(); //pops to the peek
}
stack_string.pop(); // if there is a ), pops to the peek
}
if(myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '/' || myArray[i] == '*')
{
if(stack_string.empty())
{
stack_string.push(myArray[i]); //if there's nothing on the stack, pushes the current character
//goto done;
break; //breaks out of the statement
}
char stack_beginning = stack_string.peek();
int stack_top = precendence(stack_beginning);
//int stack_top = precendence(stack_string.peek());
int operatorHierarchy = precendence(myArray);
//must be declared here because i will have been interated through array
if(operatorHierarchy > stack_top)
{
stack_string.push(myArray[i]);
}
else if(operatorHierarchy <= stack_top) //could also be an if
{
dump_out:;
cout << stack_string.peek();
stack_string.pop();
int rerunThroughStack =0;
char new_stack_beginning = stack_string.peek();
rerunThroughStack = precendence(new_stack_beginning);
if(operatorHierarchy < stack_top)
{
stack_string.push(myArray[i]);
goto done; //could break
}
if(stack_string.peek() == '(')
{
stack_string.push(myArray[i]);
goto done;
}
if(stack_string.empty())
{
stack_string.push(myArray[i]);
goto done;
}
goto dump_out;
}
}
done:;
}
cout << stack_string.peek() << endl;
//////////Evaluate Section/////////////////////////////
for(int i = 0; i < sizeof(myArray); i++)
{
if(isxdigit(myArray[i]) > 0) //this is a number
{
stack_int.push(isxdigit(myArray[i]));
goto end;
}
else if(myArray[i] == '*' || myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '/')
{
double first_operand;
first_operand = stack_int.peek(); //fetches first operand on the stack_int
stack_int.pop();
//////////////////
double second_operand;
second_operand = stack_int.peek();
stack_int.pop();
//////////////////
double answer;
answer = EvaluatePostfix(first_operand, second_operand, myArray); //THIS PROBABLY IS NOT RIGHT
stack_int.push(answer);
}
end:;
}
/*
int size_of_stack;
size_of_stack = stack_int.size();
if(size_of_stack == 1)
{
cout << stack_int.peek();
}
*/
}
}
double EvaluatePostfix(double first_operand, double second_operand, char* myArray) //might have to pass array as reference
{
/*
Cycle through the characters passed in through myArray[i];
*/
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '*')
{
double first_answer;
first_answer = (second_operand * first_operand);
return first_answer;
}
else if(myArray[i] == '/')
{
double second_answer;
second_answer = (second_operand / first_operand);
return second_answer;
}
else if(myArray[i] == '+')
{
double third_answer;
third_answer = (second_operand + first_operand);
return third_answer;
}
else if(myArray[i] == '-')
{
double fourth_answer;
fourth_answer = (second_operand - first_operand);
return fourth_answer;
}
/*
else
{
cout << "There must be an error in your file" <<endl;
break;
exit(1);
}
*/
}
}
int precendence(char stack_beginning)
{
int precendence;
if(stack_beginning == '*' || stack_beginning == '/')
{
precendence = 2;
return precendence;
}
//by making it 2, the precendence is dubbed less than +/-
if(stack_beginning == '+' || stack_beginning == '-')
{
precendence = 1;
return precendence;
}
} //by making it 1, the precendence is dubbed greater than */"/"
int precendence(char*myArray)
{
int precendence;
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '*' || myArray[i] == '/')
{
precendence = 2;
return precendence;
}
//by making it 2, the precendence is dubbed less than +/-
if(myArray[i] == '+' || myArray[i] == '-')
{
precendence = 1;
return precendence;
}
} //by making it 1, the precendence is dubbed greater than */"/"
}
I'm pretty green at C++, and I have to make an infix to postfix calculator that supports sin() and cos(), and it has to be a 2 variable function, something like z=3x*sin(3+4y), I already got the parser from infix to postfix, but I don't know how to implement sin and cos, I've been told that I could set them as operator, like +, -, /, etc. and to set a specific token for them, like "s" for sin() and "c" for cos() but I don't exactly know how, and I don't know either how to implement the variables x & y, I know that this is not something I should be asking, but I'm just tired and desperate.
Here's the code I have. I'm using Ubuntu 11:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#define MAX_SIZE 20
using namespace std;
template<class T> class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout << "Stack Error" << endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
{
return item[top--];
}
else
{
cout << "Stack is Empty" << endl;
exit(11);
}
}
int size()
{
return top + 1;
}
bool is_empty()
{
if(top == -1)
return true;
else
return false;
}
bool is_full()
{
if(top == MAX_SIZE - 1)
return true;
else
return false;
}
void display()
{
for(int i = 0; i < this->size(); i++)
{
cout << item[i] << " ";
}
cout << endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool two_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->two_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1 == '+' || op1 == '-' || op1 == '*' || op1 == '/') && op2 == '(')
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1 == '$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op >= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op =='+' || op =='-' || op == '/' || op =='*' || op =='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop;
Stack<char> stack;
for(position = 0; (c = infix[position]) != '\0'; position++)
{
if(this->isOperand(c))
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count >= 2)
{
this->two_digit_flag = true;
}
}
else if(this->isOperator(c))
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position + 1]))
{
cout << " '\' aMissing argument in between " << infix[position] << " and " << infix[position + 1] << " in column " << position + 1 << endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop = stack.return_top();
stack.push(c);
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] = temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop == '(')
break;
}
stack.push(c);
stacktop = stack.return_top();
}
}
else if(c == '(')
{
count = 0;
stack.push(c);
stacktop = stack.return_top();
}
else if(c == ')')
{
count = 0;
while(1)
{
if(stack.size() == 0)
{
cout << "Warning!! Number of ')' is greater than '('" << endl;
exit(2);
}
temp = stack.pop();
if(temp != '(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop = stack.return_top();
}
else
{
cout << "Invalid input";
exit(3);
}
if(infix[position] == ')' && infix[position + 1] == '(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size() != 0)
{
cout << "Warning!!Number of '(' is greater than ')'" << endl;
// exit(6);
}
if(!this->return_flag())
{
cout << "You must Enter Numeric value for calculation" << endl;
cout << "This program cannot perform operations on variables";
exit(5);
}
if(this->two_digit_flag)
{
cout << "Sory! Althoug u may have entered right string" << endl;
cout << "this program is only for single digit operation" << endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &);
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+': return (op1 + op2);
case '-': return (op1 - op2);
case '*': return (op1 * op2);
case '/': return (op1 / op2);
case '^': return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[], Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position]) != '\0'; position++)
{
if(convert.isOperand(c))
{
temp1 = double(c - '0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size() == 0)
{
cout << "This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size() >= 2)
{
cout << "Sory! this program cannot calculate this" << endl;
cout << "Enter +, *, /, - or ^ between bracket" << endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout << "Enter string: ";
cin >> infix;
cout << endl;
cout << "Entered String: " << infix << endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout << "Equivalent Postfix string: " << postfix << endl;
cout << "RESULT: ";
cout << evaluate.eval(postfix, convert);
cout << "\nCalculate another string?(y/n) ";
cin >> choice;
cout << endl;
if(choice == 'n')
break;
}
return 0;
}
So here's my problem:
I'm supposed to write a c++ program that checks a string to be balanced. So far I have the code working to make sure that it has the same number of ('s and )'s (the same with ['s and {'s). The problem is that this works for almost everything, but it doesn't work for strings where the {'s, ('s and ['s all get mixed up.
For example: "{ { [ ( ) ] } ( ) }" comes back as balanced (true) as it should. However, "{ ( [ ] } )" comes back true, but it shouldn't.
What are some ideas in the logic and/or code that would check for when they're out of order?
Thanks for any help!
In case it helps, my code follows:
bool ExpressionManager::isBalanced(string expression)
{
//remove whitespace
string edited;
for(int i = 0; i < expression.length(); i++)
{
if(expression[i] == ' ')
{
continue;
}
else
{
edited += expression[i];
}
}
expression = edited;
//set up brckets
string brackets;
for(int i = 0; i < expression.length(); i++)
{
if (expression.at(i)=='(')
{
brackets += expression.at(i);
}
if (expression.at(i)=='[')
{
brackets += expression.at(i);
}
if (expression.at(i)=='{')
{
brackets += expression.at(i);
}
if (expression.at(i)=='}')
{
brackets += expression.at(i);
}
if (expression.at(i)==']')
{
brackets += expression.at(i);
}
if (expression.at(i)==')')
{
brackets += expression.at(i);
}
}
int parenbal = 0;
int brackbal = 0;
int mustachebal = 0;
for (int i = 0; i<(brackets.size());i++)
{
if(brackets[i]=='(')
parenbal++;
if(brackets[i]=='[')
brackbal++;
if(brackets[i]=='{')
mustachebal++;
if(brackets[i]==')')
parenbal--;
if(brackets[i]==']')
brackbal--;
if(brackets[i]=='}')
mustachebal--;
}
bool isbalanced = false;
if ((mustachebal==0)&&(brackbal==0)&&(parenbal==0))
{
isbalanced = true;
}
//check for brackets mixed up with other stuff.
return isbalanced;
}
If you employ a Stack to store those tokens, then you are always looking for the closing-counterpart corresponding to the one on the top of the stack or an open-token.
The flow would be
If the token is an open token, push it onto the stack.
If the token is a close token, check if the top of the stack is the corresponding open-token. If it is, then pop the stack as you found them balanced. If it is not, then it's an error.
Seems more like a homework assignment. So I would comment accordingly and allow you to learn a few things.
Always initialize your variables. strings are not initialized in your code.
You do not iterate over the string three time, you can check the string only once.
Use if-else if-else structure instead of if-if-if structure.
Always use brackets braces
Be consistent with your usage, either use at() or [], but dont mix them in code.
//this code may help you check string for balanced brackets with no
//repeated brackets,paranthesis or braces (e.g. [2*{3/(1+2)}].Note: no repeatance of
//brackets
#include <iostream.h>
#include <conio.h>
#include "IntStack.h"
#include <stdio.h>
void main(void)
{
char bracket[20];
gets (bracket);
char arr[6];
int i=0;
while(i<20)
{
switch(bracket[i])
{
case '[':
{
arr[0]=1;
break;
}
case '{':
{
arr[1]=2;
break;
}
case '(':
{
arr[2]=3;
break;
}
case ')':
{
arr[3]=3;
break;
}
case '}':
{
arr[4]=2;
break;
}
case ']':
{
arr[5]=1;
break;
}
default:
cout<<"";
}
i++;
}
if(arr[3]==arr[2])
cout<<"";
else
cout<<" ) or ( is missing "<<endl;
if(arr[1]==arr[4])
cout<<"";
else
cout<<" } or { is missing "<<endl;
if(arr[5]==arr[0])
cout<<"";
else
cout<<" ] or [ is missing"<<endl;
}
void check_brackets (string bituy)
{
int flag = 1
int count[6] = {0, 0, 0, 0, 0, 0};
stack<char> barstack;
for (int i = 0; i < bituy.length(); i++)
{
if (bituy[i] == '{')
count[0]++;
else if (bituy[i] == '}')
count[1]++;
else if (bituy[i] == '(')
count[2]++;
else if (bituy[i] == ')')
count[3]++;
else if (bituy[i] == '[')
count[4]++;
else if (bituy[i] == ']')
count[5]++;
}
for (int i = 0; i < 6; i += 2)
{
if (count[i] != count[i+1])
{
cout << "Wrong Syntax!" << endl;
flag = 0;
break;
}
}
if (flag)
{
for (int i = 0; i < bituy.length(); i++)
{
if (bituy[i] == '{' || bituy[i] == '(' || bituy[i] == '[')
barstack.push(bituy[i]);
else
{
if ((barstack.top() == '{' && bituy[i] == '}') || (barstack.top() == '(' && bituy[i] == ')') || (barstack.top() == '[' && bituy[i] == ']'))
barstack.pop();
else
{
cout << "Wrong Syntax!" << endl;
flag = 0;
break;
}
}
}
}
if (flag)
cout << "No Errors!" << endl;
}
#include<bits/stdc++.h>
using namespace std;
bool isBalance(char n[],int size){
int i,count=0;
//int size=strlen(n);
for(i=0;i<size;i++){
if(n[i]=='{'||n[i]=='['||n[i]=='('){
count ++;
}
else if(n[i]=='}'||n[i]==']'||n[i]==')'){
count --;
}
else return -1;
}
if(count==0)
return true;
else
return false;
}
int main(){
char n[1000];
gets(n);
int size=strlen(n);
bool result=isBalance(n,size);
if(result==true)
cout<<"Balance";
else
cout<<"Not Balance";
return 0;
}
//bracket Chaecker program
void bracket_checker()
{
int i=0;
char d;
char ch;
int count=0;
char *s = new char[21];
fstream out;
out.open("brace.txt",ios::in);
while(out>>d)
{
if(d =='}'|| d ==')' || d == '{' || d =='(')
{
s[i]=d;
i++;
}
}
if (i % 2 != 0)
cout <<"\ninvalid braces";
else if (( s[0] == '}' || s[0]==')' || s[0]==']') || (s[i]=='{' || s[i]=='(' || s[i]=='[' ))
cout <<"\n invalid braces";
else
{
for(int a=0; a<i; a++)
{
if (s[a] == '(' || s[a] == '{' || s[a] =='[' )
push1(s[a]);
if((s[a]=='(' && (s[a+1]=='{' || s[a+1]=='}')) || (s[a]=='[' && (s[a+1]=='{' || s[a+1]=='}')))
break;
else
if (s[a] == ')' || s[a] == '}' )
{
if (head != NULL)
{
ch = pop1();
if( ch == '{' && s[a] == '}' || ch == '(' && s[a] == ')' || ch=='[' && s[a]==']')
cout <<" ";
else
break;
}
else
break;
}
}
if(head==NULL)
cout <<" valid";
else
cout <<"In Valid";
}
}