This commit is contained in:
Michael Zhang 2018-01-29 17:24:20 -06:00
commit 1ba4536588
No known key found for this signature in database
GPG key ID: A1B65B603268116B
897 changed files with 104285 additions and 0 deletions

BIN
_templates/templates Executable file

Binary file not shown.

144
_templates/templates.cc Normal file
View file

@ -0,0 +1,144 @@
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
class ArenaEntity {
public:
ArenaEntity(int r = 10) : radius(r) {}
void Print() { std::cout << "Entity with radius " << radius << std::endl; }
private:
int radius;
};
// A polymorphic swap function for any type of object
template <typename T>
void MySwap(T& x, T& y) {
T temp;
temp = x;
x = y;
y = temp;
}
// A polymorphic class holding an [x,y] position of any type
template <class T>
class Position {
public:
Position(T x = 0, T y = 0) : x_(x), y_(y) {}
friend std::ostream& operator<<(std::ostream& os, const Position& p) {
return os << "[" << p.x_ << ", " << p.y_ << "]";
}
// >>>> ADD SETTERS AND GETTERS
T get_x() { return x_; }
void set_x(T x) { x_ = x; }
T get_y() { return y_; }
void set_y(T y) { y_ = y; }
// >>>>> OVERLOAD OPERATORS + and - binary operators as member functions.
Position operator+(const Position& other) {
return Position(x_ + other.x_, y_ + other.y_);
}
Position operator-(const Position& other) {
return Position(x_ - other.x_, y_ - other.y_);
}
private:
T x_;
T y_;
};
// >>>>> CREATE AN ARRAY TEMPLATE that takes type and number of elements
// template<class T, int N> ...
// >>>>> OVERLOAD operator []. Do a check on index to be in range
// >>>>> METHODS to push and pop
template <class T, int N>
class
AnArrayClassThatsWorseThanVectorButApparentlyBetterThanBuiltinArraysButNotReally {
public:
T operator[](const int index) {
if (index > N) {
int* x = (int*)NULL;
printf("%d\n", *x);
// cause a segfault cuz why not
}
return array[index];
}
void push(T a) {
if (array.size() >= N) return;
array.push_back(a);
}
T pop() {
auto last = *(array.rbegin());
array.erase(array.rbegin());
return last;
}
private:
std::vector<T> array; // use a vector internally because it's the best!
};
int main(void) {
// -----------------------------------------------------------------
// Demonstration of the use of the template Vector and its iterator
std::vector<class ArenaEntity*> entities_;
entities_.push_back(new ArenaEntity(20));
entities_.push_back(new ArenaEntity(25));
for (std::vector<class ArenaEntity*>::iterator ent = entities_.begin();
ent != entities_.end(); ++ent) {
(*ent)->Print();
}
// This is the same as above, except with the convenience of auto typing
std::cout << std::endl;
for (auto ent : entities_) {
ent->Print();
}
// -----------------------------------------------------------------
// Demonstration of the use of template for function overloading
int intA, intB;
float floatA, floatB;
char charA, charB;
intA = 10;
intB = 20;
floatA = 2.5;
floatB = 10.5;
charA = 'a';
charB = 'b';
std::cout << std::endl;
std::cout << "int A,B: [" << intA << ", " << intB << "]" << std::endl;
std::cout << "float A,B: [" << floatA << ", " << floatB << "]" << std::endl;
std::cout << "char A,B: [" << charA << ", " << charB << "]" << std::endl;
MySwap(intA, intB);
MySwap(floatA, floatB);
MySwap(charA, charB);
std::cout << std::endl;
std::cout << "int A,B: [" << intA << ", " << intB << "]" << std::endl;
std::cout << "float A,B: [" << floatA << ", " << floatB << "]" << std::endl;
std::cout << "char A,B: [" << charA << ", " << charB << "]" << std::endl;
// -----------------------------------------------------------------
// Demonstration of the use of template for class definition
Position<int> intPos(10, 10);
Position<float> floatPos(1.5, 1.5);
Position<char> charPos('A', 'B');
std::cout << std::endl;
std::cout << intPos << std::endl;
std::cout << floatPos << std::endl;
std::cout << charPos << std::endl;
Position<int> intPos2(20, 20);
intPos2.set_x(30);
std::cout << intPos + intPos2 << std::endl;
// -----------------------------------------------------------------
// Demonstration of the use of template for class ARRAY
AnArrayClassThatsWorseThanVectorButApparentlyBetterThanBuiltinArraysButNotReally<
int, 1>
a;
a.push(5);
a.push(6);
printf("value: %d\n", a[2]);
}

1
aaaa Submodule

@ -0,0 +1 @@
Subproject commit 10983be67c48557abadab23de493ba4bae41289a

3
class-repo-public/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.o
*.*~
*.out

View file

@ -0,0 +1,74 @@
CSCI3081 Fall 2017
## Writing Assignment : Responding to Writing in CS
<font color="red">
Due: Monday, September 25 at 10:00pm
</font>
### Introduction
There are many different types of writing in computer science. This assignment gives you a chance to reflect on an example of your choice and, ignoring the technical content for the moment, reflect upon just the writing style and approach to determine what makes it successful or unsuccessful.
### Your Assignment
Find one piece of computer science writing that is of interest to you and read it.  This can be online or hardcopy material, and "computer science writing" can be interpreted widely here.  In this class, we are interested in software design and development, so you might look for some writing that relates to software design patterns, coding style, libraries or toolkits for software development, or even research on software engineering.  Anything a software developer might find useful as a part of doing his or her job, honing his or her skills, etc. is fine -- pick something that is interesting to you.  The writing should be <u>more than a couple pages long</u>. Once you have read the material, answer the following questions in a typed document with separate headings for Question 1, Question 2, etc. **Submit a PDF of your responses directly to the Writing Assignment link in Moodle**.
#### Question 1 
What is the title of the writing and where can it be found? Give a citation or URL. 
#### Question 2
What is the purpose of the writing?  For example, is the purpose to present a new technique, describe a software testing plan, argue for adopting a particular methodology for software design, etc.?
#### Question 3 
As best as you can tell, who is the intended audience? 
#### Question 4 
At the end of this page is a list of Elements of Successful Writing in CS that was recently compiled by the faculty in the Department of Computer Science & Engineering.  How important is each item on this list for the type of writing that you picked? Copy the list below, and for each item, rate how important you think it is using the following scale:  (a) extremely important, (b) useful but not critical, (c) not very important, or (d) not applicable.  Note, we are not (yet) asking you to judge the quality of what you read based on these "successful elements".  First, let's just establish which of these elements are most important for the type of writing (e.g., a scholarly report, a blog post, a user manual, a programmer's style guide) you have selected.
#### Question 5
Now, let's evaluate the writing.  What do you think is the most successful element of the writing (e.g., a good organization and logical flow, good use of visuals)?  Write one paragraph to explain why you think this element is so critical to making the writing work for the intended audience and purpose.
#### Question 6 
Finally, what is the least successful element of the writing?  Write one paragraph to explain how the structure, visuals, organization, or whatever other element you think is weak in this example, limits the writing in achieving its purpose for the intended audience.
## Elements of Successful Writing in CS:
<ol type="A">
<li> States key information clearly (important findings, recommendations, ideas, issues, etc.). 
<li> Addresses the target audience with an appropriate tone and level of explanation. 
<li> Presents any needed background explanation clearly or informatively. 
<li> Persuasively justifies a choice of algorithm, design, problem approach, problem solution, etc. 
<li> Describes algorithms, data structures, software system components, etc. accurately. 
<li> Describes algorithms, data structures, software system components, etc. informatively and concisely. 
<li> Uses terminology and notation correctly. 
<li> Explains high-level ideas with low-level details. 
<li> Presents low-level details clearly and accurately. 
<li> Uses appropriate structures (e.g., lists, diagrams, equations, code samples, etc.). 
<li> Includes clear and informative tables, diagrams, references, etc. 
<li> Smoothly integrates tables, diagrams, references, etc. into the text. 
<li> Has a good organization and logical flow. 
<li> Uses correct grammar, spelling, and mechanics. 
<li> Avoids including irrelevant information, overemphasizing less important material, or writing verbosely.
</ol>

Binary file not shown.

View file

@ -0,0 +1,20 @@
#include "cart.h"
CartEntry::CartEntry( float p, int q) {
price = p;
quantity = q;
}
Order::Order( CartContents c, float s ) {
cart = c;
salesTax = s;
}
float Order::OrderTotal() {
float cartTotal = 0;
for (int i=0; i < cart.itemCount; i++) {
cartTotal += cart.items[i].price * cart.items[i].quantity;
}
cartTotal += cartTotal * salesTax;
return cartTotal;
}

View file

@ -0,0 +1,26 @@
// A class for a single element in a cart
class CartEntry {
public:
float price;
int quantity;
CartEntry( float p=0, int q=0);
};
// A collection of elements in a cart
// CartContents "has a" CartEntry - using composition
class CartContents{
public:
int itemCount; // number of elements in cart
CartEntry* items;
};
// An order is the combination of a cart and tax
// different states apply different salesTax rates.
class Order {
private:
CartContents cart;
float salesTax;
public:
Order(CartContents cart, float salesTax);
float OrderTotal();
};

View file

@ -0,0 +1,27 @@
#include <iostream>
#include "cart.h"
int main() {
// Create an array of CartEntry's to put in the cart
// Arbitrary values for price and quantity
CartEntry inCart[5];
for (int i=0; i<5; i++) {
inCart[i].price = i*2;
inCart[i].quantity = i;
}
// Place the CartEntry array in a CartContents
CartContents purchases;
purchases.items = inCart;
purchases.itemCount = 5;
// Make this an order with associated tax
Order order1(purchases, .077);
// Get total price of order
std::cout << '$' << order1.OrderTotal() << std::endl;
return 0;
}

View file

@ -0,0 +1,18 @@
# CSCI3081 cart exercise makefile
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
all: main.o cart.o
$(CC) $(LFLAGS) main.o cart.o -o cart
main.o : main.cpp
$(CC) $(CFLAGS) main.cpp -o main.o
robot.o : cart.cpp
$(CC) $(CFLAGS) cart.cpp -o cart.o
clean:
\rm *.o *.*~ cart

View file

@ -0,0 +1,8 @@
### Shopping with Bad Design
This example demonstrates bad design. There are many things wrong with respect to the design principles of
encapsulation, coupling, cohesion, and information hiding. The interface of the class, which is dictated
by the class definition, is integral to the quality of the design.
Can you identify some of the problems with this design? Think about our enemy _modification_, and where
in the code would modifications have a ripple effect that requires several changes in several places.

View file

@ -0,0 +1,83 @@
#include <iostream>
using std::cout;
using std::endl;
class ObjectClass {
private:
int privateVar;
protected:
int protectedVar;
public:
ObjectClass() :
privateVar(10), protectedVar(15) {}
ObjectClass(int a, int b) :
privateVar(a), protectedVar(b) {}
void print() {
cout << "in objectClass. ";
cout << "priv, prot = " << privateVar << ' '<< protectedVar << endl;
}
void setPrivate(int a) { privateVar = a;}
void setProtected(int a) { protectedVar = a;}
};
class ComposedClass {
private:
ObjectClass object;
//int privateVar;
public:
void print() {
//cout << "in composedClass. ";
//cout << "privateVar " << privateVar << endl;
//cout << "protectedVar " << protectedVar << endl;
//cout << "object privateVar " << object.privateVar << endl;
//cout << "object protectedVar " << object.protectedVar << endl;
object.print();
}
protected:
//int protectedVar;
};
class DerivedClass : public ObjectClass {
private:
/*
int privateVar;
int protectedVar;
*/
public:
// DerivedClass() {}
//DerivedClass() : ObjectClass(1,2) {}
/*{
privateVar = 20;
protectedVar = 25;
}*/
void print() {
//cout << "in derivedClass. ";
//cout << "privateVar " << privateVar << endl;
//cout << "protectedVar " << protectedVar << endl;
//cout << "object privateVar " << ObjectClass::privateVar << endl;
//cout << "object protectedVar " << ObjectClass::protectedVar << endl;
ObjectClass::print();
}
};
int main() {
ObjectClass baseObject_default;
ObjectClass baseObject_2_3(2,3);
ComposedClass hasAobject_default;
DerivedClass isAobject_default;
// DerivedClass isAobject_4_5(4,5);
cout << "Base default: ";
baseObject_default.print();
cout << "Base 2,3 : ";
baseObject_2_3.print();
cout << "Composed default : ";
hasAobject_default.print();
cout << "Derived default : ";
isAobject_default.print();
cout << "Derived 4,5 : ";
// isAobject_4_5.print();
return 1;
}

View file

@ -0,0 +1,42 @@
### _ComposedClass_
<ol>
<li> Uncomment each of the 'cout' statements, explain why it doesn't compile:
<ul>
<li> privateVar </li>
<li> protectedVar </li>
<li> object.privateVar </li>
<li> object.protectedVar </li>
</ul>
<li> Uncomment the declaration of privateVar and protectedVar inside the ComposedClass definition.
<ul><li>
Which of the 'cout' statements can now be successfully compiled? Why?
</ul>
<li> ComposedClass probably needs to interact with _object_ members. How will you give it access?
</ol>
### DerivedClass
<ol>
<li> Uncomment each of the 'cout' statements, determine which successfully compiles and explain why or why not:
<ul>
<li> privateVar
<li> protectedVar
<li> ObjectClass::privateVar
<li> ObjectClass::protectedVar
</ul>
<li> How is it that you redefined _print()_ in the derived class, and yet you can still call _print()_ in the ObjectClass?
<li> In main, the declaration of isAobject_4_5(4,5) is commented out because it will not compile. Why not? There isn't a constructor for DerivedClass with no parameters and that works.
<li> Uncomment the DerivedClass constructor that has no parameters (i.e. 'DerivedClass() :' ).
- Determine which of the cout statements compiles and explain why.
<li> Uncomment the members privateVar and protectedVar in DerivedClass, and modify comments in the code so that DerivedClass() : sets those vars to 20 and 25.
<ul><li>
Report the values for each 'cout' in Derived and explain the results.
</ul>
<li> In main, now fix DerivedClass so that the statement 'DerivedClass isAobject_4_5(4,5)' works.
</ol>

View file

