Replace the 40 element transition table of {near side, far side, type} triples w
ID: 3835414 • Letter: R
Question
Replace the 40 element transition table of {near side, far side, type} triples with two 20 length linked lists of {near side, far side} state pairs.
The first list is a list of good state pairs,
The second list is a list of bad state pairs. Create a array of error messages and associate each error message with bad state pair.
The goodTransition function searches the good transition list for a match to the (this side state, that side state) pair computed from the function's two parameters. If the function finds a match the function returns true. If the function returns false then the cross function searches the bad transition list for a match. If finds a match then it displays the error message associated with the {this side state, that side state} pair.
Replace the menu with a simple command language.
For example,
If the user types "w" or "W" then the program tries to carry the wolf and the showman across the river. If the user types "g" then the program tries to carry the goat and the showman across the river.
below is the given code that needs modification
Cargo.cpp
#include "Cargo.h"
int Cargo::charToCargo(char cargo)
{
switch(cargo)
{
case 'w': case 'W':
return WOLF;
case 's': case 'S':
return SHOWMAN;
case 'g': case 'G':
return GOAT;
case 'c': case 'C':
return CABBAGES;
default:
return NOCARGO;
}
}
char Cargo::cargoToChar(int cargo)
{
switch(cargo)
{
case WOLF:
return 'W';
case SHOWMAN:
return 'S';
case GOAT:
return 'G';
case CABBAGES:
return 'C';
case NOCARGO:
return 'N';
default:
return 'B';
}
}
bool Cargo::isCargo(char candidate)
{
switch(candidate)
{
case 'w': case 'W':
case 's': case 'S':
case 'g': case 'G':
case 'C': case 'c':
case 'N': case 'n':
return true;
default:
return false;
}
}
int Cargo::read(void)
{
char cargo;
do
{
cout << "Enter W for Wolf" << endl;
cout << "Enter N for no cargo" << endl;
cout << "Enter G for Goat" << endl;
cout << "Enter C for cabbages" << endl;
cout << "Enter cargo - ";
cin.get(cargo);
cin.ignore(numeric_limits<int>::max(), ' ');
}
while(!isCargo(cargo));
return charToCargo(cargo);
}
Cargo.h
#pragma once
#include <iostream>
#include <limits.h>
#include <string>
using namespace std;
class Cargo
{
public:
static int read(void);
static int charToCargo(char);
static char cargoToChar(int);
static bool isCargo(char);
static const int BADCARGO = -1;
static const int CABBAGES = 0;
static const int GOAT = 1;
static const int SHOWMAN = 2;
static const int WOLF = 3;
static const int NOCARGO = 4;
static const int CARGO_AND_SHOWMAN = 5;
};
River.Cpp
#include "River.h"
River::River(void)
{
for (int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
_far_side[pos] = false;
}
void River::show(void)
{
for(int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
if(_far_side[pos])
cout << "- | " << Cargo::cargoToChar(pos) << endl;
else
cout << Cargo::cargoToChar(pos) << " | -" << endl;
cout << endl;
}
void River::cross(int cargo)
{
copy(_far_side, _near_side);
_far_side[Cargo::SHOWMAN] = !_near_side[Cargo::SHOWMAN];
_far_side[cargo] = !_near_side[cargo];
if(!goodCrossing(_near_side, _far_side))
copy(_near_side, _far_side);
}
void River::copy(bool source[], bool sink[])
{
for(int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
sink[pos] = source[pos];
}
unsigned River::state(bool river[])
{
unsigned _state = 0;
for(unsigned pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
_state = _state + river[pos] * (int)pow(2, pos);
return _state;
}
bool River::goodCrossing(bool this_side[], bool that_side[])
{
static const unsigned I = 0;
static const unsigned B = 1;
static const unsigned G = 2;
static const unsigned n_transitions = 40;
static Transition transit[] =
{ {0,4,B},{0,5,B},{0,6,G},{0,12,B},
{1,5,B},{1,7,G},{1,13,G},
{2,6,G},{2,7,G},{2,14,G},
{3,7,B},{3,15,B},
{4,0,B},
{5,0,B},{5,1,B},
{6,0,G},{6,2,G},
{7,1,G},{7,2,G},{7,3,B},
{8,12,B},{8,13,G},{8,14,G},
{9,13,G},{9,15,G},
{10,14,B},{10,15,B},
{11,15,B},
{12,0,B},{12,8,B},
{13,1,G},{13,8,G},{13,9,G},
{14,2,G},{14,8,G},{14,10,B},
{15,3,B},{15,9,G},{15,10,B},{15,11,B} };
unsigned this_side_state = state(this_side);
unsigned that_side_state = state(that_side);
unsigned id = 0;
while (id < n_transitions && (transit[id].this_side != this_side_state || transit[id].that_side != that_side_state))
id++;
return transit[id].type == G;
}
bool River::stop(void)
{
return state(_far_side) == stop_state;
}
River.H
#pragma once
#include <math.h>
#include "cargo.h"
class River
{
public:
River(void);
void show(void);
void cross(int);
bool stop(void);
private:
struct Transition { unsigned this_side; unsigned that_side; unsigned type; };
static const unsigned start_state = 0;
static const unsigned stop_state = 15;
bool _far_side[Cargo::CARGO_AND_SHOWMAN];
bool _near_side[Cargo::CARGO_AND_SHOWMAN];
void copy(bool[], bool[]);
unsigned state(bool[]);
bool goodCrossing(bool [], bool []);
};
main.cpp
#include <iostream>
#include <string>
#include "cargo.h"
#include "river.h"
using namespace std;
int main()
{
River river;
river.show();
do
{
int cargo = Cargo::read();
river.cross(cargo);
river.show();
}
while(!river.stop());
system("pause");
return 0;
}
Explanation / Answer
aa#include "Cargo.h"
int Cargo::charToCargo(char cargo)
{
switch(cargo)
{
case 'w': case 'W':
return WOLF;
case 's': case 'S':
return SHOWMAN;
case 'g': case 'G':
return GOAT;
case 'c': case 'C':
return CABBAGES;
default:
return NOCARGO;
}
}
char Cargo::cargoToChar(int cargo)
{
switch(cargo)
{
case WOLF:
return 'W';
case SHOWMAN:
return 'S';
case GOAT:
return 'G';
case CABBAGES:
return 'C';
case NOCARGO:
return 'N';
default:
return 'B';
}
}
bool Cargo::isCargo(char candidate)
{
switch(candidate)
{
case 'w': case 'W':
case 's': case 'S':
case 'g': case 'G':
case 'C': case 'c':
case 'N': case 'n':
return true;
default:
return false;
}
}
int Cargo::read(void)
{
char cargo;
do
{
cout << "Enter W for Wolf" << endl;
cout << "Enter N for no cargo" << endl;
cout << "Enter G for Goat" << endl;
cout << "Enter C for cabbages" << endl;
cout << "Enter cargo - ";
cin.get(cargo);
cin.ignore(numeric_limits<int>::max(), ' ');
}
while(!isCargo(cargo));
return charToCargo(cargo);
}
Cargo.h
#pragma once
#include <iostream>
#include <limits.h>
#include <string>
using namespace std;
class Cargo
{
public:
static int read(void);
static int charToCargo(char);
static char cargoToChar(int);
static bool isCargo(char);
static const int BADCARGO = -1;
static const int CABBAGES = 0;
static const int GOAT = 1;
static const int SHOWMAN = 2;
static const int WOLF = 3;
static const int NOCARGO = 4;
static const int CARGO_AND_SHOWMAN = 5;
};
River.Cpp
#include "River.h"
River::River(void)
{
for (int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
_far_side[pos] = false;
}
void River::show(void)
{
for(int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
if(_far_side[pos])
cout << "- | " << Cargo::cargoToChar(pos) << endl;
else
cout << Cargo::cargoToChar(pos) << " | -" << endl;
cout << endl;
}
void River::cross(int cargo)
{
copy(_far_side, _near_side);
_far_side[Cargo::SHOWMAN] = !_near_side[Cargo::SHOWMAN];
_far_side[cargo] = !_near_side[cargo];
if(!goodCrossing(_near_side, _far_side))
copy(_near_side, _far_side);
}
void River::copy(bool source[], bool sink[])
{
for(int pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
sink[pos] = source[pos];
}
unsigned River::state(bool river[])
{
unsigned _state = 0;
for(unsigned pos = Cargo::CABBAGES; pos <= Cargo::WOLF; pos++)
_state = _state + river[pos] * (int)pow(2, pos);
return _state;
}
bool River::goodCrossing(bool this_side[], bool that_side[])
{
static const unsigned I = 0;
static const unsigned B = 1;
static const unsigned G = 2;
static const unsigned n_transitions = 40;
static Transition transit[] =
{ {0,4,B},{0,5,B},{0,6,G},{0,12,B},
{1,5,B},{1,7,G},{1,13,G},
{2,6,G},{2,7,G},{2,14,G},
{3,7,B},{3,15,B},
{4,0,B},
{5,0,B},{5,1,B},
{6,0,G},{6,2,G},
{7,1,G},{7,2,G},{7,3,B},
{8,12,B},{8,13,G},{8,14,G},
{9,13,G},{9,15,G},
{10,14,B},{10,15,B},
{11,15,B},
{12,0,B},{12,8,B},
{13,1,G},{13,8,G},{13,9,G},
{14,2,G},{14,8,G},{14,10,B},
{15,3,B},{15,9,G},{15,10,B},{15,11,B} };
unsigned this_side_state = state(this_side);
unsigned that_side_state = state(that_side);
unsigned id = 0;
while (id < n_transitions && (transit[id].this_side != this_side_state || transit[id].that_side != that_side_state))
id++;
return transit[id].type == G;
}
bool River::stop(void)
{
return state(_far_side) == stop_state;
}
River.H
#pragma once
#include <math.h>
#include "cargo.h"
class River
{
public:
River(void);
void show(void);
void cross(int);
bool stop(void);
private:
struct Transition { unsigned this_side; unsigned that_side; unsigned type; };
static const unsigned start_state = 0;
static const unsigned stop_state = 15;
bool _far_side[Cargo::CARGO_AND_SHOWMAN];
bool _near_side[Cargo::CARGO_AND_SHOWMAN];
void copy(bool[], bool[]);
unsigned state(bool[]);
bool goodCrossing(bool [], bool []);
};
main.cpp
#include <iostream>
#include <string>
#include "cargo.h"
#include "river.h"
using namespace std;
int main()
{
River river;
river.show();
do
{
int cargo = Cargo::read();
river.cross(cargo);
river.show();
}
while(!river.stop());
system("pause");
return 0;
}