Wt examples 3.1.10
/build/buildd/witty-3.1.10/examples/hangman/HangmanWidget.C
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 Wim Dumon
00003  *
00004  * See the LICENSE file for terms of use.
00005  */
00006 
00007 #include "HangmanWidget.h"
00008 
00009 #include <Wt/WBreak>
00010 #include <Wt/WCssDecorationStyle>
00011 #include <Wt/WTable>
00012 #include <Wt/WText>
00013 #include <Wt/WTableCell>
00014 #include <Wt/WLineEdit>
00015 #include <Wt/WPushButton>
00016 #include <Wt/WImage>
00017 #include <Wt/WSignalMapper>
00018 #include <boost/lexical_cast.hpp>
00019 
00020 #include "Dictionary.h"
00021 #include "HangmanDb.h"
00022 
00023 HangmanWidget::HangmanWidget(std::wstring user, Dictionary dict,
00024                              WContainerWidget *parent):
00025    WContainerWidget(parent),
00026    MaxGuesses(9),
00027    User(user),
00028    Dict(dict)
00029 {
00030    setContentAlignment(AlignCenter);
00031 
00032    Title = new WText("Guess the word!", this);
00033    Title->decorationStyle().font().setSize(WFont::XLarge);
00034 
00035    WordContainer = new WContainerWidget(this);
00036    WordContainer->setMargin(20, Top | Bottom);
00037    WordContainer->setContentAlignment(AlignCenter);
00038    WCssDecorationStyle& style = WordContainer->decorationStyle();
00039    style.setBorder(WBorder(WBorder::Solid));
00040    style.font().setFamily(WFont::Monospace, "courier");
00041    style.font().setSize(WFont::XXLarge);
00042 
00043    StatusText = new WText(this);
00044    new WBreak(this);
00045    createHangmanImages(this);
00046    createAlphabet(this);
00047    new WBreak(this);
00048    NewGameButton = new WPushButton("New Game", this);
00049    NewGameButton->clicked().connect(this, &HangmanWidget::newGame);
00050 
00051    // prepare for first game
00052    newGame();
00053 }
00054 
00055 void HangmanWidget::createHangmanImages(WContainerWidget *parent)
00056 {
00057    for(unsigned int i = 0; i <= MaxGuesses; ++i) {
00058       std::string fname = "icons/hangman";
00059       fname += boost::lexical_cast<std::string>(i) + ".png";
00060       WImage *theImage = new WImage(fname, parent);
00061       HangmanImages.push_back(theImage);
00062 
00063       // Although not necessary, we can avoid flicker (on konqueror)
00064       // by presetting the image size.
00065       theImage->resize(256, 256);
00066    }
00067 
00068    HurrayImage = new WImage("icons/hangmanhurray.png", parent);
00069    resetImages(); // Hide all images
00070 }
00071 
00072 void HangmanWidget::createAlphabet(WContainerWidget *parent)
00073 {
00074    LetterButtonLayout = new WTable(parent);
00075 
00076    // The default width of a table is 100%...
00077    LetterButtonLayout->resize(13*30, WLength::Auto);
00078 
00079    WSignalMapper<WPushButton *> *mapper
00080      = new WSignalMapper<WPushButton *>(this);
00081 
00082    for(unsigned int i = 0; i < 26; ++i) {
00083       std::wstring c(1, 'A' + i);
00084       WPushButton *character =
00085          new WPushButton(c, LetterButtonLayout->elementAt(i / 13, i % 13));
00086       LetterButtons.push_back(character);
00087       character->resize(30, WLength::Auto);
00088       mapper->mapConnect(character->clicked(), character);
00089    }
00090 
00091    mapper->mapped().connect(this, &HangmanWidget::processButton);
00092 }
00093 
00094 void HangmanWidget::newGame()
00095 {
00096    Word = RandomWord(Dict);
00097    Title->setText(L"Guess the word, " + User + L"!");
00098    NewGameButton->hide(); // don't let the player chicken out
00099 
00100    // Bring widget to initial state
00101    resetImages();
00102    resetButtons();
00103    BadGuesses = DisplayedLetters = 0;
00104    HangmanImages[0]->show();
00105 
00106    // Prepare the widgets for the new word
00107    WordContainer->clear();
00108    WordLetters.clear();
00109    for(unsigned int i = 0; i < Word.size(); ++i) {
00110       WText *c = new WText("-", WordContainer);
00111       WordLetters.push_back(c);
00112    }
00113 
00114    // resize appropriately so that the border nooks nice.
00115    WordContainer->resize(WLength(Word.size() * 1.5, WLength::FontEx),
00116                          WLength::Auto);
00117 
00118    StatusText->setText("");
00119 }
00120 
00121 void HangmanWidget::processButton(WPushButton *button)
00122 {
00123    if (!button->isEnabled())
00124      return;
00125 
00126    wchar_t c = button->text().value().c_str()[0];
00127    if(std::find(Word.begin(), Word.end(), c) != Word.end())
00128       registerCorrectGuess(c);
00129    else
00130       registerBadGuess();
00131    button->disable();
00132 }
00133 
00134 void HangmanWidget::registerBadGuess()
00135 {
00136    if(BadGuesses < MaxGuesses) {
00137       HangmanImages[BadGuesses]->hide();
00138       BadGuesses++;
00139       HangmanImages[BadGuesses]->show();
00140       if(BadGuesses == MaxGuesses) {
00141          StatusText->setText(L"You hang... <br />"
00142                              L"The correct answer was: " + Word);
00143          LetterButtonLayout->hide();
00144          NewGameButton->show();
00145          HangmanDb::addToScore(User, -10);
00146       }
00147    }
00148 }
00149 
00150 void HangmanWidget::registerCorrectGuess(wchar_t c)
00151 {
00152    for(unsigned int i = 0; i < Word.size(); ++i) {
00153       if(Word[i] == c) {
00154          DisplayedLetters++;
00155          WordLetters[i]->setText(std::wstring(1, c));
00156       }
00157    }
00158    if(DisplayedLetters == Word.size()) {
00159       StatusText->setText("You win!");
00160       HangmanImages[BadGuesses]->hide();
00161       HurrayImage->show();
00162       LetterButtonLayout->hide();
00163       NewGameButton->show();
00164       HangmanDb::addToScore(User, 20 - BadGuesses);
00165    }
00166 }
00167 
00168 void HangmanWidget::resetImages()
00169 {
00170     HurrayImage->hide();
00171     for(unsigned int i = 0; i < HangmanImages.size(); ++i)
00172        HangmanImages[i]->hide();
00173 }
00174 
00175 void HangmanWidget::resetButtons()
00176 {
00177    for(unsigned int i = 0; i < LetterButtons.size(); ++i) {
00178       LetterButtons[i]->enable();
00179    }
00180    LetterButtonLayout->show();
00181 }

Generated on Mon Nov 14 2011 for the C++ Web Toolkit (Wt) by doxygen 1.7.4