Имитация последовательности ходов в пошаговой игре с одним человеком - PullRequest
0 голосов
/ 29 марта 2012

Я работаю над пошаговой карточной игрой.Основной цикл прост, у меня есть эта структура (она очень упрощенная, чтобы быть краткой):

while (!gameEnded) {
    for (Player *pl in players) {
        Action *a = [pl askForAction];
        self [manageAction];
    }
    if (some condition...) {
        gameEnded = TRUE;
    }
}

Если все игроки являются компьютерными игроками, то нет проблем, но если я хочу иметь игрока-человека, askForActionметод должен «приостановить» цикл и позволить игроку выбрать действие (нажатие кнопки или касание карты ...)

Как я могу это сделать?Я "гуглил" это, но ничего не могу найти.Я полагаю, что решением должно быть использование NSThread (или, может быть, NSRunLoop ...), но я не могу найти подход.Кто-нибудь может мне помочь?

Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 29 марта 2012

Способ, которым я бы это сделал (возможно, есть лучшие ответы), заключается в использовании модели, управляемой событиями, а не в цикле.

В делегате (или где-либо еще) отслеживайте текущего игрока (индекс в массиве игроков). Звоните [[players objectAtIndex:currentPlayer] askForActionWithDelegate:self];

В делегате есть получатель (вы можете использовать manageAction), а когда пользователь выполнил действие, позвоните manageAction. В manageAction проверьте состояние победы и продвиньтесь currentPlayer.

3 голосов
/ 29 марта 2012

Как говорит Адам, модель, управляемая событиями, вероятно, лучшая.Тем не менее, я просто хочу подчеркнуть, насколько просто решить эту проблему, и нет необходимости в чем-либо вроде NSThread или NSRunLoop.

Вы просто прекращаете итерацию, когда попадаете на человека-игрока, а затем начинаете итерацию снова, как только получаете от них действие:

- (void)nextTurn
    while (!gameEnded) {
        Player *pl = [self nextPlayer];
        if (pl.isHuman) {
            break;
        } else {
            Action *a = [pl getActionFromComputer];
            [self manageAction:a];
        }
    }
    if (gameEnded) {
        // game over
    } else {
        // Set up your UI so it can get an action from the player.
        // Your UI should be set up so that once it gets an action,
        // it does [self manageAction:uiAction] then [self nextTurn]
    }
}
0 голосов
/ 09 апреля 2012

Извините за задержку. Я применил этот подход, и это то, что я хочу. Я сделал это следующим образом:

- (void)consumeTurn:(int)idPlayer {
    if (![gameEnded]) {
        Player *p = [getPlayer:idPlayer];
        if (![p isHuman]) {
            /** Do some stuff **/
            consumeTurn:[getNextPlayer];
        } else {
            /** Show UIView with buttons for human player interaction **/
        }
    } else {
        /** Game is ended... **/
    }
}

И затем для каждой кнопки действие, связанное с каждой кнопкой:

- (IBAction)playerAction {
    /** Do some stuff **/
    consumeTurn:[getNextPlayer];
}

Я вызываю метод потребление в моем основном ViewController (viewDidLoad).

Спасибо всем за помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...