From: Reto Zingg Date: Mon, 5 Oct 2009 14:41:57 +0000 (+0300) Subject: initial load of http://downloads.sourceforge.net/project/cmancala/mancala-gui/mancala... X-Git-Tag: mancala-gui/0.1.0 X-Git-Url: http://vcs.maemo.org/git/?a=commitdiff_plain;h=52befa5d23562e3cd598d6a49d2d6c13131f38a6;hp=606abd932a14a2ac10f783761613bf4416381c5f;p=mancala initial load of downloads.sourceforge.net/project/cmancala/mancala-gui/mancala-gui-0.1.0/mancala-gui-0.1.0.tar.gz --- diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..2a7e338 --- /dev/null +++ b/COPYING @@ -0,0 +1,356 @@ + + NOTE! This copyright does *not* cover user programs that use kernel + services by normal system calls - this is merely considered normal use + of the kernel, and does *not* fall under the heading of "derived work". + Also note that the GPL below is copyrighted by the Free Software + Foundation, but the instance of code that it refers to (the Linux + kernel) is copyrighted by me and others who actually wrote it. + + Also note that the only valid version of the GPL as far as the kernel + is concerned is _this_ particular version of the license (ie v2, not + v2.2 or v3.x or whatever), unless explicitly otherwise stated. + + Linus Torvalds + +---------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..56ae381 --- /dev/null +++ b/INSTALL @@ -0,0 +1,62 @@ +/* + * Mancala Installation Instructions + * $Id: INSTALL,v 1.1.2.1 2004/01/17 20:09:02 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. + * + */ + +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/README b/README new file mode 100644 index 0000000..d6521e1 --- /dev/null +++ b/README @@ -0,0 +1,194 @@ +-------------------------------- + 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... :) + +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! 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/doc/template b/doc/template new file mode 100644 index 0000000..c88eed1 --- /dev/null +++ b/doc/template @@ -0,0 +1,53 @@ +/* + * Source File Name -- filename + * $#Id$ + * + * 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. + * + */ + + + +/* ...code goes here... */ + + + +/* End filename */ + + + +/* + * Source File Template -- template + * $Id: template,v 1.1.2.2 2003/12/31 21:33:04 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. + * + */ + + + +/* End template */ diff --git a/res/icon.png b/res/icon.png new file mode 100644 index 0000000..e37ee06 Binary files /dev/null and b/res/icon.png differ diff --git a/res/stone00.png b/res/stone00.png new file mode 100644 index 0000000..25512d2 Binary files /dev/null and b/res/stone00.png differ diff --git a/res/stone01.png b/res/stone01.png new file mode 100644 index 0000000..395da68 Binary files /dev/null and b/res/stone01.png differ diff --git a/res/stone02.png b/res/stone02.png new file mode 100644 index 0000000..20b122f Binary files /dev/null and b/res/stone02.png differ diff --git a/res/stone03.png b/res/stone03.png new file mode 100644 index 0000000..78d6dd6 Binary files /dev/null and b/res/stone03.png differ diff --git a/res/stone04.png b/res/stone04.png new file mode 100644 index 0000000..a384ec1 Binary files /dev/null and b/res/stone04.png differ diff --git a/res/stone05.png b/res/stone05.png new file mode 100644 index 0000000..9bd7103 Binary files /dev/null and b/res/stone05.png differ diff --git a/res/stone06.png b/res/stone06.png new file mode 100644 index 0000000..15e4521 Binary files /dev/null and b/res/stone06.png differ diff --git a/res/stone07.png b/res/stone07.png new file mode 100644 index 0000000..935c623 Binary files /dev/null and b/res/stone07.png differ diff --git a/res/stone08.png b/res/stone08.png new file mode 100644 index 0000000..bd3ba50 Binary files /dev/null and b/res/stone08.png differ diff --git a/res/stone09.png b/res/stone09.png new file mode 100644 index 0000000..1a7f4a7 Binary files /dev/null and b/res/stone09.png differ diff --git a/res/stone10.png b/res/stone10.png new file mode 100644 index 0000000..7789916 Binary files /dev/null and b/res/stone10.png differ diff --git a/res/tile.png b/res/tile.png new file mode 100644 index 0000000..9f490ec Binary files /dev/null and b/res/tile.png differ diff --git a/src/ChangeLog b/src/ChangeLog new file mode 100644 index 0000000..6231fde --- /dev/null +++ b/src/ChangeLog @@ -0,0 +1,214 @@ +$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/Makefile b/src/Makefile new file mode 100644 index 0000000..bb47fb8 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,69 @@ +# GNU Makefile -- Makefile +# Kevin Riggle +# 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 +CC = gcc +DBG = gdb +STD = _GNU_SOURCE +CFLAGS = `sdl-config --cflags` -I/usr/local/include/SDL +LFLAGS = `sdl-config --static-libs` -lSDL_image -lSDL_ttf + +MAIN_OBJ = main.o graphics.o mancala.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 + +#'$<' 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) + $(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 /usr/share/pixmaps/mancala + cp ../res/*.png /usr/share/pixmaps/mancala + cp ./mancala /usr/bin + +uninstall: + rm -rf /usr/share/pixmaps/mancala + rm /usr/bin/mancala + +clean: + rm -f *.o *.core *.swp *~ *.log + +clobber: clean + rm -f mancala ai-test + +distclean: clobber + @echo "No configuration files to distclean yet." + @echo "I will do my best to make some! ;-)" + +# End Makefile diff --git a/src/ai-init.c b/src/ai-init.c new file mode 100644 index 0000000..2562f56 --- /dev/null +++ b/src/ai-init.c @@ -0,0 +1,50 @@ +/* + * 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 +#include +#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 new file mode 100644 index 0000000..bf42688 --- /dev/null +++ b/src/ai-init.h @@ -0,0 +1,18 @@ +/* + * 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 new file mode 100644 index 0000000..cb53fa8 --- /dev/null +++ b/src/ai-recurse.c @@ -0,0 +1,88 @@ +/* + * 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 +#include +#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 new file mode 100644 index 0000000..2c97197 --- /dev/null +++ b/src/ai-test.c @@ -0,0 +1,110 @@ +/* + * 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 +#include +#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 new file mode 100644 index 0000000..1234862 --- /dev/null +++ b/src/ai-ultimate.c @@ -0,0 +1,92 @@ +/* + * "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 +#include +#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 new file mode 100644 index 0000000..1ddcf4d --- /dev/null +++ b/src/ai.c @@ -0,0 +1,59 @@ +/* + * 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 +#include +#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 new file mode 100644 index 0000000..f1c81df --- /dev/null +++ b/src/ai.h @@ -0,0 +1,13 @@ +/* + * 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/graphics.c b/src/graphics.c new file mode 100644 index 0000000..72a76ad --- /dev/null +++ b/src/graphics.c @@ -0,0 +1,311 @@ +/* + * 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 + * + * 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 + +#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" + +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; xw; x++) + for (y=0; yh; 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 new file mode 100644 index 0000000..d4103f9 --- /dev/null +++ b/src/graphics.h @@ -0,0 +1,29 @@ +/* + * 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/main.c b/src/main.c new file mode 100644 index 0000000..2a2bc30 --- /dev/null +++ b/src/main.c @@ -0,0 +1,281 @@ +/* + * 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 + * + * 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 +#include +#include +#include + +#include "SDL.h" +#include "SDL_image.h" +#include "SDL_ttf.h" + +#include "main.h" +#include "graphics.h" +#include "mancala.h" +#include "ai.h" + +#define HMN_WAIT 1 +#define HMN_MOVE 2 +#define CMP_WAIT 3 +#define CMP_MOVE 4 +#define GAME_WON 0 + +int main(int argc, char **argv) { + + SDL_Surface *screen, *board, *title_text, *tile, *stone[STONE_MAX+1]; + SDL_Rect board_rect, title_rect; + SDL_Color font_color; + SDL_Event event; + + TTF_Font *title_font, *home_font, *board_font; + + 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]; + 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) < 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", + SDL_GetError()); + exit(1); + } + + if (TTF_Init() < 0) { + fprintf(stderr, "Unable to initialize SDL_ttf: %s\n", + SDL_GetError()); + exit(1); + } + + /* Make sure we clean up after ourselves */ + atexit(SDL_Quit); + atexit(TTF_Quit); + + /* Load our images... PNGs now, maybe XPMs later */ + sprintf(tile_path, "%s/tile.png", RES_PATH); + if ((tile = LoadRes(tile_path)) == NULL) { + fprintf(stderr, "Unable to load resource: %s\n", + SDL_GetError()); + return 1; + } + + for (i=0; i<=STONE_MAX; i++) { + if (sprintf(stone_path, "%s/stone%02d.png", RES_PATH, i) == 0) + fprintf(stderr, "Problems assembling path.\n"); + if (!(stone[i] = LoadRes(stone_path))) { + fprintf(stderr, "Unable to load resource: %s\n", + SDL_GetError()); + return 1; + } + } + + /* Load our font(s) */ + if (sprintf(title_path, "%s/VeraSeBd.ttf", FONT_PATH) == 0) + fprintf(stderr, "Problems assembling path.\n"); + if (!(title_font = TTF_OpenFont(title_path, TITLE_SIZE))) { + fprintf(stderr, "Could not load font: %s\n", TTF_GetError()); + exit(1); + } + + if (sprintf(board_path, "%s/VeraSeBd.ttf", FONT_PATH) == 0) + fprintf(stderr, "Problems assembling path.\n"); + if (!(board_font = TTF_OpenFont(board_path, BOARD_SIZE))) { + fprintf(stderr, "Could not load font: %s\n", TTF_GetError()); + exit(1); + } + + if (sprintf(home_path, "%s/VeraSeBd.ttf", FONT_PATH) == 0) + fprintf(stderr, "Problems assembling path.\n"); + if (!(home_font = TTF_OpenFont(home_path, HOME_SIZE))) { + fprintf(stderr, "Could not load font: %s\n", TTF_GetError()); + exit(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; + + /* set window properties and create it */ + SDL_WM_SetCaption("Mancala", "Mancala"); + if (sprintf(icon_path, "%s/icon.png", RES_PATH) == 0) + fprintf(stderr, "Problems assembling icon path.\n"); + SDL_WM_SetIcon(LoadRes(icon_path), NULL); + if ((screen = SDL_SetVideoMode(tile->w*8, tile->h*2, 16, SDL_SWSURFACE)) + == NULL) { + fprintf(stderr, "Unable to set %dx%d video: %s", tile->w*8, + tile->h*2, SDL_GetError()); + exit(1); + } + + + state = HMN_WAIT; + redraw_board = 1; + old_highlight = 0; + highlight = 0; + active = 0; + + /* GAME LOOP */ + while (state != GAME_WON) { + /* figure out if anything important happened */ + old_highlight = highlight; + while (SDL_PollEvent(&event)) { + /* BAIL OUT! BAIL OUT! */ + if (event.type == SDL_QUIT) { + SDL_FreeSurface(board); + SDL_FreeSurface(tile); + for(i=0; i<=STONE_MAX; i++) + SDL_FreeSurface(stone[i]); + TTF_CloseFont(title_font); + TTF_CloseFont(board_font); + TTF_CloseFont(home_font); + exit(0); + } + /* get events */ + if (state == HMN_WAIT) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + if ((event.button.button = 1) && + (event.button.y < tile->h)) { + current_move = event.button.x / tile->w; + 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); + 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(5000); + 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); + 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))) + fprintf(stderr, "TTF: %s\n", TTF_GetError()); + } + else { + if (!(title_text = TTF_RenderText_Blended(title_font, + "Human Wins!", font_color))) + fprintf(stderr, "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) { + fprintf(stderr, "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; + } + + } + + SDL_Delay(5000); + + return 0; + +} + +/* End main.c */ diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..f89ca88 --- /dev/null +++ b/src/main.h @@ -0,0 +1,35 @@ +/* + * 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 "/usr/share/pixmaps/mancala" +#define FONT_PATH "/usr/share/fonts/bitstream-vera" + +/* various constants */ +#define STRING_MAX 1000 +#define STONE_MAX 10 +#define DELAY_MAX 1 + +/* font sizes */ +#define TITLE_SIZE 75 +#define HOME_SIZE 50 +#define BOARD_SIZE 35 + +/* End main.h */ diff --git a/src/mancala.c b/src/mancala.c new file mode 100644 index 0000000..c464f19 --- /dev/null +++ b/src/mancala.c @@ -0,0 +1,109 @@ +/* + * 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 $ + * + */ + +#include +#include +#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; + + /* Pick up the stones. */ + stones = *(activeBoard + move); + *(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; + +} + +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 new file mode 100644 index 0000000..c89c378 --- /dev/null +++ b/src/mancala.h @@ -0,0 +1,20 @@ +/* + * 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/welcome b/welcome deleted file mode 100644 index e69de29..0000000