/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ import java.util.Hashtable; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Choice; import javax.microedition.lcdui.ChoiceGroup; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.StringItem; import javax.microedition.midlet.MIDlet; /** * This class implements the old "tic tac toe" game * on a client device. */ public class TicTacToeMIDlet extends AbstractMIDlet implements CommandListener { private Display display; private StringItem position; private ChoiceGroup boardSize; private StringItem message; private StringItem result; private Command exitCommand; private Command startCommand; private Command selectCommand; private Command sizeSelectCommand; private Command continueCommand; private Command newGameCommand; private BoardCanvas board; private Form startForm; private Form sizeForm; private Form messageForm; private Form waitForm; private Form gameOverForm; private String webform; private ConnectionManager connectionMgr; private Thread connectionThread; // ------ Standard MIDlet methods ----------------------------- public void startApp() { display = Display.getDisplay(this); exitCommand = new Command("Exit", Command.EXIT, 1); createStartForm(); createSizeForm(); createBoardCanvas(); createGameOverForm(); connectionMgr = new ConnectionManager(this); connectionThread = new Thread(connectionMgr); connectionThread.start(); waitForm = new Form("Waiting..."); display.setCurrent(startForm); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} // ------ Create Display Objects ------------------------------ public void createStartForm() { startForm = new Form("Start"); startForm.setTitle("Welcome"); startForm.append("Start the TicTacToe Game"); startCommand = new Command("Start", Command.OK, 0); startForm.addCommand(startCommand); startForm.addCommand(exitCommand); startForm.setCommandListener(this); } public void createSizeForm() { sizeForm = new Form("Size"); sizeForm.setTitle("Game Board Size Selection"); sizeForm.append("Choose a board size:"); boardSize = new ChoiceGroup("Size", Choice.EXCLUSIVE); sizeForm.append(boardSize); sizeSelectCommand = new Command("Select", Command.OK, 0); sizeForm.addCommand(sizeSelectCommand); sizeForm.addCommand(exitCommand); sizeForm.setCommandListener(this); } public void createBoardCanvas() { board = new BoardCanvas(); board.setTitle("Game Board"); selectCommand = new Command("Select", Command.OK, 0); board.addCommand(selectCommand); board.setCommandListener(this); } public void createMessageForm() { messageForm = new Form("Message"); message = new StringItem("", null); messageForm.append(message); continueCommand = new Command("Continue", Command.OK, 0); messageForm.addCommand(continueCommand); messageForm.addCommand(exitCommand); messageForm.setCommandListener(this); } public void createGameOverForm() { gameOverForm = new Form("Game Over"); result = new StringItem("", null); gameOverForm.append(result); newGameCommand = new Command("New Game", Command.OK, 0); gameOverForm.addCommand(newGameCommand); gameOverForm.addCommand(exitCommand); gameOverForm.setCommandListener(this); } /** * The standard listener method for MIDlet commands.. */ public void commandAction(Command c, Displayable s) { if (c == startCommand) { doStart(); } else if (c == sizeSelectCommand) { doSizeSelect(); } else if (c == selectCommand) { doSelect(); } else if (c == newGameCommand) { notifyDestroyed(); doNewGame(); } else if (c == exitCommand) notifyDestroyed(); } // ------ Connection Methods -------------------------------- public void connect(String url, Hashtable request) { display.setCurrent(waitForm); connectionMgr.connect(url, request); } public void connectionCompleted(Hashtable response) { webform = (String) response.get("form"); if (webform.equals("start")) { displayStart(response); } else if (webform.equals("play")) { displayPlay(response); } else if ((webform.equals("won")) || (webform.equals("lost")) || (webform.equals("draw"))) { displayGameOver(response); } } // ------ Helper Methods private void doStart() { connect("start.faces", null); } private void doSizeSelect() { Hashtable request = new Hashtable(); request.put("boardsize", boardSize.getString( boardSize.getSelectedIndex())); request.put("form", "start"); request.put("submit", ""); connect("start.faces", request); } private void doSelect() { Hashtable request = new Hashtable(); request.put("board", board.getString()); request.put("form", "play"); request.put("submit", ""); connect("play.faces", request); } private void doNewGame() { Hashtable request = new Hashtable(); request.put("form", webform); request.put("newgame", ""); connect(webform + ".faces", request); } private void displayStart(Hashtable response) { // Display the choice group from response data.... String name = "boardsize"; String value = (String) response.get(name); String label = null; int i = 0; boardSize.deleteAll(); while ((label = (String) response.get(name + ".label." + i)) != null) { boardSize.append(label, null); if (label.equals(value)) { boardSize.setSelectedIndex(i, true); } i++; } display.setCurrent(sizeForm); } private void displayPlay(Hashtable response) { board.parse((String) response.get("board")); String msg = (String) response.get("messages.board"); if (msg != null) { message.setText(msg); display.setCurrent(messageForm); return; } display.setCurrent(board); } private void displayGameOver(Hashtable response) { result.setText((String) response.get("result")); display.setCurrent(gameOverForm); } } /** * Canvas used for displaying and manipulating the game board. */ class BoardCanvas extends Canvas { public static final int SELECTED = 1; public static final int TAKEN = 2; private int[][] positions; private int rows = 0; private int columns = 0; private int currentRow = 0; private int currentColumn = 0; public void parse(String layout) { for (int i = 0; i < layout.length(); i++) { if (layout.charAt(i) == ' ') { rows = i; break; } } columns = rows; positions = new int[rows][columns]; int n = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { char c = layout.charAt(n); n++; positions[i][j] = c - '0'; } n++; } } public String getString() { return "" + (char) ('A' + currentRow) + (1 + currentColumn); } public void paint(Graphics g) { int width = getWidth(); int height = getHeight(); int oldColor = g.getColor(); g.setColor(0xFFFFFF); g.fillRect(0, 0, width, height); g.setColor(oldColor); int cellWidth = width / (columns + 2); int cellHeight = height / (rows + 2); int cellSize = Math.min(cellWidth, cellHeight); for (int i = 0; i <= rows; i++) { int y = (i + 1) * cellSize; g.drawLine(cellSize, y, (columns + 1) * cellSize, y); } for (int j = 0; j <= columns; j++) { int x = (j + 1) * cellSize; g.drawLine(x, cellSize, x, (rows + 1) * cellSize); } for (int i = 0; i < rows; i++) { int y = (i + 1) * cellSize; for (int j = 0; j < columns; j++) { int x = (j + 1) * cellSize; int p = positions[i][j]; if ((p & SELECTED) != 0) g.drawRect(x+6, y+6, cellSize-12, cellSize-12); if ((p & TAKEN) != 0) { if (p == (TAKEN | SELECTED)) { oldColor = g.getColor(); g.setColor(0xFFFFFF); } g.drawLine(x, y, x + cellSize, y + cellSize); g.drawLine(x + cellSize, y, x, y + cellSize); if (p == (TAKEN | SELECTED)) g.setColor(oldColor); } } } int x = (currentColumn + 1) * cellSize; int y = (currentRow + 1) * cellSize; g.drawRect(x - 1, y - 1, cellSize + 2, cellSize + 2); } public void keyPressed(int keyCode) { int gameAction = getGameAction(keyCode); if (gameAction == LEFT) { currentColumn = (currentColumn + columns - 1) % columns; } else if (gameAction == RIGHT) { currentColumn = (currentColumn + 1) % columns; } else if (gameAction == UP) { currentRow = (currentRow + rows - 1) % rows; } else if (gameAction == DOWN) { currentRow = (currentRow + 1) % rows; } repaint(); } }