/*
*
* Copyright 2006 by Mark Roth. All rights reserved.
*
*/
package com.octagonsoftware.gwthangman.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Entry point class for Hangman application build on Google's GWT
*
* @author Mark Roth
*/
public class GwtHangman
implements EntryPoint
{
/** UI Widgets */
private RootPanel _contentPanel;
private Panel _titlePanel;
private HorizontalPanel _gamePanel;
private Grid _wordPanel;
private Grid _lettersPanel;
private RadioButton _difficultyEasy;
private RadioButton _difficultyMedium;
private RadioButton _difficultyHard;
private Label _guessesRemainingLabel;
private Image _hangmanImage;
private Label _gameOverLabel;
private Button _playAgainButton;
/** Number of guesses to assign when a new game starts */
private int _newGameGuesses;
/** Number of guesses remaining */
private int _guesses;
/** The word being guessed */
private String _word;
/** True if the game is over */
private boolean _gameOver;
/** True if the letter is guessed or false if not */
private boolean[] _letterGuessed = new boolean[26];
/**
* Called when page loads.
*/
public void onModuleLoad() {
_contentPanel = RootPanel.get("contentPanel");
_contentPanel.setWidth("640");
createTitlePanel();
createGamePanel();
_contentPanel.add(_titlePanel);
_newGameGuesses = 6;
}
private void createTitlePanel() {
_titlePanel = new VerticalPanel();
Label welcome = new Label("Welcome to GWT Hangman!");
_titlePanel.add(welcome);
_titlePanel.add(new HTML("
"));
_difficultyEasy = new RadioButton("difficulty", "Easy (6 guesses)");
_difficultyMedium = new RadioButton("difficulty", "Medium (5 guesses)");
_difficultyHard = new RadioButton("difficulty", "Hard (4 guesses)");
_difficultyEasy.addClickListener(new DifficultyClickListener(6));
_difficultyMedium.addClickListener(new DifficultyClickListener(5));
_difficultyHard.addClickListener(new DifficultyClickListener(4));
_difficultyEasy.setChecked(true);
_titlePanel.add(_difficultyEasy);
_titlePanel.add(_difficultyMedium);
_titlePanel.add(_difficultyHard);
_titlePanel.add(new HTML("
"));
Button playButton = new Button("Play!");
_titlePanel.add(playButton);
playButton.addClickListener(
new ClickListener() {
public void onClick(Widget sender) {
newGame();
}
}
);
}
private void createGamePanel() {
createWordPanel();
createLettersPanel();
_gamePanel = new HorizontalPanel();
VerticalPanel leftPanel = new VerticalPanel();
leftPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
_guessesRemainingLabel = new Label("Guesses Remaining: ");
leftPanel.add(_guessesRemainingLabel);
leftPanel.add(_wordPanel);
leftPanel.setCellHeight(_wordPanel, "130");
_gameOverLabel = new Label("");
_gameOverLabel.setVisible(false);
leftPanel.add(_gameOverLabel);
leftPanel.add(new HTML("
"));
_playAgainButton = new Button("Play Again");
_playAgainButton.setVisible(false);
leftPanel.add(_playAgainButton);
_playAgainButton.addClickListener(
new ClickListener() {
public void onClick(Widget sender) {
mainMenu();
}
}
);
leftPanel.add(_lettersPanel);
leftPanel.setCellHeight(_lettersPanel, "130");
_gamePanel.add(leftPanel);
_gamePanel.setCellWidth(leftPanel, "440");
_hangmanImage = new Image("hangman0.png");
_gamePanel.add(_hangmanImage);
_gamePanel.setCellHeight(leftPanel, "340");
}
private void createWordPanel() {
_wordPanel = new Grid(1, 10);
_wordPanel.setStyleName("gwthangman-bigfont");
}
private void createLettersPanel() {
_lettersPanel = new Grid(2, 13);
_lettersPanel.setStyleName("gwthangman-bigfont");
}
private void newGame() {
_gameOver = false;
_guesses = _newGameGuesses;
for(int i = 0; i < _letterGuessed.length; i++) {
_letterGuessed[i] = false;
}
updateLettersPanel();
int wordIndex = (int)(Math.random() * Words.WORDS.length);
_word = Words.WORDS[wordIndex];
updateWordPanel();
_contentPanel.remove(_titlePanel);
_contentPanel.add(_gamePanel);
_playAgainButton.setVisible(false);
_gameOverLabel.setVisible(false);
_lettersPanel.setVisible(true);
updateGuessesRemaining();
}
private void updateGuessesRemaining() {
_guessesRemainingLabel.setText("Guesses Remaining: " + _guesses);
_hangmanImage.setUrl("hangman" + (6 - _guesses) + ".png");
if(_guesses == 0) {
gameOver();
}
}
private void gameOver() {
_gameOver = true;
updateLettersPanel();
_playAgainButton.setVisible(true);
_gameOverLabel.setVisible(true);
if(isWin()) {
_gameOverLabel.setText("You win!");
_gameOverLabel.setStyleName("gwthangman-win");
}
else {
_gameOverLabel.setText("Game over");
_gameOverLabel.setStyleName("gwthangman-lose");
}
}
private void guess(char c) {
if(_word.indexOf(c) == -1) {
_guesses--;
}
int y = (c - 'A') / 13;
int x = (c - 'A') % 13;
_letterGuessed[c - 'A'] = true;
updateGuessesRemaining();
updateWordPanel();
updateLettersPanel();
if(isWin()) {
gameOver();
}
}
private boolean isWin() {
boolean result = true;
for(int i = 0; i < _word.length(); i++) {
char c = _word.charAt(i);
if(!_letterGuessed[c - 'A']) {
result = false;
break;
}
}
return result;
}
private void mainMenu() {
_contentPanel.remove(_gamePanel);
_contentPanel.add(_titlePanel);
}
private void updateWordPanel() {
for(int i = 0; i < 10; i++) {
if(i < _word.length()) {
char c = _word.charAt(i);
if(_gameOver) {
HTML w = new HTML(c + " ");
_wordPanel.setWidget(0, i, w);
if(!_letterGuessed[c - 'A']) {
w.setStyleName("gwthangman-missingletter");
}
}
else if(!_letterGuessed[c - 'A']) {
_wordPanel.setWidget(0, i, new HTML("_ "));
}
else {
_wordPanel.setWidget(0, i, new HTML(c + " "));
}
}
else {
_wordPanel.setWidget(0, i, new HTML(""));
}
}
}
private void updateLettersPanel() {
for(char c = 'A'; c <= 'Z'; c++) {
int y = (c - 'A') / 13;
int x = (c - 'A') % 13;
Widget w;
if(!_gameOver && !_letterGuessed[c - 'A']) {
Hyperlink hyperlink = new Hyperlink("" + c, "" + c);
final char ch = c;
hyperlink.addClickListener(
new ClickListener() {
public void onClick(Widget sender) {
guess(ch);
}
}
);
w = hyperlink;
}
else {
w = new Label("" + c);
if(_letterGuessed[c - 'A']) {
w.setStyleName("gwthangman-guessed");
}
}
_lettersPanel.setWidget(y, x, w);
}
}
private class DifficultyClickListener
implements ClickListener
{
private int _difficulty;
public DifficultyClickListener(int difficulty) {
_difficulty = difficulty;
}
public void onClick(Widget sender) {
_newGameGuesses = _difficulty;
}
}
}