@ -0,0 +1,89 @@
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
class Robot;
class EventDistress;
/*!
* @brief The [x,y] position with respect to the graphics arena
*
* \todo Implement operator overloading for '-' and '<<'
*/
struct Position {
Position( double in_x=0, double in_y=0) : x(in_x), y(in_y) {}
double x;
double y;
// Operator Overload '-'
// Operator Overload '<<'
};
/**
* @brief Activates when a distress call is within its range.
*
* SensorDistress is a part of a robot. Implented with the Observer Pattern
* the Arena (i.e. the subject) will call \ref Accept to alert the sensor
* of all distress calls in the arena. The SensorDistress has to determine
* whether or not this call will activate its sensor (which is part of a Robot).
*
* Either the Robot or parts of the Robot (e.g. RobotMotionHandler) will use
* the sensor output to effect behavior.
*
*/
class SensorDistress {
public:
SensorDistress(const Robot * robot, double range):
robot_(robot), range_(range) {}
void Accept(const EventDistress & ed);
int Output();
private:
double range_;
const Robot * robot_;
std::vector<int> entity_ids_;
};
// As an observer, the sensor gets alerted of the "subject" arena
void SensorDistress::Accept(const EventDistress & ed ) {
// Is this distress call from the robot that I am part of?
// Is this a distress call I can hear?
}
int Output() {
return 1;
// Is this activated or not?
}
/*!
* @brief A simple robot class that has an id and position
*
*/
class Robot {
public:
Robot(Position p, int id) : pos_(p), id_(id),
sensor_distress_(new SensorDistress(this,50)) {}
Position get_pos() { return pos_; }
void set_pos(Position p) { pos_ = p; }
int get_id() { return id_; }
void set_id(int i) { id_ = i; }
private:
SensorDistress * sensor_distress_;
Position pos_;
int id_;
};
// Communication of the event that a distress call was emitted in the arena
class EventDistress {
public:
EventDistress(Position p, int id) : pos_(p), entity_id_(id) {}
Position get_pos() { return pos_; }
int get_entity_id() { return entity_id_; }
private:
Position pos_;
int entity_id_;
};
int main() {
Robot robbie(Position(100,100),1);
}

View file

@ -0,0 +1,106 @@
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
class ArenaEntity {
public:
ArenaEntity(int r=10) : radius(r) {}
void Print() {
std::cout << "Entity with radius " << radius << std::endl;
}
private:
int radius;
};
// A polymorphic swap function for any type of object
template<typename T>
void MySwap( T& x, T& y) {
T temp;
temp = x;
x = y;
y = temp;
}
// A polymorphic class holding an [x,y] position of any type
template<class T>
class Position {
public:
Position(T x=0, T y=0) : x_(x), y_(y) {}
friend std::ostream& operator<<(std::ostream& os, const Position& p) {
return os << "[" << p.x_ << ", " << p.y_ << "]";
}
// >>>> ADD SETTERS AND GETTERS
// >>>>> OVERLOAD OPERATORS + and - binary operators as member functions.
private:
T x_;
T y_;
};
// >>>>> CREATE AN ARRAY TEMPLATE that takes type and number of elements
// template<class T, int N> ...
// >>>>> OVERLOAD operator []. Do a check on index to be in range
// >>>>> METHODS to push and pop
int main(void) {
// -----------------------------------------------------------------
// Demonstration of the use of the template Vector and its iterator
std::vector<class ArenaEntity*> entities_;
entities_.push_back(new ArenaEntity(20));
entities_.push_back(new ArenaEntity(25));
for (std::vector<class ArenaEntity*>::iterator ent = entities_.begin();
ent != entities_.end();
++ent ) {
(*ent)->Print();
}
// This is the same as above, except with the convenience of auto typing
std::cout << std::endl;
for (auto ent : entities_) {
ent->Print();
}
// -----------------------------------------------------------------
// Demonstration of the use of template for function overloading
int intA, intB;
float floatA, floatB;
char charA, charB;
intA = 10; intB = 20;
floatA = 2.5; floatB = 10.5;
charA = 'a'; charB = 'b';
std::cout << std::endl;
std::cout << "int A,B: [" << intA << ", " << intB << "]" << std::endl;
std::cout << "float A,B: [" << floatA << ", " << floatB << "]" << std::endl;
std::cout << "char A,B: [" << charA << ", " << charB << "]" << std::endl;
MySwap(intA,intB);
MySwap(floatA,floatB);
MySwap(charA,charB);
std::cout << std::endl;
std::cout << "int A,B: [" << intA << ", " << intB << "]" << std::endl;
std::cout << "float A,B: [" << floatA << ", " << floatB << "]" << std::endl;
std::cout << "char A,B: [" << charA << ", " << charB << "]" << std::endl;
// -----------------------------------------------------------------
// Demonstration of the use of template for class definition
Position<int> intPos(10,10);
Position<float> floatPos(1.5,1.5);
Position<char> charPos('A','B');
std::cout << std::endl;
std::cout << intPos << std::endl;
std::cout << floatPos << std::endl;
std::cout << charPos << std::endl;
Position<int> intPos2(20,20);
//intPos2.set_x(30);
//std::cout << intPos+intPos2 << std::endl;
// -----------------------------------------------------------------
// Demonstration of the use of template for class ARRAY
}

Binary file not shown.

View file

@ -0,0 +1,3 @@
*.out
*.o
robot

View file

@ -0,0 +1,267 @@
### Demonstration of Class Definition in C++
<hr>
This first example makes use of the default constructor, but this is problematic due to initialization.
#### Robot.h
```C++
class Robot {
private:
float directionAngle;
int position[2];
public:
void moveForward( int distance );
void display();
};
```
#### Robot.cpp
```C++
#include "robot.h"
#include <math.h>
#include <iostream>
void Robot::moveForward(int distance) {
position[0] = position[0] + distance*cos(directionAngle);
position[1] = position[1] + distance*sin(directionAngle);
}
void Robot::display() {
cout << "Pos [" << position[0] << " " << position[1] << "]. angle "
<< directionAngle << endl;
}
```
#### main.cpp
In C++, _main()_ serves as the entry point to the program. It must exist to generate an executable.
```C++
#include "robot.h"
#include <iostream>
using std::cout;
int main() {
Robot rosyRobot;
rosyRobot.display();
}
```
You can compile the program using the provided makefile, then call the executable _robot_.
```
make
./robot
```
<hr>
We will fix the initialization problem by adding "setters" and add some "getters" while we are at it.
#### Robot.h
```C++
class Robot {
private:
float directionAngle;
int position[2];
public:
// setters and getters
void position( int x, int y);
int* position();
void radianDirectionAngle(float theta);
float radianDirectionAngle();
void moveForward( int distance );
void display();
};
```
#### Robot.cpp
Adding the following to the source code.
```C++
// setters and getters
void Robot::xyPosition( int x, int y) {
position[0] = x;
position[1] = y;
}
int* Robot::xyPosition() {
return position;
}
void Robot::radianDirectionAngle(float theta) {
directionAngle = theta;
}
float Robot::radianDirectionAngle() {
return directionAngle;
}
```
#### main.cpp
```C++
int main() {
Robot rosyRobot;
rosyRobot.xyPosition(0,0);
rosyRobot.radianDirectionAngle(0);
rosyRobot.display();
}
```
<hr>
This is dangerous to require users to initialize. Let's fix this by forcing the user to provide initialization.
#### Adding to Robot.h
We can pass along an array, but let's not do that right now. We will see why later.
```C++
Robot( int x, int y, float theta );
```
#### Adding to Robot.cpp
```C++
Robot( int x, int y, float theta ) {
position[0] = x;
position[1] = y;
directionAngle = theta;
}
```
<hr>
This can be cumbersome, let's give the user some options.
OPTION 1: Add a no-parameter constructor that initializes to reasonable values.
<hr>
#### Adding to robot.h
```C++
public:
Robot();
```
#### Adding to robot.cpp
```C++
Robot::Robot() {
position[0] = 0;
position[1] = 0;
directionAngle = 0;
}
```
#### Change main.cpp
```C++
int main() {
Robot rosyRobot;
rosyRobot.display();
}
```
OPTION 2: Add a constructor with a subset of the member variables.
#### Adding to robot.h
```C++
public:
Robot();
Robot( int x, int y );
Robot(float theta);
```
Then you will add these definitions to robot.cpp. Let's see how we use them.
#### main.cpp
```C++
int main() {
Robot rosyRobot;
Robot c3poRobot(100,100);
Robot halRobot(0,0,3.14/2);
Robot eveRobot(-100,-100,-3.14/4);
rosyRobot.display();
c3poRobot.display();
halRobot.display();
eveRobot.display();
}
```
Looks like this when you run it ...
```
Pos [0 0]. angle 0
Pos [100 100]. angle 0
Pos [0 0]. angle 1.57
Pos [-100 -100]. angle -0.785
```
OPTION 3: (Probably the best) Create a single constructor that can take 1 to all member variable initializations.
Now we have to undo some of our work. We need only the one constructor, because we will add _default_ values.
#### robot.h
```C++
Robot( int x=0, int y=0, float theta=0);
```
#### robot.cpp
```C++
Robot::Robot( int x, int y, float theta ) {
position[0] = x;
position[1] = y;
directionAngle = theta;
}
```
#### main.cpp
There was no need to change anything in main from before. All of the various forms of constructors was captured in the one constructor with default arguments.
```C++
int main() {
Robot rosyRobot;
Robot c3poRobot(100,100);
Robot halRobot(3.14);
Robot eveRobot(-100,-100,-3.14/4);
rosyRobot.display();
c3poRobot.display();
halRobot.display();
eveRobot.display();
}
```
And it comes out like this ...
```
Pos [0 0]. angle 0
Pos [100 100]. angle 0
Pos [3 0]. angle 0
Pos [-100 -100]. angle -0.785
```
*__OOPS__*. What happened to hal? We specified an angle of 3.14, but that didn't work. Can you explain that?
<hr>
#### Position is awkward and prone to error. Let's fix that with a class definition.
```
struct Position {
int x;
int y;
};
```
But now we have to change all of our code. Too bad we didn't think about this change before we started!

View file

@ -0,0 +1,27 @@
#include "robot.h"
#include <iostream>
using std::cout;
int main() {
Robot rosyRobot(0,0,0);
//rosyRobot.xyPosition(0,0);
//rosyRobot.radianDirectionAngle(0);
rosyRobot.display();
/*
c3poRobot.display();
Robot c3poRobot(100,100);
halRobot.display();
Robot halRobot(3.14);
Robot eveRobot(-100,-100,-3.14/4);
eveRobot.display();
*/
}

View file

@ -0,0 +1,18 @@
# CSCI3081 robot exercise makefile
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
all: main.o robot.o
$(CC) $(LFLAGS) main.o robot.o -o robot
main.o : main.cpp
$(CC) $(CFLAGS) main.cpp -o main.o
robot.o : robot.cpp
$(CC) $(CFLAGS) robot.cpp -o robot.o
clean:
\rm *.o *.*~ robot

View file

@ -0,0 +1,41 @@
#include "robot.h"
#include <math.h>
#include <iostream>
using std::cout;
using std::endl;
Robot::Robot( int x, int y, float theta) {
position[0] = x;
position[1] = y;
directionAngle = theta;
}
void Robot::moveForward(int distance) {
position[0] = position[0] + distance*cos(directionAngle);
position[1] = position[1] + distance*sin(directionAngle);
}
void Robot::display() {
cout
<< "Pos [" << position[0] << " " << position[1] << "]. angle "
<< directionAngle << endl;
}
void Robot::xyPosition( int x, int y) {
position[0] = x;
position[1] = y;
}
int* Robot::xyPosition() {
return position;
}
void Robot::radianDirectionAngle(float d) {
directionAngle = d;
}
float Robot::radianDirectionAngle() {
return directionAngle;
}

View file

@ -0,0 +1,19 @@
class Robot {
private:
float directionAngle;
int position[2];
public:
Robot(int x=0, int y=0, float theta=0);
void moveForward( int distance );
void display();
// setters and getters
void xyPosition( int x, int y);
int* xyPosition();
void radianDirectionAngle(float d);
float radianDirectionAngle();
};

View file

