Thursday 27 October 2016

simple password based authentication program in c++

#ifdef __linux__
#include <unistd.h>
#endif
#include <iostream>
#include <stdlib.h>
#ifndef __linux__
#include <conio.h>
#endif

using namespace std;

int main()
{
 string pass = "";
#ifdef __linux__
    system("clear");
    pass  = getpass("Enter Password : ");
#else
    system("cls");
    char ch;
    cout << "Enter Password : ";
    ch = _getch();
    while(ch != 13) //character 13 is enter
    {
        pass.push_back(ch);
        cout << '*';
        ch = _getch();
    }
#endif
    if(pass == "Hello")
    {
        cout << "\nAccess granted :P\n";
        //Further processing goes here...
    }
    else
    {
        cout << "\nAccess aborted...\n";
    }
}

Hash Table

//linklist_impl.hpp
#include<string>
using namespace std;
class linklist
{
    int c;
    struct node
    {
    public:
        string data;
        node *link;
    } *p;
public:
    linklist();
    void append(string &str);
    void del(string &str);
    void display();
    string getData();
    int searchlist(string);
    bool isListEmpty();
    ~linklist();
};

//linklist_impl.cpp
#include <iostream>
#include <string>
#include <cstring>
#include "linklist_impl.hpp"
using namespace std;


linklist::linklist()
{
    p = NULL;
    c = 0;
}

void linklist::append(string &str)
{
    node *q, *t;
    if(p==NULL)
    {
        p = new node;
        p->data = str;
        p->link = NULL;
        c += 1;
    }
    else
    {
        q = p;
        while(q->link != NULL)
        {
            q = q->link;
        }
        t = new node;
        t->data = str;
        t->link = NULL;
        q->link = t;
        c += 1;
    }
}

void linklist::del(string &str)
{
    node *q, *r;
    q = p;
    if(q->data == str)
    {
        p = q->link;
        delete q;
        c -= 1;
        return;
    }
    r = q;
    while(q != NULL)
    {
        if(q->data == str)
        {
            r->link = q->link;
            delete q;
            c -= 1;
            return;
        }
        r = q;
        q = q->link;
    }
    cout<<"Element "<<str<<" not found"<<endl;
}

void linklist::display()
{
    node *q;
    int i;
    for(q = p, i = 0; q != NULL, i < c; q = q->link, i++)
    {
        cout<<"\t"<<i<<": "<<q->data<<endl;
    }
}

string linklist::getData()
{
  return p->data;
}

bool linklist::isListEmpty()
{
    node *q;
    int i,flag = 0;
    for(q = p, i = 0; q != NULL, i < c; q = q->link, i++)
    {
      if(q->data != "")
        flag = 1;
    }
    if(flag == 1)
      return false;
    else
      return true;
}

int linklist::searchlist(string searchItem)
{
    node *q;
    int i;
    for(q = p, i = 0; q != NULL, i < c; q = q->link, i++)
    {
      if(q -> data == searchItem)
        return i;
    }
    return -1;
}

linklist::~linklist()
{
    node *q;
    if(p == NULL)
    {
        return;
    }
    while(p != NULL)
    {
        q = p->link;
        delete p;
        p = q;
    }
}


</cstring></string></iostream>

//schashtable.cpp
#include<iostream>
#include<sys/time.h>
#include<stdlib.h>
#include<stdio.h>
#include<limits>
#include<cstring>
#include "linklist_impl.hpp"

using namespace std;
struct timeval starttime,endtime,timediff;
enum {FILLED = 0 , ALL};
const int sizeHTable = 5;


class table
{

private:
    linklist *items;
    int nel;
    int strhash(const char *str);
public:
    table(int size);
    ~table();
    void addItem();
    int searchTable(string);
    void delItem();
    void display( int mode);
    int getCount();
    bool isEmpty();
};

#define BAD_INPUT_CUTOFF 3
unsigned int getIntInRange(unsigned int min, unsigned int max,
                           const char *prompt)
{
    int input, //used to get input
    bad_count=0; //used to keep track of how many bad attempts.
    do
    {
        std::cout << prompt;
        std::cin >> input;
        if (!std::cin.good() || input < min || input > max)
        {
            std::cout << "\nInvalid Input!" << std::endl;
            std::cin.clear(); //resets the state flag
            
//clears out the buffer
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
                   
            bad_count++; //User made a bad input, count it
            input = 0;   // user did not enter a valid number
        }
        //See if this is a valid number (users are mean/stupid sometimes)
    }
    while (input == 0 && bad_count < BAD_INPUT_CUTOFF);
    return input;
}


