Apakah mungkin untuk secara ringkas menggunakan kondisi kompleks untuk perulangan while?

Saya sedang mengerjakan permainan di mana saya menggunakan kelas yang memungkinkan pengguna memasukkan pilihan sebagai string untuk melakukan salah satu dari 3 opsi: "menyerang", "bertahan", atau "kabur". Hal ini secara logis dapat ditangani oleh 'OR eksklusif' (XOR). Saya memutuskan untuk mencoba menggunakan perulangan while menggunakan logika ini alih-alih konstruksi Switch biasa untuk melihat apa yang terjadi, dengan hanya dipersenjatai dengan sedikit matematika diskrit. Saya tahu kondisinya akan jelek dan memakan waktu lama, tapi ternyata berhasil!, dan saya menyukainya! Saya ingin tahu, karena saya ingin menggunakan kembali perulangan while ini di bagian lain kode jika ada cara untuk menyimpan kondisi perulangan while (seperti sebagai variabel, metode, atau semacamnya) sehingga saya dapat memasukkannya ke dalam kondisi perulangan while dan tidak memakan 8 baris kode setiap kali. Ini loop while saya. Jangan tertawa, itu berhasil. DAN, ini menghindari try-catch. Ini sebenarnya berjalan sangat bersih. Saya memposting metode yang saya gunakan di bawah ini. Metode ini dipanggil oleh kelas lain:

public static void fighterAction(){  
    String selection = null;
    Scanner userChoice = new Scanner(System.in);

//Fighter 1 chooses combat action to perform: this is performed by 
//(XOR) logic:
//(( a  || b ) && !( a && b ) || c ) && !((( a || b ) && !( a && b ) && c ))

    while((( !"attack".equals(selection)  || !"defend".equals(selection) ) 
            && !( !"attack".equals(selection) && !"defend".equals(selection)
            ) || !"flee".equals(selection) ) &&
            !((( !"attack".equals(selection) || !"defend".equals(selection)
            ) && !( !"attack".equals(selection) && 
            !"defend".equals(selection) ) && !"flee".equals(selection) )))
    {    
        System.out.println("Choose action: attack  defend  flee\n\nEnter: ");
        selection = userChoice.next();
        if((( !"attack".equals(selection)  || !"defend".equals(selection) ) 
                && !( !"attack".equals(selection) && 
                !"defend".equals(selection) ) || !"flee".equals(selection) )
                && !((( !"attack".equals(selection) || 
                !"defend".equals(selection) ) && 
                !( !"attack".equals(selection) && 
                !"defend".equals(selection) ) && 
                !"flee".equals(selection) )))
        {
            System.out.println("Invalid Entry!");
        }else{
        System.out.println(selection + " was chosen");
        System.out.println("");
        }
    }        
}

Sekali lagi, saya bertanya apakah ada cara untuk mengambil klausa while ini (yang saya tekankan, berfungsi dengan sempurna):

(( !"menyerang".sama dengan(pilihan) || !"pertahanan".sama dengan(pilihan) ) && !( !"menyerang".sama dengan(pilihan) && !"pertahankan".sama dengan(pilihan) ) || !" lari".sama dengan(pilihan) ) && !((( !"serangan".sama dengan(pilihan) || !"pertahanan".sama dengan(pilihan) ) && !( !"serangan".sama dengan(pilihan) && !"pertahankan ".equals(pilihan) ) && !"lari".sama dengan(pilihan) ))

sehingga cocok dengan kondisi perulangan while:

 while(FITS HERE){}  

Terima kasih!


person Smith Will Suffice    schedule 15.10.2013    source sumber


Jawaban (3)


Ini akan "pas" apa adanya, dengan kata lain Anda dapat menggunakannya apa adanya, tetapi akan sulit untuk dibaca dan yang lebih penting, sulit untuk di-debug. Agar lebih cantik, jadikanlah itu sebuah metode.


Karena itu, menggunakan Strings untuk hal semacam ini jelek dan berbahaya, ditambah lagi itu akan membatasi program Anda jika Anda memutuskan untuk mengubah UI menjadi antarmuka GUI, misalnya Swing atau Android. Saya malah akan mempertimbangkan untuk membuat enum untuk merangkum opsi pengguna:

public enum UserOption {
  ATTACK, DEFEND, FLEE
}

Sebuah metode yang mengharapkan enum ini hanya dapat menerima salah satu dari tiga konstanta enum (atau null) sehingga memberi Anda pemeriksaan tipe waktu kompilasi dan batasan opsi pengguna dan juga akan menghasilkan kode yang lebih cantik dan dapat digunakan kembali dan diperluas.

Maka aplikasi konsol Anda dapat memiliki metode validasi:

public boolean validateUserOptionsString(String text) {
  for (UserOption option : UserOption.Values() {
    if (text.equalsIgnoreCase(option.toString())) {
      return true;
    }
  }
  return false;
}
person Hovercraft Full Of Eels    schedule 15.10.2013
comment
Selain itu, Anda juga dapat menggunakan kembali metode tersebut untuk menyempurnakan pernyataan if... ! - person user268396; 16.10.2013

Wah, wah, wah. selection hanya dapat memiliki satu nilai dalam satu waktu. Ada sejumlah pemfaktoran ulang yang dapat membuat kode ini lebih bersih (seperti menggunakan enum, dan tidak menyematkan konstanta ajaib), tetapi Anda secara logis dapat menciutkan semuanya menjadi

while(!"attack".equals(selection) && !"defend".equals(selection) && !"flee".equals(selection)) { ... }
person chrylis -cautiouslyoptimistic-    schedule 15.10.2013

Beginilah cara saya menulisnya

String select;
while (true) {
   System.out.println("Enter: attack, defend or flee");
   selection = userChoice.nextLine();
   if (select.equals("attack") || select.equals("defend")||select.equals("flee"))
       break;
   System.out.println("Invalid input: " + select);
}
person Peter Lawrey    schedule 15.10.2013