@ -0,0 +1,218 @@
import math
import turtle
# -------------- CLASS DEFINITIONS -----------------
# ----------------------------------------------------
def Velocity(angle, length):
x = length*math.cos(angle)
y = length*math.sin(angle)
return Vector(x,y)
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
self.angle = math.atan2(y,x)
self.pen = turtle.Turtle()
self.pen.hideturtle()
def Draw(self,color="black"):
self.pen.pu()
#self.pen.goto(self.ox, self.oy)
self.pen.goto(0,0)
self.pen.left(self.angle*180/math.pi)
self.pen.pd()
self.pen.color(color)
#self.pen.goto(int(self.x+self.ox), int(self.y+self.oy))
self.pen.goto(int(self.x), int(self.y))
def Clear(self):
self.pen.clear()
class Circle:
def __init__( self, radius, heading, pos, color ):
self.radius = radius
self.pos = pos
self.heading = heading
self.color = color
self.pen = turtle.Turtle()
self.pen.hideturtle()
self.vel = Velocity(self.heading, self.radius)
def Draw(self):
self.pen.pu()
self.pen.goto(self.pos[0], self.pos[1])
self.pen.pd()
self.pen.dot(self.radius*2, self.color)
def DrawHeading(self):
self.vel.Draw()
def Clear(self):
self.pen.clear()
self.vel.Clear()
# ---------------------------------------------------
def main(wall,test):
# wall==true, means test walls, else test quadrants
# test quadrant: 1:NE, 2:NW, 3:SW, 4:SE
# test wall: 0:right, 1:left, 2:up, 3:down, -1:quadrants instead
if wall:
# test wall: 0:right, 1:left, 2:up, 3:down, -1:quadrants instead
if 0 == test:
collision_angle_rad = math.atan2(0,40)
heading_angle_rad = math.atan2(10,20)
elif 1 == test:
collision_angle_rad = math.atan2(0,-40)
heading_angle_rad = math.atan2(10,-20)
elif 2 == test:
collision_angle_rad = math.atan2(40,0)
heading_angle_rad = math.atan2(20,10)
elif 3 == test:
collision_angle_rad = math.atan2(-40,0)
heading_angle_rad = math.atan2(-20,10)
else:
print('Error'); return
else:
# test quadrant: 1:NE, 2:NW, 3:SW, 4:SE
if 0 == test:
collision_angle_rad = math.pi/5
heading_angle_rad = math.pi/7
elif 1 == test:
collision_angle_rad = math.pi/2+ math.pi/5
heading_angle_rad = math.pi/2 + math.pi/7
elif 2 == test:
collision_angle_rad = math.pi+math.pi/5
heading_angle_rad = math.pi+math.pi/7
elif 3 == test:
collision_angle_rad = -math.pi/5
heading_angle_rad = -math.pi/7
else:
print('Error'); return
print('H: ',heading_angle_rad,', ',heading_angle_rad*180/math.pi)
print('CA: ',collision_angle_rad,', ',collision_angle_rad*180/math.pi)
radius = 40
robot = Circle( radius, heading_angle_rad, [ 0,0 ], "yellow")
stationary = Circle( radius, 0,
[2*radius*math.cos(collision_angle_rad), \
2*radius*math.sin(collision_angle_rad)], "black")
print(robot.pos)
print(stationary.pos)
robot.Draw()
robot.DrawHeading()
stationary.Draw()
# All code above: this would be set by the actual position and heading
# of the robot and colliding obstacle. This does assume that the two
# balls are not overlapping. See flatredball if you want to reposition
# them to a touching, but not overlapping position
# This code based on the flatredball resource
# http://flatredball.com/documentation/tutorials/math/circle-collision/
# robot = circle 1
# Determine the point of collision, which also defines the angle
collision = Vector( stationary.pos[0]-robot.pos[0], \
stationary.pos[1]-robot.pos[1] )
collision.Draw("red")
# Define the tangent to the point of collision
collision_tangent = Vector( stationary.pos[1]-robot.pos[1], \
-(stationary.pos[0]-robot.pos[0]))
collision_tangent.Draw("purple")
print('tangent ',collision_tangent.x,' ', collision_tangent.y)
# Normalize the tangent by making it of length 1
tangent_length = (collision_tangent.x**2 + collision_tangent.y**2)**0.5
normal_tangent = Vector( collision_tangent.x/tangent_length, \
collision_tangent.y/tangent_length)
print('NormTang :',normal_tangent.x,' ',normal_tangent.y)
normal_tangent.Draw('blue')
# relative velocity = robot because stationary circle has 0 velocity
# See flatredball to modify code for 2 moving objects
rel_velocity = robot.vel
print('RelVel :',rel_velocity.x,' ',rel_velocity.y)
rel_velocity.Draw('black')
# Determine the velocity vector along the tangent
length = rel_velocity.x*normal_tangent.x + rel_velocity.y*normal_tangent.y
print('length ',length)
print('NormTang :',normal_tangent.x,' ',normal_tangent.y)
tangent_velocity = Vector( normal_tangent.x*length, normal_tangent.y*length)
print('VonT ',tangent_velocity.x,' ',tangent_velocity.y)
tangent_velocity.Draw('orange')
# Determine the velocity vector perpendicular to the tangent
perpendicular = Vector(rel_velocity.x-tangent_velocity.x, \
rel_velocity.y-tangent_velocity.y )
print("Vperp ",perpendicular.x,' ',perpendicular.y)
perpendicular.Draw("green")
# New Heading
# This is for robot only. See flatredball to move both entities
new_heading = Vector( (robot.vel.x-2*perpendicular.x), \
(robot.vel.y-2*perpendicular.y))
print('new heading ',new_heading.x,' ',new_heading.y)
new_heading.Draw("blue")
input("to continue")
robot.Clear()
stationary.Clear()
collision_tangent.Clear()
perpendicular.Clear()
def TestWalls():
for i in range(4):
main(True,i)
def TestQuadrants():
for i in range(4):
main(False,i)
TestWalls()
TestQuadrants()
# ---------------------------------------------------------------
# ---------------------------------------------------------------
# This is identical to above without the printing and drawing ...
def DetermineNewHeading( robot, stationary ):
# Determine the point of collision, which also defines the angle
collision = Vector( stationary.pos[0]-robot.pos[0], \
stationary.pos[1]-robot.pos[1] )
# Define the tangent to the point of collision
collision_tangent = Vector( stationary.pos[1]-robot.pos[1], \
-(stationary.pos[0]-robot.pos[0]))
# Normalize the tangent making it length 1
tangent_length = (collision_tangent.x**2 + collision_tangent.y**2)**0.5
normal_tangent = Vector( collision_tangent.x/tangent_length, \
collision_tangent.y/tangent_length)
# relative velocity = robot because stationary circle has 0 velocity
# See flatredball to modify code for 2 moving objects
rel_velocity = robot.vel
# Determine the velocity vector along the tangent
length = rel_velocity.x*normal_tangent.x + rel_velocity.y*normal_tangent.y
tangent_velocity = Vector( normal_tangent.x*length, normal_tangent.y*length)
# Determine the velocity vector perpendicular to the tangent
perpendicular = Vector(rel_velocity.x-tangent_velocity.x, \
rel_velocity.y-tangent_velocity.y )
# New Heading
# This is for robot only. See flatredball to move both entities
new_heading = Vector( (robot.vel.x-2*perpendicular.x), \
(robot.vel.y-2*perpendicular.y))

View file

