tournamentstate.cpp
来自「Source code (C++) of the Amoebax game fo」· C++ 代码 · 共 629 行 · 第 1/2 页
CPP
629 行
//// Cross-platform free Puyo-Puyo clone.// Copyright (C) 2006, 2007 Emma's Software//// 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.//#if defined (HAVE_CONFIG_H)#include <config.h>#endif // HAVE_CONFIG_H#include <cassert>#include <sstream>#include "AIPlayerFactory.h"#include "CongratulationsState.h"#include "File.h"#include "HumanPlayer.h"#include "System.h"#include "TournamentState.h"#include "TwoComputerPlayersState.h"#include "TwoPlayersState.h"#include "VersusState.h"#if defined (IS_GP2X_HOST) && !defined (__SYMBIAN32__)#include "TwoGP2XPlayersState.h"#endif // IS_GP2X_HOSTusing namespace Amoebax;static const int32_t k_BlinkTime = 400;static const uint8_t k_InvalidCharacterIndex = 255;static const uint8_t k_FaceSize = 128;static const uint8_t k_FacesPerRow = 7;static const uint16_t k_InitialHorizontalPosition = 1280 / 2 - k_FaceSize / 2;static const int32_t k_MatchStartTime = k_BlinkTime * 8;////// \brief Constructor.////// \param players The list of players going to compete in the tournament.///TournamentState::TournamentState (const std::vector<TournamentState::Player> &players): IState (), m_CurrentMatch (0), m_Background (0), m_BackgroundMusic (0), m_CurrentMatchBlinkTime (k_BlinkTime), m_CurrentMatchStartTime (k_MatchStartTime), m_Faces (0), m_HorizontalOffset (), m_Matches (), m_NumPlayers (players.size ()), m_ShowCurrentOpponents (true), m_SoundLose (Sound::fromFile (File::getSoundFilePath ("youlose.wav"))), m_SoundWin (Sound::fromFile (File::getSoundFilePath ("youwin.wav"))), m_VerticalPosition (){ loadGraphicResources (); createMatchTree (players);}////// \brief Destructor.///TournamentState::~TournamentState (void){ deleteMatch (m_Matches.children.first); deleteMatch (m_Matches.children.second);}voidTournamentState::activate (void){ if ( Music::isPaused () ) { Music::resume (); } else if ( !Music::isPlaying () ) { if ( 0 == m_BackgroundMusic.get () ) { m_BackgroundMusic.reset (Music::fromFile (File::getMusicFilePath ("menu.ogg"))); } m_BackgroundMusic->play (); }}////// \brief Creates the tree of matches.////// Based on the number of players, this function creates a tree/// of matches and initializes it. It also initializes the vertical/// positions and horizontal offsets of each level of the tree.////// \param players The vector of players that will play at the tournament.///voidTournamentState::createMatchTree (const std::vector<Player> &players){ assert ( (2 == players.size () || 4 == players.size ()) && "Currently only tournaments of 2 or 4 players are supported." ); // This is a sentinel player used to represent unused entries. Player sentinelPlayer; sentinelPlayer.characterIndex = k_InvalidCharacterIndex; // The first "match" is the winner. m_Matches.parent = 0; m_Matches.opponents.first = sentinelPlayer; m_Matches.opponents.second = sentinelPlayer; m_Matches.children.second = 0; Match *semifinal = new Match; semifinal->parent = &m_Matches; if ( 2 == players.size () ) { m_HorizontalOffset.push_back (0); m_HorizontalOffset.push_back (192); m_VerticalPosition.push_back (288); m_VerticalPosition.push_back (544); semifinal->opponents.first = players[0]; semifinal->opponents.first.score = 0; semifinal->opponents.second = players[1]; semifinal->opponents.second.score = 0; semifinal->children.first = 0; semifinal->children.second = 0; m_Matches.children.first = semifinal; m_CurrentMatch = semifinal; } else { m_HorizontalOffset.push_back (0); m_HorizontalOffset.push_back (321); m_HorizontalOffset.push_back (192); m_VerticalPosition.push_back (160); m_VerticalPosition.push_back (416); m_VerticalPosition.push_back (672); semifinal->opponents.first = sentinelPlayer; semifinal->opponents.second = sentinelPlayer; m_Matches.children.first = semifinal; Match *leftMatch = new Match; leftMatch->children.first = 0; leftMatch->children.second = 0; leftMatch->parent = semifinal; leftMatch->opponents.first = players[0]; leftMatch->opponents.first.score = 0; leftMatch->opponents.second = players[1]; leftMatch->opponents.second.score = 0; Match *rightMatch = new Match; rightMatch->children.first = 0; rightMatch->children.second = 0; rightMatch->parent = semifinal; rightMatch->opponents.first = players[2]; rightMatch->opponents.first.score = 0; rightMatch->opponents.second = players[3]; rightMatch->opponents.second.score = 0; semifinal->children.first = leftMatch; semifinal->children.second = rightMatch; m_CurrentMatch = leftMatch; }}////// \brief Recursively deletes a match and all its children.////// \param match The match to delete, and all its children.///voidTournamentState::deleteMatch (Match *match){ if ( 0 != match ) { deleteMatch (match->children.first); deleteMatch (match->children.second); delete match; }}voidTournamentState::endOfMatch (IPlayer::PlayerSide winner, uint32_t leftPlayerScore, uint32_t rightPlayerScore){ // Check if both players are computers, to play the correct sound later. bool bothComputer = getCurrentMatch ()->opponents.first.isComputerPlayer && getCurrentMatch ()->opponents.second.isComputerPlayer; // Accumulate the scores. getCurrentMatch ()->opponents.first.score += leftPlayerScore; getCurrentMatch ()->opponents.second.score += rightPlayerScore; Player winnerPlayer; if ( IPlayer::LeftSide == winner ) { winnerPlayer = getCurrentMatch ()->opponents.first; getCurrentMatch ()->opponents.first.characterIndex = k_InvalidCharacterIndex; } else { winnerPlayer = getCurrentMatch ()->opponents.second; getCurrentMatch ()->opponents.second.characterIndex = k_InvalidCharacterIndex; } if ( getCurrentMatch()->parent == &m_Matches ) { setCurrentMatch (&m_Matches); m_Matches.opponents.first = winnerPlayer; } else if ( getCurrentMatch () == getCurrentMatch ()->parent->children.first ) { getCurrentMatch ()->parent->opponents.first = winnerPlayer; if ( 0 != getCurrentMatch ()->parent->children.second ) { setCurrentMatch (getCurrentMatch ()->parent->children.second); } else { setCurrentMatch (getCurrentMatch ()->parent); } } else { getCurrentMatch ()->parent->opponents.second = winnerPlayer; setCurrentMatch (getCurrentMatch ()->parent); } // Play the "winner" sound effect if the winner is human, otherwise // play the "lose" sound effect. if ( winnerPlayer.isComputerPlayer ) { if ( bothComputer ) { m_SoundWin->play (); } else { m_SoundLose->play (); } } else { m_SoundWin->play (); }}////// \brief Gets the best two players states based on the characters.////// \param leftCharacter The information about the left player's character./// \param rightCharacter The information about the right player's character./// \return The best two players state based on \p leftCharacter and/// \p rightCharacter fully initialized and ready to be set as/// active.///IState *TournamentState::getBestTwoPlayersState (const Player &leftCharacter, const Player &rightCharacter){ IState *twoPlayersState = 0; if ( leftCharacter.isComputerPlayer && rightCharacter.isComputerPlayer ) { twoPlayersState = new TwoComputerPlayersState (leftCharacter.computerPlayerLevel, rightCharacter.computerPlayerLevel, this); }#if defined (IS_GP2X_HOST)&& !defined (__SYMBIAN32__) else if ( !leftCharacter.isComputerPlayer && !rightCharacter.isComputerPlayer ) { twoPlayersState = new TwoGP2XPlayersState ( AIPlayerFactory::getRandomBackgroundFileName (), leftCharacter.score, rightCharacter.score, this); }#endif // IS_GP2X_HOST else { IPlayer *leftPlayer = getMatchPlayer (leftCharacter, IPlayer::LeftSide); IPlayer *rightPlayer = getMatchPlayer (rightCharacter, IPlayer::RightSide); twoPlayersState = new TwoPlayersState (leftPlayer, rightPlayer, AIPlayerFactory::getRandomBackgroundFileName (), leftCharacter.score, rightCharacter.score, this); } return twoPlayersState;}////// \brief Gets the current match.////// \return The pointer to the current match.///
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?