| @@ -1,19 +0,0 @@ | |||
| // | |||
| // SA_DiceComparators.h | |||
| // DieBot Mobile | |||
| // | |||
| // Created by Sandy Achmiz on 5/4/16. | |||
| // | |||
| // | |||
| #import <Foundation/Foundation.h> | |||
| #ifndef SA_DiceComparators_h | |||
| #define SA_DiceComparators_h | |||
| NSComparisonResult compareEvaluatedExpressionsByResult(NSDictionary* expression1, | |||
| NSDictionary *expression2); | |||
| NSComparisonResult compareEvaluatedExpressionsByAttemptBonus(NSDictionary* expression1, | |||
| NSDictionary *expression2); | |||
| #endif /* SA_DiceComparators_h */ | |||
| @@ -1,33 +0,0 @@ | |||
| // | |||
| // SA_DiceComparators.m | |||
| // DieBot Mobile | |||
| // | |||
| // Created by Sandy Achmiz on 5/4/16. | |||
| // | |||
| // | |||
| #import "SA_DiceComparators.h" | |||
| #import "SA_DiceExpressionStringConstants.h" | |||
| NSComparisonResult compareEvaluatedExpressionsByResult(NSDictionary* expression1, | |||
| NSDictionary *expression2) { | |||
| if ([expression1[SA_DB_RESULT] integerValue] < [expression2[SA_DB_RESULT] integerValue]) { | |||
| return NSOrderedAscending; | |||
| } else if ([expression1[SA_DB_RESULT] integerValue] > [expression2[SA_DB_RESULT] integerValue]) { | |||
| return NSOrderedDescending; | |||
| } else { | |||
| return NSOrderedSame; | |||
| } | |||
| } | |||
| NSComparisonResult compareEvaluatedExpressionsByAttemptBonus(NSDictionary* expression1, | |||
| NSDictionary *expression2) { | |||
| if ([expression1[SA_DB_OPERAND_RIGHT][SA_DB_RESULT] integerValue] < [expression2[SA_DB_OPERAND_RIGHT][SA_DB_RESULT] integerValue]) { | |||
| return NSOrderedAscending; | |||
| } else if ([expression1[SA_DB_OPERAND_RIGHT][SA_DB_RESULT] integerValue] > [expression2[SA_DB_OPERAND_RIGHT][SA_DB_RESULT] integerValue]) { | |||
| return NSOrderedDescending; | |||
| } else { | |||
| return NSOrderedSame; | |||
| } | |||
| } | |||
| @@ -0,0 +1,126 @@ | |||
| // | |||
| // SA_DiceExpression.h | |||
| // SA_IRCBotServer | |||
| // | |||
| // Created by Said Achmiz on 6/23/19. | |||
| // | |||
| // | |||
| #import <Foundation/Foundation.h> | |||
| /***********************/ | |||
| #pragma mark Definitions | |||
| /***********************/ | |||
| typedef NS_ENUM(NSUInteger, SA_DiceExpressionTermType) { | |||
| SA_DiceExpressionTerm_NONE, | |||
| SA_DiceExpressionTerm_OPERATION, | |||
| SA_DiceExpressionTerm_ROLL_COMMAND, | |||
| SA_DiceExpressionTerm_ROLL_MODIFIER, | |||
| SA_DiceExpressionTerm_VALUE | |||
| }; | |||
| typedef NS_ENUM(NSUInteger, SA_DiceExpressionOperator) { | |||
| SA_DiceExpressionOperator_NONE, | |||
| SA_DiceExpressionOperator_MINUS, | |||
| SA_DiceExpressionOperator_PLUS, | |||
| SA_DiceExpressionOperator_TIMES | |||
| }; | |||
| typedef NS_ENUM(NSUInteger, SA_DiceExpressionRollCommand) { | |||
| SA_DiceExpressionRollCommand_NONE, | |||
| SA_DiceExpressionRollCommand_SUM, | |||
| SA_DiceExpressionRollCommand_SUM_EXPLODING | |||
| }; | |||
| typedef NS_ENUM(NSUInteger, SA_DiceExpressionDieType) { | |||
| SA_DiceExpressionDice_STANDARD, | |||
| SA_DiceExpressionDice_FUDGE | |||
| }; | |||
| typedef NS_ENUM(NSUInteger, SA_DiceExpressionRollModifier) { | |||
| SA_DiceExpressionRollModifier_NONE, | |||
| SA_DiceExpressionRollModifier_KEEP_HIGHEST, | |||
| SA_DiceExpressionRollModifier_KEEP_LOWEST | |||
| }; | |||
| typedef NS_OPTIONS(NSUInteger, SA_DiceExpressionError) { | |||
| // Errors for expression parsing. | |||
| SA_DiceExpressionError_NONE, | |||
| SA_DiceExpressionError_ROLL_STRING_EMPTY = 1 << 0 , | |||
| SA_DiceExpressionError_ROLL_STRING_HAS_ILLEGAL_CHARACTERS = 1 << 1 , | |||
| // Errors for expression evaluation. | |||
| SA_DiceExpressionError_UNKNOWN_ROLL_COMMAND = 1 << 2 , | |||
| SA_DiceExpressionError_ROLL_MODIFIER_INAPPLICABLE = 1 << 3 , | |||
| SA_DiceExpressionError_UNKNOWN_ROLL_MODIFIER = 1 << 4 , | |||
| SA_DiceExpressionError_DIE_COUNT_NEGATIVE = 1 << 5 , | |||
| SA_DiceExpressionError_DIE_COUNT_EXCESSIVE = 1 << 6 , | |||
| SA_DiceExpressionError_DIE_SIZE_INVALID = 1 << 7 , | |||
| SA_DiceExpressionError_DIE_SIZE_EXCESSIVE = 1 << 8 , | |||
| SA_DiceExpressionError_UNKNOWN_OPERATOR = 1 << 9 , | |||
| SA_DiceExpressionError_INVALID_EXPRESSION = 1 << 10 , | |||
| SA_DiceExpressionError_INTEGER_OVERFLOW_NEGATION = 1 << 11 , | |||
| SA_DiceExpressionError_INTEGER_OVERFLOW_ADDITION = 1 << 12 , | |||
| SA_DiceExpressionError_INTEGER_UNDERFLOW_ADDITION = 1 << 13 , | |||
| SA_DiceExpressionError_INTEGER_OVERFLOW_SUBTRACTION = 1 << 14 , | |||
| SA_DiceExpressionError_INTEGER_UNDERFLOW_SUBTRACTION = 1 << 15 , | |||
| SA_DiceExpressionError_INTEGER_OVERFLOW_MULTIPLICATION = 1 << 16 , | |||
| SA_DiceExpressionError_INTEGER_UNDERFLOW_MULTIPLICATION = 1 << 17 , | |||
| SA_DiceExpressionError_KEEP_COUNT_EXCEEDS_ROLL_COUNT = 1 << 18 , | |||
| SA_DiceExpressionError_KEEP_COUNT_NEGATIVE = 1 << 19 | |||
| }; | |||
| /***********************/ | |||
| #pragma mark - Functions | |||
| /***********************/ | |||
| NSString *NSStringFromSA_DiceExpressionOperator(SA_DiceExpressionOperator operator); | |||
| NSString *NSStringFromSA_DiceExpressionRollCommand(SA_DiceExpressionRollCommand command); | |||
| NSString *NSStringFromSA_DiceExpressionRollModifier(SA_DiceExpressionRollModifier modifier); | |||
| NSString *NSStringFromSA_DiceExpressionError(SA_DiceExpressionError error); | |||
| @class SA_DiceExpression; | |||
| NSComparisonResult compareEvaluatedExpressionsByResult(SA_DiceExpression *expression1, | |||
| SA_DiceExpression *expression2); | |||
| NSComparisonResult compareEvaluatedExpressionsByAttemptBonus(SA_DiceExpression *expression1, | |||
| SA_DiceExpression *expression2); | |||
| /*************************************************/ | |||
| #pragma mark - SA_DiceExpression class declaration | |||
| /*************************************************/ | |||
| @interface SA_DiceExpression : NSObject <NSCopying> | |||
| /************************/ | |||
| #pragma mark - Properties | |||
| /************************/ | |||
| @property SA_DiceExpressionTermType type; | |||
| @property NSUInteger errorBitMask; | |||
| @property SA_DiceExpressionOperator operator; | |||
| @property (nonatomic, strong) SA_DiceExpression *leftOperand; | |||
| @property (nonatomic, strong) SA_DiceExpression *rightOperand; | |||
| @property SA_DiceExpressionRollCommand rollCommand; | |||
| @property (nonatomic, strong) SA_DiceExpression *dieCount; | |||
| @property (nonatomic, strong) SA_DiceExpression *dieSize; | |||
| @property SA_DiceExpressionDieType dieType; | |||
| @property SA_DiceExpressionRollModifier rollModifier; | |||
| @property (nonatomic, strong) NSNumber *value; | |||
| @property (copy, nonatomic) NSString *inputString; | |||
| @property (copy, nonatomic) NSAttributedString *attributedInputString; | |||
| @property (nonatomic, strong) NSNumber *result; | |||
| @property (nonatomic, strong) NSArray <NSNumber *> *rolls; | |||
| @end | |||
| @@ -0,0 +1,146 @@ | |||
| // | |||
| // SA_DiceExpression.m | |||
| // SA_IRCBotServer | |||
| // | |||
| // Created by Said Achmiz on 6/23/19. | |||
| // | |||
| // | |||
| #import "SA_DiceExpression.h" | |||
| /*********************/ | |||
| #pragma mark Functions | |||
| /*********************/ | |||
| NSString *NSStringFromSA_DiceExpressionOperator(SA_DiceExpressionOperator operator) { | |||
| static NSDictionary <NSNumber *, NSString *> *SA_DiceExpressionOperatorStringValues; | |||
| static dispatch_once_t onceToken; | |||
| dispatch_once(&onceToken, ^{ | |||
| SA_DiceExpressionOperatorStringValues = @{ @(SA_DiceExpressionOperator_NONE) : @"SA_DB_OPERATOR_NONE", | |||
| @(SA_DiceExpressionOperator_MINUS) : @"SA_DB_OPERATOR_MINUS", | |||
| @(SA_DiceExpressionOperator_PLUS) : @"SA_DB_OPERATOR_PLUS", | |||
| @(SA_DiceExpressionOperator_TIMES) : @"SA_DB_OPERATOR_TIMES" | |||
| }; | |||
| }); | |||
| return SA_DiceExpressionOperatorStringValues[@(operator)]; | |||
| } | |||
| NSString *NSStringFromSA_DiceExpressionRollCommand(SA_DiceExpressionRollCommand command) { | |||
| static NSDictionary <NSNumber *, NSString *> *SA_DiceExpressionRollCommandStringValues; | |||
| static dispatch_once_t onceToken; | |||
| dispatch_once(&onceToken, ^{ | |||
| SA_DiceExpressionRollCommandStringValues = @{ @(SA_DiceExpressionRollCommand_SUM) : @"SA_DB_ROLL_COMMAND_SUM", | |||
| @(SA_DiceExpressionRollCommand_SUM_EXPLODING) : @"SA_DB_ROLL_COMMAND_SUM_EXPLODING" | |||
| }; | |||
| }); | |||
| return SA_DiceExpressionRollCommandStringValues[@(command)]; | |||
| } | |||
| NSString *NSStringFromSA_DiceExpressionRollModifier(SA_DiceExpressionRollModifier modifier) { | |||
| static NSDictionary <NSNumber *, NSString *> *SA_DiceExpressionRollModifierStringValues; | |||
| static dispatch_once_t onceToken; | |||
| dispatch_once(&onceToken, ^{ | |||
| SA_DiceExpressionRollModifierStringValues = @{ @(SA_DiceExpressionRollModifier_KEEP_HIGHEST) : @"SA_DB_ROLL_MODIFIER_KEEP_HIGHEST", | |||
| @(SA_DiceExpressionRollModifier_KEEP_LOWEST) : @"SA_DB_ROLL_MODIFIER_KEEP_LOWEST" | |||
| }; | |||
| }); | |||
| return SA_DiceExpressionRollModifierStringValues[@(modifier)]; | |||
| } | |||
| NSString *NSStringFromSA_DiceExpressionError(SA_DiceExpressionError error) { | |||
| static NSDictionary <NSNumber *, NSString *> *SA_DiceExpressionErrorStringValues; | |||
| static dispatch_once_t onceToken; | |||
| dispatch_once(&onceToken, ^{ | |||
| SA_DiceExpressionErrorStringValues = @{ @(SA_DiceExpressionError_ROLL_STRING_EMPTY) : @"SA_DB_ERROR_ROLL_STRING_EMPTY", | |||
| @(SA_DiceExpressionError_ROLL_STRING_HAS_ILLEGAL_CHARACTERS) : @"SA_DB_ERROR_ROLL_STRING_HAS_ILLEGAL_CHARACTERS", | |||
| @(SA_DiceExpressionError_UNKNOWN_ROLL_COMMAND) : @"SA_DB_ERROR_UNKNOWN_ROLL_COMMAND", | |||
| @(SA_DiceExpressionError_ROLL_MODIFIER_INAPPLICABLE) : @"SA_DB_ERROR_ROLL_MODIFIER_INAPPLICABLE", | |||
| @(SA_DiceExpressionError_UNKNOWN_ROLL_MODIFIER) : @"SA_DB_ERROR_UNKNOWN_ROLL_MODIFIER", | |||
| @(SA_DiceExpressionError_DIE_COUNT_NEGATIVE) : @"SA_DB_ERROR_DIE_COUNT_NEGATIVE", | |||
| @(SA_DiceExpressionError_DIE_COUNT_EXCESSIVE) : @"SA_DB_ERROR_DIE_COUNT_EXCESSIVE", | |||
| @(SA_DiceExpressionError_DIE_SIZE_INVALID) : @"SA_DB_ERROR_DIE_SIZE_INVALID", | |||
| @(SA_DiceExpressionError_DIE_SIZE_EXCESSIVE) : @"SA_DB_ERROR_DIE_SIZE_EXCESSIVE", | |||
| @(SA_DiceExpressionError_UNKNOWN_OPERATOR) : @"SA_DB_ERROR_UNKNOWN_OPERATOR", | |||
| @(SA_DiceExpressionError_INVALID_EXPRESSION) : @"SA_DB_ERROR_INVALID_EXPRESSION", | |||
| @(SA_DiceExpressionError_INTEGER_OVERFLOW_NEGATION) : @"SA_DB_ERROR_INTEGER_OVERFLOW_NEGATION", | |||
| @(SA_DiceExpressionError_INTEGER_OVERFLOW_ADDITION) : @"SA_DB_ERROR_INTEGER_OVERFLOW_ADDITION", | |||
| @(SA_DiceExpressionError_INTEGER_UNDERFLOW_ADDITION) : @"SA_DB_ERROR_INTEGER_UNDERFLOW_ADDITION", | |||
| @(SA_DiceExpressionError_INTEGER_OVERFLOW_SUBTRACTION) : @"SA_DB_ERROR_INTEGER_OVERFLOW_SUBTRACTION", | |||
| @(SA_DiceExpressionError_INTEGER_UNDERFLOW_SUBTRACTION) : @"SA_DB_ERROR_INTEGER_UNDERFLOW_SUBTRACTION", | |||
| @(SA_DiceExpressionError_INTEGER_OVERFLOW_MULTIPLICATION) : @"SA_DB_ERROR_INTEGER_OVERFLOW_MULTIPLICATION", | |||
| @(SA_DiceExpressionError_INTEGER_UNDERFLOW_MULTIPLICATION) : @"SA_DB_ERROR_INTEGER_UNDERFLOW_MULTIPLICATION", | |||
| @(SA_DiceExpressionError_KEEP_COUNT_EXCEEDS_ROLL_COUNT) : @"SA_DB_ERROR_KEEP_COUNT_EXCEEDS_ROLL_COUNT", | |||
| @(SA_DiceExpressionError_KEEP_COUNT_NEGATIVE) : @"SA_DB_ERROR_KEEP_COUNT_NEGATIVE" | |||
| }; | |||
| }); | |||
| return SA_DiceExpressionErrorStringValues[@(error)]; | |||
| } | |||
| NSComparisonResult compareEvaluatedExpressionsByResult(SA_DiceExpression *expression1, | |||
| SA_DiceExpression *expression2) { | |||
| if (expression1.result.integerValue < expression2.result.integerValue) | |||
| return NSOrderedAscending; | |||
| else if (expression1.result.integerValue > expression2.result.integerValue) | |||
| return NSOrderedDescending; | |||
| else | |||
| return NSOrderedSame; | |||
| } | |||
| NSComparisonResult compareEvaluatedExpressionsByAttemptBonus(SA_DiceExpression *expression1, | |||
| SA_DiceExpression *expression2) { | |||
| if (expression1.rightOperand.result.integerValue < expression2.rightOperand.result.integerValue) | |||
| return NSOrderedAscending; | |||
| else if (expression1.rightOperand.result.integerValue > expression2.rightOperand.result.integerValue) | |||
| return NSOrderedDescending; | |||
| else | |||
| return NSOrderedSame; | |||
| } | |||
| /****************************************************/ | |||
| #pragma mark - SA_DiceExpression class implementation | |||
| /****************************************************/ | |||
| @implementation SA_DiceExpression | |||
| /*******************************/ | |||
| #pragma mark - NSCopying methods | |||
| /*******************************/ | |||
| -(instancetype) copyWithZone:(NSZone *)zone { | |||
| SA_DiceExpression *copy = [SA_DiceExpression new]; | |||
| copy.type = _type; | |||
| copy.errorBitMask = _errorBitMask; | |||
| copy.operator = _operator; | |||
| copy.leftOperand = [_leftOperand copy]; | |||
| copy.rightOperand = [_rightOperand copy]; | |||
| copy.rollCommand = _rollCommand; | |||
| copy.dieCount = [_dieCount copy]; | |||
| copy.dieSize = [_dieSize copy]; | |||
| copy.dieType = _dieType; | |||
| copy.rollModifier = _rollModifier; | |||
| copy.value = _value; | |||
| copy.inputString = _inputString; | |||
| copy.attributedInputString = _attributedInputString; | |||
| copy.result = _result; | |||
| copy.rolls = _rolls; | |||
| return copy; | |||
| } | |||
| @end | |||