UD05 · Notebook 2 — Piedra, papel o tijera¶
In [1]:
Copied!
from experta import *
from experta.fact import *
import random
NERD = True
from experta import * from experta.fact import * import random NERD = True
In [2]:
Copied!
class WinTotals(Fact):
human = Field(int, default=0)
computer = Field(int, default=0)
ties = Field(int, default=0)
class Results(Fact):
winner = Field(str, mandatory=True)
loser = Field(str, mandatory=True)
why = Field(str, mandatory=True)
class ValidAnswer(Fact):
answer = Field(str, mandatory=True)
key = Field(str, mandatory=True)
class Action(Fact):
pass
class HumanChoice(Fact):
pass
class ComputerChoice(Fact):
pass
class RockPaperScissors(KnowledgeEngine):
def yes_or_no(self, question):
return input(question).upper().startswith('Y')
@DefFacts()
def game_rules(self, is_nerd=False):
"""Declare game rules and valid input keys for the user."""
self.valid_answers = dict()
yield Results(winner='rock', loser='scissors', why='Rock smashes scissors')
yield Results(winner='paper', loser='rock', why='Paper covers rock')
yield Results(winner='scissors', loser='paper', why='Scissors cut paper')
yield ValidAnswer(answer='rock', key='r')
yield ValidAnswer(answer='paper', key='p')
yield ValidAnswer(answer='scissors', key='s')
if is_nerd:
yield Results(winner='rock', loser='lizard', why='Rock crushes lizard')
yield Results(winner='spock', loser='rock', why='Spock vaporizes rock')
yield Results(winner='spock', loser='scissors', why='Spock smashes scissors')
yield Results(winner='paper', loser='spock', why='Paper disproves Spock')
yield Results(winner='scissors', loser='lizard', why='Scissors decapitates lizard')
yield Results(winner='lizard', loser='paper', why='Lizard eats paper')
yield Results(winner='lizard', loser='spock', why='Lizard poisons Spock')
yield ValidAnswer(answer='spock', key='k')
yield ValidAnswer(answer='lizard', key='l')
@Rule()
def startup(self):
print("Lets play a game!")
print("You choose rock, paper, or scissors,")
print("and I'll do the same.")
self.declare(WinTotals(human=0, computer=0, ties=0))
self.declare(Action('get-human-move'))
@Rule(NOT(Action()),
ValidAnswer(answer=MATCH.answer,
key=MATCH.key))
def store_valid_answers(self, answer, key):
self.valid_answers[key] = answer
#
# HUMAN MOVE RULES
#
@Rule(Action('get-human-move'))
def get_human_move(self):
question = ", ".join(
"{name} ({key})".format(
name=a[1].title(), key=a[0].upper())
for a in self.valid_answers.items()) + '? '
res = input(question).lower()
self.declare(HumanChoice(res))
@Rule(AS.f1 << HumanChoice(MATCH.choice),
ValidAnswer(answer=MATCH.answer,
key=MATCH.choice),
AS.f2 << Action('get-human-move'))
def good_human_move(self, f1, f2, answer):
self.retract(f1)
self.retract(f2)
self.declare(HumanChoice(answer))
self.declare(Action('get-computer-move'))
@Rule(AS.f1 << HumanChoice(MATCH.choice),
NOT(ValidAnswer(key=MATCH.choice)),
AS.f2 << Action('get-human-move'))
def bad_human_move(self, f1, f2, choice):
print("Sorry %s is not a valid answer" % choice)
self.retract(f1)
self.retract(f2)
self.declare(Action('get-human-move'))
#
# COMPUTER MOVE RULES
#
@Rule(AS.f1 << Action('get-computer-move'))
def get_computer_move(self, f1):
choice = random.choice(list(self.valid_answers.values()))
self.retract(f1)
self.declare(ComputerChoice(choice))
self.declare(Action('determine-results'))
#
# WIN DETERMINATION RULES
#
@Rule(AS.f1 << Action('determine-results'),
AS.f2 << ComputerChoice(MATCH.cc),
AS.f3 << HumanChoice(MATCH.hc),
AS.w << WinTotals(computer=MATCH.cw),
Results(winner=MATCH.cc,
loser=MATCH.hc,
why=MATCH.explanation))
def computer_wins(self, f1, f2, f3, w, cw, explanation):
self.retract(f1)
self.retract(f2)
self.retract(f3)
self.modify(w, computer=cw + 1)
print("Computer wins!", explanation)
self.declare(Action('determine-play-again'))
@Rule(AS.f1 << Action('determine-results'),
AS.f2 << ComputerChoice(MATCH.cc),
AS.f3 << HumanChoice(MATCH.hc),
'w' << WinTotals(human=MATCH.hw),
Results(winner=MATCH.hc,
loser=MATCH.cc,
why=MATCH.explanation))
def humans_wins(self, f1, f2, f3, w, hw, explanation):
self.retract(f1)
self.retract(f2)
self.retract(f3)
self.modify(w, human=hw + 1)
print("You win!", explanation)
self.declare(Action('determine-play-again'))
@Rule(AS.f1 << Action('determine-results'),
AS.f2 << ComputerChoice(MATCH.cc),
AS.f3 << HumanChoice(MATCH.cc),
AS.w << WinTotals(ties=MATCH.nt))
def tie(self, f1, f2, f3, w, nt):
self.retract(f1)
self.retract(f2)
self.retract(f3)
self.modify(w, ties=nt + 1)
print("Tie! Ha-ha!")
self.declare(Action('determine-play-again'))
#
# PLAY AGAIN RULE
#
@Rule(AS.f1 << Action('determine-play-again'),
WinTotals(computer=MATCH.ct,
human=MATCH.ht,
ties=MATCH.tt))
def play_again(self, f1, ct, ht, tt):
self.retract(f1)
if not self.yes_or_no("Play again?"):
print("You won", ht, "game(s).")
print("Computer won", ct, "game(s).")
print("We tied", tt, "game(s).")
self.halt()
else:
self.declare(Action('get-human-move'))
class WinTotals(Fact): human = Field(int, default=0) computer = Field(int, default=0) ties = Field(int, default=0) class Results(Fact): winner = Field(str, mandatory=True) loser = Field(str, mandatory=True) why = Field(str, mandatory=True) class ValidAnswer(Fact): answer = Field(str, mandatory=True) key = Field(str, mandatory=True) class Action(Fact): pass class HumanChoice(Fact): pass class ComputerChoice(Fact): pass class RockPaperScissors(KnowledgeEngine): def yes_or_no(self, question): return input(question).upper().startswith('Y') @DefFacts() def game_rules(self, is_nerd=False): """Declare game rules and valid input keys for the user.""" self.valid_answers = dict() yield Results(winner='rock', loser='scissors', why='Rock smashes scissors') yield Results(winner='paper', loser='rock', why='Paper covers rock') yield Results(winner='scissors', loser='paper', why='Scissors cut paper') yield ValidAnswer(answer='rock', key='r') yield ValidAnswer(answer='paper', key='p') yield ValidAnswer(answer='scissors', key='s') if is_nerd: yield Results(winner='rock', loser='lizard', why='Rock crushes lizard') yield Results(winner='spock', loser='rock', why='Spock vaporizes rock') yield Results(winner='spock', loser='scissors', why='Spock smashes scissors') yield Results(winner='paper', loser='spock', why='Paper disproves Spock') yield Results(winner='scissors', loser='lizard', why='Scissors decapitates lizard') yield Results(winner='lizard', loser='paper', why='Lizard eats paper') yield Results(winner='lizard', loser='spock', why='Lizard poisons Spock') yield ValidAnswer(answer='spock', key='k') yield ValidAnswer(answer='lizard', key='l') @Rule() def startup(self): print("Lets play a game!") print("You choose rock, paper, or scissors,") print("and I'll do the same.") self.declare(WinTotals(human=0, computer=0, ties=0)) self.declare(Action('get-human-move')) @Rule(NOT(Action()), ValidAnswer(answer=MATCH.answer, key=MATCH.key)) def store_valid_answers(self, answer, key): self.valid_answers[key] = answer # # HUMAN MOVE RULES # @Rule(Action('get-human-move')) def get_human_move(self): question = ", ".join( "{name} ({key})".format( name=a[1].title(), key=a[0].upper()) for a in self.valid_answers.items()) + '? ' res = input(question).lower() self.declare(HumanChoice(res)) @Rule(AS.f1 << HumanChoice(MATCH.choice), ValidAnswer(answer=MATCH.answer, key=MATCH.choice), AS.f2 << Action('get-human-move')) def good_human_move(self, f1, f2, answer): self.retract(f1) self.retract(f2) self.declare(HumanChoice(answer)) self.declare(Action('get-computer-move')) @Rule(AS.f1 << HumanChoice(MATCH.choice), NOT(ValidAnswer(key=MATCH.choice)), AS.f2 << Action('get-human-move')) def bad_human_move(self, f1, f2, choice): print("Sorry %s is not a valid answer" % choice) self.retract(f1) self.retract(f2) self.declare(Action('get-human-move')) # # COMPUTER MOVE RULES # @Rule(AS.f1 << Action('get-computer-move')) def get_computer_move(self, f1): choice = random.choice(list(self.valid_answers.values())) self.retract(f1) self.declare(ComputerChoice(choice)) self.declare(Action('determine-results')) # # WIN DETERMINATION RULES # @Rule(AS.f1 << Action('determine-results'), AS.f2 << ComputerChoice(MATCH.cc), AS.f3 << HumanChoice(MATCH.hc), AS.w << WinTotals(computer=MATCH.cw), Results(winner=MATCH.cc, loser=MATCH.hc, why=MATCH.explanation)) def computer_wins(self, f1, f2, f3, w, cw, explanation): self.retract(f1) self.retract(f2) self.retract(f3) self.modify(w, computer=cw + 1) print("Computer wins!", explanation) self.declare(Action('determine-play-again')) @Rule(AS.f1 << Action('determine-results'), AS.f2 << ComputerChoice(MATCH.cc), AS.f3 << HumanChoice(MATCH.hc), 'w' << WinTotals(human=MATCH.hw), Results(winner=MATCH.hc, loser=MATCH.cc, why=MATCH.explanation)) def humans_wins(self, f1, f2, f3, w, hw, explanation): self.retract(f1) self.retract(f2) self.retract(f3) self.modify(w, human=hw + 1) print("You win!", explanation) self.declare(Action('determine-play-again')) @Rule(AS.f1 << Action('determine-results'), AS.f2 << ComputerChoice(MATCH.cc), AS.f3 << HumanChoice(MATCH.cc), AS.w << WinTotals(ties=MATCH.nt)) def tie(self, f1, f2, f3, w, nt): self.retract(f1) self.retract(f2) self.retract(f3) self.modify(w, ties=nt + 1) print("Tie! Ha-ha!") self.declare(Action('determine-play-again')) # # PLAY AGAIN RULE # @Rule(AS.f1 << Action('determine-play-again'), WinTotals(computer=MATCH.ct, human=MATCH.ht, ties=MATCH.tt)) def play_again(self, f1, ct, ht, tt): self.retract(f1) if not self.yes_or_no("Play again?"): print("You won", ht, "game(s).") print("Computer won", ct, "game(s).") print("We tied", tt, "game(s).") self.halt() else: self.declare(Action('get-human-move'))
In [3]:
Copied!
rps = RockPaperScissors()
rps = RockPaperScissors()
In [4]:
Copied!
rps.reset()
rps.run()
rps.reset() rps.run()
Lets play a game! You choose rock, paper, or scissors, and I'll do the same. Scissors (S), Paper (P), Rock (R)? P Tie! Ha-ha! Play again?Y Scissors (S), Paper (P), Rock (R)? P You win! Paper covers rock Play again?Y Scissors (S), Paper (P), Rock (R)? R You win! Rock smashes scissors Play again?Y Scissors (S), Paper (P), Rock (R)? S Computer wins! Rock smashes scissors Play again?N You won 2 game(s). Computer won 1 game(s). We tied 1 game(s).
In [5]:
Copied!
rps = RockPaperScissors()
rps.reset(is_nerd=True)
rps.run()
rps = RockPaperScissors() rps.reset(is_nerd=True) rps.run()
Lets play a game! You choose rock, paper, or scissors, and I'll do the same. Lizard (L), Spock (K), Scissors (S), Paper (P), Rock (R)? L Tie! Ha-ha! Play again?K You won 0 game(s). Computer won 0 game(s). We tied 1 game(s).
In [ ]:
Copied!