0% found this document useful (0 votes)
25 views66 pages

Programming: Principles and Practice Using C++, Second Edition Stroustrup Full Chapters Included

The document provides information about the book 'Programming: Principles and Practice Using C++, Second Edition' by Bjarne Stroustrup, which is set for release in 2025 and has received a high rating of 4.7/5.0 from users. It includes details about available formats, additional related textbooks, and a comprehensive table of contents covering various programming concepts. The document also emphasizes the book's educational value and reliability for learners in programming.

Uploaded by

kralik0555romy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views66 pages

Programming: Principles and Practice Using C++, Second Edition Stroustrup Full Chapters Included

The document provides information about the book 'Programming: Principles and Practice Using C++, Second Edition' by Bjarne Stroustrup, which is set for release in 2025 and has received a high rating of 4.7/5.0 from users. It includes details about available formats, additional related textbooks, and a comprehensive table of contents covering various programming concepts. The document also emphasizes the book's educational value and reliability for learners in programming.

Uploaded by

kralik0555romy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

https://textbookfull.

com

https://textbookfull.com/product/programming-principles-and-practice-using-
c-second-edition-stroustrup/

UPDATED: OCT 2025

Programming: Principles and


Practice Using C++ , Second
Edition Stroustrup

Most Recent Release 2025

★★★★★ 4.7/5.0 - 931 downloads

'One of the best resources for my course.' - Robert W.

Get PDF Instantly

100% Reliable Results


Programming: Principles and Practice Using C++ , Second
Edition Stroustrup

TEXTBOOK

Available Formats

■ PDF eBook Study Guide Ebook

EXCLUSIVE 2025 ACADEMIC EDITION – LIMITED RELEASE

Available Instantly Access Library


Editor's Choice

Programming Principles and Practice Using C 3rd Edition


Stroustrup
Link Product: https://textbookfull.com/product/programming-princi
ples-and-practice-using-c-3rd-edition-stroustrup/

Programming Principles and Practice Using C Third Edition


Bjarne Stroustrup
Link Product: https://textbookfull.com/product/programming-princi
ples-and-practice-using-c-third-edition-bjarne-stroustrup/

Primary Mathematics Textbook 2B Jennifer Hoerst


Link Product: https://textbookfull.com/product/primary-mathematic
s-textbook-2b-jennifer-hoerst/

Handbook of Macroeconomics, Volume 2A-2B SET 1st Edition


John B. Taylor
Link Product: https://textbookfull.com/product/handbook-of-macro
economics-volume-2a-2b-set-1st-edition-john-b-taylor/
A Tour of C++ Stroustrup
Link Product: https://textbookfull.com/product/a-tour-of-c-stroustru
p/

A Tour of C++ Stroustrup


Link Product: https://textbookfull.com/product/a-tour-of-c-stroustru
p-2/

Biota Grow 2C gather 2C cook Loucas


Link Product: https://textbookfull.com/product/biota-grow-2c-gathe
r-2c-cook-loucas/

A Tour of C 3rd Edition Stroustrup B.


Link Product: https://textbookfull.com/product/a-tour-of-c-3rd-editi
on-stroustrup-b/

Tour of C A C In Depth Series 3rd Edition Stroustrup


Link Product: https://textbookfull.com/product/tour-of-c-a-c-in-dept
h-series-3rd-edition-stroustrup/
About This eBook

ePUB is an open, industry-standard format for eBooks. However,


support of ePUB and its many features varies across reading devices
and applications. Use your device or app settings to customize the
presentation to your liking. Settings that you can customize often
include font, font size, single or double column, landscape or portrait
mode, and figures that you can click or tap to enlarge. For additional
information about the settings and features on your reading device
or app, visit the device manufacturer’s Web site.
Many titles include programming code or configuration examples.
To optimize the presentation of these elements, view the eBook in
single-column, landscape mode and adjust the font size to the
smallest setting. In addition to presenting code and configurations in
the reflowable text format, we have included images of the code
that mimic the presentation found in the print book; therefore,
where the reflowable format may compromise the presentation of
the code listing, you will see a “Click here to view code image” link.
Click the link to view the print-fidelity code image. To return to the
previous page viewed, click the Back button on your device or app.
Programming: Principles and
Practice Using C++
Second Edition

Bjarne Stroustrup

Upper Saddle River, NJ • Boston • Indianapolis • San Francisco


New York • Toronto • Montreal • London • Munich • Paris • Madrid
Capetown • Sydney • Tokyo • Singapore • Mexico City
Many of the designations used by manufacturers and sellers to
distinguish their products are claimed as trademarks. Where those
designations appear in this book, and the publisher was aware of a
trademark claim, the designations have been printed with initial
capital letters or in all capitals.
A complete list of photo sources and credits appears on pages 1273–
1274.
The author and publisher have taken care in the preparation of this
book, but make no expressed or implied warranty of any kind and
assume no responsibility for errors or omissions. No liability is
assumed for incidental or consequential damages in connection with
or arising out of the use of the information or programs contained
herein.
For information about buying this title in bulk quantities, or for
special sales opportunities (which may include electronic versions;
custom cover designs; and content particular to your business,
training goals, marketing focus, or branding interests), please
contact our corporate sales department at
[email protected] or (800) 382-3419.
For government sales inquiries, please contact
[email protected].
For questions about sales outside the United States, please contact
[email protected].
Visit us on the Web: informit.com/aw
Library of Congress Cataloging-in-Publication Data
Stroustrup, Bjarne, author.
Programming : principles and practice using C++ / Bjarne
Stroustrup. — Second edition.
pages cm
Includes bibliographical references and index.
ISBN 978-0-321-99278-9 (pbk. : alk. paper)
1. C++ (Computer program language) I. Title.
QA76.73.C153S82 2014
005.13'3—dc23

2014004197
Copyright © 2014 Pearson Education, Inc.
All rights reserved. Printed in the United States of America. This
publication is protected by copyright, and permission must be
obtained from the publisher prior to any prohibited reproduction,
storage in a retrieval system, or transmission in any form or by any
means, electronic, mechanical, photocopying, recording, or likewise.
To obtain permission to use material from this work, please submit a
written request to Pearson Education, Inc., Permissions Department,
One Lake Street, Upper Saddle River, New Jersey 07458, or you may
fax your request to (201) 236-3290.
ISBN-13: 978-0-321-99278-9
ISBN-10: 0-321-99278-4
Text printed in the United States on recycled paper at RR Donnelley
in Crawfordsville, Indiana.
First printing, May 2014
Discover thousands of test banks and solution manuals at
https://textbookfull.com – and enjoy exclusive offers today.
Contents

Preface
Chapter 0 Notes to the Reader
0.1 The structure of this book
0.1.1 General approach
0.1.2 Drills, exercises, etc.
0.1.3 What comes after this book?
0.2 A philosophy of teaching and learning
0.2.1 The order of topics
0.2.2 Programming and programming language
0.2.3 Portability
0.3 Programming and computer science
0.4 Creativity and problem solving
0.5 Request for feedback
0.6 References
0.7 Biographies
Bjarne Stroustrup
Lawrence “Pete” Petersen
Chapter 1 Computers, People, and Programming
1.1 Introduction
1.2 Software
1.3 People
1.4 Computer science
1.5 Computers are everywhere
1.5.1 Screens and no screens
1.5.2 Shipping
1.5.3 Telecommunications
1.5.4 Medicine
1.5.5 Information
1.5.6 A vertical view
1.5.7 So what?
1.6 Ideals for programmers

Part I The Basics