table::table(int size)
{
    items = new linklist[size];
    for(int i = 0; i<sizeHTable ;i++)
    nel = 0;
}

table::~table()
{  
    if(items)
    delete[] items;
}

int table::strhash(const char *str) {
    unsigned long hash = 0;
      int i=0;
        while(i <= strlen(str)) {
              hash = hash + (hash<<5) + (unsigned long)(str[i]);
                  i++;
                    }
          return (hash%sizeHTable); //return the hashed number which must be 
                                    //between 0 an size-1, this is why I used
                                    //hash%size
}

void table::addItem()
{
        string str;
        
        cout<<"\nEnter Data : ";
        cin>>str;

        
        int i = strhash(str.c_str());
        if( i >= 0 && i < sizeHTable )
        {
            items[i].append(str);
            cout<<"\nInserted";
            nel++;
            return;
        }

}

int table::searchTable(string searchItem)
{
    int pos;
    
    int i = strhash(searchItem.c_str());

    if((pos = items[i].searchlist(searchItem)) != -1 )
    {
        cout<<"Bucket["<<i<<"] -> pos : "<<pos<<"\t" <<"\t"<< endl;
        return i;
    }
    else
    {
            cout<<"Data "<<searchItem<<" not present in the table" << endl;
            return -1;
    }
}

void table::delItem()
{
    string item;
    cout<<"\nEnter an item to delete : ";
    cin>>item;
    
    int index;
    index = strhash(item.c_str());
        items[index].del(item);
        nel--;
}

bool table::isEmpty()
{
    if( nel > 0)
    {
        return false;
    }
    else
    {
        cout<<"\nTable is Empty"<<endl;
        return true;
    }
}

void table::display(int mode = FILLED)
{
    if(isEmpty())
        return;

   if(mode == FILLED)
   {
     int i;
     for(i=0; i<sizeHTable; i++)
     { 
        if(items[i].isListEmpty() == false)
        {
          cout<<"Bucket["<<i<<"] :"<<endl;
          items[i].display(); //call the function of our linked list,
                              //which outputs it's records with their indexes
        }
     }
   } 
   else if(mode == ALL)
   {
     int i;
     for(i=0; i<sizeHTable; i++)
     {
        cout<<"Bucket["<<i<<"] :"<<endl;
        items[i].display(); //call the function of our linked list,
                            //which outputs it's records with their indexes
     }
   } 
}

int table::getCount()
{
    return nel;
}

