Что такое 8037?
Это небольшая математическая игра: вы идете по улице, и просто считаете сумму цифр в автомобильных номерах. Эту игру мы реализуем в консольном варианте, на четырех языках: Swift, Objective-C, Java и C#.
В первой части мы написали часть приложения, которая спрашивает у пользователя ответ пока тот не введет слово для выхода из приложения. Как резонно заметили в комментариях, в таком случае правильнее все-таки использовать цикл вместо рекурсии. Поэтому первое, что мы сделаем — уберем рекурсию и напишем вместо нее цикл в методе startGame
.
Swift:
func startGame() {
var inputWord: String
repeat {
print(GreetingMessage.replacingOccurrences(of: ExitWordPlaceholder, with: self.exitWord))
inputWord = readLine() ?? ""
} while check(inputWord: inputWord)
}
private func check(inputWord: String) -> Bool {
let isExitWord = (inputWord == self.exitWord)
print(isExitWord ? GoodByeMessage : InputAcceptMessage.replacingOccurrences(of: InputWordPlaceholder, with: inputWord))
return !isExitWord
}
Objective-C:
- (void)startGame {
NSString *inputWord;
do {
NSLog(GreetingMessage, self.exitWord);
inputWord = [self readLine];
} while ([self checkInputWord:inputWord]);
}
- (BOOL)checkInputWord:(NSString *)inputWord {
BOOL isExitWord = [inputWord isEqualToString:self.exitWord];
isExitWord ? NSLog(@"%@", GoodByeMessage) : NSLog(InputAcceptMessage, inputWord);
return !isExitWord;
}
Java:
void startGame() {
String inputWord;
do {
System.out.println(String.format(GreetingMessage, exitWord));
inputWord = readLine();
} while (checkInputWord(inputWord));
}
private boolean checkInputWord(String inputWord) {
boolean isExitWord = inputWord.equals(exitWord);
System.out.println(isExitWord ? GoodByeMessage : String.format(InputAcceptMessage, inputWord));
return !isExitWord;
}
C#:
public void startGame()
{
string inputWord;
do
{
Console.WriteLine(string.Format(GreetingMessage, exitWord));
inputWord = Console.ReadLine();
}
while (checkInputWord(inputWord));
}
bool checkInputWord(string inputWord)
{
bool isExitWord = inputWord.Equals(exitWord);
Console.WriteLine(isExitWord ? GoodByeMessage : string.Format(InputAcceptMessage, inputWord));
return !isExitWord;
}
Ну а дальше — мы, наконец, создадим класс нашей игры (как вы помните, мы специально создавали интерфейс (протокол) Game
, который мы должны реализовать в нашем классе):
class Game8037: Game {
// MARK: - Game
func greet(with exitWord: String) {
}
func check(userAnswer: String) {
}
}
Оставим пока что методы протокола пустыми, и займемся организацией функциональности класса. В первую очередь нам понадобится enum с уровнями сложности:
private enum Level: String {
case easy
case normal
case hard1
case hard2
func forSelect() -> String {
return LevelForSelect.replacingOccurrences(of: LevelPlaceholder, with: self.rawValue)
.replacingOccurrences(of: LevelNumberPlaceholder, with: "\(self.hashValue+1)")
}
}
В enum мы добавили метод forSelect()
он будет для каждого уровня сложности создавать строку вида 1 - easy
(номер уровня и его название). Это нам пригодится для предложения пользователю выбрать уровень сложности. Дальше нам понадобятся два свойства которые будут содержать в себе выбранный уровень и правильный ответ на задание:
private var level: Level
private var result: UInt32
Теперь мы можем написать наш инициализатор:
init?() {
self.result = 0
let levels = Level.easy.forSelect() + Level.normal.forSelect() + Level.hard1.forSelect() + Level.hard2.forSelect()
print(StartGreeting.replacingOccurrences(of: LevelsPlaceholder, with: levels))
let selectedLevel = readLine() ?? ""
switch selectedLevel {
case "\(Level.easy.hashValue+1)", Level.easy.rawValue:
self.level = .easy
case "\(Level.normal.hashValue+1)", Level.normal.rawValue:
self.level = .normal
case "\(Level.hard1.hashValue+1)", Level.hard1.rawValue:
self.level = .hard1
case "\(Level.hard2.hashValue+1)", Level.hard2.rawValue:
self.level = .hard2
default:
print(ErrorLevelMessage)
return nil
}
}
Как видите, для начала, мы задаем значение по-умолчанию для свойства result
(оно у нас пока что хранит в себе ноль). Дальше мы формируем информационную строку для пользователя о необходимости выбрать уровень сложности. В консоли это выглядит так:
Ну и потом, мы считываем введенный пользователем уровень сложности и, если он корректен — сохраняем его в свойстве level
.
Теперь нам понадобится метод расчета правильного ответа на задание в зависимости от уровня:
private func result(with level: Level, and randomizer: Randomizer) -> UInt32 {
let result: UInt32
switch level {
case .easy:
result = randomizer.firstNumber + randomizer.secondNumber + randomizer.thirdNumber + randomizer.fourthNumber
case .normal:
result = randomizer.firstNumber*10 + randomizer.secondNumber + randomizer.thirdNumber*10 + randomizer.fourthNumber
case .hard1:
let firstNumber = (randomizer.firstNumber == 0) ? 1 : randomizer.firstNumber
let secondNumber = (randomizer.secondNumber == 0) ? 1 : randomizer.secondNumber
let thirdNumber = (randomizer.thirdNumber == 0) ? 1 : randomizer.thirdNumber
let fourthNumber = (randomizer.fourthNumber == 0) ? 1 : randomizer.fourthNumber
result = firstNumber * secondNumber * thirdNumber * fourthNumber
case .hard2:
result = (randomizer.firstNumber*10 + randomizer.secondNumber) * (randomizer.thirdNumber*10 + randomizer.fourthNumber)
}
return result
}
И, наконец, нужно реализовать методы протокола Game
.
Метод greet(with exitWord: String)
:
func greet(with exitWord: String) {
let randomizer = Randomizer()
self.result = self.result(with: self.level, and: randomizer)
let task = BaseGreeting.replacingOccurrences(of: FirstNumberPlaceholder, with: "\(randomizer.firstNumber)")
.replacingOccurrences(of: SecondNumberPlaceholder, with: "\(randomizer.secondNumber)")
.replacingOccurrences(of: ThirdNumberPlaceholder, with: "\(randomizer.thirdNumber)")
.replacingOccurrences(of: FourthNumberPlaceholder, with: "\(randomizer.fourthNumber)")
print(TaskMessage.replacingOccurrences(of: TaskPlaceholder, with: task)
.replacingOccurrences(of: ExitWordPlaceholder, with: exitWord))
}
Тут мы создаем новый Randomizer
и рассчитываем правильный ответ для текущего уровня сложности. После чего показываем пользователю задание.
Метод check(userAnswer: String)
:
func check(userAnswer: String) {
if self.result == UInt32(userAnswer) {
print(CorrectMessage)
} else {
print(WrongMessage)
}
}
Тут все просто: мы просто сравниваем правильный ответ с тем, что ввел пользователь и выводим информационное сообщение на экран.
Итак полный текст класса в Swift выглядит так:
private let LevelsPlaceholder = "{levels}"
private let LevelNumberPlaceholder = "{levelNumber}"
private let LevelPlaceholder = "{level}"
private let FirstNumberPlaceholder = "{firstNumber}"
private let SecondNumberPlaceholder = "{secondNumber}"
private let ThirdNumberPlaceholder = "{thirdNumber}"
private let FourthNumberPlaceholder = "{fourthNumber}"
private let ExitWordPlaceholder = "{exitWord}"
private let TaskPlaceholder = "{taskPlaceholder}"
private let StartGreeting = "Hello, let's play. Please select difficulty level:\(LevelsPlaceholder)"
private let LevelForSelect = "\n\(LevelNumberPlaceholder) - \(LevelPlaceholder)"
private let BaseGreeting = "\(FirstNumberPlaceholder) \(SecondNumberPlaceholder) \(ThirdNumberPlaceholder) \(FourthNumberPlaceholder)"
private let TaskMessage = "The next task is \(TaskPlaceholder)\n(enter \"\(ExitWordPlaceholder)\" for exit)"
private let CorrectMessage = "Absolutely right.\n"
private let WrongMessage = "Sorry, you made a mistake. Try again.\n"
private let ErrorLevelMessage = "Sorry, you have selected wrong level. Good bye.\n"
class Game8037: Game {
private enum Level: String {
case easy
case normal
case hard1
case hard2
func forSelect() -> String {
return LevelForSelect.replacingOccurrences(of: LevelPlaceholder, with: self.rawValue)
.replacingOccurrences(of: LevelNumberPlaceholder, with: "\(self.hashValue+1)")
}
}
private var level: Level
private var result: UInt32
init?() {
self.result = 0
let levels = Level.easy.forSelect() + Level.normal.forSelect() + Level.hard1.forSelect() + Level.hard2.forSelect()
print(StartGreeting.replacingOccurrences(of: LevelsPlaceholder, with: levels))
let selectedLevel = readLine() ?? ""
switch selectedLevel {
case "\(Level.easy.hashValue+1)", Level.easy.rawValue:
self.level = .easy
case "\(Level.normal.hashValue+1)", Level.normal.rawValue:
self.level = .normal
case "\(Level.hard1.hashValue+1)", Level.hard1.rawValue:
self.level = .hard1
case "\(Level.hard2.hashValue+1)", Level.hard2.rawValue:
self.level = .hard2
default:
print(ErrorLevelMessage)
return nil
}
}
private func result(with level: Level, and randomizer: Randomizer) -> UInt32 {
let result: UInt32
switch level {
case .easy:
result = randomizer.firstNumber + randomizer.secondNumber + randomizer.thirdNumber + randomizer.fourthNumber
case .normal:
result = randomizer.firstNumber*10 + randomizer.secondNumber + randomizer.thirdNumber*10 + randomizer.fourthNumber
case .hard1:
let firstNumber = (randomizer.firstNumber == 0) ? 1 : randomizer.firstNumber
let secondNumber = (randomizer.secondNumber == 0) ? 1 : randomizer.secondNumber
let thirdNumber = (randomizer.thirdNumber == 0) ? 1 : randomizer.thirdNumber
let fourthNumber = (randomizer.fourthNumber == 0) ? 1 : randomizer.fourthNumber
result = firstNumber * secondNumber * thirdNumber * fourthNumber
case .hard2:
result = (randomizer.firstNumber*10 + randomizer.secondNumber) * (randomizer.thirdNumber*10 + randomizer.fourthNumber)
}
return result
}
// MARK: - Game
func greet(with exitWord: String) {
let randomizer = Randomizer()
self.result = self.result(with: self.level, and: randomizer)
let task = BaseGreeting.replacingOccurrences(of: FirstNumberPlaceholder, with: "\(randomizer.firstNumber)")
.replacingOccurrences(of: SecondNumberPlaceholder, with: "\(randomizer.secondNumber)")
.replacingOccurrences(of: ThirdNumberPlaceholder, with: "\(randomizer.thirdNumber)")
.replacingOccurrences(of: FourthNumberPlaceholder, with: "\(randomizer.fourthNumber)")
print(TaskMessage.replacingOccurrences(of: TaskPlaceholder, with: task)
.replacingOccurrences(of: ExitWordPlaceholder, with: exitWord))
}
func check(userAnswer: String) {
if self.result == UInt32(userAnswer) {
print(CorrectMessage)
} else {
print(WrongMessage)
}
}
}
Реализация этого же класса в Objective-C:
// файл заголовка Game8037.h
@interface Game8037 : NSObject <Game>
@end
// файл реализации GameStart.m
const NSString *EasyLevelNumber = @"1";
const NSString *NormalLevelNumber = @"2";
const NSString *Hard1LevelNumber = @"3";
const NSString *Hard2LevelNumber = @"4";
const NSString *EasyLevelName = @"easy";
const NSString *NormalLevelName = @"normal";
const NSString *Hard1LevelName = @"hard1";
const NSString *Hard2LevelName = @"hard2";
const NSString *StartGreeting = @"Hello, let's play. Please select difficulty level:%@";
const NSString *LevelForSelect = @"\n%@ - %@";
const NSString *BaseGreeting = @"%i %i %i %i";
const NSString *TaskMessage = @"The next task is %@\n(enter \"%@\" for exit)";
const NSString *CorrectMessage = @"Absolutely right.\n";
const NSString *WrongMessage = @"Sorry, you made a mistake. Try again.\n";
const NSString *ErrorLevelMessage = @"Sorry, you have selected wrong level. Good bye.\n";
typedef enum {
LevelEasy,
LevelNormal,
LevelHard1,
LevelHard2
} Level;
@interface Game8037()
@property (assign, nonatomic) Level level;
@property (assign, nonatomic) NSInteger result;
@end
@implementation Game8037
- (instancetype)init
{
self = [super init];
if (self) {
self.result = 0;
NSString *levels = [NSString stringWithFormat:@"%@%@%@%@",
[self levelForSelect:LevelEasy],
[self levelForSelect:LevelNormal],
[self levelForSelect:LevelHard1],
[self levelForSelect:LevelHard2]];
NSLog(StartGreeting, levels);
NSString *selectedLevel = [self readLine];
if ([selectedLevel isEqualToString:EasyLevelNumber] || [selectedLevel isEqualToString:EasyLevelName]) {
self.level = LevelEasy;
} else if ([selectedLevel isEqualToString:NormalLevelNumber] || [selectedLevel isEqualToString:NormalLevelName]) {
self.level = LevelNormal;
} else if ([selectedLevel isEqualToString:Hard1LevelNumber] || [selectedLevel isEqualToString:Hard1LevelName]) {
self.level = LevelHard1;
} else if ([selectedLevel isEqualToString:Hard2LevelNumber] || [selectedLevel isEqualToString:Hard2LevelName]) {
self.level = LevelHard2;
} else {
NSLog(@"%@", ErrorLevelMessage);
return nil;
}
}
return self;
}
- (NSString *)levelForSelect:(Level)level {
NSString *levelNumber;
NSString *levelName;
switch (level) {
case LevelEasy:
levelNumber = EasyLevelNumber;
levelName = EasyLevelName;
break;
case LevelNormal:
levelNumber = NormalLevelNumber;
levelName = NormalLevelName;
break;
case LevelHard1:
levelNumber = Hard1LevelNumber;
levelName = Hard1LevelName;
break;
case LevelHard2:
levelNumber = Hard2LevelNumber;
levelName = Hard2LevelName;
break;
}
return [NSString stringWithFormat:LevelForSelect, levelNumber, levelName];
}
- (NSInteger)resultWithLevel:(Level)level andRandomizer:(Randomizer *)randomizer {
NSInteger result = 0;
switch (level) {
case LevelEasy:
result = randomizer.firstNumber + randomizer.secondNumber + randomizer.thirdNumber + randomizer.fourthNumber;
break;
case LevelNormal:
result = randomizer.firstNumber*10 + randomizer.secondNumber + randomizer.thirdNumber*10 + randomizer.fourthNumber;
break;
case LevelHard1:
result = (randomizer.firstNumber == 0 ? 1 : randomizer.firstNumber) * (randomizer.secondNumber == 0 ? 1 : randomizer.secondNumber) * (randomizer.thirdNumber == 0 ? 1 : randomizer.thirdNumber) * (randomizer.fourthNumber == 0 ? 1 : randomizer.fourthNumber);
break;
case LevelHard2:
result = (randomizer.firstNumber*10 + randomizer.secondNumber) * (randomizer.thirdNumber*10 + randomizer.fourthNumber);
break;
}
return result;
}
- (NSString *)descriptionOfLevel:(Level)level {
NSString *result = @"";
switch (level) {
case LevelEasy:
result = EasyLevelName;
break;
case LevelNormal:
result = NormalLevelName;
break;
case LevelHard1:
result = Hard1LevelName;
break;
case LevelHard2:
result = Hard2LevelName;
break;
}
return result;
}
- (NSString *)readLine {
char inputValue;
scanf("%s", &inputValue);
return [NSString stringWithUTF8String:&inputValue];
}
#pragma mark - Game
- (void)greetWithExitWord:(NSString *)exitWord {
Randomizer *randomizer = [[Randomizer alloc] init];
self.result = [self resultWithLevel:self.level andRandomizer:randomizer];
NSString *task = [NSString stringWithFormat:BaseGreeting,
randomizer.firstNumber,
randomizer.secondNumber,
randomizer.thirdNumber,
randomizer.fourthNumber];
NSLog(TaskMessage, task, exitWord);
}
- (void)checkUserAnswer:(NSString *)userAnswer {
if (self.result == [userAnswer integerValue]) {
NSLog(@"%@", CorrectMessage);
} else {
NSLog(@"%@", WrongMessage);
}
}
@end
Java:
public class Game8037 implements Game {
private static final String EasyLevelNumber = "1";
private static final String NormalLevelNumber = "2";
private static final String Hard1LevelNumber = "3";
private static final String Hard2LevelNumber = "4";
private static final String EasyLevelName = "easy";
private static final String NormalLevelName = "normal";
private static final String Hard1LevelName = "hard1";
private static final String Hard2LevelName = "hard2";
private static final String StartGreeting = "Hello, let's play. Please select difficulty level:%s";
private static final String LevelForSelect = "\n%s - %s";
private static final String BaseGreeting = "%s %s %s %s";
private static final String TaskMessage = "The next task is %s\n(enter \"%s\" for exit)";
private static final String CorrectMessage = "Absolutely right.\n";
private static final String WrongMessage = "Sorry, you made a mistake. Try again.\n";
private static final String ErrorLevelMessage = "Sorry, you have selected wrong level. Good bye.\n";
private enum Level {
Easy {
public String toString() {
return EasyLevelName;
}
},
Normal {
public String toString() {
return NormalLevelName;
}
},
Hard1 {
public String toString() {
return Hard1LevelName;
}
},
Hard2 {
public String toString() {
return Hard2LevelName;
}
}
}
private Level level;
private int result;
private Game8037(Level level) {
this.level = level;
this.result = 0;
}
@Nullable
public static Game8037 Create() {
String levels = String.format("%s%s%s%s", levelForSelect(Level.Easy), levelForSelect(Level.Normal), levelForSelect(Level.Hard1), levelForSelect(Level.Hard2));
System.out.println(String.format(StartGreeting, levels));
Game8037 game8037;
String selectedLevel = readLine();
switch (selectedLevel) {
case EasyLevelNumber:
case EasyLevelName:
game8037 = new Game8037(Level.Easy);
break;
case NormalLevelNumber:
case NormalLevelName:
game8037 = new Game8037(Level.Normal);
break;
case Hard1LevelNumber:
case Hard1LevelName:
game8037 = new Game8037(Level.Hard1);
break;
case Hard2LevelNumber:
case Hard2LevelName:
game8037 = new Game8037(Level.Hard2);
break;
default:
game8037 = null;
System.out.println(ErrorLevelMessage);
break;
}
return game8037;
}
private static String levelForSelect(Level level) {
String levelNumber = "";
String levelName = "";
switch (level) {
case Easy:
levelNumber = EasyLevelNumber;
levelName = EasyLevelName;
break;
case Normal:
levelNumber = NormalLevelNumber;
levelName = NormalLevelName;
break;
case Hard1:
levelNumber = Hard1LevelNumber;
levelName = Hard1LevelName;
break;
case Hard2:
levelNumber = Hard2LevelNumber;
levelName = Hard2LevelName;
break;
}
return String.format(LevelForSelect, levelNumber, levelName);
}
private int resultWithLevelAndRandomizer(Level level, Randomizer randomizer) {
int result = 0;
switch (level) {
case Easy:
result = randomizer.firstNumber + randomizer.secondNumber + randomizer.thirdNumber + randomizer.fourthNumber;
break;
case Normal:
result = randomizer.firstNumber*10 + randomizer.secondNumber + randomizer.thirdNumber*10 + randomizer.fourthNumber;
break;
case Hard1:
int firstNumber = (randomizer.firstNumber == 0) ? 1 : randomizer.firstNumber;
int secondNumber = (randomizer.secondNumber == 0) ? 1 : randomizer.secondNumber;
int thirdNumber = (randomizer.thirdNumber == 0) ? 1 : randomizer.thirdNumber;
int fourthNumber = (randomizer.fourthNumber == 0) ? 1 : randomizer.fourthNumber;
result = firstNumber * secondNumber * thirdNumber * fourthNumber;
break;
case Hard2:
result = (randomizer.firstNumber*10 + randomizer.secondNumber) * (randomizer.thirdNumber*10 + randomizer.fourthNumber);
break;
}
return result;
}
static private String readLine() {
java.util.Scanner scanner = new java.util.Scanner(System.in);
return scanner.next();
}
@Override
public void greet(String exitWord) {
Randomizer randomizer = new Randomizer();
result = resultWithLevelAndRandomizer(level, randomizer);
String task = String.format(BaseGreeting, randomizer.firstNumber, randomizer.secondNumber, randomizer.thirdNumber, randomizer.fourthNumber);
System.out.println(String.format(TaskMessage, task, exitWord));
}
@Override
public void checkUserAnswer(String userAnswer) {
int answer;
try {
answer = Integer.parseInt(userAnswer);
} catch (Exception e) {
System.out.println(WrongMessage);
return;
}
if (result == answer) {
System.out.println(CorrectMessage);
} else {
System.out.println(WrongMessage);
}
}
}
C#:
public class Game8037 : IGame
{
const string EasyLevelNumber = "1";
const string NormalLevelNumber = "2";
const string Hard1LevelNumber = "3";
const string Hard2LevelNumber = "4";
const string EasyLevelName = "easy";
const string NormalLevelName = "normal";
const string Hard1LevelName = "hard1";
const string Hard2LevelName = "hard2";
const string StartGreeting = "Hello, let's play. Please select difficulty level:{0}";
const string LevelForSelect = "\n{0} - {1}";
const string BaseGreeting = "{0} {1} {2} {3}";
const string TaskMessage = "The next task is {0}\n(enter \"{1}\" for exit)";
const string CorrectMessage = "Absolutely right.\n";
const string WrongMessage = "Sorry, you made a mistake. Try again.\n";
const string ErrorLevelMessage = "Sorry, you have selected wrong level. Good bye.\n";
enum Level { Easy, Normal, Hard1, Hard2 };
Level level;
int result;
private Game8037(Level level)
{
this.level = level;
result = 0;
}
public static Game8037 Create()
{
string levels = string.Format("{0}{1}{2}{3}", levelForSelect(Level.Easy), levelForSelect(Level.Normal), levelForSelect(Level.Hard1), levelForSelect(Level.Hard2));
Console.WriteLine(string.Format(StartGreeting, levels));
Game8037 game8037;
string selectedLevel = Console.ReadLine();
switch (selectedLevel)
{
case EasyLevelNumber:
case EasyLevelName:
game8037 = new Game8037(Level.Easy);
break;
case NormalLevelNumber:
case NormalLevelName:
game8037 = new Game8037(Level.Normal);
break;
case Hard1LevelNumber:
case Hard1LevelName:
game8037 = new Game8037(Level.Hard1);
break;
case Hard2LevelNumber:
case Hard2LevelName:
game8037 = new Game8037(Level.Hard2);
break;
default:
game8037 = null;
Console.WriteLine(ErrorLevelMessage);
break;
}
return game8037;
}
static string levelForSelect(Level level)
{
string levelNumber = "";
string levelName = "";
switch (level)
{
case Level.Easy:
levelNumber = EasyLevelNumber;
levelName = EasyLevelName;
break;
case Level.Normal:
levelNumber = NormalLevelNumber;
levelName = NormalLevelName;
break;
case Level.Hard1:
levelNumber = Hard1LevelNumber;
levelName = Hard1LevelName;
break;
case Level.Hard2:
levelNumber = Hard2LevelNumber;
levelName = Hard2LevelName;
break;
}
return string.Format(LevelForSelect, levelNumber, levelName);
}
int resultWithLevelAndRandomizer(Level level, Randomizer randomizer)
{
int result = 0;
switch (level)
{
case Level.Easy:
result = randomizer.firstNumber + randomizer.secondNumber + randomizer.thirdNumber + randomizer.fourthNumber;
break;
case Level.Normal:
result = randomizer.firstNumber * 10 + randomizer.secondNumber + randomizer.thirdNumber * 10 + randomizer.fourthNumber;
break;
case Level.Hard1:
int firstNumber = (randomizer.firstNumber == 0) ? 1 : randomizer.firstNumber;
int secondNumber = (randomizer.secondNumber == 0) ? 1 : randomizer.secondNumber;
int thirdNumber = (randomizer.thirdNumber == 0) ? 1 : randomizer.thirdNumber;
int fourthNumber = (randomizer.fourthNumber == 0) ? 1 : randomizer.fourthNumber;
result = firstNumber* secondNumber * thirdNumber * fourthNumber;
break;
case Level.Hard2:
result = (randomizer.firstNumber * 10 + randomizer.secondNumber) * (randomizer.thirdNumber * 10 + randomizer.fourthNumber);
break;
}
return result;
}
string descriptionOfLevel(Level level)
{
string result = "";
switch (level)
{
case Level.Easy:
result = "easy";
break;
case Level.Normal:
result = "normal";
break;
case Level.Hard1:
result = "hard1";
break;
case Level.Hard2:
result = "hard2";
break;
}
return result;
}
public void greet(string exitWord)
{
Randomizer randomizer = new Randomizer();
result = resultWithLevelAndRandomizer(level, randomizer);
string task = string.Format(BaseGreeting, randomizer.firstNumber, randomizer.secondNumber, randomizer.thirdNumber, randomizer.fourthNumber);
Console.WriteLine(string.Format(TaskMessage, task, exitWord));
}
public void checkUserAnswer(string userAnswer)
{
int answer;
try
{
answer = int.Parse(userAnswer);
}
catch
{
Console.WriteLine(WrongMessage);
return;
}
if (result == answer)
{
Console.WriteLine(CorrectMessage);
}
else
{
Console.WriteLine(WrongMessage);
}
}
}
В Java и C# есть нюанс при создании объекта класса Game8037
. Дело в том, что здесь нет failable инициализаторов, поэтому мы воспользовались статическим методом для создания объекта.
Нам остается добавить создание нашей игры в класс GameStart
и воспользоваться методами greet(...)
и check(...)
. Теперь класс GameStart
выглядит так.
Swift:
class GameStart {
private var exitWord: String
private var game: Game
init?(with exitWord: String) {
self.exitWord = exitWord
if let game = Game8037() {
self.game = game
} else {
return nil
}
}
func startGame() {
var inputWord: String
repeat {
self.game.greet(with: self.exitWord)
inputWord = readLine() ?? ""
} while check(inputWord: inputWord)
}
private func check(inputWord: String) -> Bool {
let isExitWord = (inputWord == self.exitWord)
if isExitWord {
print(GoodByeMessage)
} else {
self.game.check(userAnswer: inputWord)
}
return !isExitWord
}
}
Objective-C:
@interface GameStart()
@property (strong, nonatomic) NSString *exitWord;
@property (strong, nonatomic) id<Game> game;
@end
@implementation GameStart
- (instancetype)initWithExitWord:(NSString *)exitWord {
self = [super init];
if (self) {
self.exitWord = exitWord;
self.game = [[Game8037 alloc] init];
}
return self;
}
- (void)startGame {
if (self.game) {
NSString *inputWord;
do {
[self.game greetWithExitWord:self.exitWord];
inputWord = [self readLine];
} while ([self checkInputWord:inputWord]);
}
}
- (BOOL)checkInputWord:(NSString *)inputWord {
BOOL isExitWord = [inputWord isEqualToString:self.exitWord];
if (isExitWord) {
NSLog(@"%@", GoodByeMessage);
} else {
[self.game checkUserAnswer:inputWord];
}
return !isExitWord;
}
- (NSString *)readLine {
char inputValue;
scanf("%s", &inputValue);
return [NSString stringWithUTF8String:&inputValue];
}
@end
Java:
public class GameStart {
private static final String GreetingMessage = "Please enter your answer (enter \"%s\" for exit):";
private static final String InputAcceptMessage = "You entered \"%s\".\n";
private static final String GoodByeMessage = "Good bye.\n";
private String exitWord;
private Game game;
public GameStart(String exitWord) {
this.exitWord = exitWord;
this.game = Game8037.Create();
}
void startGame() {
if (game != null) {
String inputWord;
do {
game.greet(exitWord);
inputWord = readLine();
} while (checkInputWord(inputWord));
}
}
private boolean checkInputWord(String inputWord) {
boolean isExitWord = inputWord.equals(exitWord);
if (isExitWord) {
System.out.println(GoodByeMessage);
} else {
game.checkUserAnswer(inputWord);
}
return !isExitWord;
}
private String readLine() {
java.util.Scanner scanner = new java.util.Scanner(System.in);
return scanner.next();
}
}
C#:
public class GameStart
{
const string GreetingMessage = "Please enter your answer (enter \"{0}\" for exit):";
const string InputAcceptMessage = "You entered \"{0}\".\n";
const string GoodByeMessage = "Good bye.\n";
readonly string exitWord;
readonly IGame iGame;
public GameStart(string exitWord)
{
this.exitWord = exitWord;
iGame = Game8037.Create();
}
public void startGame()
{
if (iGame != null)
{
string inputWord;
do
{
iGame.greet(exitWord);
inputWord = Console.ReadLine();
}
while (checkInputWord(inputWord));
}
}
bool checkInputWord(string inputWord)
{
bool isExitWord = inputWord.Equals(exitWord);
if (isExitWord)
{
Console.WriteLine(GoodByeMessage);
}
else
{
iGame.checkUserAnswer(inputWord);
}
return !isExitWord;
}
}
Как видите, у нас добавилось свойство game
типа Game
(или IGame
в C#). Также в методе startGame()
мы вызываем self.game.greet(...)
, а в методе check(...)
— self.game.check(...)
. Таким образом, в будущем можно будет вместо Game8037
подставить туда любую другую игру, которая реализует наш протокол Game
.
Заключение
На этом работа над нашим приложением окончена, исходный код всего этого можно найти здесь. Всем спасибо за внимание, замечания, критику, советы, пожелания. :)