SC_FIFO write : First chance exception - c++

I've written a simple program which will send data from a 2D array from one module to another module, however it does not seem to work and I am not sure why. Here is my code:
Server.h
#include <iostream>
#include "stdafx.h"
using namespace std;
SC_MODULE(Server){
sc_in <bool> clock;
sc_fifo_out <sc_uint<20> > writePath;
bool init_flag;
int numRobots;
void Server_Main();
SC_CTOR(Server){
init_flag = 0;
numRobots = 4;
SC_METHOD(Server_Main){ sensitive << clock.pos(); }
}
};
Server.cpp
#include "stdafx.h"
#include "Server.h"
void Server::Server_Main(){
if (init_flag == 0){
int robotPath[4][5] = {
{ 1, 2, 3, 4, 1 },
{ 2, 1, 6, 3, 4 },
{ 3, 2, 9, 5, 1 },
{ 4, 1, 6, 8, 7 }
};
//Write robot path to Sensor
for (int i = 0; i < numRobots; i++){
for (int j = 0; j < 5; j++){
cout << "SERVER MODULE: Write Robot Paths " << i << ": " << robotPath[i][j] << endl;
writePath.write(robotPath[i][j]);
}
}
init_flag = 1;
}
else{ sc_stop(); }
}
Sensor.h
#include <iostream>
#include "stdafx.h"
using namespace std;
SC_MODULE(Sensor){
//sc_in <bool> clock;
sc_fifo_in <sc_uint<20> > readPath;
int robotPath[4][5];
void loadPath();
//void Sensor_Main();
SC_CTOR(Sensor){
//SC_METHOD(Sensor_Main){ sensitive << clock.pos(); }
SC_THREAD(loadPath){}
}
};
Sensor.cpp
#include "stdafx.h"
#include "Sensor.h"
void Sensor::loadPath(){
int i = 0;
int j = 0;
while (1){
robotPath[i][j] = readPath.read();
cout << "SENSOR MODULE: Read Robot " << i << " Path " << j << " : " << robotPath[i][j] << endl;
if (j == 4){
j = 0; //Set index to beginning of array
i++; //Move to next robot
}
else{ j++; } //Continue loading path for current robot
}
}
Main.cpp
#include "stdafx.h"
#include <iostream>
#include "Sensor.h"
#include "Server.h"
using namespace std;
int sc_main(int argc, char* argv[])
{
sc_clock clock("sysclock", 50, SC_MS, .5);
sc_fifo <sc_uint<20> > robotPath;
Sensor sensor_mod("Sensor");
sensor_mod.readPath(robotPath);
Server server_mod("Server");
server_mod.clock(clock);
server_mod.writePath(robotPath);
sc_start();
return 0;
}
Here's what my output looks like:
Here's the error i get from VS2013:
The program seems to throw an exception when it tries to write robotPath[3][1] to the fifo but im not sure why. I specified my fifo size to be 20 so that it can store 20 values at once but I dont send more than 20 values and this exception is happening when i try to write the 17th value so maybe im misunderstanding the use of sc_fifo_out. It might be some obvious mistake im overlooking but im kind of burnt out at this point and cannot figure out what it is im messing up.

Are you trying to model a Hardware design using SystemC or trying to use SystemC for software modelling?
It seems you have mixed up the contexts.
Here are a list of pointers you need to consider:
In Server module Server_Main() should be registered as a SC_THREAD:
SC_THREAD(Server_Main);
sensitive << clk.pos();
Since you are using sc_fifo's write method which internally calls wait(), in SystemC it is illegal to use wait in a SC_METHOD.
Modify the Server.cpp as mentioned below:
void Server::Server_Main() {
int robotPath[4][5] = {{ 1, 2, 3, 4, 1 },
{ 2, 1, 6, 3, 4 },
{ 3, 2, 9, 5, 1 },
{ 4, 1, 6, 8, 7 }};
//Write robot path to Sensor
for (int i = 0; i < numRobots; i++){
for (int j = 0; j < 5; j++){
cout << "SERVER MODULE: Write Robot Paths " << i << ": " << robotPath[i][j] << endl;
writePath.write(robotPath[i][j]);
wait(); //< Notice this wait statement.
}
}
}
Add a wait() statement in the while loop of the Sensor.cpp.
Also sc_fifo< sc_uint<20> > is not instantiating a sc_fifo with depth 20 as you might think.
It is actually instantiating a sc_fifo with sc_uint<20> as the datatype which is used for modelling a 20-bit unsigned integer, and the default depth of fifo as 16 as per the SystemC specs.
You can instantiate a sc_fifo<> with depth 20 as mentioned below:
sc_fifo<sc_uint<20> > robotPath("robotPath", 20);
Note: You don't need to do this since the above change from SC_METHOD to SC_THREAD and also updating the Server_Main will invalidate this behavior.

