Giter Club home page Giter Club logo

quince's Introduction

Quince

Classic card game written in Python

Build Status codecov

UI

Overview

La escoba de quince is a card game of Spanish origin wherein players take turns collecting cards (following the rule that whatever cards they collect must add up to a value of 15) until they have exhausted the deck. If you are not familiar with the rules, you can read up on them in Spanish or in English over on Wikipedia.

Quince is intended to be a cross-platform implementation of this classic game, written in Python.

Game features

  • Play against 3 computer opponents
  • See scores after playing a single round

Getting started

The following procedure should get you up and running to either play the game or contribute to the project.

  1. Fork the repository to your own GitHub account.
  2. Clone the repository to your local workstation (git clone https://username.github.com/repository)
  3. Set up a virtual environment (this step is not required but highly recommended. Read this article to learn more about virtual environments in python.)
  4. Navigate to the main project directory. This is the same directory where you can find the Makefile.
  5. Run make run to start the graphical user interface.

Contributing

Contributions of all sorts will be very much welcomed. Please see CONTRIBUTING.md file in the ./docs directory.

License

MIT. Copyright (c) 2018 Daniel Liberatori

Card designs courtesy of Basquetteur. Available on Wikipedia

quince's People

Contributors

aamnv avatar dliberat avatar evinces avatar kingakeem avatar

Forkers

aamnv

quince's Issues

Find all possible ways of adding to 15

Need to write this function in order to implement AI.

def enumerate_possibilities(mesa, hand):
     """Finds all the way of adding to 15 using exactly 1 card from the hand,
     and any arbitrary number from the mesa.

     Args:
          mesa -- List of Card objects
          hand -- List of Card objects

     Returns:
         List of tuples, each representing a different possibility for adding up to 15.
         Example: [(card1, card2), (card1, card3, card4)]
     """

Alert user when trying to make an invalid pickup

If the user attempts to pick up a combination of cards that is invalid, they should receive some sort of visual feedback to alert them.

The following method in game_frame.py checks the validity of the pickup:

    def play_hand(self, hand_card):
        """Callback function executed when
        player clicks the "Play Hand" button.
        """
        if self.ronda.current_player is self.player:
            print(f"Attempting to play {hand_card} and\
                pick up: {self.selected_table_cards}")

            if is_valid_pickup(hand_card, self.selected_table_cards):
                self.ronda = self.ronda.play_turn(hand_card,
                                                  self.selected_table_cards)
                self.draw()
                self.play_next_move()
        else:
            print("not your turn")

Specifically, we can see that the if is_valid_pickup line does not have an else statement associated with it.

As for a specific implementation, at the moment I'm thinking that flashing something like this might be a good idea, but if someone wants to tackle this issue and has some other visual implementation in mind, it would be more than welcome.

screen shot 2018-10-05 at 12 30 33

Use double quotes consistently

The codebase is a mess of single and double quotes.

Everything should be changed to double quotes (") for consistency.

Implement Intermediate AI

At present, the NPC AI doesn't do much.

  1. Figure out what possibilities there are to pick up cards from the mesa
  2. If there are no possibilities, lay down a card
  3. If there are possibilities, choose one at random.

https://github.com/garroadran/quince/blob/89b5699a63642fd1ed172b566670b4dd8a2f8e18/quince/components/player.py#L117-L122

It would be good to modify the NPC class to assign weights to all the different possibilities.

  • Remove the @staticmethod decorator. Convert this to a standard instance method.
  • All subclasses of NPC can override a function or attribute that tells the class how to assign weights
  • When choosing what hand to play, all NPCs choose from among the weighted possibilities, with higher-weighted possibilities being more likely to be chosen.
  • Beginner or standard NPCs can assign an equal weight to every possibility.
  • Create a new subclass of NPC (possibly called IntermediateNPC)
  • Intermediate NPCs can assign higher weight to possibilities that include oros (since picking up the most oros is worth a point)
  • Intermediate NPCs can assign a high weight to possibilities that include the 7 of oro (since it is worth a single point all by itself)
  • Intermediate NPCs should avoid dropping the 7 of oro unless there is no other legal move.

User cards display disappears when the user holds no cards

When the user is holding 1-3 cards, the display looks like this:

screen shot 2018-10-09 at 19 04 57

However, when the user holds 0 cards, the display shrinks to this:
screen shot 2018-10-09 at 19 05 16

It would be better for the avatar image and the button on the right to stay equally spaced at all times.

Player class needs __repr__ and __str__ methods

Is your feature request related to a problem? Please describe.
It's difficult to debug/run a game in the python shell.

Describe the solution you'd like
quince/components/player.py needs to have repr and str methods, similar to those found in quince/components/deck.py.

Create custom error for cards that don't add up to 15

Error reporting could stand to be a little more descriptive and specific.

It would be nice if the pick_up_from_mesa method in quince/player.py raised a custom error when the cards don't add up to 15 instead of a standard ValueError.

        # Verify that the sum is OK to pick up
        mesa_amount = 0
        for card in mesa_cards:
            mesa_amount += card[0]
        if mesa_amount + own_card[0] != 15:
            raise ValueError('Tried to pick up cards that don\'t add to 15.')

A similar thing should probably be done for the other two errors that get raised in the same method.

Use fstrings for string representations

In Deck.py, the following code

    def __str__(self):
        return 'Deck containing ' + str(len(self.cards())) + ' Cards.'

    def __repr__(self):
        return 'Deck containing ' + str(len(self.cards())) + ' Cards.'

should be updated to the more modern fstring format. (This will mean that the project will require python 3.6 or higher)

Implement logging

The application needs to be able to generate some sort of logs to both facilitate development and identify bugs.

Python's standard logging library probably provides more than enough functionality to get this done.

  1. Identify functions that could benefit from logging (eg. most of the Ronda class), and write logs with appropriate messages.
  2. Allow the app to receive a or --debug switch that would enable logging to the console.

(Logging to file can be left for later)

Create ronda module

A ronda is the shortest possible complete segment of a game, from initial deal to points calculation.

A complete game will have as many rondas as necessary until one player reaches a total of 30 points.

The Ronda class will need to include some of the following methods:

def __init__(self, players, dealer, card):
   “””Starts a new ronda.
    Resets all players’ current scores. Creates a new shuffled deck with the given card class, and puts 4 cards on the table. If the four cards add up to 15, those cards are taken off the table and given to the dealer along with an escoba.”””

def deal_next_hand(self):
    “””deals three cards to each player”””

def current_player(self):
    “””Returns the player whose turn it is”””

def calculate_score(self):
    “””calculate the scores for the ronda once the deck has been exhausted”””

Linting: Module names

These errors need to be fixed.

************* Module quince.components.Game
C:  1, 0: Module name "Game" doesn't conform to snake_case naming style (invalid-name)
************* Module quince.components.Deck
C:  1, 0: Module name "Deck" doesn't conform to snake_case naming style (invalid-name)
************* Module quince.components.Player
C:  1, 0: Module name "Player" doesn't conform to snake_case naming style (invalid-name)
************* Module quince.components.Pila
C:  1, 0: Module name "Pila" doesn't conform to snake_case naming style (invalid-name)
************* Module quince.components.Card
C:  1, 0: Module name "Card" doesn't conform to snake_case naming style (invalid-name)
R: 49, 8: Unnecessary "else" after "return" (no-else-return)

How to play window

Under the Help menu, there should be an entry titled "How to Play".

The "How to Play" menu entry should bring up a tk.Toplevel window that contains a small tutorial on how to play the game.

Implement Beginner AI

At present, the NPC AI doesn't do much.

  1. Figure out what possibilities there are to pick up cards from the mesa
  2. If there are no possibilities, lay down a card
  3. If there are possibilities, choose one at random.

https://github.com/garroadran/quince/blob/89b5699a63642fd1ed172b566670b4dd8a2f8e18/quince/components/player.py#L117-L122

It would be good to create a subclass of NPC, (perhaps calling it BeginnerNPC) that occasionally messes up and lays down cards even if there are possibilities for picking up. The error ratio could be around 1%.

To make it even more realistic, the NPC "mistakes" could only occur when there's only one or two possibilities available, since in general the more possibilities that are available, the more likely it would be that a beginner player would find at least one of them.

score_report needs a button to start a new ronda

At present, players can only play through a single ronda, whereupon they are shown the scores for that ronda.

The score report needs to include a button that the user can click to start the next ronda.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.