@ -0,0 +1,32 @@
#include <iostream>
class Robot {
private:
const int radius;
const int color;
int speed;
public:
Robot() : radius(50), color(0xFF0000) {speed = 250;}
Robot(int r, int c, int s) {
radius=r;
color=c;
speed=s;
void setSpeed(int inS) {speed = inS;}
void setColor (int inC) {color = inC;}
int getSpeed() { return speed; }
int getRadius() { return radius; }
int getColor() { return color; }
};
int main() {
Robot robot1(20, 0x00FF00, 200);
const Robot robot2;
std::cout << "Setting Robot1 speed to 45" << std::endl;
robot1.setSpeed(45);
int s = robot1.getSpeed();
std::cout << "speed: " << s << std::endl;
robot2.setSpeed(250);
int s2 = robot2.getSpeed();
}

View file

@ -0,0 +1,54 @@
#include <iostream>
/* YOUR ASSIGNMENT. change
Pos incPos(Pos p) to Pos incPos( const &Pos p)
*/
class Pos{
private:
int x;
int y;
public:
Pos(): x(0), y(0) {}
Pos(int inX, int inY): x(inX), y(inY) {}
void setX(int inX) { x=inX;}
void setY(int inY) {y=inY;}
int getX() {return x;}
int getY() {return y;}
};
Pos incPos(Pos p) {
std::cout << "=====In incPos=====" << std::endl;
std::cout << "p x: " << p.getX() << ", p y: " << p.getY() << std::endl;
int x = p.getX() + 2;
int y = p.getY() + 3;
p.setX(30);
Pos pos(x, y);
std::cout << "pos x: " << pos.getX() << ", pos y: " << pos.getY() << std::endl;
std::cout << "=====Leaving incPos=====" << std::endl;
return pos;
}
int calcDist(Pos p1, Pos p2) {
std::cout << "=====In calcDist=====" << std::endl;
std::cout << "p1 x: " << p1.getX() << ", p1 y: " << p1.getY() << std::endl;
std::cout << "p2 x: " << p2.getX() << ", p2 y: " << p2.getY() << std::endl;
std::cout << "=====Leaving calcDist=====" << std::endl;
return 23;
}
int main() {
Pos pos1(2,5);
int dist;
std::cout << "======Starting in main=========" << std::endl;
std::cout << "pos1 x: " << pos1.getX() << ", pos1 y: " << pos1.getY() << std::endl;
int x = pos1.getX() + 2;
std::cout << "x value: " << x << std::endl;
int x2 = incPos(pos1).getX();
std::cout << "x2 value: " << x2 << std::endl;
dist = calcDist(incPos(pos1), pos1);
std::cout << "After calculations" << std::endl;
std::cout << "x: " << x << ", x2: " << x2 << ", Dist: " << dist << std::endl;
std::cout << "pos1 x: " << pos1.getX() << ", pos1 y: " << pos1.getY() << std::endl;
}

View file

@ -0,0 +1,44 @@
int main() {
//const int myConst1;
const int myConst1 = 100;
const int myConst2 = 200;
const int* pMyConst;
// init integer
//myConst1 = 100;
// init pointer
//pMyConst = &myConst2;
// change pointer
//pMyConst = &myConst2;
// change integer
//myConst2 = myConst2 + 5;
// change integer using pointer
//*pMyConst = myConst1 + 1;
int myInt_3;
int myInt_4 = 400;
int* const cpMyInt_3 = &myInt_3;
// initialize the pointer
//int* const cpMyInt_4;
//int* const cpMyInt_4 = &myInt_4;
// initialize integer
//myInt_3 = 300;
// change the integer
//myInt_4 = myInt_4 + 5;
// change integer using pointer
//*cpMyInt_3 = myInt_4;
// change the pointer
//cpMyInt_3 = &myInt_4;
}

Binary file not shown.

View file

@ -0,0 +1,9 @@
*.o
*.obj
*.out
*.*~
*~
duckVisitor

View file

@ -0,0 +1,53 @@
#include <iostream>
#include <stdlib.h>
#include "Visitor.h"
#include "Fly.h"
#include "Quack.h"
#include "Duck.h"
using namespace std;
//----------------------------------------------
// THE DUCKS
Duck::Duck() {
flyBehavior = new FlyBehavior;
quackBehavior = new QuackBehavior;
name = "mystery";
}
void Duck::accept( Visitor * v ) { v->visit(this); }
void Duck::display() { cout << "I am a duck." << endl; }
void Duck::fly() { flyBehavior->fly(); }
void Duck::quack() { quackBehavior->quack(); }
double Duck::getSpeed() { return flyBehavior->getSpeed(); }
double Duck::getDB() { return quackBehavior->getDB(); }
void Duck::setName(string inName) { name = inName; }
string Duck::getName() { return name; }
//----------------------------------------------
// MALLARD
Mallard::Mallard() {
flyBehavior = new FlyWithWings;
quackBehavior = new Quack;
}
void Mallard::accept( Visitor * v) { v->visit(this); }
void Mallard::display() { cout << "I am a Mallard." << endl; }
//----------------------------------------------
// THE RUBBERDUCK
RubberDuck::RubberDuck() {
flyBehavior = new NoFly;
quackBehavior = new Squeak(2);
}
void RubberDuck::accept( Visitor * v) { v->visit(this); }
void RubberDuck::display() { cout << "I am a Rubber Duck." << endl; }

View file

@ -0,0 +1,50 @@
#ifndef DUCKS_EXERCISES_DUCK_H_
#define DUCKS_EXERCISES_DUCK_H_
#include <iostream>
#include <stdlib.h>
#include "Visitor.h"
#include "Fly.h"
#include "Quack.h"
using namespace std;
//----------------------------------------------
// THE DUCKS
class Duck {
protected:
FlyBehavior * flyBehavior;
QuackBehavior * quackBehavior;
string name;
public:
Duck();
virtual void accept( Visitor * v );
virtual void display();
virtual void fly();
virtual void quack();
virtual double getSpeed();
virtual double getDB();
virtual void setName(string inName);
virtual string getName();
};
class Mallard : public Duck {
public:
Mallard();
void accept( Visitor * v);
void display();
};
class RubberDuck : public Duck {
public:
RubberDuck();
void accept( Visitor * v);
void display();
};
#endif

View file

@ -0,0 +1,40 @@
#include <iostream>
#include <stdlib.h>
#include "Fly.h"
//-----------------------------------------------
// FLYING BEHAVIOR
using namespace std;
FlyBehavior::FlyBehavior() {
milesPerHour = MPH_DEFAULT;
}
void FlyBehavior::fly() {
cout << "Generic Flying at " << milesPerHour << " mph." << endl;
}
double FlyBehavior::getSpeed() {
return milesPerHour; }
//-----------------------------------------------
// FLY WITH WINGS
FlyWithWings::FlyWithWings() {
}
void FlyWithWings::fly() {
cout << "Fly with wings at speed of " << milesPerHour << " mph." << endl;
}
//-----------------------------------------------
// NO FLYING
//NoFly::NoFly() {}
//-----------------------------------------------
// FLY WITH ROCKET
//FlyWithRocket::FlyWithRocket() {}

View file

@ -0,0 +1,38 @@
#ifndef DUCKS_EXERCISES_FLY_H_
#define DUCKS_EXERCISES_FLY_H_
#include <iostream>
#include <stdlib.h>
//-----------------------------------------------
// FLYING
#define MPH_DEFAULT 5
using namespace std;
class FlyBehavior {
protected:
double milesPerHour;
public:
FlyBehavior();
virtual void fly();
virtual double getSpeed();
};
class FlyWithWings : public FlyBehavior {
public:
FlyWithWings();
virtual void fly();
};
class NoFly : public FlyBehavior {
public:
// cannot fly <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Fill this in;
};
class FlyWithRocket : public FlyBehavior {
// Can fly REALLY fast - don't use the default speed <<<<<<<<<< Fill this in;
};
#endif

View file

@ -0,0 +1,64 @@
#include <iostream>
#include <stdlib.h>
//-----------------------------------------------
// QUACKING BEHAVIOR
#include "Quack.h"
using namespace std;
QuackBehavior::QuackBehavior() : volume(DB_DEFAULT) {
}
void QuackBehavior::quack() {
cout << "Generic Quack at " << volume << " decibels" << endl;
}
double QuackBehavior::getDB() {
return volume;
}
//-----------------------------------------------
// QUACK
Quack::Quack() {
volume = DB_DEFAULT;
}
void Quack::quack() {
cout << "Quack at " << volume << " decibels" << endl;
}
//-----------------------------------------------
// MUTE
Mute::Mute() {
volume = 0;
}
void Mute::quack() {
cout << "Cannot talk." << endl;
}
//-----------------------------------------------
// SQUEAK
Squeak::Squeak() {
}
Squeak::Squeak(int d) {
volume = d;
}
void Squeak::quack() {
cout << "Squeak at " << volume << " decibels." << endl;
}
//-----------------------------------------------
// HONK
/*
Honk::Honk() {
// This is a confused swan that honks instead of quacks. Fill this in. <<<<<<<<<<<<<<<<
};
*/

View file

@ -0,0 +1,46 @@
#ifndef DUCKS_EXERCISES_QUACK_H_
#define DUCKS_EXERCISES_QUACK_H_
#include <iostream>
#include <stdlib.h>
//-----------------------------------------------
// QUACKING
#define DB_DEFAULT 10
using namespace std;
class QuackBehavior {
protected:
double volume;
public:
QuackBehavior();
virtual void quack();
virtual double getDB();
};
class Quack : public QuackBehavior {
public:
Quack();
void quack();
};
class Mute : public QuackBehavior {
public:
Mute();
void quack();
};
class Squeak : public QuackBehavior {
public:
Squeak();
Squeak(int d);
void quack();
};
class Honk : public QuackBehavior {
// This is a confused swan that honks instead of quacks. Fill this in. <<<<<<<<<<<<<<<<
};
#endif

View file

@ -0,0 +1,36 @@
#include <iostream>
#include <stdlib.h>
#include "Visitor.h"
#include "Duck.h"
using namespace std;
Visitor::Visitor() {}
void Visitor::visit( Duck * d ) {}
void Visitor::visit( RubberDuck * r ) {}
void Visitor::visit( Mallard * m ) {}
void RealDuckReport::visit( RubberDuck * r ) {
// RubberDucks aren't real ducks. do not include
}
void RealDuckReport::visit( Mallard * m ) {
cout << "Mallard : " << m->getName() << " : " << m->getSpeed() << " MPH" << endl;
}
void RealDuckReport::visit( Duck * d ) {
// Ducks are generic ducks. do not include
}
void FakeDuckReport::visit( RubberDuck * r ) {
cout << "Rubberduck : " << r->getName() << " : " << r->getDB() << " DB" << endl;
}
void FakeDuckReport::visit( Mallard * m ) {
// Mallards aren't fake. Do not include.
}
void FakeDuckReport::visit( Duck * d ) {
// Ducks are generic ducks. do not include
}

View file

@ -0,0 +1,30 @@
#ifndef DUCKS_EXERCISES_VISITOR_H_
#define DUCKS_EXERCISES_VISITOR_H_
class Duck;
class RubberDuck;
class Mallard;
class Visitor {
public:
Visitor();
virtual void visit( Duck * d );
virtual void visit( RubberDuck * r );
virtual void visit( Mallard * m );
};
class RealDuckReport : public Visitor {
public:
void visit( RubberDuck * r );
void visit( Mallard * m );
void visit( Duck * d );
};
class FakeDuckReport : public Visitor {
public:
void visit( RubberDuck * r );
void visit( Mallard * m );
void visit( Duck * d );
};
#endif

View file

@ -0,0 +1,57 @@
#include <iostream>
#include <stdlib.h>
#include "Visitor.h"
#include "Duck.h"
using namespace std;
// helper defined at bottom of file
void duck_introduction( Duck * duck );
int main() {
// EXAMPLE of polymorphism and the Strategy Pattern
Duck* ducks[3];
ducks[0] = new Duck();
ducks[0]->setName("Jane");
ducks[1] = new Mallard();
ducks[1]->setName("Maloy");
ducks[2] = new RubberDuck();
ducks[2]->setName("Lemon");
for (int i = 0; i<3; i++) {
duck_introduction( ducks[i] );
}
// EXAMPLE of the Visitor Pattern
// This is a visitor of ducks.
// It needs information, but only from certain kinds of ducks.
RealDuckReport * rd = new RealDuckReport ;
// Tell each duck to accept a visit from RealDuckReport
cout << "----- REPORT of Real Ducks -----" << endl;
for (int i=0; i<3; i++) {
ducks[i]->accept(rd);
}
cout << endl;
// This is a visitor of ducks.
// It needs information, but only from certain kinds of ducks.
FakeDuckReport * fd = new FakeDuckReport ;
// Tell each duck to accept a visit from FakeDuckReport
cout << "----- REPORT of Fake Ducks -----" << endl;
for (int i=0; i<3; i++) {
ducks[i]->accept(fd);
}
cout << endl;
}
void duck_introduction( Duck * duck ) {
duck->display();
duck->fly();
duck->quack();
cout << endl;
}

View file

@ -0,0 +1,17 @@
# CSCI3081 Ducks Exercise makefile
CXX = g++
DEBUG = -g
CXXFLAGS = -Wall -c $(DEBUG)
LDFLAGS = -Wall $(DEBUG)
OBJS = Duck.o Visitor.o Fly.o Quack.o
all: duckVisitor.o $(OBJS)
$(CXX) $(LDFLAGS) -o duckVisitor duckVisitor.o $(OBJS)
%.o : %.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
clean:
\rm *.o *.*~ duckVisitor

View file

@ -0,0 +1,25 @@
### Visitor Pattern Example
The visitors here want information from the ducks to generate a report.
However, they only need data from some of the types of ducks.
The ducks are oblivious to this distinction or even what specific information
the visitor wants from them. They need only to welcome the visitor (i.e. accept(Visitor)).
Notice that the visitor creates a visit() method for each type of Duck, this
way, ducks can be treated generically in some circumstances, but the visitor
can treat each type in a distinct way.
YOUR TASKS:
- create a decoy duck
- create a sea duck
- add these types, and a couple more of a type of your choosing to ducks[]
- view the reports
- create a visitor subclass that speeds up ducks (increases their mph), but only for those that are real.
- again generate a report of real ducks
> No claim that this is excellent, efficient code! Feel free to clean it up or add helper functions.

View file

@ -0,0 +1,13 @@
*.o
*.obj
*.out
*~
duckStrategyComplete.cpp
duckStrategyPolyComplete.cpp
*_print.*
*.txt

View file

@ -0,0 +1,17 @@
#include <iostream>
#include <string>
using std::string;
class DuckClass {
protected:
string typeOf;
string name;
public:
DuckClass() {
typeOf = "duck";
name = "noname";
}
void display() { std::cout << "I am " << name << ", and I am a " << typeOf << ".\n"; }
};

View file

@ -0,0 +1,20 @@
#include <iostream>
#include <string>
using std::string;
class DuckClass {
protected:
string typeOf;
string name;
public:
DuckClass() {
typeOf = "duck";
name = "noname";
}
void display() { std::cout << "I am " << name << ", and I am a " << typeOf << ".\n"; }
void fly() { std::cout << "I fly.\n"; };
void quack() { std::cout << "I quack.\n"; };
};

View file

@ -0,0 +1,31 @@
#include <iostream>
#include <string>
using std::string;
class DuckClass {
protected:
string typeOf;
string name;
bool canFly;
bool canQuack;
public:
DuckClass() : canFly(true), canQuack(true) {
typeOf = "duck";
name = "noname";
}
void display()
{ std::cout << "I am " << name << ", and I am a " << typeOf << ".\n"; }
void fly() {
if (canFly) std::cout << "I fly.\n";
else std::cout << "I cannot fly.\n";
}
void quack() {
if (canQuack) std::cout << "I quack.\n";
else std::cout << "I do not quack.\n";
}
};

View file

@ -0,0 +1,36 @@
#include <iostream>
#include <string>
using std::string;
class DuckClass {
protected:
string typeOf;
string name;
public:
DuckClass() {
typeOf = "duck";
name = "noname";
}
void display() { std::cout << "I am " << name << ", and I am a " << typeOf << ".\n"; }
void fly() { std::cout << "I fly.\n"; };
void quack() { std::cout << "I quack.\n"; };
};
class NoFlyDuck : public DuckClass {
public:
NoFlyDuck( string n = "lame" ) {
typeOf = "noFly";
name = n;
}
void fly() { std::cout << "I cannot fly.\n"; }
};
class NoQuackDuck : public DuckClass {
public:
NoQuackDuck( string n = "quiet" ) {
typeOf = "noQuack";
name = n;
}
void quack() { std::cout << "I cannot quack.\n"; }
};

View file

@ -0,0 +1,133 @@
#include <iostream>
#include <stdlib.h>
#define MPH_DEFAULT 5
#define DB_DEFAULT 10
using namespace std;
//-----------------------------------------------
// QUACKING
class QuackBehavior {
protected:
double volume;
public:
QuackBehavior() : volume(DB_DEFAULT) {}
void quack() { cout << "Generic Quack at " << volume << " decibels" << endl; }
};
class Quack : public QuackBehavior {
public:
Quack() {}
void quack() { cout << "Quack at " << volume << " decibels" << endl; }
};
class Mute : public QuackBehavior {
public:
Mute() { volume = 0; }
void quack() { cout << "Cannot talk." << endl; }
};
class Squeak : public QuackBehavior {
public:
Squeak() {}
Squeak(int d) { volume = d; }
void quack() { cout << "Squeak at " << volume << " decibels." << endl; }
};
class Honk : public QuackBehavior {
// This is a confused swan that honks instead of quacks. Fill this in. <<<<<<<<<<<<<<<<
};
//-----------------------------------------------
// FLYING
class FlyBehavior {
protected:
double milesPerHour;
public:
FlyBehavior() : milesPerHour(MPH_DEFAULT) {}
void fly() { cout << "Generic Flying at " << milesPerHour << " mph." << endl; }
};
class FlyWithWings : public FlyBehavior {
public:
FlyWithWings() {}
void fly() { cout << "Fly at speed of " << milesPerHour << " mph." << endl; }
};
class NoFly : public FlyBehavior {
public:
// cannot fly <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Fill this in;
};
class FlyWithRocket : public FlyBehavior {
// Can fly REALLY fast - don't use the default speed <<<<<<<<<< Fill this in;
};
//----------------------------------------------
// THE DUCKS
class Duck {
protected:
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public:
Duck() {
flyBehavior = FlyWithWings();
quackBehavior = Quack();
}
void display() { cout << "I am a duck." << endl; }
void fly() { flyBehavior.fly(); }
void quack() { quackBehavior.quack(); }
};
class Mallard : public Duck {
public:
Mallard() {
flyBehavior = FlyWithWings();
quackBehavior = Quack();
}
void display() { cout << "I am a Mallard." << endl; }
void quack() { quackBehavior.quack(); }
void fly() { flyBehavior.fly(); }
};
class RubberDuck : public Duck {
public:
RubberDuck() {
flyBehavior = NoFly();
quackBehavior = Squeak(2);
}
void display() { cout << "I am a Rubber Duck." << endl; }
void quack() { quackBehavior.quack(); }
void fly() { flyBehavior.fly(); }
};
int main() {
Mallard mary;
RubberDuck ralph;
Duck donald;
cout << endl << "Donald does this ... " << endl;
donald.display();
donald.fly();
donald.quack();
cout << endl << "Mary does this ... " << endl;
mary.display();
mary.fly();
mary.quack();
cout << endl << "Ralph does this ... " << endl;
ralph.display();
ralph.fly();
ralph.quack();
cout << endl;
}

View file

@ -0,0 +1,142 @@
#include <iostream>
#include <stdlib.h>
#define MPH_DEFAULT 5
#define DB_DEFAULT 10
using namespace std;
//-----------------------------------------------
// QUACKING
class QuackBehavior {
protected:
double volume;
public:
QuackBehavior() : volume(DB_DEFAULT) {}
void quack() { cout << "Generic Quack at " << volume << " decibels" << endl; }
};
class Quack : public QuackBehavior {
public:
Quack() {}
void quack() { cout << "Quack at " << volume << " decibels" << endl; }
};
class Mute : public QuackBehavior {
public:
Mute() { volume = 0; }
void quack() { cout << "Cannot talk." << endl; }
};
class Squeak : public QuackBehavior {
public:
Squeak() {}
Squeak(int d) { volume = d; }
void quack() { cout << "Squeak at " << volume << " decibels." << endl; }
};
class Honk : public QuackBehavior {
// This is a confused swan that honks instead of quacks. Fill this in. <<<<<<<<<<<<<<<<
};
//-----------------------------------------------
// FLYING
class FlyBehavior {
protected:
double milesPerHour;
public:
FlyBehavior() : milesPerHour(MPH_DEFAULT) {}
void fly() { cout << "Generic Flying at " << milesPerHour << " mph." << endl; }
};
class FlyWithWings : public FlyBehavior {
public:
FlyWithWings() {}
void fly() { cout << "Fly with wings at speed of " << milesPerHour << " mph." << endl; }
};
class NoFly : public FlyBehavior {
public:
// cannot fly <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Fill this in;
};
class FlyWithRocket : public FlyBehavior {
// Can fly REALLY fast - don't use the default speed <<<<<<<<<< Fill this in;
};
//----------------------------------------------
// THE DUCKS
class Duck {
protected:
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public:
Duck() {
flyBehavior = FlyBehavior();
quackBehavior = QuackBehavior();
}
void display() { cout << "I am a duck." << endl; }
void fly() { flyBehavior.fly(); }
void quack() { quackBehavior.quack(); }
};
class Mallard : public Duck {
public:
Mallard() {
flyBehavior = FlyWithWings();
quackBehavior = Quack();
}
void display() { cout << "I am a Mallard." << endl; }
};
class RubberDuck : public Duck {
public:
RubberDuck() {
flyBehavior = NoFly();
quackBehavior = Squeak(2);
}
void display() { cout << "I am a Rubber Duck." << endl; }
};
int main() {
Mallard mary;
RubberDuck ralph;
Duck donald;
cout << endl << "Donald does this ... " << endl;
donald.display();
donald.fly();
donald.quack();
cout << endl << "Mary does this ... " << endl;
mary.display();
mary.fly();
mary.quack();
cout << endl << "Ralph does this ... " << endl;
ralph.display();
ralph.fly();
ralph.quack();
cout << endl;
Duck* ducks[3];
ducks[0] = new Duck();
ducks[1] = new Mallard();
ducks[2] = new RubberDuck();
for (int i = 0; i<3; i++) {
ducks[i]->display();
ducks[i]->fly();
ducks[i]->quack();
cout << endl;
}
}

View file

@ -0,0 +1,41 @@
#include "duck1.h"
using std::string;
class Mallard : public DuckClass {
public:
Mallard(string n="nameless") {
typeOf = "mallard";
name = n;
}
void fly() { std::cout << "I fly.\n"; }
void quack() { std::cout << "I quack.\n"; }
};
class Loon : public DuckClass {
public:
// This duck quacks and flies <<<<<<<<<<<< FILL THIS IN
Loon( string n = "nameless" ) {
typeOf = "loon";
name = n;
}
};
class Decoy : public DuckClass {
// This duck quacks but cannot fly <<<<<<<<<<< FILL THIS IN
public:
Decoy( string n = "nameless" ) {
typeOf = "decoy";
name = n;
}
};
// <<<<<<<<<<<< WHAT ABOUT A RUBBER DUCK ??
int main() {
Mallard molly("molly");
molly.display();
molly.fly();
molly.quack();
}

View file

@ -0,0 +1,46 @@
#include "duck2.h"
using std::string;
class Mallard : public DuckClass {
public:
Mallard(string n="nameless") {
typeOf = "mallard";
name = n;
}
};
class Loon : public DuckClass {
// This duck flies and quacks <<<<< IMPLEMENT THIS
public:
Loon( string n="nameless") {
typeOf = "loon";
name = n;
}
};
class RubberDuck : public DuckClass {
// This duck squeaks (no quack) and cannot fly <<<<< IMPLEMENT THIS
public:
RubberDuck( string n="nameless") {
typeOf = "rubber duck";
name = n;
}
};
class Decoy : public DuckClass {
// This duck quacks but cannot fly <<<<<<< IMPLEMENT THIS
public:
Decoy (string n = "nameless") {
typeOf = "decoy";
name = n;
}
};
int main() {
Mallard molly("molly");
molly.display();
molly.fly();
molly.quack();
}

View file

@ -0,0 +1,38 @@
#include "duck3.h"
using std::string;
class Mallard : public DuckClass {
// Flies and quacks <<<<<<<<<<<<<<< IMPLEMENT THIS
public:
Mallard(string n="nameless") {
typeOf = "mallard";
name = n;
}
};
class Decoy : public DuckClass {
// This duck quacks but cannot fly <<<<<<<<<<< IMPLEMENT THIS
public:
Decoy( string n = "nameless" ) {
typeOf = "decoy";
name = n;
}
};
class RubberDuck : public DuckClass {
// Squeaks (no quack) and cannot fly <<<<<<<<< IMPLEMENT THIS
public:
RubberDuck( string n = "nameless" ) {
typeOf = "loon";
name = n;
}
};
int main() {
Mallard molly("molly");
molly.display();
molly.fly();
molly.quack();
}

View file

@ -0,0 +1,48 @@
#include "duck4.h"
using std::string;
class Mallard : public DuckClass {
public:
Mallard(string n="nameless") {
typeOf = "mallard";
name = n;
}
};
class Decoy : public NoFlyDuck {
// This duck quacks but cannot fly
public:
Decoy( string n = "nameless" ) {
typeOf = "decoy";
name = n;
}
};
class DuckKite : public DuckClass {
// A kite, shaped like a duck, that flies but can't quack <<<<<< IMPLEMENT THIS
public:
DuckKite( string n = "nameless" ) {
typeOf = "kite";
name = n;
}
};
class RubberDuck : public DuckClass {
// This duck squeeks (no quack) and cannot fly <<<<<<<<<<<<< IMPLEMENT THIS
// Inheriting from DuckClass gives it both behaviors. Need something else.
public:
RubberDuck( string n = "nameless" ) {
typeOf = "loon";
name = n;
}
};
//-------------------------------------------------
int main() {
Mallard molly("molly");
molly.display();
molly.fly();
molly.quack();
}

View file

@ -0,0 +1,5 @@
all:
g++ -Wall -o ducks main.o Duck.o MallardDuck.o DecoyDuck.o RubberDuck.o QuackBehavior.o Quack.o Squeak.o MuteQuack.o
clean:
rm *.o ducks

View file

@ -0,0 +1,16 @@
# CSCI3081 In-Class Exercise dynamic allocation and arrays
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
OBJS = array_pointer_test.o duck.o
all: main.o $(OBJS)
$(CC) $(LFLAGS) -o ducks main.o $(OBJS)
%.o : %.cc
$(CC) $(CFLAGS) -o $@ $<
clean:
\rm *.o *.*~ ducks

View file

@ -0,0 +1,30 @@
## Dynamic Allocation and Class destructor
The ArrayPointerTest class has a collection of 4 arrays of Duck and Duck pointers.
main() calls a helper function in which it declares an instance of this class.
Then displaycontents is called, which simply makes every duck in every array
PerformQuack(). Upon exit of the helper, everything is destroyed (or is it!).
Note that there are print statements inside the destructors to better understand when things are called. To make things even more evident, you can print the name of the duck before you destroy it.
Here is your assignment:
- Copy to a git repo of someone in your group.
- Put the name of eveyone in your group at the top of this readme!
- Fill in the initialization of all duck arrays in the constructor.
- Make all the ducks quack in DisplayContents().
- Fix the delete's where appropriate in the destructor.
- Answer the following questions directly in the readme in your git repo:
1. Decide which of these you think is correct and briefly justify:
```C++
printf("Initializing ducks1\n");
ducks1_[0].SetName("angel");
```
```C++
printf("Initializing ducks1\n");
ducks1_[0] = Duck("angel");
```
2. In the destructor, there are 2 lines with the comment "WILL NOT COMPILE". Explain why these will not compile.
3. For each delete statement that is insufficient, explain how you fixed it.
- Push to git.

View file

@ -0,0 +1,64 @@
#include "array_pointer_test.h"
#include <string>
ArrayPointerTest::ArrayPointerTest(int size) {
size_ = size;
std::string names[3] = { "angel", "yang", "mia" };
/* USE THIS FOR INITIALIZING DUCKS
Duck::Duck(std::string name) {
SetName(name);
}
*/
// Initialize Duck ducks1[3];
printf("Initializing ducks1\n");
// Initialize Duck * ducks2; with "size" number of elements
printf("Initializing ducks2\n");
// Initialize Duck * ducks3_[3];
printf("Initializing ducks3_[3]\n");
// Initialize Duck ** ducks4; with "size" number of elements
printf("Initializing ducks2\n");
}
ArrayPointerTest::~ArrayPointerTest() {
printf("In destructor\n");
// delete Duck ducks1[3];
printf("Deleting ducks1\n");
// delete ducks1_; // WILL NOT COMPILE
// delete Duck * ducks2;
printf("Deleting ducks2\n");
delete[] ducks2_;
// delete Duck * ducks3[3]
printf("Deleting ducks3\n");
// delete[] ducks3_; // WILL NOT COMPILE
// delete Duck ** ducks4;
printf("Deleting ducks4\n");
delete[] ducks4_;
}
void ArrayPointerTest::DisplayContents() {
// PerformQuack() for all in Duck ducks1[3];
printf("Quack ducks1[3]\n");
// PerformQuack() for all in Duck * ducks2;
printf("Quack ducks2[size_]\n");
// PerformQuack() for all in Duck * ducks3[3]
printf("Quack ducks3[3]\n");
// PerformQuack() for all in Duck ** ducks4;
printf("Quack ducks4[size_]\n");
}

View file

@ -0,0 +1,15 @@
#include "duck.h"
class ArrayPointerTest {
public:
ArrayPointerTest(int size=3);
~ArrayPointerTest();
void DisplayContents();
private:
Duck ducks1_[3];
Duck * ducks2_;
Duck * ducks3_[3];
Duck ** ducks4_;
int size_;
};

View file

@ -0,0 +1,25 @@
//
// Duck.cpp
//
// Created by Sarit Ghildayal on 1/24/15.
// Copyright (c) 2015 Sarit Ghildayal. All rights reserved.
//
#include "duck.h"
#include <iostream>
using std::cout;
using std::endl;
Duck::Duck() {
SetName("Duck");
}
Duck::Duck(std::string name) {
SetName(name);
}
void Duck::PerformQuack() {
printf("Quack\n");
}

View file

@ -0,0 +1,27 @@
//
// Duck.h
//
// Created by Sarit Ghildayal on 1/24/15.
// Copyright (c) 2015 Sarit Ghildayal. All rights reserved.
//
#ifndef DUCK_H_
#define DUCK_H_
#include <string>
class Duck {
public:
// Constructors and Destructor
Duck();
Duck(std::string name);
~Duck() {printf("destroying duck\n");};
// Mutators and Accessors
void PerformQuack();
std::string GetName() {return m_name_;}
void SetName(std::string name ) {m_name_ = name;}
protected:
std::string m_name_;
};
#endif

Binary file not shown.

View file

@ -0,0 +1,13 @@
#include "array_pointer_test.h"
void helper() {
printf("initializing all my ducks\n");
ArrayPointerTest allMyDucks(3);
allMyDucks.DisplayContents();
printf("about to delete all my ducks\n");
}
int main(void) {
helper();
return 0;
}

View file

@ -0,0 +1,19 @@
int staticArray[50000];
void helper() {
int stackArray[30000];
int * heapArray;
heapArray = new int[100000];
}
int main(void) {
int stackArray[25000];
int * heapArray;
heapArray = new int[20000];
helper();
}

Binary file not shown.

View file

@ -0,0 +1,45 @@
## How to install an example of nanogui.
1. Go to the repo on GitHub: https://github.com/wjakob/nanogui
2. Find a good place on your machine to install nanogui.
3. Clone the repo with `--recursive` tag:
```git clone --recursive https://github.com/wjakob/nanogui
```
4. Use cmake to create a make file (Windows might have other directions - look at documentation).
```
cd nanogui
mkdir build
cd build
cmake ..
```
What just happened? You created a directory in which to build. You called cmake
on the nanogui directory, which will create a makefile.
5. Call the makefile to build the examples: `make`
6. Run example1: `./example1`. There are 4 examples.
7. Explore the source code for the example which can be found at `cd ../src`.
## How to check Google Style Compliance on a file.
Google Style Guide: https://google.github.io/styleguide/cppguide.html
cpplint: https://github.com/google/styleguide/tree/gh-pages/cpplint
1. Obtain cpplint (this is a python script, so if you don't have Python,
you have to start there: python.org).
2. With Python3 installed, you should be able to get cpplint with:
`pip3 install cpplint`
3. Now run a file through the checker:
`cpplint <filename>`
4. Follow the style guide and the comments to get to no errors.
## Practice Google Style Compliance
Try to get the Visitor Pattern example to comply or the Duck example from
lab03. I wouldn't try it on the in-class polymorphism duck example, as that
is so far from compliance, it would require a restructuring of the files.

View file

@ -0,0 +1,114 @@
#include <cstdio>
#include <iostream>
#include <cstring>
class VectorDouble;
// Vector in an x,y plane
class Vector {
public:
Vector(int x=0, int y=0) : x_(x), y_(y) {}
//*** SPECIAL CONSTRUCTOR ****//
// Vector( VectorDouble v) {}
int get_x() { return x_; }
void set_x(int x) { x_ = x; }
int get_y() { return y_; }
void set_y(int y) { y_ = y; }
friend class VectorDouble;
// Overload = (binary)
const Vector operator=(const Vector& right) {
x_ = right.x_;
y_ = right.y_;
return *this;
}
// Overload + (binary)
const Vector operator+(const Vector& right) {
return Vector(x_ + right.x_, y_ + right.y_);
}
// Overload - (binary)
// Overload * of Vector*Vector = x*x + y*y
// Overload * of Vector*int = Vector(int*x, int*y)
// Overland - (unary)
// Overload <<
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
private:
int x_;
int y_;
};
std::ostream& operator<<(std::ostream& os, const Vector& v) {
os << "[" << v.x_ << ", " << v.y_ << "]";
return os;
}
class VectorDouble {
public:
VectorDouble( double x=0, double y=0) : x_(x), y_(y) {}
//*** SPECIAL CONSTRUCTOR ****//
VectorDouble( Vector v) { x_ = v.get_x(); y_ = v.get_y(); }
double get_x() { return x_; }
void set_x(double x) { x_ = x; }
double get_y() { return y_; }
void set_y(double y) { y_ = y; }
// Overload = (binary)
const VectorDouble operator=(const VectorDouble& right) {
x_ = right.x_;
y_ = right.y_;
return *this;
}
// Overload + (binary)
const VectorDouble operator+(const VectorDouble& right) {
x_ = x_ + right.x_;
y_ = y_ + right.y_;
return *this;
}
// Overload <<
friend std::ostream& operator<<(std::ostream& os, const VectorDouble& v);
const VectorDouble operator+(const Vector& right) {
return VectorDouble( x_ + right.x_, y_ + right.y_);
}
private:
double x_;
double y_;
};
std::ostream& operator<<(std::ostream& os, const VectorDouble& v) {
os << "[" << v.x_ << ", " << v.y_ << "]";
return os;
}
int main(void) {
Vector v1(2,3);
Vector v2(5,8);
Vector v3;
VectorDouble d1(1.0,1.5);
VectorDouble d2(6.3,2.9);
std::cout << v1 << std::endl;
std::cout << v2 << std::endl;
std::cout << d1 << std::endl;
std::cout << d2 << std::endl;
v1 = v2;
std::cout << v1 << std::endl;
v3 = v1+v2;
std::cout << v3 << std::endl;
VectorDouble mix = d1+v3;
std::cout << mix << std::endl;
}

View file

@ -0,0 +1,133 @@
import turtle
import math
def Positive(angle):
# make every angle positive in range 0 to 360
if angle<0:
return 360+angle
if angle>360:
return angle % 360
return angle
class Position:
def __init__(self, x, y):
self.x = x
self.y = y
class SensorCone:
# Proximity sensor rendering. Distance is from center of robot.
# fov: field of view, centered on heading of robot
def __init__(self, entity, distance, fov ):
# param entity: robot entity to which it belongs
self.entity = entity
self.distance = distance
self.fov = fov
self.pen = turtle.Turtle()
self.pen.hideturtle()
self.pen.speed(0)
def Draw(self):
# Draw perimeter around entire robot, but then show limited fov
self.pen.pu()
self.pen.goto(self.entity.pos.x, self.entity.pos.y)
self.pen.setheading(self.entity.heading_deg)
self.pen.pd()
self.pen.dot(self.distance*2,'yellow')
# draw the cone
self.pen.left(self.fov//2)
for i in [0,1,1]:
self.pen.right((self.fov//2)*i)
self.pen.pd()
self.pen.forward(self.distance)
self.pen.pu()
self.pen.goto(self.entity.pos.x, self.entity.pos.y)
class Robot:
def __init__( self, radius, heading, pos, color ):
self.radius = radius
self.pos = pos
self.heading_deg = Positive(heading)
self.color = color
self.pen = turtle.Turtle()
self.pen.hideturtle()
self.pen.speed(0)
# default value of 3*radius for proximity sensor
self.sensor = SensorCone( self, radius*3, 30)
def Draw(self):
self.pen.pu()
self.pen.goto(self.pos.x, self.pos.y)
self.pen.pd()
self.pen.dot(self.radius*2,self.color)
self.pen.pu()
def DrawSensor(self):
self.sensor.Draw()
def DrawTriangle(self, width_angle, dir_angle, dist):
# this is the triangle formed by this robot and the one being sensed
self.pen.pu()
self.pen.goto(self.pos.x, self.pos.y)
self.pen.setheading(dir_angle)
self.pen.right(width_angle)
self.pen.pd()
self.pen.forward(dist)
self.pen.pu()
self.pen.goto(self.pos.x, self.pos.y)
self.pen.setheading(dir_angle)
self.pen.left(width_angle)
self.pen.pd()
self.pen.forward(dist)
def InRange( range1, range2 ):
print(range1)
print(range2)
# if crossing zero, adjust all angles
if range1[0] > range1[1]:
distToCrossing = 360-range1[0]
range1 = [ (range1[0]+distToCrossing)%360, range1[1]+distToCrossing]
range2 = [ (range2[0]+distToCrossing)%360, (range2[1]+distToCrossing)%360]
if range2[0] > range2[1]:
distToCrossing = 360-range2[0]
range1 = [ (range1[0]+distToCrossing)%360, range1[1]+distToCrossing]
range2 = [ (range2[0]+distToCrossing)%360, (range2[1]+distToCrossing)%360]
# if 2nd robot spans the proximiy sensor, then in range
if range2[0] < range1[0] and range2[1] > range1[1]:
return True
if range2[0] >= range1[0] and range2[0] <= range1[1]:
return True
if range2[1] >= range1[0] and range2[1] <= range1[1]:
return True
return False
def SensorReading( r_sensing, r_sensed):
deltaX = r_sensed.pos.x-r_sensing.pos.x
deltaY = r_sensed.pos.y-r_sensing.pos.y
dist = (deltaX**2 + deltaY**2)**0.5
if dist > r_sensing.sensor.distance + r_sensed.radius:
return False
# triangle is formed from center of r_sensing to the point along the tangents
# to r_sensed. The height is dist and the width is r_sensed.radius*2.
triangle_theta = Positive(math.atan(r_sensed.radius/dist)*180/3.14)
distance_theta = Positive(math.atan2(deltaY, deltaX)*180/3.14)
r_sensing.DrawTriangle(triangle_theta, distance_theta, dist)
sensor_lower = r_sensing.heading_deg - r_sensing.sensor.fov//2
sensor_upper = r_sensing.heading_deg + r_sensing.sensor.fov//2
sensed_lower = distance_theta - triangle_theta
sensed_upper = distance_theta + triangle_theta
if InRange( [ Positive(sensor_lower), Positive(sensor_upper) ], \
[ Positive(sensed_lower), Positive(sensed_upper) ] ):
print('True: ', dist)
else:
print('False')
#Robot(radius, heading, pos, color)
R = Robot( 50, 0, Position(0,0), 'green')
R2 = Robot( 20, 270, Position(150,-25),'red')
R.DrawSensor()
R.Draw()
R2.Draw()
SensorReading( R, R2)

View file

@ -0,0 +1,158 @@
/*
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include <gtest/gtest.h>
#include "../src/common.h"
#include "../src/robot.h"
#include "../src/sensor_distress.h"
#include "../src/event_distress.h"
//#ifdef SENSOR_DISTRESS_TEST
/******************************************************
* TEST FEATURE SetUp
*******************************************************/
class SensorDistressTest : public ::testing::Test {
protected:
virtual void SetUp() {
// Initialize Distress Sensors for Collections of TESTS
robot = new csci3081::Robot();
sensor = new csci3081::SensorDistress(robot);
robot_id = robot->get_id();
event_own_distress.set_id(robot_id);
event_internal.set_id(robot_id+1);
event_internal.set_pos(csci3081::Position(10,0));
event_at_range.set_id(robot_id+1);
event_at_range.set_pos(csci3081::Position(50,0));
event_in_range.set_id(robot_id+1);
event_in_range.set_pos(csci3081::Position(30,0));
event_out_of_range.set_id(robot_id+1);
event_out_of_range.set_pos(csci3081::Position(200,200));
}
// Default robot is at position (0,0) heading 0
csci3081::Robot * robot;
csci3081::SensorDistress * sensor;
int robot_id;
// Default range and fov is 50 and 360 degrees
csci3081::EventDistress event_own_distress;
csci3081::EventDistress event_internal;
csci3081::EventDistress event_in_range;
csci3081::EventDistress event_at_range;
csci3081::EventDistress event_out_of_range;
};
/*******************************************************************************
* Test Cases
******************************************************************************/
TEST_F(SensorDistressTest, Constructor) {
// get range, fov, and activated
EXPECT_EQ(sensor->get_range(), DEFAULT_RANGE) << "FAIL: Range:Constructor";
EXPECT_EQ(sensor->get_fov_angle(), DEFAULT_FOV_ANGLE) << "FAIL: FOV:Constructor";
EXPECT_EQ(sensor->IsActivated(), false) << "FAIL: Active:Constructor";
}
TEST_F(SensorDistressTest, DistressCallInRange) {
// A robot distress in range, not itself
// should activate the sensor
sensor->Update(event_in_range);
EXPECT_EQ(sensor->IsActivated(), true);
}
TEST_F(SensorDistressTest, DistressCallAtRange) {
// A robot distress in range, not itself
// should activate the sensor
sensor->Update(event_at_range);
EXPECT_EQ(sensor->IsActivated(), true);
}
TEST_F(SensorDistressTest, MultipleDistressCalls) {
// Sensor should stay active until a reset,
// which Robot will perform at each update
sensor->Update(event_in_range);
sensor->Update(event_out_of_range);
EXPECT_EQ(sensor->IsActivated(), true);
}
TEST_F(SensorDistressTest, Reset) {
sensor->Reset();
EXPECT_EQ(sensor->get_range(), DEFAULT_RANGE) << "FAIL: Range, Reset";
EXPECT_EQ(sensor->get_fov_angle(), DEFAULT_FOV_ANGLE) << "FAIL: FOV, Reset";
EXPECT_EQ(sensor->IsActivated(), false) << "FAIL: Active, Reset";
}
// Receives notice of event of own distress
// Relies on Reset working properly
TEST_F(SensorDistressTest, EventOfSelf) {
sensor->Reset();
sensor->Update(event_own_distress);
EXPECT_EQ(sensor->IsActivated(), false);
}
TEST_F(SensorDistressTest, DistressCallOutOfRange) {
sensor->Reset();
sensor->Update(event_out_of_range);
EXPECT_EQ(sensor->IsActivated(), false);
}
TEST_F(SensorDistressTest, DistressCallInRobot) {
sensor->Reset();
sensor->Update(event_internal);
EXPECT_EQ(sensor->IsActivated(), true);
}
TEST_F(SensorDistressTest, SetRange) {
// Bad input that should be ignored
int range = sensor->get_range();
sensor->set_range(1000);
EXPECT_EQ(sensor->get_range(), range) << "FAIL: Too big, Range.";
sensor->set_range(-10);
EXPECT_EQ(sensor->get_range(), range) << "FAIL: Negative, Range.";
// Input should be converted to an int
sensor->set_range(1.2);
EXPECT_EQ(sensor->get_range(), 1) << "FAIL: Double, Range";
// Good input
sensor->set_range(DEFAULT_RANGE+10);
EXPECT_EQ(sensor->get_range(), DEFAULT_RANGE+10) << "FAIL: Good, Range";
// Acceptable input that essentially turns off sensor
sensor->set_range(0);
EXPECT_EQ(sensor->get_range(), 0) << "FAIL: Zero, range";
}
TEST_F(SensorDistressTest, SetFovAngle) {
// Bad input that should be ignored
int angle = sensor->get_fov_angle();
sensor->set_fov_angle(-10);
EXPECT_EQ(sensor->get_fov_angle(), angle) << "FAIL: Negative, FOV.";
sensor->set_fov_angle(500);
EXPECT_EQ(sensor->get_fov_angle(), angle) << "FAIL: Too big, FOV.";
// Input should be converted to an int
sensor->set_fov_angle(3.1);
EXPECT_EQ(sensor->get_fov_angle(), 3) << "FAIL: double, FOV";
// Good input
sensor->set_fov_angle(DEFAULT_FOV_ANGLE-1);
EXPECT_EQ(sensor->get_fov_angle(), DEFAULT_FOV_ANGLE-1) << "FAIL: good, FOV";
// Acceptable input that essentially turns off sensor
sensor->set_fov_angle(0);
EXPECT_EQ(sensor->get_fov_angle(), 0) << "FAIL: zero, FOV";
}
//#endif /* SENSOR_DISTRESS_TEST */

View file

@ -0,0 +1,26 @@
## Design of Class Member Variables
The reason that there was a need for the fix to pos_ was due to an assumption
on my part about the design of the ArenaEntity. I did not look at it closely
enough and assumed setters and getters were implemented polymorphically.
Through testing it was discovered that the setters and getters were not
working when upcasting. It raises interesting questions about the design of
inheritance.
By defining member variables only in the parent class and making them private,
the user of the class is forced to use the setters and getters, rather than
having direct access to the member variables.
Questions:
1. Explain why overriding the variable position\_ and its getter in the non-virtual version does not work.
2. Explain why position\_ must be protected, rather than private in the virtual (polymorphic) version.
3. Draw a picture of each version of a robot, including all objects enclosed. Show where the member variable
position resides within the objects.
4. Imagine the non-virtual version, but with the replacement of position and get_pos in that class (i.e. like the version that
was in the class-repo). Draw that robot.
5. Identify the advantages and disadvantages of each version (not the incorrect one). Consider robustness and other programmers
using the code.
6. Heading and speed are stored inside of the motion_handler\_, yet these values are sometimes needed outside of the class
(e.g. when being drawn). Notice that there is a setter and getter for these variables in the robot class, yet they are not member variables of robot. What do you think about this design with respect to both robustness and use by other programmers. Do you think heading should also exist in robot and somehow be maintained between the motion_handler and the robot class?

View file

@ -0,0 +1,16 @@
# CSCI3081 setterGetter makefile
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
OBJS = arena.o motion_behavior.o motion_handler.o robot_virtual.o robot.o
all: main.o $(OBJS)
$(CC) $(LFLAGS) -o robots main.o $(OBJS)
%.o : %.cpp
$(CC) $(CFLAGS) -o $@ $<
clean:
\rm *.o *.*~ robots

View file

@ -0,0 +1,104 @@
/**
* @file arena.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include <algorithm>
#include <iostream>
#include "arena.h"
#include "robot.h"
#include "robot_virtual.h"
/*******************************************************************************
* Constructors/Destructor
******************************************************************************/
Arena::Arena() :
n_robots_virtual_(0), n_robots_(0) {
}
Arena::~Arena(void) {
for (int i=0;i<n_robots_;i++) {
delete robots_[i];
} /* for(ent..) */
}
/*******************************************************************************
* Member Functions
******************************************************************************/
void Arena::AddRobotVirtual(const Position& pos, const int rad) {
robots_virtual_[n_robots_virtual_] = new RobotVirtual( pos, rad);
n_robots_virtual_++;
}
void Arena::AddRobot(const Position& pos, const int rad) {
robots_[n_robots_] = new Robot( pos, rad );
n_robots_++;
}
void Arena::AdvanceTime() {
UpdateEntities();
}
void Arena::UpdateEntities(void) {
// Update the position of all entities.
for (int i=0; i<n_robots_; i++) {
robots_[i]->TimestepUpdate();
}
// Some pairs of entities may now be close enough to be colliding
for (int i=0; i<n_robots_; i++) {
for (int j=i+1; j<n_robots_; j++) {
if (CheckForCollision(robots_[i],robots_[j])) {
std::cout << "Robot "<< i << " colliding with robot " << j << "\n";
}
}
}
// Same thing, except for robots with virtual setters/getters
for (int i=0; i<n_robots_virtual_; i++) {
robots_virtual_[i]->TimestepUpdate();
}
// Some pairs of entities may now be close enough to be colliding
for (int i=0; i<n_robots_virtual_; i++) {
for (int j=i+1; j<n_robots_virtual_; j++) {
if (CheckForCollisionVirtual(robots_virtual_[i],robots_virtual_[j])) {
std::cout << "Virtual robot "<< i << " colliding with robot " << j << "\n";
}
}
}
}
bool Arena::CheckForCollision(Entity* ent1, Entity* ent2 ) {
/* Note: this assumes circular entities */
double ent1_x = ent1->get_position().x;
double ent1_y = ent1->get_position().y;
double ent2_x = ent2->get_position().x;
double ent2_y = ent2->get_position().y;
double dist = std::sqrt(std::pow(ent2_x - ent1_x, 2) +
std::pow(ent2_y - ent1_y, 2));
if (dist > (ent1->get_radius() + ent2->get_radius())) {
return false;
} else {
return true;
}
} /* CheckForCollision() */
bool Arena::CheckForCollisionVirtual(EntityVirtual* ent1,
EntityVirtual* ent2 ) {
/* Note: this assumes circular entities */
double ent1_x = ent1->get_position().x;
double ent1_y = ent1->get_position().y;
double ent2_x = ent2->get_position().x;
double ent2_y = ent2->get_position().y;
double dist = std::sqrt(std::pow(ent2_x - ent1_x, 2) +
std::pow(ent2_y - ent1_y, 2));
if (dist > (ent1->get_radius() + ent2->get_radius())) {
return false;
} else {
return true;
}
} /* CheckForCollisionVirtual() */

View file

@ -0,0 +1,63 @@
/**
* @file robot_arena.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ARENA_H_
#define SRC_ARENA_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include <cmath>
#include <iostream>
#include <vector>
#include "robot.h"
#include "robot_virtual.h"
class Arena {
public:
explicit Arena();
~Arena(void);
void AddRobot(const Position& pos, const int rad);
void AddRobotVirtual(const Position& pos, const int rad);
/**
* @brief Advance the simulation by the specified # of steps.
*/
void AdvanceTime();
private:
/**
* @brief Determine if two entities have collided in the arena. Collision is
* defined as the difference between the extents of the two entities being less
* than a run-time parameter.
*
* @param ent1 Entity #1.
* @param ent2 Entity #2.
* @param pointer to a collision event
*
* Collision Event is populated appropriately.
*/
bool CheckForCollision(Entity* ent1, Entity* ent2);
bool CheckForCollisionVirtual(EntityVirtual* ent1, EntityVirtual* ent2);
/**
* @brief Update all entities for a single timestep
*/
void UpdateEntities(void);
// Entities populating the arena
int n_robots_;
Entity* robots_[3];
int n_robots_virtual_;
EntityVirtual* robots_virtual_[3];
};
#endif // SRC_ARENA_H_

View file

@ -0,0 +1,39 @@
/**
* @file arena_entity.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ARENA_ENTITY_H_
#define SRC_ARENA_ENTITY_H_
#include <string>
#include "position.h"
class Entity {
public:
Entity(const Position& pos, int rad) : position_(pos), radius_(rad) {}
virtual ~Entity(void) {}
/**
* @brief Perform whatever updates are needed for a particular entity after 1
* timestep.
*/
virtual void TimestepUpdate() {}
/**
* @brief Setter and Getter for position. Defined here only (not in subclass)
*
*/
void set_position(const Position& pos) { position_ = pos; }
const Position& get_position(void) const { return position_; }
void set_radius(const int rad) { radius_ = rad; }
const int& get_radius(void) const { return radius_; }
private:
Position position_;
int radius_;
};
#endif /* SRC_ARENA_ENTITY_H_ */

View file

@ -0,0 +1,35 @@
/**
* @file arena_entity.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ARENA_ENTITY_VIRTUAL_H_
#define SRC_ARENA_ENTITY_VIRTUAL_H_
#include <string>
#include "position.h"
class EntityVirtual {
public:
EntityVirtual(const Position& pos, int rad) : position_(pos), radius_(rad) {}
virtual ~EntityVirtual(void) {}
/**
* @brief Perform whatever updates are needed for a particular entity after 1
* timestep.
*/
virtual void TimestepUpdate() {}
virtual void set_position(const Position& pos) = 0;
virtual const Position& get_position(void) const = 0;
virtual void set_radius(const int& rad) = 0;
virtual const int& get_radius(void) const = 0;
protected:
Position position_;
int radius_;
};
#endif /* SRC_ARENA_ENTITY_H_ */

View file

@ -0,0 +1,21 @@
/**
* @file main.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "arena.h"
/*******************************************************************************
* Non-Member Functions
******************************************************************************/
int main(int, char **) {
Arena arena;
return 0;
}

View file

@ -0,0 +1,51 @@
/**
* @file mobile_arena_entity.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ARENA_MOBILE_ENTITY_H_
#define SRC_ARENA_MOBILE_ENTITY_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include <algorithm>
#include "entity.h"
/*******************************************************************************
* Class Definitions
******************************************************************************/
/**
* @brief A mobile entity in the arena, capable of updating its own position
* and/or velocity when asked by the simulation.
*
* All mobile entities must have a heading angle so that their orientation can
* be properly drawn by the viwer.
*/
class MobileEntity : public Entity {
public:
MobileEntity(const Position& pos, const int rad ) : Entity(pos, rad) {}
/**
* @brief Get/Set the current heading angle for the entity.
*/
virtual double heading_angle(void) const = 0;
virtual void heading_angle(double heading_angle) = 0;
/**
* @brief Get/Set the current speed of an arena entity.
*/
virtual double get_speed(void) const = 0;
virtual void set_speed(double sp) = 0;
/**
* @brief Update an entity's position after the specified # of
* timesteps has elapsed.
*/
void TimestepUpdate() = 0;
private:
};
#endif /* SRC_ARENA_MOBILE_ENTITY_H_ */

View file

@ -0,0 +1,38 @@
/**
* @file mobile_arena_entity.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ARENA_MOBILE_ENTITY_VIRTUAL_H_
#define SRC_ARENA_MOBILE_ENTITY_VIRTUAL_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include <algorithm>
#include "entity_virtual.h"
class MobileEntityVirtual : public EntityVirtual {
public:
MobileEntityVirtual(const Position& pos, const int rad)
: EntityVirtual(pos, rad) {}
/**
* @brief Get/Set the current heading angle for the entity.
*/
virtual double heading_angle(void) const = 0;
virtual void heading_angle(double heading_angle) = 0;
/**
* @brief Get/Set the current speed of an arena entity.
*/
virtual double get_speed(void) const = 0;
virtual void set_speed(double sp) = 0;
void TimestepUpdate();
private:
};
#endif /* SRC_ARENA_MOBILE_ENTITY_H_ */

