Games Engineering - Principles of Software Engineering PDF
Document Details
Uploaded by StrongestQuail
University of Warwick
Prof. Kurt Debattista
Tags
Related
- Simplified Guide for AEs: Software Engineering, DevOps, and Cybersecurity PDF
- original_1489125567_Chapter_1_Introduction_to_software_product_engineering.pdf
- Chapter 2: Software Engineering Lifecycle PDF
- Advanced Software Engineering (Software Engineering 2) Lecture Notes PDF
- Larman 2004 - Chapter 8: XP PDF
- W02 C++ Libraries PDF
Summary
This document is a set of lecture notes on software engineering principles, particularly focused on games development. It covers fundamental concepts like object-oriented programming (OOP), design patterns, and introduces an interesting example on random walk simulation.
Full Transcript
Games Engineering Principles of Software Engineering Prof. Kurt Debattista Introduction Practical guide to games engineering Will not delve deeply into theory – Describe good practice – Give you overall intuition – Make your coding life easier Overview OOP Problem / Solution Design Pattern...
Games Engineering Principles of Software Engineering Prof. Kurt Debattista Introduction Practical guide to games engineering Will not delve deeply into theory – Describe good practice – Give you overall intuition – Make your coding life easier Overview OOP Problem / Solution Design Patterns SE Principles OOP Overview Object Oriented Design with Applications – (1991) Grady Booch Object-Oriented Programming – Abstraction – Encapsulation – Hierarchy – Polymorphism Abstraction Define aspects of the computation as objects “An abstraction denotes the essential characteristics of an object that distinguishes it from all other kinds of objects and thus provide crisply defined conceptual boundaries, relative to the perspective of the view” Booch Image Courtesy of Booch et al. (2007) Encapsulation Bind data and operations together Each class must have – Interface – Implementation Information hiding Enforce modularity Image Courtesy of Booch et al. (2007) Reduce coupling “for abstractions to work implementations must be encapsulated” Liskov Hierarchy Organisation that reflects relationships – Inheritance – Composition Simplify code Promote clarity Represent real world relationships Polymorphism Polymorphism means “many shapes” Objects respond to operations based on type Extend with new behaviours – Without modifying existing behaviours Other Principles Modularity – Architected of loosely coupled modules Reusability – Encourage component reuse Dynamic Binding – Called methods determined at run time Random Walk Problem In this problem you will simulate the movements of a robot in a field. For simplicity we will allow the robot to move along a Cartesian grid. The robot’s movement is defined by the movement chip. There are different types of movement chips. Also, there are different types of fields that the robot moves along. Your goal is to provide a simulation which determines how far from the original location the robot is after a certain number of time steps T when: a) the field is uniform; the movement chip randomly selects one direction from the compass at each step b) the field is uniform; the movement chip randomly selects one direction from East or West c) the field is uniform; the movement chip selects South twice as often as the other directions d) the field has a warp space along the diagonals - if the robot touches one of the diagonals it is sent back to the start; movement chip as in a) e) the field is slanting in the west - every step taken by the robot moves it by 1 extra step towards the west; movement chip as in a) f) the robot only moves towards the east g) the field does not permit movement to the north; the robot goes north three times as often as the other directions h) the robot takes two steps at a time in any given direction i) the robot can move along the diagonals, the field flips co-ordinates 10% of the time Discussion Random Walk Base version: the field is uniform; the movement chip randomly selects one direction from the compass at each step Robot options: 1. N, S, E, W movement 2. N 3 times more often 3. 2 steps in each direction 4. E, W only 5. Can move onto diagonals Field options: 1. uniform 2. diagonal send back to centre 3. slanting west 4. field no north movement 5. field flips axes Coding – Use location.h if you want Abstraction Classes abstract functionality – Location – Movement – Robot – Field – Simulation Interact without knowing implementation details Encapsulation Classes protected data Allow controlled access – Robot grants access to location Internal implementations can be changed – Eg movement can be changed how? Hierarchy Inheritance – movement – Field Composition – Robot and movement – Simulation with field and robot Clear modular design Polymorphism Virtual functions – movement::move() – field::moveInFIield() Dynamic changes at run time via pointer Simulation can run different types Simplifies changes to movement and field – Flexible – Extensible Concept Application Benefit Base classes (movement, field) Simplifies interactions with Abstraction define interfaces, hiding complex types. implementation details. Private/protected members in Maintains object integrity and Encapsulation location, robot, etc., restrict flexibility. direct access. Inheritance (movement, field) Promotes code reuse and Hierarchy and composition (robot, modularity. simulation). Virtual methods in movement Polymorphism and field enable runtime behavior Adds flexibility and extensibility. changes. Concept Application Benefits Independent classes (robot, Simplifies development, Modularity movement, field, simulation). testing, and maintenance. Configurable components (location, movement and Promotes efficient use of Reusability field) reusable in different code and easy integration. contexts. Virtual methods (move, Enables extensibility and Dynamic Binding moveInField) ensure runtime flexibility. behaviour resolution. Design Patterns Following on from Booch OOP principles Design patterns – Design Patterns: Elements of Reusable Object-Oriented Software (1994) – Commonly know as Gang of Four – Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Foundational to software design – Address recurring problems in software development Pattern Description Abstract Factory Interface for creating families of related/dependent objects without specifying concrete classes. Builder Separates construction of a complex object from its representation. Factory Method Interface for creating an object, allowing subclasses to alter the type of object created. Prototype Creates new objects by copying an existing object (prototype). Singleton Ensures a class has only one instance and provides a global point of access. Adapter Converts an interface into one expected by clients. Bridge Decouples abstraction from implementation to allow independent variation. Composite Composes objects into tree structures to represent part-whole hierarchies. Decorator Adds responsibilities to an object dynamically. Facade Provides a unified interface to a set of interfaces in a subsystem. Flyweight Shares data to reduce memory costs of creating many similar objects. Proxy Provides a placeholder or surrogate to control access to another object. Chain of Responsibility Passes a request along a chain of handlers until one handles it. Command Encapsulates a request as an object, enabling parameterisation and queuing. Interpreter Defines a grammar and an interpreter to evaluate sentences in the language. Iterator Sequentially accesses elements of a collection without exposing its structure. Mediator Centralizes control over how objects interact, reducing direct dependencies. Memento Captures and restores an object's state without violating encapsulation. Observer Defines a one-to-many dependency to notify observers of state changes. State Alters an object’s behavior when its internal state changes. Strategy Encapsulates interchangeable algorithms and allows their selection at runtime. Template Method Defines the structure of an algorithm, deferring steps to subclasses. Visitor Adds new operations to objects without modifying their classes. Pattern Description Abstract Factory Interface for creating families of related/dependent objects without specifying concrete classes. Builder Separates construction of a complex object from its representation. Factory Method Interface for creating an object, allowing subclasses to alter the type of object created. Prototype Creates new objects by copying an existing object (prototype). Singleton Ensures a class has only one instance and provides a global point of access. Adapter Converts an interface into one expected by clients. Bridge Decouples abstraction from implementation to allow independent variation. Composite Composes objects into tree structures to represent part-whole hierarchies. Decorator Adds responsibilities to an object dynamically. Façade Provides a unified interface to a set of interfaces in a subsystem. Flyweight Shares data to reduce memory costs of creating many similar objects. Proxy Provides a placeholder or surrogate to control access to another object. Chain of Responsibility Passes a request along a chain of handlers until one handles it. Command Encapsulates a request as an object, enabling parameterisation and queuing. Interpreter Defines a grammar and an interpreter to evaluate sentences in the language. Iterator Sequentially accesses elements of a collection without exposing its structure. Mediator Centralises control over how objects interact, reducing direct dependencies. Memento Captures and restores an object's state without violating encapsulation. Observer Defines a one-to-many dependency to notify observers of state changes. State Alters an object’s behaviour when its internal state changes. Strategy Encapsulates interchangeable algorithms and allows their selection at runtime. Template Method Defines the structure of an algorithm, deferring steps to subclasses. Visitor Adds new operations to objects without modifying their classes. Pattern Description Abstract Factory Interface for creating families of related/dependent objects without specifying concrete classes. Builder Separates construction of a complex object from its representation. Factory Method Interface for creating an object, allowing subclasses to alter the type of object created. Prototype Creates new objects by copying an existing object (prototype). Singleton Ensures a class has only one instance and provides a global point of access. Adapter Converts an interface into one expected by clients. Bridge Decouples abstraction from implementation to allow independent variation. Composite Composes objects into tree structures to represent part-whole hierarchies. Decorator Adds responsibilities to an object dynamically. Façade Provides a unified interface to a set of interfaces in a subsystem. Flyweight Shares data to reduce memory costs of creating many similar objects. Proxy Provides a placeholder or surrogate to control access to another object. Chain of Responsibility Passes a request along a chain of handlers until one handles it. Command Encapsulates a request as an object, enabling parameterisation and queuing. Interpreter Defines a grammar and an interpreter to evaluate sentences in the language. Iterator Sequentially accesses elements of a collection without exposing its structure. Mediator Centralises control over how objects interact, reducing direct dependencies. Memento Captures and restores an object's state without violating encapsulation. Observer Defines a one-to-many dependency to notify observers of state changes. State Alters an object’s behaviour when its internal state changes. Strategy Encapsulates interchangeable algorithms and allows their selection at runtime. Template Method Defines the structure of an algorithm, deferring steps to subclasses. Visitor Adds new operations to objects without modifying their classes. Pattern Description Abstract Factory Interface for creating families of related/dependent objects without specifying concrete classes. Builder Separates construction of a complex object from its representation. Factory Method Interface for creating an object, allowing subclasses to alter the type of object created. Prototype Creates new objects by copying an existing object (prototype). Singleton Ensures a class has only one instance and provides a global point of access. Adapter Converts an interface into one expected by clients. Bridge Decouples abstraction from implementation to allow independent variation. Composite Composes objects into tree structures to represent part-whole hierarchies. Decorator Adds responsibilities to an object dynamically. Façade Provides a unified interface to a set of interfaces in a subsystem. Flyweight Shares data to reduce memory costs of creating many similar objects. Proxy Provides a placeholder or surrogate to control access to another object. Chain of Responsibility Passes a request along a chain of handlers until one handles it. Command Encapsulates a request as an object, enabling parameterisation and queuing. Interpreter Defines a grammar and an interpreter to evaluate sentences in the language. Iterator Sequentially accesses elements of a collection without exposing its structure. Mediator Centralises control over how objects interact, reducing direct dependencies. Memento Captures and restores an object's state without violating encapsulation. Observer Defines a one-to-many dependency to notify observers of state changes. State Alters an object’s behaviour when its internal state changes. Strategy Encapsulates interchangeable algorithms and allows their selection at runtime. Template Method Defines the structure of an algorithm, deferring steps to subclasses. Visitor Adds new operations to objects without modifying their classes. Pattern Description Abstract Factory Interface for creating families of related/dependent objects without specifying concrete classes. Builder Separates construction of a complex object from its representation. Factory Method Interface for creating an object, allowing subclasses to alter the type of object created. Prototype Creates new objects by copying an existing object (prototype). Singleton Ensures a class has only one instance and provides a global point of access. Adapter Converts an interface into one expected by clients. Bridge Decouples abstraction from implementation to allow independent variation. Composite Composes objects into tree structures to represent part-whole hierarchies. Decorator Adds responsibilities to an object dynamically. Façade Provides a unified interface to a set of interfaces in a subsystem. Flyweight Shares data to reduce memory costs of creating many similar objects. Proxy Provides a placeholder or surrogate to control access to another object. Chain of Responsibility Passes a request along a chain of handlers until one handles it. Command Encapsulates a request as an object, enabling parameterisation and queuing. Interpreter Defines a grammar and an interpreter to evaluate sentences in the language. Iterator Sequentially accesses elements of a collection without exposing its structure. Mediator Centralises control over how objects interact, reducing direct dependencies. Memento Captures and restores an object's state without violating encapsulation. Observer Defines a one-to-many dependency to notify observers of state changes. State Alters an object’s behaviour when its internal state changes. Strategy Encapsulates interchangeable algorithms and allows their selection at runtime. Template Method Defines the structure of an algorithm, deferring steps to subclasses. Visitor Adds new operations to objects without modifying their classes. Singleton pattern class RandomEngine { public: static std::mt19937& getEngine() { static RandomEngine instance; return instance.engine; } private: std::mt19937 engine{ std::random_device{}() }; RandomEngine() = default; RandomEngine(const RandomEngine&) = delete; RandomEngine& operator=(const RandomEngine&) = delete; }; Singleton pattern Only one instance of RandomEngine RandomEngine::getEngine() controlled access Consistent random number generation Singleton pattern Single instance – Ensures only one instance exists – Global access Useful for managing global resources – Loggers – Configuration managers – Database connections – Game settings class GameSettings { public: static GameSettings& getInstance() { static GameSettings instance; // Lazy initialisation return instance; } // Prevent copying or assignment GameSettings(const GameSettings&) = delete; GameSettings& operator=(const GameSettings&) = delete; void set(const std::string& key, const std::string& value) { settings_[key] = value; } std::string get(const std::string& key) { return settings_[key]; } private: GameSettings() = default; // Private constructor std::unordered_map settings_; }; int main() { GameSettings::getInstance().set("Resolution", "1920x1080"); GameSettings::getInstance().set("Volume", "75"); std::cout