Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Herooik · Mar 04, 2020 at 08:37 PM · scripting problemrefactor

How could I replace these many if statement?

Hello! I made a game "Rock,Paper,Scissors" and I'm trying to figure out how to replace these if statements in my class. I'm not interested in replacing these with switch. Any ideas?

Everything works properly. I just want to refactor my code ;)

 private void CheckForWin()
    {
       if (_playerOneChoice == _playerTwoChoice)
       {
          StartCoroutine(ShowResultTextCo(_drawText, "DRAW"));
          
          ActivateEndRoundButtons();
       }
 
       if (_playerOneChoice == GameChoices.ROCK && _playerTwoChoice == GameChoices.SCISSORS)
       {
          EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
       }
       
       if (_playerOneChoice == GameChoices.SCISSORS && _playerTwoChoice == GameChoices.PAPER)
       {
          EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
       }
       
       if (_playerOneChoice == GameChoices.PAPER && _playerTwoChoice == GameChoices.ROCK)
       {
          EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
       }
       
       if (_playerOneChoice == GameChoices.ROCK && _playerTwoChoice == GameChoices.PAPER)
       {
          EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
       }
       
       if (_playerOneChoice == GameChoices.PAPER && _playerTwoChoice == GameChoices.SCISSORS)
       {
          EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
       }
       
       if (_playerOneChoice == GameChoices.SCISSORS && _playerTwoChoice == GameChoices.ROCK)
       {
          EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
       }
    }





Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Bunny83 · Mar 05, 2020 at 01:02 AM

A different approach would be to express which choice beats which. You can use a dictionary which is populated during Start.

 Dictionary<GameChoices, GameChoices> rules;
 
 void Start()
 {
     rules = new Dictionary<GameChoices, GameChoices>();
     rules.Add(GameChoices.ROCK, GameChoices.SCISSORS);
     rules.Add(GameChoices.SCISSORS, GameChoices.PAPER);
     rules.Add(GameChoices.PAPER, GameChoices.ROCK);
 }
 
 private void CheckForWin()
 {
     GameChoices other;
     if(rules.TryGetValue(_playerOneChoice, out other) && _playerTwoChoice == other)
     {
         EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
     }
     else if(rules.TryGetValue(_playerTwoChoice, out other) && _playerOneChoice == other)
     {
         EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
     }
     else
     {
         StartCoroutine(ShowResultTextCo(_drawText, "DRAW"));
         ActivateEndRoundButtons();
     }
 }

This should work for the classic rock - paper - scissors. However with this approach each choice can only beat exactly one other choice.


A different approach would be to actually encode the "winning pairs" as a "key" like that:

 public struct ChoicePair
 {
     public GameChoices c1;
     public GameChoices c2;
     public ChoicePair(GameChoices aC1, GameChoices aC2)
     {
         c1 = aC1;
         c2 = aC2;
     }
 }
 HashSet<ChoicePair> rules = new HashSet<ChoicePair>();
 private void Start()
 {
     rules.Add(new ChoicePair(GameChoices.ROCK, GameChoices.SCISSORS));
     rules.Add(new ChoicePair(GameChoices.SCISSORS, GameChoices.PAPER));
     rules.Add(new ChoicePair(GameChoices.PAPER, GameChoices.ROCK));
 }

 private void CheckForWin()
 {
     if(rules.Contains(new ChoicePair(_playerOneChoice, _playerTwoChoice)))
     {
         EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
     }
     else if(rules.Contains(new ChoicePair(_playerTwoChoice, _playerOneChoice)))
     {
         EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
     }
     else
     {
         StartCoroutine(ShowResultTextCo(_drawText, "DRAW"));
         ActivateEndRoundButtons();
     }
 }

