remove old files add new sources
authorReto Zingg <g.d0b3rm4n@gmail.com>
Sat, 3 Jul 2010 20:52:33 +0000 (23:52 +0300)
committerReto Zingg <g.d0b3rm4n@gmail.com>
Sat, 3 Jul 2010 20:52:33 +0000 (23:52 +0300)
55 files changed:
COPYRIGHT.BH [deleted file]
INSTALL [deleted file]
Makefile [deleted file]
README [deleted file]
src/Board.cpp [new file with mode: 0644]
src/Board.h [new file with mode: 0644]
src/ChangeLog [deleted file]
src/Cup.cpp [new file with mode: 0644]
src/Cup.h [new file with mode: 0644]
src/GameController.cpp [new file with mode: 0644]
src/GameController.h [new file with mode: 0644]
src/GameInfo.cpp [new file with mode: 0644]
src/GameInfo.h [new file with mode: 0644]
src/GraphicsScene.cpp [new file with mode: 0644]
src/GraphicsScene.h [new file with mode: 0644]
src/Kalah.cpp [new file with mode: 0644]
src/Kalah.h [new file with mode: 0644]
src/MainWindow.cpp [new file with mode: 0644]
src/MainWindow.h [new file with mode: 0644]
src/Makefile [deleted file]
src/MoveGenerator.cpp [new file with mode: 0644]
src/MoveGenerator.h [new file with mode: 0644]
src/Score.cpp [new file with mode: 0644]
src/Score.h [new file with mode: 0644]
src/Stone.cpp [new file with mode: 0644]
src/Stone.h [new file with mode: 0644]
src/ThemeManager.cpp [new file with mode: 0644]
src/ThemeManager.h [new file with mode: 0644]
src/ai-init.c [deleted file]
src/ai-init.h [deleted file]
src/ai-recurse.c [deleted file]
src/ai-test.c [deleted file]
src/ai-ultimate.c [deleted file]
src/ai.c [deleted file]
src/ai.h [deleted file]
src/callbacks.c [deleted file]
src/callbacks.h [deleted file]
src/graphics.c [deleted file]
src/graphics.h [deleted file]
src/launcher/Makefile [deleted file]
src/launcher/mancala-launcher.c [deleted file]
src/main.c [deleted file]
src/main.cpp [new file with mode: 0644]
src/main.h [deleted file]
src/mancala.c [deleted file]
src/mancala.h [deleted file]
src/play.c [deleted file]
src/play.h [deleted file]
src/plugin/Makefile [deleted file]
src/plugin/mancala-ui-plugin.c [deleted file]
src/settingswidget.cpp [new file with mode: 0644]
src/settingswidget.h [new file with mode: 0644]
src/sounds.c [deleted file]
src/sounds.h [deleted file]
src/src.pro [new file with mode: 0644]

diff --git a/COPYRIGHT.BH b/COPYRIGHT.BH
deleted file mode 100644 (file)
index 78c6065..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font 
-instruction code copyright (c) 2001 by URW++ GmbH. All Rights 
-Reserved. Luxi is a registered trademark of Bigelow & Holmes Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining 
-a copy of these Fonts and associated documentation files (the "Font 
-Software"), to deal in the Font Software, including without 
-limitation the rights to use, copy, merge, publish, distribute, 
-sublicense, and/or sell copies of the Font Software, and to permit 
-persons to whom the Font Software is furnished to do so, subject to 
-the following conditions:
-
-The above copyright and trademark notices and this permission notice 
-shall be included in all copies of one or more of the Font Software.
-
-The Font Software may not be modified, altered, or added to, and in 
-particular the designs of glyphs or characters in the Fonts may not 
-be modified nor may additional glyphs or characters be added to the 
-Fonts. This License becomes null and void when the Fonts or Font 
-Software have been modified.
-
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT.  IN NO EVENT SHALL 
-BIGELOW & HOLMES INC. OR URW++ GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES 
-OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, 
-INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF 
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR 
-INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT 
-SOFTWARE.
-
-Except as contained in this notice, the names of Bigelow & Holmes 
-Inc. and URW++ GmbH. shall not be used in advertising or otherwise to 
-promote the sale, use or other dealings in this Font Software without 
-prior written authorization from Bigelow & Holmes Inc. and URW++ GmbH.
-
-For further information, contact:
-
-info@urwpp.de
-or
-design@bigelowandholmes.com
diff --git a/INSTALL b/INSTALL
deleted file mode 100644 (file)
index 56ae381..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,62 +0,0 @@
-/*  
- *  Mancala Installation Instructions
- *  $Id: INSTALL,v 1.1.2.1 2004/01/17 20:09:02 sparrow_hawk Exp $
- *
- *  Copyright (C) 2003 Kevin Riggle
- *  <sparrow_hawk@users.sourceforge.net>
- *  http://cmancala.sourcefoge.net
- *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-To compile mancala, you will need:
-- the Simple DirectMedia Layer (SDL), the main graphics library
-  (http://www.libsdl.org)
-- SDL_image (http://www.libsdl.org/projects/SDL_image/)
-- SDL_ttf (http://www.libsdl.org/projects/SDL_ttf/)
-- the Bitstream Vera fonts (http://www.gnome.org/fonts/)
-
-SDL_image in turn requires:
-- libPNG (http://www.libpng.org/pub/png/libpng.html)
-- zlib (http://www.gzip.org/zlib/)
-
-SDL_ttf needs:
-- FreeType2 (http://www.freetype.org/)
-If you're a CVS junkie, note that the SDL_ttf in question is the SDL_ttf2
-module, not the SDL_ttf one.  It'll save you a lot of time and hassle.
-
-This seems like a lot because it is.  Most modern distributions have libSDL and
-the support libraries (eg. libPNG), so all you will need to compile are 
-SDL_image and SDL_ttf.  Check your system before compiling anything from source
-(eg. rpm -q libSDL).
-
-To compile mancala itself, unzip the source tarball and cd to the 'src' 
-directory under the 'mancala-gui-0.x.x' directory.  From there, type 'make', 
-su to root, and type 'make install'.  Congratulations!  You've just installed
-mancala!
-
-If the Bitstream Vera fonts are *not* in /usr/share/fonts/bitstream-vera, make
-the appropriate change to main.h before compiling.  My guess is that anyone on
-RedHat >=8.0 or Fedora will have no problem compiling this.  Those on other
-distributions may have more problems.
-
-Mancala is, at this point, only distributed as source.  I intend to make binary 
-packages available eventually, but that is going to take some doing, and I feel
-it is more important to release *something* than to wait until it is perfect.
-This program doesn't have much more than a niche following anyway, so if you
-want to run it I assume you can compile it yourself.  I have not been able to
-make it compile on Windows (using mingw), so if anyone else has better luck I
-would be very interested to hear about it.
-
-Thanks for trying mancala out, and feel free to e-mail me at 
-sparrow_hawk@users.sourceforge.net if you have any questions.
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 61290a4..0000000
--- a/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2009 Reto Zingg
-
-subsystem:
-       $(MAKE) -C src
-
-install:
-       $(MAKE) -C src install
-       mkdir -p $(DESTDIR)/usr/share/applications/hildon
-       mkdir -p $(DESTDIR)/usr/share/icons/hicolor/40x40/apps
-       mkdir -p $(DESTDIR)/usr/share/dbus-1/services
-       mkdir -p $(DESTDIR)/home/opt/mancala/data/
-       mkdir -p $(DESTDIR)/home/opt/mancala/bin/
-       cp data/mancala.desktop $(DESTDIR)/usr/share/applications/hildon
-       cp data/mancala.png $(DESTDIR)/usr/share/icons/hicolor/40x40/apps/mancala.png
-       cp data/com.nokia.mancala.service $(DESTDIR)/usr/share/dbus-1/services/
-       cp data/com.nokia.mancala_startup.service $(DESTDIR)/usr/share/dbus-1/services/
-       cp data/mancala.conf $(DESTDIR)/home/opt/mancala/data/
-       cp data/mancala.game $(DESTDIR)/home/opt/mancala/data/
-       cp data/mancala.html $(DESTDIR)/home/opt/mancala/data/
-       cp data/mancala.sh $(DESTDIR)/home/opt/mancala/bin/
-
-clean:
-       rm -f build-stamp config.guess config.sub
-       rm -rf debian/mancala
-       $(MAKE) -C src clean
-
-clobber: clean
-       $(MAKE) -C src clobber
-
-maemo-source: clean
-       dpkg-buildpackage -rfakeroot -sa -S -us -uc -i -I.git
-       
-maemo-bin: clean
-       dpkg-buildpackage -rfakeroot -b -us -uc
-
-.PHONY: clobber clean install subsystem maemo-source maemo-bin
diff --git a/README b/README
deleted file mode 100644 (file)
index d6521e1..0000000
--- a/README
+++ /dev/null
@@ -1,194 +0,0 @@
---------------------------------
- Mancala README file
- Kevin Riggle
- http://cmancala.sourceforge.net
- $Revision: 1.15.2.3 $
- $Date: 2004/01/17 20:18:06 $
---------------------------------
-
-To compile the Mancala program itself, cd into 'src' and type 'make'.
-To compile the ai-test program, type 'make ai-test-normal'.  ('make recurse' 
-and 'make ultimate' compile the mancala with the recursive and "ultimate" ai 
-modules, respectively.)
-
-
-DEV-LOG:
-
-01-17-04: A lot of work has happened on the graphical branch without much in 
-the way of updates here.  I would in no way call the code "production ready" --
-it's a game, for crying out loud, and I'm in high school.  It is in a lot better
-shape now, however.  There's still a memory leak somewhere, and valgrind is
-segfaulting on me (grr), but it more-or-less works and looks good doing it, so
-I'm releasing version 0.1.0 of the graphical Mancala in C today. :)  Projects
-for later include making it work with autoconf/automake/etc., fixing the
-remaining bugs, adding some configurability, and making it compile on Windows.
-I spent about five hours trying to get everything in place, and I'm still
-getting Blue Screens of Death.  At least it works on Linux, and I can show it
-to my teacher for a grade.  Happy compiling!
-
-01-07-04: The graphical version is getting off the ground, though the current
-code looks like barfed-up ramen.  Bugger.  Once I decided I didn't like the
-random stone placement look, I had an established code structure that forced
-me to do the drawing a certain way.  It's proving to be a real pain in the ass,
-since it's more logical to draw the entire board at once, but I'd rather not
-pass half my environment to a function.  I may have to, since the alternative
-is putting it all in main(), which is nasty, or dividing it up somehow, which
-just doesn't make any sense at all.  I think my first impulse (before random
-stones) was right -- all the board-drawing code goes in a function in
-graphics.c, and no more messing around with half-a-dozen intermediate surfaces.
-Oh, and I'm also keeping something of a development log at the Mancala in C
-webpage (http://cmancala.sourceforge.net) *and* the day-to-day changes in the
-ChangeLog, so I may be updating this less frequently than I used to.
-
-12-28-03: Well, well, well.  Looks like I may write a graphical version of
-mancala after all!  I've cleaned up the source code tree as well, using several
-other notable projects (*cough*Linuxkernel*cough*) as models.  I've also
-learned a bit about CVS in the process and how it handles branches.  Grrr...
-At any rate, this should be fun to watch. :)
-
-12-04-03: Progress continues.  Taking a small break from the ultimate algo, 
-(stealing homework time, too, but -- hey, this is homework too).  Redid the 
-Makefile a little more so you can make mancala and ai-test with any of the
-three routines, plus wrote *another* wrapper function because the copy-the-
-boards-and-set-up-the-logs code was being duplicated in -recurse and -ultimate.
-I'm proud to say that my first attempt at passing function pointers worked
-without a single hitch.  I love C... <sigh> :)
-
-12-01-03: Made good progress over Thanksgiving break.  SSH works pretty well,
-even over my grandmother's feeble dial-up connection.  Work is starting on the
-"ultimate" algorithm, which may or may not be "ultimate," but will certainly
-improve on the recursive algorithm, which doesn't have any concept of 
-"strategy" or not letting me have a huge capture.  Thankfully the memory
-requirements don't seem too overwhelming (c'mon, Kev, you really expected a
-couple pitiful little integer tables would bring a modern computer to its
-knees?)  If this comes along as quickly as it is seeming to, I may have time
-to write a GUI before Christmas.  Oh, and I removed Makefile.bsd because I
-figured out how to make one work for *both* UNIXes I use.
-
-11-22-03: Getting better at CVS every day.  Set up a separate branch for the
-new ai-test stuff (-r ai-test-headless), which lets me test the ai without
-entering each value manually.  Instead, it grabs it from a file, which allows
-me to, say, use AskIgor (http://www.st.cs.uni-sb.de/askigor/) to debug the ai.
-Once I've got the code tightened up, all I need to do is release my working
-directory and run "cvs co -j ai-test-headless mancala", resolve conflicts, and
-commit.  Sweetness. :)
-
-11-21-03: from the its-not-a-bug-its-a-feature dept.:  Turns out the ai-test 
-program was balking because I entered the human board as all zeroes, so it
-thought the game had been won.  Silly me.  Anyhow, 0.2.0 is in good shape
-and I'm starting on the ultimate algo now.  Nothing more to see here, move
-along... 
-
-11-19-03: Not sure *why* I can't squash the bug, but I need to step away and 
-we're due for a release anyway, so prepare for mancala-0.2.0!  This should
-include the bugfixes I came up with to the original ai lo these many years ago,
-and should otherwise prove that, yes, Virginia, I really am doing something.
-The old AI beats the recursive one *anyway*, so it isn't really a big deal.
-Now to refresh my memory about game theory so I can write THE ULTIMATE AI...
-MUAHAHAHAHA...  sorry. 
-
-11-12-03: Made a good start on squashing the bug I talked about two days ago.
-Still getting some confusing results (ai-test="0 1 2 0 0 0 0"), but it is 
-obvious we're getting the information we need without passing more pointers
-with each recursion.  I should be able to ditch *ptCount, too -- I love 
-abstraction, which lets me mess with the function definitions without making
-me rewrite the call in main.c too. :)  
-
-11-10-03: Almost have the recursive algorithm licked.  Looks like there's only 
-one major bug left, namely the "i have no idea how many stones i got when i
-recursed" bug.  Discovered that the algorithm had no idea if we'd won the
-game, and so would loop infinitely trying to find a move that didn't exist.
-Also changed the Makefiles so that they will clean up the logs the program 
-and the recursive algo generate.  Code needs some clean-up, commenting, and
-pretty exhaustive documentation (preferably step-by-step) just so I can say
-I'm doing *something* in my independent study, but is otherwise pretty close.
-
-10-29-03: Okay, added the select-a-random-move-if-we-don't-have-a-good-
-alternative code to the recursive algo -- need to check the main program
-logic to discern why the computer won't take its extra turns.  This may
-be why the recursive algorithm seems "worse" than the heiuristic one,
-when in fact they should play almost identically except in certain
-special cases (ie. where taking the extra turn destroys an opportunity
-for a larger gain, eg. a good capture).  Prepping a nicely-commented
-version for MIT.
------
-Bah.  Tested the instance I mentioned above and discovered that when my
-function actually recurses beyond one or two levels, it ends up getting
-stuck somewhere. Bah.
-
-10-28-03: And now it comes to me why I don't use my lovely rand_btw
-function in my heiuristic AI...  it doesn't work (or rather, it puts the
-"pseudo-" in "pseudo-random").  Research needed on a better and more
-random random-function, though its current form will work well enough
-for the version of the recursive algo I send to MIT (they won't see that
-code anyway :).  It's in mancala.c now, and extern'd.
-
-10-27-03: Well, the recursive algorithm now a) compiles and b) runs,
-though it doesn't play terribly well.  There are also several noticable
-bugs that need to be fixed (eg. if the AI cannot make a move that gains
-it points, it does not move at all), but by in large I'm happy that I've
-at least reached this juncture.  I'm also hoping to send the recursive
-algorithm to MIT with my application as an example of extra things I do
-in my spare time, so it's a good thing it's coming along so nicely.
-
-10-16-03: Taking a little longer than expected -- needing to get a development
-environment set up on SDF takes more time and money (!) than I initially thought
-it would.  At any rate, it's all set so I should be making some more progress
-now.  Added the two new ai modules (recursive and "ultimate") and started 
-updating the makefile to allow for that.  Nothing actually works yet, but
-it's in process now.  We'll see how far I get...
-
-09-21-03: Wow, it's really been a while.  The code is in SourceForge CVS 
-(finally) because I'm doing a little work on it for an independent-study at school -- learning about recursion and working with pointers.  At any rate, I'm
-making progress, and may even have a GUI in the works.  We'll see if I can
-learn to stomach graphics programming. :)
-
-07-10-02: Getting this ready to post to SourceForge.
-
-07-07-02: Coded the game loop plus neccessary game modules (mostly 
-mancala.c:move), integrating the AI.  The by far biggest bug in the AI (aside
-from the fact that it always loses against me) is that the 'random move'
-algorithm often picks piddly little moves that don't get it any points -- say
-moving one or two stones when there are ten in another hole.  The AI also needs
-a true random-number generator (probably a whole new algorithm).  I'm going to
-have to con a family member or three into sitting down and playing against this
-thing.  Since I *programmed* the dang thing, I have some insight into how it
-works.  (Which I stupidly revealed tonight, though they'll hopefully a. forget
-it, or b. not know what to do with the knowledge.)  I must say, if the program
-*I* design beats *me*, using just these pitiful hueristic methodss and not some
-fancy-schmancy neural-net-cum-expert-system-cum-kitchen-sink, it wouldn't say
-much for my skill at Mancala or the difficulty of the game.  (In short, it 
-would be *really* embarrassing!)  Not that I'm worried, mind you. ;-)
-
-07-04-02: Worked on instructions and game setup.  Also morphed common.h into
-mancala.[ch], containing the same game-wide symbolic constants plus most of
-the core game modules like move() and gameWon().
-
-07-03-02: Began the main program module by coding in support for command-line
-options.  Not sexy work, but necessary.  I also revised the Makefile to get
-rid of the *~ files EMACS sometimes leaves behind.
-
-06-29-02: Not only does it work, but I've fixed the remaining bugs in the AI
-module, so it's time to code the UI/game modules!
-
-06-28-02 (later): IT WORKS! (That thunking you hear is the sound of brain cells
-being violently beaten to death.  I forgot to dereference the pointers.  Shit.)
-AI code, at least with the minimal testing I've done, gives the expected 
-result.  This project may go quicker than I thought it would! :-)  Mad props to
-Peder Skyt of povray.off-topic for pointing out my error.
-
-06-28-02: Posted a query to povray.off-topic RE: the segfault/"scanf-needs-a-
-pointer" conundrum.  Gah.  Entered my code for the AI module itself.  No way to
-test it out (obviously), but it compiles so I'm happy.  Updated the Makefile
-(again) to compile with debugging, and introduced common.h to store standard
-symbolic constants (BOARD_MAX, INITIAL_STONES, etc.).
-
-06-27/28-02: Tried to code the bulk of ai-test.  Didn't work.  It's the ai-test
-module, now with SEGFAULTs!  I know it's a stupid problem, I *know* I've seen
-it before, but I can't. make. it. work! <grrrr>  Also updated the Makefile to 
-reflect the way GNU make *actually* works, not the way I think it does. :-)
-
-06-27-02: Well, just getting this project off the ground... set up a Makefile
-and put basic 'Hello, world!'-ish stubs in to test it out, set up a
-basic structure, etc. etc. etc. and checked it into CVS.  We'll see how this
-turns out... :-)
diff --git a/src/Board.cpp b/src/Board.cpp
new file mode 100644 (file)
index 0000000..bdc762d
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "Board.h"
+
+#include "math.h"
+
+#include <QDebug>
+
+// #include <kdebug.h>
+
+#include "Cup.h"
+#include "Kalah.h"
+#include "Stone.h"
+#include "GameInfo.h"
+#include "ThemeManager.h"
+
+
+Board::Board(GameInfo *gameInfo, ThemeManager *theme)
+    : QGraphicsSvgItem(0)
+{
+    setSharedRenderer(theme);
+    m_gameInfo = gameInfo;
+    m_theme = theme;
+    setElementId("board");
+    initialSetup();
+    setZValue(1);
+
+    qreal posX,posY,width,height,scaleX,scaleY;
+
+    posX = sceneBoundingRect().x() + sceneBoundingRect().width() * 0.0125; // 0.15
+    posY = sceneBoundingRect().y() + sceneBoundingRect().height() * 0.03; // 0.8
+    width = 1.16 * sceneBoundingRect().width(); // 0.85
+    // height = width / 1.75 ; // 2.5
+    height = 2.6 * sceneBoundingRect().height();
+
+    scaleX = width / ( boundingRect().width() );
+    scaleY = height / ( boundingRect().height() ) ;
+    scale(scaleX,scaleY);
+
+    setPos(posX,posY);
+    
+//     qDebug() << "posX" << posX;
+//     qDebug() << "posY" << posY;
+//     qDebug() << "scaleX" << scaleX;
+//     qDebug() << "scaleY" << scaleY;
+//     qDebug() << "width" << width;
+//     qDebug() << "height" << height;
+//     qDebug() << "boundingRect width" << boundingRect().width();
+//     qDebug() << "boundingRect height" << boundingRect().height();
+//     qDebug() << "sceneBoundingRect().height()" << sceneBoundingRect().height();
+//     qDebug() << "sceneBoundingRect().width()" << sceneBoundingRect().width();
+//     qDebug() << "sceneBoundingRect().y()" << sceneBoundingRect().y();
+//     qDebug() << "sceneBoundingRect().x()" << sceneBoundingRect().x();
+   
+}
+
+Board::~Board(){
+    //kDebug() << "Destructor of Board";
+    while(m_cups.count())
+        m_cups.pop_front();
+}
+
+void Board::initialSetup(){
+    createKalahs();
+    createCups();
+}
+
+void Board::createKalahs(){
+
+    //If the game supports Kalah(store) then create kalah
+    if(m_gameInfo->numKalahs()){
+        m_leftKalah = new Kalah(m_gameInfo, Kalah::Left, this);
+        m_rightKalah = new Kalah(m_gameInfo, Kalah::Right, this);
+    }
+    else return;
+}
+
+void Board::createCups(){
+
+    int i = 0;
+
+    //kDebug() << "---------Total in the list before first push---------: " << m_cups.count();
+    for(int row = 0; row < m_gameInfo->numRows(); row++){
+        for(int column = 0; column < m_gameInfo->numCupsPerRow(); column++){
+            //appending to the list of cup
+            m_cups << new Cup(m_gameInfo, i++ , this);
+        }
+    }
+
+}
+
+void Board::manipulateStones(QList<Stone*>& currentStoneList){
+
+    int j = 0 , stonesPerCupInitially = m_gameInfo->initialStonesPerCup();
+    Cup* cup;
+    m_stones = currentStoneList;
+
+    foreach(cup,m_cups){
+        for(int i = 0; i < stonesPerCupInitially ; i++ ){
+            cup->addStone(m_stones[j++]);
+        }
+    }
+
+}
+
+
+int Board::findCupIndex(QPointF position){
+    Cup* cup;
+    foreach(cup,m_cups){
+
+        if(cup->shape().contains( cup->mapFromScene(position) )){
+            return cup->index();
+        }
+    }
+    return -1;
+}
+
+
+void Board::updateChildren(int cupIndex,int kalahIndex,int stoneNo){
+
+    //kDebug() << "Int3 is called";
+
+    for(int i = 0 ; i < stoneNo ; i++){
+        //Remove from cup a stone
+        Stone *stone = m_cups[cupIndex]->updateStoneList();
+
+        if(kalahIndex == Kalah::Left){
+            m_leftKalah->updateStoneList(stone);
+        }
+        else m_rightKalah->updateStoneList(stone);
+        update();
+    }
+    update();
+}
+
+//It will remove stone from cupIndex and push it to kalah[index] or cup[index]
+void Board::updateChildren(int cupIndex,int index,bool isCup){
+
+    Stone* stone = m_cups[cupIndex]->updateStoneList();
+
+    m_isCup = isCup;
+    m_index = index;
+    m_stone = stone;
+
+    slotUpdateChildren();
+    update();
+}
+
+
+void Board::slotUpdateChildren(){
+
+    if(m_isCup)
+        m_cups[m_index]->updateStoneList(m_stone);
+
+    else{
+        if(m_index == Kalah::Left)
+            m_leftKalah->updateStoneList(m_stone);
+        else m_rightKalah->updateStoneList(m_stone);
+    }
+}
+
+
diff --git a/src/Board.h b/src/Board.h
new file mode 100644 (file)
index 0000000..bdc49ad
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BOARD_H
+#define BOARD_H
+
+#include <QtSvg/QGraphicsSvgItem>
+#include <QList>
+
+class Cup;
+class Kalah;
+class Stone;
+class GameInfo;
+class ThemeManager;
+
+class Board : public QGraphicsSvgItem{
+    Q_OBJECT
+public:
+
+    Board(GameInfo *manager, ThemeManager *theme);
+    ~Board();
+
+    void manipulateStones(QList<Stone*>& currentStoneList);
+    void updateChildren(int cupIndex,QList<Stone*> &currentStoneList);
+
+    void updateChildren(int,int,bool);
+    void updateChildren(int,int,int);
+
+    void initialSetup();
+
+    int findCupIndex(QPointF);
+
+public slots:
+    void slotUpdateChildren();
+
+protected:
+    QPointF calcCupPosition(int row, int col);
+
+private:
+    void createKalahs();
+    void createCups();
+    void showGameName();
+
+    QList <Cup*> m_cups;
+    QList <Stone*> m_stones;
+    Kalah* m_rightKalah;
+    Kalah* m_leftKalah;
+
+    GameInfo *m_gameInfo;
+    ThemeManager *m_theme;
+
+    qreal gapWidth;
+
+    bool m_isCup;
+    int m_index;
+    Stone* m_stone;
+};
+
+#endif // BOARD_H
diff --git a/src/ChangeLog b/src/ChangeLog
deleted file mode 100644 (file)
index 6231fde..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-$Id: ChangeLog,v 1.1.2.10 2004/01/17 20:20:21 sparrow_hawk Exp $
-
-2004_01_17:
-Released mancala-gui 0.1.0!
-
-Makefile:
-- Added 'make install' and 'make uninstall' targets.
-
-graphics.c:
-- Fixed a bug valgrind found in the text-drawing code.
-
-2004_01_12:
-graphics.c:
-- Fixed a memory leak. :-$
-- Coded function to dim opponent's side of the board.
-- Fixed glaring bug in board-drawing code.
-
-main.c:
-- Fixed memory leak.
-
-2004_01_08:
-graphics.c:
-- Cleaned up FillHole() in preparation for development of DrawBoard().
-- Extracted DrawBoard() from main.c and cleaned it up substantially.
-- DrawBoard now works, centers the text, and otherwise looks really freaking
-good.  I'm so totally modest. ;)
-
-graphics.h:
-- Added DrawBoard(), internalized FillHole().
-
-main.c:
-- Removed DrawBoard(). 
-- Centered the title.
-
-2004_01_07:
-graphics.c:
-- Now prints stone numbers above 10 in text.
-- Added int->string conversion and size-checking.
-- Code centers text.
-- Tried to blit it, having problems with alpha transparency.
-
-graphics.[ch], main.c:
-- Modified FillHole() call.
-- Modified NewSurfaceFrom() call.
-
-2004_01_06:
-graphics.c:
-- Abstracted code to create new surface using old as a model. 
-- Tore out random stone-positioning code, wrote new code to reflect new stone
-graphics.
-
-graphics.h:
-- Fixed typo.
-
-main.c:
-- Added code to initialize SDL_ttf, load a font, and render the title.
-
-main.h:
-- #define'd the location of the Bitstream Vera fonts temporarily.
-- #define'd various font sizes.
-
-Makefile:
-- Added compiler flags to compile with SDL_ttf.
-
-stone[00-10].png:
-- Graphics now show the full number of stones instead of a single one.
-
-2004_01_05:  
-main.c:
-- Extracted specialized graphics routines to graphics.c, now called through
-graphics.h.
-- Kludged in code to display stones.
-
-Makefile:
-- Added graphics.c.
-
-graphics.c, graphics.h:
-- Added.
-- Wrote function to populate hole with random stones.
-
-2004_01_04:  Wrote code to load and display the board.
-
-2003_12_28:  Began graphical branch.
-
--------------------------------------------------------------------------------
-Pre-graphics Changes
-
-Makefile:
-- Modified to make more easily extensible and added ai-init.
-- May have solved the problem which necessitates two Makefiles.
-- Rewrote Makefiles to compile ai-test with ultimate.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Resynched Makefile with Makefile.bsd.  Not pretty.  Need a ./configure script.
-- Added recursive and "ultimate" ai modules; updated the Makefile to compensate.
-
-main.c:
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Housekeeping and a dev-log update.
-- Have a nasty recursion bug partway squashed.  Adding printf's and, more
-importantly, fprintf's, which should help me debug any future issues.
-- More minor bugfixes...  rand_btw() got moved to the mancala common libs
-because I'm now using it in the recursive algorithm.
-- Latest revisions, mostly for portability issues.  (Added new rules for
-building on BSD, fixed a long-standing bug with the BOARD ARRAYS.)
-Otherwise, pretty mundane.
-
-mancala.c:
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- More minor bugfixes...  rand_btw() got moved to the mancala common libs
-because I'm now using it in the recursive algorithm.
-
-mancala.h:
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- More minor bugfixes...  rand_btw() got moved to the mancala common libs
-because I'm now using it in the recursive algorithm.
-
-ai-init.c:
-- Added needed #include.
-- Abstracted the ai initialization routines.
-
-ai-init.h:
-Abstracted the ai initialization routines.
-
-ai-recurse.c:
-- Now uses ai-init routine.
-- Finished removing ptCount.  Persistent bugger.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Deprecated ptCount.
-- Bug still isn't squashed... back to the way it was.
-- Cleaned up the code and added comments.
-- I squashed the bug's head, but his legs are still squirming.
-- Nasty infinite loop bug solved.  Added code that recognizes when the
-game has been won.
-- Added more fprintf's, only to discover that C doesn't really appreciate
-my trying to open the same file handle with *every* iteration of the
-recursive function.  Blast.  Will need to move logging to wrapper, and
-pass the file handle on down.
-- Have a nasty recursion bug partway squashed.  Adding printf's and, more
-importantly, fprintf's, which should help me debug any future issues.
-- Swatting bugs, added some printf's to try to discover where the
-problem lies.  Yay.
-- Couple more small modifications... still hunting the big bug.
-- Fixed a big, should-have-been-obvious bug where the recursive function
-was actually modifying the boards for the main program.  Added a layer
-of "insulation" (ie. another set of temporary boards) to the stub API
-function.
-- Pegged a couple obvious bugs.  Loops weren't considering the last
-position in the *Board[] arrays.
-- Added depth-perception.  Still chasing bugs.
-- Added random move feature to recursive algorithm.  Discovered new bugs.
-- More minor bugfixes...  rand_btw() got moved to the mancala common libs
-because I'm now using it in the recursive algorithm.
-- Ironed out some more bugs in the recursive algorithm.  It's beginning to
-take shape. :)
-- Minor bugfixes.  Recursive AI compiles... now to make it actually
-*work*.  Heh.
-- Latest revisions, mostly for portability issues.  (Added new rules for
-building on BSD, fixed a long-standing bug with the BOARD ARRAYS.)
-Otherwise, pretty mundane.
-- Added recursive and "ultimate" ai modules; updated the Makefile to compensate.
-
-ai-test.c:
-- ai-test now takes board layouts on the command line.
-- Merged ai-test-headless into trunk.  Adding code to accept board data in
-three different formats.  Direct input and file input work, now need to
-make command-line options work.
-- Cleaning up ai.h interitance broke ai-test. Added the relevant #include.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Messing with my test suite again.
-- More minor bugfixes.  (...be vewy qwiet, ve are hunting a big wone...)
-
-ai-ultimate.c:
-- Working on the ai code... @#$%.
-- Now uses ai-init routine.
-- More progress -- working on the figuring-out-the-best-move code.
-- Function now prints outcome table.
-- In progress...
-- Ditching old code and rewriting...
-- Added logging to ultimate's API function.
-- Coded API function, cleaned up some "pseudocode".
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Latest revisions, mostly for portability issues.  (Added new rules for
-building on BSD, fixed a long-standing bug with the BOARD ARRAYS.)
-Otherwise, pretty mundane.
-- Added recursive and "ultimate" ai modules; updated the Makefile to compensate.
-
-ai.c:
-- Reworking inheritence broke ai.c -- fixed now.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- More minor bugfixes...  rand_btw() got moved to the mancala common libs
-because I'm now using it in the recursive algorithm.
-
-ai.h:
-- Eliminated inheritence cruftiness.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-
-blankfile:  (template)
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-
-README:
-- Added ai initialization routine to the AI API, updated dev-log.
-- Deprecated and removed Makefile.bsd; updated dev-log.
-- Added SF.net URL and $Source: /cvsroot/cmancala/mancala/src/Attic/ChangeLog,v $ directive to headers.
-- Added ai-test-headless branch, updated dev-log with additional info.
-- "bug" fixed.
-- Updated dev-log.
-- I squashed the bug's head, but his legs are still squirming.
-- Housekeeping and a dev-log update.
-- Not sure why the README file had a zero at its beginning, but it did.  Gone.
-- Added random move feature to recursive algorithm.  Discovered new bugs.
-- Updated DEV-LOG. :)
-- Ironed out some more bugs in the recursive algorithm.
-- Added recursive and "ultimate" ai modules; updated the Makefile to compensate.
-- First commit in SourceForge CVS.  Lost the log off my system -- check README for development history up to this point.
diff --git a/src/Cup.cpp b/src/Cup.cpp
new file mode 100644 (file)
index 0000000..41d7c88
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Cup.h"
+
+#include <math.h>
+
+#include <QFont>
+#include <QSize>
+#include <QPainter>
+#include <QPointF>
+#include <QGraphicsSceneMouseEvent>
+#include <QTimer>
+
+// #include <kdebug.h>
+
+#include "Stone.h"
+#include "Board.h"
+#include "GameInfo.h"
+
+
+Cup::Cup(GameInfo* info, int cupNumber, QGraphicsSvgItem *parent)
+    : QGraphicsSvgItem(parent)
+
+{
+    m_index = cupNumber;
+    m_board = qgraphicsitem_cast<Board*>(parent);
+    m_gameInfo = info;
+    m_text = new QGraphicsSimpleTextItem(parent);
+
+    setSharedRenderer(m_board->renderer());
+    setElementId("cup");
+    setZValue(2);
+
+    drawInitially();
+    drawTextInitially(m_gameInfo->initialStonesPerCup());
+
+    //connect(this,SIGNAL(signalChangeText()),this,SLOT(slotChangeText()));
+}
+
+void Cup::drawInitially(){
+
+    qreal gapWidth = m_board->boundingRect().width() * ( 0.2 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() + 1 ) );
+
+    m_size.setWidth( m_board->boundingRect().width() * 0.8 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() ) );
+    m_size.setHeight( m_board->boundingRect().height() * 0.35 );
+
+    qreal posX,posY;
+
+    if(m_index < m_gameInfo->numCupsPerRow())
+        posX = m_board->boundingRect().x() + gapWidth * ( m_index % m_gameInfo->numCupsPerRow() +
+        m_gameInfo->numKalahs()) + ( m_index % m_gameInfo->numCupsPerRow() + 1) * m_size.width();
+
+    else{
+        posX = m_board->boundingRect().x() + gapWidth *
+        ((((2*m_gameInfo->numCupsPerRow()-1)-m_index) % m_gameInfo->numCupsPerRow()) + m_gameInfo->numKalahs() )
+        +(((2*m_gameInfo->numCupsPerRow()-1)-m_index) % m_gameInfo->numCupsPerRow() + 1) * m_size.width();
+    }
+    posY = m_board->boundingRect().y() + 0.1 * m_board->boundingRect().height();
+    if(m_index >= m_gameInfo->numCupsPerRow())
+        posY += 0.1 * m_board->boundingRect().height() + m_size.height();
+
+
+    m_pos.setX(posX);
+    m_pos.setY(posY);
+
+    qreal cupScaleX = m_size.width() / this->boundingRect().width();
+    qreal cupScaleY = m_size.height()/ this->boundingRect().height();
+
+    m_mid_point.setX( m_pos.x() + m_size.width() / 2 );
+    m_mid_point.setY( m_pos.y() + m_size.height() / 2 );
+
+    setPos(m_pos);
+    scale(cupScaleX,cupScaleY);
+
+}
+
+
+void Cup::drawTextInitially(int numStone){
+
+    QString str;
+    while(numStone != 0){
+            //qDebug() << "Number " << numStone % 10 << " Char " <<(QChar)(numStone % 10 + '0') ;
+            str.push_front( (QChar)(numStone % 10 + '0') );
+            numStone /= 10;
+        }
+
+    m_text->setText(str);
+    m_text->setFont( QFont("Comic Sans MS", 24, QFont::Bold) );
+    m_text->setPen(QPen(QColor("darkslateblue"), 1.5, Qt::SolidLine, Qt::RoundCap,
+                   Qt::RoundJoin));
+
+    QLinearGradient gradient(0, 0, 0, 100);
+    gradient.setColorAt(0.0, "mediumslateblue");
+    gradient.setColorAt(1.0, "cornsilk");
+    m_text->setBrush(gradient);
+
+    m_text->setVisible(false);
+
+    int textX = m_pos.x() + m_size.width();
+    textX -= m_text->boundingRect().size().width() + 15;
+
+    int textY =  m_pos.y() + m_size.height();
+    textY -= m_text->boundingRect().size().height() - 15;
+
+    m_text->scale(0.6,0.6);
+    m_text->setPos( textX,textY );
+    m_text->setZValue(4);
+    m_text->setVisible(true);
+
+}
+
+//add Stone to cup
+void Cup::addStone(Stone* stone){
+
+    QPointF* stonePos;
+    qreal m_diameter_stone = qMin(m_size.width()/5, m_size.height()/5);
+
+    stone->setSize(QSize(m_diameter_stone,m_diameter_stone));
+    stonePos = calculateStonePosition(stone);
+
+    //kDebug() << "Stone Position: " << stonePos->x() << " " <<stonePos->y();
+
+    stone->setPosition(stonePos->x(),stonePos->y());
+
+    m_stone.append(stone);
+}
+
+
+//Add a stone to the stoneList
+void Cup::updateStoneList(Stone* stoneItem){
+
+    QPointF *stonePos;
+    m_stone.append(stoneItem);
+
+    //calculate and update stone position
+    stonePos = calculateStonePosition(stoneItem);
+    stoneItem->animateStones(QPointF(stonePos->x(),stonePos->y()));
+    update();
+
+    QTimer::singleShot(500, this, SLOT(slotChangeText()));
+
+}
+
+//Remove a stone from the stoneList
+Stone* Cup::updateStoneList(){
+
+    Stone* stone;
+
+    if(m_stone.count()){
+        stone = m_stone.front();
+        m_stone.pop_front();
+    }
+    else{
+        // kDebug() << "List is empty already";
+        return NULL;
+    }
+    slotChangeText();
+
+    return stone;
+
+}
+
+void Cup::slotChangeText(){
+
+    m_text->setVisible(false);
+    if( m_stone.count() ){
+        m_text->setText( QString("%1").arg( m_stone.count() ));
+        m_text->setVisible(true);
+        update();
+    }
+}
+
+
+QPointF* Cup::calculateStonePosition(Stone* stone){
+
+    QPointF *returnPoint = new QPointF();
+
+    qreal diameter = qMin( m_size.width(),m_size.height());
+
+    int initialLength = qrand() % (int) diameter / 3;
+    int angle = qrand() % 360;
+
+    qreal posX = middlePoint().x() + initialLength * cos(angle * M_PI / 180);
+    qreal posY = middlePoint().y() + initialLength * sin(angle * M_PI / 180);
+
+    if( ( posX + stone->size().width()) > ( position().x() + 0.7 * m_size.width() ) )
+        posX -= stone->size().width();
+    else if( posX < ( m_pos.x()+ 0.3 * m_size.width() ) )
+        posX += stone->size().width();
+
+    if( ( posY + stone->size().height() ) > ( m_pos.y() + 0.7 * m_size.height() ) )
+        posY -= stone->size().height();
+    else if( posY < (m_pos.y() + 0.3 < m_size.height() ) )
+        posY += stone->size().height();
+
+    returnPoint->setX(posX);
+    returnPoint->setY(posY);
+
+    return returnPoint;
+
+}
+
+//Reimplementing the shape item
+QPainterPath Cup::shape() const
+ {
+     QPainterPath path;
+     path.addEllipse(boundingRect());
+     return path;
+ }
diff --git a/src/Cup.h b/src/Cup.h
new file mode 100644 (file)
index 0000000..3f07466
--- /dev/null
+++ b/src/Cup.h
@@ -0,0 +1,77 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CUP_H
+#define CUP_H
+
+#include <QtSvg/QGraphicsSvgItem>
+#include <QGraphicsSimpleTextItem>
+
+class QSizeF;
+class Board;
+class Stone;
+class QPainter;
+class GameInfo;
+
+class Cup : public QGraphicsSvgItem{
+    Q_OBJECT
+    public:
+        Cup(GameInfo* info, int cupNumber, QGraphicsSvgItem *parent);
+
+        void drawInitially();
+        void drawTextInitially(int numStone);
+        void updateStoneList(Stone* stoneItem);
+        Stone* updateStoneList();
+        QPointF* calculateStonePosition(Stone *stone);
+        void addStone(Stone* stone);
+
+        //void setIdentifier(int num){ m_identifier = num;}
+        void setPosition(QPointF pos){ m_pos = pos;}
+        void setSize(QSizeF size){ m_size = size;}
+
+        //getting methods
+        int index() const{ return m_index; }
+        QSizeF size() const{ return m_size;}
+        QPointF middlePoint() const{ return m_mid_point;}
+        QPointF position() const{return m_pos;}
+        QPainterPath shape() const;
+
+    signals:
+
+    public slots:
+        void slotChangeText();
+
+    private:
+        //int m_identifier; //only for debugging
+
+        QPointF m_pos;
+        QSizeF m_size;
+        QPointF m_mid_point;
+        int m_index;
+        QString m_stone_num;
+
+        QList <Stone*> m_stone;
+        QGraphicsSimpleTextItem *m_text;
+
+        GameInfo* m_gameInfo;
+        Board* m_board;
+    };
+
+#endif // CUP_H
+
diff --git a/src/GameController.cpp b/src/GameController.cpp
new file mode 100644 (file)
index 0000000..5138c66
--- /dev/null
@@ -0,0 +1,975 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// #include <KLocale>
+
+#include "GameController.h"
+
+#include <QTimer>
+#include <QStringList>
+#include <QList>
+
+// #include <kdebug.h>
+
+#include "Board.h"
+#include "Score.h"
+#include "Kalah.h"
+#include "MoveGenerator.h"
+
+
+GameController::GameController(GameInfo* gameInfo){
+    m_gameInfo = gameInfo;
+    m_humanScore = new Score();
+    m_computerScore = new Score();
+    initializeGameController();
+
+    connect(this,SIGNAL(signalSowMaker(int)),this,SLOT(sowMaker(int)));
+    connect(this,SIGNAL(signalAfterSow(int)),this,SLOT(afterSow(int)));
+    connect(this,SIGNAL(signalComputerMove()),this,SLOT(makeComputerMove()));
+
+}
+
+void GameController::initializeGameController(){
+
+    m_gameDifficulty = GameController::EASY;
+    m_moveGenerator = new MoveGenerator(m_gameDifficulty,m_gameInfo,this);
+    m_humanTurn = true;
+    m_cupIndexClicked = -1;
+    m_humanSide = GameController::LOWER;
+    m_humanKalah = Kalah::Right;
+    m_gamePaused = false;
+    m_gameOver = false;
+    m_physicalMoveAllowed = false;
+    m_captureInfo = m_gameInfo->captureInfo();
+
+    //If game is clockwise change human kalah
+    if(m_humanSide == GameController::LOWER && m_gameInfo->rotationType() == GameInfo::CLOCKWISE){
+        m_humanKalah = Kalah::Left;
+    }
+
+    m_humanScore->reset();
+    m_computerScore->reset();
+
+    emit signalMessage("");
+    emit signalShowTurn(m_humanTurn);
+    emit signalShowScore(m_humanScore->score(),true);
+    emit signalShowScore(m_computerScore->score(),false);
+
+    initializeBoard();
+    setHumanSideCups();
+
+}
+
+void GameController::initializeBoard(){
+
+    while(m_physicalBoard.count()){
+        m_physicalBoard.pop_back();
+        m_logicalBoard.pop_back();
+    }
+
+    //stoneInfo in cups (0 to 2*m_gameInfo->numCupsPerRow()-1)
+    for(int i = 0 ; i< 2*m_gameInfo->numCupsPerRow();i++){
+        m_physicalBoard.append(m_gameInfo->initialStonesPerCup());
+        m_logicalBoard.append(m_gameInfo->initialStonesPerCup());
+    }
+
+    //stoneInfo in kalah's
+    for(int i = 0 ; i < 2 ; i++){
+        m_physicalBoard.append(0);
+        m_logicalBoard.append(0);
+    }
+
+}
+
+void GameController::setHumanSideCups(){
+
+    while(m_humanSideCups.count())
+        m_humanSideCups.pop_back();
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow();i++)
+        m_humanSideCups.append(i);
+    if(m_humanSide == GameController::LOWER)
+        for(int i = 0 ; i < m_gameInfo->numCupsPerRow();i++){
+        m_humanSideCups[i] = 2*m_gameInfo->numCupsPerRow() - 1 - m_humanSideCups[i];
+
+    }
+
+}
+
+//It is called from the GraphcisScene to start the game
+void GameController::setBoardItem(Board *board){
+    m_board = board;
+
+    //If computer starts we will delay it by 1.5 seconds
+    if(!m_humanTurn){
+        emit signalShowTurn(false);
+        QTimer::singleShot(1500, this, SLOT(makeComputerMove()));
+    }
+
+}
+
+//-------------Is this valid cup(cupIndex) belongs to human ----------------
+bool GameController::isHumanCup(int cupIndex){
+
+    if(cupIndex >= m_gameInfo->numCupsPerRow())
+        return true;
+    return false;
+}
+
+//----------------Is the kalah(kalahIndex) belongs to human---------------------
+bool GameController::isHumanKalah(int kalahIndex){
+    kalahIndex -= 2*m_gameInfo->numCupsPerRow();
+
+    if(kalahIndex == m_humanKalah){
+        return true;
+    }
+    return false;
+}
+
+//-----------------------------Human Move-----------------------------------
+void GameController::makeHumanMove(int index){
+
+    if(isGameOver(m_physicalBoard) || !m_humanTurn) return;
+
+    m_physicalMoveAllowed = true;
+    // kDebug() << "Human Moving .................";
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE)
+        m_multipleLapDelay = false;
+    m_rotationInfo = m_gameInfo->rotationInfo(index);
+    sowMaker(index);
+
+}
+
+//----------------------------------Computer Move----------------------------
+void GameController::makeComputerMove(){
+
+    if(isGameOver(m_physicalBoard) || m_humanTurn) return;
+
+    // kDebug() << "Computer Moving ................";
+
+    m_physicalMoveAllowed = false;
+    int index = m_moveGenerator->bestMove(m_physicalBoard,false);
+    m_physicalMoveAllowed = true;
+    m_rotationInfo = m_gameInfo->rotationInfo(index);
+
+    if(index != -1){
+        // kDebug() << "Index: " << index << " Stones: " << m_physicalBoard[index];
+        sowMaker(index);
+    }
+
+    else
+        computerHasNoMove();
+}
+
+//slot sowMaker
+void GameController::sowMaker(int index){
+
+    if(isGameOver(m_physicalBoard)) return;
+    m_physicalMoveAllowed = true;
+
+    m_index = index;
+    //For human Turn, we want to response quick, unless it falls between multiple lap
+    if(m_humanTurn){
+        if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE && m_multipleLapDelay)
+            QTimer::singleShot(1500,this,SLOT(sowController()));
+        else sowController();
+    }
+
+    else QTimer::singleShot(1500,this,SLOT(sowController()));
+}
+
+
+void GameController::sowController(){
+
+    if(m_gameOver) return;
+
+    int index = m_index;
+    index = singleSow(index);
+
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE && !isEndOfLap(index,m_physicalBoard)){
+        if(m_humanTurn) m_multipleLapDelay = true;
+        emit signalSowMaker(index);
+    }
+    else{
+        emit signalAfterSow(index);
+    }
+
+}
+
+//slot After Sow
+void GameController::afterSow(int index){
+
+    if(isGameOver(m_physicalBoard)) return;
+    if(m_gameInfo->isBonusTurn()){
+
+        if(index >= 2*m_gameInfo->numCupsPerRow()){   //is a kalah
+            // kDebug() << "A Bonus Turn:";
+            if(m_humanTurn && isHumanKalah(index)){
+                emit signalMessage( tr("You got a bonus turn") );
+                if(isHumanSideEmpty(m_physicalBoard)) humanHasNoMove();
+                return;
+
+            }
+            else if(!m_humanTurn && !isHumanKalah(index)){
+                emit signalMessage( tr("Computer got a bonus turn") );
+                if(isComputerSideEmpty(m_physicalBoard)) computerHasNoMove();
+                emit signalComputerMove();
+                return;
+            }
+
+        }
+    }
+
+
+    if(isGameOver(m_physicalBoard)) return;
+    handleCrossCapture(index,m_physicalBoard);
+    emit signalMessage("");
+
+    if(isGameOver(m_physicalBoard)) return;
+    int multiplier = handleCountNSeriesCapture(index,m_physicalBoard);
+
+    if(isGameOver(m_physicalBoard)) return;
+    changeTurn();
+
+    if(!m_humanTurn && !m_gameOver){
+        // kDebug() << "Next turn computer";
+        if(isComputerSideEmpty(m_physicalBoard)) computerHasNoMove();
+        else{
+            if(multiplier > 0)
+                QTimer::singleShot( multiplier * 1500, this, SLOT(makeComputerMove() ) );
+            else
+                QTimer::singleShot(1500, this, SLOT(makeComputerMove()));
+        }
+    }
+    else{
+        // kDebug() << "Next turn Human";
+        if(isHumanSideEmpty(m_physicalBoard) ) humanHasNoMove();
+    }
+
+}
+
+void GameController::changeTurn(){
+
+    m_humanTurn == true ? m_humanTurn = false : m_humanTurn = true;
+    emit signalShowTurn(m_humanTurn);
+}
+
+//---------------------------- is End Of Lap -----------------------------------
+bool GameController::isEndOfLap(int index,QList<int>& board){
+
+    //if last stone ends on a cup with desired no of stone
+    if(index < 2*m_gameInfo->numCupsPerRow() && board[index] == m_gameInfo->stonesToEndLap()){
+        return true;
+    }
+    //if last stone on a kalah
+    if(index >= 2*m_gameInfo->numCupsPerRow()){
+        return true;
+    }
+
+    return false;
+}
+
+//Will be true when each cup is empty
+bool GameController::isGameOver(QList<int>& board){
+
+    if(m_gameOver) return true;
+
+    for(int i = 0 ; i < 2*m_gameInfo->numCupsPerRow() ; i++)
+        if( board[i] > m_gameInfo->leftToCup() )
+            return false;
+    if(m_physicalMoveAllowed) emit signalGameOver();
+    m_gameOver = true;
+    return m_gameOver;
+}
+
+//--------------------------------single Lap sowing -------------------------------------
+int GameController::singleSow(int cupIndex){
+    //we first find out from which side the sowing started - easy, who is moving
+    Side side = m_humanSide;
+    if(!m_humanTurn) side = (Side)(1 - m_humanSide);
+
+    // if(m_physicalMoveAllowed) kDebug() << "We are here to sow";
+
+    QList<int> board;
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    //0-CLOCKWISE,1-ANTI_CLOCKWISE
+    int rotation = m_gameInfo->rotationInfo(cupIndex);
+    int i , kalahNo = Kalah::Left;
+    bool putKalahNow = false;
+    int returnValue = cupIndex;
+
+    //Initial Check where to put in the first stone
+    if( rotation == GameInfo::ANTICLOCKWISE){
+
+        i = cupIndex - 1;
+        if(cupIndex >= m_gameInfo->numCupsPerRow()){
+            kalahNo = Kalah::Right;
+        }
+
+        if( m_gameInfo->stonesToKalah() &&
+            ( (cupIndex == m_gameInfo->numCupsPerRow() && side == GameController::LOWER)
+            || ( cupIndex == 0 && side == GameController::UPPER ) ) )
+            putKalahNow = true;
+    }
+    //clockwise
+    else{
+        i = cupIndex + 1;
+        if(cupIndex < m_gameInfo->numCupsPerRow())
+            kalahNo = Kalah::Right;
+
+        if( m_gameInfo->stonesToKalah() &&
+            ( (cupIndex == (2 * m_gameInfo->numCupsPerRow()-1) && side == GameController::LOWER)
+               || ( cupIndex == (m_gameInfo->numCupsPerRow()-1) && side == GameController::UPPER) ) )
+            putKalahNow = true;
+    }
+
+
+    //Continuous check and update
+    int loop = board[cupIndex]- m_gameInfo->leftToCup();
+
+    for(int j = 0 ; j < loop ; j++){
+
+        if( rotation == GameInfo::CLOCKWISE)
+            i %= 2 * m_gameInfo->numCupsPerRow();
+        else
+            if( i < 0) i = 2 * m_gameInfo->numCupsPerRow() - 1;
+
+        //If it is need to be put in cup
+        if( !putKalahNow ){
+            board[i]++;
+
+            if(m_physicalMoveAllowed){
+                m_board->updateChildren(cupIndex,i,true);
+//                // kDebug() << "Putting to cup: " << i;
+            }
+            returnValue = i;
+
+            //check whether the next stone will put in kalah or not
+            if( rotation == GameInfo::ANTICLOCKWISE){
+                if( m_gameInfo->stonesToKalah() &&
+                    ( ( i == m_gameInfo->numCupsPerRow() && side == GameController::LOWER )
+                      ||( i == 0 && side == GameController::UPPER ) ) )
+                    putKalahNow = true;
+                i--;
+            }
+            else{
+                if( m_gameInfo->stonesToKalah() &&
+                    ( (i == (2 * m_gameInfo->numCupsPerRow()-1) && side == GameController::LOWER)
+                     || ( i == (m_gameInfo->numCupsPerRow()-1) &&  side == GameController::UPPER) ) )
+                    putKalahNow = true;
+                i++;
+            }
+
+        }
+        //going to put it in kalah
+        else{
+
+            if(kalahNo == Kalah::Right){
+
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "Putting to Right Kalah";
+                    m_board->updateChildren(cupIndex,Kalah::Right,false);
+                }
+                returnValue = 2*m_gameInfo->numCupsPerRow() + Kalah::Right;
+                board[returnValue]++;
+            }
+
+            else{
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "Putting to left kalah";
+                    m_board->updateChildren(cupIndex,Kalah::Left,false);
+                }
+
+                returnValue = 2*m_gameInfo->numCupsPerRow() + Kalah::Left;
+                board[returnValue]++;
+            }
+
+            if(m_physicalMoveAllowed){
+                if(m_humanTurn && kalahNo == m_humanKalah)
+                    changeScore(1,true);
+                else changeScore(1,false);
+            }
+
+            putKalahNow = false;
+        }
+
+        board[cupIndex]--;
+    }
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+    return returnValue;
+}
+
+
+void GameController::slotGameDifficulty(Difficulty difficulty){
+//    kDebug() << "GameDifficulty is: " << difficulty;
+    m_gameDifficulty = difficulty;
+    m_moveGenerator->changeDifficulty(m_gameDifficulty);
+}
+
+
+//******************************** slots ******************************************
+void GameController::slotMouseClicked(int index){
+
+    if(m_gameOver)
+        return;
+
+    if(m_humanTurn){
+        m_cupIndexClicked = index;
+
+        if(isHumanSideEmpty(m_physicalBoard)){
+            emit signalMessage( tr("Sorry, you have no move") );
+            humanHasNoMove();
+        }
+        else if(m_cupIndexClicked < 0){
+            emit signalMessage( tr("Click on a Cup") );
+        }
+
+        else if(!isHumanCup(index))
+            emit signalMessage( tr("Click on a cup in the lower row") );
+
+        else if(m_physicalBoard[index] <= m_gameInfo->leftToCup())
+            emit signalMessage( tr("Sorry, not enough stones to move") );
+
+        else{
+            makeHumanMove(m_cupIndexClicked);
+        }
+    }
+
+}
+
+void GameController::slotGameOverForNewGame(int identity){
+    m_gameOver = true;
+    emit signalMessage( tr("Loading game...") );
+
+    QTimer* timer = new QTimer(this);
+    signalMapper = new QSignalMapper(this);
+    connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+    signalMapper->setMapping(timer,identity);
+    connect(signalMapper,SIGNAL(mapped(int)),this,SIGNAL(timeout(int)));
+
+    connect(this,SIGNAL(timeout(int)),this,SLOT(newGameEmitter(int)));
+    timer->setSingleShot(true);
+    timer->start(1500);
+}
+
+void GameController::newGameEmitter(int identity){
+    emit signalNewGame(identity);
+}
+
+void GameController::slotGameOverForRestartGame(){
+    m_gameOver = true;
+//    kDebug() << "GameOver is true";
+    emit signalMessage( tr("Loading game...") );
+    QTimer::singleShot(2000,this,SLOT(restartGameEmitter()));
+}
+
+void GameController::restartGameEmitter(){
+    emit signalRestartGame();
+}
+
+//******************************** slots *****************************
+
+bool GameController::isHumanSideEmpty(QList<int>& board){
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow() ; i++)
+        if(board[m_humanSideCups[i]] > m_gameInfo->leftToCup())
+            return false;
+    return true;
+}
+
+bool GameController::isComputerSideEmpty(QList<int>& board){
+
+    int maxIndex = 2*m_gameInfo->numCupsPerRow() - 1;
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow() ; i++)
+        if(board[maxIndex - m_humanSideCups[i]] > m_gameInfo->leftToCup())
+            return false;
+    return true;
+}
+
+//---------------------------------- capture handling-------------------------------------
+
+void GameController::handleCrossCapture(int index,QList<int>& board){
+
+    if(m_physicalMoveAllowed){ //kDebug() << "handle Cross capture -------";
+        if(isGameOver(m_physicalBoard)) return;
+    }
+    if(index >= 2*m_gameInfo->numCupsPerRow())
+        return;
+
+    //if CrossCapture allowed then 0th bit should be 1
+    int capture = m_gameInfo->captureType();
+    if(m_physicalMoveAllowed) // kDebug() << "Capture Info: " << capture;
+    if(!(capture & 1)){
+        if(m_physicalMoveAllowed) //kDebug() << "We will return";
+        return;
+    }
+
+    int opponentCupIndex;
+    int kalahIndex = -1;
+    //If it is a cup
+    if(index < 2*m_gameInfo->numCupsPerRow()){
+
+        opponentCupIndex = 2*m_gameInfo->numCupsPerRow() - 1 - index;
+        //if opponet cup is empty
+        if(board[opponentCupIndex] == 0)
+            return;
+        if(board[index] != 1)    //we are now taking that only 1 stone
+            return;
+
+        if(isHumanCup(index) && m_humanTurn)
+            kalahIndex = m_humanKalah;
+        else if(!m_humanTurn && !isHumanCup(index))
+            kalahIndex = 1 - m_humanKalah;
+
+        //Now do the capture;
+        if(kalahIndex != -1){
+           QString strIndex = QString("%1,%2").arg(index).arg(kalahIndex);
+
+           //Animation part
+           if(m_physicalMoveAllowed){
+               QTimer* timer = new QTimer(this);
+               signalMapper = new QSignalMapper(this);
+
+               connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+               signalMapper->setMapping(timer,strIndex);
+               connect(signalMapper,SIGNAL(mapped(const QString&)),this,SIGNAL(timeout(const QString&)));
+
+               connect(this,SIGNAL(timeout(const QString&)),this,SLOT(crossCapture(const QString&)));
+               timer->setSingleShot(true);
+               timer->start(1500);
+           }
+           else crossCapture(strIndex);
+        }
+    }
+
+}
+
+//Cross Capture is done here
+void GameController::crossCapture(const QString& indexString){
+
+    if(isGameOver(m_physicalBoard)) return;
+
+    int capture = m_gameInfo->captureType();
+    if(! (capture & 1) ) return;
+
+    int loop,i;
+    QList<int> board;
+    QStringList list;
+    int index,kalahIndex,opponentCupIndex;
+
+    list = indexString.split(',');
+    index = list[0].toInt();
+    kalahIndex = list[1].toInt();
+    opponentCupIndex = 2*m_gameInfo->numCupsPerRow() - 1 - index;
+
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    loop = board[index];
+    for(i = 0 ; i < loop ; ++i){
+        //we want to remove from index and put to kalah(human)
+        if(m_physicalMoveAllowed) m_board->updateChildren(index,kalahIndex,false);
+        board[index]--;
+        board[kalahIndex + 2*m_gameInfo->numCupsPerRow()]++;
+
+        if(m_physicalMoveAllowed){
+            if(kalahIndex == m_humanKalah)
+                changeScore(1,true);
+            else changeScore(1,false);
+        }
+    }
+
+    loop = board[opponentCupIndex];
+    for(i = 0 ; i < loop ; ++i){
+        //we want to remove from index and put to kalah(human)
+        if(m_physicalMoveAllowed) m_board->updateChildren(opponentCupIndex,kalahIndex,false);
+        board[opponentCupIndex]--;
+        board[kalahIndex + 2*m_gameInfo->numCupsPerRow()]++;
+
+        if(m_physicalMoveAllowed){
+            if(kalahIndex == m_humanKalah)
+                changeScore(1,true);
+            else changeScore(1,false);
+        }
+
+    }
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+}
+
+int GameController::handleCountNSeriesCapture(int index,QList<int>& board){
+    if(m_physicalMoveAllowed){
+        // kDebug() << "count and series capture--------";
+        if(isGameOver(m_physicalBoard)) return 0;
+    }
+    //Do the capture
+    int capture = m_gameInfo->captureType(),i = 0,kalahIndex;
+    int countCaptureIndex = -1,seriesCaptureIndex = -1;
+    bool captureAllowed;
+    int timerCount;
+
+    if(capture & 1) i++;    //cross capture is at capture_info[0]
+    if(capture & 2) countCaptureIndex = i++;
+    if(capture & 4) seriesCaptureIndex = i++;
+
+    //If no count capture, then no series capture also
+    if(countCaptureIndex == -1){
+        return 0;
+    }
+    else{
+        //At this point we know count captue is allowed in this game
+        captureAllowed = false;
+
+        //we will check whether capture is allowed in this position. For example, game supports
+        //capture at the opponent, but current last stone is on own cup, so no capture
+        if( ( !( (m_humanTurn == false && isHumanCup(index) == false) || (m_humanTurn && isHumanCup(index) ) )
+            && ( m_captureInfo[countCaptureIndex].first == GameInfo::OPPONENT ||
+                 m_captureInfo[countCaptureIndex].first == GameInfo::BOTH ) )
+            ||
+                    ( ( ( m_humanTurn && isHumanCup(index) ) || (!m_humanTurn && !isHumanCup(index) ) )
+                      && (m_captureInfo[countCaptureIndex].first == GameInfo::OWN ||
+                          m_captureInfo[countCaptureIndex].first == GameInfo::BOTH ) ) )
+        {
+            captureAllowed = true;
+            timerCount = 0;
+        }
+
+        while(captureAllowed){
+
+            //if capture allowed and stone Number matched at the cup, then we will capture
+            if(stoneNumberMatched(index,countCaptureIndex,board)){
+                timerCount++;
+
+//                if(m_physicalMoveAllowed) kDebug() << "count capture allowed";
+                if(m_humanTurn) kalahIndex = m_humanKalah;
+                else kalahIndex = 1 - m_humanKalah;
+
+                QString strIndex = QString("%1,%2").arg(index).arg(kalahIndex);
+
+                //Animation part
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "str: " << strIndex;
+
+                    QTimer* timer = new QTimer(this);
+                    signalMapper = new QSignalMapper(this);
+
+                    connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+                    signalMapper->setMapping(timer,strIndex);
+                    connect(signalMapper,SIGNAL(mapped(const QString&)),this,SIGNAL(timeout(const QString&)));
+
+                    connect(this,SIGNAL(timeout(const QString&)),this,SLOT(countCapture(const QString&)));
+                    timer->setSingleShot(true);
+                    timer->start(timerCount * 1500);
+                }
+                else countCapture(strIndex);
+
+            }
+            else break;
+
+            //Get Index of the next cup
+            if(seriesCaptureIndex != -1){
+                index = nextIndex(index,seriesCaptureIndex);
+//                if(m_physicalMoveAllowed) kDebug() << "Next Cup Index: " << index;
+            }
+            else break;
+
+            //if at my own side but capture is only allowed at the opponent
+            if( ( ( ( m_humanTurn && isHumanCup(index)) || (!m_humanTurn && !isHumanCup(index) ) )
+                && m_captureInfo[countCaptureIndex].first == GameInfo::OPPONENT )
+                    ||
+            //Or at my opponent side, but capture is allowed only at my own side
+                    ( ( ( m_humanTurn && !isHumanCup(index) ) || ( !m_humanTurn && isHumanCup(index) ) )
+                && m_captureInfo[countCaptureIndex].first == GameInfo::OWN  ) )
+                    captureAllowed = false;
+        }
+
+    }
+    return timerCount;
+
+}
+
+//do the capture
+void GameController::countCapture(const QString& indexString){
+
+    if(isGameOver(m_physicalBoard)) return;
+
+    QList<int> board;
+    QStringList list;
+    int index,kalahIndex;
+
+    list = indexString.split(',');
+    index = list[0].toInt();
+    kalahIndex = list[1].toInt();
+
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    if(m_physicalMoveAllowed) m_board->updateChildren(index,kalahIndex,board[index]);
+    board[kalahIndex + 2*m_gameInfo->numCupsPerRow()] += board[index];
+
+    if(m_physicalMoveAllowed){
+        if(m_humanTurn) changeScore(board[index],true);
+        else changeScore(board[index],false);
+    }
+
+    board[index] = 0;
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+}
+
+bool GameController::stoneNumberMatched(int index,int countCaptureIndex,QList<int>& board){
+    //numbered
+    if( m_captureInfo[countCaptureIndex].second[0] == GameInfo::NUMBER){
+        //Check whether the cup has necessary stone to capture
+        for(int i = 1; i<m_captureInfo[countCaptureIndex].second.count();i++){
+            if(m_captureInfo[countCaptureIndex].second[i] == board[index]){
+//                if(m_physicalMoveAllowed) kDebug() << "Index: " << index << " Stone:" << board[index];
+                return true;
+            }
+        }
+//        if(m_physicalMoveAllowed) kDebug() << "Returning false";
+        return false;
+    }
+    //pattern
+    else{
+//        if(m_physicalMoveAllowed) kDebug() << "I am in pattern";
+        //Even Pattern
+        if(m_captureInfo[countCaptureIndex].second[1] == GameInfo::EVEN){
+            if( board[index] % 2 == 0 && board[index] != 0){
+//                if(m_physicalMoveAllowed) kDebug() << "Index: " << index << " Stone:" << board[index];
+                return true;
+            }
+        }
+        //Odd Pattern
+        else{
+            if(board[index] % 2)
+                return true;
+        }
+
+        return false;
+    }
+}
+
+
+int GameController::nextIndex(int index,int seriesCaptureIndex){
+    //We have to go back
+
+    if(m_captureInfo[seriesCaptureIndex].second[0] == GameInfo::FOLLOWING){
+
+        if(m_rotationInfo == GameInfo::CLOCKWISE){
+            if(index == 0){
+                index = 2 * m_gameInfo->numCupsPerRow() - 1;
+                return index;
+            }
+
+            else{
+                index = index-1;
+                return index;
+            }
+        }
+        else{
+            index = (index+1) % ( 2 * m_gameInfo->numCupsPerRow() );
+            return index;
+        }
+    }
+    //we will go forward
+    else{
+
+        if(m_rotationInfo == GameInfo::CLOCKWISE){
+            index = (index + 1) % ( 2 * m_gameInfo->numCupsPerRow() );
+            return index;
+        }
+
+        else{
+            if(index == 0){
+                index = 2 * m_gameInfo->numCupsPerRow() - 1;
+                return index;
+            }
+            else{
+                index = index - 1;
+                return index;
+            }
+        }
+    }
+}
+
+//-------------------------------------capture handling ends---------------------------
+
+void GameController::changeScore(int amount,bool human){
+    if(human){
+        m_humanScore->changeScore(amount);
+        emit signalShowScore(m_humanScore->score(),true);
+    }
+    else{
+        m_computerScore->changeScore(amount);
+        emit signalShowScore(m_computerScore->score(),false);
+    }
+}
+
+//Human Has no move, now what
+void GameController::humanHasNoMove(){
+
+    if(m_gameOver) return;
+    int check = m_gameInfo->specialFlag();
+    if(m_physicalMoveAllowed) emit signalMessage( tr("No Move human") );
+
+    if( check & 2){//turn passing
+        if(m_physicalMoveAllowed) changeTurn();
+        else m_humanTurn = !m_humanTurn;
+
+        if(m_physicalMoveAllowed) makeComputerMove();
+    }
+    else{
+        if(m_physicalMoveAllowed) finalCapture(m_physicalBoard);
+        else finalCapture(m_logicalBoard);
+    }
+}
+
+//computer has no move, now what
+void GameController::computerHasNoMove(){
+    // Special Flag - 0(empty Opponent),1(turn Passing),2(Compulsory Moves)
+    if(m_gameOver) return;
+    int check = m_gameInfo->specialFlag();
+    if(m_physicalMoveAllowed) emit signalMessage( tr("No Move Computer") );
+
+    if( check & 2){//turn passing
+        if(m_physicalMoveAllowed) changeTurn();
+        else m_humanTurn = !m_humanTurn;
+    }
+    else{
+        if(m_physicalMoveAllowed) finalCapture(m_physicalBoard);
+        else finalCapture(m_logicalBoard);
+    }
+}
+
+//when one has no move, this is called on condition
+void GameController::finalCapture(QList<int>& board){
+
+    int loop;
+
+    //capture from human side to humanKalah
+    for( int i = 0 ; i < m_humanSideCups.count() ; i++){
+        int index = m_humanSideCups[i];
+
+        //Going to Human Kalah
+        if(board[index]){
+            loop = board[index];
+            for(int i = 0 ; i < loop ; i++){
+                if(m_physicalMoveAllowed) m_board->updateChildren(index,m_humanKalah,false);
+                board[index]--;
+                board[m_humanKalah + 2*m_gameInfo->numCupsPerRow()]++;
+                if(m_physicalMoveAllowed) changeScore(1,true);
+            }
+        }
+        //Going to Computer kalah
+        if(board[2*m_gameInfo->numCupsPerRow() - 1 - index]){
+            loop = board[2*m_gameInfo->numCupsPerRow() - 1 - index];
+            for(int i = 0 ; i < loop ; i++){
+                if(m_physicalMoveAllowed)  m_board->updateChildren(2*m_gameInfo->numCupsPerRow() - 1 - index,1-m_humanKalah,false);
+                board[2*m_gameInfo->numCupsPerRow() - 1 - index]--;
+                board[1-m_humanKalah + 2*m_gameInfo->numCupsPerRow()]++;
+                if(m_physicalMoveAllowed) changeScore(1,false);
+            }
+        }
+
+    }
+
+    if(m_physicalMoveAllowed){
+        m_gameOver = true;
+        emit signalGameOver();
+    }
+}
+
+//----------------------------------------------------------------------------------------
+
+
+QPair< bool,QList<int> > GameController::logicalMoveController(QList<int>board,int index,bool turn){
+
+    bool tempTurn = m_humanTurn; //storing turn of physical board
+    m_physicalMoveAllowed = false; //setting physical move as invalid
+
+    bool humanTurn = !turn; //next turn should be other(if not bonus move)
+    m_humanTurn = turn;    //current board status, turn of parent node
+    setLogicalBoard(board);
+
+    //sowing
+    index = singleSow(index);
+
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE){
+        while(!isEndOfLap(index,m_logicalBoard)){
+            index = singleSow(index);
+        }
+    }
+
+
+    //If bonus turn do not change turn
+    if(m_gameInfo->isBonusTurn()){
+
+        if(index >= 2*m_gameInfo->numCupsPerRow()){   //is a kalah
+            //kDebug() << "A Bonus Turn:";
+            if(m_humanTurn && isHumanKalah(index)){
+                humanTurn = true;
+            }
+            else if(!m_humanTurn && !isHumanKalah(index)){
+                humanTurn = false;
+            }
+
+        }
+    }
+
+    handleCrossCapture(index,m_logicalBoard);
+    handleCountNSeriesCapture(index,m_logicalBoard);
+
+    if(isHumanSideEmpty(m_logicalBoard))
+        humanHasNoMove();
+    else if(isComputerSideEmpty(m_logicalBoard))
+        computerHasNoMove();
+
+    m_humanTurn = tempTurn; //restoring m_humanTurn
+    m_physicalMoveAllowed = true;
+    return qMakePair(humanTurn,m_logicalBoard);
+
+}
+
+void GameController::setPhysicalBoard(QList<int> board){
+    for(int i = 0 ; i < m_physicalBoard.count() ; i++)
+        m_physicalBoard[i] = board[i];
+}
+
+
+void GameController::setLogicalBoard(QList<int> board){
+    for(int i = 0 ; i < m_logicalBoard.count() ; i++)
+        m_logicalBoard[i] = board[i];
+}
+
+QList<int> GameController::logicalBoard(){ return m_logicalBoard;}
+QList<int> GameController::physicalBoard(){return m_physicalBoard;}
+
+//----------------------------------------------------------------------------------------
+#include "moc_GameController.cpp"
diff --git a/src/GameController.h b/src/GameController.h
new file mode 100644 (file)
index 0000000..06c09f8
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GAMECONTROLLER_H
+#define GAMECONTROLLER_H
+
+#include <QPair>
+#include <QList>
+
+// #include <kxmlguiwindow.h>
+
+#include <QSignalMapper>
+#include <QThread>
+
+#include "GameInfo.h"
+
+
+class Board;
+class Score;
+class MoveGenerator;
+
+class GameController : public QThread{
+
+    Q_OBJECT
+public:
+    enum Side{UPPER,LOWER};
+    enum Difficulty{EASY,MEDIUM,HARD};
+
+    GameController(GameInfo*);
+
+    void setBoardItem(Board* board);
+    void initializeGameController();
+    int humanKalahIndex(){ return m_humanKalah; }
+    QPair< bool,QList<int> > logicalMoveController(QList<int>board,int cupIndex,bool turn);
+
+signals:
+    void signalShowScore(int,bool);   //score,whose
+    void signalShowTurn(bool);
+    void signalMessage(const QString);
+    void signalGameOver();
+    void timeout(int);
+    void timeout(const QString&);
+    void signalSowMaker(int index);
+    void signalAfterSow(int index);
+    void signalComputerMove();
+
+    void signalNewGame(int);
+    void signalRestartGame();
+
+public slots:
+    void slotMouseClicked(int);
+    void slotGameOverForNewGame(int );
+    void slotGameOverForRestartGame();
+    void newGameEmitter(int);
+    void restartGameEmitter();
+
+    void makeHumanMove(int);
+    void makeComputerMove();
+    void crossCapture(const QString&);
+    void countCapture(const QString&);
+    void slotGameDifficulty(GameController::Difficulty difficulty);
+    void sowMaker(int index);
+    void sowController();
+    void afterSow(int index);
+
+private:
+    QSignalMapper *signalMapper;
+
+    int m_index;
+    int m_rotationInfo;
+    bool m_multipleLapDelay;
+
+    Difficulty m_gameDifficulty;
+    Board* m_board;
+    GameInfo* m_gameInfo;
+    Score* m_humanScore;
+    Score* m_computerScore;
+    Side m_humanSide;
+    MoveGenerator *m_moveGenerator;
+
+    int m_humanKalah;
+    bool m_humanTurn;
+    bool m_gamePaused;
+    bool m_gameOver;
+    bool m_physicalMoveAllowed; //Will be used to check invalid move
+    int m_cupIndexClicked;
+
+    //totalStone - first 2*cupPerRow(0,..) will be cupInfo, next 2 KalahInfo(left,right)
+    QList<int> m_logicalBoard;
+    QList<int> m_physicalBoard;
+    QList<QPair< GameInfo::Side,QList<int> > > m_captureInfo;
+    QList<int>m_humanSideCups;
+
+    void setPhysicalBoard(QList<int> board);
+    void setLogicalBoard(QList<int> board);
+    QList<int> physicalBoard();
+    QList<int> logicalBoard();
+
+    void initializeBoard();
+    void setHumanSideCups();
+
+    bool isHumanCup(int index);
+    bool isHumanKalah(int index);
+    bool isGameOver(QList<int>& board);
+
+    void handleCrossCapture(int,QList<int>& board);
+    int handleCountNSeriesCapture(int,QList<int>& board);
+    int nextIndex(int index,int seriesCaptureIndex);
+    bool stoneNumberMatched(int index,int countCaptureIndex,QList<int>& board);
+
+    void changeTurn();
+    void showBoard(QList<int>&);
+    void changeScore(int amount,bool human);
+
+    bool isHumanSideEmpty(QList<int>& board);
+    bool isComputerSideEmpty(QList<int>& board);
+    void computerHasNoMove();
+    void humanHasNoMove();
+    void finalCapture(QList<int>& board);
+    void sowingAnimation(int index,int multiplier);
+    int singleSow(int index);
+
+    bool physicalMoveController(int index);
+    bool isEndOfLap(int index,QList<int>& board);
+
+};
+
+
+#endif // GAMECONTROLLER_H
diff --git a/src/GameInfo.cpp b/src/GameInfo.cpp
new file mode 100644 (file)
index 0000000..052df1c
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "GameInfo.h"
+
+#include <math.h>
+#include <QFile>
+#include <QStringList>
+// #include <kdebug.h>
+// #include <kstandarddirs.h>
+
+
+
+GameInfo::GameInfo(){
+
+    initializeAll();
+
+}
+
+void GameInfo::initializeAll(){
+
+    //making all list empty
+    m_capture_types = 0;
+    while(m_capture_info.count())
+        m_capture_info.pop_front();
+    while(m_rotation_cup.count())
+        m_rotation_cup.pop_front();
+
+}
+
+void GameInfo::setGameInfo(QString file){
+
+    QString fileName = QString("/opt/mancala/data/rules/%1.xml").arg(file);
+//    kDebug() << "The GameInfo File Name: " << fileName;
+    if(fileName.isEmpty()) return;
+
+    QFile infoFile(fileName);
+    if (!infoFile.open(QFile::ReadOnly | QFile::Text)) return;
+    parseXmlFile(&infoFile);
+
+}
+
+//The parsing operation will be here
+void GameInfo::parseXmlFile(QIODevice *device){
+
+    //kDebug() << "Starting of setGameInfo: " ;
+    setDevice(device);
+
+
+    while(!atEnd()){
+        readNext();
+
+        if(isStartElement()){
+
+            if(name() == "game"){
+                parseGame();
+            }
+            else raiseError(QObject::tr("This is not the exact file Needed"));
+        }
+    }
+
+    //kDebug() << "Region: " << m_region;
+    //kDebug() << "Game Type: " << m_type;
+
+    //kDebug() << "Row Number " << m_num_rows;
+    //kDebug() << "Cup Per Row " << m_cups_per_row;
+    //kDebug() << "Kalah Number " << m_num_kalahs;
+    //kDebug() << "Initial Stone Per Row " << m_initial_stones_per_cup;
+
+    //kDebug() << "Sowing Information: --------------";
+    //kDebug() << "Minimum stone to sow:" << m_min_stones_to_sow;
+    //kDebug() << "Left Stone to Cup:" << m_left_stone_to_cup;
+    //kDebug() << "Omit Initial Cup:" << m_omit_initial_cup;
+    //kDebug() << "stones to kalah:" << m_stones_to_kalah;
+    //kDebug() << "Bonus Turn" << m_bonus_turn;
+
+//    kDebug() << "Capture types: " << m_capture_types;
+
+}
+
+void GameInfo::parseGame(){
+
+    Q_ASSERT(isStartElement() && name() == "game");
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement())
+            break;
+
+        if(isStartElement()){
+
+            if(name() == "type"){
+                QString typeString = readElementText();
+                if(typeString == "modern")
+                    m_type = MODERN;
+                else if(typeString == "traditional")
+                    m_type = TRADITIONAL;
+                else m_type = CUSTOM;
+            }
+            else if( name() == "region")
+                m_region = readElementText();
+            else if( name() == "board")
+                parseBoard();
+            //Other Elements will be here
+            else if(name() == "rules")
+                parseRules();
+            else {
+                // kDebug() << "Option that is not still handled";
+            }
+        }
+    }
+
+}
+
+void GameInfo::parseBoard(){
+
+    //kDebug() << " I am here to parseBoard() ";
+    //kDebug() << "Name is: " << name();
+
+    Q_ASSERT(isStartElement() && name() == "board");
+
+    while(!atEnd()){
+        readNext();
+
+        //kDebug() << "Name is: " << name();
+        if(isEndElement())
+            break;
+        if(isStartElement()){
+
+            if(name() == "row_number"){
+                m_num_rows = readElementText().toInt();
+            }
+
+            else if(name() == "cup_per_row"){
+                m_cups_per_row = readElementText().toInt();
+            }
+
+            else if(name() == "kalah_number"){
+                m_num_kalahs = readElementText().toInt();
+            }
+
+            else if(name() == "initial_stone_number"){
+                m_initial_stones_per_cup = readElementText().toInt();
+            }
+            else {
+                // kDebug() << "Option that is not still handled";
+            }
+        }
+    }
+
+    //setCupRotation (default anticlockwise)
+    for(int i = 0 ; i < m_num_rows * m_cups_per_row ; i++){
+        m_rotation_cup << GameInfo::ANTICLOCKWISE;
+        ////kDebug() << "Cup: " << i << " rotation: " << m_rotation_cup[i];
+    }
+
+}
+
+void GameInfo::parseRules(){
+
+    Q_ASSERT( isStartElement() && name() == "rules");
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            if(name() == "sowing")
+                parseSowing();
+            else if(name() == "capture")
+                parseCapture();
+            else if(name() == "end_rule")
+                parseEndRules();
+            else if( name() == "special_rules")
+                parseSpecialRules();
+            else {
+                // kDebug() << "Option that is not still handled";
+            }
+        }
+    }
+
+}
+
+void GameInfo::parseSowing(){
+
+    Q_ASSERT( isStartElement() && name() == "sowing");
+
+    //kDebug() << "I am here to parseSowing()";
+
+    //kDebug() << "Name is: " << name();
+
+    while(!atEnd()){
+        readNext();
+
+        //kDebug() << "Name is: " << name();
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            if(name() == "rotation"){
+
+                //kDebug() << "found Rotation";
+
+                if(attributes().value("id") == "complicated"){
+                    //kDebug() << "Attribute value: " << "complicated";
+                }
+                else if(attributes().value("id") == "anticlockwise"){
+                    //kDebug() << "Attribute value: " << "anticlockwise";
+                    m_rotation_type = GameInfo::ANTICLOCKWISE;
+                }
+                else{
+                    m_rotation_type = GameInfo::CLOCKWISE;
+                    //kDebug() << "Attribute value: " << "clockwise";
+                    //set Cup Rotation Info - clockwise
+                    for(int i = 0 ; i < m_num_rows * m_cups_per_row ; i++)
+                        m_rotation_cup << GameInfo::ANTICLOCKWISE;
+                }
+                parseRotation();
+            }
+
+            else if( name() == "lap" ){
+
+                //kDebug() << "found lap -----------";
+                if(attributes().value("id") == "single"){
+                    m_lap_style = GameInfo::SINGLE;
+                    //kDebug() << "single Lap";
+                }
+
+                else if(attributes().value("id") == "multiple"){
+                    //kDebug() << "lap Style:" << "multiple";
+                    m_lap_style = GameInfo::MULTIPLE;
+                }
+                parseLap();
+            }
+
+            else if( name() == "min_stone_to_sow" )
+                m_min_stones_to_sow = readElementText().toInt();
+
+            else if( name() == "left_stone_to_cup" )
+                m_left_stone_to_cup = readElementText().toInt();
+
+            else if( name() == "omit_initial_cup" ){
+                if(readElementText() == "yes")
+                    m_omit_initial_cup = true;
+                else m_omit_initial_cup = false;
+            }
+
+            else if( name() == "stones_to_kalah"){
+
+                //If it is necessary that readElementText() will be used more than once then
+                //assign it to a QString
+                QString valueText = readElementText();
+                //kDebug() << "The valueText is: " << valueText;
+
+                if( valueText == "none")
+                    m_stones_to_kalah = GameInfo::NONE;
+                else if( valueText == "both" )
+                    m_stones_to_kalah = GameInfo::BOTH;
+                else if( valueText == "own" )
+                    m_stones_to_kalah = GameInfo::OWN;
+                else if( valueText == "opponent")
+                    m_stones_to_kalah = GameInfo::OPPONENT;
+            }
+            else if(name() == "bonus_turn"){
+
+                if(readElementText() == "yes"){
+                    //kDebug() << "Bonus Turn True";
+                    m_bonus_turn = true;
+                }
+                else m_bonus_turn = false;
+            }
+        }
+
+    }
+}
+
+//capture
+void GameInfo::parseCapture(){
+
+    Q_ASSERT(isStartElement() && name() == "capture");
+
+    //kDebug() << "I am in capture";
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+
+        if(isStartElement()){
+
+            if( name() == "capture_type"){
+
+                if(attributes().value("id") == "cross"){
+                    //kDebug() << "Caputure type: cross :" << m_capture_types;
+                    m_capture_types |= 1;
+                    //kDebug() << "Capture types: " << m_capture_types;
+                    parseCrossCapture();
+                    //kDebug() << "Capture types: " << m_capture_types;
+                }
+                else if(attributes().value("id") == "count"){
+                    m_capture_types |= 2;
+                    parseCountCapture();
+                }
+                else if(attributes().value("id") == "series"){
+                    m_capture_types |= 4;
+                    parseSeriesCapture();
+                }
+                else if(attributes().value("id") == "pull_across"){
+                    m_capture_types |= 16;
+                    parsePullAcrossCapture();
+                }
+            }
+        }
+    }
+
+}
+
+//special rules
+void GameInfo::parseSpecialRules(){
+
+    Q_ASSERT(isStartElement() && name() == "special_rules");
+
+    //kDebug() << "I am in special rules";
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        m_special_flags = 0;
+        if(isStartElement()){
+
+            if( name() == "empty_opponent" ){
+                if( readElementText() == "yes")
+                    m_special_flags |= 1;
+                //kDebug() << "empty Opponent:" << (m_special_flags & 1);
+            }
+            else if( name() == "turn_passing" ){
+                if(readElementText() == "yes")
+                    m_special_flags |= 2;
+                //kDebug() << "Turn Passing:" << (m_special_flags & 2);
+            }
+            else if( name() == "compulsory_move" ){
+                if(readElementText() == "yes")
+                    m_special_flags |= 4;
+                //kDebug() << "Compulsory Moves:" << (m_special_flags & 4);
+            }
+        }
+
+    }
+    //kDebug() << "Special_Flags" << (m_special_flags & 1) << " " << (m_special_flags & 2) << " " << (m_special_flags & 4);
+}
+
+
+//end_rule
+void GameInfo::parseEndRules(){
+
+}
+
+//lap
+void GameInfo::parseLap(){
+
+    Q_ASSERT( isStartElement() && name() == "lap");
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            if( name() == "end_of_lap" && attributes().value("id") == "cup"){
+                //kDebug() << "Found cup in end_of_lap";
+                parseLapEnd();
+            }
+        }
+
+    }
+}
+
+//lap_end
+void GameInfo::parseLapEnd(){
+
+    Q_ASSERT( isStartElement() && name() == "end_of_lap" );
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            if( name() == "stone_no"){
+                m_stones_to_end_lap = readElementText().toInt();
+                //kDebug() << "Stone in cup to end lap: " << m_stones_to_end_lap;
+            }
+
+            else if( name() == "side"){
+                QString valueText = readElementText();
+                //kDebug() << "lap end side: " << valueText;
+
+                if( valueText == "both")
+                    m_side_to_end_lap = GameInfo::BOTH;
+                else if( valueText == "own")
+                    m_side_to_end_lap = GameInfo::OWN;
+                else
+                    m_side_to_end_lap = GameInfo::OPPONENT;
+            }
+        }
+    }
+}
+
+//rotation - complicated
+void GameInfo::parseRotation(){
+
+    Q_ASSERT( isStartElement() && name() == "rotation" );
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            if( name() == "clockwise"){
+
+                int upper,j,lower;
+                int numCup;// = readElementText().toInt();
+
+                if(attributes().value("direction") == "left"){
+                    numCup = readElementText().toInt();
+
+                    upper = m_cups_per_row -1 ;
+                    lower = 2 * m_cups_per_row -1;
+
+                    for(j = 0 ; j < numCup ; ++j,--upper,--lower )
+                        m_rotation_cup[upper] = m_rotation_cup[lower] = GameInfo::CLOCKWISE;
+
+
+                }
+                else{
+                    numCup = readElementText().toInt();
+
+                    upper = 0;
+                    lower = m_cups_per_row;
+
+                    for( j = 0 ; j < numCup; ++j,++upper,++lower)
+                        m_rotation_cup[upper] = m_rotation_cup[lower] = GameInfo::CLOCKWISE;
+                }
+            }
+
+            //            kDebug() << "All cup rotation type:";
+            //            for( int i = 0 ; i < m_cups_per_row * m_num_rows ; i++ ){
+            //                kDebug() << "Cup: " << i << m_rotation_cup[i];
+            //            }
+
+        }
+    }
+}
+
+//capture parsings - CrossCapture
+void GameInfo::parseCrossCapture(){
+
+    Q_ASSERT( isStartElement() && name() == "capture_type");
+    //kDebug() << "Now in CrossCapture:" << m_capture_types;
+
+    Side captureSide;
+    QList<int>stoneNumbers;
+    QString text;
+    QStringList list;
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+            text = readElementText();
+
+            if( name() == "side"){
+                //kDebug() << "In side: " << text;
+
+                if( text == "own")
+                    captureSide = GameInfo::OWN;
+                else if( text == "opponent")
+                    captureSide = GameInfo::OPPONENT;
+                else if( text =="both")
+                    captureSide = GameInfo::BOTH;
+            }
+            else if( name() == "myside_stone_no"){
+
+                list = text.split(',');
+
+                //kDebug() << "Putting to List:";
+                for( int i = 0 ; i < list.size() ; i++ ){
+                    //kDebug() << list[i].toInt() << " ";
+                    stoneNumbers.append(list[i].toInt());
+                }
+            }
+
+        }
+    }
+
+    //inserting to m_capture_info
+    m_capture_info.append( qMakePair(captureSide,stoneNumbers) );
+    //kDebug() << "Side:" << m_capture_info[0].first << " stoneNumbers: " << m_capture_info[0].second;
+
+}
+
+void GameInfo::parseCountCapture(){
+
+    Q_ASSERT( isStartElement() && name() == "capture_type");
+
+    //kDebug() << "I am in count capture";
+
+    Side captureSide;
+    QString text;
+    QList<int>stoneNumbers;
+    QStringList list;
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+        if(isStartElement()){
+
+            text = readElementText();
+
+            if( name() == "side"){
+                //kDebug() << "In side: " << text;
+
+                if( text == "own")
+                    captureSide = GameInfo::OWN;
+                else if( text == "opponent")
+                    captureSide = GameInfo::OPPONENT;
+                else if( text =="both")
+                    captureSide = GameInfo::BOTH;
+            }
+            else if( name() == "stones_in_cup"){
+
+                list = text.split(',');
+
+                if(list[0] == "number"){
+                    stoneNumbers.append(GameInfo::NUMBER);
+
+                    for(int i = 1 ; i < list.size() ; i++){
+                        //kDebug() << list[i].toInt() << " ";
+                        stoneNumbers.append(list[i].toInt());
+                    }
+                }
+                else if(list[0] == "pattern"){
+
+                    stoneNumbers.append(GameInfo::PATTERN);
+
+                    if(list[1] == "even")
+                        stoneNumbers.append(GameInfo::EVEN);
+                    else if(list[1] == "odd")
+                        stoneNumbers.append(GameInfo::ODD);
+                }
+
+            }
+
+        }
+
+    }
+
+    //(side,countCaptureType(pattern or specific),stone numbers or pattern)
+    m_capture_info.append( qMakePair(captureSide,stoneNumbers) );
+    //kDebug() << "Side:" << m_capture_info[0].first << " stoneNumbers: " << m_capture_info[0].second;
+}
+
+void GameInfo::parseSeriesCapture(){
+
+    Q_ASSERT( isStartElement() && name() == "capture_type");
+    //kDebug() << "I am in series capture";
+
+    Side captureSide;
+    QList<int>stoneNumbers;//0-direction,1-grandslam option
+    QString text;
+
+    //kDebug() << "StoneNumbers Now: " << stoneNumbers;
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+        if(isStartElement()){
+
+            text = readElementText();
+
+            if( name() == "side"){
+                //kDebug() << "In side: " << text;
+
+                if( text == "own")
+                    captureSide = GameInfo::OWN;
+                else if( text == "opponent")
+                    captureSide = GameInfo::OPPONENT;
+                else if( text =="both")
+                    captureSide = GameInfo::BOTH;
+            }
+            else if( name() == "direction"){
+                if(text == "following") //0
+                    stoneNumbers.append(GameInfo::FOLLOWING);
+                else if(text == "preceding") //1
+                    stoneNumbers.append(GameInfo::PRECEDING);
+
+            }
+            else if( name() == "grandslam"){
+
+                if(text == "penalty")
+                    stoneNumbers.append(GameInfo::PENALTY);
+                else if(text == "capture")
+                    stoneNumbers.append(GameInfo::CAPTURE);
+                else if(text == "no_capture")
+                    stoneNumbers.append(GameInfo::NO_CAPTURE);
+                else stoneNumbers.append(GameInfo::INVALID);
+            }
+        }
+
+    }
+    //kDebug() << "stoneNumbers Now:" << stoneNumbers;
+    m_capture_info.append( qMakePair(captureSide,stoneNumbers) );
+    //kDebug() << "Side:" << m_capture_info[1].first << " direction " << m_capture_info[1].second;
+}
+
+
+void GameInfo::parsePullAcrossCapture(){
+
+    Q_ASSERT( isStartElement() && name() == "capture_type");
+
+    while(!atEnd()){
+        readNext();
+
+        if(isEndElement()) break;
+
+        if(isStartElement()){
+
+        }
+    }
+
+}
diff --git a/src/GameInfo.h b/src/GameInfo.h
new file mode 100644 (file)
index 0000000..7b06a65
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GAMEINFO_H
+#define GAMEINFO_H
+
+#include <QXmlStreamReader>
+#include <QList>
+#include <QPair>
+
+//Store the necessary info of game. For example, num of rows, cup per row, num of stone
+//initially etc.
+
+class GameInfo : public QXmlStreamReader{
+    public:
+        GameInfo();
+        ~GameInfo();
+//enums
+        enum Rotation{ CLOCKWISE,ANTICLOCKWISE,COMPLICATED };
+        //PUlll Across - captured pieces statrs from player's side(omweso)
+        enum Capture{ CROSS,COUNT,SERIES,PULL_ACCROSS };
+        enum Side{ NONE,OWN,OPPONENT,BOTH };
+        enum Lap{ SINGLE, MULTIPLE, PUSSA_KANAWA};
+        enum GameType{TRADITIONAL,MODERN,CUSTOM};
+        enum CountCapture{NUMBER,PATTERN};
+        enum SeriesCapture{ FOLLOWING,PRECEDING};
+        enum GrandSlam{ INVALID,NO_CAPTURE,CAPTURE,PENALTY };
+        enum WinCondition{ TOTAL_STONE,DISABLING_OPPONENT,GOING_EMPTY };
+        enum Pattern{EVEN,ODD};
+        enum Direction{LEFT,RIGHT};
+
+//functions
+        void initializeAll();
+
+        int numCupsPerRow() const{ return m_cups_per_row; }
+        int numRows() const{ return m_num_rows; }
+        int numKalahs() const{ return m_num_kalahs; }
+        int initialStonesPerCup() const{ return m_initial_stones_per_cup; }
+        int stones() const{ return m_initial_stones_per_cup * m_num_rows * m_cups_per_row;}
+        Rotation rotationType() const{ return m_rotation_type;}
+        int stonesToKalah() const{ return m_stones_to_kalah;}
+        int leftToCup() const{ return m_left_stone_to_cup;}
+        bool omitCup() const{return m_omit_initial_cup;}
+        int lapStyle() const{ return m_lap_style;}
+        int stonesToEndLap() const{ return m_stones_to_end_lap;}
+        bool isBonusTurn() const{ return m_bonus_turn;}
+        int specialFlag() const{ return m_special_flags;}
+
+        void setGameInfo(QString file);
+        void parseXmlFile( QIODevice *device );
+        void setLogicalBoard();
+
+        int captureType(){return m_capture_types;}
+        QList< QPair<Side,QList<int> > > captureInfo(){ return m_capture_info;}
+
+        int rotationInfo(int cupIndex){ return m_rotation_cup[cupIndex];}
+
+    protected:
+
+    private:
+
+        GameType m_type;//modern,traditional(default-traditional)
+        QString m_region;
+
+        //Board Info
+        int m_num_rows;
+        int m_cups_per_row;
+        int m_initial_stones_per_cup;
+        int m_num_kalahs; //In kalah,oware 2
+
+        //Game Info
+
+        //sowing
+        Lap m_lap_style;              //which lap style the game follows(default-single)
+        //If game has multiple lap, then it ends if the last stone put in kalah(m_stones_to_kalah is not none)
+        //or it ends in a cup which has some number of stone
+        int m_stones_to_end_lap;      //only for multiple lap
+        Side m_side_to_end_lap;         //on which side the cup should be
+
+        Rotation m_rotation_type;    // In kalah,oware anticlockwise(default-anitclockwise)
+        QList<Rotation>m_rotation_cup; //For Every cup, there will be a rotation type(bechi)
+
+        Side m_sowing_side;     //from whose side sowing starts for a player(default-own)
+        int m_min_stones_to_sow;  //In kalah,oware 1(default-1)
+        bool m_omit_initial_cup;   //Is it necessary to omit cup when sowing(default-false)
+                                    //it may happen when a cup has more than 2*n-1 stones
+                                    //in oware(n->numofcups)
+        int m_left_stone_to_cup;    // 0->empty cup, 1->keep 1 stone at house when sowing and so on(default-0)
+        bool m_bonus_turn;          //Is bonus turn allowed(default-false)
+        Side m_stones_to_kalah;   //default - none
+
+
+        //capture
+        int m_capture_types;  //0th bit-cross, 1st-count, 2nd-series, 3rd-GrandSlam, 4th-PullAcross
+        QList< QPair<Side,QList<int> > > m_capture_info; //For every capture, the stone info in cup
+        //For example in cross capture(kalah) both,1(the stonenumber in the cup where last stone
+        //is put), for count capture(oware) opponent,(GameInfo::NUMBER,2,3)(opponent cup should have 2 or 3 stones to capture)
+        //For series capture(oware) opponent,GameInfo::FOLLOWING
+        //GrandSlam m_grandslam_option;//If a series capture empties the opponent it is called
+        //GrandSlam
+
+        bool m_cup_movement_previously; //needed for bechi when count/series capture (default-false)
+
+
+        //special rules
+        int m_special_flags; // 0th-empty opponent, 1st-turn passing, 2nd-compulsory move
+        //Can you keep your opponent empty(default-true)
+        //Is Turn passing allowed,if no move(default-true)
+        /*Is it must to move, if possible to your opponents pits whe
+        he has no stones to move, so that he can continue(default-false)*/
+
+        //end rules
+        WinCondition m_win_condition;    //1->by total stones in kalah, 2->by disabling opponent to move,
+        //3->by going empty(if he runs out of seeds) default-total
+
+        //Functions
+        void parseGame();
+        void parseBoard();
+        void parseRules();
+        void parseSowing();
+        void parseCapture();
+        void parseSpecialRules();
+        void parseEndRules();
+
+        void parseRotation();
+        void parseLap();
+        void parseLapEnd();
+
+        void parseCrossCapture();
+        void parseCountCapture();
+        void parseSeriesCapture();
+        void parsePullAcrossCapture();
+
+    };
+
+#endif // GAMEINFO_H
diff --git a/src/GraphicsScene.cpp b/src/GraphicsScene.cpp
new file mode 100644 (file)
index 0000000..cf86742
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "GraphicsScene.h"
+
+#include <QGraphicsSceneMouseEvent>
+#include <QSvgRenderer>
+#include <QPainter>
+#include <QWidget>
+
+// #include <kdebug.h>
+// #include <ksvgrenderer.h>
+
+#include "GameInfo.h"
+#include "ThemeManager.h"
+#include "Board.h"
+#include "Stone.h"
+#include "GameController.h"
+#include "MainWindow.h"
+
+GraphicsScene::GraphicsScene(GameInfo *gameInfo,ThemeManager *theme,GameController*
+                             gameController ,QWidget *parent)
+    : QGraphicsScene(parent){
+
+    m_gameInfo = gameInfo;
+    m_gameTheme = theme;
+    m_parent = (MainWindow*)parent;
+    m_gameController = gameController;
+
+    setSceneRect(m_parent->windowRect());
+    setupGameNecessaries();
+
+    connect( this,SIGNAL(signalMouseClicked(int)),
+             m_gameController , SLOT(slotMouseClicked(int)) );
+    connect( m_gameController,SIGNAL(signalRestartGame()),this,SLOT(slotStartGame()));
+
+}
+
+void GraphicsScene::showGameName(){
+
+    qreal posX,posY,width,height,scaleX,scaleY;
+
+    m_gameName = new QGraphicsSvgItem(0);
+    m_gameName->setSharedRenderer(m_gameTheme);
+    m_gameName->setElementId("GameName");
+
+    posX = sceneRect().x() + sceneRect().width() * 0.40; // 0.30
+    posY = sceneRect().y() + sceneRect().height() * 0.05; // 0.10
+    width = 0.20 * sceneRect().width(); // 0.40
+    height = width / 10 ; // 5
+
+    scaleX = width / ( m_gameName->boundingRect().width() );
+    scaleY = height / ( m_gameName->boundingRect().height() ) ;
+    m_gameName->scale(scaleX,scaleY);
+
+    m_gameName->setPos(posX,posY);
+
+    addItem(m_gameName);
+}
+
+
+void GraphicsScene::setupGameNecessaries(){
+
+    // showGameName();
+    m_board = new Board(m_gameInfo, m_gameTheme);
+
+    for( int i = 0; i < m_gameInfo->stones(); i++)
+        m_stones << new Stone(i, m_gameInfo, m_gameTheme, m_board);
+
+    m_board->manipulateStones(m_stones);
+    addItem(m_board);
+
+    //For the first time
+    m_gameController->setBoardItem(m_board);
+
+    renderBackground(sceneRect().size().toSize(),true);
+
+}
+
+void GraphicsScene::deleteGameNecessaries(){
+
+    Stone *stone;
+    // delete m_gameName;
+
+    while(m_stones.count()){
+        stone = m_stones.front();
+        m_stones.pop_front();
+        delete stone;
+    }
+
+    if(m_board != NULL){
+        delete m_board;
+        m_board = NULL;
+    }
+
+}
+
+
+void GraphicsScene::slotStartGame(){
+
+    deleteGameNecessaries();
+    setupGameNecessaries();
+
+    update(sceneRect());
+
+    m_gameController->initializeGameController();
+    m_gameController->setBoardItem(m_board);
+
+}
+
+
+void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event){
+
+    // kDebug() << event->scenePos();
+    int cupIndex = m_board->findCupIndex(event->scenePos());
+    emit signalMouseClicked(cupIndex);
+}
+
+QPixmap GraphicsScene::renderBackground(const QSize& size,bool newGame){
+    QPixmap pix;
+    QString cacheName("BackGround");
+
+    if( !QPixmapCache::find(cacheName, pix) || newGame)
+    {
+        QSvgRenderer* m_renderer = new QSvgRenderer(m_gameTheme->current());
+
+        pix = QPixmap(size);
+        pix.fill(Qt::transparent);
+        QPainter painter(&pix);
+        m_renderer->render( &painter, "BackGround");
+        QPixmapCache::insert(cacheName, pix);
+    }
+
+    return pix;
+}
+
+void GraphicsScene::drawBackground(QPainter* painter, const QRectF &rect){
+
+    QSize size = m_parent->windowRect().size().toSize();
+    painter->drawPixmap( 0, 0, renderBackground( size , false ) );
+
+}
+
diff --git a/src/GraphicsScene.h b/src/GraphicsScene.h
new file mode 100644 (file)
index 0000000..be85acf
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GRAPHICSSCENE_H
+#define GRAPHICSSCENE_H
+
+#include <QGraphicsScene>
+#include <QWheelEvent>
+#include <QPixmap>
+#include <QPixmapCache>
+#include <qmath.h>
+
+
+class GameInfo;
+class ThemeManager;
+class Board;
+class GameController;
+class Stone;
+class QWidget;
+class MainWindow;
+class QGraphicsSvgItem;
+
+class GraphicsScene : public QGraphicsScene{
+    Q_OBJECT
+
+public:
+    GraphicsScene( GameInfo* ,ThemeManager* , GameController* , QWidget* parent = 0);
+    QPixmap renderBackground(const QSize& size,bool newGame);
+
+signals:
+    void signalMouseClicked(int);
+
+public slots:
+    void slotStartGame();
+
+
+private:
+
+    QGraphicsSvgItem *m_gameName;
+    GameInfo* m_gameInfo;
+    GameController* m_gameController;
+    ThemeManager* m_gameTheme;
+    Board* m_board;
+    QList<Stone*> m_stones;
+    MainWindow* m_parent;
+
+    void setupGameNecessaries();
+    void deleteGameNecessaries();
+
+    void showGameName();
+    virtual void mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent );
+    virtual void drawBackground( QPainter* painter,const QRectF &rect);
+};
+
+#endif // GRAPHICSSCENE_H
diff --git a/src/Kalah.cpp b/src/Kalah.cpp
new file mode 100644 (file)
index 0000000..bbe8a06
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Kalah.h"
+
+#include <math.h>
+
+#include <QGraphicsScene>
+#include <QGraphicsSvgItem>
+// #include <kdebug.h>
+
+#include "GameInfo.h"
+#include "Board.h"
+#include "Stone.h"
+
+
+Kalah::Kalah(GameInfo* info, Kalah::side p, QGraphicsSvgItem *parent)
+: QGraphicsSvgItem(parent){
+
+    m_side = p;
+    m_gameInfo = info;
+    m_board = qgraphicsitem_cast<Board*>(parent);
+
+    setSharedRenderer(m_board->renderer());
+    setElementId("kalah");
+    setZValue(2);
+    initialSetup();
+    setupText();
+
+}
+
+
+//The Drawing of Kalah Items
+void Kalah::initialSetup(){
+
+    qreal gapWidth = m_board->boundingRect().width() * ( 0.2 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() + 1 ) );
+
+    m_size.setWidth( m_board->boundingRect().width() * 0.8 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() ) );
+    m_size.setHeight( m_board->boundingRect().height() * 0.8 );
+
+    //kalahWidth and cupWidth are same
+    if(m_side == Left)
+        m_pos.setX( m_board->boundingRect().x() + gapWidth );
+    else m_pos.setX( m_board->boundingRect().x() +  gapWidth + ( gapWidth + m_size.width() ) * ( m_gameInfo->numCupsPerRow() + 1 ) );
+    m_pos.setY( m_board->boundingRect().y() + m_board->boundingRect().height() * 0.1 );
+
+    //scaling the kalah object
+    qreal kalahScaleX = m_size.width() / boundingRect().width();
+    qreal kalahScaleY = m_size.height()/ boundingRect().height();
+
+    m_mid_point.setX( m_pos.x() + m_size.width() / 2 );
+    m_mid_point.setY( m_pos.y() + m_size.height() / 2 );
+
+    setPos(m_pos);
+    scale(kalahScaleX,kalahScaleY);
+}
+
+void Kalah::setupText(){
+
+    m_text = new QGraphicsSimpleTextItem("0",m_board);
+    m_text->setFont( QFont("Comic Sans MS", 24, QFont::Bold) );
+    m_text->setPen(QPen(QColor("darkslateblue"), 1.5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+    QLinearGradient gradient(0, 0, 0, 100);
+    gradient.setColorAt(0.0, "mediumslateblue");
+    gradient.setColorAt(1.0, "cornsilk");
+    m_text->setBrush(gradient);
+
+    int textX = m_pos.x() + m_size.width();
+    textX -= m_text->boundingRect().size().width() + 15;
+
+    int textY =  m_pos.y() + m_size.height();
+    textY -= m_text->boundingRect().size().height() - 15;
+
+    m_text->scale(0.8,0.8);
+    m_text->setPos(textX,textY);
+    m_text->setZValue(4);
+    m_text->setVisible(false);
+}
+
+void Kalah::updateStoneList(Stone* stoneItem){
+
+    //kDebug() << "In Kalah" ;
+    QPointF *stonePos;
+
+    m_text->setVisible(false);
+    m_stone.append(stoneItem);
+
+    //calculate stone postion and place it
+    stonePos = calculateStonePosition(stoneItem);
+    stoneItem->animateStones(QPointF(stonePos->x(),stonePos->y()));
+
+    //we want to change the text showing ball number
+    if( m_stone.count() ){
+
+        m_text->setText( QString("%1").arg(m_stone.count() ) );
+        m_text->setVisible(true);
+
+        update();
+    }
+
+    //kDebug() << "Returning";
+}
+
+
+//calculate stonePostion in Kalah
+QPointF* Kalah::calculateStonePosition(Stone* stone){
+
+    QPointF *returnPoint = new QPointF();
+
+    qreal diameterCup = qMin(m_size.width(),m_size.height());
+
+    int initialLength = qrand() % (int) diameterCup / 3;
+    int angle = qrand() % 360;
+
+    qreal posX = middlePoint().x() + initialLength * cos(angle * M_PI / 180);
+    qreal posY = middlePoint().y() + initialLength * sin(angle * M_PI / 180);
+
+    if( ( posX + stone->size().width()) > ( m_pos.x() + 0.7 * m_size.width() ) )
+        posX -= stone->size().width();
+    else if( posX < ( m_pos.x()+ 0.3 * m_size.width() ) )
+        posX += stone->size().width();
+
+    if( ( posY + stone->size().height() ) > ( m_pos.y() + 0.7 * m_size.height() ) )
+        posY -= stone->size().height();
+    else if( posY < (m_pos.y() + 0.3 < m_size.height() ) )
+        posY += stone->size().height();
+
+    returnPoint->setX(posX);
+    returnPoint->setY(posY);
+
+    return returnPoint;
+}
diff --git a/src/Kalah.h b/src/Kalah.h
new file mode 100644 (file)
index 0000000..1cf264c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KALAH_H
+#define KALAH_H
+
+#include <QtSvg/QGraphicsSvgItem>
+#include <QGraphicsSimpleTextItem>
+
+
+class Board;
+class Stone;
+class GameInfo;
+
+class Kalah : public QGraphicsSvgItem{
+
+    public:
+        enum side{Left, Right};
+
+        Kalah(GameInfo* info, Kalah::side p, QGraphicsSvgItem *parent);
+
+        QPointF* calculateStonePosition(Stone* stone);
+        void updateStoneList(Stone* stoneItem);
+
+        QSizeF size() const{ return m_size;}
+        QPointF position() const{ return m_pos;}
+        QPointF middlePoint() const{ return m_mid_point;}
+        int index() const{ return m_side;}
+
+
+    private:
+        void initialSetup();
+        void setupText();
+
+        QSizeF m_size;
+        QPointF m_mid_point,m_pos;
+        QList <Stone*> m_stone;
+        QGraphicsSimpleTextItem *m_text;
+
+        side m_side;
+        Board *m_board;
+        GameInfo *m_gameInfo;
+};
+
+#endif // KALAH_H
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
new file mode 100644 (file)
index 0000000..52e91e5
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MainWindow.h"
+
+#include <QMainWindow>
+#include <QStatusBar>
+#include <QGraphicsView>
+#include <QFile>
+#include <QPushButton>
+#include <QLabel>
+#include <QAction>
+#include <QtGui>
+#include <QStackedWidget>
+
+//#include <kdebug.h>
+//#include <kaction.h>
+//#include <klocale.h>
+//#include <kactioncollection.h>
+//#include <kstandardaction.h>
+//#include <kapplication.h>
+//#include <kstandarddirs.h>
+//#include <kstatusbar.h>
+//#include <kmenu.h>
+//#include <kstandardgameaction.h>
+//#include <kselectaction.h>
+//#include <kgameclock.h>
+
+#include "ThemeManager.h"
+#include "GameInfo.h"
+#include "GraphicsScene.h"
+#include "settingswidget.h"
+//#include "GraphicsView.h"
+
+MainWindow::MainWindow(QWidget* parent) {
+
+    m_StackedWidget = new QStackedWidget();
+    setWindowTitle("Mancala");
+    setupGame();
+    setupWidgets();
+    setupActions();
+
+}
+
+MainWindow::~MainWindow(){}
+
+void MainWindow::setupGame(){
+
+    //gameInfo
+    setGameName(QString("kalah")) ;
+    m_gameNameId = 0;
+    m_gameInfo = new GameInfo();
+
+    m_gameInfo->setGameInfo(m_gameName);
+
+    //gameTheme
+    QString fileName = QString("/opt/mancala/data/themes/theme_%1.svg").arg(m_gameName);
+    m_gameTheme = new ThemeManager(fileName);
+    m_gameTheme->setTheme(m_gameName);
+
+    //gameController
+    m_gameController = new GameController(m_gameInfo);
+
+}
+
+void MainWindow::setupWidgets(){
+
+    //status bar
+//    statusBar()->insertItem(QString(),4);
+//    statusBar()->insertItem(tr("Turn: your"), 0 );
+//    statusBar()->insertItem(tr( "Human Player: 0"),1 );
+//    statusBar()->insertItem(tr( "Computer: 0"),2);
+
+    settings = new SettingsWidget(this);
+
+    //set to m_gameNameList - we should done it initially
+    reader = new QXmlStreamReader();
+    setGameName();
+    settings->setGameNames(m_gameNameList);
+
+    connect(settings,
+            SIGNAL(start()),
+            this,
+            SLOT(slotStartGame()));
+
+    connect(settings,
+            SIGNAL(levelChanged(int)),
+            this,
+            SLOT(slotChangeDifficulty(int)));
+
+    connect(settings,
+            SIGNAL(gameChanged(int)),
+            this,
+            SLOT(slotChangeGameName(int)));
+
+    m_StackedWidget->addWidget(settings);
+
+    msgLabel = new QLabel();
+    turnLabel = new QLabel("Turn: your");
+    humanScore = new QLabel("Human: 0");
+    aiScore = new QLabel("Computer: 0");
+
+    statusBar()->addWidget(turnLabel);
+    statusBar()->addWidget(msgLabel,1);
+    statusBar()->addWidget(humanScore);
+    statusBar()->addWidget(aiScore);
+
+
+    /*setting up the connections for m_gameTheme and m_gameController with this*/
+    connect(this, SIGNAL( signalLoadTheme()), m_gameTheme, SLOT( slotLoadTheme() ));
+    emit signalLoadTheme();
+    //showScore
+    connect(m_gameController,SIGNAL(signalShowScore(int,bool)),
+            this,SLOT(slotShowScore(int,bool)));
+    //showTurn
+    connect(m_gameController,SIGNAL(signalShowTurn(bool)),this,SLOT(slotShowTurn(bool)));
+    //Message from gameController
+    connect(m_gameController,SIGNAL(signalMessage(QString)),this,SLOT(slotMessage(QString)));
+    connect(m_gameController,SIGNAL(signalGameOver()),this,SLOT(slotShowGameOver()));
+    connect(this,SIGNAL(signalGameDifficulty(GameController::Difficulty)),m_gameController,SLOT(slotGameDifficulty(GameController::Difficulty)));
+
+
+    //GraphicsScene and GraphicsView
+    m_scene = new GraphicsScene(m_gameInfo,m_gameTheme,m_gameController,this);
+    m_view = new QGraphicsView(m_scene, this);
+
+    m_StackedWidget->addWidget(m_view);
+
+    m_StackedWidget->setCurrentIndex(0);
+
+    setCentralWidget(m_StackedWidget);
+
+}
+
+
+
+void MainWindow::setupActions(){
+
+    mainMenu = menuBar()->addMenu("Main");
+
+//    helpAction = new QAction(tr("Help"), this);
+//    connect(helpAction,
+//            SIGNAL(triggered()),
+//            this,
+//            SLOT(help()));
+
+    //New Game KSelectAction ---------------------------
+    // newGameAct = new KSelectAction(i18n("&New Game"),this);
+    // actionCollection()->addAction("new_game",newGameAct);
+
+    restartGameAction = new QAction(tr("restart game"), this);
+
+    connect(restartGameAction,
+            SIGNAL(triggered()),
+            this,
+            SLOT(slotStartGame()));
+
+    mainMenu->addAction(restartGameAction);
+
+    newGameAction = new QAction(tr("new game"), this);
+
+    connect(newGameAction,
+            SIGNAL(triggered()),
+            this,
+            SLOT(slotShowSettings()));
+
+    mainMenu->addAction(newGameAction);
+
+
+    helpAction = new QAction(tr("Help"), this);
+
+    connect(helpAction,
+            SIGNAL(triggered()),
+            this,
+            SLOT(help()));
+
+    mainMenu->addAction(helpAction);
+
+//    //set to m_gameNameList - we should done it initially
+//    reader = new QXmlStreamReader();
+//    setGameName();
+
+//    newGameAct->setItems(m_gameNameList);
+//    newGameAct->setCurrentItem(0);
+    //kDebug() << "Current Text:" << newGameAct->currentText();
+
+//    connect( newGameAct , SIGNAL(triggered(int)),m_gameController, SLOT(slotGameOverForNewGame(int) ) );
+//    connect( m_gameController,SIGNAL(signalNewGame(int)),this,SLOT(newGame(int)));
+
+
+    //Quit Action ------------------
+    // KStandardAction::quit(kapp, SLOT(quit()),  actionCollection());
+
+    // KAction* restartGame = new KAction(this);
+//    restartGame->setText(tr("&Restart Game"));
+//    actionCollection()->addAction("restartgame",restartGame);
+//    connect(restartGame,SIGNAL(triggered(bool)),m_gameController,SLOT(slotGameOverForRestartGame()) );
+
+    // Difficulty
+//    KGameDifficulty::init(this, this, SLOT(slotChangeDifficulty(KGameDifficulty::standardLevel)));
+//    KGameDifficulty::addStandardLevel(KGameDifficulty::Easy);
+//    KGameDifficulty::addStandardLevel(KGameDifficulty::Medium);
+//    KGameDifficulty::addStandardLevel(KGameDifficulty::Hard);
+//    KGameDifficulty::setLevel(KGameDifficulty::Easy);
+
+    // setupGUI();
+}
+
+
+//---------------------parsting starts -------------------------
+
+//ready the file to be parsed by reader
+void MainWindow::setGameName(){
+
+    QString fileName = QString("/opt/mancala/data/gamelist.xml");
+    //kDebug() << "File Name: " << fileName;
+    if(fileName.isEmpty()) return;
+
+    QFile infoFile(fileName);
+    if (!infoFile.open(QFile::ReadOnly | QFile::Text)) return;
+    parseXml(&infoFile);
+
+}
+
+//parse gamelist.xml file
+void MainWindow::parseXml(QIODevice *device){
+
+    reader->setDevice(device);
+
+    while(!reader->atEnd()){
+        reader->readNext();
+
+        if(reader->isStartElement()){
+
+            if(reader->name() == "gamelist")
+                parseNames();
+            else reader->raiseError(QObject::tr("This is not the exact file Needed"));
+        }
+    }
+
+}
+
+//set the names in m_gameNameList
+void MainWindow::parseNames(){
+
+    Q_ASSERT(reader->isStartElement() && reader->name() == "gamelist");
+
+    while(!reader->atEnd()){
+        reader->readNext();
+
+        if(reader->isEndElement())
+            break;
+
+        if(reader->isStartElement()){
+
+            Q_ASSERT( reader->name() == "name");
+            m_gameNameList << reader->readElementText();
+
+        }
+    }
+
+}
+
+//------------------------------ parsing ends ---------------------------
+
+
+
+//------------------------------ slot zone starts -------------------------
+
+//Now working with this
+void MainWindow::newGame(int gameId){
+
+    //kDebug() << "newGame called";
+    qDebug() << "newGame called" << gameId;
+    m_gameName = m_gameNameList[gameId];
+
+    //gameInfo
+    m_gameInfo->initializeAll();
+    m_gameInfo->setGameInfo(m_gameName);
+
+    //gameTheme
+    m_gameTheme->setTheme(m_gameName);
+    emit signalLoadTheme();
+
+    m_scene->slotStartGame();
+}
+
+void MainWindow::slotStartGame(){
+
+    newGame(m_gameNameId);
+
+    m_StackedWidget->setCurrentIndex(1);
+
+    // TODO: this looks nasty, is there no other way?
+    // w/o the gameboard is tiny, just after a resize it adapts!?
+    QSize oldSize = this->size();
+    this->resize(100,100);
+    this->resize(oldSize);
+
+    slotMessage(QString("New game started..."));
+
+}
+
+void MainWindow::slotShowScore(int score,bool human){
+
+    if(human){
+        // statusBar()->changeItem(tr("Human Player: %1",score),1);
+       humanScore->setText(tr("Human: %1").arg(score) );
+    }
+    else{
+        // statusBar()->changeItem(tr("Computer: %1",score),2);
+        aiScore->setText(tr("Computer: %1").arg(score) );
+    }
+}
+
+void MainWindow::slotShowTurn(bool human){
+
+//    if(human)
+//        // statusBar()->changeItem(tr("Turn: your"),0);
+//    else
+//        // statusBar()->changeItem(tr("Turn: computer"),0);
+
+    if(human){
+        turnLabel->setText(tr("Turn: your"));
+    }
+    else{
+        turnLabel->setText(tr("Turn: computer"));
+    }
+}
+
+void MainWindow::slotMessage(QString str){
+
+    // statusBar()->changeItem(str,4);
+    msgLabel->setText(str);
+}
+
+
+void MainWindow::slotPause(){
+
+}
+
+void MainWindow::slotShowGameOver(){
+    slotMessage( tr("Game Over") );
+
+    QTimer::singleShot(2500,this,SLOT(slotShowSettings()));
+}
+
+void MainWindow::slotShowSettings(){
+    m_StackedWidget->setCurrentIndex(0);
+}
+
+//void MainWindow::slotChangeDifficulty(KGameDifficulty::standardLevel level){
+//
+//    switch(level) {
+//
+//        case KGameDifficulty::Easy:
+//            emit signalGameDifficulty(GameController::EASY);
+//            break;
+//        case KGameDifficulty::Medium:
+//            emit signalGameDifficulty(GameController::MEDIUM);
+//            break;
+//        case KGameDifficulty::Hard:
+//            emit signalGameDifficulty(GameController::HARD);
+//            break;
+//    }
+//}
+
+void MainWindow::slotChangeDifficulty(int level){
+
+    switch(level){
+    case Easy:
+        emit signalGameDifficulty(GameController::EASY);
+        qDebug() << "Level: " << level;
+        break;
+    case Medium:
+        emit signalGameDifficulty(GameController::MEDIUM);
+        qDebug() << "Level: " << level;
+        break;
+    case Hard:
+        emit signalGameDifficulty(GameController::HARD);
+        qDebug() << "Level: " << level;
+        break;
+    }
+}
+
+void MainWindow::slotChangeGameName(int game){
+    qDebug() << "slotChangeGameName:" << game;
+    setGameName(m_gameNameList[game]);
+    m_gameNameId = game;
+}
+
+void MainWindow::help(){
+    QDesktopServices::openUrl(QUrl("file:///opt/mancala/data/mancala.html"));
+}
+
+
+//----------------------------- slot zone ends --------------------------
+
+
+void MainWindow::resizeEvent(QResizeEvent *event){
+
+    //We need scroll Bars to Off so that there is no probability of recursing fitInView
+    //m_view->fitInView(QRect(QPoint(0,0), m_scene->sceneRect().size().toSize()), Qt::KeepAspectRatio);
+    m_view->fitInView(QRect(QPoint(0,0), m_scene->sceneRect().size().toSize()));
+    // KXmlGuiWindow::resizeEvent(event);
+
+}
+
+void MainWindow::setGameName(QString gameName){
+    m_gameName = gameName; 
+}
diff --git a/src/MainWindow.h b/src/MainWindow.h
new file mode 100644 (file)
index 0000000..687d047
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtCore>
+#include <QSizeF>
+#include <QRectF>
+#include <QResizeEvent>
+#include <QMainWindow>
+#include <QLabel>
+#include <QAction>
+#include <QStackedWidget>
+
+//#include <kxmlguiwindow.h>
+//#include <kgamedifficulty.h>
+
+#include "GameController.h"
+#include "settingswidget.h"
+
+class GameInfo;
+class ThemeManager;
+class GraphicsScene;
+class GameController;
+class QGraphicsView;
+//class KSelectAction;
+class QXmlStreamReader;
+//class KGameClock;
+
+class MainWindow : public QMainWindow{
+    Q_OBJECT
+
+    public:
+        MainWindow(QWidget *parent = 0);
+        ~MainWindow();
+
+        QString gameName(){ return m_gameName;}
+
+        QRectF windowRect(){ return this->rect();}
+
+        void setGameName(QString gameName);
+
+
+    private slots:
+        void newGame(int gameId);
+        void slotShowScore(int score,bool human);
+        void slotShowTurn(bool);
+        void slotShowGameOver();
+        void slotMessage(QString);
+        void slotPause();
+        // void slotChangeDifficulty(KGameDifficulty::standardLevel);
+        void slotChangeDifficulty(int level);
+        void slotStartGame();
+        void slotShowSettings();
+        void slotChangeGameName(int game);
+        void help();
+
+    signals:
+        void signalLoadTheme();
+        void signalGameDifficulty(GameController::Difficulty);
+
+    protected:
+        void resizeEvent(QResizeEvent *event);
+
+    private:
+        void setupGame();
+        void setupWidgets();
+        void startGame();
+        void setupActions();
+
+
+        void setGameName();
+        void parseXml(QIODevice *device);
+        void parseNames();
+
+        GraphicsScene *m_scene;
+        GameInfo* m_gameInfo;
+        ThemeManager* m_gameTheme;
+        GameController *m_gameController;
+        // KGameClock* m_gameClock;
+
+        QStringList m_gameNameList;
+        QString m_gameName;
+        int m_gameNameId;
+        QGraphicsView *m_view;
+//        GraphicsView* m_view;
+
+        // KSelectAction* newGameAct;
+        QXmlStreamReader *reader;
+
+        QLabel *msgLabel;
+        QLabel *turnLabel;
+        QLabel *humanScore;
+        QLabel *aiScore;
+
+        enum Level {
+            Easy = 0,
+            Medium = 1,
+            Hard = 2
+        };
+
+        QMenu *mainMenu;
+        QMenu *newGameMenu;
+        QAction *newGameAction;
+        QAction *restartGameAction;
+        QAction *helpAction;
+
+        SettingsWidget *settings;
+        QStackedWidget *m_StackedWidget;
+
+    signals:
+        void resized(QSizeF size);
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644 (file)
index ea07efa..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-# GNU Makefile -- Makefile
-# Kevin Riggle
-# 2009 Reto Zingg
-# http://cmancala.sourceforge.net
-# $Source: /cvsroot/cmancala/mancala/src/Attic/Makefile,v $
-# $Revision: 1.10.2.7 $
-# $Date: 2004/01/16 20:49:30 $
-
-# NOTE:  You MUST update /etc/ld.so.conf and rerun ldconfig *or* update
-# the LD_LIBRARY_PATH environment variable to include /usr/local/lib in
-# order to compile with SDL_ttf.
-
-# Linux-dependent right now, modify for platform-independency later
-# is now adapted for maemo (and dh_* scripts)
-
-CC = gcc
-DBG = gdb
-STD = _GNU_SOURCE
-CFLAGS = `sdl-config --cflags` -I/usr/local/include/SDL `pkg-config hildon-1 --cflags` -I/usr/include/dbus-1.0/ -I/usr/lib/dbus-1.0/include/
-LFLAGS = `sdl-config --static-libs ` -lSDL_image -lSDL_ttf -lSDL_mixer `pkg-config hildon-1 --libs` `pkg-config --libs  libosso` -lhgw
-
-# MAIN_OBJ = main.o graphics.o mancala.o sounds.o play.o
-MAIN_OBJ = graphics.o mancala.o sounds.o play.o callbacks.o
-TEST_OBJ = ai-test.o mancala.o
-
-NORMAL = ai.o
-RECURSE = ai-init.o ai-recurse.o
-ULTIMATE = ai-init.o ai-ultimate.o
-
-subsystem:
-       $(MAKE) -C launcher
-       $(MAKE) -C plugin 
-
-#'$<' is filename of input, '$@' is filename of output
-.c.o:
-       $(CC) -c -g$(DBG) -Wall $(CFLAGS) -D$(STD) $<
-.h.o:
-       $(CC) -c -g$(DBG) -Wall $(CFLAGS) -D$(STD) $<
-
-all:           $(MAIN_OBJ) $(NORMAL)
-       $(MAKE) -C launcher all
-       $(MAKE) -C plugin all
-       $(CC) $(MAIN_OBJ) $(NORMAL) $(LFLAGS) -o mancala
-
-recurse:       $(MAIN_OBJ) $(RECURSE)
-       $(CC) $(MAIN_OBJ) $(RECURSE) $(LFLAGS) -o mancala
-
-ultimate:      $(MAIN_OBJ) $(ULTIMATE)
-       $(CC) $(MAIN_OBJ) $(ULTIMATE) $(LFLAGS) -o mancala
-
-ai-test-normal:                $(TEST_OBJ) $(NORMAL)
-       $(CC) $(TEST_OBJ) $(NORMAL) $(LFLAGS) -o ai-test
-
-ai-test-recurse:       $(TEST_OBJ) $(RECURSE)
-       $(CC) $(TEST_OBJ) $(RECURSE) $(LFLAGS) -o ai-test
-
-ai-test-ultimate:      $(TEST_OBJ) $(ULTIMATE)
-       $(CC) $(TEST_OBJ) $(ULTIMATE) $(LFLAGS) -o ai-test
-
-install:       all
-       mkdir -p $(DESTDIR)/home/opt/mancala/bin/
-       cp ./mancala $(DESTDIR)/home/opt/mancala/bin/
-       mkdir -p $(DESTDIR)/home/opt/mancala/data/
-       cp ../data/*.png $(DESTDIR)/home/opt/mancala/data/
-       cp ../data/*.wav $(DESTDIR)/home/opt/mancala/data/
-       cp ../data/*.ttf $(DESTDIR)/home/opt/mancala/data/
-       $(MAKE) -C launcher install
-       $(MAKE) -C plugin install
-
-
-uninstall:
-       rm -rf $(DESTDIR)/home/opt/mancala/
-
-
-clean:
-       rm -f *.o *.core *.swp *~ *.log
-       $(MAKE) -C launcher clean
-       $(MAKE) -C plugin clean
-
-clobber:       clean
-       rm -f mancala ai-test
-       $(MAKE) -C launcher clobber
-       $(MAKE) -C plugin clobber
-
-distclean:     clobber
-       @echo "No configuration files to distclean yet."
-       @echo "I will do my best to make some! ;-)"
-
-# End Makefile
diff --git a/src/MoveGenerator.cpp b/src/MoveGenerator.cpp
new file mode 100644 (file)
index 0000000..d24641b
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "MoveGenerator.h"
+
+// #include <kdebug.h>
+
+#include "GameInfo.h"
+#include "GameController.h"
+
+
+MoveGenerator::MoveGenerator(int gameDifficulty,GameInfo *gameInfo,GameController *gameController){
+
+    m_gameDifficulty = gameDifficulty;
+    m_gameInfo = gameInfo;
+    m_gameController = gameController;
+    m_gameDifficulty = 0;
+
+    //we need to use m_depthList[m_gameDifficulty];
+    m_depthList[0] = 2;
+    m_depthList[1] = 6;
+    m_depthList[2] = 8;
+
+}
+
+int MoveGenerator::bestMove(QList<int> currentState,bool humanTurn){
+
+    // As we are calculating move only for computer player, humanTurn is currently
+    // unused
+    int cupIndex = -1,utility;   //The valid move we want to return
+    int value = -1000;
+
+    //rootNode is a maximizer
+    Node* rootNode = new Node(m_gameInfo);
+    copyBoard(rootNode,currentState);
+    rootNode->setTurn(false);
+    showBoardState(rootNode);
+    QList<Node*> m_possibleMoves;
+    Node* node;
+
+    simulateMoves(rootNode,m_possibleMoves);
+    //kDebug() << "Move simulation ended";
+
+    while(allEvaluations.count())
+        allEvaluations.pop_back();
+    while(allCupIndexes.count())
+        allCupIndexes.pop_back();
+
+
+    while(m_possibleMoves.count()){
+
+        node = m_possibleMoves.front();
+
+        //we have a bonus turn, so we maximize again
+        if(rootNode->turn() == node->turn()){
+//            kDebug() << "Calling maxValue";
+            allCupIndexes.append(node->move());
+            utility = maxValue(node,-1000,1000);
+            allEvaluations.append(utility);
+            if(utility > value){
+                value = utility;
+                cupIndex = node->move();
+            }
+        }
+        //we are making turn, so it is a minimizer
+        else {
+//            kDebug() << "Calling minValue";
+            allCupIndexes.append(node->move());
+            utility = minValue(node,-1000,1000);
+            allEvaluations.append(utility);
+            if(utility > value){
+                value = utility;
+                cupIndex = node->move();
+            }
+        }
+
+        m_possibleMoves.pop_front();
+    }
+
+    //kDebug() << "Evaluations: " << allEvaluations;
+    // kDebug() << "Index: " << cupIndex << " value " << value ;
+    return cupIndex;
+}
+
+int MoveGenerator::maxValue(Node *parentNode,int alpha,int beta){
+
+    if(isGameOver( parentNode->getBoard() ) || parentNode->depth() == m_depthList[m_gameDifficulty])
+        return parentNode->evaluationFunction(m_gameController);
+
+    int value = -1000,utility;
+    //kDebug() << alpha << beta << parentNode->turn();
+
+    QList<Node*> m_possibleMoves;
+    Node* node;
+    simulateMoves(parentNode,m_possibleMoves);
+
+    while(m_possibleMoves.count()){
+
+        node = m_possibleMoves.front();
+//        kDebug() << "cost: " << node->evaluationFunction(m_gameController);
+
+        //we have a bonus turn, so we maximize again
+        if(parentNode->turn() == node->turn()){
+//            kDebug() << "Calling maxValue";
+            allCupIndexes.append(node->move());
+            utility = maxValue(node,alpha,beta);
+            allEvaluations.append(utility);
+            if(utility > value){
+                value = utility;
+            }
+        }
+        //we are making turn, so it is a minimizer
+        else {
+//            kDebug() << "Calling minValue";
+            allCupIndexes.append(node->move());
+            utility = minValue(node,alpha,beta);
+            allEvaluations.append(utility);
+            if(utility > value){
+                value = utility;
+            }
+        }
+
+        if(value >= beta)
+            return value;
+        if(value > alpha)
+            alpha = value;
+
+
+        m_possibleMoves.pop_front();
+    }
+
+    return value;
+}
+
+int MoveGenerator::minValue(Node *parentNode,int alpha,int beta){
+
+    if(isGameOver(parentNode->getBoard()) || parentNode->depth() == m_depthList[m_gameDifficulty])
+        return parentNode->evaluationFunction(m_gameController);
+
+    int value = 1000,utility;
+    //kDebug() << alpha << beta << parentNode->turn();
+
+    QList<Node*> m_possibleMoves;
+    Node* node;
+    simulateMoves(parentNode,m_possibleMoves);
+
+
+    while(m_possibleMoves.count()){
+
+        node = m_possibleMoves.front();
+//        kDebug() << "cost: " << node->evaluationFunction(m_gameController);
+
+        //we have a bonus turn, so we minimize again
+        if(parentNode->turn() == node->turn()){
+//            kDebug() << "Calling minValue";
+            allCupIndexes.append(node->move());
+            utility = minValue(node,alpha,beta);
+            allEvaluations.append(utility);
+            if(utility < value){
+                value = utility;
+            }
+        }
+        //we are making turn, so it is a maximizer
+        else {
+//            kDebug() << "Calling maxValue";
+            utility = maxValue(node,alpha,beta);
+            allCupIndexes.append(node->move());
+            allEvaluations.append(utility);
+            if(utility < value){
+                value = utility;
+            }
+        }
+
+        if(value < beta)
+            beta = value;
+        if(value <= alpha)
+            return value;
+
+
+        m_possibleMoves.pop_front();
+    }
+
+    return value;
+
+}
+
+void MoveGenerator::simulateMoves(Node* currentNode,QList<Node*> &nodes){
+
+    //    Node* tempNode;
+    int count1,count2;
+    QList<int> parentBoard = currentNode->getBoard();
+    //    QPair<bool,QList<int> > infoNode;
+
+    //Computer turn
+    if(currentNode->turn() == false){
+        count1 = 0;
+        for(int i = 0 ; i < m_gameInfo->numCupsPerRow() ; i++){
+            //If there is enough stone to sow
+            if( parentBoard[i] > m_gameInfo->leftToCup()){
+
+                count1++;
+                Node* tempNode = new Node(m_gameInfo);
+                QPair<bool,QList<int> > infoNode;
+
+                infoNode = m_gameController->logicalMoveController(parentBoard,i,currentNode->turn());
+
+                //setting node information
+                copyBoard(tempNode,infoNode.second);
+                tempNode->setTurn(infoNode.first);
+                tempNode->setDepth( currentNode->depth() + 1 );
+                tempNode->setMove(i);
+
+                //kDebug() << "Node Info:";
+                //kDebug() << tempNode->getBoard();
+                //kDebug() << "Turn: " << tempNode->turn() << " Move: " << tempNode->move();
+
+                nodes.append(tempNode);
+            }
+        }
+
+    }
+
+    //Human Turn
+    else{
+        count2 = 0;
+        for(int i = m_gameInfo->numCupsPerRow() ; i < 2*m_gameInfo->numCupsPerRow() ; i++){
+            //If there is enough stone to sow
+            if( parentBoard[i] > m_gameInfo->leftToCup()){
+
+                count2++;
+                Node* tempNode = new Node(m_gameInfo);
+                QPair<bool,QList<int> > infoNode;
+
+                infoNode = m_gameController->logicalMoveController(parentBoard,i,currentNode->turn());
+
+                //setting node information
+                copyBoard(tempNode,infoNode.second);
+                tempNode->setTurn(infoNode.first);
+                tempNode->setDepth( currentNode->depth() + 1 );
+                tempNode->setMove(i);
+
+                //kDebug() << "Node Info:";
+                //kDebug() << tempNode->getBoard();
+                //kDebug() << "Turn: " << tempNode->turn() << " Move: " << tempNode->move();
+
+                nodes.append(tempNode);
+            }
+        }
+
+    }
+
+    //if(count1 > 0) kDebug() << "Count1: " << count1;
+    //if(count2 > 0) kDebug() << "Count2: " << count2;
+}
+
+bool MoveGenerator::isGameOver(QList<int> board){
+
+    for(int i = 0 ; i < 2*m_gameInfo->numCupsPerRow() ; i++)
+        if( board[i] > m_gameInfo->leftToCup() )
+            return false;
+    //kDebug() << "Game Is Over ...";
+    return true;
+}
+
+void MoveGenerator::copyBoard(Node* to,Node* from){
+    QList<int> fromBoard,toBoard;
+    fromBoard = from->getBoard();
+
+    for(int i = 0 ; i < 2 * m_gameInfo->numCupsPerRow() + 2 ; i++ )
+        toBoard.append(fromBoard[i]);
+    to->setBoard(toBoard);
+}
+
+void MoveGenerator::copyBoard(Node* to,QList<int>board){
+    QList<int> tempBoard;
+    for(int i = 0 ; i < 2 * m_gameInfo->numCupsPerRow() + 2 ; i++ ){
+        //kDebug() << "Index: " << i << " content: " << board[i];
+        tempBoard.append(board[i]);
+    }
+    to->setBoard(tempBoard);
+}
+
+void MoveGenerator::showBoardState(Node *node){
+    QList<int> board = node->getBoard();
+    // kDebug() << board;
+}
+
+//--------------------------------- Node Functions Below ------------------------------
+
+Node::Node(GameInfo* info){
+
+    m_gameInfo = info;
+    m_depth = 0;
+    m_humanTurn = false;
+    m_move = -1;
+
+    for(int i = 0 ; i < 2 * m_gameInfo->numCupsPerRow() + 2 ; i++)
+        m_boardState.append(0);
+}
+
+int Node::evaluationFunction(GameController* controller){
+
+    int cost = 0;
+//    kDebug() << "In kalah of Computer: "
+//    << m_boardState[1-controller->humanKalahIndex() + 2 * m_gameInfo->numCupsPerRow()]
+//    << "depth: "<< m_depth;
+    cost = m_boardState[1-controller->humanKalahIndex() + 2 * m_gameInfo->numCupsPerRow()]
+           - m_boardState[controller->humanKalahIndex() + 2 * m_gameInfo->numCupsPerRow()];
+
+    //kDebug() << "returning: " << cost;
+    return cost;
+}
+
+void Node::setBoard(QList<int> board){
+
+    for(int i = 0 ; i < 2 * m_gameInfo->numCupsPerRow() + 2 ; i++)
+        m_boardState[i] = board[i];
+}
diff --git a/src/MoveGenerator.h b/src/MoveGenerator.h
new file mode 100644 (file)
index 0000000..7a170d5
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef MOVEGENERATOR_H
+#define MOVEGENERATOR_H
+
+
+#include <QList>
+// #include <kdebug.h>
+
+class GameController;
+class GameInfo;
+class Node;
+
+class MoveGenerator{
+
+    public:
+
+        MoveGenerator(int gameDifficulty,GameInfo *gameInfo,GameController *gameController);
+
+        void changeDifficulty(int gameDifficulty){
+            // kDebug() << "GameDifficulty Changed to: " << gameDifficulty;
+            m_gameDifficulty = gameDifficulty;
+        }
+        //Will be called when we need a move and pass the current board state
+        int bestMove(QList<int> ,bool );
+        int maxValue(Node *currentNode,int alpha,int beta);
+        int minValue(Node *currentNode,int alpha,int beta);
+
+        void copyBoard(Node* to,Node* from);
+        void copyBoard(Node *to,QList<int>board);
+        void simulateMoves(Node *currentNode,QList<Node*>& );
+
+        bool isGameOver(QList<int> board);
+        void showBoardState(Node* node);
+
+    private:
+
+
+        QList<int> allCupIndexes;
+        QList<int> allEvaluations;
+        GameInfo* m_gameInfo;
+        GameController* m_gameController;
+        int m_searchDepth;
+        int m_gameDifficulty;
+        int m_depthList[3];
+
+};
+
+//Node of the Minimax Tree
+class Node{
+
+    public:
+        Node(GameInfo *gameInfo);
+
+        int evaluationFunction(GameController* controller);
+        QList<int> getBoard(){ return m_boardState; }
+        void setBoard(QList<int>board);
+
+        void setDepth(int depth){ m_depth = depth;}
+        void setTurn(bool turn){ m_humanTurn = turn;}
+        void setMove(int move){ m_move = move;}
+
+        int depth() const{ return m_depth;}
+        int move() const{return m_move;}
+        bool turn() const{ return m_humanTurn;}
+
+
+    private:
+
+        GameInfo* m_gameInfo;
+        int m_depth;
+        bool m_humanTurn;
+        QList<int> m_boardState;
+        int m_move;     //from which cup the move has been generated
+};
+
+#endif // MOVEGENERATOR_H
diff --git a/src/Score.cpp b/src/Score.cpp
new file mode 100644 (file)
index 0000000..5144500
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "Score.h"
+
+Score::Score(){
+    scoreNow = 0;
+}
+
+void Score::reset(){
+    scoreNow = 0;
+}
+
+void Score::start(){
+    scoreNow = 0;
+}
+
+void Score::changeScore(int numCaptured){
+    scoreNow += numCaptured;
+}
diff --git a/src/Score.h b/src/Score.h
new file mode 100644 (file)
index 0000000..f7881e0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef SCORE_H
+#define SCORE_H
+
+class Score{
+
+public:
+    Score();
+
+    void start();
+    void reset();
+    void changeScore(int numCaptured);
+    int score() const{ return scoreNow;}
+
+private:
+    int scoreNow;
+
+};
+
+#endif
diff --git a/src/Stone.cpp b/src/Stone.cpp
new file mode 100644 (file)
index 0000000..d332a2a
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Stone.h"
+#include <math.h>
+
+#include <QSvgRenderer>
+#include <QGraphicsItemAnimation>
+#include <QTimeLine>
+
+// #include "kdebug.h"
+// #include "kstandarddirs.h"
+
+#include "Board.h"
+
+
+//Stone::Stone(int index , QSvgRenderer *render,  GameInfo* gameInfo, ThemeManager* theme)
+Stone::Stone(int index , GameInfo* gameInfo, ThemeManager* theme,QGraphicsSvgItem *parent)
+    : QGraphicsSvgItem(parent)
+
+{
+    m_themeManager = theme;
+    m_gameInfo = gameInfo;
+    m_board = qgraphicsitem_cast<Board*>(parent);
+
+    setSharedRenderer((QSvgRenderer*)theme);
+    setElementId("stone");
+
+    m_index = index;
+    setZValue(3);
+
+}
+
+void Stone::setPosition(qreal x, qreal y){
+
+    m_pos.setX(x);
+    m_pos.setY(y);
+
+    //kDebug() << "Pos Here: " << x << " " << y;
+    setPos(x,y);
+
+}
+
+void Stone::animateStones(QPointF newPos){
+
+    //kDebug() << "Stone Pos: New: "<< newPos << " Old: " << m_pos;
+    int steps = abs(m_pos.x() - newPos.x()) + abs(m_pos.y() - newPos.y()),diff;
+
+    QTimeLine *timer = new QTimeLine(1000);
+    timer->setFrameRange(0, 100);
+
+    QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
+    animation->setItem(this);
+    animation->setTimeLine(timer);
+
+    for (int i = 0; i < (int)steps; ++i){
+
+        if(i < abs(m_pos.x() - newPos.x()) ){
+            if( m_pos.x() < newPos.x() ){
+                animation->setPosAt(i / (qreal)steps, QPointF( i + m_pos.x() , m_pos.y()));
+                //kDebug() << "Position: " << QPointF( i + m_pos.x() , m_pos.y());
+            }
+            else animation->setPosAt(i / (qreal)steps, QPointF( m_pos.x() - i , m_pos.y()));
+            diff = i;
+        }
+        else{
+            //if( diff+1 == i) kDebug() <<"Diff is:" << diff;
+
+            if(m_pos.y() < newPos.y()){
+                animation->setPosAt( i/ (qreal) steps, QPointF(newPos.x() , i-diff+m_pos.y() ));
+                //kDebug() << "Position: " << QPointF(newPos.x() , i-diff+m_pos.y() );
+            }
+            else{
+                animation->setPosAt( i/ (qreal) steps, QPointF(newPos.x() , m_pos.y()-(i-diff) ));
+                //kDebug() << "Position: " << QPointF(newPos.x() , m_pos.y()-(i-diff));
+            }
+        }
+    }
+
+    timer->start();
+
+    m_pos.setX(newPos.x());
+    m_pos.setY(newPos.y());
+
+}
diff --git a/src/Stone.h b/src/Stone.h
new file mode 100644 (file)
index 0000000..8af9f52
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef STONE_H
+#define STONE_H
+
+#include <QtSvg/QGraphicsSvgItem>
+
+
+class GameInfo;
+class ThemeManager;
+class Board;
+
+class Stone : public QGraphicsSvgItem{
+    Q_OBJECT
+    public:
+
+        Stone(int index, GameInfo* gameInfo, ThemeManager* theme, QGraphicsSvgItem *parent);
+        void initialSetup();
+
+        void setSize(QSizeF size){ m_size = size;}
+
+        QSizeF size() const{ return m_size;}
+        int index() const{ return m_index;}
+
+        void animateStones(QPointF);
+        void setPosition(qreal x, qreal y);
+
+    signals:
+        void nothing();
+
+
+    protected:
+
+    private:
+
+        int m_index;
+        QSizeF m_size;
+        QPointF m_pos;
+        Board* m_board;
+
+        ThemeManager *m_themeManager;
+        GameInfo *m_gameInfo;
+};
+
+#endif // STONE_H
diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp
new file mode 100644 (file)
index 0000000..eb86d0c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "ThemeManager.h"
+
+// #include "kdebug.h"
+// #include "kstandarddirs.h"
+
+ThemeManager::ThemeManager(QString str) : QSvgRenderer(str){
+
+  m_currentTheme = str;
+
+}
+
+const QString& ThemeManager::current() const{
+  return m_currentTheme;
+}
+
+void ThemeManager::setTheme(QString str){
+    m_currentTheme = QString("/opt/mancala/data/themes/theme_%1.svg").arg(str);
+}
+
+void ThemeManager::slotLoadTheme(){
+    load(m_currentTheme);
+
+}
+
+
diff --git a/src/ThemeManager.h b/src/ThemeManager.h
new file mode 100644 (file)
index 0000000..3603dbe
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef THEMEMANAGER_H
+#define THEMEMANAGER_H
+
+#include <QString>
+#include <QtSvg/QSvgRenderer>
+
+
+class QSvgRenderer;
+
+class ThemeManager : public QSvgRenderer{
+    Q_OBJECT
+public:
+  ThemeManager(QString str);
+
+  const QString& current() const;
+  void setTheme(QString str);
+
+public slots:
+  void slotLoadTheme();
+
+private:
+  QString m_currentTheme;
+
+};
+
+#endif
diff --git a/src/ai-init.c b/src/ai-init.c
deleted file mode 100644 (file)
index 2562f56..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*  
- *  AI Initialization Routine -- ai-init.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai-init.c,v $
- *  $Revision: 1.3.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "mancala.h"
-#include "ai-init.h"
-
-/* Initialize everything needed by the ai function */
-
-int aiInit(
-       int *aiBoard, int *humanBoard, char *filename, 
-       int (*aifunc)(int *aiBoard, int *humanBoard, int depth, FILE *log)
-) {
-
-       int aiBoardTemp[BOARD_MAX+1], humanBoardTemp[BOARD_MAX+1];
-       int bestmove, k;
-       FILE *log;
-
-       /* open a log file */
-       if ((log = fopen(filename, "w")) == NULL) {
-               printf("Cannot open %s...\n", filename);
-               return 1; 
-       }
-
-       /* make a temporary copy of the boards */
-       for (k=0; k<=BOARD_MAX; k++) {
-               aiBoardTemp[k] = aiBoard[k];
-               humanBoardTemp[k] = humanBoard[k];
-       }
-
-       /* call the function in question */
-       bestmove = (*aifunc)(aiBoardTemp, humanBoardTemp, 0, log);
-
-       /* clean up and return the best move */
-       fflush(log);
-       fclose(log);
-
-       return bestmove;
-
-}
-
-/* End ai-init.c */
diff --git a/src/ai-init.h b/src/ai-init.h
deleted file mode 100644 (file)
index bf42688..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*  
- *  AI Initialization Header -- ai-init.h
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai-init.h,v $
- *  $Revision: 1.2.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-/* Prototype the initialization function */
-
-extern int aiInit(
-       int *aiBoard, int *humanBoard, char *filename, 
-       int (*aifunc)(int *aiBoard, int *humanBoard, int depth, FILE *log)
-);
-
-/*  End ai-init.h */
diff --git a/src/ai-recurse.c b/src/ai-recurse.c
deleted file mode 100644 (file)
index cb53fa8..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*  
- *  Recursive AI Algorithm -- ai-recurse.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai-recurse.c,v $
- *  $Revision: 1.22.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "mancala.h"
-#include "ai.h"
-#include "ai-init.h"
-
-/* How far should I go? */
-#define MAX_DEPTH 20
-
-/* keep the actual mechanics of the recursive algorithm internal */
-static int aiRecurse (int *aiBoard, int *humanBoard, int depth, FILE *log);
-
-/* new stub api function using init routine */
-
-int aiMove(int *aiBoard, int *humanBoard) {
-
-       return aiInit(aiBoard, humanBoard, "recurse.log", aiRecurse);
-
-}
-
-/* actual recursive function, accept no imitations */
-int aiRecurse (int *aiBoard, int *humanBoard, int depth, FILE *log) { 
-
-       int aiBoardTemp[BOARD_MAX+1], humanBoardTemp[BOARD_MAX+1];
-       int i, j, bestmove, pts, endpos;
-
-       bestmove = pts = endpos = 0;
-
-       /*printf("AI at depth %d\n", depth);*/
-       fprintf(log, "AI at depth %d\n", depth);
-
-       /* Keep us from recursing infinitely */ 
-       if (depth > MAX_DEPTH) 
-               return bestmove; 
-
-       /* iterate through each board position */
-       for (i=1; i<=BOARD_MAX; i++) {
-
-               /* copy boards to temp. location */
-               for(j=0; j<=BOARD_MAX; j++) {
-                       aiBoardTemp[j] = aiBoard[j];
-                       humanBoardTemp[j] = humanBoard[j];
-               }
-
-               /* test the current move */ 
-               endpos = move(aiBoardTemp, humanBoardTemp, i);
-
-               /* if we get another turn, recurse */
-               if (endpos == 0)
-                       aiRecurse(aiBoardTemp, humanBoardTemp, 
-                               (depth+1), log);
-
-               /* log it */
-               fprintf(log, "Moving from %d at depth %d\n", i, depth);
-               fprintf(log, "Ends at %d and nets %d points.\n", endpos,
-                       (aiBoardTemp[0] - aiBoard[0]));
-
-               /* if this move is better, record it */ 
-               if ((aiBoardTemp[0] - aiBoard[0]) > pts) {
-                       pts = (aiBoardTemp[0] - aiBoard[0]);
-                       bestmove = i;
-               }
-       }
-
-       /* if no move is best and some still exist, pick one at random */  
-       if ((bestmove == 0) && (!gameWon(aiBoard, humanBoard)))
-               while (aiBoard[(bestmove 
-                       = rand_btw(1,BOARD_MAX+1))] == 0)
-                       ;
-
-       /* make the final move and return */
-       move(aiBoard, humanBoard, bestmove);
-
-       return bestmove;
-
-}
-
-/*  End ai-recurse.c  */
diff --git a/src/ai-test.c b/src/ai-test.c
deleted file mode 100644 (file)
index 2c97197..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*  
- *  AI Testing Module -- ai-test.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai-test.c,v $
- *  $Revision: 1.8.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ai.h"
-#include "mancala.h"
-
-static void print_board(int *aiBoard, int *humanBoard);
-
-int main(int argc, char **argv) {
-
-  int *aiBoard, *humanBoard;
-  int current_move, i;
-  FILE *data;
-
-  aiBoard = (int *) calloc(BOARD_MAX+1, sizeof(int));
-  humanBoard = (int *) calloc(BOARD_MAX+1, sizeof(int));
-
-  printf("Hello and welcome to the mancala ai-test program.\n");
-  printf("If you liked these bugs, please check out http://cmancala.sourceforge.net\n");
-  printf("for more fine specimens.  Thanks!  -kr\n");
-
-  if ((argv[1] != NULL) && (argc == 2)) {
-    if ((data = fopen((char *) argv[1], "r")) == NULL) {
-      printf("Cannot open file %s...\n", (char *) argv[1]);
-      return 1;
-    }
-
-    /* Store hypothetical board layouts to test AI with */
-    for(i=0;i<=BOARD_MAX;i++) 
-      if (fscanf(data, "%d", (aiBoard + i)) == EOF) {
-               printf("Reached end of file...\n");
-               return 1; 
-       }
-
-    for(i=0;i<=BOARD_MAX;i++)
-      if (fscanf(data, "%d", (humanBoard + i)) == EOF) {
-               printf("Reached end of file...\n");
-               return 1;
-       }
-
-    fclose(data);
-  }
-  else if ((argv[1] != NULL) && (argc >= (BOARD_MAX*2 + 3))) {
-       for (i=0; i<=BOARD_MAX; i++)
-               *(aiBoard + i) = **(argv + i + 1) - 48;
-       for (i=0; i<=BOARD_MAX; i++)
-               *(humanBoard + i) = **(argv + i + (BOARD_MAX+2)) - 48;
-  }
-  else {
-       for (i=0; i<=BOARD_MAX; i++) {
-               printf("aiBoard[%d] = ", i);
-               scanf("%d", &aiBoard[i]);
-       }
-       for (i=0; i<=BOARD_MAX; i++) {
-               printf("humanBoard[%d] = ", i);
-               scanf("%d", &humanBoard[i]);
-       }
-  }
-
-  free(aiBoard);
-  free(humanBoard);
-
-  print_board(aiBoard, humanBoard);
-
-  /* Test it! */
-  printf("Dave: Let's test out the AI!\n");
-  if ((current_move = aiMove(aiBoard, humanBoard)) == 0)
-    printf("HAL: I'm sorry, Dave.  I can't do that.\n");
-  else {
-    printf("HAL: All my circuits are operational.\n");
-    printf("HAL: I'm going to move from hole %d.\n", current_move);
-    printf("HAL: I'm sorry, Dave.  You've lost.\n");
-  }
-
-  /* AskIgor Testing 
-  if (current_move == 1)
-    printf("pass\n");
-  else
-    printf("fail\n");
-  */
-
-  return 0;
-
-}
-
-
-/* Print board layout to stdout. */
-static void print_board(int *aiBoard, int *humanBoard) {
-  int i;
-
-  printf("\nHuman        AI\n");
-  printf("       %d\n", *aiBoard);
-  for (i=1; i<=BOARD_MAX; i++)
-    printf("%d - %d     %d - %d\n", ((BOARD_MAX + 1) - i),
-          *(humanBoard + ((BOARD_MAX + 1) - i)), *(aiBoard + i), i);
-  printf("       %d\n\n", *humanBoard);
-
-}
-
-/* End ai-test.c */
diff --git a/src/ai-ultimate.c b/src/ai-ultimate.c
deleted file mode 100644 (file)
index 1234862..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*  
- *  "Ultimate" AI Algorithm -- ai-ultimate.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai-ultimate.c,v $
- *  $Revision: 1.12.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "mancala.h"
-#include "ai.h"
-#include "ai-init.h"
-
-static int aiUltimate(int *aiBoard, int *humanBoard, int depth, FILE *log);
-
-/* api function */
-
-int aiMove(int *aiBoard, int *humanBoard) {
-
-       return aiInit(aiBoard, humanBoard, "ultimate.log", aiUltimate);
-
-}
-
-int aiUltimate(int *aiBoard, int *humanBoard, int depth, FILE *log) {
-
-       int aiBoardTemp[BOARD_MAX+1], humanBoardTemp[BOARD_MAX+1];
-       int *outcomes[BOARD_MAX+1];
-       int ai_min[BOARD_MAX+1], human_max[BOARD_MAX+1];
-       int i, j, k, result, bestmove;
-
-       bestmove = result = 0;
-
-       /* allocate memory to store the results */
-       for (i=0; i<=BOARD_MAX; i++)
-               if ((outcomes[i] = (int *) calloc(BOARD_MAX+1, sizeof(int)))
-                       == NULL)
-                       printf("Cannot allocate memory...\n");
-
-       for (i=1; i<=BOARD_MAX; i++) {
-       for (j=1; j<=BOARD_MAX; j++) {
-
-               /* make another temporary copy of the boards */ 
-               for (k=0; k<=BOARD_MAX; k++) {
-                       aiBoardTemp[k] = aiBoard[k];
-                       humanBoardTemp[k] = humanBoard[k];
-               }
-
-               /*  RECURSION
-               if (move(aiBoardTemp, humanBoardTemp, i) == 0)
-                       aiUltimate(aiBoardTemp, humanBoardTemp, (depth+1), log);
-               if (move(humanBoardTemp, aiBoardTemp, j) == 0)
-                       aiUltimate(humanBoardTemp, aiBoardTemp, {depth+1), log);
-               END RECURSION */
-
-               move(aiBoardTemp, humanBoardTemp, i);
-               move(humanBoardTemp, aiBoardTemp, j);
-
-               result = (aiBoardTemp[0] - aiBoard[0]) 
-                       - (humanBoardTemp[0] - humanBoard[0]);
-
-               *(outcomes[i] + j) = result;
-
-               printf("%d ", *(outcomes[i] + j));
-
-       }
-       printf("\n");
-       }
-
-       /* find the ai's min move and the human's max move for each row/col */
-       for (i=1; i<=BOARD_MAX; i++)
-       for (j=1; j<=BOARD_MAX; j++) {
-               ai_min[i] = human_max[j] = 0;
-               ai_min[i] = (*(outcomes[i] + j) < ai_min[i])
-                               ? *(outcomes[i] + j) : ai_min[i];
-               human_max[j] = (*(outcomes[j] + i) > human_max[j])
-                               ? *(outcomes[j] + i) : human_max[j];
-               printf("A @ %d: %d; H @ %d: %d\n", i, ai_min[i], j,
-                       human_max[j]);
-       }
-
-       /* free the calloc()s!  free the calloc()s! */
-       for (i=0; i<=BOARD_MAX; i++)
-               free(outcomes[i]);
-
-       return bestmove;
-
-}
-
-/*   End ai-ultimate.c   */
diff --git a/src/ai.c b/src/ai.c
deleted file mode 100644 (file)
index 1ddcf4d..0000000
--- a/src/ai.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*  
- *  AI Source Module -- ai.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai.c,v $
- *  $Revision: 1.5.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ai.h"
-#include "mancala.h"
-
-/* Return the computer's move. */
-int aiMove(int *aiBoard, int *humanBoard) {
-
-  int BestCapture, CapturePoints, BestMove, MoveSize, Test, i;
-  
-  BestCapture = CapturePoints = BestMove = MoveSize = Test = i = 0;
-
-  /* printf("HAL: I'm thinking, Dave...\n"); */
-  /* Loop through possible moves... */
-  for(i=1;i<=BOARD_MAX;i++) {
-    /* ...only if there is any move to make! */
-    if (aiBoard[i] != 0) {
-      /* Calculate position of final stone */
-      Test = i - (aiBoard[i] % ((2 * BOARD_MAX)+1));
-    
-      /* If this move ends on my home, take it. */
-      if (Test == 0)
-       return i;
-      /* If it doesn't but a capture does occur... */
-      else if ((Test>0) && (aiBoard[Test] == 0)) {
-       /* ...that's the best we've seen so far, store the info. */
-       if (humanBoard[(BOARD_MAX + 1) - Test] > CapturePoints) {
-         BestCapture = i;
-         CapturePoints = humanBoard[(BOARD_MAX + 1) - Test];
-       }
-      }
-      /* If neither happen, but this is larger than previous, record it. */
-      if (aiBoard[i] > MoveSize) {
-       BestMove = i;
-       MoveSize = aiBoard[i];
-      }
-    }
-  }
-
-  /* If we have a good capture, take it. */
-  if (BestCapture != 0)
-    return BestCapture;
-  
-  /* Otherwise, move the largest concentration of stones. */
-  return BestMove;
-
-}
-
-/*  End ai.c  */
diff --git a/src/ai.h b/src/ai.h
deleted file mode 100644 (file)
index f1c81df..0000000
--- a/src/ai.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*  
- *  AI API Header file -- ai.h
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/ai.h,v $
- *  $Revision: 1.4.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-extern int aiMove(int *aiBoard, int *humanBoard);
-
-/*  End ai.h  */
diff --git a/src/callbacks.c b/src/callbacks.c
deleted file mode 100644 (file)
index cbfe07d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-* This file is part of Mancala
-*
-* Originally from Crazyparking:
-*
-* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia
-* http://www.indt.org/maemo
-*
-* adapted:
-* Copyright (c) 2009 Reto Zingg
-*
-* This software is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public License
-* as published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA
-*
-*/
-#include <stdio.h>
-#include <hgw/hgw.h>
-#include "callbacks.h"
-
-
-// Pause the game
-int exit_callback(int errcode) {
-       printf("exit_callback called...\n");
-       hgw_context_destroy(hgw_context, HGW_BYE_INACTIVE);
-       return 0;
-}
-
-// Quit game
-int quit_callback(int errcode) {
-       printf("quit_callback called...\n");
-       hgw_context_destroy(hgw_context, HGW_BYE_INACTIVE);
-       return 0;
-}
-
-int flush_callback(int errcode) {
-       printf("quit_callback called...\n");
-       hgw_context_destroy(hgw_context, HGW_BYE_INACTIVE);
-       return 0;
-}
diff --git a/src/callbacks.h b/src/callbacks.h
deleted file mode 100644 (file)
index baa1383..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* This file is part of Mancala
-*
-* Originally from Crazyparking:
-* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia
-* http://www.indt.org/maemo
-*
-* This software is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public License
-* as published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA
-*
-*/ 
-extern HgwContext *hgw_context;
-
-int exit_callback(int errcode/*, AppData *app_data*/);
-int quit_callback(int errcode/*, AppData *app_data*/);
-int flush_callback(int errcode);
diff --git a/src/graphics.c b/src/graphics.c
deleted file mode 100644 (file)
index 7a01e16..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/*  
- *  Graphics Routines -- graphics.c
- *  $Id: graphics.c,v 1.1.2.20 2004/01/14 05:18:19 sparrow_hawk Exp $
- *
- *  Copyright (C) 2003 Kevin Riggle 
- *  http://cmancala.sourcefoge.net
- *  Copyright (C) 2009 Reto Zingg
- *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-#include <stdio.h>
-
-#include "SDL.h"
-#include "SDL_endian.h"        /* Used for the endian-dependent 24 bpp mode */
-
-#include "SDL_image.h"
-#include "SDL_ttf.h"
-
-#include "graphics.h"
-#include "main.h"
-#include "mancala.h"
-#include "play.h"
-
-static SDL_Surface *ShiftColors(SDL_Surface *old, Uint8 red, Uint8 blue, Uint8 green, Uint8 alpha);
-
-SDL_Surface *LoadRes(char *filename) {
-
-       return IMG_LoadPNG_RW(SDL_RWFromFile(filename, "r"));
-
-}
-
-
-SDL_Rect SurfaceToRect(SDL_Surface *src) {
-
-       SDL_Rect dest;
-
-       dest.x = 0;
-       dest.y = 0;
-       dest.w = src->w;
-       dest.h = src->h;
-
-       return dest;
-
-}
-
-/* create a new, blank surface with another's properties */
-static SDL_Surface *NewSurfaceFrom(SDL_Surface *old, Uint32 flags) {
-
-       return SDL_CreateRGBSurface(
-                       flags, old->w, old->h, old->format->BitsPerPixel,
-                       old->format->Rmask, old->format->Gmask, 
-                       old->format->Bmask, old->format->Amask
-       );
-
-}
-
-static SDL_Surface *FillHole(int stones, TTF_Font *font, 
-                               SDL_Surface **stone_gfx) {
-
-       SDL_Surface *text;
-       SDL_Color font_color;
-       char stone_string[STRING_MAX];
-       int w, h;
-
-       /* do we have a graphic for this number of stones? */
-       if (stones <= STONE_MAX) {
-
-               return *(stone_gfx + stones);
-       }
-       else {
-               font_color.r = 128;
-               font_color.g = 128;
-               font_color.b = 128;
-               /* convert the integer to text */
-               if (sprintf(stone_string, "%d", stones)<=0)
-                       fprintf(stderr, "String conversion problem.\n");
-               /* get the size of the rendered text */
-               if (TTF_SizeText(font, stone_string, &w, &h)<0) 
-                       fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
-               /* if the text is too large, render a '?' */
-               if ((w > (*stone_gfx)->w) || (h > (*stone_gfx)->h))
-                       sprintf(stone_string, "?");
-               if (!(text = TTF_RenderText_Blended(font, stone_string, 
-                       font_color))) {
-                       fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
-                       return NULL;
-               }
-               return text;
-       }
-
-       /* NEVER REACHED */
-       return NULL;
-}
-
-
-SDL_Surface *DrawBoard(int *aiBoard, int *humanBoard,
-                       TTF_Font *board_font, TTF_Font *home_font,
-                       SDL_Surface *tile, SDL_Surface **stone_gfx,
-                       int active, int highlight) {
-
-       SDL_Surface *board, *stones;
-       SDL_Rect tile_rect, blit_rect;
-       SDL_Color home_color;
-       char home_string[STRING_MAX];
-       int i;
-
-       /* initialize the board surface */
-       board = SDL_CreateRGBSurface(SDL_SWSURFACE, tile->w*(BOARD_MAX+2),
-               tile->h*2, tile->format->BitsPerPixel, 0, 0, 0, 0);
-       if (!board) {
-               fprintf(stderr, "DrawBoard: %s\n", SDL_GetError());
-               return NULL;
-       }
-
-       tile_rect = SurfaceToRect(tile);
-       /*printf("tile is %dx%d\n", tile_rect.w, tile_rect.h);*/
-
-       /* set the color of text in the home */
-       home_color.r = 0;
-       home_color.g = 0;
-       home_color.b = 0;
-
-       for (i=0; i<=BOARD_MAX+1; i++)
-       {
-               /* update current tile location */
-               tile_rect.x = i * tile_rect.w;
-               tile_rect.y = 0;
-               /*printf("Currently a %dx%d rectangle at %d,%d.\n", tile_rect.w,
-                       tile_rect.h, tile_rect.x, tile_rect.y);*/
-               blit_rect = tile_rect;
-               /* is this is the first or last tile? */
-               if ((i==0) || (i==BOARD_MAX+1)) {
-                       /* make it blank */
-                       if (SDL_BlitSurface(tile, NULL, board, &blit_rect)<0)
-                               fprintf(stderr,"DrawBoard: %s\n", 
-                                       SDL_GetError());
-                       blit_rect = tile_rect;
-                       blit_rect.y = blit_rect.h;
-                       SDL_BlitSurface(tile, NULL, board, &blit_rect);
-                       /* render the number of stones in each home */
-                       if (i==0) {
-                               if (sprintf(home_string,"%d",humanBoard[0])<=0)
-                                       printf("Human string problems.\n");
-                       }
-                       else {
-                               if (sprintf(home_string, "%d", aiBoard[0])<=0)
-                                       printf("AI string problems.\n");
-                       }
-                        if (!(stones = TTF_RenderText_Blended(home_font, 
-                               home_string, home_color)))
-                                fprintf(stderr, "DrawBoard: %s\n", 
-                                       TTF_GetError());
-                        blit_rect.w = stones->w;
-                        blit_rect.h = stones->h;
-                        blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
-                        blit_rect.y = ((tile_rect.h*2 - blit_rect.h)/2);
-                        SDL_BlitSurface(stones, NULL, board, &blit_rect);
-               }
-               /* otherwise, draw a hole and fill it */
-               else {
-                       SDL_BlitSurface(stone_gfx[0], NULL, board, &blit_rect);
-                       if (humanBoard[i] > 0) {
-                               if (!(stones = FillHole(humanBoard[i], 
-                                       board_font, stone_gfx)))
-                                       fprintf(stderr,"FillHole() problems\n");
-                               if (i == highlight)
-                                       stones = ShiftColors(stones,128,128,128,255);
-                               if (active == 1)
-                                       stones = ShiftColors(stones,0,0,0,160);
-                               blit_rect.w = stones->w;
-                               blit_rect.h = stones->h;
-                               blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
-                               blit_rect.y += ((tile_rect.h - blit_rect.h)/2);
-                               SDL_BlitSurface(stones,NULL,board,&blit_rect);
-                       }
-
-                       blit_rect = tile_rect;
-                       blit_rect.y = blit_rect.h;
-                       SDL_BlitSurface(stone_gfx[0], NULL, board, &blit_rect);
-                       if (aiBoard[BOARD_MAX-i+1] > 0) {
-                               if (!(stones = FillHole(aiBoard[BOARD_MAX-i+1], 
-                                       board_font, stone_gfx)))
-                                       fprintf(stderr,"FillHole() problems\n");
-                               if (active == 0)
-                                       stones = ShiftColors(stones,0,0,0,160);
-                               blit_rect.w = stones->w;
-                               blit_rect.h = stones->h;
-                               blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
-                               blit_rect.y += ((tile_rect.h - blit_rect.h)/2);
-                               SDL_BlitSurface(stones,NULL,board,&blit_rect);
-                       }
-               }
-       }
-
-       SDL_FreeSurface(stones);
-
-       return board;
-}
-
-
-/* flagrantly stol^H^H^Hborrowed from SDL Introduction */
-/* passing 0 for red, green, or blue leaves them alone */
-/* passing 0 for alpha makes the image transparent     */
-
-SDL_Surface *ShiftColors(SDL_Surface *old, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha)
-{
-    SDL_Surface *new;
-    Uint8 r, g, b, a;
-    int x, y;
-
-    new = NewSurfaceFrom(old, (SDL_SWSURFACE|SDL_SRCALPHA));
-
-    if ( SDL_MUSTLOCK(old) ) {
-       if (SDL_LockSurface(old) < 0 ) {
-           return NULL;
-       }
-    }
-
-    if ( SDL_MUSTLOCK(new) ) {
-        if ( SDL_LockSurface(new) < 0 ) {
-            return NULL;
-        }
-    }
-
-    for (x=0; x<old->w; x++)
-    for (y=0; y<old->h; y++) {
-    r = g = b = a = 0;
-
-    switch (old->format->BytesPerPixel) {
-        case 1: { /* Assuming 8-bpp */
-            Uint8 *bufp, *bufq;
-
-            bufp = (Uint8 *)old->pixels + y*old->pitch + x;
-            bufq = (Uint8 *)new->pixels + y*new->pitch + x;
-            SDL_GetRGBA((Uint32)*bufp, old->format, &r, &g, &b, &a);
-           a *= alpha/SDL_ALPHA_OPAQUE;
-           *bufq = (Uint8)SDL_MapRGBA(new->format, r, g, b, a);
-        }
-        break;
-
-        case 2: { /* Probably 15-bpp or 16-bpp */
-            Uint16 *bufp, *bufq;
-
-            bufp = (Uint16 *)old->pixels + y*old->pitch/2 + x;
-            bufq = (Uint16 *)new->pixels + y*new->pitch + x;
-           SDL_GetRGBA((Uint32)*bufp, new->format, &r, &g, &b, &a);
-           a *= alpha/SDL_ALPHA_OPAQUE;
-            *bufq = (Uint8)SDL_MapRGBA(new->format, r, g, b, a);
-        }
-        break;
-
-        case 3: { /* Slow 24-bpp mode, usually not used */
-            Uint8 *bufp, *bufq;
-           Uint32 color;
-
-            bufp = (Uint8 *)old->pixels + y*old->pitch + x * 3;
-            bufq = (Uint8 *)new->pixels + y*new->pitch + x * 3;
-           SDL_GetRGBA((Uint32)*bufp, old->format, &r, &g, &b, &a);
-           a *= alpha/SDL_ALPHA_OPAQUE;
-           color = SDL_MapRGBA(new->format, r, g, b, a);
-            if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
-                bufq[0] = color;
-                bufq[1] = color >> 8;
-                bufq[2] = color >> 16;
-            } else {
-                bufq[2] = color;
-                bufq[1] = color >> 8;
-                bufq[0] = color >> 16;
-            }
-        }
-        break;
-
-        case 4: { /* Probably 32-bpp */
-            Uint32 *bufp, *bufq;
-
-            bufp = (Uint32 *)old->pixels + y*old->pitch/4 + x;
-            bufq = (Uint32 *)new->pixels + y*new->pitch/4 + x;
-           SDL_GetRGBA(*bufp, old->format, &r, &g, &b, &a);
-           a = (int)((long)a * (long)alpha/SDL_ALPHA_OPAQUE);
-           r += (int)((long)(SDL_ALPHA_OPAQUE - r) * (long)red/SDL_ALPHA_OPAQUE);
-           g += (int)((long)(SDL_ALPHA_OPAQUE - g) * (long)green/SDL_ALPHA_OPAQUE);
-           b += (int)((long)(SDL_ALPHA_OPAQUE - b) * (long)blue/SDL_ALPHA_OPAQUE);
-          *bufq = SDL_MapRGBA(new->format, r, g, b, a);
-        }
-        break;
-    }
-    }
-
-    if ( SDL_MUSTLOCK(new) ) {
-       SDL_UnlockSurface(new);
-    }
-  
-    if ( SDL_MUSTLOCK(old) ) {
-        SDL_UnlockSurface(old);
-    }
-    
-    return new;
-}
-
-
-/*  End graphics.c  */
diff --git a/src/graphics.h b/src/graphics.h
deleted file mode 100644 (file)
index d4103f9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*  
- *  Graphics Routines Header -- graphics.h
- *  $Id: graphics.h,v 1.1.2.10 2004/01/14 05:08:58 sparrow_hawk Exp $
- *
- *  Copyright (C) 2003 Kevin Riggle 
- *  http://cmancala.sourcefoge.net
- *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-extern SDL_Surface *LoadRes(char *filename);
-extern SDL_Rect SurfaceToRect(SDL_Surface *src);
-extern SDL_Surface *DrawBoard(int *aiBoard, int *humanBoard,
-                        TTF_Font *board_font, TTF_Font *home_font,
-                        SDL_Surface *tile, SDL_Surface **stone_gfx,
-                       int active, int highlight);
-
-
-/*  End graphics.h  */
diff --git a/src/launcher/Makefile b/src/launcher/Makefile
deleted file mode 100644 (file)
index 16cc005..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# GNU Makefile -- Makefile
-# 2009 Reto Zingg
-
-
-CC = gcc
-
-
-all:
-       $(CC) mancala-launcher.c -o mancala-launcher
-
-install:       all
-       mkdir -p $(DESTDIR)/home/opt/mancala/bin/
-       cp ./mancala-launcher $(DESTDIR)/home/opt/mancala/bin/mancala-launcher
-
-uninstall:
-       rm -rf $(DESTDIR)/home/opt/mancala/mancala-launcher
-
-clean:
-       rm -f *.o *.core *.swp *~ *.log
-
-clobber:       clean
-       rm -f mancala-launcher
-
diff --git a/src/launcher/mancala-launcher.c b/src/launcher/mancala-launcher.c
deleted file mode 100644 (file)
index 20462e2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-* This file is part of Mancala
-*
-* Idea from Crazyparking
-*
-* Copyright (c) 2009 Reto Zingg
-*
-* This software is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public License
-* as published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-
-char *wrapper_args[] = {"/usr/games/wrapper/wrapper",
-                        "/home/opt/mancala/data/mancala.game",
-                        NULL};
-
-int main(int argc, char *argv[])
-{
-    
-    if (execv ("/usr/games/wrapper/wrapper", wrapper_args) == -1) {
-        printf("Launching mancala wrapper failed\n");
-    }
-
-    return 0;
-}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index d587d33..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-*
-*  This file is part of Mancala
-*
-*  Copyright (C) 2009 Reto Zingg
-*
-*  Some of the code is based on the examples on:
-*  http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide
-*
-*  This program 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 2, or (at your option) any
-*  later version.
-*
-*  This program 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, a copy of which may be found in
-*  the file COPYING provided in the main directory of this release.
-*
-*/
-
-/*********************************************************************
-**
-** NOT used at the moment...
-**
-*********************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <hildon/hildon.h>
-#include <libosso.h>
-#include <gtk/gtk.h>
-
-
-#include "play.h"
-
-#define OSSO_SERVICE "com.nokia.mancala"
-
-osso_context_t *ossoContext = NULL;
-
-gint
-dbus_callback (const gchar *interface, const gchar *method,
-                GArray *arguments, gpointer data,
-                osso_rpc_t *retval)
-{
-        printf ("Msg dbus: %s, %s\n", interface, method);
-
-        if (!strcmp (method, "top_application"))
-                gtk_window_present (GTK_WINDOW (data));
-
-        retval->type = DBUS_TYPE_INVALID;
-        return OSSO_OK;
-}
-
-
-void play_wrapper (GtkWidget *win)
-{
-
-        fprintf(stderr, "Button start-play pressed\n");
-        if (play() > 0){
-                fprintf(stderr, "start play failed\n");
-        }
-        else{
-                fprintf(stderr, "successfull played...\n");
-        }
-
-        osso_application_top(ossoContext, OSSO_SERVICE, NULL);
-
-}
-
-static HildonAppMenu* create_menu (GtkWidget *win)
-        {
-                int i;
-                gchar *command_id;
-                GtkWidget * button;
-                HildonAppMenu *menu = HILDON_APP_MENU (hildon_app_menu_new ());
-                for (i = 1; i <= 2; i++) {
-                        /* Create menu entries */
-                        button = hildon_gtk_button_new (HILDON_SIZE_AUTO);
-                        command_id = g_strdup_printf ("Menu command %d", i);
-                        gtk_button_set_label (GTK_BUTTON (button), command_id);
-
-                        /* Attach callback to clicked signal */
-                        switch (i) {
-                                // Start game
-                                case 1:
-                                        command_id = g_strdup_printf ("Play");
-                                        gtk_button_set_label (GTK_BUTTON (button), command_id);
-                                        g_signal_connect_after (button, "clicked",
-                                                G_CALLBACK (play_wrapper),win);
-                                break;
-                                // Show help
-                                case 2:
-                                        command_id = g_strdup_printf ("Quit");
-                                        gtk_button_set_label (GTK_BUTTON (button), command_id);
-                                        g_signal_connect_after (button, "clicked",
-                                                G_CALLBACK (gtk_main_quit), NULL);
-                                break;
-                        }
-                        /* Add entry to the view menu */
-                        hildon_app_menu_append (menu, GTK_BUTTON (button));
-                }
-
-        gtk_widget_show_all (GTK_WIDGET (menu));
-        return menu;
-}
-
-
-int main (int argc, char **argv) {
-
-        osso_return_t ret;
-
-        g_print("Initializing LibOSSO\n");
-        ossoContext = osso_initialize(OSSO_SERVICE, "0.1", FALSE, NULL);
-        if (ossoContext == NULL) {
-                g_error("Failed to initialize LibOSSO\n");
-        }
-
-        GtkWidget *win;
-        GtkWidget *textbox;
-        GtkTextBuffer *textbox_buffer;
-        gchar *textbox_text;
-        GtkBox *vbox;
-        HildonAppMenu *menu;
-        PangoFontDescription *font_desc;
-        GtkWidget * button;
-        gchar *button_lable_text;
-        GtkWidget *pannable_text;
-
-        hildon_gtk_init (&argc, &argv);
-        win = hildon_window_new ();
-
-        /* Create and pack labels */     
-        textbox_text = g_strdup_printf("Welcome to Mancala, the ancient African game of skill!\n\nMancala is a very simple, easy-to-learn game. Each player begins with a horizontal row of holes or pits filled with a certain number of stones. At either end of the board are the players' home pits, which are used to keep score. In this case, the human player has the left home pit and the upper row holes. A move is made by clicking into the hole you wish to move from. The stones are then picked up and distributed, one to each hole, moving toward your home pit is reached, and then moving through your opponent's row, bypassing his/her home, and moving back towards in a circle (counterclockwise), until all the stones have been distributed.\n\nIf the last stone is placed in your home, you receive an extra turn. If the last stone lands in an empty hole on your side, you 'capture' the stones in the opposite hole on your opponent's side, moving them to your home.\n\nThe game ends when one player cannot play (ie. there are no stones on his/her side of the board.  The player who has the most stones on his/her *side* wins.");
-
-        textbox = hildon_text_view_new();
-        // gtk_text_view_set_editable(GTK_TEXT_VIEW(textbox), FALSE);
-        // gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textbox), FALSE);
-        gtk_text_view_set_indent(GTK_TEXT_VIEW(textbox), 10);
-        gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textbox), 10);
-        gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textbox), 10);
-        gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(textbox), 3);
-        gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(textbox), 2);
-        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textbox), GTK_WRAP_WORD);
-        // gtk_widget_set_sensitive(textbox, FALSE);
-        font_desc = pango_font_description_from_string ("vera 18");
-        gtk_widget_modify_font(textbox, font_desc);
-        pango_font_description_free (font_desc);
-
-        textbox_buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (textbox));
-
-        gtk_text_buffer_set_text(textbox_buffer, textbox_text, -1);
-
-
-        pannable_text = hildon_pannable_area_new();
-        hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA(pannable_text), textbox);
-
-
-        vbox = GTK_BOX (gtk_vbox_new (FALSE, 2));
-
-        button = hildon_button_new (HILDON_SIZE_AUTO | HILDON_SIZE_FINGER_HEIGHT,
-                                        HILDON_BUTTON_ARRANGEMENT_VERTICAL);
-        button_lable_text = g_strdup_printf ("Play");
-        gtk_button_set_label (GTK_BUTTON (button), button_lable_text);
-        g_signal_connect_after (button, "clicked",
-                                 G_CALLBACK (play_wrapper),win);
-
-        gtk_box_pack_start (vbox, button, FALSE, TRUE, 1);
-        gtk_box_pack_start (vbox, pannable_text, TRUE, TRUE, 1);
-
-        /* Create menu */
-        menu = create_menu (win);
-
-        /* Attach menu to the window */
-        hildon_window_set_app_menu (HILDON_WINDOW (win), menu);
-
-        /* Add label's box to window */
-        gtk_container_add (GTK_CONTAINER (win), GTK_WIDGET (vbox));
-
-        g_signal_connect (win, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
-
-        gtk_widget_show_all (win);
-
-        ret = osso_rpc_set_default_cb_f (ossoContext, dbus_callback, GTK_WINDOW(win));
-        if (ret != OSSO_OK)
-        {
-                fprintf (stderr, "osso_rpc_set_default_cb_f failed: %d.\n", ret);
-                exit (1);
-        }
-
-        gtk_main ();
-
-        osso_deinitialize(ossoContext);
-        ossoContext = NULL;
-
-        return 0;
-}
-
-
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644 (file)
index 0000000..bc26195
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+This program 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 2 of
+the License, or (at your option) any later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QtGui/QApplication>
+
+//#include <kapplication.h>
+//#include <kaboutdata.h>
+//#include <kcmdlineargs.h>
+//#include <KDE/KLocale>
+//#include <KGlobal>
+
+#include "MainWindow.h"
+
+static const char description[] = "Mancala Game for KDE";
+
+static const char version[] = "0.2";
+
+
+int main(int argc, char *argv[]){
+//    KAboutData about("mancala", 0, ki18n("Mancala"), version, ki18n(description),
+//                     KAboutData::License_GPL, ki18n("(C) 2009 A.H.M. Mahfuzur Rahman"),
+//                     KLocalizedString(), 0, "65mahfuz90@gmail.com");
+
+//    about.addAuthor( ki18n("A.H.M.Mahfuzur Rahman"), ki18n("Current Maintainer"), "65mahfuz90@gmail.com" );
+//    about.addCredit(ki18n("Tomaz Canabrava"),
+//                        ki18n("Coding help"), "tomaz.canabrava@gmail.com ");
+
+//    KCmdLineArgs::init(argc, argv, &about);
+
+//    KApplication app;
+//    KGlobal::locale()->insertCatalog("libkdegames");
+
+    QApplication a(argc, argv);
+
+    MainWindow *window = new MainWindow();
+    QSize oldSize = window->size();
+    window->show();
+    window->resize(100,100);
+    window->resize(oldSize);
+
+    return a.exec();
+
+}
diff --git a/src/main.h b/src/main.h
deleted file mode 100644 (file)
index f95b555..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-*  Copyright (C) 2009 Reto Zingg
-*
-*  This program 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 2, or (at your option) any
-*  later version.
-*
-*  This program 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, a copy of which may be found in
-*  the file COPYING provided in the main directory of this release.
-*
-*/
-
-
-
-
diff --git a/src/mancala.c b/src/mancala.c
deleted file mode 100644 (file)
index 951bf37..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*  
- *  Mancala Common Source Module -- mancala.c
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/mancala.c,v $
- *  $Revision: 1.4.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- *  Copyright (C) 2003, 2004 Kevin Riggle
- *  Copyright (C) 2009 Reto Zingg
- *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "mancala.h"
-
-/* Set up the game board. */
-void gameInit(int *aiBoard, int *humanBoard) {
-
-  int i;
-
-  *aiBoard = *humanBoard = 0;
-
-  for (i=1; i<=BOARD_MAX; i++)
-    *(aiBoard + i) = *(humanBoard + i) = INITIAL_STONES;
-
-}
-
-/* Has the game been won by someone? */
-int gameWon(int *aiBoard, int *humanBoard) {
-
-  int aiTotal, humanTotal, i;
-
-  aiTotal = humanTotal = 0;
-
-  /* Sum the stones on each side... */
-  for (i=1; i<=BOARD_MAX; i++) {
-    aiTotal = aiTotal + *(aiBoard + i);
-    humanTotal = humanTotal + *(humanBoard + i);
-  }
-
-  /* If one side has none, return accordingly. */
-  if (aiTotal == 0 || humanTotal == 0) {
-    /* Calculate the final score. */
-    for (i=1; i<=BOARD_MAX; i++) {
-      *aiBoard = *aiBoard + *(aiBoard + i);
-      *humanBoard = *humanBoard + *(humanBoard + i);
-      *(aiBoard + i) = *(humanBoard + i) = 0;
-    }    
-    return 1;
-  }
-  else
-    return 0;
-
-}
-
-/* Make a move, and return the position of the last stone! */
-int move(int *activeBoard, int *passiveBoard, int move) {
-
-  int *currentPosition, stones;
-
-  currentPosition = activeBoard + move;
-
-  stones = *(activeBoard + move);
-  if (stones > 0){
-      /* Pick up the stones. */
-      *(activeBoard + move) = 0;
-
-      /* Loop for each stone. */
-      for (; stones>0; stones--) {
-              /* Move to the next board location. */
-              if (currentPosition == activeBoard)
-                      currentPosition = passiveBoard + BOARD_MAX;
-              else if (currentPosition == passiveBoard + 1)
-                      currentPosition = activeBoard + BOARD_MAX;
-              else
-                      currentPosition--;
-              /* Drop a stone. */
-              (*currentPosition)++;
-      }
-      
-      /* If the last stone lands on an empty hole... */
-      if (*currentPosition == 1 && activeBoard < currentPosition && 
-              currentPosition <= (activeBoard + BOARD_MAX)) {
-              /* ...calculate the position of the opposite hole... */
-              int oppHole = (BOARD_MAX + 1) - (currentPosition - activeBoard);
-              /* ...and make the capture. */
-              *activeBoard = *activeBoard + *(passiveBoard + oppHole);
-              printf("Captured %d stones.\n", *(passiveBoard + oppHole));
-              *(passiveBoard + oppHole) = 0;
-      }
-      
-      return currentPosition - activeBoard;
-  }
-  else{
-      printf("move from empty hole...\n");
-      /* return 0 so human can make a move again */
-      return 0;
-  }
-   
-}
-
-int rand_btw(int min, int max) {
-
-       int range;
-
-       range = (max - min) + 1;
-
-       return ((rand() % range) + min);
-
-}
-  
-/*  End mancala.c  */
diff --git a/src/mancala.h b/src/mancala.h
deleted file mode 100644 (file)
index c89c378..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*  
- *  Mancala Headers -- mancala.h
- *  Kevin Riggle
- *  http://cmancala.sourceforge.net
- *  $Source: /cvsroot/cmancala/mancala/src/Attic/mancala.h,v $
- *  $Revision: 1.4.2.1 $
- *  $Date: 2003/12/29 05:49:52 $
- *
- */
-
-/* Game constants */
-#define BOARD_MAX 6
-#define INITIAL_STONES 4
-
-extern void gameInit(int *aiBoard, int *humanBoard);
-extern int gameWon(int *aiBoard, int *humanBoard);
-extern int move(int *activeBoard, int *passiveBoard, int move);
-extern int rand_btw(int min, int max);
-
-/*  End mancala.h  */
diff --git a/src/play.c b/src/play.c
deleted file mode 100644 (file)
index cb761dd..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
-*  for Maemo renamed to play.c and some bugfixes (2009, Reto Zingg)
-*
-*  Main Mancala Program Module Source -- main.c 
-*  $Id: main.c,v 1.7.2.25 2004/01/17 06:56:23 sparrow_hawk Exp $
-*
-*  Copyright (C) 2003 Kevin Riggle 
-*  http://cmancala.sourcefoge.net
-*  Copyright (C) 2009 Reto Zingg
-*
-*  This program 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 2, or (at your option) any
-*  later version.
-*
-*  This program 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, a copy of which may be found in
-*  the file COPYING provided in the main directory of this release.
-*
-*/
-
-#include <hildon/hildon.h>
-#include <hgw/hgw.h>
-#include <unistd.h>
-
-#include "SDL_mixer.h"
-#include "SDL.h"
-#include "SDL_image.h"
-#include "SDL_ttf.h"
-#include "SDL_getenv.h"
-
-#include "graphics.h"
-#include "mancala.h"
-#include "ai.h"
-#include "sounds.h"
-#include "play.h"
-
-#include "callbacks.h"
-
-// the surfaces
-SDL_Surface *screen, *board, *title_text, *tile, *stone[STONE_MAX+1], *exit_text;
-// the fonts
-TTF_Font *title_font, *home_font, *board_font;
-// The sound effects that will be used
-Mix_Chunk *pick = NULL;
-// the hildon-game-wrapper context
-HgwContext *hgw_context = NULL;
-
-// for debugging, example:
-
-// rmz_debug(g_strdup_printf("play step 2: SDL_AUDIODRIVER: %s",
-//                            my_sdl_audiodrv)
-//                          );
-
-// void rmz_debug (char *msg){
-//     FILE *pFile;
-//     
-//     pFile = fopen ("/home/rzingg/mancala.debug", "a");
-//     if (pFile) {
-//         fprintf (pFile, "rmz_debug: %s \n", msg);
-//         fclose (pFile);
-//     }
-// }
-
-void sdl_clean_up(){
-        
-        int i = 0;
-        
-        SDL_FreeSurface(board);
-        SDL_FreeSurface(tile);
-        SDL_FreeSurface(exit_text);
-        SDL_FreeSurface(title_text);
-        for(i=0; i<=STONE_MAX; i++)
-                SDL_FreeSurface(stone[i]);
-        SDL_FreeSurface(screen);
-        TTF_CloseFont(title_font);
-        TTF_CloseFont(board_font);
-        TTF_CloseFont(home_font);
-        Mix_FreeChunk(pick);
-        /* Make sure we clean up after ourselves */
-        TTF_Quit();
-        Mix_CloseAudio();
-        SDL_Quit();
-        return;
-}
-
-int play() {
-
-        // Scratchbox needs different SDL_AudiDriver env
-        #if __i386__
-        putenv("SDL_AUDIODRIVER=alsa") ;
-        #endif /* __i386__ */
-        
-        SDL_Rect board_rect, title_rect, exit_rect;
-        SDL_Color font_color;
-        SDL_Event event;
-        SDL_Color font_color_exit;
-        
-        char tile_path[STRING_MAX], stone_path[STRING_MAX];
-        char icon_path[STRING_MAX], title_path[STRING_MAX];
-        char home_path[STRING_MAX], board_path[STRING_MAX];
-        char pick_path[STRING_MAX];
-        int aiBoard[BOARD_MAX+1], humanBoard[BOARD_MAX+1];
-        int i, redraw_board, highlight, old_highlight, active;
-        int current_move, ai_last_move, human_last_move, state;
-        
-        /* Set up the game board and game variables. */
-        gameInit(aiBoard, humanBoard);
-        current_move = 0;
-        ai_last_move = human_last_move = -99;
-        
-        /* initialize our libraries */
-        //if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0) {
-       if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
-               printf("Unable to initialize SDL: %s\n", 
-                        SDL_GetError());
-                        sdl_clean_up();
-                        return 1;
-       }
-       
-       if (TTF_Init() < 0) {
-               printf("Unable to initialize SDL_ttf: %s\n", 
-                        SDL_GetError());
-                        sdl_clean_up();
-                        return 1;
-       }
-       
-       //Initialize SDL_mixer 
-       if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) 
-       // if( Mix_OpenAudio(22050, (Uint16)AUDIO_U8, 2, 256 ) == -1 )
-       {
-               printf("Unable to initialize Mix_OpenAudio: %s\n",
-                        SDL_GetError());
-                        sdl_clean_up();
-                        return 1;
-       }
-       
-       /* Load our images... PNGs now, maybe XPMs later */
-       sprintf(tile_path, "%s/tile.png", RES_PATH);
-       if ((tile = LoadRes(tile_path)) == NULL) {
-               printf("Unable to load resource: %s\n", 
-                        SDL_GetError());
-                        sdl_clean_up();
-                        return 1;
-       }
-       
-       for (i=0; i<=STONE_MAX; i++) {
-               if (sprintf(stone_path, "%s/stone%02d.png", RES_PATH, i) == 0)
-                       printf("Problems assembling path.\n");
-               if (!(stone[i] = LoadRes(stone_path))) {
-                       printf("Unable to load resource: %s\n",
-                                SDL_GetError());
-                                sdl_clean_up();
-                                return 1;
-               }
-       }
-       
-       /* Load our font(s) */
-       if (sprintf(title_path, "%s/luxisr.ttf", FONT_PATH) == 0)
-               printf("Problems assembling path.\n");
-       if (!(title_font = TTF_OpenFont(title_path, TITLE_SIZE))) {
-               printf("Could not load font: %s\n", TTF_GetError());
-               sdl_clean_up();
-               return 1;
-       }
-       
-       if (sprintf(board_path, "%s/luxisr.ttf", FONT_PATH) == 0)
-               printf("Problems assembling path.\n");
-       if (!(board_font = TTF_OpenFont(board_path, BOARD_SIZE))) {
-               printf("Could not load font: %s\n", TTF_GetError());
-               sdl_clean_up();
-               return 1;
-       }
-       
-       if (sprintf(home_path, "%s/luxisr.ttf", FONT_PATH) == 0)
-               printf("Problems assembling path.\n");
-       if (!(home_font = TTF_OpenFont(home_path, HOME_SIZE))) {
-               printf("Could not load font: %s\n", TTF_GetError());
-               sdl_clean_up();
-               return 1;
-       }
-       
-       /* Load sound effects */ 
-       sprintf(pick_path, "%s/pick.wav", RES_PATH); 
-       if ((pick = Mix_LoadWAV(pick_path)) == NULL) { 
-               printf("Unable to load sound: %s\n", 
-                        SDL_GetError());
-                        sdl_clean_up();
-                        return 1; 
-       }
-       
-       /* store the font's color */
-       font_color.r = 255;
-       font_color.b = 255;
-       font_color.g = 255;
-       
-       /* render the title text 
-       if (!(title_text = TTF_RenderText_Solid(title_font, 
-               "Mancala", font_color))) 
-               fprintf(stderr, "TTF: %s\n", TTF_GetError());
-       */
-       title_text = NULL;
-       
-       
-       /* define the position of the board in the screen */
-       board_rect.x = 0;
-       board_rect.y = Y_OFFSET;
-       board_rect.w = 0;
-       board_rect.h = 0;
-       
-       /* set window properties and create it */
-       // SDL_WM_SetCaption("Mancala", "Mancala");
-       // if (sprintf(icon_path, "%s/icon.png", RES_PATH) == 0)
-       //        printf("Problems assembling icon path.\n");
-       // SDL_WM_SetIcon(LoadRes(icon_path), NULL);
-       if ((screen = SDL_SetVideoMode(tile->w*8, (tile->h*2) + Y_OFFSET, 16, SDL_FULLSCREEN))
-               == NULL) {
-               printf("Unable to set %dx%d video: %s", tile->w*8,
-                        tile->h*2, SDL_GetError());
-                        sdl_clean_up();
-                        return 1;
-       }
-       SDL_ShowCursor(SDL_DISABLE);
-       
-       /* define the font color fot the exit text */
-       font_color_exit.r = 255;
-       font_color_exit.r = 255;
-       font_color_exit.r = 255;
-       
-       if (!(exit_text = TTF_RenderText_Blended(home_font, "EXIT", 
-             font_color_exit))) {
-                     printf("SDL_ttf: %s\n", TTF_GetError());
-                     return 1;
-        }
-       
-        exit_rect.x = 400;
-        exit_rect.y = 0;
-        exit_rect.w = 0;
-        exit_rect.h = 0;
-        
-        SDL_BlitSurface(exit_text, NULL, screen, &exit_rect);
-        
-       state = HMN_WAIT;
-       redraw_board = 1;
-       old_highlight = 0;      
-       highlight = 0;
-       active = 0;
-       
-       /* GAME LOOP */
-       while (state != GAME_WON) {
-               
-               /* check for GTK events... */
-               /* otherwise hildon thinks the app hangs... */
-               while (gtk_events_pending ())
-                       gtk_main_iteration ();
-               
-               /* figure out if anything important happened */
-               old_highlight = highlight;
-               while (SDL_PollEvent(&event)) {
-                       /* BAIL OUT! BAIL OUT! */
-                       if (event.type == SDL_KEYDOWN){
-                               printf("event SDL_KEYDOWN found....\n");
-                               if ( event.key.keysym.sym == SDLK_q )
-                               {
-                                       printf("event SDLK_q found....\n");
-                                       SDL_Event quit_event;
-                                       quit_event.type = SDL_QUIT;
-                                       SDL_PushEvent(&quit_event);
-                               }
-                       }
-                       
-                       if (event.type == SDL_MOUSEBUTTONDOWN) {
-                               if ((event.button.button = 1) &&
-                                   (event.button.y < Y_OFFSET)) {
-                                       printf("clicked out side the board in exit area...\n");
-                                       SDL_Event quit_event;
-                                       quit_event.type = SDL_QUIT;
-                                       SDL_PushEvent(&quit_event);
-                               }
-                       }
-                       
-                       if (event.type == SDL_QUIT) {
-                               printf("event SDL_QUIT found....\n");
-                               sdl_clean_up();
-                               return 0;
-                       }
-                       
-                       /* get events */
-                       if (state == HMN_WAIT) {
-                               switch (event.type) {
-                                       case SDL_MOUSEBUTTONDOWN:
-                                               if ((event.button.button = 1) &&
-                                                   (event.button.y < tile->h) &&
-                                                   (event.button.y > Y_OFFSET)) {
-
-                                                       int pitch=0;
-                                                       pitch = event.button.x / tile->w;
-
-                                                        // pitch 0 and 7 are the homebases which you can't play
-                                                        if ( pitch == 0 || pitch == 7 ){
-                                                                 printf("clicked out side the board...\n");
-                                                        }
-                                                        else{
-                                                                current_move = pitch;
-                                                                state = HMN_MOVE;
-                                                        }
-                                               }
-                                               break;
-                                       case SDL_MOUSEMOTION:
-                                               if (event.motion.y < tile->h) {
-                                                       highlight = event.motion.x / tile->w;
-                                               }
-                                               else
-                                                       highlight = 0;
-                                               break;
-                                       case SDL_ACTIVEEVENT:
-                                               if (event.active.gain == 0)
-                                                       highlight = 0;
-                                               break;
-                               }
-                       }
-               }
-               SDL_Delay(DELAY_MAX);
-               
-               /* GAME LOGIC */
-               if (gameWon(aiBoard, humanBoard) == 1)
-                       state = GAME_WON;
-               
-               /* happy happy state machine */
-               switch(state) {
-                       case HMN_WAIT:
-                               active = 0;
-                               if (highlight != old_highlight)
-                                       redraw_board = 1;
-                               break;
-                       case HMN_MOVE:
-                               human_last_move = move(humanBoard,aiBoard,current_move);
-                               play_sound(pick);
-                               redraw_board = 1;
-                               if (human_last_move == 0)
-                                       state = HMN_WAIT;
-                               else 
-                                       state = CMP_WAIT;
-                               printf("Human moving from %d to %d, now %d\n", current_move, human_last_move, state);
-                               break;
-                       case CMP_WAIT:
-                               SDL_Delay(DELAY_AI);
-                               active = 1;
-                               current_move = aiMove(aiBoard, humanBoard);
-                               state = CMP_MOVE;
-                               break;
-                       case CMP_MOVE:
-                               printf("Computer moving\n");
-                               ai_last_move = move(aiBoard,humanBoard,current_move);
-                               play_sound(pick);
-                               redraw_board = 1;
-                               if (ai_last_move == 0)
-                                       state = CMP_WAIT;
-                               else
-                                       state = HMN_WAIT;
-                               break;
-                       case GAME_WON:
-                               if (aiBoard[0] > humanBoard[0]) {
-                                       if (!(title_text = TTF_RenderText_Blended(title_font, 
-                                               "Computer Wins!", font_color)))
-                                               printf("TTF: %s\n", TTF_GetError());
-                               }
-                               else {
-                                       if (!(title_text = TTF_RenderText_Blended(title_font, 
-                                               "Human Wins!", font_color))) 
-                                               printf("TTF: %s\n", TTF_GetError());
-                               }
-                               redraw_board = 1;
-                               break;
-               }
-               
-               /* redraw the board if needed */
-               if (redraw_board == 1) {
-                       /*printf("redrawing board\n");*/
-                       
-                       /* draw and blit the board */
-                       board = DrawBoard(aiBoard, humanBoard, board_font, 
-                                          home_font, tile, stone, active, 
-                                          highlight);
-                                          if (!board) {
-                                                  printf("Could not draw the board.\n");
-                                          }
-                                          else {
-                                                  // board_rect = SurfaceToRect(board);
-                                                  SDL_BlitSurface(board, NULL, screen, 
-                                                                   &board_rect);
-                                          }
-                                          
-                                          /* draw, center, and blit the title */
-                                          if (title_text) {
-                                                  title_rect = SurfaceToRect(title_text);
-                                                  title_rect.x = ((screen->w - title_rect.w)/2);
-                                                  title_rect.y = ((screen->h - title_rect.h)/2);
-                                                  SDL_BlitSurface(title_text, NULL, screen, 
-                                                                   &title_rect);
-                                          }
-                                          
-                                          SDL_UpdateRect(screen, 0,0,0,0);
-                                          
-                                          redraw_board = 0;
-               }
-               
-               hgw_msg_compat_receive(hgw_context, 0);
-               
-       }
-       
-       SDL_Delay(DELAY_AI);
-       
-       
-       sdl_clean_up();
-       return 0;
-       
-}
-
-
-int main(int argc, char **argv) {
-
-    hgw_context = hgw_context_compat_init(argc, argv);
-    if (!hgw_context) {
-        printf("Cannot init hildon-games-startup!\n");
-        return 0;
-    }
-
-    hgw_compat_set_cb_exit(hgw_context, exit_callback);
-    hgw_compat_set_cb_quit(hgw_context, quit_callback);
-    hgw_compat_set_cb_flush(hgw_context, flush_callback);    
-    if(!hgw_context_compat_check(hgw_context)) return 0;
-
-    /* hildon-games-wrapper part */
-    hgw_msg_compat_receive(hgw_context, 0);
-    usleep(100);
-
-    // Main game
-    play();
-
-    // hgw_context_compat_destroy_deinit(hgw_context);
-    // hgw_context_compat_destroy_quit(hgw_context);
-    // hgw_context_destroy(hgw_context);
-    hgw_context_destroy(hgw_context, HGW_BYE_INACTIVE);
-
-    return 0;
-}
-
diff --git a/src/play.h b/src/play.h
deleted file mode 100644 (file)
index c2a0b72..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-*  for Maemo renamed to play.h and adapted (2009, Reto Zingg)
-*
-*  Main Mancala Program Module Header -- main.h 
-*  $Id: main.h,v 1.1.2.8 2004/01/16 20:49:30 sparrow_hawk Exp $
-*
-*  Copyright (C) 2003 Kevin Riggle 
-*  http://cmancala.sourcefoge.net
-*
-*  This program 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 2, or (at your option) any
-*  later version.
-*
-*  This program 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, a copy of which may be found in
-*  the file COPYING provided in the main directory of this release.
-*
-*/
-
-/* path to resource files */
-#define RES_PATH "/home/opt/mancala/data"
-#define FONT_PATH "/home/opt/mancala/data"
-
-/* various constants */
-#define STRING_MAX 1000
-#define STONE_MAX 10
-#define DELAY_MAX 1
-#define DELAY_AI 3000
-
-/* font sizes */
-#define TITLE_SIZE 75
-#define HOME_SIZE 50
-#define BOARD_SIZE 35
-
-#define HMN_WAIT 1
-#define HMN_MOVE 2
-#define CMP_WAIT 3
-#define CMP_MOVE 4
-#define GAME_WON 0
-
-#define Y_OFFSET 70
-
-extern int play();
-
diff --git a/src/plugin/Makefile b/src/plugin/Makefile
deleted file mode 100644 (file)
index c55993b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# GNU Makefile -- Makefile
-# 2009 Reto Zingg
-
-CC = gcc
-DBG = gdb
-STD = _GNU_SOURCE
-CFLAGS = `pkg-config hildon-1 --cflags` -I/usr/include/dbus-1.0/ -I/usr/lib/dbus-1.0/include/
-LFLAGS =  -shared `pkg-config hildon-1 --libs`
-
-MAIN_OBJ = mancala-ui-plugin.o
-
-
-
-#'$<' is filename of input, '$@' is filename of output
-.c.o:
-       $(CC) -c -g$(DBG) -Wall $(CFLAGS) -D$(STD) $<
-.h.o:
-       $(CC) -c -g$(DBG) -Wall $(CFLAGS) -D$(STD) $<
-
-all:   $(MAIN_OBJ)
-       $(CC) $(LFLAGS) $(MAIN_OBJ) -o mancala-ui-plugin.so
-
-install:       all
-       mkdir -p $(DESTDIR)/home/opt/mancala/plugin/
-       cp mancala-ui-plugin.so $(DESTDIR)/home/opt/mancala/plugin/
-
-clean:
-       rm -f *.o *.core *.swp *~ *.log
-
-clobber:       clean
-       rm -f mancala-ui-plugin.so
-
-
-
diff --git a/src/plugin/mancala-ui-plugin.c b/src/plugin/mancala-ui-plugin.c
deleted file mode 100644 (file)
index 9fb5cf7..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-* This file is part of Mancala
-*
-* Originally from Crazyparking:
-* Copyright (C) 2005 INdT - Instituto Nokia de Tecnologia
-* http://www.indt.org/maemo
-*
-* adapted:
-* Copyright (c) 2009 Reto Zingg
-*
-* Some of the code is based on the examples on:
-* http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide
-*
-* This software is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public License
-* as published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA
-*
-*/ 
-
-
-#include <stdio.h>
-#include <hildon/hildon.h>
-#include <gtk/gtk.h>
-#include <startup_plugin.h>
-#include <startup_app.h>
-#include <dbus/dbus-glib.h>
-
-
-static GtkWidget *load_plugin               (void);
-static void       unload_plugin             (void);
-static void       write_config              (void);
-
-static GameStartupInfo gs;
-
-static StartupPluginInfo plugin_info = {
-  load_plugin,
-  unload_plugin,
-  write_config,
-  NULL
-};
-
-
-
-
-STARTUP_INIT_PLUGIN(plugin_info, gs, FALSE, FALSE)
-
-// the following does not work proper until osso_game_startup is
-// implemented as stackable window...
-
-// static void destroy_help_subwindow (void)
-// {
-//     StartupApp *app = gs.ui->app;
-//     osso_application_top(app->osso, app->path, NULL);
-// }
-// 
-// static void show_help_subwindow (void)
-// {
-//     GtkWidget *win;
-//     GtkWidget *textbox;
-//     GtkTextBuffer *textbox_buffer;
-//     gchar *textbox_text;
-//     PangoFontDescription *font_desc;
-//     GtkWidget *pannable_text;
-//     
-//     /* Create the subwindow (a stackable window) */
-//     win = hildon_stackable_window_new();
-//     gtk_window_set_title ( GTK_WINDOW (win), "Help");
-// 
-//     /* Create and pack labels */     
-//     textbox_text = g_strdup_printf("Welcome to Mancala, the ancient African game of skill!\n\nMancala is a very simple, easy-to-learn game. Each player begins with a horizontal row of holes or pits filled with a certain number of stones. At either end of the board are the players' home pits, which are used to keep score. In this case, the human player has the left home pit and the upper row holes. A move is made by clicking into the hole you wish to move from. The stones are then picked up and distributed, one to each hole, moving toward your home pit is reached, and then moving through your opponent's row, bypassing his/her home, and moving back towards in a circle (counterclockwise), until all the stones have been distributed.\n\nIf the last stone is placed in your home, you receive an extra turn. If the last stone lands in an empty hole on your side, you 'capture' the stones in the opposite hole on your opponent's side, moving them to your home.\n\nThe game ends when one player cannot play (ie. there are no stones on his/her side of the board.  The player who has the most stones on his/her *side* wins.");
-//     
-//     textbox = hildon_text_view_new();
-//     gtk_text_view_set_editable(GTK_TEXT_VIEW(textbox), FALSE);
-//     // gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textbox), FALSE);
-//     gtk_text_view_set_indent(GTK_TEXT_VIEW(textbox), 10);
-//     gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textbox), 10);
-//     gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textbox), 10);
-//     gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(textbox), 3);
-//     gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(textbox), 2);
-//     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textbox), GTK_WRAP_WORD);
-//     // gtk_widget_set_sensitive(textbox, FALSE);
-//     font_desc = pango_font_description_from_string ("vera 18");
-//     gtk_widget_modify_font(textbox, font_desc);
-//     pango_font_description_free (font_desc);
-//     
-//     textbox_buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (textbox));
-//     
-//     gtk_text_buffer_set_text(textbox_buffer, textbox_text, -1);
-//     
-//     
-//     pannable_text = hildon_pannable_area_new();
-//     hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA(pannable_text), textbox);
-//     
-//     gtk_container_add (GTK_CONTAINER (win), pannable_text);
-//     
-//     g_signal_connect (win, "destroy",    destroy_help_subwindow, NULL);
-//     
-// 
-//     /* This call show the window and also add the window to the stack */
-//     gtk_widget_show_all (win);
-// }
-
-
-static void show_help_browser (void)
-{
-    char *uri = "file:///home/opt/mancala/data/mancala.html";
-    DBusGConnection *connection;
-    GError *error = NULL;
-    DBusGProxy *proxy;
-    
-    connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-    
-    if (connection == NULL){
-        printf("Dbus connection failed: %s\n",error->message);
-        g_error_free (error);
-        return;
-    }
-    
-    proxy = dbus_g_proxy_new_for_name (connection,
-                                       "com.nokia.osso_browser",
-                                       "/com/nokia/osso_browser/request",
-                                       "com.nokia.osso_browser");
-
-    error = NULL;
-
-    if (!dbus_g_proxy_call (proxy, "load_url", &error, G_TYPE_STRING, uri, G_TYPE_INVALID, G_TYPE_INVALID)){
-        printf("Load_URL failed: %s\n",error->message);
-        g_error_free (error);
-    }
-
-}
-
-
-static GtkWidget *load_plugin (void)
-{
-    GtkWidget *button;
-    button =  gtk_button_new_with_label ("Instuctions");
-    
-    g_signal_connect (button, "clicked", G_CALLBACK (show_help_browser), NULL);
-    
-    return GTK_WIDGET(button);
-    
-}
-
-static void
-unload_plugin (void)
-{
-
-}
-
-static void
-write_config (void)
-{
-  
-}
-
-
diff --git a/src/settingswidget.cpp b/src/settingswidget.cpp
new file mode 100644 (file)
index 0000000..b54eba0
--- /dev/null
@@ -0,0 +1,80 @@
+/***************************************************************************
+
+Copyright 2010 Reto Zingg <g.d0b3rm4n@gmail.com>
+
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program 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 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+
+#include "settingswidget.h"
+
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QComboBox>
+#include <QLabel>
+#include <QPushButton>
+
+
+SettingsWidget::SettingsWidget(QWidget *parent) :
+    QWidget(parent)
+{
+
+    QVBoxLayout *vbox = new QVBoxLayout();
+
+    QHBoxLayout *hbox_level = new QHBoxLayout();
+    QHBoxLayout *hbox_game = new QHBoxLayout();
+    QHBoxLayout *hbox_bottom = new QHBoxLayout();
+
+    m_ComboLevel = new QComboBox();
+    m_ComboLevel->addItem("Easy");
+    m_ComboLevel->addItem("Medium");
+    m_ComboLevel->addItem("Hard");
+
+    connect(m_ComboLevel,
+            SIGNAL(currentIndexChanged(int)),
+            this,
+            SIGNAL(levelChanged(int)));
+
+    m_ComboGame = new QComboBox();
+
+    connect(m_ComboGame,
+            SIGNAL(currentIndexChanged(int)),
+            this,
+            SIGNAL(gameChanged(int)));
+
+    QLabel *label_level = new QLabel(tr("Level:"));
+    hbox_level->addWidget(label_level);
+    hbox_level->addWidget(m_ComboLevel);
+
+    QLabel *label_game = new QLabel(tr("Game:"));
+    hbox_game->addWidget(label_game);
+    hbox_game->addWidget(m_ComboGame);
+
+    QPushButton *m_button = new QPushButton();
+    m_button->setText(tr("Start"));
+    hbox_bottom->addWidget(m_button);
+
+    connect(m_button,
+            SIGNAL(clicked()),
+            this,
+            SIGNAL(start()));
+
+    vbox->addLayout(hbox_level);
+    vbox->addLayout(hbox_game);
+    vbox->addLayout(hbox_bottom);
+
+    setLayout(vbox);
+
+}
+
+void SettingsWidget::setGameNames(QStringList gameNames){
+    m_ComboGame->addItems(gameNames);
+}
diff --git a/src/settingswidget.h b/src/settingswidget.h
new file mode 100644 (file)
index 0000000..4eeb19e
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+
+Copyright 2010 Reto Zingg <g.d0b3rm4n@gmail.com>
+
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*   This program 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 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************/
+
+
+#ifndef SETTINGSWIDGET_H
+#define SETTINGSWIDGET_H
+
+#include <QWidget>
+#include <QComboBox>
+#include <QPushButton>
+
+class SettingsWidget : public QWidget
+{
+Q_OBJECT
+public:
+    explicit SettingsWidget(QWidget *parent = 0);
+    void setGameNames(QStringList gameNames);
+
+signals:
+    void start();
+    void levelChanged(int);
+    void gameChanged(int);
+
+public slots:
+
+private:
+    QComboBox *m_ComboLevel;
+    QComboBox *m_ComboGame;
+    QPushButton *m_button;
+
+};
+
+#endif // SETTINGSWIDGET_H
diff --git a/src/sounds.c b/src/sounds.c
deleted file mode 100644 (file)
index c1b4301..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*  
- *  Sounds Routines -- sounds.c
- *
- *  Copyright (C) 2009 Reto Zingg
-  *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-#include <stdio.h>
-#include "SDL.h"
-#include "SDL_mixer.h"
-
-int play_sound(Mix_Chunk *chunk){
-        //Play the scratch effect
-        if( Mix_PlayChannel( -1, chunk, 0 ) == -1 )
-        {
-                fprintf(stderr, "Unable to load sound: %s\n", 
-                         SDL_GetError());
-                exit(1);
-        }
-        else{
-                return 0;
-        }
-}
diff --git a/src/sounds.h b/src/sounds.h
deleted file mode 100644 (file)
index 4bc3eea..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*  
- *  Sounds Routines Header -- sounds.h
- *
- *  Copyright (C) 2009 Reto Zingg 
- *
- *  This program 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 2, or (at your option) any
- *  later version.
- *
- *  This program 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, a copy of which may be found in
- *  the file COPYING provided in the main directory of this release.
- *
- */
-
-extern int play_sound(Mix_Chunk *chunk);
-
-
diff --git a/src/src.pro b/src/src.pro
new file mode 100644 (file)
index 0000000..b491185
--- /dev/null
@@ -0,0 +1,50 @@
+# #####################################################################
+# Automatically generated by qmake (2.01a) Thu Jun 17 22:05:58 2010
+# #####################################################################
+TEMPLATE = app
+TARGET = mancala
+DEPENDPATH += .
+INCLUDEPATH += .
+QT += svg
+
+# Input
+HEADERS += Board.h \
+    Cup.h \
+    GameController.h \
+    GameInfo.h \
+    GraphicsScene.h \
+    Kalah.h \
+    MainWindow.h \
+    MoveGenerator.h \
+    Score.h \
+    Stone.h \
+    ThemeManager.h \
+    settingswidget.h
+SOURCES += Board.cpp \
+    Cup.cpp \
+    GameController.cpp \
+    GameInfo.cpp \
+    GraphicsScene.cpp \
+    Kalah.cpp \
+    main.cpp \
+    MainWindow.cpp \
+    MoveGenerator.cpp \
+    Score.cpp \
+    Stone.cpp \
+    ThemeManager.cpp \
+    settingswidget.cpp
+    
+unix {
+        #VARIABLES
+        isEmpty(PREFIX) {
+            PREFIX = /usr/local
+        }
+        
+        BINDIR = $$PREFIX/bin
+        
+        #MAKE INSTALL
+        
+        INSTALLS += target
+        
+        target.path =$$BINDIR
+   }