I am new in Objective C, and I need to do a basic math application within a 5 times loop. Users will need to state what operation will perform (+,-,*,/) and the program will generates two random numbers to do math operations. Then the user will do the math and the program will compare his input with the correct answer. At the end the user will receive a score % and a custom message according to right or wrong answer. I am a bit stuck. First I did the program which generates two random numbers and run nicely. However when I added the rest of the code I have a warning message that says that the implementation is incomplete. I am also unable to see what is happening whit the else structure within the case because I received errors indicating "Expected expression" in each one of them.
Any help is very much appreciated.
Here is my code:
#import <Foundation/Foundation.h>
#interface myMath : NSObject
//methods
-(int) getRandomNumber;
-(void) add: (double) result;
-(void) subtract: (double) result;
-(void) multiply: (double) result;
-(void) divide: (double) result;
#end
#implementation myMath
//returns a random number between 1 and 100
-(int) getRandomNumber{
return (arc4random()%(100-1))+1;
}
#end
#interface Calculator : NSObject
#property double setaccumulator, accumulator; //Synt all methods.
#end
#implementation Calculator{
double accumulator;
}
-(void) setAccumulator: (double) value;
{ accumulator = value; }
-(void) clear
{ accumulator = 0; }
-(double) accumulator
{ return accumulator; }
-(void) add: (double) value
{ accumulator += value; }
-(void) subtract: (double) value
{ accumulator -= value; }
-(void) multiply: (double) value
{ accumulator *= value; }
-(void) divide: (double) value
{ accumulator /= value; }
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
myMath *myMathStuff;
myMathStuff = [[myMath alloc] init];
int rnum1 = [myMathStuff getRandomNumber];
int rnum2 = [myMathStuff getRandomNumber];
double result;
char operator;
Calculator *myCalculator = [[Calculator alloc]init];
int n, right, wrong, cont;
n = 0, right, wrong, cont = 0;
NSLog(#"The random numbers are %i and %i", rnum1, rnum2);
while (n <= 5){
NSLog(#"What operation do you want to perform? (+ . - . * . / .");
scanf(" %c", &operator);
[myCalculator setAccumulator:(double) rnum1];
switch (operator) {
case '+':
[myCalculator add: rnum2];
NSLog(#"Please type the addition result: ");
scanf("%lf", &result);
if (result == rnum1)
right =+1;
NSLog(#"Congratulations, you did it right!");
else
wrong =+1;
NSLog(#"Sorry, the addition result is: %.2f", [myCalculator accumulator]);
break;
case '-':
[myCalculator subtract: rnum2]
NSLog(#"Please type the subtraction: ");
scanf("%lf", &result);
if (result == rnum1)
right =+1;
NSLog(#"Congratulations, you did it right!");
else
wrong =+1,
NSLog(#"Sorry, the subtraction result is: %.2f", [myCalculator accumulator]);
break;
case '*':
[myCalculator multiply: rnum2];
NSLog(#"Please type the multiplication result: ");
scanf("%lf", &result);
if (result == rnum1)
right =+1;
NSLog(#"Congratulations, you did it right!");
else
wrong =+1,
NSLog(#"Sorry, the multiplication result is: %.2f", [myCalculator accumulator]);
break;
case '/':
[myCalculator divide: rnum2];
NSLog(#"Please type the division result: ");
scanf("%lf", &result);
if (result == rnum1)
right =+1;
NSLog(#"Congratulations, you did it right!");
else
wrong =+1,
NSLog(#"Sorry, the division result is: %.2f", [myCalculator accumulator]);
break;
default:
break;
}
++n;
}
NSLog(#"You were right %i", right);
NSLog(#"You were wrong %i", wrong);
if (right == 4)
NSLog(#"Excellent you have a perfect 100 percent score");
else if (right == 3)
NSLog(#"Good job you have a 80 percent score");
else if (right == 2)
NSLog (#"Well, you have a 60 percent score");
else if (right ==1)
NSLog(#"Sorry, you have received a 20 percent score");
}
return 0;
}
I made some changes on the myMath implementation and I also changed the lines where the "else" appears as I show below. I am still getting the expected expression. If somebody else can see what I am not seeing I would appreciate your input.
Part of the code I changed:
switch (operator) {
case '+':
[myMathStuff add: rnum2];
NSLog(#"Please type the addition result: ");
scanf("%lf", &result);
if (result == rnum1)
right =+1;
NSLog (#"Congratulations, you did it right!");
else {
wrong =+1;
NSLog (#"Sorry, the addition result is: %.2f", [myMathStuff accumulator]);
}
break;
I was able to find the solution.
You are getting implementation is incomplete because in your MyMath class you are saying that you have 5 methods at the class level, and only one of those (GetRandomNumber) is actually implemented.
You need to finish the contract - that is - code out what the other four methods are going to do (add, subtract, multiply, divide).
Related
I am new at Objective C and ay programmer's world in general (2 or 3 weeks). Also I am Italian, and so It's quite difficult for me using english and the right terminology.
I created a class: "Mano" (Hand) with its instances and methods: m1 and m2.
My question is: How can I do to read m1 variables value with m2 ?
m1 and m2 have for example "int a; a=0;"
then m1, executing a method, sets a = 10
how can m2 read m1's a? Becouse if m2 simply reads a it reads his own a ... a=0, right?
Sorry again but I don't know how to explain myself better than this!
This was meant to be a simple RPS (Rock Paper Scissors) game just to start learning a little Objective C programming. In the beginning there were two objects m1 and m2 as the “Computer hand m1” and the “Player hand m2”.
Of course as you can see i joined the two methods (computer random number and human number choosing) so that all de job is made by just one object.
When methods were splitted I had problems in the [verdetto] (game results) methods because of m2 (jn my case) were not able to get the right value of the object instance (i needed m1 values) …
and that’s why I asked you my question!
Here you have 0=Rock 1=Scissors 2=Paper
// File main.m
#import <Foundation/Foundation.h>
#import "mano.h"
int main(int argc, const char * argv[])
{
int contatore;
contatore = 1;
#autoreleasepool {
mano *m1;
m1 = [[ mano alloc ] init ];
// mano *m2;
// m2 = [[ mano alloc ] init ];
while (contatore <= 5) {
NSLog(#"\n Partita N. %d", contatore);
contatore++;
[m1 gioco];
[m1 controlloRisultato]; }
// [m1 generatoreRandom] RANDOM NUMBER GENERATOR to let the computer choose
// [m2 scelta numero]here the player was meant to choose bw 0,1,2.
[m1 verdetto]; //game results
}
return 0;
}
// File mano.h
#import <Foundation/Foundation.h>
#interface mano : NSObject {
NSArray *simboli; //Rock Scissors Paper
NSInteger casuale; // Random Number
NSInteger scelta; // Player Number
NSInteger computer; // CPU wins
NSInteger giocatore; // Player Wins
NSInteger pareggi; // Draws
}
- (void) gioco;
- (void) controlloRisultato;
- (void) verdetto;
// - (void) generatoreRandom
// - (void) scelta numero
#end
// File mano.m
#import "mano.h"
#implementation mano
- (id) init {
self = [super init];
casuale = 0;
scelta = 0;
simboli = [ [ NSArray alloc] initWithObjects: #"Sasso",#"Forbici",#"Carta", nil]; //questo va nella init, giustamente, altrimenti non vale per tutti i metodi.
return self; }
- (void) gioco {
scelta =0;
casuale =0;
casuale = arc4random_uniform(3); //il computer sceglie un numero
// L'utente fa la sua scelta qui sotto
do {
NSLog (#"\n \n Inserisci 0 per Sasso, 1 per Forbici, 2 per Carta");
scanf ("%ld", &scelta);
if (scelta >2 || scelta <0) NSLog (#" \n Hai inserito un numero NON VALIDO");
} while (scelta >2 || scelta <0);
}
- (void) controlloRisultato {
NSLog(#"\nIl computer ha scelto: %#", [simboli objectAtIndex:casuale]);
NSLog(#"\nTu hai scelto: %#", [simboli objectAtIndex:scelta ]);
switch (casuale) {
case (0):
if (scelta == 0) {
NSLog (#"\n È un pareggio!");
++pareggi;
break;}
else if (scelta == 1) {
NSLog (#"\n Il Computer Vince!");
++computer;
break;}
else if (scelta == 2) {
NSLog (#"\n Hai vinto!");
++giocatore;
break;}
case (1):
if (scelta == 0) {
NSLog (#"\n Hai Vinto!");
++giocatore;
break;}
else if (scelta == 1) {
NSLog (#"\n È un pareggio!");
++pareggi;
break;}
else if (scelta == 2) {
NSLog (#"\n Il computer Vince!");
++computer;
break; }
case (2):
if (scelta == 0) {
NSLog (#"\n Il computer Vince!");
++computer;
break; }
else if (scelta == 1) {
NSLog (#"\n Hai Vinto!");
++giocatore;
break; }
else if (scelta == 2) {
NSLog (#"\n È un pareggio");
++pareggi;
break;}
break;
default:
break;
}
}
- (void)verdetto {
NSLog(#"\n Vittorie giocatore: %ld", giocatore);
NSLog(#"\n Vittorie computer: %ld", computer);
NSLog(#"\n Pareggi: %ld", pareggi);
if (giocatore > computer) NSLog(#"\n Bravo! Hai vinto tu la partita!");
else NSLog(#"\n Hai perso! Il computer ha vinto la partita");
}
#end
Same as you would if they were not the same kind of object, basically. First, make what you want to read public:
// Hand.h
#import <Foundation/Foundation.h>
#interface Hand : NSObject
// Each hand maintains a value
#property (assign) int a;
// This makes it easy to show two Hands working together...not necesary
- (instancetype)initAsFirst:(BOOL)first;
#end
Then, use a reference to one object from inside the other:
// Hand.m
#import "Hand.h"
#implementation Hand
// To start, some other object will call this with first set to YES.
- (instancetype)initAsFirst:(BOOL)first
{
self = [super init];
if (self) {
if (first) {
// The first Hand will create a second one to demonstrate the difference.
self.a = 0;
[self showHands:[[Hand alloc] initAsFirst:NO]];
} else {
// The second Hand will have a different value to prove that it's different.
self.a = 10;
}
}
return self;
}
- (void)showHands:(Hand *)h
{
// Display both the value of this hand (first) and the one this hand created (second)
NSLog(#"Mine: %d, Other: %d", self.a, h.a);
}
#end
now I have 1 class
#interface mani : NSObject
that maybe could control the game result.
and 2 subclasses:
#interface computer : mani //for random number generator
#interface giocatore : mani //for player choosing number
Now the matter for me is letting the first class (mani) read its subclasses variables, and do what to do to determine who is the winner! Still can't get how it works, and belive me, I am reading forums, and e-books!
I'm writing my first real objective C program and it's to make a very simple calculator like in the book Programming in Objective-C 2.0 by Stephen Kochan.
Anyway, whenever I run the program it just continually prints the same thing over and over again, not giving me the option to type anything else. The code is below, and if anyone could help I think the problem is somewhere between the while loop and the switch function. Thank you in advance!
#import <Foundation/Foundation.h>
#interface Calculator : NSObject {
double number, accumulator;
char operator;
}
-(void) add: (double) n;
-(void) subtract: (double) n;
-(void) multiply: (double) n;
-(void) divide: (double) n;
#end
#implementation Calculator
-(void) add: (double) n {
accumulator += n;
NSLog(#"%fl", accumulator);
}
-(void) subtract: (double) n {
accumulator -= n;
NSLog(#"%fl", accumulator);
}
-(void) multiply: (double) n {
accumulator *= n;
NSLog(#"%fl", accumulator);
}
-(void) divide: (double) n {
if (n == 0)
NSLog(#"Error! You can't divide by 0!");
else
accumulator /= n;
NSLog(#"%fl", accumulator);
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
double number, accumulator;
char operator;
Calculator *myCalc = [[Calculator alloc] init];
NSLog(#"Begin calculations by typing a number then S");
scanf("%lf, %c", &accumulator, &operator);
while (operator != 'E') {
NSLog(#"%lf", accumulator);
NSLog(#"What would you like to do next?");
scanf("%lf, %c", &number, &operator);
switch (operator) {
case '+':
[myCalc add: number];
break;
case '-':
[myCalc subtract: number];
break;
case '*':
[myCalc multiply: number];
break;
case '/':
[myCalc divide: number];
break;
default:
break;
}
}
}
return 0;
}
scanf is generally a bad function to use. It's generally better to read an input line into a string and then use sscanf (or some other parser) on the string.
However, the fix in this case is simple. scanf returns the number of input items successfully assigned. You expect two. If there's an error, or end-of-file is reached, it will return less than two. Thus:
int rc = scanf("%lf, %c", &number, &operator);
if (rc < 2) {
break;
}
In short: don't use scanf(). It doesn't work how you think it does.
I'm already tried explaining what's wrong, but basically it doesn't like newlines and stuff and it's pedantic. Search SO for similar questions. The easy solution is to replace scanf() with something actually useful, such as
char buf[0x100];
char *end;
fgets(buf, sizeof buf, stdin);
accumulator = strtod(buf, &end);
while (isspace(*end))
end++;
operator = *end;
Also, your calculator logic is flawed. The myCalc object doesn't share the identically named accumulator variable with the main() function. Your program basically doesn't take into account the first number entered. Also, I don't see what purpose the "type 'S'" part serves, there's absolutely no check for entering "S" in the code, only "E" for end.
On a side note: we're in C (basically), but it's still not a good idea to use C++ keywords as identifiers. Let new and operator be reserved. Call that variable op.
Also, as a design improvement, you can abstract away the big switch statement into the calculator class, and that way you could write something like [myCalc performOp:'+' withNumber:number]; etc.
Hi guys I've created a main.m file a calculator.h and calculator.m file
before writing down my code my problem is that the program doesn't ask for the operator it only asks for 1st and 2nd number.
here are my codes for the main.m
int num1,num2;
char op;
Calculator *myCalculator=[[Calculator alloc]init];
NSLog(#"Please Enter The First Number");
scanf("%i",&num1);
NSLog(#"Please Choose a mathematical operation '+', '-', '*', '/' :");
scanf("%c",&op);
NSLog(#"Please Enter The Second Number");
scanf("%i",&num2);
switch (op) {
case '+':
NSLog(#"The Result is : %i",[myCalculator Add:num1 :num2]);
break;
case '-':
NSLog(#"The Result is : %i",[myCalculator Sub:num1 :num2]);
break;
case '*':
NSLog(#"The Result is : %i",[myCalculator Mul:num1 :num2]);
break;
case '/':
NSLog(#"The Result is : %i",[myCalculator Div:num1 :num2]);
break;
default:
NSLog(#"Unknown Operator");
break;
}
and my codes for the implementation are as follows:
-(int) Add:(int)num1 :(int)num2
{
return num1+num2;
}
-(int) Sub:(int)num1 :(int)num2
{
return num1-num2;
}
-(int) Mul:(int)num1 :(int)num2
{
return num1*num2;
}
-(int) Div:(int)num1 :(int)num2
{
return num1/num2;
}
any help will be appreciated thanks in advance !
Haven't done anything like this in awhile, but when I made a small text based RPG battle system I ran into a similar problem. The user presses enter after inputting a number, right? The number will get scanned into num1 and the newline character will get scanned into op. Log the value of op before your switch.
I followed a tutorial to make an iOS Calculator, and I am now wanting to add a decimal place button to it. Here is my code
header file:
#import <UIKit/UIKit.h>
#interface CalcViewController : UIViewController {
float result;
float selectedNumber;
int selectedOperation;
IBOutlet UILabel *calcScreen;
}
-(IBAction)numberPressed:(id)sender;
-(IBAction)operationPressed:(id)sender;
-(IBAction)clearNumber:(id)sender;
-(IBAction)clearOperation:(id)sender;
#end
Here is my implementation file
#import "CalcViewController.h"
#implementation CalcViewController
-(IBAction)numberPressed:(id)sender {
selectedNumber = selectedNumber * 10 + (float) [sender tag];
calcScreen.text = [NSString stringWithFormat:#"%2g", selectedNumber];
}
-(IBAction)operationPressed:(id)sender {
if (selectedOperation == 0) {
result = selectedNumber;
} else {
switch (selectedOperation) {
case 1:
result = result + selectedNumber;
break;
case 2:
result = result - selectedNumber;
break;
case 3:
result = result * selectedNumber;
break;
case 4:
result = result / selectedNumber;
break;
case 5:
selectedOperation = 0;
break;
}
}
selectedNumber = 0;
calcScreen.text = [NSString stringWithFormat:#"%2g", result];
if ([sender tag] == 0) result = 0;
selectedOperation = [sender tag];
}
-(IBAction)clearNumber:(id)sender {
selectedNumber = 0;
calcScreen.text = #"0";
}
-(IBAction)clearOperation:(id)sender {
selectedNumber = 0;
calcScreen.text = #"0";
selectedOperation = 0;
}
I saw on another thread that someone had suggesting using the method:
- (IBAction)Decimal:(id)sender
{
NSString *currentText = calcScreen.text;
if ([currentText rangeOfString:#"." options:NSBackwardsSearch].length == 0) {
calcScreen.text = [calcScreen.text stringByAppendingString:#"."];
}
However this did not seem to work for me. It would indeed let me enter a decimal point, but when a second number was entered the decimal point would be lost. Can anyone suggest a method I could implement to achieve what I am trying to?
Cheers in advance!
My quick thought: keep the number as text on the screen, adding additional digits and/or decimal point to it as text. Only convert it to a float (I would use double myself, btw) at the moment that an operation is performed. The suggested method should then work fine.
Something like:
-(IBAction)numberPressed:(id)sender {
calcScreen.text = [calcScreen.text stringByAppendingString:[sender tag]];
}
-(IBAction)operationPressed:(id)sender {
selectedNumber = [calcScreen.text floatValue];
...
}
One quick tip, instead of using
int selectedOperation;... and later in code
switch (selectedOperation) {
case 1:
result = result + selectedNumber;
break;
case 2:
result = result - selectedNumber;
...
Try using typedef enum
typedef enum {
OperationTypeAdd = 0,
OperationTypeSub,
...
} OperationType
and in switch block
switch (operationType) {
case OperationTypeAdd:
result = result + selectedNumber;
break;
case operationTypeSub:
result = result - selectedNumber;
break;
I was doing a simple calculator with the following code. Right now it executes perfectly. When I tried to change things around, however, it doesn't work. I used BOOL program to check whether to continue asking for input from the person or finish the program.
If I change the expression of while statement to just (program) and change YES/NO in the program statements, why does the code fail to do what is inside the while?
// A simple printing calculator
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]
Calculator *deskCalc = [[Calculator alloc] init];
double value1;
char operator
BOOL program;
[deskCalc setAccumulator: 0];
while (!program) {
NSLog (#"Please type in your expression");
scanf (" %lf %c", &value1, &operator);
program = NO;
if (operator == '+') {
[deskCalc add: value1];
}
else if (operator == '-') {
[deskCalc subtract: value1];
}
else if (operator == '*' || operator == 'x') {
[deskCalc multiply: value1];
}
else if (operator == '/') {
if (value1 == 0)
NSLog (#"Division by zero!");
else
[deskCalc divide: value1];
}
else if (operator == 'S') {
[deskCalc set: value1];
}
else if (operator == 'E') {
[deskCalc accumulator];
program = YES;
}
else {
NSLog (#"Unknown operator");
}
}
NSLog (#"The result is %f", [deskCalc accumulator]);
[deskCalc release];
[pool drain];
return 0;
}
You haven't set the initial value of program, so it defaults to a garbage value which just happens to be non-zero.
Set the initial value of program when you declare it:
BOOL program = NO; // or YES, whichever is appropriate
It is always a good practice to initialize all your variables when you declare them.
Also using scanf for input may be overdoing it, if I were you I would use fgets and then extract the information from the string using strtok. That way even if the user puts his elbow on the keyboard you will not have to worry. Alternatively if you are fond of scanf use sscanf on that string instead of strtok.