haas/fall2026/cprog/projects/fwg5.md
... ...
@@ -0,0 +1,405 @@
1
+# CSCS1320 C/C++ Programming
2
+
3
+# PROJECT: FUN WITH GAMES (fwg5)
4
+
5
+## OBJECTIVE
6
+
7
+Using your Vircon32 build and installation from fwg0, the `v32c++`
8
+transpiler from fwg4, and the game foundations from fwg1 through fwg4,
9
+implement a simple 2D game in which your classes are related by
10
+**inheritance**. Rather than writing out the same position, velocity,
11
+and size members in every class, you will factor what your game objects
12
+have in common into a **base class**, and let **derived classes** build
13
+on it.
14
+
15
+Your game can be a continuation of your fwg4 game (refactored to use
16
+inheritance), or something entirely new. The demo `fwg5.cpp` (see
17
+`make copy`) shows the idea in miniature; do not just rename it.
18
+
19
+This project is **single inheritance only**: each derived class has
20
+exactly ONE base class. (Multiple inheritance is a topic for another
21
+day.)
22
+
23
+## BACKGROUND
24
+
25
+### Why inheritance?
26
+
27
+In fwg4 you might have noticed your `Player` and your `Ball` (or
28
+`Enemy`, or `Bullet`) carrying very similar data: an `x`, a `y`, a
29
+`dx`, a `dy`, a `width`, a `height`. Copy/pasting that into each class
30
+works, but now a bug (or a change) has to be fixed in every copy.
31
+
32
+Inheritance lets one class **acquire** the members of another:
33
+
34
+ * the **base class** (also: parent, superclass) holds what is common
35
+ * the **derived class** (also: child, subclass) gets all of that for
36
+ free, and adds or specializes what makes it different
37
+
38
+The litmus test is the **"is-a"** relationship. A `Player` IS-A
39
+`Entity`. A `Banner` IS-A `Entity`. If you cannot say "a ___ is a ___"
40
+with a straight face, inheritance is probably the wrong tool (a `Player`
41
+HAS-A `score`; that is just a data member, not a base class).
42
+
43
+### Syntax
44
+
45
+```
46
+class Entity // the base class: nothing special
47
+{
48
+ ...
49
+};
50
+
51
+class Player : public Entity // Player is derived from Entity
52
+{
53
+ ...
54
+};
55
+```
56
+
57
+The `: public Entity` part says "Player inherits from Entity". Use
58
+`public` inheritance: it preserves the is-a relationship, and it is the
59
+only flavor we will use.
60
+
61
+Everything that is accessible in `Entity` (see below) is now usable
62
+through a `Player` object:
63
+
64
+```
65
+Player me(20, 20);
66
+me.move(); // move() is defined in Entity, not in Player
67
+```
68
+
69
+### Access control: who gets to see what?
70
+
71
+You met `public` and `private` in fwg4. Inheritance introduces a third
72
+level, `protected`, and now the question "who can touch this?" has
73
+three audiences: **the class itself**, **its derived classes**, and
74
+**everyone else**.
75
+
76
+| member declared | the class itself | derived classes | everyone else |
77
+|-----------------|:----------------:|:---------------:|:-------------:|
78
+| `public` | yes | yes | yes |
79
+| `protected` | yes | yes | **no** |
80
+| `private` | yes | **no** | **no** |
81
+
82
+The key line is the `private` row: **a derived class does NOT get to
83
+touch its parent's private data**, even though it inherited it (the
84
+data is there inside every child object, but the child cannot name it).
85
+As we say in class:
86
+
87
+> **Children cannot access their parent's private parts.**
88
+
89
+If that sounds harsh, consider why: if any child could rummage through
90
+the parent's private data, then "private" would protect nothing; all
91
+anyone would need to do is write a derived class. Access control is only
92
+worth anything if inheritance cannot be used to get around it.
93
+
94
+So how does a child get at what it needs?
95
+
96
+ 1. **Through the parent's public interface**: accessors ("getters") and
97
+ mutators ("setters") such as `getX()` and `setPosition()`. This is
98
+ the best default.
99
+ 2. **Through `protected` members**: data the parent is willing to
100
+ share with its descendants (but not with the world). Use sparingly:
101
+ every `protected` member is a promise to all current and future
102
+ children.
103
+
104
+A good rule of thumb: start everything `private`. Loosen to `protected`
105
+only when a derived class has a real need, and to `public` only when
106
+outside code does.
107
+
108
+```
109
+class Entity
110
+{
111
+ private:
112
+ int x, y; // only Entity's own functions touch these
113
+
114
+ protected:
115
+ int dx, dy; // Entity and its children may touch these
116
+
117
+ public:
118
+ int getX() { return x; }
119
+ void setPosition(int nx, int ny) { x = nx; y = ny; }
120
+};
121
+
122
+class Player : public Entity
123
+{
124
+ public:
125
+ void stop() { dx = 0; dy = 0; } // OK: protected in Entity
126
+ void home() { x = 0; y = 0; } // ERROR: x and y are private
127
+ void home2() { setPosition(0, 0); } // OK: via the public interface
128
+};
129
+```
130
+
131
+### Constructors and inheritance
132
+
133
+When you create a `Player`, the `Entity` part of it has to be built too,
134
+and it is built **first**: base class constructor, then the derived
135
+class constructor. If the base class constructor needs arguments, the
136
+derived constructor supplies them using an **initializer list** (the
137
+part after the colon):
138
+
139
+```
140
+class Player : public Entity
141
+{
142
+ private:
143
+ int score;
144
+
145
+ public:
146
+ Player(int startx, int starty)
147
+ : Entity(startx, starty, 10, 20) // build the Entity part first
148
+ {
149
+ score = 0; // then our own extras
150
+ }
151
+};
152
+```
153
+
154
+If the base class has a constructor that takes arguments and the derived
155
+constructor does not say which one to call, the build fails; there is
156
+nothing sensible for the compiler to guess.
157
+
158
+### What a derived class can do
159
+
160
+ * use everything `public` and `protected` from its base
161
+ * **add** its own data members and member functions
162
+ * be used wherever the base class is expected (a `Player` is an
163
+ `Entity`)
164
+
165
+### The class hierarchy
166
+
167
+Draw it. Arrow from child to parent:
168
+
169
+```
170
+ Banner Player
171
+ \ /
172
+ \ /
173
+ Entity
174
+```
175
+
176
+Two derived classes, one base: that is the minimum for this project.
177
+
178
+## PROGRAM
179
+
180
+You are to write a Vircon32 C++ game that:
181
+
182
+ * has a player-controlled object, moved via the gamepad
183
+ * has at least one other kind of game object (enemy, obstacle,
184
+ ball, projectile, pickup, etc.) that acts on its own
185
+ * detects collisions between objects, with a meaningful result
186
+ * keeps a score (or lives, or timer) displayed or otherwise tracked
187
+ * has a win and/or lose condition (even if it simply resets)
188
+ * is built around **inheritance**:
189
+ * define a **base class** holding the data and behavior common to
190
+ your game objects (at minimum: position and size, plus a
191
+ constructor, accessors, and a mutator or two)
192
+ * the base class must have **private** and/or **protected** data;
193
+ use `protected` only where a derived class truly needs it
194
+ * define at least **TWO derived classes**, each inheriting
195
+ **publicly** from the base, from a **single** base class
196
+ * each derived class **constructor must invoke the base class
197
+ constructor** (initializer list)
198
+ * each derived class must **add** something of its own: data and/or
199
+ member functions that the base class does not have
200
+ * derived classes **must not** touch the base class's private data;
201
+ go through the public interface (or `protected` members)
202
+ * create objects of your derived classes and let them do the work
203
+ through their member functions; `main()` coordinates
204
+
205
+NOTE: you are free to use arrays of objects if your game calls for it,
206
+but the emphasis of this project is on the design of the class
207
+hierarchy and on respecting access control while using it.
208
+
209
+NOTE: if `v32c++` rejects a C++ feature, **keep it simple** and ask in
210
+the class chat; learning where the tool's limits are is part of the
211
+experience.
212
+
213
+NOTE: the first gamepad by default is mapped to the keyboard
214
+
215
+## CLASS REMINDERS
216
+
217
+A skeleton of the sort of thing we are after (yours will differ):
218
+
219
+```
220
+class Entity // BASE CLASS
221
+{
222
+ private:
223
+ int x; // position: private
224
+ int y;
225
+
226
+ protected:
227
+ int dx; // motion: shared with children
228
+ int dy;
229
+ int width;
230
+ int height;
231
+
232
+ public:
233
+ Entity(int startx, int starty, int w, int h);
234
+ int getX();
235
+ int getY();
236
+ void setPosition(int newx, int newy);
237
+ void move();
238
+};
239
+
240
+class Enemy : public Entity // DERIVED CLASS
241
+{
242
+ private:
243
+ int strength; // new data, only Enemy has it
244
+
245
+ public:
246
+ Enemy(int startx, int starty)
247
+ : Entity(startx, starty, 10, 20) // call the base constructor
248
+ {
249
+ strength = 3;
250
+ }
251
+
252
+ void update(); // new behavior
253
+};
254
+```
255
+
256
+Remember: a derived object **is** a base object, so every public member
257
+function of the base class works on it, too.
258
+
259
+## CARTRIDGE BUILD PROCESS
260
+
261
+All of these steps can be automated with the use of the provided
262
+`Makefile` simply by typing `make` at the prompt. Use `make copy` to
263
+pull the demo project (`fwg5.cpp`, `Makefile`) into your repository
264
+directory, and `make update` to refresh the `Makefile`.
265
+
266
+The build is the same as for fwg4: `v32c++` transpiles your `.cpp` and,
267
+as a side effect, generates the cartridge XML and the build script
268
+(`Make.sh`), which then compiles, assembles, converts any textures and
269
+sounds, and packs the ROM.
270
+
271
+### TRANSPILE
272
+
273
+```
274
+yoursystem:~/src/SEMESTER/cprog/fwg5$ v32c++ fwg5.cpp -o fwg5.c
275
+```
276
+
277
+Do **NOT** track the generated `.c` file; it is a build product.
278
+
279
+### COMPILE
280
+
281
+```
282
+yoursystem:~/src/SEMESTER/cprog/fwg5$ compile fwg5.c -o fwg5.asm
283
+```
284
+
285
+### ASSEMBLE
286
+
287
+```
288
+yoursystem:~/src/SEMESTER/cprog/fwg5$ assemble fwg5.asm -o fwg5.vbin
289
+```
290
+
291
+### IMAGE CONVERSION
292
+
293
+```
294
+yoursystem:~/src/SEMESTER/cprog/fwg5$ png2vircon sprites.png -o sprites.vtex
295
+```
296
+
297
+Note that you'll also want to ensure the XML file has been updated to
298
+reference these textures:
299
+
300
+```
301
+ <binary path="fwg5.vbin" />
302
+ <textures>
303
+ <texture path="sprites.vtex" />
304
+ </textures>
305
+```
306
+
307
+### AUDIO CONVERSION
308
+
309
+```
310
+yoursystem:~/src/SEMESTER/cprog/fwg5$ wav2vircon soundfx.wav -o soundfx.vsnd
311
+```
312
+
313
+```
314
+ <sounds>
315
+ <sound path="soundfx.vsnd" />
316
+ </sounds>
317
+```
318
+
319
+### PACKING THE ROM
320
+
321
+```
322
+yoursystem:~/src/SEMESTER/cprog/fwg5$ packrom fwg5.xml
323
+```
324
+
325
+## SUBMISSION
326
+
327
+To be successful in this project, the following criteria (or their
328
+equivalent) must be met:
329
+
330
+ * Project must be submit on time, by the deadline.
331
+ * Late submissions will lose 33% credit per day, with the submission window closing on the 3rd day following the deadline.
332
+ * Executed programs must display in a manner similar to provided output
333
+ * output formatted, where applicable, must match that of project requirements
334
+ * Processing must be correct based on input given and output requested
335
+ * Output, if applicable, must be correct based on values input
336
+ * Code must be nicely and consistently indented
337
+ * Code must be consistently written, to strive for readability from having a consistent style throughout
338
+ * Code must be commented
339
+ * Any "to be implemented" comments **MUST** be removed
340
+ * these "to be implemented" comments, if still present at evaluation time, will result in points being deducted.
341
+ * Sufficient comments explaining the point of provided logic **MUST** be present
342
+ * No global variables (without instructor approval), no goto statements, no calling of main()!
343
+ * Track/version the source code in your private semester repository
344
+ * Submit a copy of your source code to me using the **submit** tool by the deadline.
345
+
346
+Do **NOT** track or submit generated or binary files (`obj/`, `bin/`,
347
+`.c`, `.vbin`, `.v32`); `make submit` cleans these for you.
348
+
349
+### SUBMIT TOOL USAGE
350
+
351
+```
352
+lab46:~/src/SEMESTER/cprog/fwg5$ make submit
353
+```
354
+
355
+You should get some sort of confirmation indicating successful submission
356
+if all went according to plan. If not, check for typos and or locational
357
+mismatches.
358
+
359
+## COURSE OBJECTIVES ASSESSED
360
+
361
+Some of the rubric line items below also serve as evaluations of the
362
+course objectives listed on the course homepage:
363
+
364
+ * *Implement functional programs ... that satisfy automated test requirements*:
365
+ the cartridge builds with no warning or error
366
+ * *Label data structures as either scalar or composite*:
367
+ the base class and its data/interface
368
+ * *Construct modular code by defining functions and utilizing different
369
+ methods of passing data into them*: derived constructors passing data
370
+ up to the base class
371
+ * *Select the most appropriate control structure or data type to solve a
372
+ specific, predefined logical problem*: modeling shared and
373
+ specialized game objects with a class hierarchy
374
+ * *Utilize built-in language libraries*: texture and sound use
375
+
376
+Not every line item maps to an objective, and that is fine.
377
+
378
+### RUBRIC
379
+
380
+I'll be evaluating the project based on the following criteria:
381
+
382
+```
383
+286:fwg5:final tally of results (286/286)
384
+*:fwg5:code modified to meet project specifications [26/26]
385
+*:fwg5:screenshot or video posted to class DISCORD of game running [26/26]
386
+*:fwg5:base class defined with protected/private data and a public interface [26/26]
387
+*:fwg5:at least two classes derive publicly from a base (single inheritance) [26/26]
388
+*:fwg5:derived constructors invoke the base class constructor [26/26]
389
+*:fwg5:access control respected: children do not touch their parent's private parts [26/26]
390
+*:fwg5:derived classes add their own data and/or behavior [26/26]
391
+*:fwg5:working collision detection between game objects [26/26]
392
+*:fwg5:game has scoring (or lives/timer) and a win/lose condition [13/13]
393
+*:fwg5:game uses at least one texture and one sound [13/13]
394
+*:fwg5:source file, XML file, build script, and cartridge submit [13/13]
395
+*:fwg5:code compiles, cartridge builds with no warning or error [13/13]
396
+*:fwg5:committed project related changes to private semester repo [13/13]
397
+*:fwg5:grabit of project data by Sunday prior to duedate [13/13]
398
+```
399
+
400
+Additionally:
401
+
402
+ * Solutions not abiding by spirit of project will be subject to a 50% overall deduction
403
+ * Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
404
+ * Solutions not utilizing indentation to promote scope and clarity or otherwise maintaining consistency in code style and presentation will be subject to a 25% overall deduction
405
+ * Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction
haas/fall2026/cprog/projects/fwg6.md
... ...
@@ -0,0 +1,404 @@
1
+# CSCS1320 C/C++ Programming
2
+
3
+# PROJECT: FUN WITH GAMES (fwg6)
4
+
5
+## OBJECTIVE
6
+
7
+Using your Vircon32 build and installation from fwg0, the `v32c++`
8
+transpiler from fwg4, and the class hierarchy skills from fwg5,
9
+implement a simple 2D game built around **polymorphism**: a collection
10
+of different kinds of game objects, all handled through a **base class
11
+pointer**, each responding to the same function call in its own way via
12
+**virtual functions**. Along the way you will also try out
13
+**overloading**: functions that share a name, and operators (`+`, `==`,
14
+...) taught how to work on your own classes.
15
+
16
+Your game can be a continuation of your fwg5 game or something entirely
17
+new. The demo `fwg6.cpp` (see `make copy`) shows the ideas in miniature;
18
+do not just rename it.
19
+
20
+As in fwg5, inheritance is **single inheritance only**.
21
+
22
+## BACKGROUND
23
+
24
+### The problem polymorphism solves
25
+
26
+Suppose your game has a player, some drifting rocks, and a chaser. They
27
+are all "things that update and draw themselves", but each one does so
28
+differently. With plain inheritance you can write:
29
+
30
+```
31
+Player me;
32
+Drifter rock1, rock2;
33
+Chaser stalker;
34
+
35
+me.update();
36
+rock1.update();
37
+rock2.update();
38
+stalker.update();
39
+```
40
+
41
+...and every new kind of object means more lines in `main()`. What you
42
+want is **one list of game objects, one loop, one call**, with each
43
+object doing the right thing for what it actually is:
44
+
45
+```
46
+for (i = 0; i < NUM_ACTORS; i++)
47
+{
48
+ actors[i]->update();
49
+}
50
+```
51
+
52
+That is **polymorphism** ("many forms"): the same call, many behaviors,
53
+the right one chosen **at run time** by the real type of the object.
54
+
55
+### Two ingredients
56
+
57
+**1. A base class pointer can point at a derived object.** A `Drifter`
58
+IS-A `Actor`, so an `Actor *` is allowed to hold the address of a
59
+`Drifter`:
60
+
61
+```
62
+Drifter rock(200, 100, 2, 1);
63
+Actor *a = &rock; // address-of (&): a points at rock
64
+a->update(); // arrow (->): call through the pointer
65
+```
66
+
67
+This is where your pointer skills (address-of `&`, the arrow `->`) pay
68
+off. Since every element of an array has to be the same type, an array
69
+of `Actor *` can hold the addresses of a mixed bag of derived objects:
70
+
71
+```
72
+Actor *actors[3];
73
+actors[0] = &me; // a Player
74
+actors[1] = &rock; // a Drifter
75
+actors[2] = &stalker; // a Chaser
76
+```
77
+
78
+**2. Virtual functions.** By default, `a->update()` on an `Actor *`
79
+calls **`Actor`'s** version of `update()`, because that is the type
80
+the pointer claims. Mark the function `virtual` in the base class and
81
+C++ instead looks at what the pointer **really** points at:
82
+
83
+```
84
+class Actor
85
+{
86
+ public:
87
+ virtual void update(); // "derived classes may replace this"
88
+};
89
+
90
+class Drifter : public Actor
91
+{
92
+ public:
93
+ virtual void update(); // Drifter's own version: an OVERRIDE
94
+};
95
+```
96
+
97
+Now `a->update()` runs `Drifter::update()` when `a` points at a
98
+`Drifter`, `Player::update()` when it points at a `Player`, and so on.
99
+(The word `virtual` is optional on the override once the base declares
100
+it, but writing it keeps your intentions clear; do so.)
101
+
102
+### Pure virtual functions and abstract base classes
103
+
104
+Sometimes the base class cannot say anything sensible about how a
105
+function should work: what does it mean to `draw()` a generic `Actor`?
106
+Declare it **pure virtual** by giving it `= 0` instead of a body:
107
+
108
+```
109
+class Actor
110
+{
111
+ public:
112
+ virtual void update() = 0; // pure virtual: no body here
113
+ virtual void draw() = 0;
114
+};
115
+```
116
+
117
+A class with at least one pure virtual function is an **abstract base
118
+class**:
119
+
120
+ * you **must not** create an object of it (`Actor a;` is an error in
121
+ standard C++; `v32c++` does not check this for you, so the
122
+ discipline is yours, and it will be checked when your project is
123
+ evaluated): it is a promise, not a thing
124
+ * every derived class that wants to be instantiated **must override**
125
+ all of the pure virtuals, i.e. it must keep the promise
126
+ * you **can** still have pointers to it (`Actor *a;`), which is what
127
+ makes the polymorphic array above possible
128
+
129
+Think of the abstract base class as a contract: "anything that wants to
130
+be an `Actor` must know how to `update()` and `draw()`."
131
+
132
+### Overriding is not overloading
133
+
134
+These two words sound alike and mean different things:
135
+
136
+ * **overriding**: a derived class re-implements a **virtual** function
137
+ from its base, with the **same name and same parameters**. Resolved
138
+ at run time by the object's real type.
139
+ * **overloading**: two or more functions with the **same name but
140
+ different parameters**, in the same scope. Resolved at compile time
141
+ from the arguments you pass.
142
+
143
+### Function overloading
144
+
145
+```
146
+class Actor
147
+{
148
+ public:
149
+ void setPosition(int newx, int newy); // two ints...
150
+ void setPosition(Vec2 newpos); // ...or one Vec2
151
+};
152
+
153
+actor.setPosition(10, 20); // picks the first
154
+actor.setPosition(Vec2(10, 20)); // picks the second
155
+```
156
+
157
+You have already used this without noticing: a class can have more than
158
+one **constructor**, as long as their parameter lists differ.
159
+
160
+### Operator overloading
161
+
162
+Operators like `+` and `==` already work on `int`s. For your own classes
163
+you can teach them what to do. An operator is just a function with an
164
+odd name: `operator+`, `operator==`, `operator+=`, ...
165
+
166
+```
167
+class Vec2
168
+{
169
+ private:
170
+ int x;
171
+ int y;
172
+
173
+ public:
174
+ Vec2(int newx, int newy) { x = newx; y = newy; }
175
+
176
+ Vec2 operator+(Vec2 other) // a + b
177
+ {
178
+ return Vec2(x + other.x, y + other.y);
179
+ }
180
+
181
+ void operator+=(Vec2 other) // a += b
182
+ {
183
+ x += other.x;
184
+ y += other.y;
185
+ }
186
+
187
+ int operator==(Vec2 other) // a == b
188
+ {
189
+ return (x == other.x && y == other.y);
190
+ }
191
+};
192
+
193
+Vec2 pos(10, 10);
194
+Vec2 vel(2, 1);
195
+
196
+pos += vel; // same as pos.operator+=(vel)
197
+if (pos == vel) { ... } // same as pos.operator==(vel)
198
+Vec2 next = pos + vel; // same as pos.operator+(vel)
199
+```
200
+
201
+Guidelines: overload an operator only when its meaning is **obvious**
202
+(adding two vectors with `+` is; making `+` launch a missile is not).
203
+Overloading changes how your own types are *written*, not what the
204
+operator can do for built-in types: `3 + 4` is unaffected.
205
+
206
+*Access control reminder (from fwg5):* notice that `operator+` reads
207
+`other.x`. That is legal because the function is a member of `Vec2` and
208
+may touch the private data of any `Vec2`, not just its own object.
209
+Children still cannot access their parent's private parts, though.
210
+
211
+### A word about destructors
212
+
213
+In ordinary C++ a class that is meant to be used through a base pointer
214
+also gets a `virtual` destructor so deleting a derived object through a
215
+base pointer cleans up correctly. Our cartridges never `new`/`delete`
216
+objects (all of ours live as local variables in `main()`), so we need no
217
+destructors for this project.
218
+
219
+## PROGRAM
220
+
221
+You are to write a Vircon32 C++ game that:
222
+
223
+ * has a player-controlled object, moved via the gamepad
224
+ * has at least two other kinds of game object that act on their own
225
+ * detects collisions between objects, with a meaningful result
226
+ * keeps a score (or lives, or timer) displayed or otherwise tracked
227
+ * has a win and/or lose condition (even if it simply resets)
228
+ * is built around **polymorphism**:
229
+ * define an **abstract base class** with at least one **pure
230
+ virtual** function (for example `update()` and `draw()`)
231
+ * define at least **TWO derived classes** (publicly, single
232
+ inheritance) that **override** the virtual function(s) with
233
+ behavior of their own
234
+ * keep your game objects in an **array of base class pointers**,
235
+ holding **at least two different derived types**
236
+ * use a **loop** to call the virtual function(s) through those
237
+ pointers (`->`)
238
+ * demonstrates **overloading**:
239
+ * overload at least **one operator** for a class of yours (for
240
+ example a vector or point class), and **use it** meaningfully in
241
+ your game code
242
+ * demonstrate **function overloading** with at least one set of
243
+ functions (or constructors) sharing a name but differing in
244
+ parameters
245
+
246
+NOTE: the first gamepad by default is mapped to the keyboard
247
+
248
+NOTE: the transpiler emits an empty function body for each pure virtual
249
+function, and the Vircon32 compiler reports `argument "this" is not
250
+used` for it. That specific warning is expected and is **not** held
251
+against you for the "no warning or error" line item; any other warning
252
+or error is.
253
+
254
+NOTE: `v32c++` is not a full C++ compiler. If a feature is rejected,
255
+simplify and ask in the class chat; documenting what works and what
256
+does not is valuable.
257
+
258
+## CARTRIDGE BUILD PROCESS
259
+
260
+All of these steps can be automated with the use of the provided
261
+`Makefile` simply by typing `make` at the prompt. Use `make copy` to
262
+pull the demo project (`fwg6.cpp`, `Makefile`) into your repository
263
+directory, and `make update` to refresh the `Makefile`.
264
+
265
+The build is the same as for fwg4 and fwg5: `v32c++` transpiles your
266
+`.cpp` and generates the cartridge XML and build script (`Make.sh`),
267
+which compiles, assembles, converts textures and sounds, and packs the
268
+ROM.
269
+
270
+### TRANSPILE
271
+
272
+```
273
+yoursystem:~/src/SEMESTER/cprog/fwg6$ v32c++ fwg6.cpp -o fwg6.c
274
+```
275
+
276
+### COMPILE
277
+
278
+```
279
+yoursystem:~/src/SEMESTER/cprog/fwg6$ compile fwg6.c -o fwg6.asm
280
+```
281
+
282
+### ASSEMBLE
283
+
284
+```
285
+yoursystem:~/src/SEMESTER/cprog/fwg6$ assemble fwg6.asm -o fwg6.vbin
286
+```
287
+
288
+### IMAGE CONVERSION
289
+
290
+```
291
+yoursystem:~/src/SEMESTER/cprog/fwg6$ png2vircon sprites.png -o sprites.vtex
292
+```
293
+
294
+```
295
+ <binary path="fwg6.vbin" />
296
+ <textures>
297
+ <texture path="sprites.vtex" />
298
+ </textures>
299
+```
300
+
301
+### AUDIO CONVERSION
302
+
303
+```
304
+yoursystem:~/src/SEMESTER/cprog/fwg6$ wav2vircon soundfx.wav -o soundfx.vsnd
305
+```
306
+
307
+```
308
+ <sounds>
309
+ <sound path="soundfx.vsnd" />
310
+ </sounds>
311
+```
312
+
313
+### PACKING THE ROM
314
+
315
+```
316
+yoursystem:~/src/SEMESTER/cprog/fwg6$ packrom fwg6.xml
317
+```
318
+
319
+## SUBMISSION
320
+
321
+To be successful in this project, the following criteria (or their
322
+equivalent) must be met:
323
+
324
+ * Project must be submit on time, by the deadline.
325
+ * Late submissions will lose 33% credit per day, with the submission window closing on the 3rd day following the deadline.
326
+ * Executed programs must display in a manner similar to provided output
327
+ * output formatted, where applicable, must match that of project requirements
328
+ * Processing must be correct based on input given and output requested
329
+ * Output, if applicable, must be correct based on values input
330
+ * Code must be nicely and consistently indented
331
+ * Code must be consistently written, to strive for readability from having a consistent style throughout
332
+ * Code must be commented
333
+ * Any "to be implemented" comments **MUST** be removed
334
+ * these "to be implemented" comments, if still present at evaluation time, will result in points being deducted.
335
+ * Sufficient comments explaining the point of provided logic **MUST** be present
336
+ * No global variables (without instructor approval), no goto statements, no calling of main()!
337
+ * Track/version the source code in your private semester repository
338
+ * Submit a copy of your source code to me using the **submit** tool by the deadline.
339
+
340
+Do **NOT** track or submit generated or binary files (`obj/`, `bin/`,
341
+`.c`, `.vbin`, `.v32`); `make submit` cleans these for you.
342
+
343
+### SUBMIT TOOL USAGE
344
+
345
+```
346
+lab46:~/src/SEMESTER/cprog/fwg6$ make submit
347
+```
348
+
349
+You should get some sort of confirmation indicating successful submission
350
+if all went according to plan. If not, check for typos and or locational
351
+mismatches.
352
+
353
+## COURSE OBJECTIVES ASSESSED
354
+
355
+Some of the rubric line items below also serve as evaluations of the
356
+course objectives listed on the course homepage:
357
+
358
+ * *Implement functional programs ... that satisfy automated test requirements*:
359
+ the cartridge builds with no warning or error
360
+ * *Define the relationship between a variable's value and its memory
361
+ address using basic pointer syntax*: base class pointers holding the
362
+ address (`&`) of derived objects, called through `->`
363
+ * *Distinguish between collections of the same data type (arrays) and
364
+ collections of differing data types (structures)*: the array of base
365
+ pointers holding different derived objects
366
+ * *Construct modular code by defining functions and utilizing different
367
+ methods of passing data into them*: overriding virtual functions
368
+ * *Select the most appropriate control structure or data type to solve a
369
+ specific, predefined logical problem*: an abstract base class as the
370
+ contract for your game objects
371
+ * *Utilize built-in language libraries*: texture and sound use
372
+
373
+Not every line item maps to an objective, and that is fine.
374
+
375
+### RUBRIC
376
+
377
+I'll be evaluating the project based on the following criteria:
378
+
379
+```
380
+312:fwg6:final tally of results (312/312)
381
+*:fwg6:code modified to meet project specifications [26/26]
382
+*:fwg6:screenshot or video posted to class DISCORD of game running [26/26]
383
+*:fwg6:abstract base class declares virtual and pure virtual functions [26/26]
384
+*:fwg6:at least two derived classes override a virtual function [26/26]
385
+*:fwg6:virtual functions invoked through base class pointers [26/26]
386
+*:fwg6:array of base pointers holds different derived objects, driven by a loop [26/26]
387
+*:fwg6:at least one operator overloaded in a class [26/26]
388
+*:fwg6:overloaded operator is used meaningfully by the game code [13/13]
389
+*:fwg6:function (or constructor) overloading demonstrated [13/13]
390
+*:fwg6:working collision detection between game objects [26/26]
391
+*:fwg6:game has scoring (or lives/timer) and a win/lose condition [13/13]
392
+*:fwg6:game uses at least one texture and one sound [13/13]
393
+*:fwg6:source file, XML file, build script, and cartridge submit [13/13]
394
+*:fwg6:code compiles, cartridge builds with no warning or error [13/13]
395
+*:fwg6:committed project related changes to private semester repo [13/13]
396
+*:fwg6:grabit of project data by Sunday prior to duedate [13/13]
397
+```
398
+
399
+Additionally:
400
+
401
+ * Solutions not abiding by spirit of project will be subject to a 50% overall deduction
402
+ * Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
403
+ * Solutions not utilizing indentation to promote scope and clarity or otherwise maintaining consistency in code style and presentation will be subject to a 25% overall deduction
404
+ * Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction