SPARK-1378, TicTacToe plugin, if you want it compile it ;-)

fix in reversi: dont display button in groupchat

git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@12496 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Wolf Posdorfer
2011-06-16 12:54:37 +00:00
committed by wolf.posdorfer
parent 5e1cdcd649
commit 2757415106
26 changed files with 1539 additions and 0 deletions

View File

@ -251,6 +251,11 @@ public class ReversiPlugin implements Plugin {
ImageIcon icon = ReversiRes.getImageIcon(ReversiRes.REVERSI_ICON);
public void chatRoomOpened(final ChatRoom room) {
if(!(room instanceof ChatRoomImpl))
{
// Don't do anything if this is not a 1on1-Chat
return;
}
ChatRoomButton button = new ChatRoomButton(icon);
button.setToolTipText("Reversi");
room.getToolBar().addChatRoomButton(button);

View File

@ -0,0 +1,98 @@
<project name="tictactoe" default="jar" basedir="..">
<property name="plug.dir" value="${basedir}"/>
<property name="plug.lib.dir" value="${plug.dir}/build/lib"/>
<property name="plug.lib.dist.dir" value="${plug.lib.dir}/dist"/>
<property name="spark.home" value="${basedir}/../../.."/>
<property name="spark.target" value="${basedir}/../../../target"/>
<property name="spark.build" value="${basedir}/../../../target/build"/>
<property name="classes.dir" value="${spark.target}/plugins-dev/tictactoe/classes"/>
<property name="src.dir" value="${plug.dir}/src/java"/>
<property name="resources.dir" location="${plug.dir}/src/resources"/>
<property name="target.dir" value="${spark.target}/plugins/tictactoe"/>
<property name="target.lib.dir" value="${target.dir}/lib"/>
<property name="jar.file" value="${target.dir}/lib/plugin-classes.jar"/>
<path id="lib.classpath">
<fileset dir="${plug.lib.dir}" includes="**/*.jar, **/*.zip"/>
<fileset dir="${spark.home}/target/build/lib" includes="**/*.jar, **/*.zip"/>
<fileset dir="${spark.home}/target/build/lib/windows" includes="**/*.jar"/>
</path>
<target name="clean" description="Cleans all build related output">
<delete file="${jar.file}"/>
<delete dir="${classes.dir}"/>
<delete dir="${target.dir}"/>
</target>
<target name="compile" description="Compiles plugin source">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}"
destdir="${classes.dir}"
classpathref="lib.classpath"
source="1.6"
debug="true"
target="1.6"/>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}" includes="**/*.png"/>
<fileset dir="${src.dir}" includes="**/*.gif"/>
<fileset dir="${src.dir}" includes="**/*.jpg"/>
<fileset dir="${src.dir}" includes="**/*.jpeg"/>
<fileset dir="${src.dir}" includes="**/*.wav"/>
<fileset dir="${src.dir}" includes="**/*.properties"/>
</copy>
</target>
<target name="jar" depends="clean,compile,resources" description="Makes a plugin jar">
<mkdir dir="${target.dir}"/>
<mkdir dir="${target.lib.dir}"/>
<copy todir="${target.lib.dir}">
<fileset file="${plug.lib.dir}/lib" includes="**/*"/>
</copy>
<copy todir="${target.dir}">
<fileset file="${plug.dir}/plugin.xml"/>
</copy>
<jar basedir="${classes.dir}" file="${jar.file}" update="false"/>
<zip zipfile="${spark.build}/plugins/tictactoe.jar" basedir="${target.dir}"/>
<copy todir="${spark.home}/src/commercial">
<fileset file="${spark.build}/plugins/tictactoe.jar"/>
</copy>
</target>
<!-- resources =================================================================================== -->
<target name="resources">
<copy todir="${classes.dir}">
<fileset dir="${resources.dir}">
<include name="**/*"/>
</fileset>
<fileset dir="${src.dir}">
<include name="**/*.properties"/>
</fileset>
</copy>
</target>
<property name="pluginsstuff" value="${basedir}\..\..\..\target\build\plugins"/>
<target name="copy" depends="jar">
<echo message="${pluginsstuff}"/>
<copy todir="${pluginsstuff}">
<fileset file="${spark.build}/plugins/tictactoe.jar"/>
</copy>
</target>
</project>