Chapter 2 Hello, World!
2.1 Programs
2.2 The classic first program
2.3 Compilation
2.4 Linking
2.5 Programming environments
Chapter 3 Objects, Types, and Values
3.1 Input
3.2 Variables
3.3 Input and type
3.4 Operations and operators
3.5 Assignment and initialization
3.5.1 An example: detect repeated words
3.6 Composite assignment operators
3.6.1 An example: find repeated words
3.7 Names
3.8 Types and objects
3.9 Type safety
3.9.1 Safe conversions
3.9.2 Unsafe conversions
Chapter 4 Computation
4.1 Computation
4.2 Objectives and tools
4.3 Expressions
4.3.1 Constant expressions
4.3.2 Operators
4.3.3 Conversions
4.4 Statements
4.4.1 Selection
4.4.2 Iteration
4.5 Functions
4.5.1 Why bother with functions?
4.5.2 Function declarations
4.6 vector
4.6.1 Traversing a vector
4.6.2 Growing a vector
4.6.3 A numeric example
4.6.4 A text example
4.7 Language features
Chapter 5 Errors
5.1 Introduction
5.2 Sources of errors
5.3 Compile-time errors
5.3.1 Syntax errors
5.3.2 Type errors
5.3.3 Non-errors
5.4 Link-time errors
5.5 Run-time errors
5.5.1 The caller deals with errors
5.5.2 The callee deals with errors
5.5.3 Error reporting
5.6 Exceptions
5.6.1 Bad arguments
5.6.2 Range errors
5.6.3 Bad input
5.6.4 Narrowing errors
5.7 Logic errors
5.8 Estimation
5.9 Debugging
5.9.1 Practical debug advice
5.10 Pre- and post-conditions
5.10.1 Post-conditions
5.11 Testing
Chapter 6 Writing a Program
6.1 A problem
6.2 Thinking about the problem
6.2.1 Stages of development
6.2.2 Strategy
6.3 Back to the calculator!
6.3.1 First attempt
6.3.2 Tokens
6.3.3 Implementing tokens
6.3.4 Using tokens
6.3.5 Back to the drawing board
6.4 Grammars
6.4.1 A detour: English grammar
6.4.2 Writing a grammar
6.5 Turning a grammar into code
6.5.1 Implementing grammar rules
6.5.2 Expressions
6.5.3 Terms
6.5.4 Primary expressions
6.6 Trying the first version
6.7 Trying the second version
6.8 Token streams
6.8.1 Implementing Token_stream
6.8.2 Reading tokens
6.8.3 Reading numbers
6.9 Program structure
Chapter 7 Completing a Program
7.1 Introduction
7.2 Input and output
7.3 Error handling
7.4 Negative numbers
7.5 Remainder: %
7.6 Cleaning up the code
7.6.1 Symbolic constants
7.6.2 Use of functions
7.6.3 Code layout
7.6.4 Commenting
7.7 Recovering from errors
7.8 Variables
7.8.1 Variables and definitions
7.8.2 Introducing names
7.8.3 Predefined names
Visit https://textbookfull.com now to find academic
resources, test banks, and solution manuals at great prices.
7.8.4 Are we there yet?
Chapter 8 Technicalities: Functions, etc.
8.1 Technicalities
8.2 Declarations and definitions
8.2.1 Kinds of declarations
8.2.2 Variable and constant declarations
8.2.3 Default initialization
8.3 Header files
8.4 Scope
8.5 Function call and return
8.5.1 Declaring arguments and return type
8.5.2 Returning a value
8.5.3 Pass-by-value
8.5.4 Pass-by-const-reference
8.5.5 Pass-by-reference
8.5.6 Pass-by-value vs. pass-by-reference
8.5.7 Argument checking and conversion
8.5.8 Function call implementation
8.5.9 constexpr functions
8.6 Order of evaluation
8.6.1 Expression evaluation
8.6.2 Global initialization
8.7 Namespaces
8.7.1 using declarations and using directives
Chapter 9 Technicalities: Classes, etc.
9.1 User-defined types
9.2 Classes and members
9.3 Interface and implementation
9.4 Evolving a class
9.4.1 struct and functions
9.4.2 Member functions and constructors
9.4.3 Keep details private
9.4.4 Defining member functions
9.4.5 Referring to the current object
9.4.6 Reporting errors
9.5 Enumerations
9.5.1 “Plain” enumerations
9.6 Operator overloading
9.7 Class interfaces
9.7.1 Argument types
9.7.2 Copying
9.7.3 Default constructors
9.7.4 const member functions
9.7.5 Members and “helper functions”
9.8 The Date class

Part II Input and Output


Chapter 10 Input and Output Streams
10.1 Input and output
10.2 The I/O stream model
10.3 Files
10.4 Opening a file
10.5 Reading and writing a file
10.6 I/O error handling
10.7 Reading a single value
10.7.1 Breaking the problem into manageable parts
10.7.2 Separating dialog from function
10.8 User-defined output operators
10.9 User-defined input operators
10.10 A standard input loop
10.11 Reading a structured file
10.11.1 In-memory representation
10.11.2 Reading structured values
10.11.3 Changing representations
Chapter 11 Customizing Input and Output
11.1 Regularity and irregularity
11.2 Output formatting
11.2.1 Integer output
11.2.2 Integer input
11.2.3 Floating-point output
11.2.4 Precision
11.2.5 Fields
11.3 File opening and positioning
11.3.1 File open modes
11.3.2 Binary files
11.3.3 Positioning in files
11.4 String streams
11.5 Line-oriented input
11.6 Character classification
11.7 Using nonstandard separators
11.8 And there is so much more
Chapter 12 A Display Model
12.1 Why graphics?
12.2 A display model
12.3 A first example
12.4 Using a GUI library
12.5 Coordinates
12.6 Shapes
12.7 Using Shape primitives
12.7.1 Graphics headers and main
12.7.2 An almost blank window
12.7.3 Axis
12.7.4 Graphing a function
12.7.5 Polygons
12.7.6 Rectangles
12.7.7 Fill
12.7.8 Text
12.7.9 Images
12.7.10 And much more
12.8 Getting this to run
12.8.1 Source files
Chapter 13 Graphics Classes
13.1 Overview of graphics classes
13.2 Point and Line
13.3 Lines
13.4 Color
13.5 Line_style
13.6 Open_polyline
13.7 Closed_polyline
13.8 Polygon
13.9 Rectangle
13.10 Managing unnamed objects
13.11 Text
13.12 Circle
13.13 Ellipse
13.14 Marked_polyline
13.15 Marks
13.16 Mark
13.17 Images
Chapter 14 Graphics Class Design
14.1 Design principles
14.1.1 Types
14.1.2 Operations
14.1.3 Naming
14.1.4 Mutability
14.2 Shape
14.2.1 An abstract class
14.2.2 Access control
14.2.3 Drawing shapes
14.2.4 Copying and mutability
14.3 Base and derived classes
14.3.1 Object layout
14.3.2 Deriving classes and defining virtual functions
14.3.3 Overriding
14.3.4 Access
14.3.5 Pure virtual functions
14.4 Benefits of object-oriented programming
Chapter 15 Graphing Functions and Data
15.1 Introduction
15.2 Graphing simple functions
15.3 Function
Explore https://textbookfull.com now to access a wide range
of test banks, solution manuals, and special promotions.
15.3.1 Default Arguments
15.3.2 More examples
15.3.3 Lambda expressions
15.4 Axis
15.5 Approximation
15.6 Graphing data
15.6.1 Reading a file
15.6.2 General layout
15.6.3 Scaling data
15.6.4 Building the graph
Chapter 16 Graphical User Interfaces
16.1 User interface alternatives
16.2 The “Next” button
16.3 A simple window
16.3.1 A callback function
16.3.2 A wait loop
16.3.3 A lambda expression as a callback
16.4 Button and other Widgets
16.4.1 Widgets
16.4.2 Buttons
16.4.3 In_box and Out_box
16.4.4 Menus
16.5 An example
16.6 Control inversion
16.7 Adding a menu
16.8 Debugging GUI code