View file

@ -0,0 +1,36 @@
/**
* @file robot_motion_behavior.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include <math.h>
#include "motion_behavior.h"
#include "position.h"
/*******************************************************************************
* Member Functions
******************************************************************************/
void MotionBehavior::UpdatePosition(MobileEntity * const ent) {
Position new_pos;
// Movement is always along the heading_angle (i.e. the hypotenuse)
new_pos.x += cos(ent->heading_angle()*3.14/180.0)*ent->get_speed()*1;
new_pos.y += sin(ent->heading_angle()*3.14/180.0)*ent->get_speed()*1;
ent->set_position(new_pos);
} /* update_position() */
void MotionBehavior::UpdatePosition(
MobileEntityVirtual * const ent) {
Position new_pos;
// Movement is always along the heading_angle (i.e. the hypotenuse)
new_pos.x += cos(ent->heading_angle()*3.14/180.0)*ent->get_speed()*1;
new_pos.y += sin(ent->heading_angle()*3.14/180.0)*ent->get_speed()*1;
ent->set_position(new_pos);
} /* update_position() */

View file

@ -0,0 +1,27 @@
/**
* @file robot_motion_behavior.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ROBOT_MOTION_BEHAVIOR_H_
#define SRC_ROBOT_MOTION_BEHAVIOR_H_
#include "mobile_entity.h"
#include "mobile_entity_virtual.h"
class MotionBehavior {
public:
MotionBehavior(void) {}
/**
* @brief Update the position for an ArenaEntity, based on its current
* position and velocity.
*
* @param[in] ent The entitity to update.
*/
void UpdatePosition(class MobileEntity * const ent);
void UpdatePosition(class MobileEntityVirtual * const ent);
};
#endif /* SRC_ROBOT_MOTION_BEHAVIOR_H_ */