View File

@ -0,0 +1,12 @@
<plugin>
<name>TicTacToe of Doom</name>
<class>tic.tac.toe.TicTacToePlugin</class>
<author>Wolf Posdorfer</author>
<version>0.1</version>
<homePage>http://www.jivesoftware.com</homePage>
<description>The most sophisticated TicTacToe Game ever created</description>
<email>9posdorf@informatik.uni-hamburg.de</email>
<minSparkVersion>2.6.1</minSparkVersion>
<os>Windows,Linux,Mac</os>
<java>1.6.0_00</java>
</plugin>

View File

@ -0,0 +1,207 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Class to represent the TicTacToe gameboard
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class GameBoard {
private int[][] _board;
private int _currentPlayer;
private int _winner;
public GameBoard() {
_board = new int[3][3];
for (int[] x : _board) {
Arrays.fill(x, Mark.BLANK.ordinal());
}
_currentPlayer = Mark.X.ordinal();
_winner = 0;
}
public boolean isGameFinished() {
return _winner != 0;
}
public int getWinner()
{
return _winner;
}
public Mark getMarkAtPos(int x, int y) {
return Mark.valueOf(_board[x][y]);
}
public Mark getCurrentPlayer() {
return Mark.valueOf(_currentPlayer);
}
public void placeMark(int x, int y) {
_board[x][y] = _currentPlayer;
if (didCurrentPlayerWin()) {
_winner = _currentPlayer;
}
if (isBoardFull() && _winner < 1) {
// Setting to Tie
_winner = -1;
}
_currentPlayer = _currentPlayer == 1 ? 2 : 1;
}
/**
* Checks if the Currentplayer has won the game
*
* @return current player won the game?
*/
private boolean didCurrentPlayerWin() {
for (int x = 0; x < 3; x++) {
if (_board[x][0] == _currentPlayer
&& _board[x][1] == _currentPlayer
&& _board[x][2] == _currentPlayer) {
return true;
}
}
for (int y = 0; y < 3; y++) {
if (_board[0][y] == _currentPlayer
&& _board[1][y] == _currentPlayer
&& _board[2][y] == _currentPlayer) {
return true;
}
}
if (_board[0][0] == _currentPlayer && _board[1][1] == _currentPlayer
&& _board[2][2] == _currentPlayer) {
return true;
}
if (_board[2][0] == _currentPlayer && _board[1][1] == _currentPlayer
&& _board[0][2] == _currentPlayer) {
return true;
}
return false;
}
/**
* Checks if the Board is Full
*
* @return board is full?
*/
private boolean isBoardFull() {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (_board[x][y] == 0) {
return false;
}
}
}
return true;
}
/**
* Returns the winning positions in an arraylist of Pairs
* @return ArrayList<Pair> with 3 entries
*/
public Pair[] getWinningPositions()
{
ArrayList<Pair> liste = new ArrayList<Pair>();
if(_winner == -1)
{
// TIE
return null;
}
Mark m = Mark.valueOf(_winner);
for (int x = 0; x < 3; x++) {
if (_board[x][0] == _winner
&& _board[x][1] == _winner
&& _board[x][2] == _winner) {
new Pair(x, 0,m);
liste.add(new Pair(x, 0, m));
liste.add(new Pair(x, 1, m));
liste.add(new Pair(x, 2, m));
return liste.toArray(new Pair[3]);
}
}
for (int y = 0; y < 3; y++) {
if (_board[0][y] == _winner
&& _board[1][y] == _winner
&& _board[2][y] == _winner) {
liste.add(new Pair(0, y, m));
liste.add(new Pair(1, y, m));
liste.add(new Pair(2, y, m));
return liste.toArray(new Pair[3]);
}
}
if (_board[0][0] == _winner && _board[1][1] == _winner
&& _board[2][2] == _winner) {
liste.add(new Pair(0, 0, m));
liste.add(new Pair(1, 1, m));
liste.add(new Pair(2, 2, m));
return liste.toArray(new Pair[3]);
}
if (_board[2][0] == _winner && _board[1][1] == _winner
&& _board[0][2] == _winner) {
liste.add(new Pair(2, 0, m));
liste.add(new Pair(1, 1, m));
liste.add(new Pair(0, 2, m));
return liste.toArray(new Pair[3]);
}
return null;
}
}