Part III Data and Algorithms


Chapter 17 Vector and Free Store
17.1 Introduction
17.2 vector basics
17.3 Memory, addresses, and pointers
17.3.1 The sizeof operator
17.4 Free store and pointers
17.4.1 Free-store allocation
17.4.2 Access through pointers
17.4.3 Ranges
17.4.4 Initialization
17.4.5 The null pointer
17.4.6 Free-store deallocation
17.5 Destructors
17.5.1 Generated destructors
17.5.2 Destructors and free store
17.6 Access to elements
17.7 Pointers to class objects
17.8 Messing with types: void* and casts
17.9 Pointers and references
17.9.1 Pointer and reference parameters
17.9.2 Pointers, references, and inheritance
17.9.3 An example: lists
17.9.4 List operations
17.9.5 List use
17.10 The this pointer
17.10.1 More link use
Chapter 18 Vectors and Arrays
18.1 Introduction
18.2 Initialization
18.3 Copying
18.3.1 Copy constructors
18.3.2 Copy assignments
18.3.3 Copy terminology
18.3.4 Moving
18.4 Essential operations
18.4.1 Explicit constructors
18.4.2 Debugging constructors and destructors
18.5 Access to vector elements
18.5.1 Overloading on const
18.6 Arrays
18.6.1 Pointers to array elements
18.6.2 Pointers and arrays
18.6.3 Array initialization
18.6.4 Pointer problems
18.7 Examples: palindrome
18.7.1 Palindromes using string
18.7.2 Palindromes using arrays
18.7.3 Palindromes using pointers
Chapter 19 Vector, Templates, and Exceptions
19.1 The problems
19.2 Changing size
19.2.1 Representation
19.2.2 reserve and capacity
19.2.3 resize
19.2.4 push_back
19.2.5 Assignment
19.2.6 Our vector so far
19.3 Templates
19.3.1 Types as template parameters
19.3.2 Generic programming
19.3.3 Concepts
19.3.4 Containers and inheritance
19.3.5 Integers as template parameters
19.3.6 Template argument deduction
19.3.7 Generalizing vector
19.4 Range checking and exceptions
19.4.1 An aside: design considerations
19.4.2 A confession: macros
19.5 Resources and exceptions
19.5.1 Potential resource management problems
19.5.2 Resource acquisition is initialization
19.5.3 Guarantees
19.5.4 unique_ptr
19.5.5 Return by moving
19.5.6 RAII for vector
Chapter 20 Containers and Iterators
20.1 Storing and processing data
20.1.1 Working with data
20.1.2 Generalizing code
20.2 STL ideals
20.3 Sequences and iterators
20.3.1 Back to the example
20.4 Linked lists
20.4.1 List operations
20.4.2 Iteration
20.5 Generalizing vector yet again
20.5.1 Container traversal
20.5.2 auto
20.6 An example: a simple text editor
20.6.1 Lines
20.6.2 Iteration
20.7 vector, list, and string
20.7.1 insert and erase
20.8 Adapting our vector to the STL
20.9 Adapting built-in arrays to the STL
20.10 Container overview
20.10.1 Iterator categories
Chapter 21 Algorithms and Maps
21.1 Standard library algorithms
21.2 The simplest algorithm: find()
21.2.1 Some generic uses
21.3 The general search: find_if()
21.4 Function objects
21.4.1 An abstract view of function objects
21.4.2 Predicates on class members
21.4.3 Lambda expressions
21.5 Numerical algorithms
21.5.1 Accumulate
21.5.2 Generalizing accumulate()
21.5.3 Inner product
21.5.4 Generalizing inner_product()
21.6 Associative containers
21.6.1 map
21.6.2 map overview
Explore https://textbookfull.com now to access a wide range
of test banks, solution manuals, and special promotions.
21.6.3 Another map example
21.6.4 unordered_map
21.6.5 set
21.7 Copying
21.7.1 Copy
21.7.2 Stream iterators
21.7.3 Using a set to keep order
21.7.4 copy_if
21.8 Sorting and searching
21.9 Container algorithms

Part IV Broadening the View


Chapter 22 Ideals and History
22.1 History, ideals, and professionalism
22.1.1 Programming language aims and philosophies
22.1.2 Programming ideals
22.1.3 Styles/paradigms
22.2 Programming language history overview
22.2.1 The earliest languages
22.2.2 The roots of modern languages
22.2.3 The Algol family
22.2.4 Simula
22.2.5 C
22.2.6 C++
22.2.7 Today
22.2.8 Information sources
Chapter 23 Text Manipulation
23.1 Text
23.2 Strings
23.3 I/O streams
23.4 Maps
23.4.1 Implementation details
23.5 A problem
23.6 The idea of regular expressions
23.6.1 Raw string literals
23.7 Searching with regular expressions
23.8 Regular expression syntax
23.8.1 Characters and special characters
23.8.2 Character classes
23.8.3 Repeats
23.8.4 Grouping
23.8.5 Alternation
23.8.6 Character sets and ranges
23.8.7 Regular expression errors
23.9 Matching with regular expressions
23.10 References
Chapter 24 Numerics
24.1 Introduction
24.2 Size, precision, and overflow
24.2.1 Numeric limits
24.3 Arrays
24.4 C-style multidimensional arrays
24.5 The Matrix library
24.5.1 Dimensions and access
24.5.2 1D Matrix
24.5.3 2D Matrix
24.5.4 Matrix I/O
24.5.5 3D Matrix
24.6 An example: solving linear equations
24.6.1 Classical Gaussian elimination
24.6.2 Pivoting
24.6.3 Testing
24.7 Random numbers
24.8 The standard mathematical functions
24.9 Complex numbers
24.10 References
Chapter 25 Embedded Systems Programming
25.1 Embedded systems
25.2 Basic concepts
25.2.1 Predictability
25.2.2 Ideals
25.2.3 Living with failure
25.3 Memory management
25.3.1 Free-store problems
25.3.2 Alternatives to the general free store
25.3.3 Pool example
25.3.4 Stack example
25.4 Addresses, pointers, and arrays
25.4.1 Unchecked conversions
25.4.2 A problem: dysfunctional interfaces
25.4.3 A solution: an interface class
25.4.4 Inheritance and containers
25.5 Bits, bytes, and words
25.5.1 Bits and bit operations
25.5.2 bitset
25.5.3 Signed and unsigned
25.5.4 Bit manipulation
25.5.5 Bitfields
25.5.6 An example: simple encryption
25.6 Coding standards
25.6.1 What should a coding standard be?
25.6.2 Sample rules
25.6.3 Real coding standards
Chapter 26 Testing
26.1 What we want
26.1.1 Caveat
26.2 Proofs
26.3 Testing
26.3.1 Regression tests
26.3.2 Unit tests
26.3.3 Algorithms and non-algorithms
26.3.4 System tests
26.3.5 Finding assumptions that do not hold
26.4 Design for testing
26.5 Debugging
26.6 Performance
26.6.1 Timing
26.7 References
Chapter 27 The C Programming Language
27.1 C and C++: siblings
27.1.1 C/C++ compatibility
27.1.2 C++ features missing from C
27.1.3 The C standard library
27.2 Functions
27.2.1 No function name overloading
27.2.2 Function argument type checking
27.2.3 Function definitions
27.2.4 Calling C from C++ and C++ from C
27.2.5 Pointers to functions
27.3 Minor language differences
27.3.1 struct tag namespace
27.3.2 Keywords
27.3.3 Definitions
27.3.4 C-style casts
27.3.5 Conversion of void*
27.3.6 enum
27.3.7 Namespaces
27.4 Free store
27.5 C-style strings
27.5.1 C-style strings and const
27.5.2 Byte operations
27.5.3 An example: strcpy()
27.5.4 A style issue
27.6 Input/output: stdio
27.6.1 Output
27.6.2 Input
27.6.3 Files
27.7 Constants and macros
27.8 Macros
27.8.1 Function-like macros
27.8.2 Syntax macros
27.8.3 Conditional compilation
Head over to https://textbookfull.com to browse premium-
quality test banks and solution manuals with special
discounts.
27.9 An example: intrusive containers