Related

How do I make a function that resets a while loop?

I have made a program that outputs 0 3 6 9 12. Now, I want to make a function called reset() that resets the program, so it outputs the same numbers after 12. How do I do that?
#include <iostream>
using namespace std;
void byThrees();
void reset();
int i = 0;
int main()
{
byThrees();
return 0;
}
void byThrees()
{
while(i<13) {
cout << i << ' ';
i += 3;
}
}
void reset()
{
}
Don't use global variables when you can avoid it! And right now, you can avoid it.
No one else wants to use i except byThrees(). And it sounds like you don't want the value of i to persist across runs of byThrees(). So just make it a local variable in the function:
void byThrees()
{
int i = 0;
while(i<13) {
cout << i << ' ';
i += 3;
}
}
Now whenever you want to print your 0, 3, 6, 9, ... series, just call byThrees():
int main() {
byThrees();
std::cout << std::endl; // Add a newline between runs
byThrees();
return 0;
}
Another method to do it, if you want to save memory and just keep one global variable (at least I think this saves memory) is:
#include <iostream>
using namespace std;
int i = 0;
int main()
{
run(); // this function both resets i to 0 and runs byThrees()
return 0;
}
void byThrees()
{
while(i < 13) {
cout << i << ' ';
i += 3;
}
}
void run()
{
i = 0;
byThrees();
}
Basically, whenever you run the function run(), your code will reset the global variable i to 0 and run byThrees() with i being 0 initially. This means that you can repeatedly call run() in your code and every time it will output 0 3 6 9 12.
If what you mean in your post is that you want your code to output 0 3 6 9 12 and then 15 18 21 24 27 on the next call (and so on), you could do something like this:
#include <iostream>
using namespace std;
int i = 0, nextI = 0; // nextI is a variable that stores the next starting position of i
int main()
{
run(); // will output "0 3 6 9 12"
run(); // will output "15 18 21 24 27"
run(); // will output "30 33 36 39 42"
return 0;
}
void byThrees()
{
while(i < nextI + 13) {
cout << i << ' ';
i += 3;
}
nextI += 15; // increases nextI for the next time "run()" is called
}
void run()
{
i = nextI;
byThrees();
}
This code basically keeps track of where the list of numbers left off and continues from there.

Potential race condition for a simple multiple threading program