int main()
{
    int choice;
    
    string item;
    table T1(sizeHTable);
    int mode;

    while(1)
    {
        choice = getIntInRange(1,6,"\n1.Add New Item\n2.Delete Item
                 \n3.Search Item \n4.Display Hash Table \n5.Get the
                  number of elements \n6.Exit\nEnter your choice : ");
        
            switch(choice)
            {
            case 1 :
                T1.addItem();
                break;
            case 2 :
                T1.delItem();
                break;
            case 3 :
                if(T1.isEmpty() != true)
                {
                    cout<<"\nEnter an item to search : ";
                    cin>>item;
                    T1.searchTable(item);
                }
                break;
            case 4 :
                cout<<"\nEnter display mode (0 - FILLED / 1- ALL) : ";
                cin>>mode;
                T1.display(mode);
                break;
             case 5 :
                cout<<"Total no. of elements : "<<T1.getCount()<<endl;
                break;
             case 6 :
                exit(0);
            }
        
    }
    
    
}

Virtual Functions

#include <iostream>
using namespace std;
 class Animals{
   public :
     virtual void speak(){
      cout<<"Animals speak random";
    }
};
 
class Dog: public Animals{
  public:
      void speak(){
      cout<<"Dogs woof";
    }
};
 
int main()
{
  Animals *a;
  Dog d;
 
  a = &d;
 
  a->speak();
}
 
Output:
 //without virtual speak()
 Animals speak random
 //with virtual speak()
 Dog woof

LINKED LIST

#include <cstdio>
#include <stdlib.h>
#include <iostream>
#include <limits>
#include <stdio.h>
#define BAD_INPUT_CUTOFF 3

using namespace std;


struct node
{
    int data;
    struct node* next;
};

struct searchDS
{
    int occurence;
    int posit[100];
};

typedef struct node Node;
typedef struct searchDS SD;

Node *start = NULL;
Node *new1;

void print_list(Node*);
int print_no();
int count();
unsigned int getIntInRange(unsigned int min, unsigned int max, const char *prompt);

Node* create_node()
{
    Node* newnode;

    newnode = (Node*)malloc(sizeof(struct node));

    printf("\nEnter the data (numeric only): ");
    scanf("%d", &newnode -> data);
    newnode -> next = NULL;

    return newnode;
}

int isEmpty()
{
    if(start == NULL)
    {
        printf("\nList is empty");
        return true;
    }
    else
        return false;
}

Node* search(int data)
{
    Node* ptr;

    int flag = 0;

    for(ptr = start ; ptr; ptr = ptr -> next)
    {
        if(ptr -> data == data)
        {
            flag = 1;
            printf("\nData %d found at %x ",data,ptr);
        }
    }

    if(flag == 1 )
    {
        return ptr;
    }
    else
    {
        printf("\nData %d not found !!!",data);
        return NULL;
    }
}

void adv_search(int data, SD* sp)
{

    Node *ptr,*prev;

    int i ,j, pos = 1;

    if(start ==  NULL)
    {
        printf("\nList is empty ");
        return;
    }
    sp->occurence = 0;

    for(i=0,ptr = start; (ptr); ptr = ptr->next,pos++)
    {
        if(ptr -> data == data)
        {
            (sp->occurence)++;
            sp->posit[i++] = pos ;
        }
    }

    if(sp->occurence == 0)
    {
        printf("\nData %d not in the list!!!",data);
        return;
    }
    printf("\nOcc: %d , Positions : ", sp->occurence);
    for(j=0; j<i; j++)
        printf("%d, ",sp->posit[j]);
    printf("\n");
}

void insert_beg()
{
//printf("\n In function %s\n",__func__);

    new1 = create_node();

    if(start == NULL)
    {
        start = new1;
        print_list(start);
        return;
    }
    else
    {
        new1 -> next = start ;
        start = new1;
        print_list(start);
        return;
    }
}
void insert_end()
{
    Node *ptr,*prev;
//printf("\n In function %s\n",__func__);

    new1 = create_node();

    if(start == NULL)
    {
        start = new1;
        print_list(start);
        return;
    }
    else
    {
        for(prev = start , ptr = start -> next ; ptr ; prev = ptr , ptr = ptr -> next);

        prev -> next = new1;
        print_list(start);
    }
}
void insert_at_pos()
{
    Node *ptr , *prev;
    int pos,i;
//printf("\n In function %s\n",__func__);

    new1 = create_node();

    printf("\nWhat position do you want to enter ? ");
    scanf("%d",&pos);

    if (pos < 1 || pos > print_no())
    {
        printf("\n Inserting failed! Out of bounds!!!");
        return;
    }
    else if(pos == 1)
    {
        new1 -> next = start;
        start = new1;
        print_list(start);
    }
    else if(pos > 1)
    {
        for(i = 1 ,prev = start, ptr = start -> next; (ptr) && (i < pos -1); prev = ptr , ptr = ptr->next,i++);
        prev -> next = new1 ;
        new1 -> next = ptr ;

        print_list(start);
    }
}

void delete_node_by_pos()
{
    Node *prev, *ptr, *temp;
    int pos,i;
    //printf("\n In function %s\n",__func__);

    if(isEmpty() != true)
    {
        printf("\nEnter the node no. you want to delete: ");
        scanf("%d",&pos);

        if (pos < 1 || pos > count())
        {
            printf("\n Deletion failed! Out of bounds!!!");
            return;
        }
        else if(pos == 1)
        {
            temp = start;
            start = start -> next;
            free(temp);
            print_list(start);
        }
        else if(pos > 1)
        {
            for(i = 1 ,prev = start, ptr = start -> next; (ptr) && (i < pos -1); prev = ptr , ptr = ptr->next,i++)
            {
                //`printf("\n prev-> data : %d\tptr->data :%d" ,prev-> data, ptr->data);
            }
            temp = ptr;
            prev -> next = ptr -> next;
            free(temp);
            print_list(start);
        }
    }
}

void delete_node_by_data()
{
    Node *ptr,*prev,*temp;
    int info, ch;
    SD sp;
    static int visited = 0;
    //printf("\n In function %s\n",__func__);

    if(isEmpty() != true)
    {
        printf("\nEnter the data you want to delete: ");
        scanf("%d",&info);
        adv_search(info, &sp);

        {
            if(start -> data == info )
            {
                temp = start;
                start = start -> next;
                free(temp);
                print_list(start);
                return;
            }
            for(prev = start , ptr = start -> next ; ptr ; prev = ptr , ptr = ptr -> next)
            {
                if( ptr -> data == info)
                {
                    temp = ptr;
                    prev -> next = ptr -> next;
                    free(temp);
                    print_list(start);
                    return;
                }
            }
        }
        print_list(start);
    }
}


void print_list(Node* start)
{
    Node *ptr;
//printf("\n In function %s\n",__func__);

    printf("\n");
    for(ptr = start; ptr ; ptr = ptr ->next )
    {
        printf("-> %d ",ptr->data);
    }
    printf("\n");
}
int print_no()
{
//printf("\n In function %s\n",__func__);
    printf("\nThe total no. of members in the list are : %d \n", count());
}

int count()
{

    Node *ptr;
    int count = 0;

    ptr = start ;
    while(ptr!=NULL)
    {
        ptr = ptr -> next;
        count++;
    }

    return count;
}

Node* reverse(Node* root)
{
    Node* ret_val;

    if ( root == NULL || root->next == NULL )
    {
        return root;
    }
    ret_val = reverse ( root -> next );

    root -> next->next = root;
    root->next = NULL;
    return ret_val;
}

unsigned int getIntInRange(unsigned int min, unsigned int max,
                           const char *prompt)
{
    int input, //used to get input
        bad_count=0; //used to keep track of how many bad attempts.
    do
    {
        cout << prompt; //print out our prompt
        cin >> input; //get the input
        if (!cin.good() || input < min || input > max)
        {
            cout << "\nInvalid Input!" << std::endl;
            cin.clear(); //resets the state flag
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
                        //clears out the buffer
            bad_count++; //User made a bad input, count it
            input = 0; // user did not enter a valid number
        }
    }
    while (input == 0 && bad_count < BAD_INPUT_CUTOFF);
    return input;
}

int main()
{
    int choice,searchKey,info;
    SD sp;
    Node* temp;
    while(1)
    {

        printf("\n1.Insert a node at beg\n2.Insert a node at end \n3.Insert a node at a given position\n4.Delete a  node by data\n5.Delete a node by position\n6.Print the list\n7.Print the no. of elements\n8.Reverse the list\n9.Search \n10.Advanced Search\n11.Exit\n");

         choice  = getIntInRange(1,11,"\n Choose your option (1-11):\n");

        switch(choice)
        {
        case 1 :
            insert_beg();
            break;
        case 2 :
            insert_end();
            break;
        case 3 :
            insert_at_pos();
            break;
        case 4 :
            delete_node_by_data();
            break;
        case 5 :
            delete_node_by_pos();
            break;
        case 6 :
            print_list(start);
            break;
        case 7 :
            print_no();
            break;
        case 8 :
            start = reverse(start);
            print_list(start);
            break;
        case 9 :
            printf("\nEnter the data you want to search : ");
            scanf("%d",&searchKey);

            if(search(searchKey)!=NULL)
                printf("\nData %d at %x",searchKey , search(searchKey));

            break;
        case 10 :
            printf("\nEnter the data you want to search : ");
            scanf("%d",&searchKey);
            adv_search(searchKey,&sp);
            break;
        case 11 :
            exit(0);

        default :
            printf("\nInvalid input !!!\n");
            break;

        }
    }
}

Templates in C++

Templates are a way of making your classes more abstract by letting you define the behavior of the class without actually knowing what datatype will be handled by the operations of the class. In essence, this is what is known as generic programming; this term is a useful way to think about templates because it helps remind the programmer that a template class does not depend on the datatype (or types) it deals with. To a large degree, a template class is more focused on the algorithmic thought rather than the specific nuances of a single datatype. Templates can be used in conjunction with abstract data types in order to allow them to handle any type of data. For example, you could make a template stack class that can handle a stack of any datatype, rather than having to create a stack class for every different datatype for which you want the stack to function. The ability to have a single class that can handle several different data types means the code is easier to maintain, and it makes classes more reusable.

The basic syntax for declaring a template class is as follows:

template <class a_type> class a_class {...};

The keyword 'class' above simply means that the identifier a_type will stand for a datatype. NB: a_type is not a keyword; it is an identifier that during the execution of the program will represent a single datatype. For example, you could, when defining variables in the class, use the following line:

a_type a_var;

and when the programmer defines which datatype 'a_type' is to be when the program instantiates a particular instance of a_class, a_var will be of that type.

When defining a function as a member of a templated class, it is necessary to define it as a templated function:

template<class a_type> void a_class<a_type>::a_function(){...}
              

When declaring an instance of a templated class, the syntax is as follows:

a_class<int> an_example_class;
             

An instantiated object of a templated class is called a specialization; the term specialization is useful to remember because it reminds us that the original class is a generic class, whereas a specific instantiation of a class is specialized for a single datatype (although it is possible to template multiple types).

Usually when writing code it is easiest to precede from concrete to abstract; therefore, it is easier to write a class for a specific datatype and then proceed to a templated - generic - class. For that brevity is the soul of wit, this example will be brief and therefore of little practical application.

We will define the first class to act only on integers.

class calc
{
  public:
    int multiply(int x, int y);
    int add(int x, int y);
 };
int calc::multiply(int x, int y)
{
  return x*y;
}
int calc::add(int x, int y)
{
  return x+y;
}

We now have a perfectly harmless little class that functions perfectly well for integers; but what if we decided we wanted a generic class that would work equally well for floating point numbers? We would use a template.

template <class A_Type> class calc
{
  public:
    A_Type multiply(A_Type x, A_Type y);
    A_Type add(A_Type x, A_Type y);
};
template <class A_Type> A_Type calc<A_Type>::multiply(A_Type x,A_Type y)
{
  return x*y;
}
template <class A_Type> A_Type calc<A_Type>::add(A_Type x, A_Type y)
{
  return x+y;
}

To understand the templated class, just think about replacing the identifier A_Type everywhere it appears, except as part of the template or class definition, with the keyword int. It would be the same as the above class; now when you instantiate an
object of class calc you can choose which datatype the class will handle.

calc <double> a_calc_class;

Templates are handy for making your programs more generic and allowing your code to be reused later.

Wednesday 28 September 2016

HORSE RACE GAME PROGRAM CODE IN CPP


#include<iostream.h>
#include<stdlib.h>
#include<time.h>

void title_screen();
void generate_odds(int odds[],int size);
void get_cash(int stats[], int pl_num);
void bet(int stats[],int pl_num, int odds[]);
void disp_odds(int odds[]);
int move_horse(int odds[], int horse);
int payoff(int winner, int player[], int pl_num);
void disp_race(int positions[]);
void final_results(int player1[],int player2[]);

int main()
{
    int odds[8];
    int player1[5], player2[5];
    int position[8]={0,0,0,0,0,0,0,0};
    int count;
    int winner;
    char more_race='Y';

//Player array, slot0=money total, slot1=horse bet on, slot2=bet amount, slot3=odds of bet
//slot4=original cash level.
    srand(time(0));

    title_screen();
    get_cash(player1,1);
    get_cash(player2,2);

    do
    {
    for(count=0;count<8;count++)
        position[count]=0;
    winner=6000;
    generate_odds(odds,8);
    disp_odds(odds);
    bet(player1,1,odds);
    disp_odds(odds);
    bet(player2,2,odds);

    do
    {
    for(count=0;count<8;count++)
        {   
        position[count]+=move_horse(odds, count);
        if(position[count]>=50)
            winner=count;
        }
    disp_race(position);
    }
    while(winner==6000);
   
    cout<<"\nThe winning horse is horse "<<winner+1<<endl;
    player1[0]+=payoff(winner, player1,1);
    player2[0]+=payoff(winner, player2,2);

    if((player1[0]<=0)||(player2[0]<=0))
        more_race='n';
    else
        {
        cout<<"\nWould you like another race? (Y/N)\n";
        cin>>more_race;
        }
    }
    while((more_race=='Y')||(more_race=='y'));

    final_results(player1,player2);

    return 0;
}

void title_screen()
{

cout<<"         LET'S RACE AND WIN   ";

}

void generate_odds(int odds[], int size)
{
//This function calculates the odds for each horse at the begining of each race
    int count;

    for(count=0;count<size;count++)
        {
        odds[count]=((rand()%5)+1)*2;
        }
}

void get_cash(int stats[], int pl_num)
{
//Gets the player's initial cash fund.
//This function may eventually be replaced by a set amount of cash.
    cout<<"How much money will player "<<pl_num<<" start with?\n";
    cin>> stats[0];
    stats[4]=stats[0];
}

void bet(int stats[],int pl_num, int odds[])
{
//This function takes bets at the begining of a race.  It is designed to
//Only allow bets on real horses and to only let pleyers bet within thier bank accout
    int horse_num;
    cout<<"\nPlayer "<<pl_num<<", you have "<<stats[0]<<" dollars.\n";
   
    do
    {
    cout<<"Which horse will you bet on?\n";
    cin>> horse_num;

    stats[1]=horse_num;

    if((stats[1]<=0)||(stats[1]>=9))
        cout<<"That is an invalid choice\n\n";

    }
    while((stats[1]<=0)||(stats[1]>=9));

    stats[3]=odds[horse_num-1];

    do
    {
    cout<<"\nHow much will you bet on that horse?\n";
    cin>> stats[2];

    if(stats[2]>stats[0])
        cout<<"\nYou can't bet more then you have!\n\n";
    else if(stats[2]<=0)
        cout<<"\nYou must bet at least 1 dollar.\n\n";

    }
    while((stats[2]>stats[0])||(stats[2]<=0));
   
    stats[0]-=stats[2];

    cout<<endl;
}

void disp_odds(int odds[])
{
//This function displays the odds for each horse at the begining of each race
    int count;
   
    cout<<endl;

    for(count=0;count<8;count++)
        {
        cout<<"The odds on Horse "<<count+1<<" are: 1 in "<<odds[count]<<endl;
        }
}

int move_horse(int odds[], int horse)
{
//This function will move a horse based on it's odds of winning
    int move;
    move=5-(odds[horse])/2+(rand()%6);
    return move;
}

int payoff(int winner, int player[], int pl_num)
{
//This function pays out any winning bets
    int amount=0;

    if((player[1]-1)==winner)
        {
        cout<<"\nCongratulations player "<<pl_num<<", you are a winner.\n";
        amount+=player[3]*player[2];
        cout<<"\nYou've won "<<amount<<" dollars!\n";
        }
    else
        cout<<"\nSorry player "<<pl_num<<", your horse lost.\n";

    return amount;
}

void disp_race(int positions[])
{
//This function displays the race as a series of Xs for each horse's movement
    int count, count2;
    char nothing;

    cout<<"\nHorse       Distance                                          |FIN\n";

    for(count=0;count<8;count++)
        {
        cout<<"Horse "<<count+1<<"     ";
       
        for(count2=0;count2<positions[count];count2++)
            cout<<"X";

        cout<<endl;
        }

    cout<<"\n Type 'C' to continue\n";
    cin>>nothing;

    if(nothing=='E')
        cout<<"\nEASTER EGG!  ARRAYS SHOULD BE NUMBERED STARTING AT 1! THINGS WOULD BE EASIER!\n";
    if(nothing=='G')
        cout<<"\nWhat are you trying to prove?\n";

    return;
}

void final_results(int player1[],int player2[])
{
//This function should calculate the winner based on who gained the most.
//It should be altered to figure based on percentage gained and not actual gain
//As a person with 10000 to bet will surely be able to gain more then a person with 100.
    cout<<"\nPlayer 1 ended up with "<<player1[0]<<" dollars for a gain of: ";
    cout<<(player1[0]-player1[4])<<".\n";
    cout<<"\nPlayer 2 ended up with "<<player2[0]<<" dollars for a gain of: ";
    cout<<(player2[0]-player2[4])<<".\n";

    if((player1[0]-player1[4])>(player2[0]-player2[4]))
        cout<<"\nPlayer 1 is the winner.\n";
    else if((player2[0]-player2[4])>(player1[0]-player1[4]))
        cout<<"\nPlayer 2 is the winner.\n";
    else
        cout<<"\nIt's a tie!\n";
}

Murder Case Game Program Code in C++










#include<iostream>
#include<string>
#include<stdlib>

using namespace std;

int main()
{
    int ans1, ans2, ans3;
    int answer;

    cout << "\n Who killed Mr. Boddy! \n 1. Ms. Scarlet,\n 2. Colonel Mustard,\n 3. Mrs. White \n 4. Mr. Green,\n 5. Mrs. Peacock,\n 6. Professor Plum \n\n ";
    cin >> ans1;
    int i=1;
    while(i<7) {
        answer = rand() % i + 1;
        i++;
    }
    cout<<"\n The right answer is option  : "<<answer;
    if(answer==ans1)
        cout<<"You've done it! You've solved the case!";
    switch(answer) {
    case 1:
        cout<<" It was Ms. Scarlet \n ";
        break;
    case 2:
        cout<<"It was Colonel Mustard \n ";
        break;
    case 3:
        cout<<"It was Mrs. White \n !";
        break;
    case 4:
        cout<<"It was Mr. Green \n ";
        break;
    case 5:
        cout<<"It was Mrs. Peacock \n";
        break;
    case 6:
        cout<<"It was Professor Plum \n";
        break;
    default:
        cout<<"Sorry! Invalid Choice! ";
    }

    cout << "\n What Weapon Was Used? \n \n 1. Candlestick \n 2. Knife  \n 3. Lead pipe \n 4. Revolver \n 5. Rope \n 6. Wrench";
    cin >> ans2;
    i=1;
    while(i<7) {
        answer = rand() % i + 1;
        i++;
    }
    cout<<"\n The right answer is option  : "<<answer;
    if(ans2==answer)
        cout<<"You've done it! You've solved the case!";
    switch (answer) {
    case 1:
        cout<<" It was by  Candlestick \n ";
        break;
    case 2:
        cout<<"It was by Knife \n ";
        break;
    case 3:
        cout<<"It was by Lead pipe \n !";
        break;
    case 4:
        cout<<"It was by  Revolver \n ";
        break;
    case 5:
        cout<<"It was by  Rope  \n";
        break;
    case 6:
        cout<<"It was by  Wrench  \n";
        break;
    default:
        cout<<"Sorry! Invalid Choice! \n";
    }

    cout << "\n Where was Mr. Boddy Killed? \n \n 1. Lounge \n 2. Humanities Building \n 3. Parking Lot \n 4. Kitchen \n 5. Ball room  \n 6. Conservatory \n 7. Billiard room \n 8. Library 9. Study room \n  ";
    cin >> ans3;
    i=1;
    while(i<10) {
        answer = rand() % i + 1;
        i++;
    }
    cout<<"\n The right answer is option  : "<<answer;
    if(ans3==answer)
        cout<<"You've done it! You've solved the case! \n";
    switch (answer) {
    case 1:
        cout<<" at 1. Hall \n ";
        break;
    case 2:
        cout<<"at 2. Loung \n ";
        break;
    case 3:
        cout<<"at 3. Dining room \n ";
        break;
    case 4:
        cout<<"at 4. Kitchen \n ";
        break;
    case 5:
        cout<<"at 5. Ball room \n";
        break;
    case 6:
        cout<<"at 6. Conservatory \n";
        break;
    case 7:
        cout<<"at 7. Billiard room \n";
        break;
    case 8:
        cout<<"at 8. Library \n";
        break;
    case 9:
        cout<<"at 9. Study room \n ";
        break;
    default:
        cout<<"Sorry! Invalid Choice! \n ";
    }
    return 0;
}

Thursday 22 September 2016

Polymorphism


Before getting any deeper into this chapter, you should have a proper understanding of pointers and class inheritance. If you are not really sure of the meaning of any of the following expressions, you should review the indicated sections:
Statement:
Explained in:
int A::b(int c) { }
a->b
class A: public B {};

Pointers to base class
One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature.

The example about the rectangle and triangle classes can be rewritten using pointers taking this feature into account:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// pointers to base class
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
};