Part V Appendices
Appendix A Language Summary
A.1 General
A.1.1 Terminology
A.1.2 Program start and termination
A.1.3 Comments
A.2 Literals
A.2.1 Integer literals
A.2.2 Floating-point-literals
A.2.3 Boolean literals
A.2.4 Character literals
A.2.5 String literals
A.2.6 The pointer literal
A.3 Identifiers
A.3.1 Keywords
A.4 Scope, storage class, and lifetime
A.4.1 Scope
A.4.2 Storage class
A.4.3 Lifetime
A.5 Expressions
A.5.1 User-defined operators
A.5.2 Implicit type conversion
A.5.3 Constant expressions
A.5.4 sizeof
A.5.5 Logical expressions
A.5.6 new and delete
A.5.7 Casts
A.6 Statements
A.7 Declarations
A.7.1 Definitions
A.8 Built-in types
A.8.1 Pointers
A.8.2 Arrays
A.8.3 References
A.9 Functions
A.9.1 Overload resolution
A.9.2 Default arguments
A.9.3 Unspecified arguments
A.9.4 Linkage specifications
A.10 User-defined types
A.10.1 Operator overloading
A.11 Enumerations
A.12 Classes
A.12.1 Member access
A.12.2 Class member definitions
A.12.3 Construction, destruction, and copy
A.12.4 Derived classes
A.12.5 Bitfields
A.12.6 Unions
A.13 Templates
A.13.1 Template arguments
A.13.2 Template instantiation
A.13.3 Template member types
A.14 Exceptions
A.15 Namespaces
A.16 Aliases
A.17 Preprocessor directives
A.17.1 #include
A.17.2 #define
Appendix B Standard Library Summary
B.1 Overview
B.1.1 Header files
B.1.2 Namespace std
B.1.3 Description style
B.2 Error handling
B.2.1 Exceptions
B.3 Iterators
B.3.1 Iterator model
B.3.2 Iterator categories
B.4 Containers
B.4.1 Overview
B.4.2 Member types
B.4.3 Constructors, destructors, and assignments
B.4.4 Iterators
B.4.5 Element access
B.4.6 Stack and queue operations
B.4.7 List operations
B.4.8 Size and capacity
B.4.9 Other operations
B.4.10 Associative container operations
B.5 Algorithms
B.5.1 Nonmodifying sequence algorithms
B.5.2 Modifying sequence algorithms
B.5.3 Utility algorithms
B.5.4 Sorting and searching
B.5.5 Set algorithms
B.5.6 Heaps
B.5.7 Permutations
B.5.8 min and max
B.6 STL utilities
B.6.1 Inserters
B.6.2 Function objects
B.6.3 pair and tuple
B.6.4 initializer_list
B.6.5 Resource management pointers
B.7 I/O streams
B.7.1 I/O streams hierarchy
B.7.2 Error handling
B.7.3 Input operations
B.7.4 Output operations
B.7.5 Formatting
B.7.6 Standard manipulators
B.8 String manipulation
B.8.1 Character classification
B.8.2 String
B.8.3 Regular expression matching
B.9 Numerics
B.9.1 Numerical limits
B.9.2 Standard mathematical functions
B.9.3 Complex
B.9.4 valarray
B.9.5 Generalized numerical algorithms
B.9.6 Random numbers
Other documents randomly have
different content
24.2.4. Rendering Subsystem
At first glance VTK has a simple object-oriented rendering model
with classes corresponding to the components that make up a 3D
scene. For example, vtkActors are objects that are rendered by a
vtkRenderer in conjunction with a vtkCamera, with possibly multiple
vtkRenderers existing in a vtkRenderWindow. The scene is illuminated
by one or more vtkLights. The position of each vtkActor is
controlled by a vtkTransform, and the appearance of an actor is
specified through a vtkProperty. Finally, the geometric
representation of an actor is defined by a vtkMapper. Mappers play
an important role in VTK, they serve to terminate the data
processing pipeline, as well as interface to the rendering system.
Consider this example where we decimate data and write the result
to a file, and then visualize and interact with the result by using a
mapper:

vtkOBJReader *reader = vtkOBJReader::New();


reader->SetFileName("exampleFile.obj");

vtkTriangleFilter *tri = vtkTriangleFilter::New();


tri->SetInputConnection(reader->GetOutputPort());

vtkQuadricDecimation *deci = vtkQuadricDecimation::New();


deci->SetInputConnection(tri->GetOutputPort());
deci->SetTargetReduction( 0.75 );

vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();


mapper->SetInputConnection(deci->GetOutputPort());

vtkActor *actor = vtkActor::New();


actor->SetMapper(mapper);

vtkRenderer *renderer = vtkRenderer::New();


renderer->AddActor(actor);

vtkRenderWindow *renWin = vtkRenderWindow::New();


renWin->AddRenderer(renderer);

vtkRenderWindowInteractor *interactor = vtkRenderWindowInteractor::New();


interactor->SetRenderWindow(renWin);

renWin->Render();
Here a single actor, renderer and render window are created with
the addition of a mapper that connects the pipeline to the rendering
system. Also note the addition of a vtkRenderWindowInteractor,
instances of which capture mouse and keyboard events and
translate them into camera manipulations or other actions. This
translation process is defined via a vtkInteractorStyle (more on this
below). By default many instances and data values are set behind
the scenes. For example, an identity transform is constructed, as
well as a single default (head) light and property.
Over time this object model has become more sophisticated. Much
of the complexity has come from developing derived classes that
specialize on an aspect of the rendering process. vtkActors are now
specializations of vtkProp (like a prop found on stage), and there are
a whole slew of these props for rendering 2D overlay graphics and
text, specialized 3D objects, and even for supporting advanced
rendering techniques such as volume rendering or GPU
implementations (see Figure 24.4).
Similarly, as the data model supported by VTK has grown, so have
the various mappers that interface the data to the rendering system.
Another area of significant extension is the transformation hierarchy.
What was originally a simple linear 4×4 transformation matrix, has
become a powerful hierarchy that supports non-linear
transformations including thin-plate spline transformation. For
example, the original vtkPolyDataMapper had device-specific
subclasses (e.g., vtkOpenGLPolyDataMapper). In recent years it has
been replaced with a sophisticated graphics pipeline referred to as
the "painter" pipeline illustrated in Figure 24.4.
Figure 24.4: Display Classes

The painter design supports a variety of techniques for rendering


data that can be combined to provide special rendering effects. This
capability greatly surpasses the simple vtkPolyDataMapper that was
initially implemented in 1994.
Another important aspect of a visualization system is the selection
subsystem. In VTK there is a hierarchy of "pickers", roughly
categorized into objects that select vtkProps based on hardware-
based methods versus software methods (e.g., ray-casting); as well
as objects that provide different levels of information after a pick
operations. For example, some pickers provide only a location in XYZ
world space without indicating which vtkProp they have selected;
others provide not only the selected vtkProp but a particular point or
cell that make up the mesh defining the prop geometry.

24.2.5. Events and Interaction