I'm writing a simple program that consists of three threads. Each thread is passed in an object Foo and no matter which thread calls which function, the output for the program will always be "firstsecondthird". I use semaphore and I'm writing the test code for my implementation. Sometimes, my test case passed but sometimes the test case failed:
input: [1,2,3] = firstsecond
Assertion failed: (false), function test, file /home/foo/printInOrder.cc, line 100.
Abort trap: 6
My program looks like below:
#include "cpputility.h"
#include <functional>
#include <iostream>
#include <semaphore.h>
#include <sstream>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
using namespace std;
void printFirst()
{
cout << "first" << std::flush;
}
void printSecond()
{
cout << "second" << std::flush;
}
void printThird()
{
cout << "third" << std::flush;
}
class Foo
{
protected:
sem_t firstJobDone;
sem_t secondJobDone;
public:
Foo()
{
sem_init(&firstJobDone, 0, 0);
sem_init(&secondJobDone, 0, 0);
}
void first(function<void()> printFirst)
{
printFirst();
sem_post(&firstJobDone);
}
void second(function<void()> printSecond)
{
sem_wait(&firstJobDone);
printSecond();
sem_post(&secondJobDone);
}
void third(function<void()> printThird)
{
sem_wait(&secondJobDone);
printThird();
}
};
void test()
{
unordered_map<int, pair<void (Foo::*)(function<void()>), function<void()>>> m({
{1, {&Foo::first, printFirst}},
{2, {&Foo::second, printSecond}},
{3, {&Foo::third, printThird}},
});
struct testCase
{
vector<int> input;
string expected;
};
vector<testCase> test_cases = {
{{1, 2, 3}, "firstsecondthird"},
{{1, 3, 2}, "firstsecondthird"},
};
for (auto &&test_case : test_cases)
{
std::stringstream buffer;
std::streambuf *old = std::cout.rdbuf(buffer.rdbuf());
Foo foo;
vector<thread> threads;
for (int i = 0; i < 3; ++i)
{
threads.emplace_back(m[i+1].first, foo, m[i+1].second);
}
for (auto &&th : threads)
{
th.join();
}
auto got = buffer.str();
if (got != test_case.expected)
{
printf("input: %s = %s\n",
CPPUtility::oneDVectorStr<int>(test_case.input).c_str(),
got.c_str());
assert(false);
}
std::cout.rdbuf(old);
}
}
int main()
{
for(int i = 0; i < 10; ++i) {
// Test repeatedly to detect any potential race condition
test();
}
}
The oneDVectorStr is some helper function I write inside a file called cpputility.h to help print out the 1D vector, here is the implementation to compile the code above
template <typename T>
std::string oneDVectorStr(const std::vector<T>& vec) {
std::string cand = "[";
for(int i = 0; i < vec.size(); ++i) {
cand += std::to_string(vec[i]);
i != vec.size() - 1 ? cand += "," : cand += "";
}
cand += "]";
return cand;
}
I've stared at this code for quite a while but couldn't locate any race condition. Any suggestion is welcome. Thanks in advance.
I take a further look at code and realize that there is a subtle bug in my test code: I pass Foo object (e.g., foo) by copy when create each new thread. However, I really want to have multiple threads sharing the same Foo object across multiple threads. Thus, I add std::ref to the foo:
threads.emplace_back(m[i + 1].first, ref(foo), m[i + 1].second);
In addition, I print firstJobDone and secondJobDone semaphore values using sem_getvalue() as following:
Foo()
{
sem_init(&firstJobDone, 0, 0);
sem_init(&secondJobDone, 0, 0);
int value;
sem_getvalue(&firstJobDone, &value);
printf("The initial value of the firstJobDone is %d\n", value);
sem_getvalue(&secondJobDone, &value);
printf("The initial value of the secondJobDone is %d\n", value);
}
And quite shocking, I have:
The initial value of the firstJobDone is 32766
The initial value of the secondJobDone is 32766
input: [1,2,3] = third
Assertion failed: (false), function test, file /home/foo/printInOrder.cc, line 101.
Abort trap: 6
Both semaphores are not properly initialized to 0 with LLVM on the Mac that I'm using. However, my implementation invariant insists that both semaphores have to be initilized to 0. I don't understand why but I'm assuming since sem_init is marked as deprecated by LLVM, the behavior is not guaranteed to be correct. Thus, per the comments to my question, I change my implementation using conditional variable and mutex, and everything works fine.

Variable not declared within this scope Array Linear Search

I am trying to make a program in C++ that will search for a desired value in an array of size 10 using a separate search function. Below is the code:
main.cpp
#include <iostream>
#include <array>
using namespace std;
int main()
{
cout << "Welcome to the array linked list program.";
int sanadA[] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
int d = 0;
cin >> d;
while (d =! 0)
{
cout << "Number to be found";
cin >> d;
bool found = seqSearch1(sanadA, 10, d, -1);
cout << found;
}
}
seqSearch1.cpp
#include <iostream>
using namespace std;
bool jw_search (int *list, int size, int key, int*& rec)
{ //Basic sequential search.
bool found = false;
int i;
for(i=0;i<size;i++)
{
if (key == list[i])
{
break;
}
if (i < size)
{
found = true;
rec = &list[i];
}
}
return found;
}
I get the errors:
C:\Users\tevin\Documents\sanad\main.cpp|13|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.|
C:\Users\tevin\Documents\sanad\main.cpp|19|error: 'seqSearch1' was not declared in this scope|
I need help figuring why this happens.
I assume that the error occurs on this line:
bool found = seqSearch1(sanadA, 10, d, -1);
The problem is that you have not declared any function named seqSearch1(). Instead you have a function named jw_search(). So you can change the line to this:
bool found = jw_search(sanadA, 10, d, -1);
But you also need a header file called seqSearch1.h with the following line:
bool jw_search (int *list, int size, int key, int*& rec);
And finally add this line to the top of main.cpp:
#include "seqSearch1.h"
When you compile your code, you will need to include all source files in the command. For example, if you are using g++, you can do something like this:
g++ main.cpp seqSearch1.cpp
To understand how this works, you need to learn about header files and the difference between a function declaration and a function definition. You should also learn about the difference between the compiler and the linker.
Code-Apprentice has the direct answer to your question. If you want the code in multiple files then a declaration of the seqSearch1 function will need to be main.cpp or included via #include directive
The code has multiple problems. I've fixed it up a bit for you and put it in a single file.
#include <iostream>
#include <array>
using namespace std;
bool seqSearch1 (int *list, int size, int key, int& rec)
{//Basic sequential search.
bool found = false;
int i;
for(i=0;i<size;i++)
{
if (key == list[i])
{
found = true;
rec = i;
break;
}
}
return found;
}
int main()
{
cout << "Welcome to the array linked list program." << endl;
int sanadA[] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
int d = -1;
while (d != 0)
{
cout << "Number to be found, 0 to end?";
cin >> d;
if(d == 0) break;
int index = -1;
bool found = seqSearch1(sanadA, 10, d, index);
if(found) cout << "Found" << endl;
else cout << "Not Found" << endl;
}
}
Several issues:
The function was referred to by the wrong name.
The loop structure was a confused.
The fourth argument to seqSearch1 had type confusion.

Check if element found in array c++

