C++ for C Programmers by Ira Pohl!
Creating a C++11 class
“We can rewrite this array code to include to use new move semantics.”
l
C++ for C Programmers by Ira Pohl!
Array like class C++11
l In C++11 there is a sequential container class defined in <array> that specifies at compile time a fixed length array.
l We want to study how to code this and use the new C++11 “move semantics” for efficiency in dealing with aggregates.
C++ for C Programmers by Ira Pohl!
my_container
l template <class T, int n> l class my_container { l public: l my_container(){ a = new T[n];} l ~my_container{ delete[] a;} l private: l T* a; l };
C++ for C Programmers by Ira Pohl!
Quiz:
l What would the declaration my_container data<int, 5>;
produce?
C++ for C Programmers by Ira Pohl!
Some further constructors
l explicit my_container(T *b):my_container() l { l for(int i = 0; i <n ; ++i) l a[i] = b[i]; l }
l Suppress automatic coercion l Delegate construction – new C++11
C++ for C Programmers by Ira Pohl!
Constructor
l my_container(const my_container &b):my_container() l { l for(int i = 0; i <n ; ++i) l a[i] = b.a[i]; l } l Ordinary copy constructor –again with constructor
delegation
C++ for C Programmers by Ira Pohl!
Answer:
l Default - void signature l Conversion constructor – single argument l Copy constructor - const classType&
C++ for C Programmers by Ira Pohl!
“Move “ Constructor
l my_container(my_container &&b)noexcept l { l a = b.a; l b.a = nullptr; l }
l Contents are “moved” not copied l Note new use of && to mean an rvalue address
C++ for C Programmers by Ira Pohl!
Addresses & declarations
l a = b; //assignment a is on lhs b is on rhs l int& a = b; // a is an lvalue reference l int* ptr_a = &b; // ptr_a is address of b l int && b; //new declaration rvalue reference l A non-const lvalue reference binds to an
object l A rvalue reference binds to a temporary
object – that typically will not be used again.
C++ for C Programmers by Ira Pohl!
Associated assignment
l my_container& operator=(my_container&& b)noexcept l { l a = b.a; l b.a = nullptr; l return *this; l }
l Non-copying – move assignment; rhs destroyed
C++ for C Programmers by Ira Pohl!
Efficient swap
l void swap(my_container &b) l { l my_container temp = move(b); //will not be used l b = move(*this); l *this = move(temp); l } l The std::move() static_cast<T&&>(t) -destructive assignment l More efficient because all the assignments are referential
C++ for C Programmers by Ira Pohl!
Recommended exercise
l Add operator[](int index) to class to select ith element of the aggregate-must be non-static class method
l Add iterator logic
l Gives you an idea about how to produce an STL container
C++ for C Programmers by Ira Pohl!
Lookahead as a graph
l The standard model for strategy games involves tree lookahead
l A goes here , B goes there, continue until the position can be evaluated.
l Evaluate at the leaf nodes and backup the score
C++ for C Programmers by Ira Pohl!
Terminology
l Ply is depth of tree – example had two ply
l Branch rate – before nodes branched at 1-3 l normally this is > 1 and then leaf nodes are exponential in ply and branching rate - recall for a full binary tree of depth n – there are 2 ** n leaf nodes (how many internal nodes)
l Practically – you need to decide how much of a tree you can explore – typically this is constrained in game play to what is reasonable (in professional chess or scrabble – there is a timer)
C++ for C Programmers by Ira Pohl!
Quiz:
l [ ] MAX l / | \ l [ ] [ ] [ ] MIN l / \ | / | \ l [ ] 1 [ ] 7 [ ] [ ] l / \ / | | | l 2 5 6 1 3 9
C++ for C Programmers by Ira Pohl!
Plausible Move Generator
l When the number of moves is large – we use game heuristics
l To limit the number of moves to analyze- l Eg - in chess average branching rate 40 moves per ply l Early programs examined <10 moves – eg checks,
captures, l Development … l In Hex – on 11 by 11 can have as many as 121 moves
initially and – game generally last 20 moves per player –
l So even near end of game >60 legal moves
C++ for C Programmers by Ira Pohl!
Hex
1. Can I make a winning move – 2. Can I block or prevent a winning move 3. Can I extend my longest partial path? 4. Can I block my opponents longest path 5. Can I extend or make a bridge move from a
path 6. Can I move to a row(column) that I do not
occupy
C++ for C Programmers by Ira Pohl!
Evaluation
l Simplest – who won (or in tic tac toe, chess –draw)
l Checkmate, made a path, in backgammon brought home my men
C++ for C Programmers by Ira Pohl!
Usual Model
l Move generation
l Look ahead (min-max/ alpha-beta/monte-carlo)
l Evaluation of static positions l in checker or chess material count, in backgammon l Points made – count in the race
l in Hex --- how near to completing a path? l eg – initially 11 -
C++ for C Programmers by Ira Pohl!
Next : alpha-beta algorithm
l For the moment – some plausible move generation l And simple evaluation of resulting move – selecting the best l Read about min-max and alpha-beta in wikipedia
C++ for C Programmers by Ira Pohl!
alpha-beta and Polish
l Alpha-beta algorithm
l Polish and virtual functions
C++ for C Programmers by Ira Pohl!
Don Knuth – greatest Living Algorithms, Programming Whiz Stanford
C++ for C Programmers by Ira Pohl!
Achievements of D Knuth
l Art of Computation vol. 1-3 – Bible of CS
l TEX - computer typesetting language
l Analysis of …. Alpha-beta, sorting adversaries,…
l LR parsing
C++ for C Programmers by Ira Pohl!
Maximizer/Minimizer
l Leaf nodes are evaluated on a scale l for example large negative value minimizer
is likely to win
l large positive value maximizer is likely to win
l Values are backed up the tree – alternate max and min
C++ for C Programmers by Ira Pohl!
Alpha-Beta improvement to min-max
l Cut off of any node –passed eval of 4
C++ for C Programmers by Ira Pohl!
Alpha-beta
l Maximizer – “i can at least get alpha”
l Minimizer - “i can at least get beta”
l Optimum is when best moves are being considered
C++ for C Programmers by Ira Pohl!
Quiz: Perform alpha-beta showing cutoffs
l Max [ ] l / | \ l Min [ ] [ ] [ ] l / | / | \ | \ l [ ] [ ] [ ] [ ] [ ] [ ] [ ] l / \ / | \ / | | | \ | \ / | \ l 4 5 7 3 8 8 4 3 9 5 3 4 5 4 7
C++ for C Programmers by Ira Pohl!
Answer: alpha-beta showing cutoffs
l Max [5] l / | \ l Min [ 5] [ 3*] [ 4* ] l / | / | \ | \ l [ 5] [7*] [8] [ 3 ] [ *] [ 4] [*] l / \ / | \ / | | | \ | \ / | \ l 4 5 7 3 8 8 4 3 9 5 3 4 5 4 7
C++ for C Programmers by Ira Pohl!
Examples of reverse polish
l (9 + 6) * (3 – 2) l 9,6, +, 3, 2, -, * -parenthesis free l Usually evaluated with a stack l Place 9 and 6 on operand stack l Do binary plus – result is 15 l Place 3 and 2 on operand stack l Do binary minus- result is one l Do multiply – result is 15
C++ for C Programmers by Ira Pohl!
An expression evaluation tree
l We will build using a hierarchy – a tree for evaluating expressions ;
l This will make use of an “inheritance” architecture and virtual functions
l Method coded in C++ by Andrew Koenig- a critical contributer to the C++ language design and use
C++ for C Programmers by Ira Pohl!
Reverse Polish –answer
l Expression tree (9 * 6) – 25 /5= l 39/5 = 7.8 [if double]
C++ for C Programmers by Ira Pohl!
Referential GC
l Rather than a full copy – we maintain pointers to an aggregate – and a use counter
l When the use (reference count) goes to zero – we actually call delete on an object
l When we create a new instance –use is initialized to 1
C++ for C Programmers by Ira Pohl!
Node- Abstract Base Class
l class Node { l friend class Tree; l friend ostream& operator<<(ostream&, const Tree&); l int use; //reference count -GC l protected: l Node(){ use = 1; } l virtual void print(ostream&) = 0; //pure virtual l virtual ~Node() {} //note virtual destructor l virtual int eval() = 0; l };
C++ for C Programmers by Ira Pohl!
Tree
l class Tree { l friend class Node; //okay –between kissing cousins l friend ostream& operator<<(ostream&, const Tree&); l Node* p; //polymorphic hierarchy l public: l Tree(int); //constant l Tree(char); //variable l Tree(char*, Tree); //unary operator l Tree(char*, Tree, Tree); //binary operator l Tree(const Tree& t) { p = t.p; ++p -> use;} l ~Tree() {if (--p ->use == 0) delete p; } l void operator=(const Tree& t); l int eval() {return p->eval();} l };
C++ for C Programmers by Ira Pohl!
Note in last slide
l Tree(const Tree& t) { p = t.p; ++p -> use;} l ~Tree() {if (--p ->use == 0) delete p; }
l The critical idea in referencial copying and GC as reflected in the copy constructor and the destructor
C++ for C Programmers by Ira Pohl!
Polymorphic print
l ostream& operator<<(ostream& o, const Tree& t) l { l t.p -> print(o); l return (o); l } l t.p is pointer that selects appropriate virtual function
C++ for C Programmers by Ira Pohl!
Abstract base class = 0 notation
l class LeafNode: public Node { l friend class Tree; l void print(ostream& o) = 0; l virtual int eval() = 0; l };
C++ for C Programmers by Ira Pohl!
Simple int
l class IntNode: public LeafNode { l friend class Tree; l int n; l void print(ostream& o) { o << n ;} l IntNode(int k): n (k) {} l public: l int eval(){ return n;} l };
C++ for C Programmers by Ira Pohl!
variable
l class IdNode: public LeafNode { l friend class Tree; l char name; l void print(ostream& o) { o << name ;} l IdNode(char id): name (id) {} l public: l int eval(){ return valtab[name];} l };
C++ for C Programmers by Ira Pohl!
Unary node
l class UnaryNode: public Node { l friend class Tree; l char* op; l Tree opnd; l UnaryNode(char* a, Tree b): op(a), opnd(b) {} l void print (ostream& o) {o << "(" << op << opnd << ")";} l public: l int eval(); l };
C++ for C Programmers by Ira Pohl!
Unary evaluation
l int UnaryNode::eval() l { l switch (op[0]){ l case '-': return (-opnd.eval()); l case '+': return (+opnd.eval()); l default: cerr << "no operand\n" << endl; l return 0; l } l }
C++ for C Programmers by Ira Pohl!
Binary op
l class BinaryNode: public Node { l friend class Tree; l char* op; l Tree left; l Tree right; l BinaryNode(char* a, Tree b, Tree c): op(a), left(b), right(c){} l void print (ostream& o) {o << "(" << left << op << right << ")";} l public: l int eval(); l };
C++ for C Programmers by Ira Pohl!
Binary eval
l int BinaryNode::eval() l { l switch (op[0]){ l case '-': return (left.eval() - right.eval()); l case '+': return (left.eval() + right.eval()); l case '*': return (left.eval() * right.eval()); l default: cerr << "no operand\n" << endl; l return 0; l } l }
C++ for C Programmers by Ira Pohl!
Tree constructors
l Tree::Tree(int n) l { p = new IntNode(n);}
l Tree::Tree(char id) l { p = new IdNode(id);}
l Tree::Tree(char* op, Tree t) l { p = new UnaryNode(op, t);}
l Tree::Tree(char* op, Tree left, Tree right) l { p = new BinaryNode(op, left, right);}
C++ for C Programmers by Ira Pohl!
Build the tree and evaluate
l int main() l { l l valtab['A'] = 3; valtab['B'] = 4; l cout << "A = 3, B = 4" << endl; l Tree t1 = Tree("*", Tree("-", 5), Tree("+", 'A', 4)); l Tree t2 = Tree("+", Tree("-", 'A', 1), Tree("+", t1, 'B')); l cout << "t1 = " << t1 << " ; t2 = " << t2 << endl; l cout << "t1:" << t1.eval() << " t2:" << t2.eval() << endl; l }
C++ for C Programmers by Ira Pohl!
Quiz: what was printed by main() ?
l valtab['A'] = 3; valtab['B'] = 4; l cout << "A = 3, B = 4" << endl; l Tree t1 = Tree("*", Tree("-", 5), Tree("+", 'A', 4)); l Tree t2 = Tree("+", Tree("-", 'A', 1), Tree("+", t1, 'B')); l cout << "t1 = " << t1 << " ; t2 = " << t2 << endl; l cout << "t1:" << t1.eval() << " t2:" << t2.eval() << endl;
C++ for C Programmers by Ira Pohl!
Answer: What was printed by main() ?
l valtab['A'] = 3; valtab['B'] = 4; l cout << "A = 3, B = 4" << endl; l Tree t1 = Tree("*", Tree("-", 5), Tree("+", 'A', 4)); l Tree t2 = Tree("+", Tree("-", 'A', 1), Tree("+", t1, 'B')); l cout << "t1 = " << t1 << " ; t2 = " << t2 << endl; l cout << "t1:" << t1.eval() << " t2:" << t2.eval() << endl; l A = 3, B = 4 l t1 = ((-5)*(A + 4)) ; t2 = ((A -1)+((((-5)*(A + 4)) +B)) l t1:-35 t2:-29