2014-11-27 5 views
1

Я работаю над простой карточной игрой Blackjack. Я использую этот код для расчета оценки пользователя:Функция, которая изменяет переменную, переданную вызывающей функцией

switch (label9.Text) 
{ 
    case "J": playerTotal = playerTotal + 10; break; 
    case "Q": playerTotal = playerTotal + 10; break; 
    case "K": playerTotal = playerTotal + 10; break; 
    case "A": playerTotal = playerTotal + 11; break; 
    default: playerTotal = playerTotal + Convert.ToInt32(label9.Text); break; 
} 

Но я не хочу писать это снова и снова. Так что я поместил этот код внутри функции:

public void score(Label n, int m) 
{ 
    switch (n.Text) 
    { 
     case "J": m += 10; break; 
     case "Q": m += 10; break; 
     case "K": m += 10; break; 
     case "A": m += 11; break; 
     default: m += Convert.ToInt32(n.Text); break; 
    } 
} 

Теперь вот проблема: Когда я называю score(label7, playerTotal) из другой функции, значение playerTotal не меняется. Например:

public void hitPlayer() 
{ 
    //ilk hit 
    if (hitCounter == 0) 
    { 
     label7.Text = newDeck.Last(); 
     playerHand[2] = newDeck.Last(); 
     newDeck = newDeck.Take(newDeck.Count() - 1).ToArray(); 
     label7.Visible = true; 
     pictureBox7.Visible = true; 

     score(label7, playerTotal); // <<===== 'playerTotal' does not change 
     aceFound(hitCounter); 
     label12.Text = playerTotal.ToString(); 
    } 

Однако, когда я использую switch/case код без окружив его внутри функции, значение playerTotalделает изменения. Что случилось с тем, как я называю функцию score()?

ответ

3

Третий вариант, который я предпочитаю, чтобы либо повторно назначения оценки или передачи его по ссылке:

public int getScore(Label n) 
{ 
    switch (n.Text) 
    { 
     case "J": 
     case "Q": 
     case "K": 
      return 10; 
     case "A": 
      return 11; 
     default: 
      return Convert.ToInt32(n.Text); 
    } 
} 

...

playerTotal += getScore(label7); 
4

Pass m в исх

public void score(Label n, ref int m) 
{ 
    switch (n.Text) 
    { 
     case "J": m += 10; break; 
     case "Q": m += 10; break; 
     case "K": m += 10; break; 
     case "A": m += 11; break; 
     default: m += Convert.ToInt32(n.Text); break; 
    } 
} 

Как было предложено

@ Андрей
public void score(Label n, ref int m) 
{ 
    switch (n.Text) 
    { 
     case "J": 
     case "Q": 
     case "K": m += 10; break; 
     case "A": m += 11; break; 
     default: m += Convert.ToInt32(n.Text); break; 
    } 
} 

score(label7, ref playerTotal); 
+3

Или вернуться м в конце функции! : P – Jite

+0

@Jite конечно, мне тоже не нравится использовать 'out' и 'ref'. – EZI

+0

Почему бы не присоединиться к корпусам JQK? – Andrew

2

Ваш метод счет должен возвратить м. m является целым числом и не рассматривается как ссылка. Любые изменения в m внутри вашего метода не изменят целое число, которое вы передали.

playerTotal = оценка (label7, playerTotal);

Вы можете изменить свой метод так, чтобы playerTotal рассматривался как ссылка, добавляя «ref», как указано в другом ответе, но это не очень хороший дизайн, так как ваш метод имеет только одно состояние успеха.

1

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

public void hitPlayer() 
    { 
     //ilk hit 
     if (hitCounter == 0) 
     { 
      label7.Text = newDeck.Last(); 
      playerHand[2] = newDeck.Last(); 
      newDeck = newDeck.Take(newDeck.Count() - 1).ToArray(); 
      label7.Visible = true; 
      pictureBox7.Visible = true; 

      **playerTotal** = score(label7, playerTotal); 
      aceFound(hitCounter); 
      label12.Text = playerTotal.ToString(); 


     } 

    public int score(Label n, int m) 
    { 
     switch (n.Text) 
     { 
      case "J": m += 10; break; 
      case "Q": m += 10; break; 
      case "K": m += 10; break; 
      case "A": m += 11; break; 
      default: m += Convert.ToInt32(n.Text); break; 

     } 
     return m; 
    } 

Надеюсь, это поможет.

1

Параметр int m в методе score является копия исходного значения. Вы меняете только эту копию.

Вам лучше отделить логику от любых таблиц и текстовых полей. Также не создавайте побочные эффекты в методе score или CardValue, то есть не изменяйте ничего, кроме возвращения значения результата.

public int CardValue(string card) 
{ 
    switch (card) 
    { 
     case "J": return 10; 
     case "Q": return 10; 
     case "K": return 10; 
     case "A": return 11; 
     default: return Convert.ToInt32(card); 
    } 
} 

Использование его, как это (он выглядит чище):

playerTotal += CardValue(label7.Text); 
Смежные вопросы