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
@ -251,6 +251,11 @@ public class ReversiPlugin implements Plugin {
|
|||||||
ImageIcon icon = ReversiRes.getImageIcon(ReversiRes.REVERSI_ICON);
|
ImageIcon icon = ReversiRes.getImageIcon(ReversiRes.REVERSI_ICON);
|
||||||
|
|
||||||
public void chatRoomOpened(final ChatRoom room) {
|
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);
|
ChatRoomButton button = new ChatRoomButton(icon);
|
||||||
button.setToolTipText("Reversi");
|
button.setToolTipText("Reversi");
|
||||||
room.getToolBar().addChatRoomButton(button);
|
room.getToolBar().addChatRoomButton(button);
|
||||||
|
|||||||
98
src/plugins/tictactoe/build/build.xml
Normal 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>
|
||||||
12
src/plugins/tictactoe/plugin.xml
Normal 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>
|
||||||
207
src/plugins/tictactoe/src/java/tic/tac/toe/GameBoard.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/plugins/tictactoe/src/java/tic/tac/toe/Mark.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/plugins/tictactoe/src/java/tic/tac/toe/Pair.java
Normal 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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
63
src/plugins/tictactoe/src/java/tic/tac/toe/TTTRes.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
278
src/plugins/tictactoe/src/java/tic/tac/toe/TicTacToePlugin.java
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
192
src/plugins/tictactoe/src/java/tic/tac/toe/ui/GamePanel.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/plugins/tictactoe/src/resources/board.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/plugins/tictactoe/src/resources/empty.png
Normal file
|
After Width: | Height: | Size: 613 B |
@ -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...
|
||||||
@ -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...
|
||||||
@ -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 ...
|
||||||
@ -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 ...
|
||||||
@ -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 ...
|
||||||
BIN
src/plugins/tictactoe/src/resources/o.blue.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/plugins/tictactoe/src/resources/o.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/plugins/tictactoe/src/resources/ttt.button.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/plugins/tictactoe/src/resources/x.blue.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/plugins/tictactoe/src/resources/x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |