Небольшое вступление
Я попал в мир 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);
}
На этом первую часть я закончу. Реализацию самой игры с выбором уровня сложности, проверкой ответа игрока на корректность, с блэкджеком и ... мы сделаем во второй части. Всем добра. :)