2015-04-19 15 views
5

Sto realizzando un gioco di scissor con carta di roccia e ho riscontrato un problema con lo decisioncycle(). Quello che sto cercando di fare è chiedere all'utente di inserire una scelta in usercycle(), fare in modo che il computer generi una scelta casuale in gamecycle(), quindi determinare chi ha vinto il round e tenere traccia di ogni risultato con un conteggio di vincite e perdite. Sembra che stia decidendo quando lavorare a caso.python function random cycle if statements

import random 


class rpsgame: 

    rps= ["rock", "paper","scissors"] 


    wincount=0 
    losecount=0 
    def usercycle(self): 
     userchoice = input("rock, paper, scissor.....") 
     print("SHOOT") 
     return userchoice 

    def gamecycle(self): 
     computerchoice = random.choice(rpsgame.rps) 
     return computerchoice 




    def decisioncycle(self): 
      if rpsgame.usercycle(self) == rpsgame.rps[0] and rpsgame.gamecycle(self) == rpsgame.rps[1]: 
        print("paper beats rock, you lose!") 
        rpsgame.losecount +=1 
      elif rpsgame.usercycle(self) == rpsgame.rps[1] and rpsgame.gamecycle(self) == rpsgame.rps[0]: 
        print("paper beats rock, you win!") 
        rpsgame.wincount+=1 
      elif rpsgame.usercycle(self) == rpsgame.rps[0] and rpsgame.gamecycle(self) == rpsgame.rps[2]: 
        print("rock beats scissors, you win!") 
        rpsgame.wincount+=1 
      elif rpsgame.usercycle(self) == rpsgame.rps[2] and rpsgame.gamecycle(self) == rpsgame.rps[0]: 
        print("rock beats scissors, you lose!") 
        rpsgame.losecount+=1 
      elif rpsgame.usercycle(self) == rpsgame.rps[1] and rpsgame.gamecycle(self) == rpsgame.rps[2]: 
        print("scissors beats paper, you lose!") 
        rpsgame.losecount+=1 
      elif rpsgame.usercycle(self) == rpsgame.rps[2] and rpsgame.gamecycle(self) == rpsgame.rps[1]: 
        print("scissors beats paper, you win!") 
        rpsgame.wincount+=1 
      elif rpsgame.usercycle(self) == rpsgame.gamecycle(self): 
        print("it's a tie!!!") 
      print("wins {}, losses {}".format(rpsgame.wincount, rpsgame.losecount)) 




while True: 
    rg = rpsgame() 
    rg.usercycle() 
    rg.gamecycle() 
    rg.decisioncycle() 

Penso che il mio problema sia nel decisioncycle(). questo è il mio primo tentativo in classe perché il gioco funzionava con variabili globali, ma leggo qui che è una cattiva pratica da portare avanti per il futuro.

+3

Nel ciclo decisionale, ogni istruzione if/elif è come un round separato del gioco, che non penso sia ciò che si vuole veramente. –

+0

Esattamente, quando l'ho scritto in questo modo senza una classe che utilizza variabili globali ha funzionato come previsto. Cosa mi manca esattamente? – Rayfd3s

+1

In qualunque funzione determini l'esito del gioco, dovresti chiamare solo il ciclo di vita e il ciclo del gioco _solo_, e assegnare i risultati a 2 variabili. Quindi usa quelle variabili per fare confronti. –

risposta

2

Si sta richiedendo un nuovo input utente in ciascuna condizione. Probabilmente si desidera leggere solo una volta e poi confrontarlo con ogni tempo come

user_choice = self.usercicle() 
game_choice = self.gamecycle() 
if(user_choice == self.rps[0] and game_choice == self.rps[1]): 
    print "Paper beats rock, you lose!" 
    self.losecount += 1 
