Log   |   Assignments   |   Source   |   Discussion   |   Feedback   |   About Me  |

This page lists the fifth version (v0.5) of the Quadratic Equation Solver. This file lists the ncurses UI. Quadratic equation solution is same as in earlier versions

/*
 * Advanced Computer Architecture
 * Assignment - 1
 * Read the coefficients of a Quadratic equation from the user
 * and calculate the roots using a function call. 
 *
 * Author: Kurian John (CS10M035)
 * Revision History
 * ----------------
 * 2011-02-22 - v0.5
 * 	- Added ncurses UI. Still buggy in many
 * 	  places and code not clean at all!
 * 2011-02-15 - v0.4
 * 	- Accepts leading spaces
 * 2011-02-08 - v0.3
 * 	- Accepts spaces between sign and number
 * 	- Tells user the guaranteed number of significant digits
 * 2011-02-01 - v0.2
 * 	Almost full rewrite
 * 	 - Better input validation
 * 	 - Handles equations where b*b is much larger
 * 	   than 4*a*c
 * 2011-01-18 - v0.1
 * 	Removed structure return and packed everything into 
 * 	a long double - Read comments for more info
 * 2011-01-05 - v0.0
 * 	New program - Calculate roots of a quadratic
 * 	equation using a function call and return the roots.
 */

#include <ncurses.h>
#include <string.h>
#include <malloc.h>
#include "solveEqn.h"

WINDOW *create_newwin(int height, int width, int aWinY, int startX);
void destroy_win(WINDOW *local_win);

void clearTextBoxen (int Y, int X, int charCount)
{
	int i;
	for (i=X; i<charCount+X; i++)
	{
		move (Y, i);
		addch (' ');
	}
	return;
}

