f
This commit is contained in:
commit
1ba4536588
897 changed files with 104285 additions and 0 deletions
BIN
_templates/templates
Executable file
BIN
_templates/templates
Executable file
Binary file not shown.
144
_templates/templates.cc
Normal file
144
_templates/templates.cc
Normal 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
1
aaaa
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 10983be67c48557abadab23de493ba4bae41289a
|
3
class-repo-public/.gitignore
vendored
Normal file
3
class-repo-public/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.o
|
||||||
|
*.*~
|
||||||
|
*.out
|
74
class-repo-public/Assignments/CSwriting.md
Normal file
74
class-repo-public/Assignments/CSwriting.md
Normal 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>
|
BIN
class-repo-public/Exercises/CartDesign/cart
Executable file
BIN
class-repo-public/Exercises/CartDesign/cart
Executable file
Binary file not shown.
20
class-repo-public/Exercises/CartDesign/cart.cpp
Normal file
20
class-repo-public/Exercises/CartDesign/cart.cpp
Normal 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;
|
||||||
|
}
|
26
class-repo-public/Exercises/CartDesign/cart.h
Normal file
26
class-repo-public/Exercises/CartDesign/cart.h
Normal 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();
|
||||||
|
};
|
27
class-repo-public/Exercises/CartDesign/main.cpp
Normal file
27
class-repo-public/Exercises/CartDesign/main.cpp
Normal 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;
|
||||||
|
}
|
18
class-repo-public/Exercises/CartDesign/makefile
Normal file
18
class-repo-public/Exercises/CartDesign/makefile
Normal 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
|
8
class-repo-public/Exercises/CartDesign/readme.md
Normal file
8
class-repo-public/Exercises/CartDesign/readme.md
Normal 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.
|
83
class-repo-public/Exercises/Inheritance/object.cpp
Normal file
83
class-repo-public/Exercises/Inheritance/object.cpp
Normal 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;
|
||||||
|
}
|
42
class-repo-public/Exercises/Inheritance/readme.md
Normal file
42
class-repo-public/Exercises/Inheritance/readme.md
Normal 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>
|
89
class-repo-public/Exercises/TestSensor.cc
Normal file
89
class-repo-public/Exercises/TestSensor.cc
Normal 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);
|
||||||
|
}
|
106
class-repo-public/Exercises/_templates/templates.cc
Normal file
106
class-repo-public/Exercises/_templates/templates.cc
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
}
|
BIN
class-repo-public/Exercises/classDefRobots/.DS_Store
vendored
Normal file
BIN
class-repo-public/Exercises/classDefRobots/.DS_Store
vendored
Normal file
Binary file not shown.
3
class-repo-public/Exercises/classDefRobots/.gitignore
vendored
Normal file
3
class-repo-public/Exercises/classDefRobots/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*.out
|
||||||
|
*.o
|
||||||
|
robot
|
267
class-repo-public/Exercises/classDefRobots/classDefExercise.md
Normal file
267
class-repo-public/Exercises/classDefRobots/classDefExercise.md
Normal 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!
|
27
class-repo-public/Exercises/classDefRobots/main.cpp
Normal file
27
class-repo-public/Exercises/classDefRobots/main.cpp
Normal 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();
|
||||||
|
*/
|
||||||
|
}
|
18
class-repo-public/Exercises/classDefRobots/makefile
Normal file
18
class-repo-public/Exercises/classDefRobots/makefile
Normal 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
|
41
class-repo-public/Exercises/classDefRobots/robot.cpp
Normal file
41
class-repo-public/Exercises/classDefRobots/robot.cpp
Normal 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;
|
||||||
|
}
|
19
class-repo-public/Exercises/classDefRobots/robot.h
Normal file
19
class-repo-public/Exercises/classDefRobots/robot.h
Normal 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();
|
||||||
|
|
||||||
|
};
|
218
class-repo-public/Exercises/collision.py
Normal file
218
class-repo-public/Exercises/collision.py
Normal 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))
|
||||||
|
|
||||||
|
|
32
class-repo-public/Exercises/constants/Robot.cpp
Normal file
32
class-repo-public/Exercises/constants/Robot.cpp
Normal 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();
|
||||||
|
}
|
54
class-repo-public/Exercises/constants/chain_reference.cpp
Normal file
54
class-repo-public/Exercises/constants/chain_reference.cpp
Normal 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;
|
||||||
|
}
|
44
class-repo-public/Exercises/constants/constants.cc
Normal file
44
class-repo-public/Exercises/constants/constants.cc
Normal 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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
BIN
class-repo-public/Exercises/duckVisitor/.DS_Store
vendored
Normal file
BIN
class-repo-public/Exercises/duckVisitor/.DS_Store
vendored
Normal file
Binary file not shown.
9
class-repo-public/Exercises/duckVisitor/.gitignore
vendored
Normal file
9
class-repo-public/Exercises/duckVisitor/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.out
|
||||||
|
|
||||||
|
*.*~
|
||||||
|
*~
|
||||||
|
|
||||||
|
duckVisitor
|
||||||
|
|
53
class-repo-public/Exercises/duckVisitor/Duck.cpp
Normal file
53
class-repo-public/Exercises/duckVisitor/Duck.cpp
Normal 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; }
|
50
class-repo-public/Exercises/duckVisitor/Duck.h
Normal file
50
class-repo-public/Exercises/duckVisitor/Duck.h
Normal 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
|
40
class-repo-public/Exercises/duckVisitor/Fly.cpp
Normal file
40
class-repo-public/Exercises/duckVisitor/Fly.cpp
Normal 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() {}
|
38
class-repo-public/Exercises/duckVisitor/Fly.h
Normal file
38
class-repo-public/Exercises/duckVisitor/Fly.h
Normal 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
|
64
class-repo-public/Exercises/duckVisitor/Quack.cpp
Normal file
64
class-repo-public/Exercises/duckVisitor/Quack.cpp
Normal 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. <<<<<<<<<<<<<<<<
|
||||||
|
};
|
||||||
|
*/
|
46
class-repo-public/Exercises/duckVisitor/Quack.h
Normal file
46
class-repo-public/Exercises/duckVisitor/Quack.h
Normal 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
|
36
class-repo-public/Exercises/duckVisitor/Visitor.cpp
Normal file
36
class-repo-public/Exercises/duckVisitor/Visitor.cpp
Normal 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
|
||||||
|
}
|
30
class-repo-public/Exercises/duckVisitor/Visitor.h
Normal file
30
class-repo-public/Exercises/duckVisitor/Visitor.h
Normal 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
|
57
class-repo-public/Exercises/duckVisitor/duckVisitor.cpp
Normal file
57
class-repo-public/Exercises/duckVisitor/duckVisitor.cpp
Normal 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;
|
||||||
|
}
|
17
class-repo-public/Exercises/duckVisitor/makefile
Normal file
17
class-repo-public/Exercises/duckVisitor/makefile
Normal 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
|
25
class-repo-public/Exercises/duckVisitor/readme.md
Normal file
25
class-repo-public/Exercises/duckVisitor/readme.md
Normal 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.
|
||||||
|
|
0
class-repo-public/Exercises/duckVisitor/scratch.cpp
Normal file
0
class-repo-public/Exercises/duckVisitor/scratch.cpp
Normal file
13
class-repo-public/Exercises/ducks/.gitignore
vendored
Normal file
13
class-repo-public/Exercises/ducks/.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
*.out
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
duckStrategyComplete.cpp
|
||||||
|
duckStrategyPolyComplete.cpp
|
||||||
|
|
||||||
|
*_print.*
|
||||||
|
|
||||||
|
*.txt
|
17
class-repo-public/Exercises/ducks/duck1.h
Normal file
17
class-repo-public/Exercises/ducks/duck1.h
Normal 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"; }
|
||||||
|
};
|
||||||
|
|
20
class-repo-public/Exercises/ducks/duck2.h
Normal file
20
class-repo-public/Exercises/ducks/duck2.h
Normal 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"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
31
class-repo-public/Exercises/ducks/duck3.h
Normal file
31
class-repo-public/Exercises/ducks/duck3.h
Normal 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";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
36
class-repo-public/Exercises/ducks/duck4.h
Normal file
36
class-repo-public/Exercises/ducks/duck4.h
Normal 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"; }
|
||||||
|
};
|
133
class-repo-public/Exercises/ducks/duckStrategy.cpp
Normal file
133
class-repo-public/Exercises/ducks/duckStrategy.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
142
class-repo-public/Exercises/ducks/duckStrategyPoly.cpp
Normal file
142
class-repo-public/Exercises/ducks/duckStrategyPoly.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
41
class-repo-public/Exercises/ducks/ducks1.cpp
Normal file
41
class-repo-public/Exercises/ducks/ducks1.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
46
class-repo-public/Exercises/ducks/ducks2.cpp
Normal file
46
class-repo-public/Exercises/ducks/ducks2.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
38
class-repo-public/Exercises/ducks/ducks3.cpp
Normal file
38
class-repo-public/Exercises/ducks/ducks3.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
48
class-repo-public/Exercises/ducks/ducks4.cpp
Normal file
48
class-repo-public/Exercises/ducks/ducks4.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
5
class-repo-public/Exercises/ducks/makefile
Normal file
5
class-repo-public/Exercises/ducks/makefile
Normal 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
|
16
class-repo-public/Exercises/dynamicallocation/Makefile
Normal file
16
class-repo-public/Exercises/dynamicallocation/Makefile
Normal 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
|
30
class-repo-public/Exercises/dynamicallocation/README.md
Normal file
30
class-repo-public/Exercises/dynamicallocation/README.md
Normal 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.
|
|
@ -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");
|
||||||
|
}
|
|
@ -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_;
|
||||||
|
};
|
25
class-repo-public/Exercises/dynamicallocation/duck.cc
Normal file
25
class-repo-public/Exercises/dynamicallocation/duck.cc
Normal 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");
|
||||||
|
}
|
27
class-repo-public/Exercises/dynamicallocation/duck.h
Normal file
27
class-repo-public/Exercises/dynamicallocation/duck.h
Normal 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
|
BIN
class-repo-public/Exercises/dynamicallocation/ducks
Executable file
BIN
class-repo-public/Exercises/dynamicallocation/ducks
Executable file
Binary file not shown.
13
class-repo-public/Exercises/dynamicallocation/main.cc
Normal file
13
class-repo-public/Exercises/dynamicallocation/main.cc
Normal 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;
|
||||||
|
}
|
19
class-repo-public/Exercises/dynamicallocation/scratch.cc
Normal file
19
class-repo-public/Exercises/dynamicallocation/scratch.cc
Normal 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();
|
||||||
|
}
|
BIN
class-repo-public/Exercises/it2_design.docx
Normal file
BIN
class-repo-public/Exercises/it2_design.docx
Normal file
Binary file not shown.
45
class-repo-public/Exercises/nano_cpplint.md
Normal file
45
class-repo-public/Exercises/nano_cpplint.md
Normal 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.
|
114
class-repo-public/Exercises/op_over.cc
Normal file
114
class-repo-public/Exercises/op_over.cc
Normal 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;
|
||||||
|
}
|
133
class-repo-public/Exercises/proximity.py
Normal file
133
class-repo-public/Exercises/proximity.py
Normal 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)
|
||||||
|
|
158
class-repo-public/Exercises/sensor_distress_unittest.cc
Normal file
158
class-repo-public/Exercises/sensor_distress_unittest.cc
Normal 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 */
|
26
class-repo-public/Exercises/settersGetters/README.md
Normal file
26
class-repo-public/Exercises/settersGetters/README.md
Normal 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?
|
||||||
|
|
16
class-repo-public/Exercises/settersGetters/src/Makefile
Normal file
16
class-repo-public/Exercises/settersGetters/src/Makefile
Normal 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
|
104
class-repo-public/Exercises/settersGetters/src/arena.cc
Executable file
104
class-repo-public/Exercises/settersGetters/src/arena.cc
Executable 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() */
|
63
class-repo-public/Exercises/settersGetters/src/arena.h
Executable file
63
class-repo-public/Exercises/settersGetters/src/arena.h
Executable 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_
|
39
class-repo-public/Exercises/settersGetters/src/entity.h
Executable file
39
class-repo-public/Exercises/settersGetters/src/entity.h
Executable 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_ */
|
|
@ -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_ */
|
21
class-repo-public/Exercises/settersGetters/src/main.cc
Executable file
21
class-repo-public/Exercises/settersGetters/src/main.cc
Executable 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;
|
||||||
|
}
|
51
class-repo-public/Exercises/settersGetters/src/mobile_entity.h
Executable file
51
class-repo-public/Exercises/settersGetters/src/mobile_entity.h
Executable 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_ */
|
|
@ -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_ */
|
36
class-repo-public/Exercises/settersGetters/src/motion_behavior.cc
Executable file
36
class-repo-public/Exercises/settersGetters/src/motion_behavior.cc
Executable 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() */
|
27
class-repo-public/Exercises/settersGetters/src/motion_behavior.h
Executable file
27
class-repo-public/Exercises/settersGetters/src/motion_behavior.h
Executable 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_ */
|
26
class-repo-public/Exercises/settersGetters/src/motion_handler.cc
Executable file
26
class-repo-public/Exercises/settersGetters/src/motion_handler.cc
Executable 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_;
|
||||||
|
}
|
||||||
|
}
|
42
class-repo-public/Exercises/settersGetters/src/motion_handler.h
Executable file
42
class-repo-public/Exercises/settersGetters/src/motion_handler.h
Executable 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_ */
|
17
class-repo-public/Exercises/settersGetters/src/position.h
Normal file
17
class-repo-public/Exercises/settersGetters/src/position.h
Normal 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_ */
|
37
class-repo-public/Exercises/settersGetters/src/robot.cc
Executable file
37
class-repo-public/Exercises/settersGetters/src/robot.cc
Executable 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() */
|
45
class-repo-public/Exercises/settersGetters/src/robot.h
Executable file
45
class-repo-public/Exercises/settersGetters/src/robot.h
Executable 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_ */
|
38
class-repo-public/Exercises/settersGetters/src/robot_virtual.cc
Executable file
38
class-repo-public/Exercises/settersGetters/src/robot_virtual.cc
Executable 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() */
|
68
class-repo-public/Exercises/settersGetters/src/robot_virtual.h
Executable file
68
class-repo-public/Exercises/settersGetters/src/robot_virtual.h
Executable 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_ */
|
4
class-repo-public/Exercises/testing/.gitignore
vendored
Normal file
4
class-repo-public/Exercises/testing/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
*.o
|
||||||
|
*.*~
|
||||||
|
.DS_Store
|
||||||
|
unittests
|
17
class-repo-public/Exercises/testing/Makefile
Normal file
17
class-repo-public/Exercises/testing/Makefile
Normal 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
|
16
class-repo-public/Exercises/testing/README.md
Normal file
16
class-repo-public/Exercises/testing/README.md
Normal 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.
|
16
class-repo-public/Exercises/testing/fibonacci.h
Normal file
16
class-repo-public/Exercises/testing/fibonacci.h
Normal 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
|
21
class-repo-public/Exercises/testing/fibonacci_test.cc
Normal file
21
class-repo-public/Exercises/testing/fibonacci_test.cc
Normal 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));
|
||||||
|
}
|
14
class-repo-public/Exercises/testing/main.cc
Normal file
14
class-repo-public/Exercises/testing/main.cc
Normal 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();
|
||||||
|
}
|
23
class-repo-public/Exercises/testing/robot.cc
Normal file
23
class-repo-public/Exercises/testing/robot.cc
Normal 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;
|
||||||
|
}
|
23
class-repo-public/Exercises/testing/robot.h
Normal file
23
class-repo-public/Exercises/testing/robot.h
Normal 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
|
7
class-repo-public/Exercises/testing/robot_test.cc
Normal file
7
class-repo-public/Exercises/testing/robot_test.cc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "robot.h"
|
||||||
|
|
||||||
|
void robot_unittest() {
|
||||||
|
|
||||||
|
}
|
0
class-repo-public/Exercises/testing/test.cc
Normal file
0
class-repo-public/Exercises/testing/test.cc
Normal file
45
class-repo-public/Exercises/testing/tests.cc
Normal file
45
class-repo-public/Exercises/testing/tests.cc
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
11
class-repo-public/Exercises/testing/tests.h
Normal file
11
class-repo-public/Exercises/testing/tests.h
Normal 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
|
65
class-repo-public/Exercises/uml.md
Normal file
65
class-repo-public/Exercises/uml.md
Normal 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?
|
20
class-repo-public/README.md
Normal file
20
class-repo-public/README.md
Normal 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
6467
class-repo-public/cpplint.py
vendored
Executable file
File diff suppressed because it is too large
Load diff
163
class-repo-public/labs/lab01/3081Lab_GitBasics.md
Normal file
163
class-repo-public/labs/lab01/3081Lab_GitBasics.md
Normal 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
Loading…
Reference in a new issue