View File

@ -0,0 +1,73 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe;
import javax.swing.ImageIcon;
/**
* The Variations of Marks
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public enum Mark {
BLANK (0, "empty.png", "empty.png"),
X (1, "x.png", "x.blue.png"),
O (2, "o.png", "o.blue.png");
private int value;
private String icon;
private String redicon;
public static Mark valueOf(int x) {
switch (x) {
case 0:
return BLANK;
case 1:
return X;
case 2:
return O;
default:
return BLANK;
}
}
public ImageIcon getImage() {
ClassLoader cl = getClass().getClassLoader();
return new ImageIcon(cl.getResource(icon));
}
public ImageIcon getRedImage()
{
ClassLoader cl = getClass().getClassLoader();
return new ImageIcon(cl.getResource(redicon));
}
public int getValue() {
return value;
}
private Mark(int value, String icon, String redicon) {
this.value = value;
this.icon = icon;
this.redicon = redicon;
}
}

View File

@ -0,0 +1,56 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe;
/**
* Represents a Pair of Coordinates with the Mark underneath
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class Pair {
private int _x;
private int _y;
private Mark _m;
public Pair(int x, int y, Mark m) {
_x = x;
_y = y;
_m = m;
}
public int getX() {
return _x;
}
public int getY() {
return _y;
}
public Mark getMark() {
return _m;
}
public String toString() {
return "[" + _x + "," + _y + ";" + _m + "]";
}
}

View File

@ -0,0 +1,63 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe;
import java.text.MessageFormat;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.jivesoftware.spark.util.log.Log;
/**
* Resource Bundle for TicTacToe
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class TTTRes {
private static PropertyResourceBundle prb;
static ClassLoader cl = TTTRes.class.getClassLoader();
static {
prb = (PropertyResourceBundle) ResourceBundle
.getBundle("i18n/tictactoe_i18n");
}
public static final String getString(String propertyName) {
try {
return prb.getString(propertyName);
} catch (Exception e) {
Log.error(e);
return propertyName;
}
}
public static String getString(String propertyName, Object... obj) {
String str = prb.getString(propertyName);
if (str == null) {
return propertyName;
}
return MessageFormat.format(str, obj);
}
}

View File

@ -0,0 +1,278 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.jivesoftware.resource.Res;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomButton;
import org.jivesoftware.spark.ui.ChatRoomListener;
import org.jivesoftware.spark.ui.ChatRoomListenerAdapter;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import tic.tac.toe.packet.GameOfferPacket;
import tic.tac.toe.packet.MovePacket;
import tic.tac.toe.ui.GamePanel;
/**
* Tic Tac Toe plugin for Spark
*
* @author wolf.posdorfer
* @version 16.06.2011
*
*/
public class TicTacToePlugin implements Plugin {
private ChatRoomListener _chatRoomListener;
private PacketListener _gameOfferListener;
private HashSet<String> _currentInvitations;
private ImageIcon buttonimg;
@Override
public void initialize() {
ClassLoader cl = getClass().getClassLoader();
buttonimg = new ImageIcon(cl.getResource("ttt.button.png"));
_currentInvitations = new HashSet<String>();
ProviderManager.getInstance().addIQProvider(GameOfferPacket.ELEMENT_NAME, GameOfferPacket.NAMESPACE,GameOfferPacket.class);
ProviderManager.getInstance().addExtensionProvider(MovePacket.ELEMENT_NAME, MovePacket.NAMESPACE, MovePacket.class);
// Add IQ listener to listen for incoming game invitations.
_gameOfferListener = new PacketListener() {
public void processPacket(Packet packet) {
GameOfferPacket invitation = (GameOfferPacket) packet;
if (invitation.getType() == IQ.Type.GET) {
showInvitationAlert(invitation);
}
}
};
SparkManager.getConnection().addPacketListener(_gameOfferListener,
new PacketTypeFilter(GameOfferPacket.class));
addButtonToToolBar();
}
/**
* Add the TTT-Button to every opening Chatroom
* and create Listeners for it
*/
private void addButtonToToolBar() {
_chatRoomListener = new ChatRoomListenerAdapter() {
@Override
public void chatRoomOpened(final ChatRoom room) {
if(!(room instanceof ChatRoomImpl))
{
// Don't do anything if this is not a 1on1-Chat
return;
}
final ChatRoomButton sendGameButton = new ChatRoomButton(buttonimg);
room.getToolBar().addChatRoomButton(sendGameButton);
final String opponentJID = ((ChatRoomImpl) room).getJID();
sendGameButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(_currentInvitations.contains(StringUtils.parseBareAddress(opponentJID)))
{
return;
}
final GameOfferPacket offer = new GameOfferPacket();
offer.setTo(opponentJID);
offer.setType(IQ.Type.GET );
_currentInvitations.add(StringUtils.parseBareAddress(opponentJID));
room.getTranscriptWindow().insertCustomText
(TTTRes.getString("ttt.request.sent"), false, false, Color.BLUE);
SparkManager.getConnection().sendPacket(offer);
SparkManager.getConnection().addPacketListener(
new PacketListener() {
@Override
public void processPacket(Packet packet) {
GameOfferPacket answer = (GameOfferPacket)packet;
answer.setStartingPlayer(offer.isStartingPlayer());
answer.setGameID(offer.getGameID());
if (answer.getType() == IQ.Type.RESULT) {
// ACCEPT
_currentInvitations.remove(StringUtils.parseBareAddress(opponentJID));
room.getTranscriptWindow().insertCustomText
(TTTRes.getString("ttt.request.accept"), false, false, Color.BLUE);
createTTTWindow(answer, opponentJID);
} else {
// DECLINE
room.getTranscriptWindow().insertCustomText
(TTTRes.getString("ttt.request.decline"), false, false, Color.RED);
_currentInvitations.remove(StringUtils.parseBareAddress(opponentJID));
}
}
},
new PacketIDFilter(offer.getPacketID()));
}
});
}
};
SparkManager.getChatManager().addChatRoomListener(_chatRoomListener);
}
@Override
public void shutdown() {
_currentInvitations.clear();
SparkManager.getChatManager().removeChatRoomListener(_chatRoomListener);
SparkManager.getConnection().removePacketListener(_gameOfferListener);
}
@Override
public boolean canShutDown() {
return false;
}
@Override
public void uninstall() {
}
/**
* insert the Invitation Dialog into the Chat
*
* @param invitation
*/
private void showInvitationAlert(final GameOfferPacket invitation) {
invitation.setType(IQ.Type.RESULT);
invitation.setTo(invitation.getFrom());
final ChatRoom room = SparkManager.getChatManager().getChatRoom(StringUtils.parseBareAddress(invitation.getFrom()));
String name = StringUtils.parseName(invitation.getFrom());
final JPanel panel = new JPanel();
JLabel text = new JLabel(TTTRes.getString("ttt.game.request",name));
JLabel game = new JLabel(TTTRes.getString("ttt.game.name"));
game.setFont(new Font("Dialog", Font.BOLD, 24));
game.setForeground(Color.RED);
JButton accept = new JButton(Res.getString("button.accept").replace("&", ""));
JButton decline = new JButton(Res.getString("button.decline").replace("&", ""));
panel.add(text);
panel.add(game);
panel.add(accept);
panel.add(decline);
room.getTranscriptWindow().addComponent(panel);
accept.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SparkManager.getConnection().sendPacket(invitation);
invitation.setStartingPlayer(!invitation.isStartingPlayer());
createTTTWindow(invitation, invitation.getFrom());
panel.remove(3);
panel.remove(2);
panel.repaint();
panel.revalidate();
}
});
decline.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
invitation.setType(IQ.Type.ERROR);
SparkManager.getConnection().sendPacket(invitation);
panel.remove(3);
panel.remove(2);
panel.repaint();
panel.revalidate();
}
});
}
/**
* Creates The TicTacToe Window and starts the Game
* @param gop
* @param opponentJID
*/
private void createTTTWindow(GameOfferPacket gop, String opponentJID) {
String name = StringUtils.parseName(opponentJID);
// tictactoe versus ${name}
JFrame f = new JFrame(TTTRes.getString("ttt.window.title", TTTRes.getString("ttt.game.name"),name));
f.setIconImage(buttonimg.getImage());
GamePanel gp = new GamePanel(SparkManager.getConnection(),
gop.getGameID(), gop.isStartingPlayer(), opponentJID,f);
f.add(gp);
f.pack();
f.setLocationRelativeTo(SparkManager.getChatManager().getChatContainer());
f.setVisible(true);
}
}