class Rectangle: public Polygon {
  public:
    int area()
      { return width*height; }
};

class Triangle: public Polygon {
  public:
    int area()
      { return width*height/2; }
};

int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << rect.area() << '\n';
  cout << trgl.area() << '\n';
  return 0;
}
20
10


Function 
main declares two pointers to Polygon (named ppoly1 and ppoly2). These are assigned the addresses of rect andtrgl, respectively, which are objects of type Rectangle and Triangle. Such assignments are valid, since both Rectangleand Triangle are classes derived from Polygon.

Dereferencing 
ppoly1 and ppoly2 (with *ppoly1 and *ppoly2) is valid and allows us to access the members of their pointed objects. For example, the following two statements would be equivalent in the previous example:
1
2
ppoly1->set_values (4,5);
rect.set_values (4,5);


But because the type of 
ppoly1 and ppoly2 is pointer to Polygon (and not pointer to Rectangle nor pointer to Triangle), only the members inherited from Polygon can be accessed, and not those of the derived classes Rectangle and Triangle. That is why the program above accesses the area members of both objects using rect and trgl directly, instead of the pointers; the pointers to the base class cannot access the area members.

Member 
area could have been accessed with the pointers to Polygon if area were a member of Polygon instead of a member of its derived classes, but the problem is that Rectangle and Triangle implement different versions of area, therefore there is not a single common version that could be implemented in the base class.


