440 likes | 522 Views
AC21001 - Lab 1. The game of nim. Rules of nim. Two players Start with N counters First player takes 1, 2, or 3 counters Second player does the same Player who takes last counter loses Demo of program. Requirements. Text version of the game Ask human who goes first For each turn:
E N D
AC21001 - Lab 1 The game of nim
Rules of nim • Two players • Start with N counters • First player takes 1, 2, or 3 counters • Second player does the same • Player who takes last counter loses • Demo of program
Requirements • Text version of the game • Ask human who goes first • For each turn: • Print number of counters left • If computer’s move, select number and make move (random or strategy) • If human’s move, ask how many counters to take (check for errors) • Check if game over • Ask for another game • Keep track of scores
Lab 1: design • Use brainstorming (on your own or with a friend) • List properties required • Identify properties that can be implemented with primitive data types • Sort them into classes • Assign other properties to classes hierarchically • Using your design: • Write C++ class definitions in header files • Add a Test() method to each class
Candidates for classes • Everything in one class? • Or.... • Class for one game of nim • Another class for scores • Or.... • Classes for computer and human players • Another class for game itself
Everything in one class • Properties • Counters left • Games played • Games won (by human) • Actions • Play first? • Computer move • Human move • Adjust scores • Print scores • Game over? • Play again?
Games played Counters left Games won Play first? Computer move Human move Adjust scores Print scores Game over/Play again? Relations
Game & scores classesGame class • Properties • Counters left • Actions • Play first? • Computer move • Human move
Game & scores classesScores class • Properties • Games played • Games won • Actions • Adjust scores • Print scores • Play again?
Game class Scores class Counters left Games won Games played Play first? Adjust scores Computer move Print scores Human move Play again? Game over? Relations
Computer/human/game classesComputer class • Properties • (None) • Actions • Move
Computer/human/game classesHuman class • Properties • (None) • Actions • Move
Computer/human/game classesGame class • Properties • Counters left • Games played • Games won • Actions • Play first? • Adjust scores • Print scores • Game over? • Play again?
Class communication • Game class must call methods in scores class • How to do this? • Communicate via main( ) method
Scores class Games won Games played Adjust scores Print scores Play again? Communication main() Game class Counters left Play Play first? Computer move Human move Game over?
Class communication in C++ Declare a Game pointer void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ Declare a Scores pointer void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ Create Game and Scores objects void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ Call Play() method of Game class to start the game off void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ Play() calls interior Game class methods to play game void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ When game ends, Play() returns human’s score (1 = win; 0 = lose) void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ “result” is passed to AdjustScores() method of Scores class void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Class communication in C++ PrintScores method of Scores class is called to print scores on screen void main() { Game *nimGame; Scores *nimScores; int result; nimGame = new Game; nimScores = new Scores; // Single play of game... result = nimGame->Play(); nimScores->AdjustScores(result); nimScores->PrintScores(); }
Not the best algorithm Why is this not an efficient way of coding the turns in the game? Game::Play() { HumanPlay(); } Game::HumanPlay() { <code for human play> ComputerPlay(); } Game::ComputerPlay() { <code for computer player> HumanPlay(); }
Computer nim strategies • Two options: • Play randomly • Play to win • Random play: • Use random number generator to choose number of counters (1, 2, 3, or number left) • Winning strategy • Try to work it out...
Input/output in C++ • To write to console, use cout • cout << variable << string << endl; • To read from console into a variable, use cin • cin >> variable1 >> variable 2;
Input/output in C++ #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; cin >> AVariable; cout << "The value of AVariable is: " << AVariable << endl; } Always include these 2 lines whenever using cout or cin
Input/output in C++ #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; cin >> AVariable; cout << "The value of AVariable is: " << AVariable << endl; } Declare an int variable AVariable
Input/output in C++ #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; cin >> AVariable; cout << "The value of AVariable is: " << AVariable << endl; } Use cout to print a prompt requesting input
Input/output in C++ #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; cin >> AVariable; cout << "The value of AVariable is: " << AVariable << endl; } Use cin to read in a value from keyboard
Input/output in C++ #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; cin >> AVariable; cout << "The value of AVariable is: " << AVariable << endl; } Use cout again to print out the value
Error checking in input • Previous program has a problem: • If non-numeric value entered, goes into infinite loop • Cannot provide an error check for incorrect input • Can solve this with following code
Error-free cin cin actually returns a bool flag indicating whether data was read successfully #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; while (!(cin >> AVariable)) { cin.clear(); cin.ignore(80, '\n'); cout << "There was an error!" << endl; } cout << "You entered: " << AVariable << endl; }
Error-free cin If cin returns 'false', entered data was not in correct format #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; while (!(cin >> AVariable)) { cin.clear(); cin.ignore(80, '\n'); cout << "There was an error!" << endl; } cout << "You entered: " << AVariable << endl; }
Error-free cin Clear input buffer, ignore up to 80 characters (or until \n read) and print error message #include <iostream> using namespace std; void main() { int AVariable; cout << "Please enter a number" << endl; while (!(cin >> AVariable)) { cin.clear(); cin.ignore(80, '\n'); cout << "There was an error!" << endl; } cout << "You entered: " << AVariable << endl; }
Random numbers in Visual C++ Header files needed for random number initialization and use #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; int main() { int i; srand( (unsigned)time( NULL ) ); for (i = 0; i < 10; i++) cout << rand() % 100 + 1 << endl; }
Random numbers in Visual C++ #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; int main() { int i; srand( (unsigned)time( NULL ) ); for (i = 0; i < 10; i++) cout << rand() % 100 + 1 << endl; } Must seed the random number generator – use the current system time Note: do this ONCE only in your program – put this statement in main()
Random numbers in Visual C++ #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; int main() { int i; srand( (unsigned)time( NULL ) ); for (i = 0; i < 10; i++) cout << rand() % 100 + 1 << endl; } rand() is the library method that generates random ints between 0 and RAND_MAX (maximum value defined by compiler)
Random numbers in Visual C++ rand() % 100 generates random ints between 0 and 99, so add 1 to get numbers between 1 and 100. [Recall: % is the modulus operator – returns remainder when left operand divided by right operand.] #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; int main() { int i; srand( (unsigned)time( NULL ) ); for (i = 0; i < 10; i++) cout << rand() % 100 + 1 << endl; }
Clearing the console screen • To clear the DOS console and position the cursor at the top left: • system("cls"); • Can use system() to run any DOS command • e.g. system("notepad.exe"); • Use with caution! (e.g. system("del *");)
Lab hand-ins: the program • All labs to be handed in by email • Code will be compiled and run during marking • Make sure you hand in the right version • Results emailed back to you • Each lab marked out of 10 • 1 mark band off for each day late • e.g. B1 B2
Lab hand-ins: the program • Before emailing your code: • DELETE THE Debug DIRECTORY!!! • Use WinZip to zip up all files in your lab directory • DON’T FORGET TO INCLUDE YOUR LAB REPORT (Word file) • Email Zip file as attachment to: • growe@computing.dundee.ac.uk
Lab hand-ins: the report • Write your report using Word • Include: • Title of lab • Purpose of lab (1 or 2 sentences – refer back to lab sheet for details) • Your class design, with brief description of how you arrived at it • Use diagrams if you think it will be clearer • Table showing test results for the program • List of any bugs you couldn’t fix