View File

@ -0,0 +1,99 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.packet;
import java.util.Random;
import org.jivesoftware.smack.packet.IQ;
/**
* The Game Offer Packet
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class GameOfferPacket extends IQ {
public static final String ELEMENT_NAME = "tictactoe";
public static final String NAMESPACE = "tictactoe";
private int gameID;
private boolean imTheStartingPlayer;
public GameOfferPacket() {
super();
imTheStartingPlayer = new Random().nextBoolean();
gameID = Math.abs(new Random().nextInt());
}
/**
* Returns the game ID.
*
* @return the game ID.
*/
public int getGameID() {
return gameID;
}
/**
* Sets the game ID.
*
* @param gameID
* the game ID.
*/
public void setGameID(int gameID) {
this.gameID = gameID;
}
/**
* Returns true if the user making the game invitation is the starting
* player.
*
* @return true if the user making the game invite is the starting player.
*/
public boolean isStartingPlayer() {
return imTheStartingPlayer;
}
/**
* Sets whether the user making the game invitation is the starting player.
*
* @param startingPlayer
* true if the user making the game invite is the starting
* player.
*/
public void setStartingPlayer(boolean startingPlayer) {
this.imTheStartingPlayer = startingPlayer;
}
public String getChildElementXML() {
StringBuffer buf = new StringBuffer();
buf.append("<" + ELEMENT_NAME + " xmlns=\"" + NAMESPACE + "\">");
if (getType() == IQ.Type.GET) {
buf.append("<gameID>").append(gameID).append("</gameID>");
buf.append("<startingPlayer>").append(imTheStartingPlayer)
.append("</startingPlayer>");
buf.append(getExtensionsXML());
}
buf.append("</" + ELEMENT_NAME + ">");
return buf.toString();
}
}

View File

@ -0,0 +1,90 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.packet;
import org.jivesoftware.smack.packet.PacketExtension;
/**
* The Move Packet extension
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class MovePacket implements PacketExtension {
public static final String ELEMENT_NAME = "ttt-move";
public static final String NAMESPACE = "tictactoe";
private int posx;
private int posy;
private int gameID;
public int getGameID() {
return gameID;
}
public void setGameID(int gameID) {
this.gameID = gameID;
}
@Override
public String getElementName() {
return ELEMENT_NAME;
}
@Override
public String getNamespace() {
return NAMESPACE;
}
public int getPositionX() {
return posx;
}
public void setPositionX(int posx) {
this.posx = posx;
}
public int getPositionY() {
return posy;
}
public void setPositionY(int posy) {
this.posy = posy;
}
@Override
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<" + ELEMENT_NAME + " xmlns=\"" + NAMESPACE + "\">");
buf.append("<gameID>").append(gameID).append("</gameID>");
buf.append("<positionX>").append(posx).append("</positionX>");
buf.append("<positionY>").append(posy).append("</positionY>");
buf.append("</" + ELEMENT_NAME + ">");
return buf.toString();
}
}

View File

@ -0,0 +1,138 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.ui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import tic.tac.toe.Mark;
import tic.tac.toe.Pair;
/**
* The Gui to the Logical Board
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class GameBoardPanel extends JPanel {
private static final long serialVersionUID = -178497456422566485L;
private Image _backgroundimage;
private JLabel[][] _labels;
private GamePanel _owner;
public GameBoardPanel(GamePanel gamepanel) {
_owner = gamepanel;
setLayout(new GridLayout(3, 3));
_labels = new JLabel[3][3];
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
JLabel toadd = new JLabel(Mark.BLANK.getImage());
toadd.setOpaque(false);
final int xx = x;
final int yy = y;
toadd.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (_owner.myTurn() && _owner.isFree(xx, yy)) {
placeMark(_owner.getMyMark(), xx, yy);
}
}
});
_labels[x][y] = toadd;
add(_labels[x][y]);
}
}
ClassLoader cl = getClass().getClassLoader();
_backgroundimage = new ImageIcon(cl.getResource("board.png"))
.getImage();
setPreferredSize(new Dimension(500, 500));
}
/**
* Places the Mark, and tells the Owner to place the mark on the logical
* board
*
* @param m
* @param x
* @param y
*/
public void placeMark(Mark m, int x, int y) {
_labels[x][y].setIcon(m.getImage());
// Notify the Owner about Change
_owner.onGameBoardPlaceMark(m, x, y);
this.invalidate();
this.repaint();
this.revalidate();
}
public void colorizeWinners(Pair[] pairs)
{
if(pairs!=null)
{
for(Pair p : pairs)
{
_labels[p.getX()][p.getY()].setIcon(p.getMark().getRedImage());
}
}
this.repaint();
this.revalidate();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
final Image backgroundImage = _backgroundimage;
double scaleX = getWidth() / (double) backgroundImage.getWidth(null);
double scaleY = getHeight() / (double) backgroundImage.getHeight(null);
AffineTransform xform = AffineTransform
.getScaleInstance(scaleX, scaleY);
((Graphics2D) g).drawImage(backgroundImage, xform, this);
}
}

View File

@ -0,0 +1,51 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.ui;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* The Panel to be displayed on Winning/Losing/Tie
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class GameEndsUI extends JPanel {
/**
*
*/
private static final long serialVersionUID = -5947922803585454129L;
public GameEndsUI(String text, Color c)
{
JLabel label = new JLabel(text);
label.setFont(new Font("Dialog", Font.BOLD, 32));
label.setForeground(c);
add(label);
}
}

View File

@ -0,0 +1,192 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.spark.ui.ShakeWindow;
import tic.tac.toe.GameBoard;
import tic.tac.toe.Mark;
import tic.tac.toe.TTTRes;
import tic.tac.toe.packet.MovePacket;
/**
* Holds the GameBoard and the Playerdisplay
*
* @author wolf.posdorfer
* @version 16.06.2011
*/
public class GamePanel extends JPanel {
private static final long serialVersionUID = 5481864290352375841L;
private GameBoardPanel _gameboardpanel;
private PlayerDisplay _playerdisplay;
private Mark me;
private GameBoard _gameboard;
private XMPPConnection _connection;
private int _gameID;
private String _opponent;
private JFrame _frame;
public GamePanel(XMPPConnection connection, final int gameID,
boolean imStarting, String opponentJID, JFrame frame) {
_frame = frame;
_opponent = opponentJID;
_gameID = gameID;
_gameboard = new GameBoard();
_connection = connection;
_gameboardpanel = new GameBoardPanel(this);
if (imStarting) {
me = Mark.X;
} else {
me = Mark.O;
}
_playerdisplay = new PlayerDisplay(me, opponentJID);
setLayout(new BorderLayout());
add(_gameboardpanel, BorderLayout.CENTER);
add(_playerdisplay, BorderLayout.SOUTH);
_connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
MovePacket move = (MovePacket) packet.getExtension(
MovePacket.ELEMENT_NAME, MovePacket.NAMESPACE);
if (move.getGameID() == _gameID) {
_gameboardpanel.placeMark(getYourMark(),
move.getPositionX(), move.getPositionY());
}
}
}, new PacketExtensionFilter(MovePacket.ELEMENT_NAME,
MovePacket.NAMESPACE));
}
public PlayerDisplay getPlayerDisplay() {
return _playerdisplay;
}
public GameBoardPanel getGameBoardPanel() {
return _gameboardpanel;
}
/**
* being called from GameBoardPanel, places the Mark on the Logical Board
* and sends the Move if it was one
*
* @param m
* @param x
* @param y
*/
public void onGameBoardPlaceMark(Mark m, int x, int y) {
_gameboard.placeMark(x, y);
_playerdisplay.setCurrentPlayer(_gameboard.getCurrentPlayer());
if (m == getMyMark()) {
MovePacket move = new MovePacket();
move.setGameID(_gameID);
move.setPositionX(x);
move.setPositionY(y);
Message message = new Message(_opponent);
message.addExtension(move);
_connection.sendPacket(message);
}
if (_gameboard.isGameFinished()) {
_gameboardpanel.colorizeWinners(_gameboard.getWinningPositions());
if (_gameboard.getWinner() == getMyMark().getValue()) {
remove(_playerdisplay);
add(new GameEndsUI(TTTRes.getString("ttt.win"), Color.GREEN), BorderLayout.SOUTH);
}
if (_gameboard.getWinner() == getYourMark().getValue()) {
remove(_playerdisplay);
add(new GameEndsUI(TTTRes.getString("ttt.lose"), Color.RED), BorderLayout.SOUTH);
}
if (_gameboard.getWinner() == -1) {
remove(_playerdisplay);
add(new GameEndsUI(TTTRes.getString("ttt.tie"), Color.BLACK), BorderLayout.SOUTH);
}
ShakeWindow sw = new ShakeWindow(_frame);
sw.startShake();
repaint();
revalidate();
}
}
public Mark getMyMark() {
return me;
}
public Mark getYourMark() {
if (me == Mark.X)
return Mark.O;
else
return Mark.X;
}
public boolean myTurn() {
return _playerdisplay.getCurrentPlayer() == getMyMark()
&& !_gameboard.isGameFinished();
}
public boolean isFree(int x, int y) {
return _gameboard.getMarkAtPos(x, y) == Mark.BLANK;
}
}