Virtual members
A virtual member is a member function that can be redefined in a derived class, while preserving its calling properties through references. The syntax for a function to become virtual is to precede its declaration with the virtual keyword:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// virtual members
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area ()
      { return 0; }
};

class Rectangle: public Polygon {
  public:
    int area ()
      { return width * height; }
};

class Triangle: public Polygon {
  public:
    int area ()
      { return (width * height / 2); }
};

int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon poly;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  Polygon * ppoly3 = &poly;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly3->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  cout << ppoly3->area() << '\n';
  return 0;
}
20
10
0


In this example, all three classes (
PolygonRectangle and Triangle) have the same members: widthheight, and functions set_values and area.

The member function 
area has been declared as virtual in the base class because it is later redefined in each of the derived classes. Non-virtual members can also be redefined in derived classes, but non-virtual members of derived classes cannot be accessed through a reference of the base class: i.e., if virtual is removed from the declaration of area in the example above, all three calls to area would return zero, because in all cases, the version of the base class would have been called instead.

Therefore, essentially, what the 
virtual keyword does is to allow a member of a derived class with the same name as one in the base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a pointer to the base class that is pointing to an object of the derived class, as in the above example.

A class that declares or inherits a virtual function is called a polymorphic class.

Note that despite of the virtuality of one of its members, 
Polygon was a regular class, of which even an object was instantiated (poly), with its own definition of member area that always returns 0.


Abstract base classes
Abstract base classes are something very similar to the Polygon class in the previous example. They are classes that can only be used as base classes, and thus are allowed to have virtual member functions without definition (known as pure virtual functions). The syntax is to replace their definition by =0 (an equal sign and a zero):

An abstract base 
Polygon class could look like this:
1
2
3
4
5
6
7
8
9
// abstract class CPolygon
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area () =0;
};


Notice that 
area has no definition; this has been replaced by =0, which makes it a pure virtual function. Classes that contain at least one pure virtual function are known as abstract base classes.

Abstract base classes cannot be used to instantiate objects. Therefore, this last abstract base class version of 
Polygoncould not be used to declare objects like:

Polygon mypolygon;   // not working if Polygon is abstract base class


But an abstract base class is not totally useless. It can be used to create pointers to it, and take advantage of all its polymorphic abilities. For example, the following pointer declarations would be valid:
1
2
Polygon * ppoly1;
Polygon * ppoly2;


And can actually be dereferenced when pointing to objects of derived (non-abstract) classes. Here is the entire example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// abstract base class
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area (void) =0;
};

class Rectangle: public Polygon {
  public:
    int area (void)
      { return (width * height); }
};

class Triangle: public Polygon {
  public:
    int area (void)
      { return (width * height / 2); }
};