Interacting with data is an essential part of visualization. In VTK this
occurs in a variety of ways. At its simplest level, users can observe
events and respond appropriately through commands (the
command/observer design pattern). All subclasses of vtkObject
maintain a list of observers which register themselves with the
object. During registration, the observers indicate which particular
event(s) they are interested in, with the addition of an associated
command that is invoked if and when the event occurs. To see how
this works, consider the following example in which a filter (here a
polygon decimation filter) has an observer which watches for the
three events StartEvent, ProgressEvent, and EndEvent. These events
are invoked when the filter begins to execute, periodically during
execution, and then on completion of execution. In the following the
vtkCommand class has an Execute method that prints out the
appropriate information relative to the time it take to execute the
algorithm:

class vtkProgressCommand : public vtkCommand


{
public:
static vtkProgressCommand *New() { return new vtkProgressCommand; }
virtual void Execute(vtkObject *caller, unsigned long, void *callData)
{
double progress = *(static_cast<double*>(callData));
std::cout << "Progress at " << progress<< std::endl;
}
};

vtkCommand* pobserver = vtkProgressCommand::New();

vtkDecimatePro *deci = vtkDecimatePro::New();


deci->SetInputConnection( byu->GetOutputPort() );
deci->SetTargetReduction( 0.75 );
deci->AddObserver( vtkCommand::ProgressEvent, pobserver );

While this is a primitive form of interaction, it is a foundational


element to many applications that use VTK. For example, the simple
code above can be easily converted to display and manage a GUI
progress bar. This Command/Observer subsystem is also central to
the 3D widgets in VTK, which are sophisticated interaction objects
for querying, manipulating and editing data and are described below.
Referring to the example above, it is important to note that events in
VTK are predefined, but there is a back door for user-defined events.
The class vtkCommand defines the set of enumerated events (e.g.,
vtkCommand::ProgressEvent in the above example) as well as a user
event. The UserEvent, which is simply an integral value, is typically
used as a starting offset value into a set of application user-defined
events. So for example vtkCommand::UserEvent+100 may refer to a
specific event outside the set of VTK defined events.
From the user's perspective, a VTK widget appears as an actor in a
scene except that the user can interact with it by manipulating
handles or other geometric features (the handle manipulation and
geometric feature manipulation is based on the picking functionality
described earlier.) The interaction with this widget is fairly intuitive: a
user grabs the spherical handles and moves them, or grabs the line
and moves it. Behind the scenes, however, events are emitted (e.g.,
InteractionEvent) and a properly programmed application can
observe these events, and then take the appropriate action. For
example they often trigger on the vtkCommand::InteractionEvent as
follows:

vtkLW2Callback *myCallback = vtkLW2Callback::New();


myCallback->PolyData = seeds; // streamlines seed points, updated on
interaction
myCallback->Actor = streamline; // streamline actor, made visible on
interaction

vtkLineWidget2 *lineWidget = vtkLineWidget2::New();


lineWidget->SetInteractor(iren);
lineWidget->SetRepresentation(rep);
lineWidget->AddObserver(vtkCommand::InteractionEvent,myCallback);

VTK widgets are actually constructed using two objects: a subclass


of vtkInteractorObserver and a subclass of vtkProp. The
vtkInteractorObserver simply observes user interaction in the
render window (i.e., mouse and keyboard events) and processes
them. The subclasses of vtkProp (i.e., actors) are simply
manipulated by the vtkInteractorObserver. Typically such
manipulation consists of modifying the vtkProp's geometry including
highlighting handles, changing cursor appearance, and/or
transforming data. Of course, the particulars of the widgets require
that subclasses are written to control the nuances of widget
behavior, and there are more than 50 different widgets currently in
the system.

24.2.6. Summary of Libraries


VTK is a large software toolkit. Currently the system consists of
approximately 1.5 million lines of code (including comments but not
including automatically generated wrapper software), and
approximately 1000 C++ classes. To manage the complexity of the
system and reduce build and link times the system has been
partitioned into dozens of subdirectories. Table 24.1 lists these
subdirectories, with a brief summary describing what capabilities the
library provides.

Common core VTK classes


Filtering classes used to manage pipeline dataflow
Rendering rendering, picking, image viewing, and interaction
VolumeRendering volume rendering techniques
Graphics 3D geometry processing
GenericFiltering non-linear 3D geometry processing
Imaging imaging pipeline
Hybrid classes requiring both graphics and imaging functionality
Widgets sophisticated interaction
IO VTK input and output
Infovis information visualization
Parallel parallel processing (controllers and communicators)
Wrapping support for Tcl, Python, and Java wrapping
Examples extensive, well-documented examples
Table 24.1: VTK Subdirectories

24.3. Looking Back/Looking


Forward
VTK has been an enormously successful system. While the first line
of code was written in 1993, at the time of this writing VTK is still
growing strong and if anything the pace of development is
increasing.2 In this section we talk about some lessons learned and
future challenges.

24.3.1. Managing Growth


One of the most surprising aspects to the VTK adventure has been
the project's longevity. The pace of development is due to several
major reasons:

New algorithms and capabilities continue to be added. For


example, the informatics subsystem (Titan, primarily developed
by Sandia National Labs and Kitware) is a recent significant
addition. Additional charting and rendering classes are also
being added, as well as capabilities for new scientific dataset
types. Another important addition were the 3D interaction
widgets. Finally, the on-going evolution of GPU-based rendering
and data processing is driving new capabilities in VTK.
The growing exposure and use of VTK is a self-perpetuating
process that adds even more users and developers to the
community. For example, ParaView is the most popular scientific
visualization application built on VTK and is highly regarded in
the high-performance computing community. 3D Slicer is a
major biomedical computing platform that is largely built on VTK
and received millions of dollars per year in funding.
VTK's development process continues to evolve. In recent years
the software process tools CMake, CDash, CTest, and CPack
have been integrated into the VTK build environment. More
recently, the VTK code repository has moved to Git and a more
sophisticated work flow. These improvements ensure that VTK
remains on the leading edge of software development in the
scientific computing community.
While growth is exciting, validates the creation of the software
system, and bodes well for the future of VTK, it can be extremely
difficult to manage well. As a result, the near term future of VTK
focuses more on managing the growth of the community as well as
the software. Several steps have been taken in this regard.
First, formalized management structures are being created. An
Architecture Review Board has been created to guide the
development of the community and technology, focusing on high-
level, strategic issues. The VTK community is also establishing a
recognized team of Topic Leads to guide the technical development
of particular VTK subsystems.
Next, there are plans to modularize the toolkit further, partially in
response to workflow capabilities introduced by git, but also to
recognize that users and developers typically want to work with
small subsystems of the toolkit, and do not want to build and link
against the entire package. Further, to support the growing
community, it's important that contributions of new functionality and
subsystems are supported, even if they are not necessarily part of
the core of the toolkit. By creating a loose, modularized collection of
modules it is possible to accommodate the large number of
contributions on the periphery while maintaining core stability.

24.3.2. Technology Additions


Besides the software process, there are many technological
innovations in the development pipeline.

Co-processing is a capability where the visualization engine is


integrated into the simulation code, and periodically generates
data extracts for visualization. This technology greatly reduces
the need to output large amounts of complete solution data.
The data processing pipeline in VTK is still too complex.
Methods are under way to simplify and refactor this subsystem.
The ability to directly interact with data is increasingly popular
with users. While VTK has a large suite of widgets, many more
interaction techniques are emerging including touch-screen-
based and 3D methods. Interaction will continue its
development at a rapid pace.
Computational chemistry is increasing in importance to materials
designers and engineers. The ability to visualize and interact
with chemistry data is being added to VTK.
The rendering system in VTK has been criticized for being too
complex, making it difficult to derive new classes or support
new rendering technology. In addition, VTK does not directly
support the notion of a scene graph, again something that many
users have requested.
Finally new forms of data are constantly emerging. For example,
in the medical field hierarchical volumetric datasets of varying
resolution (e.g., confocal microscopy with local magnification).

24.3.3. Open Science


Finally Kitware and more generally the VTK community are
committed to Open Science. Pragmatically this is a way of saying we
will promulgate open data, open publication, and open source—the
features necessary to ensure that we are creating reproducible
scientific systems. While VTK has long been distributed as an open
source and open data system, the documentation process has been
lacking. While there are decent books [Kit10,SML06] there have
been a variety of ad hoc ways to collect technical publications
including new source code contributions. We are improving the
situation by developing new publishing mechanisms like the VTK
Journal3 that enable of articles consisting of documentation, source
code, data, and valid test images. The journal also enables
automated reviews of the code (using VTK's quality software testing
process) as well as human reviews of the submission.

24.3.4. Lessons Learned


While VTK has been successful there are many things we didn't do
right:

Design Modularity: We did a good job choosing the modularity


of our classes. For example, we didn't do something as silly as
creating an object per pixel, rather we created the higher-level
vtkImageClass that under the hood treats data arrays of pixel
data. However in some cases we made our classes too high
level and too complex, in many instances we've had to refactor
them into smaller pieces, and are continuing this process. One
prime example is the data processing pipeline. Initially, the
pipeline was implemented implicitly through interaction of the
data and algorithm objects. We eventually realized that we had
to create an explicit pipeline executive object to coordinate the
interaction between data and algorithms, and to implement
different data processing strategies.
Missed Key Concepts: Once of our biggest regrets is not making
widespread use of C++ iterators. In many cases the traversal of
data in VTK is akin to the scientific programming language
Fortran. The additional flexibility of iterators would have been a
significant benefit to the system. For example, it is very
advantageous to process a local region of data, or only data
satisfying some iteration criterion.
Design Issues: Of course there is a long list of design decisions
that are not optimal. We have struggled with the data execution
pipeline, having gone through multiple generations each time
making the design better. The rendering system too is complex
and hard to derive from. Another challenge resulted from the
initial conception of VTK: we saw it as a read-only visualization
system for viewing data. However, current customers often want
it to be capable of editing data, which requires significantly
different data structures.

One of the great things about an open source system like VTK is that
many of these mistakes can and will be rectified over time. We have
an active, capable development community that is improving the
system every day and we expect this to continue into the
foreseeable future.

Footnotes
1. http://en.wikipedia.org/wiki/Opaque_pointer.
2. See the latest VTK code analysis at
http://www.ohloh.net/p/vtk/analyses/latest.
3. http://www.midasjournal.org/?journal=35
Chapter 25. Battle for
Wesnoth
Richard Shimooka and David White
Programming tends to be considered a straightforward problem
solving activity; a developer has a requirement and codes a solution.
Beauty is often judged on the technical implementation's elegance or
effectiveness; this book is replete with excellent examples. Yet
beyond its immediate computing functions, code can have a
profound effect on people's lives. It can inspire people to participate
and create new content. Unfortunately, serious barriers exist that
prevent individuals from participating in a project.
Most programming languages require significant technical expertise
to utilize, which is out of reach for many. In addition, enhancing the
accessibility of code is technically difficult and is not necessary for
many programs. It rarely translates into neat coding scripts or clever
programming solutions. Achieving accessibility requires considerable
forethought in project and program design, which often runs
counter-intuitive to normal programming standards. Moreover most
projects rely upon an established staff of skilled professionals that
are expected to operate at a reasonably high level. They do not
require additional programming resources. Thus, code accessibility
becomes an afterthought, if considered at all.
Our project, the Battle for Wesnoth, attempted to address this issue
from its origins. The program is a turn-based fantasy strategy game,
produced in an open source model based on a GPL2 license. It has
been a moderate success, with over four million downloads at the
time of this writing. While this is an impressive metric, we believe
the real beauty of our project is the development model that allowed
a band of volunteers from widely different skill levels to interact in a
productive way.
Enhancing accessibility was not a vague objective set by developers,
it was viewed as essential for the project's survival. Wesnoth's open
source approach meant that the project could not immediately
expect large numbers of highly skilled developers. Making the
project accessible to a wide a number of contributors, with varying
skill levels, would ensure its long-term viability.
Our developers attempted to lay the foundations for broadening
accessibility right from its earliest iteration. This would have
undeniable consequences for all aspect of the programming
architecture. Major decisions were made largely with this objective in
mind. This chapter will provide an in-depth examination of our
program with a focus on the efforts to increase accessibility.
The first part of this chapter offers a general overview of the
project's programming, covering its language, dependencies and
architecture. The second part will focus on Wesnoth's unique data
storage language, known as Wesnoth Markup Language (WML). It
will explain the specific functions of WML, with a particular emphasis
on its effects on in-game units. The next section covers multiplayer
implementation and external programs. The chapter will end with
some concluding observations on our structure and the challenges of
broadening participation.

25.1. Project Overview


Wesnoth's core engine is written in C++, totalling around 200,000
lines at the time of this publication. This represents the core game
engine, approximately half of the code base without any content.
The program also allows in game content to be defined in a unique
data language known as Wesnoth Markup Language (WML). The
game ships with another 250,000 lines of WML code. The proportion
has shifted over the project's existence. As the program matured,
game content that was hardcoded in C++ has increasingly been
rewritten so that WML can be used to define its operation.
Figure 25.1 gives a rough picture of the program's architecture;
green areas are maintained by Wesnoth developers, while white
areas are external dependencies.

Figure 25.1: Program Architecture

Overall, the project attempts to minimize dependencies in most


cases so as to maximize the portability of the application. This has
the added benefit of reducing the program's complexity, and
decreases the need for developers to learn the nuances of a large
number of third party APIs. At the same time, the prudent use of
some dependencies can actually achieve the same effect. For
example, Wesnoth uses the Simple Directmedia Layer (SDL) for
video, I/O and event handling. It was chosen because it is easy to
use and provides a common I/O interface across many platforms.
This allows it to be portable to a wide array of platforms, rather than
the alternative of coding to specific APIs on different platforms. This
comes at a price however; it is harder to take advantage of some
platform specific features. SDL also has an accompanying family of
libraries that are used by Wesnoth for various purposes:

SDL_Mixer for audio and sound


SDL_Image for loading PNG and other image formats
SDL_Net for network I/O

Additionally, Wesnoth uses several other libraries:

Boost for a variety of advanced C++ features


Pango with Cairo for internationalized fonts
zlib for compression
Python and Lua for scripting support
GNU gettext for internationalization
Throughout Wesnoth's engine, the use of WML objects—that is,
string dictionaries with child nodes—is fairly ubiquitous. Many
objects can be constructed from a WML node, and also serialize
themselves to a WML node. Some parts of the engine keep data in
this WML dictionary based format, interpreting it directly rather than
parsing it into a C++ data structure.
Wesnoth utilizes several important subsystems, most of which are as
self-contained as possible. This segmented structure has advantages
for accessibility. An interested party can easily work a code in a
specific area and introduce changes without damaging the rest of
the program. The major subdivisions include:

A WML parser with preprocessor


Basic I/O modules that abstract underlying libraries and system
calls—a video module, a sound module, a network module
A GUI module containing widget implementations for buttons,
lists, menus, etc.
A display module for rendering the game board, units,
animations, and so forth
An AI module
A pathfinding module that includes many utility functions for
dealing with a hexagonal gaming board
A map generation module for generating different kinds of
random maps

There are also different modules for controlling different parts of the
game flow:

The titlescreen module, for controlling display of the title screen.