In this case we can essentially define any winning rules we like. For example if you want to introduce the common additional choices SPOCK and LIZARD the rules are simply:

 private void Start()
 {
     rules.Add(new ChoicePair(GameChoices.SCISSORS, GameChoices.PAPER));
     rules.Add(new ChoicePair(GameChoices.PAPER, GameChoices.ROCK));
     rules.Add(new ChoicePair(GameChoices.ROCK, GameChoices.LIZARD));
     rules.Add(new ChoicePair(GameChoices.LIZARD, GameChoices.SPOCK));
     rules.Add(new ChoicePair(GameChoices.SPOCK, GameChoices.SCISSORS));

     rules.Add(new ChoicePair(GameChoices.SCISSORS, GameChoices.LIZARD));
     rules.Add(new ChoicePair(GameChoices.LIZARD, GameChoices.PAPER));
     rules.Add(new ChoicePair(GameChoices.PAPER, GameChoices.SPOCK));
     rules.Add(new ChoicePair(GameChoices.SPOCK, GameChoices.ROCK));
     rules.Add(new ChoicePair(GameChoices.ROCK, GameChoices.SCISSORS));
 }

After adding the two extra choices to the enum and using those rules instead, everything works the same way.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Mar 05, 2020 at 01:13 AM 0
Share

Note I haven't tested the code but it should work ;) Of course for such a game using ScriptableObjects ins$$anonymous$$d of an enum would be more flexible as Ryan Hipple explained in his talk over here. He's actually mentioning the talk of Richard Fine which should get you started on how to use ScriptableObjects as an "enum". I don't want to go into details here since all that wasn't part of the question asked here.


ps: I can highly recommend watching those two talks from the beginning.

avatar image Herooik · Mar 05, 2020 at 02:26 PM 0
Share

Thank you, it looks very well! I will use this and I will give you feedback if everything works properly :D

avatar image Herooik · Mar 05, 2020 at 05:17 PM 0
Share

This works perfectly, thank you :D Still have a lot to learn about coding :)

avatar image
1

Answer by tormentoarmagedoom · Mar 04, 2020 at 08:54 PM

I dont know if this can be considered refract. You have all final options.

 iF P1 = P2    -  DRAW
 
 if P1 = sciss
     IF P2 = rock - P2 wins
     else P1 win
 
 if P1 = Rock
     if P2 = sciss   - P1 win
     ELSE P1 win
 
 if P1 = Paper
    if P2 = rock  P1 win
    else P1 win

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Herooik · Mar 05, 2020 at 02:24 PM 0
Share

Not really this but thank you anyway! :)

avatar image
0

Answer by erickluiss · Mar 05, 2020 at 03:58 AM

This is not refactoring but I believe will make easier to do so later:

 private void CheckForWin()
 {
     PlayerOneWon();
     PlayerTwoWon();
     MatchIsDraw();
 }
 
 private static void PlayerOneWon()
 {
     if (_playerOneChoice == GameChoices.ROCK && _playerTwoChoice == GameChoices.SCISSORS)
     {
         EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
     }
     else if (_playerOneChoice == GameChoices.SCISSORS && _playerTwoChoice == GameChoices.PAPER)
     {
         EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
     }
     else if (_playerOneChoice == GameChoices.PAPER && _playerTwoChoice == GameChoices.ROCK)
     {
         EndRoundUpdate(ref _playerOneScore, _playerOneScoreText, "PLAYER 1 WON");
     }
 }

 private static void PlayerTwoWon()
 {
     if (_playerOneChoice == GameChoices.ROCK && _playerTwoChoice == GameChoices.PAPER)
     {
         EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
     }
     else if (_playerOneChoice == GameChoices.PAPER && _playerTwoChoice == GameChoices.SCISSORS)
     {
         EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
     }
     else if (_playerOneChoice == GameChoices.SCISSORS && _playerTwoChoice == GameChoices.ROCK)
     {
         EndRoundUpdate(ref _playerTwoScore, _playerTwoScoreText, "PLAYER 2 WON");
     }
 }

 private void MatchIsDraw()
 {
     if (_playerOneChoice == _playerTwoChoice)
     {
         StartCoroutine(ShowResultTextCo(_drawText, "DRAW"));

         ActivateEndRoundButtons();
     }
 }

Hope it helps

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Herooik · Mar 05, 2020 at 02:27 PM 0
Share

Still not what I wanted but thank you anyway! :D

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

222 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to call invoke from a monobehaviour class using a function from an object class. 1 Answer

BoxCollider2d.bounds.Intersects Not Working 2 Answers

how do I edit a component of a specific child of an instantiated object? 2 Answers

Oculus VR Drag Slider With Finger 0 Answers

Trouble with Triggering Animation - Please help!!! 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges