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