int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  return 0;
}
20
10


In this example, objects of different but related types are referred to using a unique type of pointer (
Polygon*) and the proper member function is called every time, just because they are virtual. This can be really useful in some circumstances. For example, it is even possible for a member of the abstract base class Polygon to use the special pointerthis to access the proper virtual members, even though Polygon itself has no implementation for this function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// pure virtual members can be called
// from the abstract base class
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area() =0;
    void printarea()
      { cout << this->area() << '\n'; }
};

class Rectangle: public Polygon {
  public:
    int area (void)
      { return (width * height); }
};

class Triangle: public Polygon {
  public:
    int area (void)
      { return (width * height / 2); }
};

int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  return 0;
}
20
10


Virtual members and abstract classes grant C++ polymorphic characteristics, most useful for object-oriented projects. Of course, the examples above are very simple use cases, but these features can be applied to arrays of objects or dynamically allocated objects.

Here is an example that combines some of the features in the latest chapters, such as dynamic memory, constructor initializers and polymorphism:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    Polygon (int a, int b) : width(a), height(b) {}
    virtual int area (void) =0;
    void printarea()
      { cout << this->area() << '\n'; }
};

class Rectangle: public Polygon {
  public:
    Rectangle(int a,int b) : Polygon(a,b) {}
    int area()
      { return width*height; }
};

class Triangle: public Polygon {
  public:
    Triangle(int a,int b) : Polygon(a,b) {}
    int area()
      { return width*height/2; }
};

int main () {
  Polygon * ppoly1 = new Rectangle (4,5);
  Polygon * ppoly2 = new Triangle (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  delete ppoly1;
  delete ppoly2;
  return 0;
}
20
10


Notice that the 
ppoly pointers:
1
2
Polygon * ppoly1 = new Rectangle (4,5);
Polygon * ppoly2 = new Triangle (4,5);



are declared being of type "pointer to 
Polygon", but the objects allocated have been declared having the derived class type directly (Rectangle and Triangle).