[tictactoe] Code cleanup, new config dialog
This commit is contained in:
55
tictactoe/config_dialog.py
Normal file
55
tictactoe/config_dialog.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#
|
||||||
|
# This file is part of the TicTacToe plugin for Gajim.
|
||||||
|
#
|
||||||
|
# Gajim is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Gajim is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from gi.repository import GObject
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
from gajim.gtk.settings import SettingsDialog
|
||||||
|
from gajim.gtk.settings import SpinSetting
|
||||||
|
from gajim.gtk.const import Setting
|
||||||
|
from gajim.gtk.const import SettingType
|
||||||
|
|
||||||
|
from gajim.plugins.plugins_i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
class TicTacToeConfigDialog(SettingsDialog):
|
||||||
|
def __init__(self, plugin, parent):
|
||||||
|
|
||||||
|
self.plugin = plugin
|
||||||
|
settings = [
|
||||||
|
Setting('BoardSizeSpinSetting', _('Board Size'),
|
||||||
|
SettingType.VALUE, self.plugin.config['board_size'],
|
||||||
|
callback=self.on_setting, data='board_size',
|
||||||
|
desc=_('Size of the board'),
|
||||||
|
props={'range_': (3, 10)})]
|
||||||
|
|
||||||
|
SettingsDialog.__init__(self, parent, _('TicTacToe Configuration'),
|
||||||
|
Gtk.DialogFlags.MODAL, settings, None,
|
||||||
|
extend=[
|
||||||
|
('BoardSizeSpinSetting', SizeSpinSetting)])
|
||||||
|
|
||||||
|
def on_setting(self, value, data):
|
||||||
|
self.plugin.config[data] = value
|
||||||
|
|
||||||
|
|
||||||
|
class SizeSpinSetting(SpinSetting):
|
||||||
|
|
||||||
|
__gproperties__ = {
|
||||||
|
"setting-value": (int, 'Size', '', 3, 10, 3,
|
||||||
|
GObject.ParamFlags.READWRITE), }
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
SpinSetting.__init__(self, *args, **kwargs)
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Generated with glade 3.20.0 -->
|
|
||||||
<interface>
|
|
||||||
<requires lib="gtk+" version="3.20"/>
|
|
||||||
<object class="GtkWindow" id="window1">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="vbox1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="hbox2">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="board_size_label">
|
|
||||||
<property name="width_request">133</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Board size</property>
|
|
||||||
<property name="ellipsize">start</property>
|
|
||||||
<property name="single_line_mode">True</property>
|
|
||||||
<property name="track_visited_links">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSpinButton" id="board_size">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="has_tooltip">True</property>
|
|
||||||
<property name="tooltip_text" translatable="yes">Preview size(10-512)</property>
|
|
||||||
<property name="invisible_char">●</property>
|
|
||||||
<property name="width_chars">6</property>
|
|
||||||
<property name="snap_to_ticks">True</property>
|
|
||||||
<property name="numeric">True</property>
|
|
||||||
<signal name="value-changed" handler="board_size_value_changed" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
|
||||||
@@ -1,21 +1,20 @@
|
|||||||
## plugins/tictactoe/plugin.py
|
#
|
||||||
##
|
# Copyright (C) 2011 Yann Leboulanger <asterix AT lagaule.org>
|
||||||
## Copyright (C) 2011 Yann Leboulanger <asterix AT lagaule.org>
|
#
|
||||||
##
|
# This file is part of the TicTacToe plugin for Gajim.
|
||||||
## This file is part of Gajim.
|
#
|
||||||
##
|
# Gajim is free software; you can redistribute it and/or modify
|
||||||
## Gajim is free software; you can redistribute it and/or modify
|
# it under the terms of the GNU General Public License as published
|
||||||
## it under the terms of the GNU General Public License as published
|
# by the Free Software Foundation; version 3 only.
|
||||||
## by the Free Software Foundation; version 3 only.
|
#
|
||||||
##
|
# Gajim is distributed in the hope that it will be useful,
|
||||||
## Gajim is distributed in the hope that it will be useful,
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# GNU General Public License for more details.
|
||||||
## GNU General Public License for more details.
|
#
|
||||||
##
|
# You should have received a copy of the GNU General Public License
|
||||||
## You should have received a copy of the GNU General Public License
|
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
#
|
||||||
##
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Tictactoe plugin.
|
Tictactoe plugin.
|
||||||
@@ -30,36 +29,53 @@ import string
|
|||||||
import itertools
|
import itertools
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import nbxmpp
|
from functools import partial
|
||||||
|
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
from gi.repository import Gio
|
from gi.repository import Gio
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
import gi
|
|
||||||
gi.require_version('PangoCairo', '1.0')
|
|
||||||
from gi.repository import PangoCairo
|
|
||||||
|
|
||||||
from gajim.common import helpers
|
import nbxmpp
|
||||||
from gajim.common import app
|
|
||||||
from gajim.plugins import GajimPlugin
|
|
||||||
from gajim.plugins.helpers import log_calls, log
|
|
||||||
from gajim.plugins.gui import GajimPluginConfigDialog
|
|
||||||
from gajim import chat_control
|
from gajim import chat_control
|
||||||
|
|
||||||
|
from gajim.common import app
|
||||||
from gajim.common import ged
|
from gajim.common import ged
|
||||||
|
from gajim.common import helpers
|
||||||
from gajim.common.connection_handlers_events import InformationEvent
|
from gajim.common.connection_handlers_events import InformationEvent
|
||||||
from gajim.plugins.plugins_i18n import _
|
|
||||||
|
|
||||||
from gajim.gtk.dialogs import DialogButton
|
from gajim.gtk.dialogs import DialogButton
|
||||||
from gajim.gtk.dialogs import NewConfirmationDialog
|
from gajim.gtk.dialogs import NewConfirmationDialog
|
||||||
|
|
||||||
|
from gajim.plugins import GajimPlugin
|
||||||
|
from gajim.plugins.helpers import log
|
||||||
|
from gajim.plugins.helpers import log_calls
|
||||||
|
from gajim.plugins.plugins_i18n import _
|
||||||
|
|
||||||
|
from tictactoe.config_dialog import TicTacToeConfigDialog
|
||||||
|
|
||||||
|
try:
|
||||||
|
import gi
|
||||||
|
gi.require_version('PangoCairo', '1.0')
|
||||||
|
from gi.repository import PangoCairo
|
||||||
|
HAS_PANGOCAIRO = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_PANGOCAIRO = False
|
||||||
|
|
||||||
NS_GAMES = 'http://jabber.org/protocol/games'
|
NS_GAMES = 'http://jabber.org/protocol/games'
|
||||||
NS_GAMES_TICTACTOE = NS_GAMES + '/tictactoe'
|
NS_GAMES_TICTACTOE = NS_GAMES + '/tictactoe'
|
||||||
|
|
||||||
|
|
||||||
class TictactoePlugin(GajimPlugin):
|
class TictactoePlugin(GajimPlugin):
|
||||||
@log_calls('TictactoePlugin')
|
@log_calls('TictactoePlugin')
|
||||||
def init(self):
|
def init(self):
|
||||||
|
if not HAS_PANGOCAIRO:
|
||||||
|
self.activatable = False
|
||||||
|
self.config_dialog = None
|
||||||
|
self.available_text = _('TicTacToe requires PangoCairo to run')
|
||||||
self.description = _('Play Tictactoe.')
|
self.description = _('Play Tictactoe.')
|
||||||
self.config_dialog = TictactoePluginConfigDialog(self)
|
self.config_dialog = partial(TicTacToeConfigDialog, self)
|
||||||
self.events_handlers = {
|
self.events_handlers = {
|
||||||
'decrypted-message-received': (
|
'decrypted-message-received': (
|
||||||
ged.PREGUI, self._nec_decrypted_message_received),
|
ged.PREGUI, self._nec_decrypted_message_received),
|
||||||
@@ -109,8 +125,8 @@ class TictactoePlugin(GajimPlugin):
|
|||||||
# Already existing session?
|
# Already existing session?
|
||||||
conn = app.connections[control.account]
|
conn = app.connections[control.account]
|
||||||
sessions = conn.get_sessions(control.contact.jid)
|
sessions = conn.get_sessions(control.contact.jid)
|
||||||
tictactoes = [s for s in sessions if isinstance(s,
|
tictactoes = [s for s in sessions if isinstance(
|
||||||
TicTacToeSession)]
|
s, TicTacToeSession)]
|
||||||
if tictactoes:
|
if tictactoes:
|
||||||
base.tictactoe = tictactoes[0]
|
base.tictactoe = tictactoes[0]
|
||||||
base.enable_action(True)
|
base.enable_action(True)
|
||||||
@@ -125,8 +141,8 @@ class TictactoePlugin(GajimPlugin):
|
|||||||
def update_button_state(self, control):
|
def update_button_state(self, control):
|
||||||
for base in self.controls:
|
for base in self.controls:
|
||||||
if base.chat_control == control:
|
if base.chat_control == control:
|
||||||
if control.contact.supports(NS_GAMES) and \
|
if (control.contact.supports(NS_GAMES) and
|
||||||
control.contact.supports(NS_GAMES_TICTACTOE):
|
control.contact.supports(NS_GAMES_TICTACTOE)):
|
||||||
base.enable_action(True)
|
base.enable_action(True)
|
||||||
else:
|
else:
|
||||||
base.enable_action(False)
|
base.enable_action(False)
|
||||||
@@ -166,13 +182,13 @@ class TictactoePlugin(GajimPlugin):
|
|||||||
obj.session.received(obj.stanza)
|
obj.session.received(obj.stanza)
|
||||||
game_invite = obj.stanza.getTag('invite', namespace=NS_GAMES)
|
game_invite = obj.stanza.getTag('invite', namespace=NS_GAMES)
|
||||||
if game_invite:
|
if game_invite:
|
||||||
account = obj.conn.name
|
|
||||||
game = game_invite.getTag('game')
|
game = game_invite.getTag('game')
|
||||||
if game and game.getAttr('var') == NS_GAMES_TICTACTOE:
|
if game and game.getAttr('var') == NS_GAMES_TICTACTOE:
|
||||||
session = obj.conn.make_new_session(obj.fjid, obj.thread_id,
|
session = obj.conn.make_new_session(obj.fjid, obj.thread_id,
|
||||||
cls=TicTacToeSession)
|
cls=TicTacToeSession)
|
||||||
self.show_request_dialog(obj, session)
|
self.show_request_dialog(obj, session)
|
||||||
|
|
||||||
|
|
||||||
class Base(object):
|
class Base(object):
|
||||||
def __init__(self, plugin, chat_control):
|
def __init__(self, plugin, chat_control):
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
@@ -230,9 +246,11 @@ class Base(object):
|
|||||||
menu.remove(i)
|
menu.remove(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class InvalidMove(Exception):
|
class InvalidMove(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TicTacToeSession(object):
|
class TicTacToeSession(object):
|
||||||
def __init__(self, conn, jid, thread_id, type_):
|
def __init__(self, conn, jid, thread_id, type_):
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
@@ -266,7 +284,10 @@ class TicTacToeSession(object):
|
|||||||
|
|
||||||
def get_to(self):
|
def get_to(self):
|
||||||
to = str(self.jid)
|
to = str(self.jid)
|
||||||
return app.get_jid_without_resource(to) + '/' + self.resource
|
jid = app.get_jid_without_resource(to)
|
||||||
|
if self.resource:
|
||||||
|
jid += '/' + self.resource
|
||||||
|
return jid
|
||||||
|
|
||||||
def generate_thread_id(self):
|
def generate_thread_id(self):
|
||||||
return ''.join(
|
return ''.join(
|
||||||
@@ -274,7 +295,7 @@ class TicTacToeSession(object):
|
|||||||
random.choice, 32)]
|
random.choice, 32)]
|
||||||
)
|
)
|
||||||
|
|
||||||
# initiate a session
|
# Initiate a session
|
||||||
def begin(self, role_s='x'):
|
def begin(self, role_s='x'):
|
||||||
self.rows = self.base.plugin.config['board_size']
|
self.rows = self.base.plugin.config['board_size']
|
||||||
self.cols = self.base.plugin.config['board_size']
|
self.cols = self.base.plugin.config['board_size']
|
||||||
@@ -343,23 +364,23 @@ class TicTacToeSession(object):
|
|||||||
else:
|
else:
|
||||||
self.cols = 3
|
self.cols = 3
|
||||||
|
|
||||||
# number in a row needed to win
|
# Number in a row needed to win
|
||||||
if form.getField('strike'):
|
if form.getField('strike'):
|
||||||
self.strike = int(form.getField('strike').getValues()[0])
|
self.strike = int(form.getField('strike').getValues()[0])
|
||||||
else:
|
else:
|
||||||
self.strike = 3
|
self.strike = 3
|
||||||
|
|
||||||
# received an invitation
|
# Received an invitation
|
||||||
def invited(self, msg):
|
def invited(self, msg):
|
||||||
self.read_invitation(msg)
|
self.read_invitation(msg)
|
||||||
|
|
||||||
# the number of the move about to be made
|
# The number of the move about to be made
|
||||||
self.next_move_id = 1
|
self.next_move_id = 1
|
||||||
|
|
||||||
# display the board
|
# Display the board
|
||||||
self.board = TicTacToeBoard(self, self.rows, self.cols)
|
self.board = TicTacToeBoard(self, self.rows, self.cols)
|
||||||
|
|
||||||
# accept the invitation, join the game
|
# Accept the invitation, join the game
|
||||||
response = nbxmpp.Message()
|
response = nbxmpp.Message()
|
||||||
|
|
||||||
join = response.NT.join
|
join = response.NT.join
|
||||||
@@ -377,7 +398,7 @@ class TicTacToeSession(object):
|
|||||||
|
|
||||||
self.our_turn()
|
self.our_turn()
|
||||||
|
|
||||||
# just sent an invitation, expecting a reply
|
# Just sent an invitation, expecting a reply
|
||||||
def wait_for_invite_response(self, msg):
|
def wait_for_invite_response(self, msg):
|
||||||
if msg.getTag('join', namespace=NS_GAMES):
|
if msg.getTag('join', namespace=NS_GAMES):
|
||||||
self.board = TicTacToeBoard(self, self.rows, self.cols)
|
self.board = TicTacToeBoard(self, self.rows, self.cols)
|
||||||
@@ -388,13 +409,15 @@ class TicTacToeSession(object):
|
|||||||
self.their_turn()
|
self.their_turn()
|
||||||
|
|
||||||
elif msg.getTag('decline', namespace=NS_GAMES):
|
elif msg.getTag('decline', namespace=NS_GAMES):
|
||||||
app.nec.push_incoming_event(InformationEvent(None, conn=self.conn,
|
app.nec.push_incoming_event(
|
||||||
level='info', pri_txt=_('Invitation refused'),
|
InformationEvent(
|
||||||
sec_txt=_('%(name)s refused your invitation to play tic tac '
|
None,
|
||||||
'toe.') % {'name': self.name}))
|
conn=self.conn,
|
||||||
|
level='info',
|
||||||
|
pri_txt=_('Invitation refused'),
|
||||||
|
sec_txt=_('%(name)s refused your invitation to play tic '
|
||||||
|
'tac toe.') % {'name': self.name}))
|
||||||
self.conn.delete_session(str(self.jid), self.thread_id)
|
self.conn.delete_session(str(self.jid), self.thread_id)
|
||||||
if self.base:
|
|
||||||
self.base.button.set_active(False)
|
|
||||||
|
|
||||||
def decline_invitation(self):
|
def decline_invitation(self):
|
||||||
msg = nbxmpp.Message()
|
msg = nbxmpp.Message()
|
||||||
@@ -413,14 +436,14 @@ class TicTacToeSession(object):
|
|||||||
self.received = self.game_over
|
self.received = self.game_over
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# silently ignores any received messages
|
# Silently ignores any received messages
|
||||||
def ignore(self, msg):
|
def ignore(self, msg):
|
||||||
self.treat_terminate(msg)
|
self.treat_terminate(msg)
|
||||||
|
|
||||||
def game_over(self, msg):
|
def game_over(self, msg):
|
||||||
invite = msg.getTag('invite', namespace=NS_GAMES)
|
invite = msg.getTag('invite', namespace=NS_GAMES)
|
||||||
|
|
||||||
# ignore messages unless they're renewing the game
|
# Ignore messages unless they're renewing the game
|
||||||
if invite and invite.getAttr('type') == 'renew':
|
if invite and invite.getAttr('type') == 'renew':
|
||||||
self.invited(msg)
|
self.invited(msg)
|
||||||
|
|
||||||
@@ -440,14 +463,14 @@ class TicTacToeSession(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.board.mark(row, col, self.role_o)
|
self.board.mark(row, col, self.role_o)
|
||||||
except InvalidMove as e:
|
except InvalidMove:
|
||||||
# received an invalid move, end the game.
|
# Received an invalid move, end the game.
|
||||||
self.board.cheated()
|
self.board.cheated()
|
||||||
self.end_game('cheating')
|
self.end_game('cheating')
|
||||||
self.received = self.game_over
|
self.received = self.game_over
|
||||||
return
|
return
|
||||||
|
|
||||||
# check win conditions
|
# Check win conditions
|
||||||
if self.board.check_for_strike(self.role_o, row, col, self.strike):
|
if self.board.check_for_strike(self.role_o, row, col, self.strike):
|
||||||
self.lost()
|
self.lost()
|
||||||
elif self.board.full():
|
elif self.board.full():
|
||||||
@@ -461,7 +484,7 @@ class TicTacToeSession(object):
|
|||||||
return self.received == self.ignore
|
return self.received == self.ignore
|
||||||
|
|
||||||
def our_turn(self):
|
def our_turn(self):
|
||||||
# ignore messages until we've made our move
|
# Ignore messages until we've made our move
|
||||||
self.received = self.ignore
|
self.received = self.ignore
|
||||||
self.board.set_title('your turn')
|
self.board.set_title('your turn')
|
||||||
|
|
||||||
@@ -473,13 +496,13 @@ class TicTacToeSession(object):
|
|||||||
def move(self, row, col):
|
def move(self, row, col):
|
||||||
try:
|
try:
|
||||||
self.board.mark(row, col, self.role_s)
|
self.board.mark(row, col, self.role_s)
|
||||||
except InvalidMove as e:
|
except InvalidMove:
|
||||||
log.warn('you made an invalid move')
|
log.warn('You made an invalid move')
|
||||||
return
|
return
|
||||||
|
|
||||||
self.send_move(row, col)
|
self.send_move(row, col)
|
||||||
|
|
||||||
# check win conditions
|
# Check win conditions
|
||||||
if self.board.check_for_strike(self.role_s, row, col, self.strike):
|
if self.board.check_for_strike(self.role_s, row, col, self.strike):
|
||||||
self.won()
|
self.won()
|
||||||
elif self.board.full():
|
elif self.board.full():
|
||||||
@@ -489,7 +512,7 @@ class TicTacToeSession(object):
|
|||||||
|
|
||||||
self.their_turn()
|
self.their_turn()
|
||||||
|
|
||||||
# sends a move message
|
# Sends a move message
|
||||||
def send_move(self, row, column):
|
def send_move(self, row, column):
|
||||||
msg = nbxmpp.Message()
|
msg = nbxmpp.Message()
|
||||||
msg.setType('chat')
|
msg.setType('chat')
|
||||||
@@ -506,7 +529,7 @@ class TicTacToeSession(object):
|
|||||||
|
|
||||||
self.send(msg)
|
self.send(msg)
|
||||||
|
|
||||||
# sends a termination message and ends the game
|
# Sends a termination message and ends the game
|
||||||
def end_game(self, reason):
|
def end_game(self, reason):
|
||||||
msg = nbxmpp.Message()
|
msg = nbxmpp.Message()
|
||||||
|
|
||||||
@@ -547,22 +570,22 @@ class TicTacToeBoard:
|
|||||||
self.rows = rows
|
self.rows = rows
|
||||||
self.cols = cols
|
self.cols = cols
|
||||||
|
|
||||||
self.board = [ [None] * self.cols for r in range(self.rows) ]
|
self.board = [[None] * self.cols for r in range(self.rows)]
|
||||||
|
|
||||||
self.setup_window()
|
self.setup_window()
|
||||||
|
|
||||||
# check if the last move (at row r and column c) won the game
|
# Check if the last move (at row r and column c) won the game
|
||||||
def check_for_strike(self, p, r, c, strike):
|
def check_for_strike(self, p, r, c, strike):
|
||||||
# number in a row: up and down, left and right
|
# Number in a row: up and down, left and right
|
||||||
tallyI = 0
|
tallyI = 0
|
||||||
tally_ = 0
|
tally_ = 0
|
||||||
|
|
||||||
# number in a row: diagonal
|
# Number in a row: diagonal
|
||||||
# (imagine L or F as two sides of a right triangle: L\ or F/)
|
# (imagine L or F as two sides of a right triangle: L\ or F/)
|
||||||
tallyL = 0
|
tallyL = 0
|
||||||
tallyF = 0
|
tallyF = 0
|
||||||
|
|
||||||
# convert real columns to internal columns
|
# Convert real columns to internal columns
|
||||||
r -= 1
|
r -= 1
|
||||||
c -= 1
|
c -= 1
|
||||||
|
|
||||||
@@ -570,19 +593,19 @@ class TicTacToeBoard:
|
|||||||
r_in_range = 0 <= r+d < self.rows
|
r_in_range = 0 <= r+d < self.rows
|
||||||
c_in_range = 0 <= c+d < self.cols
|
c_in_range = 0 <= c+d < self.cols
|
||||||
|
|
||||||
# vertical check
|
# Vertical check
|
||||||
if r_in_range:
|
if r_in_range:
|
||||||
tallyI = tallyI + 1
|
tallyI = tallyI + 1
|
||||||
if self.board[r+d][c] != p:
|
if self.board[r+d][c] != p:
|
||||||
tallyI = 0
|
tallyI = 0
|
||||||
|
|
||||||
# horizontal check
|
# Horizontal check
|
||||||
if c_in_range:
|
if c_in_range:
|
||||||
tally_ = tally_ + 1
|
tally_ = tally_ + 1
|
||||||
if self.board[r][c+d] != p:
|
if self.board[r][c+d] != p:
|
||||||
tally_ = 0
|
tally_ = 0
|
||||||
|
|
||||||
# diagonal checks
|
# Diagonal checks
|
||||||
if r_in_range and c_in_range:
|
if r_in_range and c_in_range:
|
||||||
tallyL = tallyL + 1
|
tallyL = tallyL + 1
|
||||||
if self.board[r+d][c+d] != p:
|
if self.board[r+d][c+d] != p:
|
||||||
@@ -598,11 +621,11 @@ class TicTacToeBoard:
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# is the board full?
|
# Is the board full?
|
||||||
def full(self):
|
def full(self):
|
||||||
for r in range(self.rows):
|
for r in range(self.rows):
|
||||||
for c in range(self.cols):
|
for c in range(self.cols):
|
||||||
if self.board[r][c] == None:
|
if self.board[r][c] is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -628,16 +651,16 @@ class TicTacToeBoard:
|
|||||||
|
|
||||||
(width, height) = widget.get_size()
|
(width, height) = widget.get_size()
|
||||||
|
|
||||||
# convert click co-ordinates to row and column
|
# Convert click co-ordinates to row and column
|
||||||
row_height = height // self.rows
|
row_height = height // self.rows
|
||||||
col_width = width // self.cols
|
col_width = width // self.cols
|
||||||
|
|
||||||
row = int(event.y // row_height) + 1
|
row = int(event.y // row_height) + 1
|
||||||
column = int(event.x // col_width) + 1
|
column = int(event.x // col_width) + 1
|
||||||
|
|
||||||
self.session.move(row, column)
|
self.session.move(row, column)
|
||||||
|
|
||||||
# this actually draws the board
|
# This actually draws the board
|
||||||
def do_draw(self, widget, cr):
|
def do_draw(self, widget, cr):
|
||||||
cr.set_source_rgb(1.0, 1.0, 1.0)
|
cr.set_source_rgb(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
@@ -647,7 +670,7 @@ class TicTacToeBoard:
|
|||||||
(width, height) = self.win.get_size()
|
(width, height) = self.win.get_size()
|
||||||
|
|
||||||
row_height = (height - text_height) // self.rows
|
row_height = (height - text_height) // self.rows
|
||||||
col_width = width // self.cols
|
col_width = width // self.cols
|
||||||
|
|
||||||
cr.set_source_rgb(0, 0, 0)
|
cr.set_source_rgb(0, 0, 0)
|
||||||
cr.set_line_width(2)
|
cr.set_line_width(2)
|
||||||
@@ -669,11 +692,11 @@ class TicTacToeBoard:
|
|||||||
txt = _('You won !')
|
txt = _('You won !')
|
||||||
elif self.state == 'lost':
|
elif self.state == 'lost':
|
||||||
txt = _('You lost !')
|
txt = _('You lost !')
|
||||||
elif self.state == 'resign': # other part resigned
|
elif self.state == 'resign': # Other part resigned
|
||||||
txt = _('%(name)s capitulated') % {'name': self.session.name}
|
txt = _('%(name)s capitulated') % {'name': self.session.name}
|
||||||
elif self.state == 'cheated': # other part cheated
|
elif self.state == 'cheated': # Other part cheated
|
||||||
txt = _('%(name)s cheated') % {'name': self.session.name}
|
txt = _('%(name)s cheated') % {'name': self.session.name}
|
||||||
else: #draw
|
else: # Draw
|
||||||
txt = _('It\'s a draw')
|
txt = _('It\'s a draw')
|
||||||
layout.set_text(txt, -1)
|
layout.set_text(txt, -1)
|
||||||
# Inform Pango to re-layout the text with the new transformation
|
# Inform Pango to re-layout the text with the new transformation
|
||||||
@@ -689,9 +712,9 @@ class TicTacToeBoard:
|
|||||||
|
|
||||||
def draw_x(self, cr, row, col, row_height, col_width):
|
def draw_x(self, cr, row, col, row_height, col_width):
|
||||||
if self.session.role_s == 'x':
|
if self.session.role_s == 'x':
|
||||||
color = '#3d79fb' # out
|
color = '#3d79fb' # Out
|
||||||
else:
|
else:
|
||||||
color = '#f03838' # red
|
color = '#f03838' # Red
|
||||||
rgba = Gdk.RGBA()
|
rgba = Gdk.RGBA()
|
||||||
rgba.parse(color)
|
rgba.parse(color)
|
||||||
cr.set_source_rgba(rgba.red, rgba.green, rgba.blue, rgba.alpha)
|
cr.set_source_rgba(rgba.red, rgba.green, rgba.blue, rgba.alpha)
|
||||||
@@ -724,12 +747,12 @@ class TicTacToeBoard:
|
|||||||
x = col_width * (col + 0.5)
|
x = col_width * (col + 0.5)
|
||||||
y = row_height * (row + 0.5)
|
y = row_height * (row + 0.5)
|
||||||
|
|
||||||
cr.arc(x, y, row_height/4, 0, 2.0*3.2) # slightly further than 2*pi
|
cr.arc(x, y, row_height/4, 0, 2.0*3.2) # Slightly further than 2*pi
|
||||||
|
|
||||||
cr.set_line_width(row_height / 5)
|
cr.set_line_width(row_height / 5)
|
||||||
cr.stroke()
|
cr.stroke()
|
||||||
|
|
||||||
# mark a move on the board
|
# Mark a move on the board
|
||||||
def mark(self, row, column, player):
|
def mark(self, row, column, player):
|
||||||
if self.board[row-1][column-1]:
|
if self.board[row-1][column-1]:
|
||||||
raise InvalidMove
|
raise InvalidMove
|
||||||
@@ -738,7 +761,7 @@ class TicTacToeBoard:
|
|||||||
|
|
||||||
self.win.queue_draw()
|
self.win.queue_draw()
|
||||||
|
|
||||||
def set_title(self, suffix = None):
|
def set_title(self, suffix=None):
|
||||||
str_ = self.title_prefix
|
str_ = self.title_prefix
|
||||||
|
|
||||||
if suffix:
|
if suffix:
|
||||||
@@ -764,24 +787,3 @@ class TicTacToeBoard:
|
|||||||
def cheated(self):
|
def cheated(self):
|
||||||
self.state == 'cheated'
|
self.state == 'cheated'
|
||||||
self.win.queue_draw()
|
self.win.queue_draw()
|
||||||
|
|
||||||
|
|
||||||
class TictactoePluginConfigDialog(GajimPluginConfigDialog):
|
|
||||||
def init(self):
|
|
||||||
self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
|
|
||||||
'config_dialog.ui')
|
|
||||||
self.xml = Gtk.Builder()
|
|
||||||
self.xml.set_translation_domain('gajim_plugins')
|
|
||||||
self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH, ['vbox1'])
|
|
||||||
self.board_size_spinbutton = self.xml.get_object('board_size')
|
|
||||||
self.board_size_spinbutton.get_adjustment().configure(3, 3, 10, 1, 1, 0)
|
|
||||||
vbox = self.xml.get_object('vbox1')
|
|
||||||
self.get_child().pack_start(vbox, True, True, 0)
|
|
||||||
|
|
||||||
self.xml.connect_signals(self)
|
|
||||||
|
|
||||||
def on_run(self):
|
|
||||||
self.board_size_spinbutton.set_value(self.plugin.config['board_size'])
|
|
||||||
|
|
||||||
def board_size_value_changed(self, spinbutton):
|
|
||||||
self.plugin.config['board_size'] = int(spinbutton.get_value())
|
|
||||||
|
|||||||
Reference in New Issue
Block a user