/********************************************************************** * * 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 "constants.h" #include "specialpoint.h" #include "../party/party.h" #include "../party/rule.h" #include "../game/game.h" /** ** -> return ** ** @param sp the specialpoint type ** ** @return whether 'sp' was got by winning ** ** @author Diether Knof ** ** @version 0.6.6 **/ bool SPECIALPOINT::is_winning(Specialpoint const sp) { switch (sp) { case NO120: case NO90: case NO60: case NO30: case NO0: case NO90_WON: case NO60_WON: case NO30_WON: case NO0_WON: case CONTRA_WON: case SOLO: return true; break; default: return false; break; }; // switch(sp) } // bool SPECIALPOINT::is_winning(Specialpoint const sp) /** ** ** -> return ** ** @param sp the specialpoint type ** ** @return whether 'sp' was got by announcement ** ** @author Diether Knof ** ** @version 0.6.6 ** **/ bool SPECIALPOINT::is_announcement(Specialpoint const sp) { switch (sp) { case NO120_SAID: case NO90_SAID: case NO60_SAID: case NO30_SAID: case NO0_SAID: case NO120_REPLY: case NO90_REPLY: case NO60_REPLY: case NO30_REPLY: case NO0_REPLY: return true; break; default: return false; break; }; // switch(sp) } // bool SPECIALPOINT::is_announcement(Specialpoint const sp) /** ** -> result ** ** @param sp special point ** ** @result points for this specialpoint ** ** @author Borg Enders ** @author Diether Knof ** ** @version 0.6.9 **/ int Value_of_Specialpoint(Specialpoint const sp) { using namespace SPECIALPOINT; switch (sp) { case NOSPECIALPOINT: return 0; case CAUGHT_FOX: case FOX_LAST_TRICK: case CHARLIE: case CAUGHT_CHARLIE: case DOLLE_CAUGHT_DOLLE: case HEART_TRICK: case DOPPELKOPF: case NO120: case NO90: case NO60: case NO30: case NO0: case NO90_WON: case NO60_WON: case NO30_WON: case NO0_WON: return 1; case NO120_SAID: return (::party.rule()(Rule::ANNOUNCEMENT_RE_DOUBLES) ? 0 : 2); case NO90_SAID: case NO60_SAID: case NO30_SAID: case NO0_SAID: case NO120_REPLY: case NO90_REPLY: case NO60_REPLY: case NO30_REPLY: case NO0_REPLY: case CONTRA_WON: return 1; case SOLO: return 0; } // switch(sp) return 0; } // int Value_of_Specialpoint(Specialpoint sp) /** ** -> result ** ** @param type the type of the special point ** ** @return name of the specialpoints ** ** @author Borg Enders ** @author Diether Knof ** ** @version 0.6.9 **/ string name(Specialpoint const type) { using namespace SPECIALPOINT; switch(type) { case NOSPECIALPOINT: return "no specialpoint"; case CAUGHT_FOX: return "caught fox"; case FOX_LAST_TRICK: return "fox last trick"; case CHARLIE: return "charlie"; case CAUGHT_CHARLIE: return "caught charlie"; case DOLLE_CAUGHT_DOLLE: return "dolle caught dolle"; case HEART_TRICK: return "heart trick"; case DOPPELKOPF: return "Doppelkopf"; case NO120: return "no 120"; case NO90: return "no 90"; case NO60: return "no 60"; case NO30: return "no 30"; case NO0: return "no 0"; case NO90_WON: return "no 90 won"; case NO60_WON: return "no 60 won"; case NO30_WON: return "no 30 won"; case NO0_WON: return "no 0 won"; case NO120_SAID: return "no 120 said"; case NO90_SAID: return "no 90 said"; case NO60_SAID: return "no 60 said"; case NO30_SAID: return "no 30 said"; case NO0_SAID: return "no 0 said"; case NO120_REPLY: return "no 120 reply said"; case NO90_REPLY: return "no 90 reply said"; case NO60_REPLY: return "no 60 reply said"; case NO30_REPLY: return "no 30 reply said"; case NO0_REPLY: return "no 0 reply said"; case CONTRA_WON: return "contra won"; case SOLO: return "solo"; } // switch(specialpoints) return ""; } // string name(Specialpoint const specialpoint) /** ** -> result ** ** @param name special point name ** ** @return the special point with name 'name' ** ** @author Diether Knof ** ** @version 0.6.9 **/ Specialpoint specialpoint_from_name(string const& name) throw(ReadException) { for (int s = SPECIALPOINT::FIRST; s <= SPECIALPOINT::LAST; ++s) if (name == ::name(static_cast(s))) return static_cast(s); throw ReadException("unknown special point '" + name + "'"); return SPECIALPOINT::NOSPECIALPOINT; } // Specialpoint specialpoint_from_name(string name) /** ** writes the specialpoint (name) in the output stream ** ** @param ostr output stream ** @param type type to write ** ** @return output stream ** ** @author Borg Enders ** ** @version 0.6.8 ** **/ ostream& operator<<(ostream& ostr, Specialpoint const& type) { ostr << name(type); return ostr; } // ostream operator<<(ostream& ostr, Specialpoint type); /** ** Constructor ** ** @param istr input stream to read the special points from ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.9 **/ Specialpoints::Specialpoints(istream& istr) : type(SPECIALPOINT::NOSPECIALPOINT), team(TEAM::NOTEAM), counting_team(TEAM::NOTEAM), player_get_no(UINT_MAX), player_of_no(UINT_MAX) { Config config; istr >> config; this->type = specialpoint_from_name(config.name); string::size_type pos_begin = 0; while (isspace(config.value[pos_begin]) && (pos_begin < config.value.size())) pos_begin++; string::size_type pos_end = config.value.find(','); if (pos_end == string::npos) { istr.clear(ios::failbit); return ; } this->team = TEAM::from_name(string(config.value, pos_begin, pos_end - pos_begin)); pos_begin = pos_end + 1; while (isspace(config.value[pos_begin]) && (pos_begin < config.value.size())) pos_begin++; pos_end = config.value.find(',', pos_begin); if (pos_end == string::npos) { istr.clear(ios::failbit); return ; } this->counting_team = TEAM::from_name(string(config.value, pos_begin, pos_end - pos_begin)); pos_begin = pos_end + 1; while (isspace(config.value[pos_begin]) && (pos_begin < config.value.size())) pos_begin++; pos_end = config.value.find(',', pos_begin); if (pos_end == string::npos) { istr.clear(ios::failbit); return ; } // explicit cast because of problems with MinGW g++-3.2 this->player_get_no = Unsigned(string(config.value, pos_begin, pos_end - pos_begin) ).operator unsigned const&(); pos_begin = pos_end + 1; pos_end = config.value.size(); // explicit cast because of problems with MinGW g++-3.2 this->player_of_no = Unsigned(string(config.value, pos_begin, pos_end - pos_begin) ).operator unsigned const&(); } // Specialpoints::Specialpoints(istream& istr) /** ** writes the specialpoint class in the output stream ** ** @param ostr output stream ** @param specialpoint specialpoint to write ** ** @return output stream ** ** @author Diether Knof ** ** @version 0.6.9 **/ ostream& operator<<(ostream& ostr, Specialpoints const& specialpoint) { ostr << specialpoint.type << " = " << specialpoint.team << ", " << specialpoint.counting_team << ", " << Unsigned(specialpoint.player_get_no) << ", " << Unsigned(specialpoint.player_of_no) << '\n'; return ostr; } // ostream operator<<(ostream& ostr, Specialpoints specialpoint); /** ** writes the specialpoint vector in the output stream ** ** @param ostr output stream ** @param specialpointsvector specialpoints to write ** ** @return output stream ** ** @author Diether Knof ** ** @version 0.6.8 **/ ostream& operator<<(ostream& ostr, Specialpointsvector const& specialpointsvector) { for (Specialpointsvector::const_iterator sp = specialpointsvector.begin(); sp != specialpointsvector.end(); ++sp) ostr << *sp; return ostr; } // ostream operator<<(ostream& ostr, Specialpointsvector specialpointsvector); /** ** -> result ** ** @param - ** ** @return the value of the specialpoints ** ** @author Borg Enders ** @author Diether Knof ** ** @version 0.6.1 **/ int Specialpoints::value() const { DEBUG_CALLING(INFO_BASISTYPES && INFO_VALUE, "Specialpoints::value()"); DEBUG_RETURNING(Value_of_Specialpoint(this->type), INFO_BASISTYPES && INFO_VALUE, "Specialpoints::value()"); } // int Specialpoints::value() const /** ** -> result ** ** @param team teamvector ** ** @return whether the specialpoint is valid at the end of the game ** ** @author Borg Enders ** @author Diether Knof ** ** @version 0.6.1 **/ bool Specialpoints::is_valid(vector const team) const { switch(type) { case SPECIALPOINT::CAUGHT_FOX: case SPECIALPOINT::CAUGHT_CHARLIE: case SPECIALPOINT::DOLLE_CAUGHT_DOLLE: return (team[this->player_of_no] != team[this->player_get_no]); case SPECIALPOINT::FOX_LAST_TRICK: case SPECIALPOINT::CHARLIE: case SPECIALPOINT::HEART_TRICK: case SPECIALPOINT::DOPPELKOPF: return true; case SPECIALPOINT::NOSPECIALPOINT: case SPECIALPOINT::NO120: case SPECIALPOINT::NO90: case SPECIALPOINT::NO60: case SPECIALPOINT::NO30: case SPECIALPOINT::NO0: case SPECIALPOINT::NO90_WON: case SPECIALPOINT::NO60_WON: case SPECIALPOINT::NO30_WON: case SPECIALPOINT::NO0_WON: case SPECIALPOINT::NO120_SAID: case SPECIALPOINT::NO90_SAID: case SPECIALPOINT::NO60_SAID: case SPECIALPOINT::NO30_SAID: case SPECIALPOINT::NO0_SAID: case SPECIALPOINT::NO120_REPLY: case SPECIALPOINT::NO90_REPLY: case SPECIALPOINT::NO60_REPLY: case SPECIALPOINT::NO30_REPLY: case SPECIALPOINT::NO0_REPLY: case SPECIALPOINT::CONTRA_WON: case SPECIALPOINT::SOLO: return true; } // switch(specialpoints) return false; } // bool Specialpoints::is_valid(vector const team) const /********************************************************************** ** ** int Sum_of_Specialpoints(Specialpointsvector spv,Team winner) ** ** Parameters: input a specialpointsvector and Winnerteam ** ** Result: sum of all Specialpoints for winnerteam minus# ** all specialpoints of losing team ** ** Version: Alpha ** ** Description: ** ** **********************************************************************/ int Sum_of_Specialpoints(Specialpointsvector const& spv, Team const winner, Game const& g) { DEBUG_CALLING(INFO_BASISTYPES && INFO_SPECIALPOINTS, "int Sum_of_Specialpoints(const Specialpointsvector& spv,Team winner)"); int re_played=0; int re_ann=0; int re_trick=0; int contra_played=0; int contra_trick=0; int contra_ann=0; int no120s=1; #ifdef OUTDATED // 0.6.8 2004-12-03 (-> GameSummary::points(), GameSummary::points(playerno) ) int const win_mod = ( ( GAMETYPE::is_solo(g.type()) && (winner == TEAM::RE) ) ? 3 : 1); #endif #ifdef OUTDATED // 0.6.7 2004-11-14 (-> GameSummary::evaluate(Game) ) if (GAMETYPE::is_solo(g.type())) { if (winner == TEAM::RE) { win_mod=3; Specialpoints sp(SPECIALPOINT::SOLO, TEAM::RE); sp.player_of_no = g.soloplayer().no(); spv.push_back( sp ); } } #endif for (unsigned int i=0; i 4 (no120s = " << no120s); if (winner==TEAM::RE) { int result = 0; result+= re_played + re_ann - contra_played; result*=no120s; result+= re_trick - contra_trick; #ifdef OUTDATED // 0.6.8 2004-12-03 (-> GameSummary::points(), GameSummary::points(playerno) ) result*= win_mod; #endif DEBUG_RETURNING(result, INFO_BASISTYPES && INFO_SPECIALPOINTS, "int Sum_of_Specialpoints(const Specialpointsvector& spv,Team winner)"); } if (winner==TEAM::CONTRA) { int result = 0; result+= contra_played + contra_ann - re_played; result*=no120s; result+= contra_trick - re_trick; #ifdef OUTDATED // 0.6.8 2004-12-03 (-> GameSummary::points(), GameSummary::points(playerno) ) result*= win_mod; #endif DEBUG_RETURNING(result, INFO_BASISTYPES && INFO_SPECIALPOINTS, "int Sum_of_Specialpoints(const Specialpointsvector& spv,Team winner)"); } if (winner==TEAM::NOTEAM) { int result = 0; result+= re_played - contra_played; result*=no120s; result+= re_trick - contra_trick; #ifdef OUTDATED // 0.6.8 2004-12-03 (-> GameSummary::points(), GameSummary::points(playerno) ) result*= win_mod; #endif DEBUG_RETURNING(result, INFO_BASISTYPES && INFO_SPECIALPOINTS, "int Sum_of_Specialpoints(const Specialpointsvector& spv,Team winner)"); } DEBUG_RETURNING(INT_MIN, INFO_BASISTYPES && INFO_SPECIALPOINTS, "int Sum_of_Specialpoints(const Specialpointsvector& spv,Team winner)"); } // int sum_of_specialpoints(Specialpointsvector, Team winner)