/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001-2007 by Diether Knof and Borg Enders * * 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 can find this license in the file 'gpl.txt'. * * 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., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@gmx.de * Borg Enders borg@borgsoft.de * **********************************************************************/ #include "game_summary.h" #include "game.h" #ifdef OUTDATED #include "gamepointstable.h" #endif #include "../party/rule.h" #include "../player/player.h" #include "../card/trick.h" /** ** Constructor ** ** @param game game the summary is made of ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 ** ** @todo remove const cast ** **/ GameSummary::GameSummary(Game const& game) : rule_(&game.rule()), seed_(game.seed()), players_number_(game.playerno()), startplayer_no_(game.startplayer().no()), soloplayer_no_( (game.exists_soloplayer() ? game.soloplayer().no() : UINT_MAX) ), game_type_(game.type()), swines_player_no_( (game.swines_owner() ? game.swines_owner()->no() : UINT_MAX) ), hyperswines_player_no_( (game.hyperswines_owner() ? game.hyperswines_owner()->no() : UINT_MAX) ), teams_(), highest_announcement_re_(ANNOUNCEMENT::NOANNOUNCEMENT), highest_announcement_contra_(ANNOUNCEMENT::NOANNOUNCEMENT), trick_points_(), winnerteam_(TEAM::NOTEAM), points_(UINT_MAX), specialpoints_() { this->evaluate(game); return ; } // GameSummary::GameSummary(Game const& game) : /** ** Constructor ** ** @param rule the corresponding rule ** @param istr input stream to read the game from ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ GameSummary::GameSummary(Rule const& rule, istream& istr) : rule_(&rule), seed_(UINT_MAX), players_number_(UINT_MAX), startplayer_no_(UINT_MAX), soloplayer_no_(UINT_MAX), game_type_(GAMETYPE::NORMAL), swines_player_no_(UINT_MAX), hyperswines_player_no_(UINT_MAX), teams_(), highest_announcement_re_(ANNOUNCEMENT::NOANNOUNCEMENT), highest_announcement_contra_(ANNOUNCEMENT::NOANNOUNCEMENT), trick_points_(), winnerteam_(), points_(), specialpoints_() { this->read(istr); return ; } // GameSummary::GameSummary(istream& istr) : /** ** copy constructor ** ** @param game_summary game summary to copy ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.3 **/ GameSummary::GameSummary(GameSummary const& game_summary) : rule_(game_summary.rule_), seed_(game_summary.seed_), players_number_(game_summary.players_number_), startplayer_no_(game_summary.startplayer_no_), soloplayer_no_(game_summary.soloplayer_no_), game_type_(game_summary.game_type_), swines_player_no_(game_summary.swines_player_no_), hyperswines_player_no_(game_summary.hyperswines_player_no_), teams_(game_summary.teams_), highest_announcement_re_(game_summary.highest_announcement_re_), highest_announcement_contra_(game_summary.highest_announcement_contra_), trick_points_(game_summary.trick_points_), winnerteam_(game_summary.winnerteam_), points_(game_summary.points_), specialpoints_(game_summary.specialpoints_) { } /** ** Destructor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ GameSummary::~GameSummary() { return ; } // GameSummary::~GameSummary() /** ** writes the game summary into 'ostr' ** ** @param ostr output stream ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ void GameSummary::write(ostream& ostr) const { ostr << "seed = " << Unsigned(this->seed()) << '\n'; ostr << "players number = " << Unsigned(this->players_number()) << '\n'; ostr << "startplayer number = " << Unsigned(this->startplayer_no()) << '\n'; ostr << "soloplayer number = " << Unsigned(this->soloplayer_no()) << '\n'; ostr << "gametype = " << this->game_type() << '\n'; ostr << "swines player number = " << Unsigned(this->swines_player_no()) << '\n'; ostr << "hyperswines player number = " << Unsigned(this->hyperswines_player_no()) << '\n'; ostr << "teams ="; for (vector::const_iterator t = this->teams().begin(); t != this->teams().end(); ++t) { if (t != this->teams().begin()) ostr << ','; ostr << ' ' << *t; } ostr << '\n'; ostr << "highest announcement re = " << this->highest_announcement_re() << '\n'; ostr << "highest announcement contra = " << this->highest_announcement_contra() << '\n'; ostr << "trick points ="; for (vector::const_iterator p = this->trick_points().begin(); p != this->trick_points().end(); ++p) { if (p != this->trick_points().begin()) ostr << ','; ostr << ' ' << *p; } ostr << '\n'; ostr << "winnerteam = " << this->winnerteam() << '\n'; ostr << "points = " << this->points() << '\n'; ostr << "special points\n" << "{\n" << this->specialpoints() << "}\n"; return ; } // void GameSummary::write(ostream& ostr) const /** ** reads the game summary from 'ostr' ** ** @param istr input stream ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 ** ** @todo all ** **/ void GameSummary::read(istream& istr) { Unsigned seed = UINT_MAX; Unsigned players_number = UINT_MAX; Unsigned startplayer_no = UINT_MAX; Unsigned soloplayer_no = UINT_MAX; GameType game_type = GAMETYPE::NORMAL; Unsigned swines_player_no = UINT_MAX; Unsigned hyperswines_player_no = UINT_MAX; vector teams; Announcement highest_announcement_re = ANNOUNCEMENT::NOANNOUNCEMENT; Announcement highest_announcement_contra = ANNOUNCEMENT::NOANNOUNCEMENT; vector trick_points; Team winnerteam = TEAM::NOTEAM; int points = INT_MAX; Specialpointsvector specialpoints; { // read the data Config config; // the config read int depth = 0; // the depth in the blocks do { // while (istr) istr >> config; if (istr.eof()) break; if (istr.fail()) break; if ((config.name == "") && (config.value == "")) break; if (config.value.empty()) { if (config.name == "{") { depth += 1; } else if (config.name == "}") { depth -= 1; // finished with the game summary if (depth == -1) istr.putback('}'); if (depth <= 0) break; } else if (config.name == "special points") { // ToDo string line; line = read_line(istr); if (line != "{") throw ReadException("Game summary read: " "special points: expected '{', " " found '" + line + "'"); while (istr.good() && (istr.peek() != '}')) { specialpoints.push_back(Specialpoints(istr)); while (isspace(istr.peek()) && istr.good()) istr.get(); } line = read_line(istr); if (line != "}") throw ReadException("Game summary read: " "special points: expected '}', " " found '" + line + "'"); } else { // if (config.name == ...) throw ReadException("Game summary read: unknown line " "'" + config.name + "'"); } // if (config.name == ...) } else { // if !(config.value.empty()) istringstream istr(config.value); if (config.name == "seed") { istr >> seed; } else if (config.name == "players number") { istr >> players_number; } else if (config.name == "startplayer number") { istr >> startplayer_no; } else if (config.name == "soloplayer number") { istr >> soloplayer_no; } else if (config.name == "gametype") { game_type = GAMETYPE::from_name(config.value); } else if (config.name == "swines player number") { istr >> swines_player_no; } else if (config.name == "hyperswines player number") { istr >> hyperswines_player_no; } else if (config.name == "teams") { string::size_type pos_begin = 0; while ((pos_begin < config.value.size()) && isspace(config.value[pos_begin])) pos_begin++; string::size_type pos_end = pos_begin; while (pos_begin < config.value.size()) { pos_end = config.value.find(',', pos_begin); string const name(string(config.value, pos_begin, ((pos_end == string::npos) ? string::npos : (pos_end - pos_begin)))); teams.push_back(TEAM::from_name(name)); if (teams.back() == TEAM::NOTEAM) throw ReadException("Game summary read: invalid team " "'" + string(config.value, pos_begin, pos_end - pos_begin) + "'"); if (pos_end == string::npos) break; pos_begin = pos_end + 1; while ((pos_begin < config.value.size()) && isspace(config.value[pos_begin])) pos_begin++; } // while (pos_begin < config.value.size()) } else if (config.name == "highest announcement re") { highest_announcement_re = ANNOUNCEMENT::from_name(config.value); } else if (config.name == "highest announcement contra") { highest_announcement_contra = ANNOUNCEMENT::from_name(config.value); } else if (config.name == "trick points") { string::size_type pos_begin = 0; while ((pos_begin < config.value.size()) && isspace(config.value[pos_begin])) pos_begin++; string::size_type pos_end = pos_begin; while (pos_begin < config.value.size()) { pos_end = config.value.find(',', pos_begin); string const name(string(config.value, pos_begin, ((pos_end == string::npos) ? string::npos : (pos_end - pos_begin)))); trick_points.push_back(Unsigned(name)); if (trick_points.back() == UINT_MAX) throw ReadException("Game summary read: invalid trickpoints " "'" + string(config.value, pos_begin, pos_end - pos_begin) + "'"); if (pos_end == string::npos) break; pos_begin = pos_end + 1; while ((pos_begin < config.value.size()) && isspace(config.value[pos_begin])) pos_begin++; } // while (pos_begin < config.value.size()) } else if (config.name == "winnerteam") { winnerteam = TEAM::from_name(config.value); } else if (config.name == "points") { istr >> points; } else { // if (config.name == ...) throw ReadException("Game summary read: unknown line " "'" + config.name + " = " + config.value + "'"); } // if (config.name == ...) if (!istr.good() && !istr.eof()) throw ReadException("Game summary read: error loading " "'" + config.name + "'"); } // if !(config.value.empty()) } while (istr.good()); if (!istr.good()) throw ReadException("Game summary read: unknown error"); } // read the data { // test whether all data was read // explicit casts of Unsigned because of problems with MinGW g++-3.2 if (seed.operator unsigned const&() == UINT_MAX) throw ReadException("Game summary read: seed not loaded"); if (players_number.operator unsigned const&() == UINT_MAX) throw ReadException("Game summary read: players number not loaded"); if (startplayer_no.operator unsigned const&() == UINT_MAX) throw ReadException("Game summary read: startplayer number not loaded"); if (teams.size() != players_number.operator unsigned const&()) throw ReadException("Game summary read: teams not loaded"); if (trick_points.size() != players_number.operator unsigned const&()) throw ReadException("Game summary read: trick points not loaded"); if (points == INT_MAX) throw ReadException("Game summary read: points number not loaded"); } // test whether all data was read { // set the data // explicit casts of Unsigned because of problems with MinGW g++-3.2 this->seed_ = seed.operator unsigned const&(); this->players_number_ = players_number.operator unsigned const&(); this->startplayer_no_ = startplayer_no.operator unsigned const&(); this->soloplayer_no_ = soloplayer_no.operator unsigned const&(); this->game_type_ = game_type; this->swines_player_no_ = swines_player_no.operator unsigned const&(); this->hyperswines_player_no_ = hyperswines_player_no.operator unsigned const&(); this->teams_ = teams; this->highest_announcement_re_ = highest_announcement_re; this->highest_announcement_contra_ = highest_announcement_contra; this->trick_points_ = trick_points; this->winnerteam_ = winnerteam; this->points_ = points; this->specialpoints_ = specialpoints; } // set the data return ; } // void GameSummary::read(istream& istr) /** ** -> result ** ** @param - ** ** @return whether the game was a duty solo ** ** @author Diether Knof ** ** @version 0.6.8 ** **/ bool GameSummary::is_solo() const { return GAMETYPE::is_solo(this->game_type()); } // bool GameSummary::is_solo() const /** ** -> result ** ** @param - ** ** @return whether the game was a duty solo ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ bool GameSummary::is_duty_solo() const { return false; } // bool GameSummary::is_duty_solo() const /** ** -> result ** ** @param - ** ** @return whether the game was a lust solo ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ bool GameSummary::is_lust_solo() const { return (this->is_solo() && !this->is_duty_solo()); } // bool GameSummary::is_lust_solo() const /** ** -> result ** ** @param - ** ** @return the team which gets the points ** ** @author Diether Knof ** ** @version 0.6.8 ** **/ Team GameSummary::team_of_points() const { if (this->winnerteam() == TEAM::NOTEAM) { switch(this->rule()(Rule::COUNTING)) { case COUNTING_NS::PLUS: if (this->points() > 0) return TEAM::RE; else return TEAM::CONTRA; case COUNTING_NS::MINUS: if (this->points() < 0) return TEAM::RE; else return TEAM::CONTRA; case COUNTING_NS::PLUSMINUS: return TEAM::RE; } // switch(this->rule()(Rule::COUNTING)) } else { // if !(this->winnerteam() == TEAM::NOTEAM) switch(this->rule()(Rule::COUNTING)) { case COUNTING_NS::PLUS: return this->winnerteam(); case COUNTING_NS::MINUS: return opposite(this->winnerteam()); case COUNTING_NS::PLUSMINUS: return this->winnerteam(); } // switch(this->rule()(Rule::COUNTING)) } // if !(this->winnerteam() == TEAM::NOTEAM) return TEAM::NOTEAM; } // Team GameSummary::team_of_points() const /** ** -> result ** ** @param team the team ** ** @return whether the team gets points ** ** @author Diether Knof ** ** @version 0.6.9 **/ bool GameSummary::team_get_points(Team const team) const { using namespace COUNTING_NS; if (this->winnerteam() == TEAM::NOTEAM) { switch(this->rule()(Rule::COUNTING)) { case PLUS: return ( ( (this->points() > 0) && (team == TEAM::RE)) || ( (this->points() < 0) && (team == TEAM::CONTRA)) ); case MINUS: return ( ( (this->points() < 0) && (team == TEAM::RE)) || ( (this->points() > 0) && (team == TEAM::CONTRA)) ); case PLUSMINUS: return (this->points_ != 0); } // switch(this->rule()(Rule::COUNTING)) } else { // if !(p.winnerteam() == TEAM::NOTEAM) switch(this->rule()(Rule::COUNTING)) { case PLUS: case MINUS: return (team == this->team_of_points()); case PLUSMINUS: return true; } // switch(this->rule()(Rule::COUNTING)) } // if !(p.winnerteam() == TEAM::NOTEAM) DEBUG_ASSERT(false); return false; } // bool GameSummary::team_get_points(Team const team) const /** ** -> result ** ** @param team the team ** ** @return the points the team gets ** ** @author Diether Knof ** ** @version 0.6.9 **/ int GameSummary::points(Team const team) const { if (!this->team_get_points(team)) return 0; // in a solo game 'points()' returns three times the value of 'points_' switch(this->rule().counting()) { case COUNTING_NS::PLUS: if ( this->is_solo() && (this->winnerteam() == TEAM::RE)) return 3 * this->points(); if ( (this->winnerteam() == TEAM::NOTEAM) && (team == TEAM::CONTRA) ) return -this->points(); return this->points(); case COUNTING_NS::MINUS: if ( this->is_solo() && (this->winnerteam() == TEAM::CONTRA)) return 3 * (-this->points()); if ( (this->winnerteam() == TEAM::NOTEAM) && (team == TEAM::RE) ) return this->points(); return -this->points(); case COUNTING_NS::PLUSMINUS: if (this->is_solo()) { if (this->winnerteam() == TEAM::RE) { if (team == this->winnerteam()) return 3 * this->points(); else return -this->points(); } else { // if !(this->winnerteam() == TEAM::RE) if (team == this->winnerteam()) return this->points(); else return -3 * this->points(); } // if !(this->winnerteam() == TEAM::RE) } // if (this->is_solo()) if (team == this->team_of_points()) return this->points(); else return -this->points(); } // switch(this->rule().counting()) DEBUG_ASSERTION(false, "GameSummary::points(team):\n" " counting type not known: " << this->rule().counting()); return 0; } // int GameSummary::points(Team team) const /** ** -> result ** ** @param playerno the player ** ** @return whether the player gets points ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ bool GameSummary::player_get_points(unsigned const playerno) const { return team_get_points(this->team(playerno)); } // bool GameSummary::player_get_points(unsigned const playerno) const /** ** -> result ** ** @param playerno the player ** ** @return the points the player gets ** ** @author Diether Knof ** ** @version 0.6.8 ** **/ int GameSummary::points(unsigned const playerno) const { return this->points(this->team(playerno)); } // int GameSummary::points(unsigned const playerno) const /** ** -> result ** ** @param playerno the player ** ** @return the number of points 'playerno' has made in his tricks ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ unsigned GameSummary::trick_points(unsigned const playerno) const { return this->trick_points()[playerno]; } // unsigned /** ** -> result ** ** @param team the team ** ** @return the points made by the team ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ unsigned GameSummary::trick_points(Team const team) const { unsigned points = 0; for (unsigned p = 0; p < this->trick_points().size(); ++p) if (this->team(p) == team) points += this->trick_points(p); return points; } // unsigned GameSummary::trick_points(Team const team) const /** ** -> result ** ** @param playerno the player ** ** @return team of player 'playerno' ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ Team GameSummary::team(unsigned const playerno) const { return this->teams()[playerno]; } // Team GameSummary::team(unsigned const playerno) const /** ** evaluate the game ** ** @param game game to evaluate ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 **/ void GameSummary::evaluate(Game const& game) { // save the team and the trick points for(unsigned p = 0; p < game.playerno(); p++ ) { this->teams_.push_back(game.team(game.player(p))); this->trick_points_.push_back(game.points_of_player(game.player(p))); } // save the winnerteam this->winnerteam_ = game.winnerteam(); // calculate highest announcements vector re_announcement_player(ANNOUNCEMENT::NUMBER, UINT_MAX); vector contra_announcement_player(ANNOUNCEMENT::NUMBER, UINT_MAX); Announcement reply_announcement = ANNOUNCEMENT::NOANNOUNCEMENT; unsigned reply_player; for(unsigned p = 0; p < game.playerno(); p++ ) { Player const& player = game.player(p); vector const& announcements = game.announcements_of_player(player); if (is_reply(announcements.back().announcement)) { reply_announcement = announcements.back().announcement; reply_player = p; } if (game.team(player) == TEAM::RE) { if (player.announcement() > this->highest_announcement_re_) this->highest_announcement_re_ = player.announcement(); for (unsigned a = 0; a < announcements.size(); a++) re_announcement_player[announcements[a].announcement] = p; } // if (game.team(player) == TEAM::RE) if (game.team(player) == TEAM::CONTRA) { if( player.announcement() > highest_announcement_contra_) this->highest_announcement_contra_ = player.announcement(); for (unsigned a = 0; a < announcements.size(); a++) contra_announcement_player[announcements[a].announcement] = p; } // if (game.team(player) == TEAM::RE) } // for (p < game.playerno()) { // special points // Order of the points // * re no 0 // * contra no 0 // * no 0 reply // * re no 0 said // * contra no 0 said // * re no 30 // * contra no 30 // * no 30 reply // * re no 30 said // * contra no 30 said // * re no 60 // * contra no 60 // * no 60 reply // * re no 60 said // * contra no 60 said // * re no 90 // * contra no 90 // * no 90 reply // * re no 90 said // * contra no 90 said // * re won && re > 120 points // * re won && re 120 points && re no announcement && contra no announcement // * contra won && contra > 120 points // * consta won && contra 120 points && contra no announcement // * no 120 reply // * contra no 0 said && re > 30 points // * contra no 30 said && re > 60 points // * contra no 60 said && re > 90 points // * contra no 90 said && re > 120 points // * re no 0 said && contra > 30 points // * re no 30 said && contra > 60 points // * re no 60 said && contra > 90 points // * re no 90 said && contra > 120 points // * re no 120 said // * contra no 120 said // * against club queen // * multiplicator 3 // * specialpoints { // announcements // shortcuts // re no 90 #define TRICKPOINTS_RE_NO(A) \ if ((game.points_of_team(TEAM::RE) < A) \ && (game.winnerteam() != TEAM::RE)) \ this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO ## A, \ TEAM::CONTRA)) // contra no 90 #define TRICKPOINTS_CONTRA_NO(A) \ if ((game.points_of_team(TEAM::CONTRA) < A) \ && (game.winnerteam() != TEAM::CONTRA)) \ this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO ## A, \ TEAM::RE)) // re got 120 (against 'no 90') #define TRICKPOINTS_RE_GOT(A) \ if ((this->highest_announcement_contra() == ANNOUNCEMENT::NO ## A) \ && (game.points_of_team(TEAM::RE) >= (A + 30))) \ this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO ## A ## _WON, \ TEAM::RE)) // contra got 120 (against 'no 90') #define TRICKPOINTS_CONTRA_GOT(A) \ if ((this->highest_announcement_re() == ANNOUNCEMENT::NO ## A) \ && (game.points_of_team(TEAM::CONTRA) >= (A + 30))) \ this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO ## A ## _WON, \ TEAM::CONTRA)) // replied on announcement #define ANNOUNCEMENT_REPLY(A) \ if ( (reply_announcement == ANNOUNCEMENT::NO ## A ## _REPLY) \ && (game.winnerteam() != TEAM::NOTEAM)) { \ Specialpoints sp( SPECIALPOINT::NO ## A ## _REPLY, \ game.player(reply_player).team(), \ game.winnerteam()); \ sp.player_of_no = reply_player; \ this->specialpoints_.push_back(sp); \ } else // re announced no 60 #define TRICKPOINTS_RE_NO_ANNOUNCED(A) \ if (is_real(this->highest_announcement_re()) \ && (this->highest_announcement_re() >= ANNOUNCEMENT::NO ## A ) \ && (game.winnerteam() != TEAM::NOTEAM)) { \ Specialpoints sp(SPECIALPOINT::NO ## A ## _SAID, \ TEAM::RE, \ game.winnerteam()); \ sp.player_of_no = re_announcement_player[ANNOUNCEMENT::NO ## A]; \ this->specialpoints_.push_back(sp); \ } else // contra announced no 60 #define TRICKPOINTS_CONTRA_NO_ANNOUNCED(A) \ if (is_real(this->highest_announcement_contra()) \ && (this->highest_announcement_contra() >= ANNOUNCEMENT::NO ## A ) \ && (game.winnerteam() != TEAM::NOTEAM)) { \ Specialpoints sp(SPECIALPOINT::NO ## A ## _SAID, \ TEAM::CONTRA, \ game.winnerteam()); \ sp.player_of_no = contra_announcement_player[ANNOUNCEMENT::NO ## A]; \ this->specialpoints_.push_back(sp); \ } else #define POINTS(A) \ TRICKPOINTS_RE_NO(A); \ TRICKPOINTS_CONTRA_NO(A); \ TRICKPOINTS_RE_GOT(A); \ TRICKPOINTS_CONTRA_GOT(A); \ ANNOUNCEMENT_REPLY(A); \ TRICKPOINTS_RE_NO_ANNOUNCED(A); \ TRICKPOINTS_CONTRA_NO_ANNOUNCED(A) { // 0 // re no 0 if (( !game.hastrick(TEAM::RE)) && (game.winnerteam() != TEAM::RE)) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO0, TEAM::CONTRA)); // contra no 0 if (( !game.hastrick( TEAM::CONTRA ) ) && (game.winnerteam() != TEAM::CONTRA)) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO0, TEAM::RE)); // re 0 got if ( (this->highest_announcement_contra() == ANNOUNCEMENT::NO0) && game.hastrick(TEAM::RE) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO0_WON, TEAM::RE)); // contra 0 got if ( (this->highest_announcement_re() == ANNOUNCEMENT::NO0) && game.hastrick(TEAM::CONTRA) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO0_WON, TEAM::CONTRA)); ANNOUNCEMENT_REPLY(0); TRICKPOINTS_RE_NO_ANNOUNCED(0); TRICKPOINTS_CONTRA_NO_ANNOUNCED(0); } // 0 POINTS(30); POINTS(60); POINTS(90); { // 120 // re no 120 if ( (game.winnerteam() == TEAM::CONTRA) && ( (game.points_of_team(TEAM::RE) < 120) || ( (game.points_of_team(TEAM::RE) == 120) && ( (this->highest_announcement_contra() == ANNOUNCEMENT::NOANNOUNCEMENT) || ( (this->highest_announcement_contra() == ANNOUNCEMENT::NO120) && (this->highest_announcement_re() > ANNOUNCEMENT::NOANNOUNCEMENT) && (this->highest_announcement_re() != ANNOUNCEMENT::NO120_REPLY) ) ) ) ) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO120, TEAM::CONTRA)); if (game.rule()(Rule::ANNOUNCEMENT_CONTRA_DOUBLES_AGAINST_RE)) { // against club queens if ( !GAMETYPE::is_solo(this->game_type()) && (game.winnerteam() == TEAM::CONTRA) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::CONTRA_WON, TEAM::CONTRA)); } // if (Rule::ANNOUNCEMENT_CONTRA_DOUBLES_AGAINST_RE) // contra no 120 if ( (game.winnerteam() == TEAM::RE) && ( (game.points_of_team( TEAM::CONTRA ) < 120) || ( (game.points_of_team(TEAM::CONTRA) == 120) && (this->highest_announcement_re() == ANNOUNCEMENT::NOANNOUNCEMENT ) && (this->highest_announcement_contra() > ANNOUNCEMENT::NOANNOUNCEMENT) ) ) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::NO120, TEAM::RE)); ANNOUNCEMENT_REPLY(120); TRICKPOINTS_RE_NO_ANNOUNCED(120); TRICKPOINTS_CONTRA_NO_ANNOUNCED(120); } // 120 #undef TRICKPOINTSS_RE_NO #undef TRICKPOINTSS_CONTRA_NO #undef TRICKPOINTSS_RE_GOT #undef TRICKPOINTSS_CONTRA_GOT #undef ANNOUNCEMENT_REPLY #undef TRICKPOINTS_RE_NO_ANNOUNCED #undef TRICKPOINTS_CONTRA_NO_ANNOUNCED #undef POINTS } // announcements if (!game.rule()(Rule::ANNOUNCEMENT_CONTRA_DOUBLES_AGAINST_RE)) { // against club queens if ( !GAMETYPE::is_solo(this->game_type()) && (game.winnerteam() == TEAM::CONTRA) ) this->specialpoints_.push_back(Specialpoints(SPECIALPOINT::CONTRA_WON, TEAM::CONTRA)); } // if (Rule::ANNOUNCEMENT_CONTRA_DOUBLES_AGAINST_RE) // multiplicator 3 for solo games if ( GAMETYPE::is_solo(this->game_type()) && (this->winnerteam() == TEAM::RE) ) { Specialpoints sp(SPECIALPOINT::SOLO, TEAM::RE); sp.player_of_no = game.soloplayer().no(); this->specialpoints_.push_back(sp); } // last collect all specialpoints of each trick for (unsigned t = 0; t < game.trick_current_no(); ++t) { Specialpointsvector const spv = game.trick(t).specialpoints(); for (Specialpointsvector::const_iterator s = spv.begin(); s != spv.end(); s++) if (s->is_valid(this->teams())) this->specialpoints_.push_back(*s); } // calculating the main game points this->points_ = Sum_of_Specialpoints(this->specialpoints(), this->winnerteam(), game); DEBUG_ASSERTION((( this->winnerteam() == TEAM::RE ) || ( this->winnerteam() == TEAM::CONTRA ) || ( this->winnerteam() == TEAM::NOTEAM )), "GameSummary::evaluate(Game):" << endl << " wrong team at end: " << this->winnerteam()); } // special points return ; } // void GameSummary::evaluate(Game const& game) #ifdef OUTDATED /** ** compares this game summary with the gamepoints ** (test for errors) ** ** @param gamepoints gamepoints to compare ** ** @return whether the data is the same ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ bool GameSummary::test(GamePoints const& gamepoints) const { if (this->points() != gamepoints.points()) { cerr << "points" << endl; cerr << this->points() << " != " << gamepoints.points() << endl; return false; } for (unsigned p = 0; p < this->rule()(Rule::NUMBER_OF_PLAYERS_IN_GAME); ++p) { if (this->trick_points(p) != gamepoints.playerspoints(p)) { cerr << "playerpoins " << p << endl; return false; } if (this->team(p) != gamepoints.team(p)) { cerr << "team " << p << endl; return false; } } if (this->trick_points(TEAM::RE) != gamepoints.teampoints(TEAM::RE)) { cerr << "trick_points(RE)" << endl; return false; } if (this->trick_points(TEAM::CONTRA) != gamepoints.teampoints(TEAM::CONTRA)) { cerr << "trick_points(CONTRA)" << endl; return false; } if (this->game_type() != gamepoints.gametype()) { cerr << "gametype" << endl; return false; } if (this->winnerteam() != gamepoints.winnerteam()) { cerr << "winnerteam" << endl; return false; } #if 0 if (this->specialpoints() != gamepoints.pointlist()) { cerr << "pointlist" << endl; return false; } #endif return true; } // bool GameSummary::test(GamePoints const& gamepoints) const #endif // #ifndef OUTDATED /** ** writes the game summary into the stream ** ** @param ostr output stream ** @param game_summary game summary ** ** @return output stream ** ** @author Diether Knof ** ** @version 0.6.7 ** **/ ostream& operator<<(ostream& ostr, GameSummary const& game_summary) { game_summary.write(ostr); return ostr; } // ostream& operator<<(ostream& ostr, GameSummary const& game_summary)