View File

@ -0,0 +1,97 @@
/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tic.tac.toe.ui;
import java.awt.FlowLayout;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.jivesoftware.smack.util.StringUtils;
import tic.tac.toe.Mark;
import tic.tac.toe.TTTRes;
/**
* A display for showing, which Mark is yours, your oppononents and whos turn it
* is<br>
*
* <pre>
* you: X | max.max: O | current: O
* </pre>
*
* @author wolf.posdorfer
* @version 16.06.2011
*
*/
public class PlayerDisplay extends JPanel {
private static final long serialVersionUID = -8025502708415186558L;
private JLabel _currentplayer;
private Mark _currentMark;
public PlayerDisplay(Mark myself, String opponent) {
_currentplayer = new JLabel(" | "+TTTRes.getString("ttt.display.current"));
_currentplayer.setHorizontalTextPosition(JLabel.LEFT);
setCurrentPlayer(Mark.X);
setLayout(new FlowLayout(FlowLayout.CENTER));
JLabel mylabel = new JLabel(TTTRes.getString("ttt.display.me"));
mylabel.setIcon(new ImageIcon(myself.getImage().getImage()
.getScaledInstance(16, 16, Image.SCALE_SMOOTH)));
mylabel.setHorizontalTextPosition(JLabel.LEFT);
Mark you;
if (myself == Mark.X)
you = Mark.O;
else
you = Mark.X;
String name = StringUtils.parseName(opponent);
JLabel yourlabel = new JLabel(" | "+name);
yourlabel.setIcon(new ImageIcon(you.getImage().getImage()
.getScaledInstance(16, 16, Image.SCALE_SMOOTH)));
yourlabel.setHorizontalTextPosition(JLabel.LEFT);
add(mylabel);
add(yourlabel);
add(_currentplayer);
}
public void setCurrentPlayer(Mark m) {
_currentMark = m;
ImageIcon img = new ImageIcon(m.getImage().getImage()
.getScaledInstance(16, 16, Image.SCALE_SMOOTH));
_currentplayer.setIcon(img);
_currentplayer.repaint();
_currentplayer.revalidate();
}
public Mark getCurrentPlayer() {
return _currentMark;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

View File

@ -0,0 +1,16 @@
###########################
# Tic Tac Toe #
# by wolf.posdorfer #
###########################
ttt.game.request = {0} is requesting a game of
ttt.game.name = Tic Tac Toe of Doom
ttt.window.title = {0} versus {1}
ttt.win = Congratulations, you won!
ttt.lose = Sorry, you lost!
ttt.tie = The game ended in a draw.
ttt.display.me = I am:
ttt.display.current = currently playing:
ttt.request.decline = The game request has been denied.
ttt.request.accept = The game is starting.
ttt.request.sent = Sending game request...

View File

@ -0,0 +1,16 @@
###########################
# Tic Tac Toe #
# by wolf.posdorfer #
###########################
ttt.game.request = {0} fordert eine Partie
ttt.game.name = Tic Tac Toe des Verderbens
ttt.window.title ={0} gegen {1}
ttt.win = Gl<EFBFBD>ckwunsch, Du hast gewonnen!
ttt.lose = Leider verloren.
ttt.tie = Unentschieden.
ttt.display.me = Ich bin:
ttt.display.current = Zurzeit spielt:
ttt.request.decline = Die Spielanfrage wurde abgelehnt.
ttt.request.accept = Das Spiel beginnt.
ttt.request.sent = Sende Spielanfrage...

View File

@ -0,0 +1,16 @@
###########################
# Tic Tac Toe #
# by wolf.posdorfer #
###########################
ttt.game.request = {0} , prasydama TicTacToe zaidima
ttt.game.name = Tic Tac Toe pasmerkimo
ttt.window.title = {0} palyginti su {1}
ttt.win = Sveikinu, tu laimejai!
ttt.lose = Atsiprasome, jus praradote!
ttt.tie = Zaidimas baigesi lygiosiomis.
ttt.display.me = As esu:
ttt.display.current = siuo metu zaidzia:
ttt.request.decline = Zaidimas prasymas buvo atmestas.
ttt.request.accept = Zaidimas prasideda.
ttt.request.sent = Siuntimas zaidimas prasyma ...

View File

@ -0,0 +1,16 @@
###########################
# Tic Tac Toe #
# by wolf.posdorfer #
###########################
ttt.game.request = {0} is het aanvragen van een spel van
ttt.game.name = Tic Tac Toe van ondergang
ttt.window.title = {0} versus {1}
ttt.win = Gefeliciteerd, je hebt gewonnen!
ttt.lose = Sorry, je verloren!
ttt.tie = De wedstrijd eindigde in een gelijkspel.
ttt.display.me = Ik ben:
ttt.display.current = op dit moment spelen:
ttt.request.decline = Het spel verzoek is afgewezen.
ttt.request.accept = Het spel begint.
ttt.request.sent = Verzenden spel verzoek ...

View File

@ -0,0 +1,16 @@
###########################
# Tic Tac Toe #
# by wolf.posdorfer #
###########################
ttt.game.request = {0} está solicitando um jogo de
ttt.game.name = Tic Tac Toe e condenacao
ttt.window.title = {0} versus {1}
ttt.win = Parabéns, você ganhou!
ttt.lose = Desculpe, você perdeu!
ttt.tie = O jogo terminou em um empate.
ttt.display.me = I am:
ttt.display.current = a jogar agora:
ttt.request.decline = O pedido foi negado jogo.
ttt.request.accept = O jogo está comecando.
ttt.request.sent = Enviando pedido jogo ...

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB