From 52befa5d23562e3cd598d6a49d2d6c13131f38a6 Mon Sep 17 00:00:00 2001 From: Reto Zingg Date: Mon, 5 Oct 2009 17:41:57 +0300 Subject: [PATCH] initial load of http://downloads.sourceforge.net/project/cmancala/mancala-gui/mancala-gui-0.1.0/mancala-gui-0.1.0.tar.gz --- COPYING | 356 +++++++++++++++++++++++++++++++++++++++++++++++++++++ INSTALL | 62 ++++++++++ README | 194 +++++++++++++++++++++++++++++ doc/template | 53 ++++++++ res/icon.png | Bin 0 -> 5057 bytes res/stone00.png | Bin 0 -> 14504 bytes res/stone01.png | Bin 0 -> 653 bytes res/stone02.png | Bin 0 -> 939 bytes res/stone03.png | Bin 0 -> 994 bytes res/stone04.png | Bin 0 -> 1046 bytes res/stone05.png | Bin 0 -> 1184 bytes res/stone06.png | Bin 0 -> 1334 bytes res/stone07.png | Bin 0 -> 1444 bytes res/stone08.png | Bin 0 -> 1446 bytes res/stone09.png | Bin 0 -> 1619 bytes res/stone10.png | Bin 0 -> 1808 bytes res/tile.png | Bin 0 -> 8475 bytes src/ChangeLog | 214 ++++++++++++++++++++++++++++++++ src/Makefile | 69 +++++++++++ src/ai-init.c | 50 ++++++++ src/ai-init.h | 18 +++ src/ai-recurse.c | 88 +++++++++++++ src/ai-test.c | 110 +++++++++++++++++ src/ai-ultimate.c | 92 ++++++++++++++ src/ai.c | 59 +++++++++ src/ai.h | 13 ++ src/graphics.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++ src/graphics.h | 29 +++++ src/main.c | 281 ++++++++++++++++++++++++++++++++++++++++++ src/main.h | 35 ++++++ src/mancala.c | 109 ++++++++++++++++ src/mancala.h | 20 +++ 32 files changed, 2163 insertions(+) create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 README create mode 100644 doc/template create mode 100644 res/icon.png create mode 100644 res/stone00.png create mode 100644 res/stone01.png create mode 100644 res/stone02.png create mode 100644 res/stone03.png create mode 100644 res/stone04.png create mode 100644 res/stone05.png create mode 100644 res/stone06.png create mode 100644 res/stone07.png create mode 100644 res/stone08.png create mode 100644 res/stone09.png create mode 100644 res/stone10.png create mode 100644 res/tile.png create mode 100644 src/ChangeLog create mode 100644 src/Makefile create mode 100644 src/ai-init.c create mode 100644 src/ai-init.h create mode 100644 src/ai-recurse.c create mode 100644 src/ai-test.c create mode 100644 src/ai-ultimate.c create mode 100644 src/ai.c create mode 100644 src/ai.h create mode 100644 src/graphics.c create mode 100644 src/graphics.h create mode 100644 src/main.c create mode 100644 src/main.h create mode 100644 src/mancala.c create mode 100644 src/mancala.h delete mode 100644 welcome 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 0000000000000000000000000000000000000000..e37ee06b163d39aba8a6380835bb01e79dc5bbc8 GIT binary patch literal 5057 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 Xb=zJ9FYGQa00000NkvXXu0mjfBTB?; literal 0 HcmV?d00001 diff --git a/res/stone00.png b/res/stone00.png new file mode 100644 index 0000000000000000000000000000000000000000..25512d2397d78bb44b8e9ca9a6eecc587017ba36 GIT binary patch literal 14504 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 literal 0 HcmV?d00001 diff --git a/res/stone02.png b/res/stone02.png new file mode 100644 index 0000000000000000000000000000000000000000..20b122fe1ab6f11676a1ed87b57264e4a6f6d0d8 GIT binary patch literal 939 zcmV;c162HpP)e!As z!Q2o$2)ob11NiQalHFqtOpwee7p{?b7KW!Ga6r-8uI@ds?ag?cnaPl}$I|~vt;j}7 z%D>v~E(;<6000000000000000000000DvP5+sf`@91vCOQ-<1vlLV@i^w`HbV3q9~%**H@Qi8HcXzP=Xeo=ee`iDrP1> zwAQ4xrqO6bQ4~>GaWB+dOKNQq5<3_>j{yrOV4pwOlSAL)3UkK|&RgtLO-vSnzYtbRaNtxwboKy*G;H(UH4Jqhx8Jv538ywV&*1Le_m_dgu2;m z`Y7>3f`rPi-_D$CX>I9cv(9ITUm`Uwmn%>1&w`V;Nd?!JVob5Nmbt?#Y1f3?s5WV?GGs?Nc^05--v zw`Z&OopyIUpU;D}tAh)b=>Img>u(+HZn;=2g0`uH43+5nGuC6~bx{<-U#JZB9~O$D z_!LFaXJ%g0`>w!q%)E}G=yM-|0ssI20000000000000000000S&A-Y_68+IDA%Fk? N002ovPDHLkV1mXa$+!Rj literal 0 HcmV?d00001 diff --git a/res/stone03.png b/res/stone03.png new file mode 100644 index 0000000000000000000000000000000000000000..78d6dd66ad19567298fde886895fc73a13c2fc64 GIT binary patch literal 994 zcmV<810DQ{P)_=>pGHp0|0P*d^~r~4W*Ru zODP4V6b6Fd) z_4M@g(m6Nu?}ZS}Yj^pO(=^3sG#cLB-CdGxd=1i2t+nI!`?{{1*Y0x8!CH%=C}6F{ z*4EZ|;Xwm1p!{;@+)n$w56>@aEv&VustRRU0sy3xaLyq~lAVPI4FGAV=u98W0+sUD z1!b*;5W=6)!Ave))S-*W&hiZ(OEITfB-6j8HpJmxo_iXhBgF&-=r~pt^)%4=xVqskkq3)80 z3jC_6zEyPzA-b2oxxT*EtBw=LF?^`)rL~6E+6QY64-Xd}=c~wTDgfNx-fAi3bkXnp zP0AR9vMi^|0u8C|1`#R%^0 zzrKm|PO(cgz!-!1e2&>{hS_X}q9~fRiMmT3Y9G(1 zlu`>TYdcWCe6W74s=J>>+NjzURcnnjO`G=9{@J%7r4$|?AE!r0M<3?ZzU%H+ke#W0 z5A1oK?+PKzqVKAz>ci##_V#8r5hy?y>L#8~^-*{GKo;uX4($F+o6qMf2llVj-M&zc zR2v)EKU;VE63m=RJ+SwQGSr|3_CAq?`dyz-0feD$>iJX%f*Jn1{`J7#C-P@heLbHF z33;f%>ND1pQcgELU-pIkA1Xi?13P1kF~%5Uj4{R-V~jDz7-Nhv#u(d>pN^qb&*Q-m QlK=n!07*qoM6N<$f?9Ur<^TWy literal 0 HcmV?d00001 diff --git a/res/stone04.png b/res/stone04.png new file mode 100644 index 0000000000000000000000000000000000000000..a384ec1757b50ca5c87c9b8779a4e7ff5b56b81b GIT binary patch literal 1046 zcmV+x1nK*UP)1sY)*0*hL}tyZ{W^hu`NGx9omGaj^XpDgn z!i{K>v@=AhA8--^cFmt~fY27*8gXi}`&1W&Dv+zBJD{ zsacjG%QB>Cisf>N<#LH6Nviht_V($sn}Aem8-ZOZHD7hUF4Q$A*0n6lR(`f^$d;+U zN9Y&;wAKj25N>%{fA5x=N+~=&JuOa7PChL$>(^>B8jY&v{&4_M6vg85@{(k^N-|R0 z4(xFp?+YQaRre~2;?v{*{{Eg(2?dCxZX&SX-Q8&^>blv36CvMk90dz+9*RZ7jRwHM9vS@tUx z)n|Q|EuGYLfxVCQDWIe9-{fBcdtd8Q0CC}OHk+lc4DzWXLNp)!?5lj~uH*auhm}}e zu-4j%&5nqWuuJuwz&?cf6wpyl{nx{}Ad^z`&$p z0QD(gcv3&m*X1s`)c?Ic1rX2v+fbhZ2&HaIeF`A@@!qET6hJUix2-+}5J=s&`V>GQ zb=&Gw08OOYs`?brK~C*!U~dx&se=gYZL)Ex+g6_f2&8VRKGkQ)!+(>$1ok!|+YW21 zJ~aeL3xDfItV2q<=qg{f1?etTp94F?Fbu;m48t%C!!QiPFbu;m48shWpNLPAjBWkw Q-v9sr07*qoM6N<$g0q?OssI20 literal 0 HcmV?d00001 diff --git a/res/stone05.png b/res/stone05.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd710378b883c27386f58242456d8f498deba1f GIT binary patch literal 1184 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 literal 0 HcmV?d00001 diff --git a/res/stone07.png b/res/stone07.png new file mode 100644 index 0000000000000000000000000000000000000000..935c623be5a550affd3196be9b01983e825f9d71 GIT binary patch literal 1444 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 zs=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 -- 1.7.9.5