elif(user_choice... 

e così via

+0

Guardando a questa differenza, noto che stai eseguendo le due funzioni precedenti all'interno di un terzo, quindi semplicemente chiamando la terza funzione per eseguire l'intero script. È un modo più pulito per farlo, ma ho provato questo e mi ha dato lo stesso risultato. – Rayfd3s

+0

Stavo suggerendo più un modo alternativo per implementare il corpo di 'decisioncycle'. Se non altro, potresti stampare in alto quali sono le due scelte e cercare di capire quali coppie di risposte funzionano o non funzionano. –

0

Un sacco di cose funky lì, ma credo che il problema che stai avendo è che si sta passando self a una funzione che non accetta (realmente) un argomento come input.

class TestClass(object): 
    def some_method(self): 
     return random.choice(['rock', 'paper', 'scissors']) 
    def make_choice(self): 
     return self.some_method(self) 
     # raises TypeError 

Le classi di un metodo sono AUTOMATICAMENTE assegnate all'istanza a cui appartiene come primo argomento. Se provi a passarlo di nuovo, fallisce.

Detto questo, penso che la classe dovrebbe essere simile:

class Roshambo(object): 
    ROCK = 'rock' 
    PAPER = 'paper' 
    SCISSORS = 'scissors' 

    OPTIONS = [ROCK, PAPER, SCISSORS] 

    def get_user_input(self): 
     choice = input("r/p/s? ").lower() 
     if choice.startswith('r'): choice = self.ROCK 
     elif choice.startswith('p'): choice = self.PAPER 
     elif choice.startswith('s'): choice = self.SCISSORS 
     else: 
      # what do we do now? 
      pass # for now 
     return choice 

    def get_computer_input(self): 
     return random.choice(self.OPTIONS) 

    def start(self): 
     # get input ONCE... 
     user_choice = get_user_input() 
     computer_choice = get_computer_input() 

     if user_choice == ROCK and computer_choice == ROCK: 
      # tie 
     # etc.... 

Poi istanziare

game = Roshambo() 

Ed eseguire

game.start() 
+0

Tutte le sue chiamate all'interno di 'decisioncycle' con' self' sono perfettamente valide - non le chiama direttamente su un'istanza ma direttamente sulla classe. – Ben

+1

Certo, non lo chiamerà affatto lì, ma il modo in cui lo chiama sicuramente non è il suo problema! – Ben

+0

@Ben Hmm beh, ho * perso * che essenzialmente sta chiamando 'self .__ class __. Methodname (self)', ma anche se questo non causa l'errore, sicuramente non aiuta le cose !! –

3

invece di valutare ogni combinazione con numerosi cicli di voi può usare l'aritmetica modulare.

Diciamo che si effettua la mappatura

"rock" => 0 
"paper"=>1 
"scissors" => 2 

è possibile valutare come soluzione

(A.number - B.number) % 3 

se questo risultato è 0, è disegnare, se è 1 che A ha vinto, se 2 A è perso

+0

Potrebbe essere un buon uso dell'enumerazione, anche se non è immediatamente ovvio come funzioni quell'algoritmo. In tutti i giochi RPS che ho visto qui non ho mai visto l'approccio aritmetico offerto! Voglio dire, è davvero bello se funziona in tutti i casi, però. È estensibile? (Rock Paper Scissors Lizard Spock, per esempio) –

+0

Se pensi ad AB come differenza puoi vedere questo come differenza che è -1,0 o 1 o quando in campo finito 0,1 e 2 (2 è uguale a - 1). Si chiama aritmetica nel file finito e viene dalla teoria dei numeri. In C, ad esempio% non funziona in questo modo ad uno dovrebbe scrivere come (3 + A-B)% 3 –

1

Penso che dovresti fare una funzione separata per determinare il vincitore, e usare un dict, piuttosto che un a 7 vie se statement:

def who_won(player, computer): 
    rules = {"rock": "scissors", "paper": "rock", "scissors": "paper"} 
    if player == computer: 
     return None 
    if rules[computer] == player: 
     return "computer" 
    return "player" 

Probabilmente è una buona idea controllare l'input non valido, ma che dovrebbe essere fatto nella funzione di input, piuttosto che questa funzione.

1

Penso che questo potrebbe effettivamente essere semplificato. Ci sono alcuni errori, e sembrano essere dovuti ad una semplice non familiarità con le classi. Date un'occhiata qui:

class RpsGame: 

    # create a game loop. Let's try a while loop 
    # also, let's try using a dict to make comparisons easier 

    def play(self): 
     rps = {'rock':'scissors', 'paper':'rock', 'scissors':'paper'} 
     score = 0 
     # lets just say player must win 3 or lose 3 to end the game 
     while -3 < score < 3: 
      # ask user for their choice just once here, for instance 
      user = raw_input("Rock, paper or scissors: ").lower() 
      # and check the input is valid 
      # get the computer choice with random 

      # then find the winner and adjust score 
      # when score reaches -3, computer wins etc. 
      # comparisons could go like: 
      if com == rps[user]: 
       score += 1 
      elif user == rps[com]: 
       score -= 1 

     self.game_over(score) 

    def game_over(self, score): 
     if score == -3: 
      result == "You win" 
     else: 
      result == "You lose" 

     print "%s!!" % result 


# We would start by instantiating the game 
game = RpsGame() 
# And then calling the play method 
game.play() 

vorrei andare e hanno più di una lettura sulle classi e l'utilizzo di 'sé' se fossi in te anche.

+1

Nota che 'self' non è una parola chiave! :) –

+1

oops .. corretto. – Totem