2014-12-16 5 views
1

Я пишу палач-игру в PHP и JS, и у меня возникают проблемы. У меня есть два массива: массив ответов, который имеет правильные буквы, и массив ответов пользователя, который содержит правильные догадки пользователей.Hangman update OO value array

Ответа на этом вопрос догадки массив пользователя начинает с подчеркиванием, поскольку никаких догадок не правильны _ _ _

Я хотел бы обновить этот массив и поставить правильное письмо в соответствующее поле, когда пользователь угадывает правильно _ A _ ;

Когда я var_dump внутри функции updateAnswer(), массив ответов пользователя изменился и добавил правильную букву, однако, когда я вытягиваю из returnUserAnswer, у массива нет.

PS. библиотека только вызывается один раз, поэтому __construct не является проблемой.

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

class Word { 

private $answer; 
public $usrAnswer; 

function __construct(){ 
$this->answer = array('C','A','T'); 
$this->usrAnswer = array('_','_','_'); 
} 
function returnUserAnswer(){ 
return $this->usrAnswer; 
} 

function updateAnswer($letter,$try){ 
    $change = array($try => $letter); 
    $this->usrAnswer = array_replace($this->usrAnswer,$change); 

} 

function guess($letter){ 

    $try = array_search($letter,$this->answer); 

    if($try === FALSE){ 
    return false; 
    }else{ 
    $this->updateAnswer($letter,$try);return $try;  
    } 

} 

} 

ответ

0

Из-за тега JavaScript я предполагаю, что вы пишете реализацию палача, которая использует запросы AJAX. Если это предположение верно, то это ваше утверждение является таким же ложным, как может быть:

PS. библиотека вызывается только один раз, поэтому __construct не проблема.

PHP не имеет гражданства. Это означает, что для каждого запроса, который получает сервер, ваш экземпляр создается, а когда отправляется ответ, все изменения во всех экземплярах теряются. В результате, вот что такое Аякса управляемый поток выглядит следующим образом:

[request 1] => new Word --> constructor initialize $usrAnswer to ['_','_','_'] 
             initialize $answer to ['C', 'A', 'T'] 
      => destroy instances and resources 
      => send response 

[request 2] => guess a letter (send via AJAX) 
      => new Word --> constructor is called, same as request 1 
      => update $usrAnswer 
      => destroy instance 
      => send response 

[request 3] => see [request 2] 
[request N] => see [request 2] 

Что вам нужно сделать, то есть иметь JavaScript отправить полное состояние угадали ответ на каждый запрос, а не только одну букву. Что-то вроде следующего объекта будет делать:

var requestData = { 
    state: { 
     validGuesses: ['A'], 
     invalidGuesses: ['X', 'Q'] //<-- number of attempts, check if current guess is not a duplicate 
    }, 
    guess: 'C' 
}; 

Затем на стороне сервера (в PHP), изменить конструктор, чтобы принимать аргументы (массив в этом случае будет делать). Как и в сторону, код ниже применяет coding standards, который я очень рекомендую вам следовать, тоже:

public function __construct(array $userState = array()) 
{ 
    $this->answer = ['C', 'A', 'T']; 
    $this->usrAnswer = ['_','_','_']; 
    foreach ($userState as $value) { 
     $key = array_search($value, $this->answer); 
     if ($key === false) { 
      //handle invalid state, I'd suggest: 
      throw new InvalidArgumentException(
       sprintf('%s is not a valid answer', $value) 
      ); 
     } 
     $this->usrAnswer[$key] = $value; 
    } 
} 

Теперь, когда вы звоните guess, значение $usrAnswer будет правильным.

Update:
Чтобы прояснить мой последний комментарий (о добавлении $answer аргумента конструктора), вот что я хотел бы сделать:

public function __construct($answer = 'CAT', array $state = []) 
{ 
    $this->answer = str_split(strtoupper($answer));//ensure upper-case, create array 
    //create array containing the correct amount of _ chars 
    $this->usrAnswer = array_fill(0, strlen($answer), '_'); 
    foreach ($state as $value) { 
     $key = array_search($value, $this->answer); 
     if ($key === false) { 
      throw new InvalidArgumentException(
       sprintf('%s is not a valid answer', $value) 
      ); 
     } 
     $this->usrAnswer[$key] = $value; 
    } 
    //replace _ with dash, if the answer contains dashes (eg ice-cream) 
    $pos = -1; 
    while (($pos = strpos($answer, '-', $pos +1)) !== false) { 
     $this->usrAnswer[$pos] = '-'; 
    } 
} 

Что касается использования класса, то, ничего действительно меняется:

$cat = new Word(); 

для когда Ajax запрос должен обработки исключения:

$cat = new Word('cat', $state);//where $state is the request data 

Другой пример:

$iceCream = new Word('ice-cream', ['C', 'A']); 
//sets usrAnswer to _C_-C__A_ 
$iceCream->guess('I'); 
//usrAnswer is now IC_-C__A_ 
+0

Спасибо вам большое, я не знал об этом, спасибо за обстоятельный ответ, который я должен изучить его! –

+0

@JoeSmith: Добро пожаловать. PS: Я также предлагаю вам разрешить второй аргумент в вашем конструкторе передать значение '$ answer' экземпляру:' public function __construct ($ answer, array $ userState = []); ', тогда вы можете использовать длина '$ answer' для создания массива' $ usrAnswer', что делает ваш класс более гибким. –

+0

@JoeSmith: Обновлен мой ответ, но чтобы получить дополнительную информацию о том, как вы можете улучшить свой класс, лучше всего представить свой код [по обзору кода] (http://codereview.stackexchange.com). Сайт только что закончил бета-стадию, и стоит посмотреть –