/card_game_engine

A Stateless Card Game Engine

Primary LanguageRust

Card Game Engine

A barebones card game engine that takes an initial state builder and a rule set to build a STATELESS full card game. Best used with web API based games, checkout Dame de Pique
Explore the docs »

View Demo · Report Bug · Request Feature

Table of Contents

  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgements

About The Project

![Product Name Screen Shot][product-screenshot]

Here's a blank template to get started: To avoid retyping too much info. Do a search and replace with your text editor for the following: github_username, repo_name, twitter_handle, email, Card Game Engine, project_description

Built With

Getting Started

To get a local copy up and running follow these simple steps.

Prerequisites

This is an example of how to list things you need to use the software and how to install them.

  • Rust
    cargo build 

Installation

  1. Clone the repo
    git clone https://github.com/pseguin2011/card_game_engine.git
  2. Install Rust
    cargo build

Usage

Write an implementation of the Game Builder:

use card_game_engine::models::deck::{Deck, DeckType};
use card_game_engine::models::player::Player;
use card_game_engine::DefaultCardGameError;

#[derive(Clone)]
pub struct State {
    deck: Deck,
    players: Vec<Player>,
    turn: usize
}

pub struct MyAwesomeBuilder;

impl GameBuilder for MyAwesomeBuilder {
    type E = DefaultCardGameError;
    type S = State;

    fn initialize_game() -> Result<Self::S, Self::E> {
        let mut deck = Deck::new(DeckType::WithJokers);
        deck.shuffle();

        let mut players = vec![
            Player {
                name: format!("Player 1"),
                hand: deck.draw_cards(10)?,
            },
            Player {
                name: format!("Player 2"),
                hand: deck.draw_cards(10)?,
            },
        }

        let state = Self::S {
            deck,
            players,
            turn: 0,
        };

        Ok(state)
    }
}

Write an implementation of GameRules:

#[derive(Clone, Copy)]
pub enum MyAwesomeGameMoves {
    Draw,
    Discard(usize),
}

impl GameRules<State, DefaultCardGameError> for MyAwesomeGameMoves {
    /// Handles the player moves to drawing and discarding
    fn handle_move(&self, state: &mut State) -> Result<(), DefaultCardGameError> {
        match self {
            Self::Draw => {
                if let Some(card) = state.deck.draw_card() {
                    state.players[state.turn].add_card_to_hand(card);
                } else {
                    return Err(DefaultCardGameError::DeckEmpty);
                }
            }
            Self::Discard(card_index) => {
                let card = state.players[state.turn].play_card_from_hand(*card_index);
                state.deck.discard_card(card);
            }
        }
        Ok(())
    }

    fn is_game_over(state: &mut State) -> Result<bool, DefaultCardGameError> {
        for player in state.players {
            if player.hand.is_empty() {
                return Ok(true);
            }
        }
        Ok(false)
    }

    fn is_round_over(state: &mut State) -> Result<bool, DefaultCardGameError> {
        for player in state.players {
            if player.hand.is_empty() {
                return Ok(true);
            }
        }
        Ok(false)
    }

    fn end_turn(state: &mut State) {
        state.turn = (state.turn + 1) % state.players.len();
    }
}

Start using the Game struct to manipulate the game state in your API:

    type MyAwesomeGame = Game<MyAwesomeBuilder, MyAwesomeGameMoves>;
    let mut game_state = MyAwesomeGame::new_game()?;
    MyAwesomeGame::game_action(MyAwesomeGameMoves::Draw, &mut game_state)?;
    MyAwesomeGame::game_action(MyAwesomeGameMoves::Discard(0), &mut game_state)?;
    MyAwesomeGame::end_turn(&mut game_state);

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Pierre Seguin - pseguin2011@protonmail.com

Project Link: https://github.com/pseguin2011/card_game_engine