The storyline module, for showing cut-scene sequences.
The lobby module, for displaying and allowing setup of games
on the multiplayer server.
The "play game" module that controls the main gameplay.

The "play game" module and the main display module are the
largest within Wesnoth. Their purpose is the least well defined, as
their function is ever-changing and thus difficult to have a clear
specification for. Consequently, the modules has often been in
danger of suffering from the Blob anti-pattern over the program's
history—i.e., becoming huge dominant segments without well-
defined behaviors. The code in the display and play game modules
are regularly reviewed to see if any of it can be separated into a
module of its own.
There are also ancillary features that are part of the overall project,
but are separate from the main program. This includes a multiplayer
server that facilitates multiplayer network games, as well as a
content server that allows users to upload their content to a
common server and share it with others. Both are written in C++.

25.2. Wesnoth Markup Language


As an extensible game engine, Wesnoth uses a simple data language
to store and load all game data. Although XML was considered
initially, we decided that we wanted something a little more friendly
to non-technical users, and a little more relaxed with regard to use
of visual data. We therefore developed our own data language,
called Wesnoth Markup Language (WML). It was designed with the
least technical of users in mind: the hope was that even users who
find Python or HTML intimidating would be able to make sense of a
WML file. All Wesnoth game data is stored in WML, including unit
definitions, campaigns, scenarios, GUI definitions, and other game
logic configuration.
WML shares the same basic attributes as XML: elements and
attributes, though it doesn't support text within elements. WML
attributes are represented simply as a dictionary mapping strings to
strings, with the program logic responsible for interpretation of
attributes. A simple example of WML is a trimmed definition for the
Elvish Fighter unit within the game:

[unit_type]
id=Elvish Fighter
name= _ "Elvish Fighter"
race=elf
image="units/elves-wood/fighter.png"
profile="portraits/elves/fighter.png"
hitpoints=33
movement_type=woodland
movement=5
experience=40
level=1
alignment=neutral
advances_to=Elvish Captain,Elvish Hero
cost=14
usage=fighter
{LESS_NIMBLE_ELF}
[attack]
name=sword
description=_"sword"
icon=attacks/sword-elven.png
type=blade
range=melee
damage=5
number=4
[/attack]
[/unit_type]

Since internationalization is important in Wesnoth, WML does have


direct support for it: attribute values which have an underscore
prefix are translatable. Any translatable string is converted using
GNU gettext to the translated version of the string when the WML is
parsed.
Rather than have many different WML documents, Wesnoth opts for
the approach of all main game data being presented to the game
engine in just a single document. This allows for a single global
variable to hold the document, and when the game is loaded all unit
definitions, for instance, are loaded by looking for elements with the
name unit_type within a units element.
Though all data is stored in a single conceptual WML document, it
would be unwieldy to have it all in a single file. Wesnoth therefore
supports a preprocessor that is run over all WML before parsing.
This preprocessor allows one file to include the contents of another
file, or an entire directory. For instance:

{gui/default/window/}
will include all the .cfg files within gui/default/window/.

Since WML can become very verbose, the preprocessor also allows
macros to be defined to condense things. For instance, the
{LESS_NIMBLE_ELF} invocation in the definition of the Elvish Fighter is
a call to a macro that makes certain elf units less nimble under
certain conditions, such as when they are stationed in a forest:

#define LESS_NIMBLE_ELF
[defense]
forest=40
[/defense]
#enddef

This design has the advantage of making the engine agnostic to how
the WML document is broken up into files. It is the responsibility of
WML authors to decide how to structure and divide all game data
into different files and directories.
When the game engine loads the WML document, it also defines
some preprocessor symbols according to various game settings. For
instance, a Wesnoth campaign can define different difficulty settings,
with each difficulty setting resulting in a different preprocessor
symbol being defined. As an example, a common way to vary
difficulty is by varying the amount of resources given to an opponent
(represented by gold). To facilitate this, there is a WML macro
defined like this:

#define GOLD EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT


#ifdef EASY
gold={EASY_AMOUNT}
#endif
#ifdef NORMAL
gold={NORMAL_AMOUNT}
#endif
#ifdef HARD
gold={HARD_AMOUNT}
#endif
#enddef

This macro can be invoked using, for instance, {GOLD 50 100 200}
within the definition of an opponent to define how much gold the
opponent has based on the difficulty level.
Since the WML is processed conditionally, if any of the symbols
provided to the WML document change during execution of the
Wesnoth engine, the entire WML document must be re-loaded and
processed. For instance, when the user starts the game, the WML
document is loaded and available campaigns among other things are
loaded. But then, if the user chooses to start a campaign and
chooses a certain difficulty level—easy for instance—then the entire
document will have to be re-loaded with EASY defined.
This design is convenient in that a single document contains all
game data, and that symbols can allow easy configuration of the
WML document. However, as a successful project, more and more
content is available for Wesnoth, including much downloadable
content—all of which ends up inserted into the core document tree—
which means the WML document is many megabytes in size. This
has become a performance issue for Wesnoth: Loading the
document may take up to a minute on some computers, causing
delays in-game any time the document needs to be reloaded.
Additionally, it uses a substantial amount of memory. Some
measures are used to counter this: when a campaign is loaded, it
has a symbol unique to that campaign defined in the preprocessor.
This means that any content specific to that campaign can be
#ifdefed to only be used when that campaign is needed.

Additionally, Wesnoth uses a caching system to cache the fully


preprocessed version of the WML document for a given set of key
definitions. Naturally this caching system must inspect the
timestamp of all WML files so that if any have changed, the cached
document is regenerated.

25.3. Units in Wesnoth


The protagonists of Wesnoth are its units. An Elvish Fighter and an
Elvish Shaman might battle against a Troll Warrior and an Orcish
Grunt. All units share the same basic behavior, but many have
special abilities that alter the normal flow of gameplay. For example,
a troll regenerates some of its health every turn, an Elvish shaman
slows its opponents with an entangling root, and a Wose is invisible
in a forest.
What is the best way to represent this in an engine? It is tempting to
make a base unit class in C++, with different types of units derived
from it. For instance, a wose_unit class could derive from unit, and
unit could have a virtual function, bool is_invisible() const, which
returns false, which the wose_unit overrides, returning true if the
unit happens to be in forest.
Such an approach would work reasonably well for a game with a
limited set of rules. Unfortunately Wesnoth is quite a large game and
such an approach is not easily extendable. If a person wanted to
add a new type of unit under this approach, it would require the
addition of a new C++ class to the game. Additionally, it does not
allow different characteristics to be combined well: what if you had a
unit that regenerated, could slow enemies with a net, and was
invisible in a forest? You would have to write an entirely new class
that duplicates code in the other classes.
Wesnoth's unit system doesn't use inheritance at all to accomplish
this task. Instead, it uses a unit class to represent instances of
units, and a unit_type class, which represents the immutable
characteristics that all units of a certain type share. The unit class
has a reference to the type of object that it is. All the possible
unit_type objects are stored in a globally held dictionary that is
loaded when the main WML document is loaded.
A unit type has a list of all the abilities that that unit has. For
instance, a Troll has the "regeneration" ability that makes it heal life
every turn. A Saurian Skirmisher has the "skirmisher" ability that
allows it to move through enemy lines. Recognition of these abilities
is built into the engine—for instance, the pathfinding algorithms will
check if a unit has the "skirmisher" flag set to see if it can move
freely past enemy lines. This approach allows an individual to add
new units, which have any combination of abilities made by the
engine, by only editing WML. Of course, it doesn't allow adding
completely new abilities and unit behavior without modifying the
engine.
Additionally, each unit in Wesnoth may have any number of ways to
attack. For instance, an Elvish Archer has a long-range bow attack
and also a short-range sword attack. Each deals different damage
amounts and characteristics. To represent an attack, there is an
attack_type class, with every unit_type instance having a list of
possible attack_types.
To give each unit more character, Wesnoth has a feature known as
traits. Upon recruitment, most units are assigned two traits at
random from a predefined list. For instance, a strong unit does more
damage with its melee attacks, while an intelligent unit needs less
experience before it "levels up." Also, it is possible for units to
acquire equipment during the game that make them more powerful.
For instance, there might be a sword a unit can pick up that makes
their attacks do more damage. To implement traits and equipment
Wesnoth allows modifications on units, which are WML-defined
alterations to a unit's statistics. The modification can even be applied
to certain types of attacks. For instance, the strong trait gives strong
units more damage when attacking in melee, but not when using a
ranged strike.
Allowing completely configurable unit behavior with WML would be
an admirable goal, so it is instructional to consider why Wesnoth has
never achieved such a goal. WML would need to be much more
flexible than it is if it were to allow arbitrary unit behavior. Rather
than being a data-oriented language, WML would have to be
extended into a full-fledged programming language and that would
be intimidating for many aspiring contributors.
Additionally, the Wesnoth AI, which is developed in C++, recognizes
the abilities present in the game. It takes into account regeneration,
invisibility, and so forth, and attempts to maneuver its units to take
best advantage of these different abilities. Even if a unit ability could
be created using WML, it would be difficult to make the AI
sophisticated enough to recognize this ability to take advantage of it.
Implementing an ability but not having it accounted for by the AI
would not be a very satisfying implementation. Similarly,
implementing an ability in WML and then having to modify the AI in
C++ to account for the ability would be awkward. Thus, having units
definable in WML, but having abilities hard-wired into the engine is
considered a reasonable compromise that works best for Wesnoth's
specific requirements.

