├── .gitattributes ├── .gitignore ├── BullCowGame ├── BullCowGame.vcxproj ├── BullCowGame.vcxproj.filters ├── FBullCowGame.cpp ├── FBullCowGame.h └── main.cpp ├── LICENSE.md ├── README.md ├── Section_02.VC.db └── Section_02.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /BullCowGame/BullCowGame.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B} 23 | Win32Proj 24 | BullCowGame 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | 100 | 101 | Level3 102 | Disabled 103 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | 114 | 115 | MaxSpeed 116 | true 117 | true 118 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | 120 | 121 | Console 122 | true 123 | true 124 | true 125 | 126 | 127 | 128 | 129 | Level3 130 | 131 | 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /BullCowGame/BullCowGame.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /BullCowGame/FBullCowGame.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FBullCowGame.h" 4 | #include 5 | 6 | // to make syntax Unreal friendly 7 | #define TMap std::map 8 | using int32 = int; 9 | 10 | FBullCowGame::FBullCowGame() { Reset(); } // default constructor 11 | 12 | int32 FBullCowGame::GetCurrentTry() const { return MyCurrentTry; } 13 | int32 FBullCowGame::GetHiddenWordLength() const { return MyHiddenWord.length(); } 14 | bool FBullCowGame::IsGameWon() const { return bGameIsWon; } 15 | 16 | int32 FBullCowGame::GetMaxTries() const 17 | { 18 | TMap WordLengthToMaxTries{ {3,4}, {4,7}, {5,10}, {6,16}, {7,20} }; 19 | return WordLengthToMaxTries[MyHiddenWord.length()]; 20 | } 21 | 22 | void FBullCowGame::Reset() 23 | { 24 | const FString HIDDEN_WORD = "plane"; // this MUST be an isogram 25 | MyHiddenWord = HIDDEN_WORD; 26 | 27 | MyCurrentTry = 1; 28 | bGameIsWon = false; 29 | return; 30 | } 31 | 32 | 33 | EGuessStatus FBullCowGame::CheckGuessValidity(FString Guess) const 34 | { 35 | if (!IsIsogram(Guess)) // if the guess isn't an isogram 36 | { 37 | return EGuessStatus::Not_Isogram; 38 | } 39 | else if (!IsLowercase(Guess)) // if the guess isn't all lowercase 40 | { 41 | return EGuessStatus::Not_Lowercase; 42 | } 43 | else if (Guess.length() != GetHiddenWordLength()) // if the guess length is wrong 44 | { 45 | return EGuessStatus::Wrong_Length; 46 | } 47 | else 48 | { 49 | return EGuessStatus::OK; 50 | } 51 | } 52 | 53 | 54 | // receives a VALID guess, incriments turn, and returns count 55 | FBullCowCount FBullCowGame::SubmitValidGuess(FString Guess) 56 | { 57 | MyCurrentTry++; 58 | FBullCowCount BullCowCount; 59 | int32 WordLength = MyHiddenWord.length(); // assuming same length as guess 60 | 61 | // loop through all letters in the hidden word 62 | for (int32 MHWChar = 0; MHWChar < WordLength; MHWChar++) { 63 | // compare letters against the guess 64 | for (int32 GChar = 0; GChar < WordLength; GChar++) { 65 | // if they match then 66 | if (Guess[GChar] == MyHiddenWord[MHWChar]) { 67 | if (MHWChar == GChar) { // if they're in the same place 68 | BullCowCount.Bulls++; // incriment bulls 69 | } 70 | else { 71 | BullCowCount.Cows++; // must be a cow 72 | } 73 | } 74 | } 75 | } 76 | if (BullCowCount.Bulls == WordLength) { 77 | bGameIsWon = true; 78 | } 79 | else 80 | { 81 | bGameIsWon = false; 82 | } 83 | return BullCowCount; 84 | } 85 | 86 | bool FBullCowGame::IsIsogram(FString Word) const 87 | { 88 | // treat 0 and 1 letter words as isograms 89 | if (Word.length() <= 1) { return true; } 90 | 91 | TMap LetterSeen; // setup our map 92 | for (auto Letter : Word) // for all letters of the word 93 | { 94 | Letter = tolower(Letter); // handle mixed case 95 | if (LetterSeen[Letter]) {// if the letter is in the map 96 | return false; // we do NOT have an isogram 97 | } else { 98 | LetterSeen[Letter] = true;// add the letter to the map 99 | } 100 | } 101 | 102 | return true; // for example in cases where /0 is entered 103 | } 104 | 105 | bool FBullCowGame::IsLowercase(FString Word) const 106 | { 107 | for (auto Letter : Word) 108 | { 109 | if (!islower(Letter)) // if not a lowercase letter 110 | { 111 | return false; 112 | } 113 | } 114 | return true; 115 | } 116 | -------------------------------------------------------------------------------- /BullCowGame/FBullCowGame.h: -------------------------------------------------------------------------------- 1 | /* The game logic (no view code or direct user interaction) 2 | The game is a simple guess the word game based on Mastermind 3 | */ 4 | 5 | #pragma once 6 | #include 7 | 8 | // to make syntax Unreal friendly 9 | using FString = std::string; 10 | using int32 = int; 11 | 12 | struct FBullCowCount 13 | { 14 | int32 Bulls = 0; 15 | int32 Cows = 0; 16 | }; 17 | 18 | enum class EGuessStatus 19 | { 20 | Invalid_Status, 21 | OK, 22 | Not_Isogram, 23 | Wrong_Length, 24 | Not_Lowercase 25 | }; 26 | 27 | 28 | class FBullCowGame 29 | { 30 | public: 31 | FBullCowGame(); // constructor 32 | 33 | int32 GetMaxTries() const; 34 | int32 GetCurrentTry() const; 35 | int32 GetHiddenWordLength() const; 36 | bool IsGameWon() const; 37 | EGuessStatus CheckGuessValidity(FString) const; 38 | 39 | void Reset(); 40 | FBullCowCount SubmitValidGuess(FString); 41 | 42 | 43 | // ^^ Please try and ignore this and focus on the interface above ^^ 44 | private: 45 | // see constructor for initialisation 46 | int32 MyCurrentTry; 47 | FString MyHiddenWord; 48 | bool bGameIsWon; 49 | 50 | bool IsIsogram(FString) const; 51 | bool IsLowercase(FString) const; 52 | }; -------------------------------------------------------------------------------- /BullCowGame/main.cpp: -------------------------------------------------------------------------------- 1 | /* This is the console executable, that makes use of the BullCow class 2 | This acts as the view in a MVC pattern, and is responsible for all 3 | user interaction. For game logic see the FBullCowGame class. 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "FBullCowGame.h" 10 | 11 | // to make syntax Unreal friendly 12 | using FText = std::string; 13 | using int32 = int; 14 | 15 | // function prototypes as outside a class 16 | void PrintIntro(); 17 | void PlayGame(); 18 | FText GetValidGuess(); 19 | bool AskToPlayAgain(); 20 | void PrintGameSummary(); 21 | 22 | FBullCowGame BCGame; // instantiate a new game, which we re-use across plays 23 | 24 | // the entry point for our application 25 | int main() 26 | { 27 | bool bPlayAgain = false; 28 | do { 29 | PrintIntro(); 30 | PlayGame(); 31 | bPlayAgain = AskToPlayAgain(); 32 | } 33 | while (bPlayAgain); 34 | 35 | return 0; // exit the application 36 | } 37 | 38 | void PrintIntro() 39 | { 40 | std::cout << "Welcome to Bulls and Cows, a fun word game.\n"; 41 | std::cout << std::endl; 42 | std::cout << " } { ___ " << std::endl; 43 | std::cout << " (o o) (o o) " << std::endl; 44 | std::cout << " /-------\\ / \\ /-------\\ " << std::endl; 45 | std::cout << " / | BULL |O O| COW | \\ " << std::endl; 46 | std::cout << " * |-,--- | |------| * " << std::endl; 47 | std::cout << " ^ ^ ^ ^ " << std::endl; 48 | std::cout << "Can you guess the " << BCGame.GetHiddenWordLength(); 49 | std::cout << " letter isogram I'm thinking of?\n"; 50 | std::cout << std::endl; 51 | return; 52 | } 53 | 54 | // plays a single game to completion 55 | void PlayGame() 56 | { 57 | BCGame.Reset(); 58 | int32 MaxTries = BCGame.GetMaxTries(); 59 | 60 | // loop asking for guesses while the game 61 | // is NOT won and there are still tries remaining 62 | while (!BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries) { 63 | FText Guess = GetValidGuess(); 64 | 65 | // submit valid guess to the game, and receive counts 66 | FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess); 67 | 68 | std::cout << "Bulls = " << BullCowCount.Bulls; 69 | std::cout << ". Cows = " << BullCowCount.Cows << "\n\n"; 70 | } 71 | 72 | PrintGameSummary(); 73 | return; 74 | } 75 | 76 | // loop continually until the user gives a valid guess 77 | FText GetValidGuess() 78 | { 79 | FText Guess = ""; 80 | EGuessStatus Status = EGuessStatus::Invalid_Status; 81 | do { 82 | // get a guess from the player 83 | int32 CurrentTry = BCGame.GetCurrentTry(); 84 | std::cout << "Try " << CurrentTry << " of " << BCGame.GetMaxTries(); 85 | std::cout << ". Enter your guess: "; 86 | std::getline(std::cin, Guess); 87 | 88 | // check status and give feedback 89 | Status = BCGame.CheckGuessValidity(Guess); 90 | switch (Status) { 91 | case EGuessStatus::Wrong_Length: 92 | std::cout << "Please enter a " << BCGame.GetHiddenWordLength() << " letter word.\n\n"; 93 | break; 94 | case EGuessStatus::Not_Isogram: 95 | std::cout << "Please enter a word witout repeating letters.\n\n"; 96 | break; 97 | case EGuessStatus::Not_Lowercase: 98 | std::cout << "Please enter all lowercase letters.\n\n"; 99 | break; 100 | default: 101 | // assume the guess is valid 102 | break; 103 | } 104 | } while (Status != EGuessStatus::OK); // keep looping until we get no errors 105 | return Guess; 106 | } 107 | 108 | bool AskToPlayAgain() 109 | { 110 | std::cout << "Do you want to play again with the same hidden word (y/n)? "; 111 | FText Response = ""; 112 | std::getline(std::cin, Response); 113 | return (Response[0] == 'y') || (Response[0] == 'Y'); 114 | } 115 | 116 | void PrintGameSummary() 117 | { 118 | if (BCGame.IsGameWon()) 119 | { 120 | std::cout << "WELL DONE - YOU WIN!\n"; 121 | } 122 | else 123 | { 124 | std::cout << "Better luck next time!\n"; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 EmbraceIT Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unreal Engine Developer Course - Section 2 - Bull Cow Game 2 | 3 | This is the [Unreal Engine Developer]( http://gdev.tv/urcgithub) course – it started as a runaway success on Kickstarter and has gone on to become one of the bestselling Unreal courses on the internet! Continually updated in response to student suggestions, you will benefit from the fact we have already taught over 360,336 students game development, many shipping commercial games as a result. 4 | 5 | You're welcome to download, fork or do whatever else legal with all the files! The real value is in our huge, high-quality online tutorials that accompany this repo. You can check out the course here: [Unreal Engine Developer]( http://gdev.tv/urcgithub) 6 | 7 | ## In This Section 8 | 9 | ### 1 Intro, Notes & Section 2 Assets ### 10 | 11 | + Welcome to the first actual coding video. 12 | + Why we’re doing this in the IDE only. 13 | + What you’ll be building, see resources. 14 | + You’ll learn types, loops, routines, classes. 15 | + We’ll follow Unreal’s coding style, and re-use. 16 | + Notes and resources are attached. 17 | 18 | ### 2 S02 Game Design Document (GDD) ### 19 | 20 | + How much planning should we do? 21 | + Define the emotional problem the game solves\* 22 | + Chose concept, rules & requirements. 23 | + Start to think about the architecture. 24 | + _Copy_ as much as possible into the code! 25 | + Document now what may change later. 26 | 27 | **Useful Links** 28 | + \* [McConnell, Steve. _Code Complete._ Microsoft Press 2004. Chapter 3.3](https://www.amazon.com/gp/product/0735619670/) 29 | 30 | ### 3 How Solutions & Projects Relate ### 31 | 32 | + How projects and solutions relate. 33 | + Setting up a new command line project. 34 | + An overview of the structure of our solution. 35 | + (Adding main.cpp to our project). 36 | 37 | ### 4 C++ Function Syntax ### 38 | 39 | + The difference between an engine and a library. 40 | + How this relates to this console application. 41 | + What is building / compiling code? 42 | + How the console knows where to find our code. 43 | + The syntax of a function in C++. 44 | + Write the minimal C++ program to remove error. 45 | + Testing our application runs without error. 46 | 47 | ### 5 Using, #include and Namespaces ### 48 | 49 | + **#** represents a “preprocessor directive”. 50 | + **#include** copies-and-pastes other code. 51 | + The idea of using library code. 52 | + Use <> for standard libraries. 53 | + Use “ “ for files you have created yourself. 54 | + Notice the namespace icon in autocomplete. 55 | + Import **iostream** library and use **std** namespace. 56 | 57 | ### 6 Magic Numbers and Constants ### 58 | 59 | + What a “magic number” is. 60 | + Why it’s a good idea to avoid them. 61 | + **constexpr** means “evaluated at compile time”. 62 | + Introduce coding standards\*. 63 | + Use a constant for the word length. 64 | 65 | **Useful Links** 66 | + \* [Unreal Engine - Coding Standard](https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard/index.html) 67 | 68 | ### 7 Variables and cin for Input ### 69 | 70 | + The difference between **\n** and **endl** 71 | + Introducing pseudocode programming 72 | + Why we need to **#import \** 73 | + Getting input using **cin** 74 | + Discovering woes with our input buffer. 75 | 76 | ### 8 Using getline() ### 77 | 78 | + Re-cap the problem we have. 79 | + Why **getline()** is useful here. 80 | + Where to find C++ documentation. 81 | + A word on non-obvious solutions. 82 | 83 | ### 9 Simplifying With Functions ### 84 | 85 | + Programming is all about managing complexity. 86 | + We want to think about a few things at a time. 87 | + The idea of abstraction and encapsulation. 88 | + How functions help us simplify. 89 | + Write and call your first functions. 90 | + A warning about “side-effects” of functions. 91 | + Always use **return** at the end of your functions. 92 | 93 | ### 10 Iterating With For & While Loops ### 94 | 95 | + Why we need loops. 96 | + When to use **for** vs **while**. 97 | + The syntax of a **for** loop. 98 | + Think carefully about the first & last loop. 99 | + Write a **for** loop to repeat the game. 100 | 101 | ### 11 Clarity is Worth Fighting For ### 102 | 103 | + More about levels of abstraction. 104 | + A word on being clever. 105 | + Using Visual Studio’s Extract “Extract Function” 106 | + What a header file (.h) is. 107 | + What’s refactoring, and why we do it. 108 | + Removing side-effects. 109 | + Where to find the course code on GitHub. 110 | 111 | ### 12 Booleans and comparisons ### 112 | 113 | + What a boolean is, and how to use it. 114 | + Only use when completely clear what you mean. 115 | + Use **==** for comparison. 116 | + Use **&&** for logical AND. 117 | + Use **||** for logical OR. 118 | + Use **[n]** to access a string, starting at n=0. 119 | + Use **‘ ‘** for characters, and **“ “** for strings. 120 | 121 | ### 13 Using do and while in C++ ### 122 | 123 | + What a **do while** loop is. 124 | + How it executes code one or more times. 125 | + Making our game play multiple times. 126 | 127 | ### 14 Introducing Classes ### 128 | 129 | + Lookup the Turing machine. 130 | + A quick overview of the MVC pattern. 131 | + User defined types (classes). 132 | + About working at an interface level (black box). 133 | + An overview of class **FBullCowGame** 134 | 135 | ### 15 Using Header Files as Contracts ### 136 | 137 | + Introducing .h header files in C++. 138 | + Why the added complexity is worth it. 139 | + Defining the interface to our class. 140 | + Writing our first draft of FBullCowGame.h 141 | 142 | ### 16 Including Our Own Header File ### 143 | 144 | + NEVER use using namespace in a .h 145 | + In fact, why use it at all? 146 | + Create your .cpp files and **#include** 147 | + Don’t create chains of includes. 148 | 149 | ### 17 Instantiating Your Class ### 150 | 151 | + Relax, they’re just user defined types! 152 | + string FirstName; creates a string object 153 | + FBullCowGame BCGame; works the same way 154 | + These instances are initialised by “constructors” 155 | + Instantiating means “creating an instance of” 156 | + So we’re simply creating a game instance. 157 | 158 | ### 18 Writing & Using Getter Methods ### 159 | 160 | + What is a getter method 161 | + Why we never access variables directly 162 | + How to call a method using the dot operator 163 | + Pros and cons of initialising in at compile time 164 | + Using “Rebuild Project” to make VS behave! 165 | 166 | ### 19 Introducing the Const Keyword ### 167 | 168 | + **const**’s meaning depends on context 169 | + Generally means “I promise not to change this” 170 | + What this is depends on exactly where it appears 171 | + At the end of a member function, for example **int GetCurrentTry() const;** it prevents the function from modifying any member variables 172 | + This is a good safety feature. 173 | 174 | ### 20 Constructors For Initialisation ### 175 | 176 | + Default constructor called when object created 177 | + Initialize in constructor when decided at runtime 178 | + Initialize in declaration if known at compile time 179 | + Constructor syntax simply: **ClassName()**; 180 | + Set the member variables in constructor 181 | + Test this has worked. 182 | 183 | ### 21 Pseudocode Programming ### 184 | 185 | + More on Pseudocode Programming Practice (PPP) 186 | + Reviewing our code and architecture 187 | + Using **// TODO** as a comment prefix 188 | + Introducing Visual Studio’s Task List 189 | + Planning our next wave of coding. 190 | 191 | ### 22 Using using for Type Aliases ### 192 | 193 | + We’re substituting types to be “Unreal ready” 194 | + The declaration is **using \ = \;** 195 | + For example **using int32 = int;** 196 | + Why Unreal uses **int32** rather than **int** 197 | + **FText** is for output, **FString** is “mutable” 198 | + Where to use each type of string 199 | + Map **FText** and **FString** to **std::string** 200 | 201 | ### 23 Using struct for Simple Types ### 202 | 203 | + **struct** is almost identical to **class** 204 | + It’s member variables (data) is public by default 205 | + Ideal for simple value types like **BullCowCount** 206 | + Outline **BullCowCount SubmitGuess(FString)** 207 | 208 | ### 24 Using if Statements in C++ ### 209 | 210 | + Why we need conditionals (selection) 211 | + Use **if** when it reads better (e.g. few conditions) 212 | + Use **switch** for multiple, simple conditions 213 | + (for loads of statements consider a table lookup) 214 | + The syntax of an **if** statement 215 | + Using **if** to write count bulls and cows. 216 | 217 | ### 25 Debugging 101 ### 218 | 219 | + A very brief intro to Visual Studio’s debugger 220 | + Set a break-point by clicking in margin 221 | + Watch values by highlighting in debug mode 222 | + Use “Continue” to cycle back to breakpoint. 223 | 224 | ### 26 A Place for Everything ### 225 | 226 | + Centralising the hidden word length 227 | + Making this a property of the game class 228 | + Writing a getter to access this value 229 | + Updating our intro to vary with word length. 230 | 231 | ### 27 Introducing enumerations ### 232 | 233 | + An **enum**erated type consists of named values 234 | + Use instead of coded meaning 235 | + Makes the code more readable and meaningful 236 | + Only defined values can be used - more robust 237 | + A benefit of C++ 11’s strongly typed enums 238 | + Creating an **enum class** for error checking. 239 | 240 | ### 28 Writing Error Checking Code ### 241 | 242 | + Use **else if** for the first time 243 | + Outline or **CheckGuessValidity()** method 244 | + Write working code for checking guess length 245 | + Use the debugger to test the return values. 246 | 247 | ### 29 Using switch Statements ### 248 | 249 | + Use our error values to communicate with user 250 | + All our user interaction is via **GameManager.cpp** 251 | + We’ll use **FText** in this file, as it’s UI text 252 | + We can “switch” what we say based on the error 253 | + The syntax of a **switch** statement 254 | + Remember your **break** keywords! 255 | 256 | ### 30 Warm Fuzzy Feelings ### 257 | 258 | + _Don’t_ get comfortable with compiler warnings 259 | + Refactor **GetValidGuess()** to remove warning 260 | + Rename **SubmitGuess()** to **SubmitValidGuess()** 261 | + Improve readability of **SubmitValidGuess()** 262 | + Get a warm fuzzy feeling! 263 | 264 | ### 31 Handling Game Win Condition ### 265 | 266 | + Change our **PlayGame()** loop to a **while** 267 | + Implement our **IsGameWon()** function 268 | 269 | ### 32 Win or Lose "Screen" ### 270 | 271 | Write a method to print a game summary to the screen once the game is over. 272 | 273 | ### 33 Introducing Big O Notation ### 274 | 275 | + Algorithm: the recipe for solving a problem 276 | + or: 45th US Vice President’s dance style 277 | + Introducing the complexity of algorithms 278 | + A quick introduction to “Big O” notation 279 | + Comparing three ways of checking for isograms. 280 | 281 | ### 34 TMap and map Data Structures ### 282 | 283 | + The importance of knowing your data types 284 | + Introducing the **std::map** data type 285 | + **#define TMap std::map** to keep it ‘Unreal’ 286 | + How we’ll be using the map 287 | + **TMap\ LetterSeen;** to declare 288 | + Using **LetterSeen[Letter]** to access 289 | + Wiring-up and pseudocoding **IsIsogram()** 290 | 291 | ### 35 Range-based for Loop ### 292 | 293 | + Introducing containers and iterators 294 | + Using a range-based for loop in Unreal\* 295 | + Gently introducing the auto keyword 296 | + Finishing our IsIsogram() 297 | 298 | **Useful Links** 299 | 300 | + \* [Unreal Engine - Ranged Based For Loops](https://www.unrealengine.com/blog/ranged-based-for-loops) 301 | 302 | ### 36 Design a Helper Function ### 303 | 304 | + Gain confidence with a multi-stage challenge 305 | + A word on implicit dependencies 306 | 307 | ### 37 Playtesting Your Game ### 308 | 309 | + Having someone else play test your game is vital 310 | + Silently take notes, or record screen if possible 311 | + Immediately go away and fix obvious bugs 312 | + For improvements consider 2nd or 3rd opinion 313 | + Repeat until the bug / issue rate plateaus. 314 | 315 | ### 38 Difficulty & Play Tuning ### 316 | 317 | + About the flow channel\* 318 | + **map** word length to max tries 319 | + Play test to determine correct difficulty. 320 | 321 | **Useful Links** 322 | 323 | + \* Read more in [Sylvester, T. Designing Games - O’Reilly](https://www.amazon.com/dp/B00AWKX1FO/) 324 | 325 | ### 39 Polishing & Packaging ### 326 | 327 | + First impressions count (think reviews) 328 | + Don’t ship a half-baked product, even if digital 329 | + Check through your code (polish) 330 | + Ship to your customers (package). 331 | 332 | ### Section 2 Wrap-Up ### 333 | 334 | + HUGE congratulations on your progress 335 | + Over 5 hours of pure C++ learning 336 | + Over 30 challenges you’ve completed 337 | + The journey has only just begun 338 | + Share your source code for others to play 339 | + Here are some suggested improvements 340 | + Next we take the game logic into Unreal :-) 341 | -------------------------------------------------------------------------------- /Section_02.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UnrealCourse/02_BullCowGame/add764cbc19fde70b285d08057e00525919c29fb/Section_02.VC.db -------------------------------------------------------------------------------- /Section_02.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BullCowGame", "BullCowGame\BullCowGame.vcxproj", "{12E5C0AC-25D2-49BC-A230-2CD55D9D599B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Debug|x64.ActiveCfg = Debug|x64 17 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Debug|x64.Build.0 = Debug|x64 18 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Debug|x86.ActiveCfg = Debug|Win32 19 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Debug|x86.Build.0 = Debug|Win32 20 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Release|x64.ActiveCfg = Release|x64 21 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Release|x64.Build.0 = Release|x64 22 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Release|x86.ActiveCfg = Release|Win32 23 | {12E5C0AC-25D2-49BC-A230-2CD55D9D599B}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | --------------------------------------------------------------------------------