How can I check if my array has an element I'm looking for?
In Java, I would do something like this:
Foo someObject = new Foo(someParameter);
Foo foo;
//search through Foo[] arr
for(int i = 0; i < arr.length; i++){
if arr[i].equals(someObject)
foo = arr[i];
}
if (foo == null)
System.out.println("Not found!");
else
System.out.println("Found!");
But in C++ I don't think I'm allowed to search if an Object is null so what would be the C++ solution?
In C++ you would use std::find, and check if the resultant pointer points to the end of the range, like this:
Foo array[10];
... // Init the array here
Foo *foo = std::find(std::begin(array), std::end(array), someObject);
// When the element is not found, std::find returns the end of the range
if (foo != std::end(array)) {
cerr << "Found at position " << std::distance(array, foo) << endl;
} else {
cerr << "Not found" << endl;
}
You would just do the same thing, looping through the array to search for the term you want. Of course if it's a sorted array this would be much faster, so something similar to prehaps:
for(int i = 0; i < arraySize; i++){
if(array[i] == itemToFind){
break;
}
}
There are many ways...one is to use the std::find() algorithm, e.g.
#include <algorithm>
int myArray[] = { 3, 2, 1, 0, 1, 2, 3 };
size_t myArraySize = sizeof(myArray) / sizeof(int);
int *end = myArray + myArraySize;
// find the value 0:
int *result = std::find(myArray, end, 0);
if (result != end) {
// found value at "result" pointer location...
}
Here is a simple generic C++11 function contains which works for both arrays and containers:
using namespace std;
template<class C, typename T>
bool contains(C&& c, T e) { return find(begin(c), end(c), e) != end(c); };
Simple usage contains(arr, el) is somewhat similar to in keyword semantics in Python.
Here is a complete demo:
#include <algorithm>
#include <array>
#include <string>
#include <vector>
#include <iostream>
template<typename C, typename T>
bool contains(C&& c, T e) {
return std::find(std::begin(c), std::end(c), e) != std::end(c);
};
template<typename C, typename T>
void check(C&& c, T e) {
std::cout << e << (contains(c,e) ? "" : " not") << " found\n";
}
int main() {
int a[] = { 10, 15, 20 };
std::array<int, 3> b { 10, 10, 10 };
std::vector<int> v { 10, 20, 30 };
std::string s { "Hello, Stack Overflow" };
check(a, 10);
check(b, 15);
check(v, 20);
check(s, 'Z');
return 0;
}
Output:
10 found
15 not found
20 found
Z not found
One wants this to be done tersely.
Nothing makes code more unreadable then spending 10 lines to achieve something elementary.
In C++ (and other languages) we have all and any which help us to achieve terseness in this case. I want to check whether a function parameter is valid, meaning equal to one of a number of values.
Naively and wrongly, I would first write
if (!any_of({ DNS_TYPE_A, DNS_TYPE_MX }, wtype) return false;
a second attempt could be
if (!any_of({ DNS_TYPE_A, DNS_TYPE_MX }, [&wtype](const int elem) { return elem == wtype; })) return false;
Less incorrect, but looses some terseness.
However, this is still not correct because C++ insists in this case (and many others) that I specify both start and end iterators and cannot use the whole container as a default for both. So, in the end:
const vector validvalues{ DNS_TYPE_A, DNS_TYPE_MX };
if (!any_of(validvalues.cbegin(), validvalues.cend(), [&wtype](const int elem) { return elem == wtype; })) return false;
which sort of defeats the terseness, but I don't know a better alternative...
Thank you for not pointing out that in the case of 2 values I could just have just if ( || ). The best approach here (if possible) is to use a case structure with a default where not only the values are checked, but also the appropriate actions are done.
The default case can be used for signalling an invalid value.
You can use old C-style programming to do the job. This will require little knowledge about C++. Good for beginners.
For modern C++ language you usually accomplish this through lambda, function objects, ... or algorithm: find, find_if, any_of, for_each, or the new for (auto& v : container) { } syntax. find class algorithm takes more lines of code. You may also write you own template find function for your particular need.
Here is my sample code
#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
using namespace std;
/**
* This is old C-like style. It is mostly gong from
* modern C++ programming. You can still use this
* since you need to know very little about C++.
* #param storeSize you have to know the size of store
* How many elements are in the array.
* #return the index of the element in the array,
* if not found return -1
*/
int in_array(const int store[], const int storeSize, const int query) {
for (size_t i=0; i<storeSize; ++i) {
if (store[i] == query) {
return i;
}
}
return -1;
}
void testfind() {
int iarr[] = { 3, 6, 8, 33, 77, 63, 7, 11 };
// for beginners, it is good to practice a looping method
int query = 7;
if (in_array(iarr, 8, query) != -1) {
cout << query << " is in the array\n";
}
// using vector or list, ... any container in C++
vector<int> vecint{ 3, 6, 8, 33, 77, 63, 7, 11 };
auto it=find(vecint.begin(), vecint.end(), query);
cout << "using find()\n";
if (it != vecint.end()) {
cout << "found " << query << " in the container\n";
}
else {
cout << "your query: " << query << " is not inside the container\n";
}
using namespace std::placeholders;
// here the query variable is bound to the `equal_to` function
// object (defined in std)
cout << "using any_of\n";
if (any_of(vecint.begin(), vecint.end(), bind(equal_to<int>(), _1, query))) {
cout << "found " << query << " in the container\n";
}
else {
cout << "your query: " << query << " is not inside the container\n";
}
// using lambda, here I am capturing the query variable
// into the lambda function
cout << "using any_of with lambda:\n";
if (any_of(vecint.begin(), vecint.end(),
[query](int val)->bool{ return val==query; })) {
cout << "found " << query << " in the container\n";
}
else {
cout << "your query: " << query << " is not inside the container\n";
}
}
int main(int argc, char* argv[]) {
testfind();
return 0;
}
Say this file is named 'testalgorithm.cpp'
you need to compile it with
g++ -std=c++11 -o testalgorithm testalgorithm.cpp
Hope this will help. Please update or add if I have made any mistake.
If you were originally looking for the answer to this question (int value in sorted (Ascending) int array), then you can use the following code that performs a binary search (fastest result):
static inline bool exists(int ints[], int size, int k) // array, array's size, searched value
{
if (size <= 0) // check that array size is not null or negative
return false;
// sort(ints, ints + size); // uncomment this line if array wasn't previously sorted
return (std::binary_search(ints, ints + size, k));
}
edit: Also works for unsorted int array if uncommenting sort.
You can do it in a beginners style by using control statements and loops..
#include <iostream>
using namespace std;
int main(){
int arr[] = {10,20,30,40,50}, toFind= 10, notFound = -1;
for(int i = 0; i<=sizeof(arr); i++){
if(arr[i] == toFind){
cout<< "Element is found at " <<i <<" index" <<endl;
return 0;
}
}
cout<<notFound<<endl;
}
C++ has NULL as well, often the same as 0 (pointer to address 0x00000000).
Do you use NULL or 0 (zero) for pointers in C++?
So in C++ that null check would be:
if (!foo)
cout << "not found";

Call to function is ambiguous in C++. Candidate functions are the Prototype and the function itself

I am working through Stanford CS106B C++ assignments and I have a 'semantic issue' with an assignment.
It seems as if the compiler cannot deduce whether the call is to a function or to the prototype of the function. I don't understand why a call would ever be made to the prototype. How can I make it so that the call is made to the function rather than the prototype? The error message I get it "Call to 'humansTurn' is ambiguous".
The error messages relate to the calls of the humansTurn(Lexicon,Lexicon) function, within the humansTurn(Lexicon,Lexicon) function, at the bottom of the page. The prototype for this function is above the main function.
Any help would be greatly appreciated.
Kind regards,
Mehul
/*
* File: Boggle.cpp
* ----------------
*/
#include <iostream>
#include "gboggle.h"
#include "graphics.h"
#include "grid.h"
#include "vector.h"
#include "lexicon.h"
#include "random.h"
#include "simpio.h"
using namespace std;
/* Constants */
const int BOGGLE_WINDOW_WIDTH = 650;
const int BOGGLE_WINDOW_HEIGHT = 350;
const string STANDARD_CUBES[16] = {
"AAEEGN", "ABBJOO", "ACHOPS", "AFFKPS",
"AOOTTW", "CIMOTU", "DEILRX", "DELRVY",
"DISTTY", "EEGHNW", "EEINSU", "EHRTVW",
"EIOSST", "ELRTTY", "HIMNQU", "HLNNRZ"
};
const string BIG_BOGGLE_CUBES[25] = {
"AAAFRS", "AAEEEE", "AAFIRS", "ADENNN", "AEEEEM",
"AEEGMU", "AEGMNN", "AFIRSY", "BJKQXZ", "CCNSTW",
"CEIILT", "CEILPT", "CEIPST", "DDLNOR", "DDHNOT",
"DHHLOR", "DHLNOR", "EIIITT", "EMOTTT", "ENSSSU",
"FIPRSY", "GORRVW", "HIPRRY", "NOOTUW", "OOOTTU"
};
/* Function prototypes */
void welcome();
void giveInstructions();
// Create random board
static Grid <char> randomBoard();
// Create custom board
static Grid<char> customBoard();
static void drawAndFillBoard(Grid<char>);
static void humansTurn(Lexicon,Lexicon);
int main() {
initGraphics(BOGGLE_WINDOW_WIDTH, BOGGLE_WINDOW_HEIGHT);
welcome();
giveInstructions();
string custom = getLine("Type y to create custom board:" );
Grid<char> gridData;
if (custom=="y"){
gridData = customBoard();
} else {
gridData = randomBoard();
}
drawAndFillBoard(gridData);
Lexicon english("EnglishWords.dat");
// Lexicon holds words previously encountered
Lexicon previousWords;
humansTurn(english, previousWords);
return 0;
}
/*
* Function: welcome
* Usage: welcome();
* -----------------
* Print out a cheery welcome message.
*/
void welcome() {
cout << "Welcome! You're about to play an intense game " << endl;
}
/*
* Function: giveInstructions
* Usage: giveInstructions();
* --------------------------
* Print out the instructions for the user.
*/
void giveInstructions() {
cout << endl;
cout << "The boggle board is a grid onto which I ";
cout << "or triple your paltry score." << endl << endl;
cout << "Hit return when you're ready...";
getLine();
}
static Grid<char> randomBoard(){
Vector<string> standardCubes;
for(int i = 0; i<16;i++){
standardCubes.add(STANDARD_CUBES[i]);
}
// Shuffle cubes
for (int i = 0; i < standardCubes.size(); i++) {
int r = randomInteger(i, standardCubes.size()-1);
if (i!=r){
string stringToMove1 = standardCubes.get(i);
string stringToMove2 = standardCubes.get(r);
standardCubes.set(r, stringToMove1);
standardCubes.set(i, stringToMove2);
}
}
// Update grid with random side of cube
Grid<char> gridData(4, 4);
int counter = 0;
for (int columnNo = 0; columnNo <4; columnNo++){
for (int rowNo = 0; rowNo<4; rowNo++) {
string s = standardCubes.get(counter);
int r = randomInteger(0, 5);
gridData[columnNo][rowNo] = s[r];
counter++;
}
}
return gridData;
}
static Grid<char> customBoard(){
Grid<char> gridData(4,4);
string s = getLine("Please enter 16 characters to make up the custom board. Characters will fill the board left to right, top to bottom: ");
for (int i = 0; i < s.length(); i++) {
s[i] = toupper(s[i]);
}
if (s.length()<16){
cout << "String has to be 16 characters long, try again" << endl;
customBoard();
}
int i =0;
for (int columnNo = 0; columnNo <4; columnNo++){
for (int rowNo = 0; rowNo<4; rowNo++) {
gridData[columnNo][rowNo] = s[i];
i++;
}
}
return gridData;
}
static void drawAndFillBoard(Grid<char> gridData){
drawBoard(4, 4);
for (int columnNo = 0; columnNo <4; columnNo++){
for (int rowNo = 0; rowNo<4; rowNo++) {
labelCube(rowNo, columnNo, gridData[rowNo][columnNo]);
}
}
}
static void humansTurn(Lexicon englishWords, Lexicon &previousWords){
/*
Human’s turn (except for finding words on the board). Write the loop that allows the user to enter words. Reject words that have already been entered or that don’t meet the minimum word length or that aren’t in the lexicon. Use the gboggle functions to add words to the graphical display and keep score.
*/
string humanGuess = getLine("Please enter your guess: ");
for (int i = 0; i < humanGuess.length(); i++) {
humanGuess[i] = tolower(humanGuess[i]);
}
if (humanGuess.length()<4){
cout << "Min guess length is four characters" << endl;
humansTurn(englishWords, previousWords);
}
if (!englishWords.contains(humanGuess)) {
cout << "That word is not English, please try another word" << endl;
humansTurn(englishWords, previousWords);
}
if (previousWords.contains(humanGuess)){
cout << "That word has already been guessed, please try another word" << endl;
humansTurn(englishWords, previousWords);
}
// check if word can be made using data on board
}
Your function humansTurn definition has different signature with declaration
function declaration:
static void humansTurn(Lexicon,Lexicon);
Function definition:
static void humansTurn(Lexicon englishWords, Lexicon &previousWords)
^^
//Here