Wt examples 3.1.10
|
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 }