RosettaCodeData/Task/24-game/Modula-2/24-game.mod2

180 lines
4.5 KiB
Plaintext

MODULE TwentyFour;
FROM InOut IMPORT WriteString, WriteLn, Write, ReadString, WriteInt;
FROM RandomGenerator IMPORT Random;
TYPE operator_t = (add, sub, mul, div);
expr_t = RECORD
operand : ARRAY[0..3] OF CARDINAL;
operator : ARRAY[1..3] OF operator_t;
END;(*of RECORD*)
numbers_t = SET OF CHAR;
VAR expr : expr_t;
numbers : numbers_t;
(*******************************************************************createExpr*)
(*analyse the input string *)
PROCEDURE createExpr(s: ARRAY OF CHAR);
VAR index, counter : INTEGER;
token : CHAR;
temp_expr : expr_t;
operand : CARDINAL;
operator : operator_t;
(************************************nextToken*)
(* returns the next CHAR that isn`t a space *)
PROCEDURE nextToken(): CHAR;
BEGIN
INC(index);
WHILE (s[index] = ' ') DO
INC(index);
END;(*of WHILE*)
RETURN(s[index]);
END nextToken;
(***********************************set_operand*)
(* checks if the CHAR o inerhits a valid number*)
(* and sets 'operand' to its value *)
PROCEDURE set_operand(o: CHAR);
BEGIN
CASE o OF
'0'..'9': IF o IN numbers THEN
operand := ORD(o)-48;
numbers := numbers - numbers_t{o};
ELSE
WriteString("ERROR: '");
Write( o);
WriteString( "' isn`t a available number ");
WriteLn;
HALT;
END;(*of IF*)|
0 : WriteString("ERROR: error in input ");
WriteLn;
HALT;
ELSE
WriteString("ERROR: '");
Write( o);
WriteString( "' isn`t a number ");
WriteLn;
HALT;
END;(*of CASE*)
END set_operand;
(**********************************set_operator*)
(* checks if the CHAR o inerhits a valid *)
(* operator and sets 'operator' to its value *)
PROCEDURE set_operator(o: CHAR);
BEGIN
CASE o OF
'+' : operator := add;|
'-' : operator := sub;|
'*' : operator := mul;|
'/' : operator := div;|
0 : WriteString("ERROR: error in input ");
WriteLn;
HALT;
ELSE
WriteString("ERROR: '");
Write( o);
WriteString( "' isn`t a operator ");
WriteLn;
HALT;
END;(*of CASE*)
END set_operator;
(************************************************)
BEGIN
index := -1;
token := nextToken();
set_operand(token);
expr.operand[0] := operand;
token := nextToken();
set_operator(token);
expr.operator[1] := operator;
token := nextToken();
set_operand(token);
expr.operand[1] := operand;
token := nextToken();
set_operator(token);
expr.operator[2] := operator;
token := nextToken();
set_operand(token);
expr.operand[2] := operand;
token := nextToken();
set_operator(token);
expr.operator[3] := operator;
token := nextToken();
set_operand(token);
expr.operand[3] := operand;
END createExpr;
(*****************************************************************evaluateExpr*)
(* evaluate the expresion that was createt by 'createExpr' *)
PROCEDURE evaluateExpr(VAR num: REAL);
VAR index : INTEGER;
BEGIN
WITH expr DO
num := VAL(REAL,operand[0]);
FOR index := 1 TO 3 DO
CASE operator[index] OF
add : num := num + VAL(REAL,operand[index]);|
sub : num := num - VAL(REAL,operand[index]);|
mul : num := num * VAL(REAL,operand[index]);|
div : num := num / VAL(REAL,operand[index]);
END;(*of CASE*)
END;(*of FOR*)
END;(*of WITH*)
END evaluateExpr;
(**************************************************************generateNumbers*)
(* generates the 4 random numbers ond write them *)
PROCEDURE generateNumbers;
VAR index,ran : INTEGER;
BEGIN
numbers := numbers_t{};
ran := Random(0,9);
FOR index := 1 TO 4 DO
WHILE (CHR(ran+48) IN numbers )DO
ran := Random(0,9);
END;(*of While*)
Write(CHR(ran+48));
WriteLn;
numbers := numbers + numbers_t{CHR(ran+48)}
END;(*of FOR*)
END generateNumbers;
(****************************************************************Main Programm*)
VAR str : ARRAY[0..255] OF CHAR;
sum : REAL;
BEGIN
WriteString("Welcome to the 24 game in MODULA-2");
WriteLn;
WriteString("Here are your numbers:");
WriteLn;
generateNumbers;
WriteString("Enter your equation(This implementation dosn`t support brackets yet): ");
WriteLn;
ReadString(str);
createExpr(str);
evaluateExpr(sum);
WriteLn;
WriteString("Result:");
WriteLn;
WriteInt(TRUNC(sum),0);
WriteLn;
CASE (TRUNC(sum) - 24) OF
0 : WriteString("Perfect!");|
1 : WriteString("Almost perfect.");
ELSE
WriteString("You loose!");
END;(*of CASE*)
WriteLn;
END TwentyFour.