Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Schampijer <simon@schampijer.de>2007-07-05 13:20:43 (GMT)
committer Simon Schampijer <simon@schampijer.de>2007-07-05 13:20:43 (GMT)
commit6e426b4a243fdc2aa52f3abff8c3302ef7fb33f1 (patch)
tree706313dba6bd48c48e690512718c9288d7887d4c
parentb148f9923dd40e35c972c93ef1ac03e431a4b65c (diff)
- moved the gamestate into the model
- added the state of each tile to avoid flipping of already selected tiles - some smaller fixes
-rw-r--r--controller.py143
-rw-r--r--gamestate.py13
-rwxr-xr-xmemosonoactivity.py45
-rw-r--r--model.py73
4 files changed, 135 insertions, 139 deletions
diff --git a/controller.py b/controller.py
index dc446aa..ec588fc 100644
--- a/controller.py
+++ b/controller.py
@@ -9,7 +9,6 @@ from dbus.service import method, signal
from dbus.gobject_service import ExportedGObject
from model import Model
-from gamestate import GameState
# XXX: I'm not convinced this is in the right namespace
SERVICE = "org.freedesktop.Telepathy.Tube.Memosono"
@@ -19,8 +18,9 @@ PATH = "/org/freedesktop/Telepathy/Tube/Memosono"
GAME_PATH = os.path.join(os.path.dirname(__file__),'games/drumgit')
+MAX_NUM_PLAYERS = 2
-_logger = logging.getLogger('memosono-activity.game')
+_logger = logging.getLogger('controller')
class Controller(ExportedGObject):
@@ -40,56 +40,51 @@ class Controller(ExportedGObject):
self.owner = owner
self._get_buddy = get_buddy
self.activity = activity
-
- self.model = None
- self.playerid = None
+ self.numplayers = 0
self.turn = 0
- # index 0 is the master
- self.players = []
- self.started = 0
- self.count = 0
+
if self.is_initiator:
- self.gs = GameState()
+ self.init_game()
+
for tile in self.pv.tiles:
tile.connect('button-press-event', self._button_press_cb, self.pv.tiles.index(tile))
+
self.tube.watch_participants(self.participant_change_cb)
+
def participant_change_cb(self, added, removed):
- # Initiator is player 0, other player is player 1.
_logger.debug('adding participants: %r', added)
_logger.debug('removing participants: %r', removed)
for handle, bus_name in added:
buddy = self._get_buddy(handle)
- _logger.debug('Buddy %r was added', buddy)
if buddy is not None:
- if len(self.players) < 2:
+ _logger.debug('buddy %r was added', buddy)
+ if self.numplayers < MAX_NUM_PLAYERS:
self.buddies_panel.add_player(buddy)
- self.players.append(self.tube.participants[handle])
- if self.is_initiator:
- self.gs.points[self.tube.participants[handle]] = 0
- _logger.debug('MA: points of players: %s', self.gs.points)
- _logger.debug('MA: list of players: %s', self.players)
+ self.numplayers+=1
+ if self.is_initiator:
+ self.model.players[self.tube.participants[handle]] = [buddy.props.nick, 0]
+ _logger.debug('list of players: %s', self.model.players)
else:
- self.buddies_panel.add_watcher(buddy)
-
+ self.info_panel.show('we are already two players')
+
for handle in removed:
buddy = self._get_buddy(handle)
- _logger.debug('Buddy %r was removed', buddy)
if buddy is not None:
- self.buddies_panel.remove_watcher(buddy)
- try:
- self.players.remove(self.tube.participants[handle])
- except ValueError:
- # already absent
- pass
-
- if not self.entered:
- if self.is_initiator:
- _logger.debug('I am the initiator, so making myself the leader of the game.')
- self.init_game()
+ _logger.debug('buddy %r was removed', buddy)
+ self.buddies_panel.remove_player(buddy)
+ self.numplayers-=1
+ if self.is_initiator:
+ try:
+ del self.model.players[self.tube.participants[handle]]
+ except ValueError:
+ # already absent
+ pass
+
+ if not self.entered:
self.playerid = self.tube.get_unique_name()
self.tube.add_signal_receiver(self.info_cb, 'Info', IFACE,
path=PATH, sender_keyword='sender')
@@ -99,22 +94,24 @@ class Controller(ExportedGObject):
path=PATH, sender_keyword='sender')
self.tube.add_signal_receiver(self.points_cb, 'Points', IFACE,
path=PATH, sender_keyword='sender')
- self.entered = True
+ self.entered = True
+
if self.is_initiator:
- if len(self.players) == 2 and self.started == 0:
- _logger.debug('Start the game.')
- self.Info('Start the game')
- self.started = 1
- self.Turn(self.players[self.gs.player_active])
+ if len(self.model.players) == 2 and self.model.started == 0:
+ _logger.debug('start the game')
+ self.Info('start the game')
+ self.model.started = 1
+ self.change_turn()
- def init_game(self):
+ def init_game(self):
+ _logger.debug('I am the initiator, so making myself the leader of the game.')
self.model = Model(GAME_PATH, os.path.dirname(__file__))
self.model.read('drumgit.mson')
self.model.def_grid()
-
self.tube.add_signal_receiver(self.selected_cb, 'Selected', IFACE,
path=PATH, sender_keyword='sender')
+
@signal(dbus_interface=IFACE, signature='n')
def Selected(self, tilenum):
@@ -123,24 +120,34 @@ class Controller(ExportedGObject):
def selected_cb(self, tilenum, sender=None):
_logger.debug('MA: %s flipped tile %d', sender, tilenum)
obj, color = self.model.gettile(tilenum)
- self.Flip(tilenum, obj, color)
+ if self.model.grid[tilenum][2] == 1:
+ self.Info('selected already')
+ else:
+ self.Flip(tilenum, obj, color)
- self.count+=1
- if self.count == 1:
- self.gs.selected = tilenum
- if self.count == 2:
- self.count = 0
- # evaluate
- if( self.model.same(tilenum, self.gs.selected) == 1):
- _logger.debug('MA: Tile(%d) and (%d) are the same', tilenum, self.gs.selected)
- self.gs.points[sender]+=1
- self.Points(sender, self.gs.points[sender])
- self.info_panel.show('Open another one')
- else:
- gobject.timeout_add(2000, self._turn_back, tilenum, self.gs.selected)
- _logger.debug('Tile(%d) and (%d) are NOT the same', tilenum, self.gs.selected)
- # next player
- self.change_turn()
+ self.model.count+=1
+ if self.model.count == 1:
+ self.model.selected = tilenum
+ self.model.grid[tilenum][2] = 1
+ return
+ if self.model.count == 2:
+ self.model.count = 0
+ # evaluate
+ if( self.model.same(tilenum, self.model.selected) == 1):
+ _logger.debug('MA: Tile(%d) and (%d) are the same', tilenum, self.model.selected)
+ self.model.grid[tilenum][2] = 1
+ self.model.grid[self.model.selected][2] = 1
+
+ self.model.players[sender][1]+=1
+ self.Points(sender, self.model.players[sender][1])
+ self.Info('found pair, one more try')
+ else:
+ self.model.grid[tilenum][2] = 0
+ self.model.grid[self.model.selected][2] = 0
+ self.change_turn()
+ self.Info('pair does not match, next player')
+ gobject.timeout_add(2000, self._turn_back, tilenum, self.model.selected)
+ _logger.debug('Tile(%d) and (%d) are NOT the same', tilenum, self.model.selected)
def _turn_back(self, tilenuma, tilenumb):
self.Flip(tilenuma, 'images/black.png', 100)
@@ -148,12 +155,13 @@ class Controller(ExportedGObject):
return False
def change_turn(self):
- if self.gs.player_active == 0:
- self.gs.player_active = 1
+ if self.model.player_active < (len(self.model.players)-1):
+ self.model.player_active+=1
else:
- self.gs.player_active = 0
-
- self.Turn(self.players[self.gs.player_active])
+ self.model.player_active = 0
+
+ key = self.model.players.keys()[self.model.player_active]
+ self.Turn(key, self.model.players[key][0])
@signal(dbus_interface=IFACE, signature='nsn')
@@ -166,17 +174,16 @@ class Controller(ExportedGObject):
self.pv.flip(tilenum, os.path.join(os.path.dirname(__file__), obj), color)
- @signal(dbus_interface=IFACE, signature='s')
- def Turn(self, playerid):
+ @signal(dbus_interface=IFACE, signature='ss')
+ def Turn(self, playerid, name):
"""Signal that it is the players turn"""
- def turn_cb(self, playerid, sender=None):
+ def turn_cb(self, playerid, name, sender=None):
if self.playerid == playerid:
self.turn = 1
- self.info_panel.show('It is my turn')
else:
- self.turn = 0
-
+ self.turn = 0
+ self.info_panel.show('hey %s it is your turn'%name)
@signal(dbus_interface=IFACE, signature='sn')
def Points(self, player, points):
diff --git a/gamestate.py b/gamestate.py
deleted file mode 100644
index a3e40c9..0000000
--- a/gamestate.py
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-class GameState(object):
- ''' Used by the leader of the game to keep track of the game state
- '''
-
- def __init__(self):
- self.player_active = 0
- self.points = {}
- self.turn = 0
- self.selected = 0
-
-
diff --git a/memosonoactivity.py b/memosonoactivity.py
index 3bdc63f..47b60a8 100755
--- a/memosonoactivity.py
+++ b/memosonoactivity.py
@@ -39,12 +39,13 @@ from infopanel import InfoPanel
from controller import Controller
+_logger = logging.getLogger('activity')
class MemosonoActivity(Activity):
def __init__(self, handle):
Activity.__init__(self, handle)
- logging.debug('Starting Memosono activity...')
+ _logger.debug('Starting Memosono activity...')
self.set_title(_('Memsosono Activity'))
@@ -114,19 +115,19 @@ class MemosonoActivity(Activity):
def _get_buddy(self, cs_handle):
"""Get a Buddy from a channel specific handle."""
- logging.debug('Trying to find owner of handle %u...', cs_handle)
+ _logger.debug('Trying to find owner of handle %u...', cs_handle)
group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
my_csh = group.GetSelfHandle()
- logging.debug('My handle in that group is %u', my_csh)
+ _logger.debug('My handle in that group is %u', my_csh)
if my_csh == cs_handle:
handle = self.conn.GetSelfHandle()
- logging.debug('CS handle %u belongs to me, %u', cs_handle, handle)
+ _logger.debug('CS handle %u belongs to me, %u', cs_handle, handle)
elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES:
handle = group.GetHandleOwners([cs_handle])[0]
- logging.debug('CS handle %u belongs to %u', cs_handle, handle)
+ _logger.debug('CS handle %u belongs to %u', cs_handle, handle)
else:
handle = cs_handle
- logging.debug('non-CS handle %u belongs to itself', handle)
+ _logger.debug('non-CS handle %u belongs to itself', handle)
# XXX: deal with failure to get the handle owner
assert handle != 0
@@ -137,7 +138,7 @@ class MemosonoActivity(Activity):
self.tp_conn_path, handle)
def _shared_cb(self, activity):
- logging.debug('My Memosono activity was shared')
+ _logger.debug('My Memosono activity was shared')
self.initiating = True
self._setup()
@@ -147,17 +148,17 @@ class MemosonoActivity(Activity):
self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
self._shared_activity.connect('buddy-left', self._buddy_left_cb)
- logging.debug('This is my activity: making a tube...')
+ _logger.debug('This is my activity: making a tube...')
id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferTube(
telepathy.TUBE_TYPE_DBUS, 'org.fredektop.Telepathy.Tube.Memosono', {})
- logging.debug('Tube address: %s', self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id))
+ _logger.debug('Tube address: %s', self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id))
self.info_panel.show('Waiting for another player to join')
# FIXME: presence service should be tubes-aware and give us more help
# with this
def _setup(self):
if self._shared_activity is None:
- logging.error('Failed to share or join activity')
+ _logger.error('Failed to share or join activity')
return
bus_name, conn_path, channel_paths = self._shared_activity.get_channels()
@@ -170,27 +171,27 @@ class MemosonoActivity(Activity):
channel = telepathy.client.Channel(bus_name, channel_path)
htype, handle = channel.GetHandle()
if htype == telepathy.HANDLE_TYPE_ROOM:
- logging.debug('Found our room: it has handle#%d "%s"',
+ _logger.debug('Found our room: it has handle#%d "%s"',
handle, self.conn.InspectHandles(htype, [handle])[0])
room = handle
ctype = channel.GetChannelType()
if ctype == telepathy.CHANNEL_TYPE_TUBES:
- logging.debug('Found our Tubes channel at %s', channel_path)
+ _logger.debug('Found our Tubes channel at %s', channel_path)
tubes_chan = channel
elif ctype == telepathy.CHANNEL_TYPE_TEXT:
- logging.debug('Found our Text channel at %s', channel_path)
+ _logger.debug('Found our Text channel at %s', channel_path)
text_chan = channel
if room is None:
- logging.error("Presence service didn't create a room")
+ _logger.error("Presence service didn't create a room")
return
if text_chan is None:
- logging.error("Presence service didn't create a text channel")
+ _logger.error("Presence service didn't create a text channel")
return
# Make sure we have a Tubes channel - PS doesn't yet provide one
if tubes_chan is None:
- logging.debug("Didn't find our Tubes channel, requesting one...")
+ _logger.debug("Didn't find our Tubes channel, requesting one...")
tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES,
telepathy.HANDLE_TYPE_ROOM, room, True)
@@ -205,7 +206,7 @@ class MemosonoActivity(Activity):
self._new_tube_cb(*tube_info)
def _list_tubes_error_cb(self, e):
- logging.error('ListTubes() failed: %s', e)
+ _logger.error('ListTubes() failed: %s', e)
def _joined_cb(self, activity):
if self.ctrl is not None:
@@ -217,18 +218,18 @@ class MemosonoActivity(Activity):
for buddy in self._shared_activity.get_joined_buddies():
self.buddies_panel.add_watcher(buddy)
- logging.debug('Joined an existing Memosono game')
+ _logger.debug('Joined an existing Memosono game')
self.info_panel.show('Joined a game. Waiting for my turn...')
self.initiating = False
self._setup()
- logging.debug('This is not my activity: waiting for a tube...')
+ _logger.debug('This is not my activity: waiting for a tube...')
self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
reply_handler=self._list_tubes_reply_cb,
error_handler=self._list_tubes_error_cb)
def _new_tube_cb(self, id, initiator, type, service, params, state):
- logging.debug('New tube: ID=%d initator=%d type=%d service=%s '
+ _logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
'params=%r state=%d', id, initiator, type, service,
params, state)
@@ -245,11 +246,11 @@ class MemosonoActivity(Activity):
self._get_buddy, self)
def _buddy_joined_cb(self, activity, buddy):
- logging.debug('buddy joined')
+ _logger.debug('buddy joined')
self.buddies_panel.add_watcher(buddy)
def _buddy_left_cb(self, activity, buddy):
- logging.debug('buddy left')
+ _logger.debug('buddy left')
self.buddies_panel.remove_watcher(buddy)
diff --git a/model.py b/model.py
index 581be15..5ba6909 100644
--- a/model.py
+++ b/model.py
@@ -5,6 +5,8 @@ import random
IMAGES_PATH = 'games/drumgit/images'
+_logger = logging.getLogger('model')
+
class Model(object):
''' The model of the activity. Contains methods to read and save
the configuration for a game from xml. Stores the pairs and grid
@@ -12,19 +14,29 @@ class Model(object):
'''
def __init__(self, gamepath, dtdpath, name='noname'):
self.name = name
- self.pairs = {}
- self.grid = []
self.gamepath = gamepath
self.dtdpath = dtdpath
-
try:
self.dtd = libxml2.parseDTD(None, os.path.join(self.dtdpath, 'memosono.dtd'))
except libxml2.parserError, e:
- logging.error('No memosono.dtd found ' +str(e))
+ _logger.error('No memosono.dtd found ' +str(e))
self.dtd = None
self.ctxt = libxml2.newValidCtxt()
+
+ self.pairs = {}
+ self.grid = []
+ # used by the leader of the game to keep track of the game state
+ self.players = {}
+ self.player_active = 0
+ self.selected = 0
+ self.turn = 0
+ self.started = 0
+ self.count = 0
+
+
def read(self, filename):
+ ''' reades the configuration from an xml file '''
try:
doc = libxml2.parseFile(os.path.join(self.gamepath, filename))
if doc.validateDtd(self.ctxt, self.dtd):
@@ -55,12 +67,14 @@ class Model(object):
self.pairs[idpair] = pair
xpa.xpathFreeContext()
else:
- logging.error('Error in validation of the file')
+ _logger.error('Error in validation of the file')
doc.freeDoc()
except libxml2.parserError, e:
- logging.error('Error parsing file ' +str(e))
+ _logger.error('Error parsing file ' +str(e))
+
def save(self, filename):
+ ''' saves the configuration to an xml file '''
doc = libxml2.newDoc("1.0")
root = doc.newChild(None, "memosono", None)
root.setProp("name", self.name)
@@ -76,47 +90,34 @@ class Model(object):
doc.saveFormatFile(filename, 1)
doc.freeDoc()
+
def def_grid(self):
- print 'pairs: %s' %self.pairs
- ### create grid from pairs information
+ ''' create the grid for the play from the pairs information
+ and shuffles the grid so they always appear in a different
+ place
+ '''
+ _logger.debug(' pairs: %s', self.pairs)
for key in self.pairs.iterkeys():
- self.grid.append((key, 0))
- self.grid.append((key, 1))
- print 'self.grid: %s'%self.grid
-
- ### shuffle the grid tiles
+ self.grid.append([key, 0, 0])
+ self.grid.append([key, 1, 0])
+
random.shuffle(self.grid)
- print 'self.grid after shufle: %s'%self.grid
+ _logger.debug(' grid: %s', self.grid)
+
def gettile(self, tilenum):
- pairkey, moch = self.grid[tilenum]
+ ''' gets the information of an object associated with a tile number '''
+ pairkey, moch, state = self.grid[tilenum]
obj = os.path.join(IMAGES_PATH, self.pairs[pairkey][moch])
color = self.pairs[pairkey][2]
- # logger.debug('obj=%s color=%s'%(obj, color))
return (obj, color)
+
def same(self, a, b):
- pairkeya, moch = self.grid[a]
- pairkeyb, moch = self.grid[b]
+ ''' checks wether two tiles are matching '''
+ pairkeya, moch, state = self.grid[a]
+ pairkeyb, moch, state = self.grid[b]
return (pairkeya == pairkeyb)
-
-if __name__ == '__main__':
-
- print "[Read game from file] "
- model = Model()
- model.read('memosono.xml')
- print " name=" + model.name
- print " pairs=%s" %model.pairs
-
- elemkey = '0'
- if model.pairs.has_key(elemkey):
- del model.pairs[elemkey]
-
- model.pairs['2'] = ['frettchen.jpg', 'frettchen.wav']
-
- print "[Write game to file] "
- model.save('memosono.xml')
-