
Что такое 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);
}
}
@endJava:
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];
}
@endJava:
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.
Заключение
На этом работа над нашим приложением окончена, исходный код всего этого можно найти здесь. Всем спасибо за внимание, замечания, критику, советы, пожелания. :)
Комментарии (5)

StanZakharov
12.05.2017 11:39+2И из всего можно сделать вывод, что пишите код сразу на всех языках, они идентичные :-)
За Крымско-Украинские номера плюс летит. Давно таких тут нет.

chugunovkm
12.05.2017 13:48Статья ни о чем. На кол ее.

Pro-invader
13.05.2017 09:13Возможно, статья для новичков, чтобы показать, как можно построить структуру программы. Её можно написать в maine (как многие новички делают), а можно грамотно разбить на классы и методы.
Siemargl
Если смотреть по диагонали (слишком длинно всматриваться, не зная что искать), программы похожи почти как близнецы.
А какая мораль сей басни?