25.4. Wesnoth's Multiplayer


Implementation
The Wesnoth multiplayer implementation uses a simple-as-possible
approach to implementing multiplayer in Wesnoth. It attempts to
mitigate the possibility of malicious attacks on the server, but doesn't
make a serious attempt to prevent cheating. Any movement that is
made in a Wesnoth game—moving of a unit, attacking an enemy,
recruiting a unit, and so forth—can be saved as a WML node. For
instance, a command to move a unit might be saved into WML like
this:

[move]
x="11,11,10,9,8,7"
y="6,7,7,8,8,9"
[/move]

This shows the path that a unit follows as a result of a player's


commands. The game then has a facility to execute any such WML
command given to it. This is very useful because it means that a
complete replay can be saved, by storing the initial state of the
game and then all subsequent commands. Being able to replay
games is useful both for players to observe each other playing, as
well as to help in certain kinds of bug reports.
We decided that the community would try to focus on friendly,
casual games for the network multiplayer implementation of
Wesnoth. Rather than fight a technical battle against anti-social
crackers trying to compromise cheat prevention systems, the project
would simply not try hard to prevent cheating. An analysis of other
multiplayer games indicated that competitive ranking systems were a
key source of anti-social behavior. Deliberately preventing such
functions on the server greatly reduced the motivation for individuals
to cheat. Moreover the moderators try to encourage a positive
gaming community where individuals develop personal rapport with
other players and play with them. This placed a greater emphasis on
relationships rather than competition. The outcome of these efforts
has been deemed successful, as thus far efforts to maliciously hack
the game have been largely isolated.
Wesnoth's multiplayer implementation consists of a typical client-
server infrastructure. A server, known as wesnothd, accepts
connections from the Wesnoth client, and sends the client a
summary of available games. Wesnoth will display a 'lobby' to the
player who can choose to join a game or create a new game for
others to join. Once players are in a game and the game starts, each
instance of Wesnoth will generate WML commands describing the
actions the player makes. These commands are sent to the server,
and then the server relays them on to all the other clients in the
game. The server will thus act as a very thin, simple relay. The
replay system is used on the other clients to execute the WML
commands. Since Wesnoth is a turn-based game, TCP/IP is used for
all network communication.
This system also allows observers to easily watch a game. An
observer can join a game in-progress, in which case the server will
send the WML representing the initial state of the game, followed by
a history of all commands that have been carried out since the start
of the game. This allows new observers to get up to speed on the
state of the game. They can see a history of the game, although it
does take time for the observer to get to the game's current position
—the history of commands can be fast forwarded but it still takes
time. The alternative would be to have one of the clients generate a
snapshot of the game's current state as WML and send it to the new
observer; however this approach would burden clients with overhead
based on observers, and could facilitate denial-of-service attacks by
having many observers join a game.
Of course, since Wesnoth clients do not share any kind of game
state with each other, only sending commands, it is important that
they agree on the rules of the game. The server is segmented by
version, with only players using the same version of the game able
to interact. Players are immediately alerted if their client's game
becomes out of sync with others. This also is a useful system to
prevent cheating. Although it is rather easy for a player to cheat by
modifying their client, any difference between versions will
immediately be identified to players where it can be dealt with.

25.5. Conclusion
We believe that the beauty of the Battle for Wesnoth as a program is
how it made coding accessible to a wide variety of individuals. To
achieve this aim, the project often made compromises that do not
look elegant whatsoever in the code. It should be noted that many
of the project's more talented programmers frown upon WML for its
inefficient syntax. Yet this compromise enabled one of the project's
greatest successes. Today Wesnoth can boast of hundreds of user-
made campaigns and eras, created mostly by users with little or no
programming experience. Furthermore it has inspired a number of
people to take up programming as a profession, using the project as
a learning tool. Those are tangible accomplishments that few
programs can equal.
One of the key lessons a reader should take away from Wesnoth's
efforts is to consider the challenges faced by lesser skilled
programmers. It requires an awareness of what blocks contributors
from actually performing coding and developing their skills. For
example an individual might want to contribute to the program but
does not possess any programming skills. Dedicated technological
editors like emacs or vim possess a significant learning curve that
might prove daunting for such an individual. Thus WML was
designed to allow a simple text editor to open up its files, giving
anybody the tools to contribute.
However, increasing a code base's accessibility is not a simple
objective to achieve. There are no hard and fast rules for increasing
code's accessibility. Rather it requires a balance between different
considerations, which can have negative consequences that the
community must be aware of. This is apparent in how the program
dealt with dependencies. In some cases, dependencies can actually
increase barriers to participation, while in others they can allow
people to contribute more easily. Every issue must be considered on
a case-by-case basis.
We should also be careful not to overstate some of Wesnoth's
successes. The project enjoyed some advantages that are not easily
replicated by other programs. Making code accessible to a wider
public is partly a result of the program's setting. As an open source
program, Wesnoth had several advantages in this regard. Legally the
GNU license allows someone to open up an existing file, understand
how it works and makes changes. Individuals are encouraged to
experiment, learn and share within this culture, which might not be
appropriate for other programs. Nevertheless we hope that there are
certain elements that might prove useful for all developers and help
them in their effort to find beauty in coding.
Welcome to our online home – a place built for those who
cherish books and the pursuit of knowledge. Every book opens
a new chapter of experience, offering chances to learn, to
grow, and to dream. Guided by this belief, we’ve gathered a
wide range of works — from world-renowned literature and
expert references to empowering self-help books and stories
for children.But our mission goes beyond selling books. We
aim to be a cultural link connecting readers to the timeless
values of intellect, art, and human creativity. With a clean
design, intuitive features, and intelligent search tools, we
ensure that your reading journey is simple, pleasant, and
rewarding. Our ongoing discounts and delivery options bring
convenience right to your doorstep.Let us walk beside you as
you explore knowledge, nurture your passion, and grow every
single day.

https://textbookfull.com/

You might also like