summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board.cpp101
-rw-r--r--board.h55
-rw-r--r--cards.cpp62
-rw-r--r--cards.h53
-rw-r--r--client.cpp40
-rw-r--r--client.h40
-rw-r--r--game.cpp285
-rw-r--r--game.h89
-rw-r--r--player.cpp50
-rw-r--r--player.h51
10 files changed, 826 insertions, 0 deletions
diff --git a/board.cpp b/board.cpp
new file mode 100644
index 0000000..b11ecad
--- /dev/null
+++ b/board.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "board.h"
+
+namespace cao {
+ board::board(const cards::deck &black_deck, const cards::deck &white_deck)
+ : _black_decks(black_deck, cards::deck()),
+ _white_decks(white_deck, cards::deck()),
+ _black_pick(&_black_decks.first), _white_pick(&_white_decks.first),
+ _black_recycl(&_black_decks.second), _white_recycl(&_white_decks.second),
+ _flop(), _current_black_card(NULL)
+ {
+ _black_pick->shuffle();
+ _white_pick->shuffle();
+ }
+
+ void board::reveal_black_card()
+ {
+ /*
+ * if we do not have enough cards in the pick, then we exchange the
+ * decks with the recycling deck.
+ */
+ if (_black_pick->empty())
+ {
+ cards::deck *d = _black_pick;
+
+ _black_pick = _black_recycl;
+ _black_recycl = d;
+
+ _black_pick->shuffle();
+ }
+
+ _current_black_card = _black_pick->pick();
+ }
+
+ void board::recycle_black_card()
+ {
+ _black_recycl->push_front(_current_black_card);
+
+ _current_black_card = NULL;
+ }
+
+ const cards::card *board::pick_white_card()
+ {
+ if (_white_pick->empty())
+ {
+ cards::deck *d = _white_pick;
+
+ _white_pick = _white_recycl;
+ _white_recycl = d;
+
+ _white_pick->shuffle();
+ }
+
+ return _white_pick->pick();
+ }
+
+ void board::play_card(const cards::card *card, player *p)
+ {
+ std::pair<const cards::card *, player *> pair;
+
+ pair.first = card;
+ pair.second = p;
+
+ _flop.push_back(pair);
+ }
+
+ void board::shuffle_flop()
+ {
+ _flop.shuffle();
+ }
+
+ void board::recycle_flop()
+ {
+ for (cards::flop::const_iterator it = _flop.begin();
+ it != _flop.end(); ++it)
+ {
+ const cards::card *card = (*it).first;
+
+ _white_recycl->push_front(card);
+ }
+
+ _flop.clear();
+ }
+};
diff --git a/board.h b/board.h
new file mode 100644
index 0000000..c0af7a7
--- /dev/null
+++ b/board.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef BOARD_H
+#define BOARD_H
+
+#include "cards.h"
+
+namespace cao {
+ class board {
+ public:
+ board(const cards::deck &black_deck, const cards::deck &white_deck);
+
+ void reveal_black_card();
+ void recycle_black_card();
+ const cards::card *pick_white_card();
+ void play_card(const cards::card *, player *);
+ void shuffle_flop();
+ void recycle_flop();
+
+ const cards::flop &get_flop() const { return _flop; };
+ const cards::card *get_current_black_card() const { return _current_black_card; };
+
+ private:
+ std::pair<cards::deck, cards::deck> _black_decks;
+ std::pair<cards::deck, cards::deck> _white_decks;
+
+ cards::deck *_black_pick;
+ cards::deck *_white_pick;
+
+ cards::deck *_black_recycl;
+ cards::deck *_white_recycl;
+
+ cards::flop _flop;
+
+ const cards::card *_current_black_card;
+ };
+};
+
+#endif /* BOARD_H */
diff --git a/cards.cpp b/cards.cpp
new file mode 100644
index 0000000..cec65db
--- /dev/null
+++ b/cards.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <fstream>
+#include <cerrno>
+#include <cstring>
+#include <algorithm>
+
+#include "cards.h"
+
+namespace cao {
+ namespace cards {
+ deck::deck(const std::string &dict_file)
+ {
+ std::string line;
+ std::ifstream ifile(dict_file.c_str(), std::ios_base::in);
+
+ if (!ifile.good()) {
+ throw std::runtime_error(dict_file + ": " + strerror(errno));
+ }
+
+ while (std::getline(ifile, line)) {
+ push_back(new card(line));
+ }
+ }
+
+ void deck::shuffle()
+ {
+ std::random_shuffle(begin(), end());
+ }
+
+ const card *deck::pick()
+ {
+ const card *c = front();
+
+ pop_front();
+
+ return c;
+ }
+
+ void flop::shuffle()
+ {
+ std::random_shuffle(begin(), end());
+ }
+
+ };
+};
diff --git a/cards.h b/cards.h
new file mode 100644
index 0000000..cbe013f
--- /dev/null
+++ b/cards.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef CARDS_H
+#define CARDS_H
+
+#include <string>
+#include <deque>
+#include <vector>
+#include <map>
+
+namespace cao {
+ class player;
+
+ namespace cards {
+ typedef std::string card;
+
+ class deck : public std::deque<const card *> {
+ public:
+ deck() : deque() {};
+ deck(const std::string &dict_file);
+
+ void shuffle();
+ const card *pick();
+ };
+
+ class flop : public std::vector<std::pair<const card *, player *> > {
+ public:
+ flop() : vector() {};
+
+ void shuffle();
+ };
+
+ typedef std::map<int, const card *> hand;
+ };
+};
+
+#endif /* CARDS_H */
diff --git a/client.cpp b/client.cpp
new file mode 100644
index 0000000..c4486d1
--- /dev/null
+++ b/client.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <iostream>
+#include "client.h"
+
+namespace cao {
+ client::client(int sock, void *handler)
+ : _sock(sock), _handler(handler), _player(NULL)
+ {
+ std::clog << "creating a new client" << std::endl;
+ }
+
+ void client::join_game(const std::string &name)
+ {
+ if (_player) {
+ std::clog << "hey you already are in a game" << std::endl;
+ return;
+ }
+
+ game *game = game_manager::get_instance()->find_game_by_name(name);
+
+ _player = game->try_join(this);
+ }
+};
diff --git a/client.h b/client.h
new file mode 100644
index 0000000..ee64055
--- /dev/null
+++ b/client.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include <string>
+#include "game.h"
+
+namespace cao {
+ class client {
+ public:
+ client(int, void *);
+
+ void join_game(const std::string &name);
+
+ private:
+ int _sock;
+ void *_handler;
+
+ player *_player;
+ };
+};
+
+#endif /* CLIENT_H */
diff --git a/game.cpp b/game.cpp
new file mode 100644
index 0000000..7d87e2b
--- /dev/null
+++ b/game.cpp
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <iostream>
+#include <vector>
+#include "game.h"
+
+#define CARDS_PER_PLAYER 10
+
+namespace cao {
+ /* game {{{ */
+
+ game::game(const cards::deck &black_deck, const cards::deck &white_deck)
+ : _board(black_deck, white_deck), _state(WAITING_NEW_JUDGE),
+ _players(), _judge()
+ {
+ std::clog << "creating new game" << std::endl;
+ }
+
+ player *game::try_join(client *client)
+ {
+ if (_players.size() >= CARDS_PER_PLAYER) {
+ std::clog << "too many players in this game" << std::endl;
+ /* TODO send error */
+ return NULL;
+ }
+
+ /* pick 10 cards */
+ std::vector<const cards::card *> cards;
+
+ try {
+ for (int i = 0; i < CARDS_PER_PLAYER; ++i) {
+ cards.push_back(_board.pick_white_card());
+ }
+ } catch (std::string index_error) {
+ std::clog << "not enough white cards for player" << std::endl;
+ /* TODO send error */
+
+ /* TODO put the cards back in the pick */
+
+ return NULL;
+ }
+
+ player *p = new player(client);
+
+ for (std::vector<const cards::card *>::const_iterator it = cards.begin();
+ it != cards.end(); ++it)
+ {
+ p->receive_card(*it);
+ }
+
+ _players.push_back(p);
+
+ /* TODO send notification to other players */
+
+ /* TODO send cards and game state to player */
+
+ return p;
+ }
+
+ void game::try_become_judge(player *p)
+ {
+ if (_state != WAITING_NEW_JUDGE) {
+ std::clog << "someone is judge already" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ _judge = p;
+ _board.reveal_black_card();
+
+ _state = WAITING_COLLECTION;
+
+ /* TODO send notification "judge designed" to other players */
+
+ /* TODO send black card back to player */
+ }
+
+ void game::try_play_card(player *p, int idx)
+ {
+ if (_state != WAITING_COLLECTION) {
+ std::clog << "Who asked you to play now ?!" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ if (_judge == p) {
+ std::clog << "You're the judge, you silly" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ if (p->has_played()) {
+ std::clog << "You already played, dumb ass" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ const cards::card *c;
+
+ try {
+ c = p->pop_card(idx);
+ } catch (std::string idnex_error) {
+ std::clog << "Invalid card idx" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ p->has_played(true);
+
+ _board.play_card(c, p);
+
+ /* TODO send notification to judge */
+
+ /* TODO return card id back to the plaeyr */
+ return;
+ }
+
+ void game::try_collect_cards(player *p)
+ {
+ if (_state != WAITING_COLLECTION) {
+ std::clog << "Do you think it's the moment for collection !?" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ if (_judge != p) {
+ std::clog << "You are not the judge, you fool !" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ _board.shuffle_flop();
+
+ /* we prevent the others to play */
+ _state = WAITING_DESIGNATION;
+
+ /* TODO send notification cards collected to the others */
+
+ /* TODO send the flop back to the player */
+ }
+
+ /* TODO handle when no cards are on the board */
+ void game::try_designate_card(player *p, int idx)
+ {
+ if (_state != WAITING_DESIGNATION) {
+ std::clog << "not now, moron !" << std::endl;
+ /* TODO send error */
+
+ return;
+ }
+
+ if (_judge != p) {
+ std::clog << "who do you think you are !?" << std::endl;
+ /* TODO send error */
+
+ return;
+ }
+
+ if ((idx == -1) && (!_board.get_flop().empty())) {
+ std::clog << "there are cards on the board, so pick one !" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ if ((idx >= 0) && (!_board.get_flop().empty())) {
+ /* TODO apparently, there's an exception to check */
+ /* there are cards on the board */
+
+ player *winner;
+
+ try {
+ winner = _board.get_flop()[idx].second;
+ } catch (std::string index_error) {
+ std::clog << "invalid card" << std::endl;
+ /* TODO send error */
+ return;
+ }
+
+ winner->inc_score();
+
+ /* put the cards back in the deck */
+ _board.recycle_flop();
+
+ /* reset the state of the players */
+ for (std::vector<player *>::iterator it = _players.begin();
+ it != _players.end(); ++it)
+ {
+ player *target = (*it);
+
+ if (target->has_played()) {
+ target->receive_card(_board.pick_white_card());
+
+ /* TODO send notification to the player */
+
+ target->has_played(false);
+ }
+ }
+ }
+
+ _board.recycle_black_card();
+ _judge = NULL;
+ _state = WAITING_NEW_JUDGE;
+
+ /* TODO send notification judge needed to the other players */
+ }
+
+ void game::try_view_player_cards(const player *p) const
+ {
+ (void) p;
+ /* TODO return the cards along with their index */
+ }
+
+ void game::try_view_flop() const
+ {
+ if (_state != WAITING_DESIGNATION) {
+ std::clog << "not now, moron !" << std::endl;
+ /* TODO send error */
+ return;
+
+ }
+
+ /* TODO return the cards */
+ }
+
+ void game::try_view_black_card() const
+ {
+ const cards::card *c = _board.get_current_black_card();
+
+ if (c) {
+ /* TODO return the black card to the player */
+ return;
+ }
+
+ std::clog << "The black card has not been revealed yet" << std::endl;
+ /* TODO send error */
+ }
+
+ /* }}} */
+ /* game_manager {{{ */
+
+ game_manager *game_manager::_instance = NULL;
+
+ game_manager *game_manager::get_instance()
+ {
+ if (!_instance) {
+ _instance = new game_manager();
+ }
+
+ return _instance;
+ }
+
+ game_manager::game_manager()
+ : _games(),
+ black_deck("usr/share/cao/lang/en/cards/black"),
+ white_deck("usr/share/cao/lang/en/cards/white")
+ { }
+
+ game *game_manager::find_game_by_name(const std::string &game_name)
+ {
+ std::map<const std::string, game *>::iterator it = _games.find(game_name);
+
+ if (it != _games.end())
+ return it->second;
+
+ return _games[game_name] = new game(black_deck, white_deck);
+ }
+
+ /* }}} */
+};
diff --git a/game.h b/game.h
new file mode 100644
index 0000000..b76127c
--- /dev/null
+++ b/game.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GAME_H
+#define GAME_H
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include "game.h"
+#include "cards.h"
+#include "board.h"
+#include "player.h"
+#include "client.h"
+
+class client;
+
+namespace cao {
+ /* game {{{ */
+
+ class game {
+ public:
+ game(const cards::deck &black_deck, const cards::deck &white_deck);
+
+ enum state {
+ WAITING_NEW_JUDGE, /* we need a new judge */
+ WAITING_COLLECTION, /* the judge should collect the cards */
+ WAITING_DESIGNATION, /* the judge should pick the best card */
+ };
+
+ player *try_join(client *);
+ void try_become_judge(player *);
+ void try_play_card(player *, int idx);
+ void try_collect_cards(player *);
+ void try_designate_card(player *, int idx);
+ void try_view_player_cards(const player *) const;
+ void try_view_flop() const;
+ void try_view_black_card() const;
+
+ private:
+ board _board;
+
+ state _state;
+
+ std::vector<player *> _players;
+ player *_judge;
+
+ };
+
+ /* }}} */
+ /* game_manager {{{ */
+
+ class game_manager {
+ public:
+ static game_manager *get_instance();
+
+ game *find_game_by_name(const std::string &game_name);
+
+ private:
+ game_manager();
+
+ std::map<const std::string, game *> _games;
+
+ cards::deck black_deck;
+ cards::deck white_deck;
+
+ static game_manager *_instance;
+ };
+
+ /* }}} */
+};
+
+#endif /* GAME_H */
diff --git a/player.cpp b/player.cpp
new file mode 100644
index 0000000..e2e3ed3
--- /dev/null
+++ b/player.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "player.h"
+
+namespace cao {
+ player::player(client *client)
+ : _client(client), _name("default"), _score(0), _hand(), _next_idx(0),
+ _has_played(false)
+ {
+ }
+
+ void player::inc_score()
+ {
+ ++_score;
+
+ /* TODO send notification */
+ }
+
+ const cards::card *player::pop_card(int idx)
+ {
+ const cards::card *c = _hand[idx];
+
+ _hand.erase(idx);
+
+ return c;
+ }
+
+ int player::receive_card(const cards::card *card)
+ {
+ _hand[_next_idx++] = card;
+
+ return _next_idx - 1;
+ }
+};
diff --git a/player.h b/player.h
new file mode 100644
index 0000000..a870e5e
--- /dev/null
+++ b/player.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 Olivier Gayot <olivier.gayot@sigexec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "cards.h"
+#include "client.h"
+
+namespace cao {
+ class client;
+
+ class player {
+ public:
+ player(client *);
+
+ bool has_played() const { return _has_played; };
+ void has_played(bool has) { _has_played = has; };
+ void inc_score();
+ const cards::card *pop_card(int idx);
+ int receive_card(const cards::card *);
+ private:
+ client *_client;
+ std::string _name;
+
+ int _score;
+
+ cards::hand _hand;
+
+ int _next_idx;
+
+ bool _has_played;
+ };
+};
+
+#endif /* PLAYER_H */