Pull to refresh

Автономер на четырех языках. Часть 1

Reading time6 min
Views6.8K

Небольшое вступление


Я попал в мир IT относительно недавно: всего два года я занимаюсь разработкой приложений под iOS. Но кроме Objective-C и Swift меня всегда манил мир Java и C#. Периодически я выделял время, чтоб посмотреть какие-то видео, обучающие основам этих языков, но дальше простого просмотра и переписывания кода с экрана дело не заходило. И тут я вспомнил об одной математической игре, которую мне однажды посоветовал мой друг.


Суть игры заключается в следующем: вы идете по улице и смотрите на автомобильные номера. И в каждом номере считаете сумму всех цифр (например, в номере 8037 нужно посчитать 8 + 0 + 3 + 7). Это самый простой уровень игры. Второй по сложности уровень — посчитать сумму первой половины номера и второй (80 + 37). Есть еще третий уровень — умножить все цифры (нули при этом пропустив: 8 х 3 х 7) и четвертый — умножить первую половину номера на вторую (80 х 37).


В общем: эту игру (в консольном варианте) я и решил написать на четырех языках: Swift, Objective-C, Java и C#. Что из этого получилось? Давайте посмотрим.


С чего начнем?


Начнем мы с создания пустых проектов под консольные приложения: для Swift и Objective-C будем использовать Xcode, для Java — естественно IntelliJ IDEA, а для C# — Xamarin Studio.


Первым делом напишем вспомогательный класс GameStart. Он у нас будет заниматься запросом ответа от пользователя пока тот не введет ключевое слово для выхода из приложения.


Swift


Создадим сам класс:


class GameStart {

}

В нем у нас будет свойство exitWord и инициализатор:


private var exitWord: String

init(with exitWord: String) {
    self.exitWord = exitWord
}

Это и будет наше ключевое слово.


Также в нем будет метод startGame который будет постоянно спрашивать у пользователя ответ, пока тот не введет слово для выхода:


func startGame() {
    print(GreetingMessage.replacingOccurrences(of: ExitWordPlaceholder, with: self.exitWord))
    guard let inputWord = readLine() else {
        print(ErrorMessage)
        return
    }

    self.check(inputWord: inputWord)
}

private func check(inputWord: String) {
    if inputWord == self.exitWord {
        print(GoodByeMessage)
    } else {
        print(InputAcceptMessage.replacingOccurrences(of: InputWordPlaceholder, with: inputWord))
        startGame()
    }
}

Как видите, метод startGame приветствует пользователя, затем считывает из командной строки то что ввел пользователь, и передает полученную строку в метод check(inputWord:).


Строковые константы, которые были использованы:


private let ExitWordPlaceholder = "{exitWord}"
private let InputWordPlaceholder = "{inputWord}"

private let GreetingMessage = "Please enter your answer (enter \"\(ExitWordPlaceholder)\" for exit):"
private let InputAcceptMessage = "You entered \"\(InputWordPlaceholder)\".\n"
private let GoodByeMessage = "Good bye.\n"
private let ErrorMessage = "There is unknown error, sorry. Good bye.\n"

Наш класс готов, теперь нужно создать объект и вызвать метод startGame():


let gameStart = GameStart(with: "quit")
gameStart.startGame()

В консоли это выглядит примерно вот так:



Теперь напишем этот же класс на Objective-C:


// файл заголовка GameStart.h
@interface GameStart : NSObject

- (instancetype)initWithExitWord:(NSString *)exitWord;
- (void)startGame;

@end

// файл реализации GameStart.m
const NSString *GreetingMessage = @"Please enter your answer (enter \"%@\" for exit):";
const NSString *InputAcceptMessage = @"You entered \"%@\".\n";
const NSString *GoodByeMessage = @"Good bye.\n";
const NSString *ErrorMessage = @"There is unknown error, sorry. Good bye.\n";

@interface GameStart()

@property (strong, nonatomic) NSString *exitWord;

@end

@implementation GameStart

- (instancetype)initWithExitWord:(NSString *)exitWord {
    self = [super init];
    if (self) {
        self.exitWord = exitWord;
    }
    return self;
}

- (void)startGame {
    NSLog(GreetingMessage, self.exitWord);
    NSString *inputWord = [self readLine];

    if (inputWord) {
        [self checkInputWord:inputWord];
    } else {
        NSLog(@"%@", ErrorMessage);
    }
}

- (void)checkInputWord:(NSString *)inputWord {
    if ([inputWord isEqualToString:self.exitWord]) {
        NSLog(@"%@", GoodByeMessage);
    } else {
        NSLog(InputAcceptMessage, inputWord);
        [self startGame];
    }
}

- (NSString *)readLine {
    char inputValue;
    scanf("%s", &inputValue);
    return [NSString stringWithUTF8String:&inputValue];
}

@end

Ну и создание объекта с вызовом метода:


GameStart *gameStart = [[GameStart alloc] initWithExitWord:@"quit"];
[gameStart startGame];

Дальше у нас на очереди Java.


Класс GameStart:


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;

    public GameStart(String exitWord) {
        this.exitWord = exitWord;
    }

    void startGame() {
        System.out.println(String.format(GreetingMessage, exitWord));
        String inputWord = readLine();

        checkInputWord(inputWord);
    }

    private void checkInputWord(String inputWord) {
        if (inputWord.equals(exitWord)) {
            System.out.println(GoodByeMessage);
        } else {
            System.out.println(String.format(InputAcceptMessage, inputWord));
            startGame();
        }
    }

    private String readLine() {
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        return scanner.next();
    }

}

И вызов:


GameStart gameStart = new GameStart("quit");
gameStart.startGame();

И завершает четверку лидеров 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;

    public GameStart(string exitWord)
    {
        this.exitWord = exitWord;
    }

    public void startGame()
    {
        Console.WriteLine(string.Format(GreetingMessage, exitWord));
        string inputWord = Console.ReadLine();

        checkInputWord(inputWord);
    }

    void checkInputWord(string inputWord)
    {
        if (inputWord.Equals(exitWord))
        {
            Console.WriteLine(GoodByeMessage);
        }
        else
        {
            Console.WriteLine(string.Format(InputAcceptMessage, inputWord));
            startGame();
        }
    }
}

Вызов:


GameStart gameStart = new GameStart("quit");
gameStart.startGame();

Немного рандома не повредит


Также добавим в проект вспомогательный класс, который будет формировать наш автомобильный номер (номер должен состоять из четырех случайных цифр). Сам класс назовем просто — Randomizer.


Swift:


class Randomizer {

    var firstNumber: UInt32
    var secondNumber: UInt32
    var thirdNumber: UInt32
    var fourthNumber: UInt32

    init() {
        self.firstNumber = arc4random() % 10
        self.secondNumber = arc4random() % 10
        self.thirdNumber = arc4random() % 10
        self.fourthNumber = arc4random() % 10
    }
}

Objective-C:


// файл заголовка Randomizer.h
@interface Randomizer : NSObject

@property (assign, nonatomic) NSInteger firstNumber;
@property (assign, nonatomic) NSInteger secondNumber;
@property (assign, nonatomic) NSInteger thirdNumber;
@property (assign, nonatomic) NSInteger fourthNumber;

@end

// файл реализации Randomizer.m
@implementation Randomizer

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.firstNumber = arc4random() % 10;
        self.secondNumber = arc4random() % 10;
        self.thirdNumber = arc4random() % 10;
        self.fourthNumber = arc4random() % 10;
    }
    return self;
}

@end

Java:


public class Randomizer {

    private static Random random = new Random();

    int firstNumber;
    int secondNumber;
    int thirdNumber;
    int fourthNumber;

    public Randomizer() {
        firstNumber = random.nextInt(10);
        secondNumber = random.nextInt(10);
        thirdNumber = random.nextInt(10);
        fourthNumber = random.nextInt(10);
    }

}

C#:


public class Randomizer
{
    static readonly Random random = new Random();

    public int firstNumber;
    public int secondNumber;
    public int thirdNumber;
    public int fourthNumber;

    public Randomizer()
    {
        firstNumber = random.Next(10);
        secondNumber = random.Next(10);
        thirdNumber = random.Next(10);
        fourthNumber = random.Next(10);
    }
}

Как видите, при инициализации мы просто заполняем четыре поля в классе случайными целыми числами от 0 до 9.


Универсальность наше все


Несмотря на то, что в нашем приложении будет всего одна игра, мы сделаем вид, что предусматриваем расширяемость приложения в будущем. Поэтому добавим интерфейс (для Swift и Objective-C — протокол) Game с методами greet(with exitWord: String) и check(userAnswer: String).


Swift:


protocol Game {

    func greet(with exitWord: String)
    func check(userAnswer: String)

}

Objective-C:


@protocol Game <NSObject>

- (void)greetWithExitWord:(NSString *)exitWord;
- (void)checkUserAnswer:(NSString *)userAnswer;

@end

Java:


public interface Game {

    void greet(String exitWord);
    void checkUserAnswer(String userAnswer);

}

C#:


public interface IGame
{
    void greet(string exitWord);
    void checkUserAnswer(string userAnswer);
}

На этом первую часть я закончу. Реализацию самой игры с выбором уровня сложности, проверкой ответа игрока на корректность, с блэкджеком и ... мы сделаем во второй части. Всем добра. :)

Tags:
Hubs:
Total votes 17: ↑13 and ↓4+9
Comments26

Articles