View file

@ -0,0 +1,26 @@
/**
* @file robot_motion_handler.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "motion_handler.h"
/*******************************************************************************
* Constructors/Destructor
******************************************************************************/
MotionHandler::MotionHandler() :
heading_angle_(0), speed_(0), max_speed_(5) {
}
/*******************************************************************************
* Member Functions
******************************************************************************/
void MotionHandler::UpdateVelocity(bool collided) {
if (collided) {
heading_angle_ = -heading_angle_;
}
}

View file

@ -0,0 +1,42 @@
/**
* @file actuator_handler.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ROBOT_MOTION_HANDLER_H_
#define SRC_ROBOT_MOTION_HANDLER_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include "mobile_entity.h"
class MotionHandler {
public:
MotionHandler();
/**
* @brief Change the speed and direction according to the sensor readings.
*
* @param touch sensor that can be activated and contains point-of-contact.
*
*/
void UpdateVelocity(bool collided);
double speed(void) const { return speed_; }
void speed(double sp) { speed_ = sp; }
double heading_angle(void) const { return heading_angle_;}
void heading_angle(double ha) { heading_angle_ = ha; }
double max_speed(void) const { return max_speed_; }
void max_speed(double ms) { max_speed_ = ms; }
private:
double heading_angle_;
double speed_;
double max_speed_;
};
#endif /* SRC_ROBOT_MOTION_HANDLER_H_ */

View file

@ -0,0 +1,17 @@
/**
* @file position.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_POSITION_H_
#define SRC_POSITION_H_
struct Position {
Position(void) : x(0),y(0) { }
Position(int in_x, int in_y) : x(in_x), y(in_y) { }
int x;
int y;
};
#endif /* SRC_POSITION_H_ */

View file

@ -0,0 +1,37 @@
/**
* @file robot.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "robot.h"
#include "motion_behavior.h"
/*******************************************************************************
* Constructors/Destructor
******************************************************************************/
Robot::Robot(const Position& pos, const int rad ) :
MobileEntity(pos, rad),
id_(-1),
motion_handler_(),
motion_behavior_() {
motion_handler_.heading_angle(270);
motion_handler_.speed(5);
}
/*******************************************************************************
* Member Functions
******************************************************************************/
void Robot::TimestepUpdate() {
// Update heading and speed as indicated by touch sensor
motion_handler_.UpdateVelocity(true);
// Use velocity and position to update position
motion_behavior_.UpdatePosition(this);
} /* TimestepUpdate() */

View file

@ -0,0 +1,45 @@
/**
* @file robot.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ROBOT_H_
#define SRC_ROBOT_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include <string>
#include "mobile_entity.h"
#include "motion_behavior.h"
#include "motion_handler.h"
class Robot : public MobileEntity {
public:
explicit Robot(const Position& pos, const int rad );
/**
* @brief Update the robot's position and velocity after the specified
* duration has passed.
*
* @param dt The # of timesteps that have elapsed since the last update.
*/
void TimestepUpdate();
double heading_angle(void) const {
return motion_handler_.heading_angle();
}
void heading_angle(double ha) { motion_handler_.heading_angle(ha); }
double get_speed(void) const { return motion_handler_.speed(); }
void set_speed(double sp) { motion_handler_.speed(sp); }
private:
int id_;
MotionHandler motion_handler_;
MotionBehavior motion_behavior_;
};
#endif /* SRC_ROBOT_H_ */

View file

@ -0,0 +1,38 @@
/**
* @file robot.cc
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "robot_virtual.h"
#include "motion_behavior.h"
#include "mobile_entity_virtual.h"
/*******************************************************************************
* Constructors/Destructor
******************************************************************************/
RobotVirtual::RobotVirtual(const Position& pos, const int rad) :
MobileEntityVirtual(pos, rad),
id_(-1),
motion_handler_(),
motion_behavior_() {
motion_handler_.heading_angle(270);
motion_handler_.speed(5);
}
/*******************************************************************************
* Member Functions
******************************************************************************/
void RobotVirtual::TimestepUpdate() {
// Update heading and speed as indicated by touch sensor
motion_handler_.UpdateVelocity(true);
// Use velocity and position to update position
motion_behavior_.UpdatePosition(this);
} /* TimestepUpdate() */

View file

@ -0,0 +1,68 @@
/**
* @file robot.h
*
* @copyright 2017 3081 Staff, All rights reserved.
*/
#ifndef SRC_ROBOT_VIRTUAL_H_
#define SRC_ROBOT_VIRTUAL_H_
/*******************************************************************************
* Includes
******************************************************************************/
#include <string>
#include "mobile_entity_virtual.h"
#include "motion_behavior.h"
#include "motion_handler.h"
/*******************************************************************************
* Class Definitions
******************************************************************************/
/**
* @brief Class representing a mobile robot within the arena.
*
* Robots have the capability of updating their own position when asked, and
* also track their own velocity and heading. They have a touch sensor for
* responding to collision events which is activated/deactivated on collision
* events.
*
*/
class RobotVirtual : public MobileEntityVirtual {
public:
explicit RobotVirtual(const Position& pos, const int rad );
/**
* @brief Setter and Getter for position.
*/
void set_position(const Position& pos) { position_ = pos; }
const Position& get_position(void) const { return position_; }
/**
* @brief Setter and Getter for radius.
*/
void set_radius(const int& rad) { radius_ = rad; }
const int& get_radius(void) const { return radius_; }
/**
* @brief Update the robot's position and velocity after the specified
* duration has passed.
*/
void TimestepUpdate();
double heading_angle(void) const {
return motion_handler_.heading_angle();
}
void heading_angle(double ha) { motion_handler_.heading_angle(ha); }
double get_speed(void) const { return motion_handler_.speed(); }
void set_speed(double sp) { motion_handler_.speed(sp); }
private:
int id_;
MotionHandler motion_handler_;
MotionBehavior motion_behavior_;
};
#endif /* SRC_ROBOT_H_ */

View file

@ -0,0 +1,4 @@
*.o
*.*~
.DS_Store
unittests

View file

@ -0,0 +1,17 @@
# CSCI3081 In-Class Exercise dynamic allocation and arrays
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
TESTOBJS =
OBJS = main.o robot.o tests.o
all: $(OBJS)
$(CC) $(LFLAGS) -o unittests $(OBJS)
%.o : %.cc
$(CC) $(CFLAGS) -o $@ $<
clean:
\rm *.o *.*~ unittests

View file

@ -0,0 +1,16 @@
## Homegrown Testing Framework
### Fibonacci
1. Look at "tests.cc" to see the assert statement options.
2. Look at "fibonacci_test.cc" to see how these assert statements are used.
3. _make_ and run the unittests `./unittests` to see how successful these tests were in finding errors!
4. No need to fix these errors. The point is to understand how test cases are created and used to develop a suite of tests.
### Robot
1. Look at "robot.h" and robot.cc".
2. In the file "robot_test.cc" notice there are no tests written. Remedy this by writing a test that tests the DEFAULT constructor. This would be composed of the instantiation of a robot, then a series of the provided assert statements (e.g. _ExpectEqual()_) to check that the values for the radius and the position are as expected. The tests in "fibonacci_test.cc" provide a guide on how to create these.
3. Write a test for the other constructor.
4. Look at _Robot::CheckOverlap()_. Identify some scenarios that would be good to test.
5. For each scenario, write a collection of assert statements to confirm the results.

View file

@ -0,0 +1,16 @@
#ifndef TESTS_FIBONACCI_H_
#define TESTS_FIBONACCI_H_
int fibonacci(int n) {
// Calculate the nth fibonacci number
int sum_n;
int sum_n2 = 1;
int sum_n1 = 1;
for (int i=0;i<n;i++) {
sum_n = sum_n1 + sum_n2;
sum_n1 = sum_n;
sum_n2 = sum_n1;
}
return sum_n;
}
#endif

View file

@ -0,0 +1,21 @@
#include <iostream>
#include "fibonacci.h"
#include "tests.h"
void fibonacci_unittest() {
// test negative
ExpectEqual("Negative Input",-1,fibonacci(-1));
// test 0
ExpectEqual("0 Input",0,fibonacci(0));
// test boundary
ExpectEqual("Border 1",1,fibonacci(1));
ExpectEqual("Border 2",2,fibonacci(2));
// test typical
ExpectEqual("Typical 5", 5, fibonacci(5));
ExpectEqual("Typical 10", 55, fibonacci(10));
}

View file

@ -0,0 +1,14 @@
#include <iostream>
#include "fibonacci_test.cc"
#include "robot_test.cc"
int main() {
std::cout << std::endl ;
std::cout << "FIBONACCI TESTS" << std::endl;
fibonacci_unittest();
std::cout << std::endl << std::endl;
std::cout << "ROBOT TESTS" << std::endl;
robot_unittest();
}

View file

@ -0,0 +1,23 @@
#include <math.h>
#include "robot.h"
Robot::Robot() : radius(5), position(0,0) {
}
Robot::Robot(int r, int x, int y) : radius(r), position(x,y) {
}
bool Robot::CheckOverlap(const Robot& robot2){
// Get distance between centers
int deltaX = robot2.get_position().x - this->get_position().x;
int deltaY = robot2.get_position().y - this->get_position().y;
int distance = sqrt((double)((deltaX*deltaX) + (deltaY*deltaY)));
// check overlap
if (distance < this->get_radius() + robot2.get_radius()) {
return true;
}
return false;
}