int main(int argc, char *argv[])
{	WINDOW *aWin, *bWin, *cWin;
	int startX, aWinY, bWinY, cWinY, width, height, lMargin;
	int ch,errorLine,exitMessageLine, rootLine;
	int currXPos,i=0;
	int currYPos;
	int valuesEntered=0;
	int decimalEntered=0, waitingForDigits=1;
	float a,b,c;

	initscr();		
	cbreak();			
	noecho ();
	keypad(stdscr, TRUE); // To catch F3 to exit

	height = 3;
	width = 20;
	lMargin = 3;
	aWinY = 8;
	bWinY = aWinY+3;
	cWinY = aWinY+6;
	rootLine = 18;
	errorLine=22;
	exitMessageLine=23;
	startX = 25;	
	currXPos=startX+1;
	currYPos=aWinY+1;
	move (0,0);
	printw ("*--------------------------------------------------*\n");
	printw ("|          Quadratic Equation Solver               |\n");
	printw ("*--------------------------------------------------*\n");
	printw ("| Please enter the coefficients of a Quadratic     |\n");
	printw ("| Equation. Coefficients are numbers having less   |\n");
	printw ("| than 10 characters (including sign and decimal)  |\n");
	printw ("*--------------------------------------------------*\n");
	move (21,0);
	printw ("*--------------------------------------------------*\n");
	move (24,0);
	printw ("*--------------------------------------------------*\n");

	move (exitMessageLine, lMargin);
	printw("Press F3 to exit");
	move (aWinY+1,lMargin);
	printw ("Coefficient of X*X (a)");
	move (bWinY+1,lMargin);
	printw ("Coefficient of   X (b)");
	move (cWinY+1,lMargin);
	printw ("Constant term      (a)");
	refresh();
	//boundingWindow = create_newwin (20, 50, 0, 0);
	aWin = create_newwin(height, width, aWinY, startX);
	bWin = create_newwin(height, width, bWinY, startX);
	cWin = create_newwin(height, width, cWinY, startX);
	char* currString;
	currString = (char*) malloc (sizeof(char) * 2);
	currString[0]='\0';
	currString[1]='\0';
	move (aWinY+1, startX+1);
	while((ch = getch()) != KEY_F(3))
	{
		//move (LINES-2, 20);
		//printw ("| Current String: %s", currString);
		move (errorLine, lMargin);
		printw ("                                                             ");
		move (currYPos, currXPos );
		switch (ch)
		{
			case KEY_LEFT:
				if (currXPos > (startX+1))
					currXPos--;
				//move (LINES-2,lMargin);
				//printw ("Curr char: %c", currString[currXPos-startX-1]);
				break;
			case KEY_RIGHT:
				if ((currXPos-startX-1) < strlen(currString))
					currXPos++;
				//move (LINES-2,lMargin);
				//printw ("Curr char: %c", currString[currXPos-startX-1]);
				break;
			case 10://KEY_ENTER:
				if ( (strlen(currString) == 0) || waitingForDigits )
				{
					move (errorLine, lMargin);
					printw ("Coefficient cannot be empty!                ");
					flash ();
				}
				else
				{
					currYPos+=3;
					currXPos=startX+1;
					move (currYPos, currXPos );
					waitingForDigits=1;
					decimalEntered=0;
					valuesEntered++;
					if (valuesEntered == 1)
					{
						sscanf (currString, "%f", &a);
					}
					else if (valuesEntered == 2)
					{
						sscanf (currString, "%f", &b);
					}
					else if (valuesEntered == 3)
					{
						sscanf (currString, "%f", &c);
						callSolver (a,b,c);

						clearTextBoxen (rootLine, lMargin, 80);
						clearTextBoxen (rootLine+1, lMargin, 80);
						clearTextBoxen (rootLine+2, lMargin, 80);
						for (i=0; i<3; i++)
						{
							move (rootLine+i, 0);
							printw ("%s",responseString[i]);
							strcpy (responseString[i],"\0\0");
						}
						/*printw ("a: %16.8f\n", a);
						  printw ("b: %16.8f\n", b);
						  printw ("c: %16.8f", c);*/
						// Solve the equation here
						currYPos = aWinY+1;
						clearTextBoxen (aWinY+1, startX, 20);
						clearTextBoxen (bWinY+1, startX, 20);
						clearTextBoxen (cWinY+1, startX, 20);
						valuesEntered = 0;
					}
					free (currString);
					currString = (char*) malloc (sizeof(char) * 2);
					currString[0]='\0';
					currString[1]='\0';
				}
				break;
			case KEY_BACKSPACE:
				if (strlen(currString) > 0)
				{
					move (currYPos, currXPos-1);
					delch();
					if (currString[currXPos-startX-2] == '.')
						decimalEntered=0;
					for (i=currXPos-startX-2; i<strlen(currString);i++)
					{
						currString[i] = currString[i+1];
					}
					currXPos--;
					/*
					   for (i=0; i<20; i++)
					   {
					   move (LINES-4,i);
					   delch ();
					   }
					   */
					//printw ("Curr string: %s", currString);
				}
				if ( (strlen(currString) == 0) ||
						( (strlen(currString) == 1) && 
						  ( (currString[0]=='+') || 
						    (currString[0]=='-') || 
						    (currString[0]=='+') 
						  ) 
						) 
				   )
				{
					waitingForDigits=1;
				}
				break;

			case KEY_DC:
				delch();
				if (currString[currXPos-startX-1] == '.')
					decimalEntered=0;
				for (i=currXPos-startX-1; i<strlen(currString);i++)
				{
					currString[i] = currString[i+1];
				}
				if ( (strlen(currString) == 0) ||
						( (strlen(currString) == 1) && 
						  ( (currString[0]=='+') || 
						    (currString[0]=='-') || 
						    (currString[0]=='+') 
						  ) 
						) 
				   )
				{
					waitingForDigits=1;
				}
				break;
			default:
				if (strlen(currString) == 10)
				{
					move (errorLine, lMargin);
					printw ("Coefficients must be less than 10 digits long                ");
					flash ();
					continue;
				}	

				if (!isdigit (ch) ) 
				{
					if (ch == '.')
					{
						if (!decimalEntered)
						{
							decimalEntered = 1;
							currString = (char*) realloc (currString, sizeof(char) * strlen(currString) + 16);
							currString[strlen(currString)] = ch;
							currString[strlen(currString)+1] = '\0';
							currXPos++;
							addch (ch);	
						}
						else
						{
							flash ();
							move (errorLine, lMargin);
							printw ("Warning: Duplicate decimal point ignored");
						}
					}
					else if ( ((ch=='-') || (ch=='+')) && strlen(currString)==0) 
					{

						currString = (char*) realloc (currString, sizeof(char) * strlen(currString) + 16);
						currString[strlen(currString)] = ch;
						currString[strlen(currString)+1] = '\0';
						currXPos++;
						addch (ch);	
					}
					else
					{
						flash ();
						move (errorLine, lMargin);
						printw ("Warning: Invalid key pressed (%c)       ", ch);
					}
				}
				else
				{
					waitingForDigits=0;
					currString = (char*) realloc (currString, sizeof(char) * strlen(currString) + 16);
					currString[strlen(currString)] = ch;
					currString[strlen(currString)+1] = '\0';
					currXPos++;
					addch (ch);
				}
		}
		move (currYPos, currXPos );
	}
	endwin();		
	return 0;
}

WINDOW *create_newwin(int height, int width, int startY, int startX)
{	WINDOW *local_win;

	local_win = newwin(height, width, startY, startX);
	box(local_win, 0 , 0);	
	wrefresh(local_win);		

	return local_win;
}

void destroy_win(WINDOW *local_win)
{	
	wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
	wrefresh(local_win);
	delwin(local_win);
}