View file

@ -0,0 +1,23 @@
#ifndef TESTS_ROBOT_H_
#define TESTS_ROBOT_H_
struct Position {
int x;
int y;
Position(): x(0), y(0) {}
Position(int inX, int inY) : x(inX), y(inY) {}
};
class Robot {
public:
Robot();
Robot(int r, int x, int y);
bool CheckOverlap(const Robot& robot2);
Position get_position(void) const { return position; }
int get_radius(void) const { return radius; }
private:
int radius;
Position position;
};
#endif

View file

@ -0,0 +1,7 @@
#include <iostream>
#include "robot.h"
void robot_unittest() {
}

View file

@ -0,0 +1,45 @@
#include <iostream>
#include <string>
#include <cstdio>
#include "tests.h"
void ExpectEqual(std::string test, int expect, int got) {
std::cout << test << ":";
if (expect != got) {
printf("FAIL: expected %d, returned %d\n", expect, got);
} else {
printf("PASS\n");
}
}
void ExpectEqual(std::string test, float expect, float got) {
std::cout << test << ":";
if (expect != got) {
printf("FAIL:: expected %f, returned %f\n", expect, got);
} else {
printf("PASS\n");
}
}
void ExpectEqual(std::string test, bool expect, int got) {
char * expect_string;
char * got_string;
if (expect) {
expect_string = "True";
} else {
expect_string = "False";
}
if (got) {
got_string = "True";
} else {
got_string = "False";
}
std::cout << test << ":";
if (expect != got) {
printf("FAIL: expected %s, returned %s\n",
expect_string, got_string );
} else {
printf("PASS\n");
}
}

View file

@ -0,0 +1,11 @@
#ifndef TESTS_TESTS_H_
#define TESTS_TESTS_H_
#include <string>
// These are my "homegrown" version of Google test asserts
void ExpectEqual(std::string test, int expect, int got);
void ExpectEqual(std::string test, float expect, float got);
void ExpectEqual(std::string test, bool expect, int got);
#endif

View file

@ -0,0 +1,65 @@
## Peer Reflection on UML Diagram
The learning objectives:
- Reflect on methods for communicating code structure.
- Critically analyze the UML diagram as written communication.
- Identify the key characteristics of this writing form that best communicate code structure for the purpose of assisting others in understanding the code.
- Identify strengths and weaknesses of your UML and paragraph drafts.
### _Good_ Writing Criteria
- States key information clearly (important findings, recommendations, ideas,
issues, etc.).
- Addresses target audience with an appropriate tone and level of explanation.
- Presents any needed background explanation clearly or informatively.
- Describes algorithms, data structures, software system components, etc.
accurately.
- Describes algorithms, data structures, software system components, etc.
informatively and concisely.
- Uses terminology and notation correctly.
- Uses appropriate structures (lists, diagrams, equations, code samples, etc.).
- Includes clear and informative tables, diagrams, references, etc.
- Has a good organization and logical flow.
- Avoids including irrelevant information, overemphasizing less important material,
or writing verbosely.
## Form a Group
Form a group of 3 to 4 people. Not 2 and not more than 4. Someone volunteer to start.
> Take personal notes during the discussion to use to improve your UML, as well as develop the main page of doxygen documentation for next week's submission.
### Each person ...
1. Show your UML diagram and paragraph to the group, giving everyone a few minutes to look it over and read the paragraph.
2. Explain your process in understanding the code structure and creating your UML diagram. Did you spend hours with the code then start your UML? Did you start with the UML and fill it in as your understanding of the code grew?
3. State what tool you used. What was the good and bad of that tool? Would you recommend that tool to others?
4. Look at the UML and paragraph as a unit. In what ways does the paragraph enhance or complement the UML? In what ways does the UML complement the paragraph?
5. Share with peers what you found to be the most difficult aspect of generating the diagram.
6. Share with the group something you want to improve upon in the diagram or the paragraph.
### Next (after everyone shared) ...
Collectively discuss the following:
1. MEDIUM: Identify elements in each UML that is unique and brings value to understanding the code. (Keep this in mind as you edit your UML for next week's submission).
2. DETAIL: Compare the levels of detail on each UML. Is there huge variety? Identify places in each UML where you think either more or less detail is needed.
3. AUDIENCE: Would you change the level of detail for different audiences? For example, as someone who is now submerged in the code, do you want more or less detail? Think back to when you didn't know the code - do you think you want more or less detail?
3. VISUALIZATION: Compare the overall layouts and formatting for each. Is there huge variety? Do fonts make a difference? Can you distinguish arrows? Identify places in each UML where layout or formatting could be improved.
4. CORRECTNESS: Are things presented correctly - inheritance, composition, flow-of-information?
5. WRITING PROCESS: How much do you think the UML contributes to understanding the code OR is it the _process_ of constructing the UML that is the most informative? What is your opinion on the utility of an auto-generated UML (which doxygen will do for you)?
5. COMPLETENESS: Think back to when you first engaged the code. What was missing from what was provided to you to better assist you in understanding the code (other than the UML)? How can you incorporate those elements into either the UML or in the mainpage of your doxygen documentation?
6. DOCUMENTATION PLAN: Collectively establish a rough outline of content for the doxygen documentation. This is an introduction to the project and to the html pages. Keep in mind your audience. Level of detail is important - how much detail do you need to go into?

View file

@ -0,0 +1,20 @@
# class-repo-public for CSCI3081 Fall 2017
This is a read-only repository. Students copy from this into their personal repo in the course organization.
There is a second branch _iter1-update1_ whose source code is functionally equivalent to the master branch but
is refactored. At the start of iteration2, these branches will be merged. Students will receive instructions on
refactoring so that student repos are aligned with class-repo-public.
### USE THE MASTER BRANCH FOR TESTS
#### Latest Updates
- 10/24/17: Bug fix. robot_motion_handler_unittest. speed changed in test for UP and DOWN.
- 10/24/17: Bug fix. Accept() in robot_battery.cc added scoping - RobotBattery::
- 10/22/17: Bug fix. Added rmh.heading_angle(180) in robot-motion-handler-unittest
- 10/22/17: Simplified tests. Replaced, removed, or modified almost all of them. Email sent with FYI's.
- 10/21/17: Tests updated to use csci3081::Color
- 10/21/17: color.h added to src directory (not incorporated into other code - this is part of your work for priority 3)
- 10/21/17: Tests from iter1-tests moved into the master branch, without change.
- 10/21/17: New branch fix/priority1 has been created to fix issues related to priority1 tests. Do NOT use this branch - it is for development for staff.

6467
class-repo-public/cpplint.py vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,163 @@
# 3081 Lab01 GitHub Basics
## What You Will Learn
1. Basic Linux commands, for example _mkdir_, _cd_, _mv_, and _ls_.
1. How to configure github for your cselabs account.
2. How to _clone_ (create a local copy of an existing repo), _pull_ (get updates), and _push_ (make updates).
3. How to configure the _.gitignore_ file so that _push_ ignores files not necessary to track.
4. The required directory structure and file nomenclature for course assignments.
5. How to initiate and read automated testing of course assignments.
_For additional information about Linux, see http://www-users.cs.umn.edu/~larson/repo-website-resources/website/examples/csresources/linux.html_
### Configuring GitHub
Below, a number of commands are shown that should be typed into the command line. These are preceded by a percent sign "%" which is NOT to be typed in.
Log into your cselabs account.
`% git --version` This will establish if it is installed.
```
% git config --global user.name << "your name" >>
% git config --global user.email << your email address >>
% git config --global core.editor << your editor choice here >>.
```
Note that your name appears between double quotes since it has spaces in it. Your email address doesn't, so it doesn't need to be in quotes. If you would like `emacs -nw` as your editor (emacs such that it doesn't open a new window but opens in the terminal) then you'll want double quotes around that 2 word phrase. Also note that if you want to use gedit, you probably need to use `gedit -w -s`.
`% git config --list` to see that Git has set this up correctly.
### Cloning the Read-Only 3081 Course Repository
Computer Science courses are setup for github by first establishing a GitHub organization (e.g. _umn-csci-3081F17_), which contains a repository for each student, as well as a read-only course repository (e.g. _class-repo-public_). Course materials will be distributed via the read-only repository.
> It is probably a good idea to copy any content you will be using from the class repository, into your individual workspace. This is because as we add content, it might cause merge conflicts with files that you added. Keep in mind that the way that github is used in a class is very different from how you would use it at work. You would never have 150 people at work writing the same exact code and then trying to hide it from each other. As the semester progresses, we will point out some ways in which a repository for work differs from how it is used here.
At the top level of your cselabs account or within a directory of your choice, create a 3081 directory with any name you prefer, then move to that directory. You will clone both the class and individual repo into this directory.
```
% (optional) cd <location of your choosing>
% mkdir 3081_F17
% cd 3081_F17
% git clone https://github.umn.edu/umn-csci-3081F17/class-repo-public
% ls
```
**_What just happened?_** You made a new directory (i.e. folder) in your account with `mkdir`. You changed that to your working directory with `cd`. You copied the class repo locally to your machine with `clone`. You listed the contents of the working directory with `ls`, which should list the newly created directory with the name of the repository which it contains. These directories function exactly like all other linux directories. There are hidden files that track changes to the repository.
### Cloning and Configuring Your Student Course Repository
Follow the same process and clone your individual repository.
```
% git clone https://github.umn.edu/umn-csci-3081F17/repo-<userID>
```
Next, move the source code for lab01 from the class repo to your individual repo. Where it has _<userID>_, you **replace with your UMN userID**, e.g. _lars1050_, without the "<" and ">" symbols.
```
% cd repo-<userID>
$ ls -a
```
**_What just happened?_** You made your class repo the working directory with `cd`. You displayed (i.e. listed) the contents of the working directory with `ls`, including all hidden files with `-a`. Notice the directory _.git_, which is how files are tracked. This is contained at the top level of the repository. If you want to look inside that directory type `% ls .git`.
> It is **very important** that you never modify, delete, or move this directory, AND never copy it from one repo to another, as that will really mess things up.
```
% mkdir labs
% cp -r ../class-repo-public/lab01 labs/.
% ls -a
```
**_What just happened?_** You created a new directory with `mkdir` that will contain folders with all labs for this course. You copied the entire directory (i.e. folder) _lab01_ contained in the class repo into the _labs_ directory of your individual repo, maintaining the name _lab01_ with the use of `labs/.`. Notice the `../class-repo-public`. The `..` means to navigate up one level in the directory structure. The single `.` means look inside the current directory. The list of content for this directory does not contain the _.git_ directory.
### Executing Lab Code and Pushing Results
The code provided for lab01 will create an executable by compiling the provided C++ files using a _makefile_. Running the executable will generate 2 files that will be added to your lab01 directory. A _makefile_ manages the compilation process, which will be explored further in next week's lab.
```
% cd labs/lab01
% make
% ls
```
**_What just happened?_** You made _lab01_ your working directory with `cd`. You executed the makefile (named _makefile_) with `make`, which created object files with the extension _.o_, and the executable _lab01.out_. These files are displayed with `ls`.
```
% ./lab01.out
% ls
```
**_What just happened?_** You ran the executable with `./lab01.out`, which generated 2 files _private.pvt_ and _shared.md_. In the next part of this lab, you will setup the _.gitignore_ file so that the former file is not added to the repo, but the latter is.
Before telling git what not to track, look at what it has been tracking.
```
% git status
```
You will see the directories and files that have been added to this repository.
### Configuring and Using _.gitignore_
There are a lot of files that should not be tracked in the repository. You typically don't want object and executable files included in your repo, because these are consequences of the local compilation. There are common files or libraries that should not be included, because it is wasteful to have multiple copies and to spend bandwidth moving them around. There might also be files that are for you only, such as notes about the project or todo lists. The _.gitignore_ file stores file extensions that serve as a filter for git. Any file with that extension will not be tracked.
Navigate back to the top level of your individual repository, confirmiing you are in the right place.
```
% cd ../..
% pwd
```
If you are in the right place, using your favorite text editor, create a .gitignore file, e.g. `xemacs .gitignore &`, which will open xemacs in a new window. Edit the .gitignore file to remove your executable and build folders.
Add these lines to the file:
```
# Extensions to not include in repo
*.o
*.out
*.pvt
```
Save the file.
**What just happened?** You added a comment by prefacing the first line with `#`. You indicated to not track any and all files with the use of `*` that has a specific file extension (e.g. `*.o`). If you have a one-off, you can include that specific file. You can also add a directory name, which will ignore all contents of the directory.
Look at the results:
```
% git status
```
Now you will see that the indicated files in _.gitignore_ are no longer tracked.
### Add Changes to Repo both Locally and on the Server
You need to _stage_ all changes to the repository, which prepares those items to be permanently part of the repository. When you _commit_ those changes, they are saved to your local repository, which lives in your cselabs account (or your personal computer if that is what you are working on). When you _push_ those changes, they will be copied to the repo on the server.
```
% git add *
% git commit -m "Adding lab01 results."
% git push
```
**What just happened?** All of the tracked changes were stages with `git add *`. You could have only staged certain files by replacing _*_ with the filename. Note that `add` does not mean you are adding a new file or a new directory, it means you are adding a change (any change). Those staged changes were committed to your local repository and tagged with the message that follows `-m`, then pushed to the server.
>Always use good comments in the commit. If you need to restore a previous state of the repo that is several commits back, you will have a much easier time figuring out which commit is relevant when you use comments like _"adding robot class definition"_, as opposed to _"more class stuff"_.
>Always verify that the changes have been uploaded to the server by looking at the repo through the web interface of github.
### Reading the Feedback
Pushing to the server triggers the automated grading system. Soon your repo will contain a feedback file, letting you know if you have passed all tests of the assignment. These tests will make sure you have the right directory structure, filenames, and that everything is behaving as indicated in the requirements.
Watch your github account via the web interface to see when the feedback file is ready (hit refresh to check contents). You can look at it through the web, but it is important to pull in that file to your local repo, so as not to cause merge conflicts.
```
% git pull
% cd labs/lab01
% ls
```
> ALWAYS, ALWAYS, ALWAYS perform a _pull_ before making changes to a repository. Each time you sit down to work on a lab or project iteration, it would be an excellent habit to perform a _pull_ on both the class repo and your individual repo.
THIS LAB IS COMPLETE.
Congratulations!

Some files were not shown because too many files have changed in this diff Show more